Skip to content

Bidirectional (bidi) text support in neovim

License

Notifications You must be signed in to change notification settings

mcookly/bidi.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

49 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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. 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.

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.