Bidirectional (bidi) text support in neovim.
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. But if you would like to take over the project, by all means fork this repo, and I can update this readme to point to it.
- Neovim
- GNU FriBidi
- A terminal/GUI with bidi capabilities disabled1
- A good font for multi-lingual typing. I recommend Cousine or GNU FreeMono.
-- 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
}
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,
})
I would recommend backing up important documents beforehand.
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 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
.
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))')]]
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
There is an init.lua
in /test
.
It can also be used as a MWE.