Git Product home page Git Product logo

bidi.nvim's Introduction

bidi.nvim

Bidirectional (bidi) text support in neovim.

Introduction

bidi.nvim aims to be a simple, easy-to-configure, and lightweight plugin which adds a bidirectional display mode to neovim on a per-buffer basis.

NOTE: I no longer use neovim, so I won't be adding any extra features to this plugin unless someone else (you?) puts in the work. I will try my best to fix bugs and other issues, however.

Dependencies

Required

Optional

Configuration

-- Default plugin options
local default_opts = {
  create_user_commands = true, -- Generate user commands to enable and disable bidi-mode
  default_base_direction = 'LR', -- Options: 'LR' and 'RL'
  intuitive_delete = true, -- Swap <DEL> and <BS> when using a keymap contra base direction
}

Installation

Use any standard neovim-compatible plugin manager. Then add somewhere in your init.lua:

-- Either
require("bidi").setup()

-- Or (if you want to customize options)
require("bidi").setup({
  create_user_commands = false,
})

Usage

I would recommend backing up important documents beforehand.

Toggle Bidi-Mode

Use :BidiEnable <base direction> to enable Bidi-Mode. The base direction is case insensitive.

" Example: Enable RTL Bidi-Mode
:BidiEnable RL

" Or
:BidiEnable rl

If no base direction is supplied (:BidiEnable), Bidi-Mode will activate using the default base direction.

Use :BidiDisable to disable Bidi-Mode.

Paste bidi'd contents using :BidiPaste

Paste in Bidi-Mode with :BidiPaste. For example,

" Paste from register `b`
:BidiPaste b

You can also assign :BidiPaste to a keymap by using its lua function:

-- You can specify a buffer to use OR pass in `nil`,
-- which will ask for a register.
vim.keymap.set('n', '<leader>bp', function() require('bidi').paste(nil), {})

Sometimes content will be out of sync with the rest of the bidi'd buffer. To correct this, delete the contents to a register and paste using :BidiPaste.

Statusline Indicator

I highly recommend adding this to your statusline so that you know when Bidi-Mode is enabled and in what base direction. It will display LR (LTR) or RL (RTL) depending on the base direction you choose. Add the following to your statusline:

%!luaeval('require("bidi").buf_get_bidi_mode(vim.api.nvim_win_get_buf(0))')
-- For example (if ALL you want is the Bidi-Mode status)
vim.o.statusline = [[%!luaeval('require("bidi").buf_get_bidi_mode(vim.api.nvim_win_get_buf(0))')]]

Roadmap

Below is a simple roadmap, more or less in the order I plan to add functionality.

  • ✅ GNU FriBidi piping (0c5861a)
  • Bidi-Mode toggleability (331de66)
  • Bidi-Mode statusline option (dcba4df)
  • ✅ Manually choose base direction (5b16429)
  • ✅ Save files only in logical mode (85b77d2)
  • ✅ Switch to revins automatically (83ca8a8)
  • ✅ Paste in properly in Bidi-Mode (8fc5741)
  • Dynamic padding for RTL paragraphs (see issue #8)
  • ✅ Ability to use exclusively in rightleft mode (5b16429)
  • Extensive testing framework

Testing

There is an init.lua in /test. It can also be used as a MWE.

Footnotes

  1. Alacritty cannot render Hebrew diacritical marks properly for fonts with those characters (issue #3830), so I recommend choosing another terminal if you want to see niqqud and te'amim.

bidi.nvim's People

Contributors

mcookly avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

bidi.nvim's Issues

Add logging at INFO and DEV level

Functions within bidi.nvim should be provide information during execution for better debugging.
If someone's file gets corrupted, they should have a way to see what code was used on it.

Creating a Vimscript version for Vim

It would be nice to create a similar/identical plugin in vimscript so that vimmers aren't left out of the bidi goodness. I don't have any experience with vimscript, but since the plugin utilizes basic vim API, I don't think it would be difficult to write.

I'll wait until I have the neovim version stable at 1.0.0. If someone hasn't picked up the work in the meantime, I'll probably begin implementing it myself.

Use buffer-local autocommands

This should reduce bidi.nvim's impact on Neovim as a whole I believe.
Deleting these autocommands can be a bit of a pain and may require a restructuring of active_bufs to include the IDs of the buffer's autocommands.

Dynamic padding in `ML` and `MR` modes

This might be clunky…

When enabling Bidi-Mode, get window width and textwidth (see which is longer).
Use that width to inform fribidi of the padding length for the current line depending on base direction.
Insert contents into buffer, but I think it should also insert some symbol to designate a line break,
so that on a change in textwidth (using SetOption event) or window size (using WindowResized event) lets some function re-wrap the lines accordingly.

↳ or ↪︎ might be good options to use on the left side of the buffer to indicate a line should wrap with the above.
For example (the m's are just to force the base direction as LTR)

|mבראשית ברא אלהים את|
|↪︎    mהשמים ואת הארץ|
^ window edges       ^

This function doesn't have to be super efficient since it only is triggered when the display changes, not when the user is actively editing the file.
I can also add an option to change what the linebreak indicator is.

Things get especially tricky when the user is typing though.
I will have to add an autocmd that listens for InsertCharPre on the current line and updates the whitespace accordingly.
When it comes to wrapping text, I'll have to watch the line-length without padding and jump the user to a new line with padding when the chars reach col 0 (and bring the current word if needbe).
If the user backspaces when in the textwidth/window-width column on a wrapped line,
delete the line and move the cursor back up.

Bidi content when pasted during `Bidi-Mode`

Essentially, pipe register contents through fribidi() before inserting the text into the buffer.
Would it make more sense to assign a specific register to this or apply to all registers?

Handle lines that changed in `insert mode`

When in insert mode, it would be good to use nvim_buf_attach() so that lines that are changed can be piped through fribidi without affecting the entire buffer.
The function should be aware of wrapped lines (via the wrapped symbol) so that a wrapped line is not partially-bidi'd.
The line (or wrapped lines) in which insert mode is entered should be unbidi'd before being bidi'd with the other changed lines.

Add descriptions to user commands

Currently, these user commands don't have descriptions:

  • BidiEnable
  • BidiDisable

It would be good to have descriptions to keep the plugin well-documented.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.