Skip to content

tanloong/interlaced.nvim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

interlaced.nvim

Text re-positioning for bilingual sentence alignment.

Requirements

  • Neovim >= 0.9.0

Installation

{
  "tanloong/interlaced.nvim",
  config = function() require("interlaced").setup {} end,
  ft = "text",
}

Configuration

local rpst = require("interlaced.reposition")
local mt = require("interlaced.match")
local it
local Dump = function()
it = it or require("interlaced"); it.cmd.Dump()
end
local Load = function()
it = it or require("interlaced"); it.cmd.Load()
end
local config = {
keymaps = {
{ "n", ",", rpst.cmd.PushUp, { noremap = true, buffer = true, nowait = true } },
{ "n", "<", rpst.cmd.PushUpPair, { noremap = true, buffer = true, nowait = true } },
{ "n", ".", rpst.cmd.PullBelow, { noremap = true, buffer = true, nowait = true } },
{ "n", ">", rpst.cmd.PullBelowPair, { noremap = true, buffer = true, nowait = true } },
{ "n", "d", rpst.cmd.PushDownRightPart, { noremap = true, buffer = true, nowait = true } },
{ "n", "D", rpst.cmd.PushDown, { noremap = true, buffer = true, nowait = true } },
{ "n", "s", rpst.cmd.LeaveAlone, { noremap = true, buffer = true, nowait = true } },
{ "n", "[e", rpst.cmd.SwapWithAbove, { noremap = true, buffer = true, nowait = true } },
{ "n", "]e", rpst.cmd.SwapWithBelow, { noremap = true, buffer = true, nowait = true } },
{ "n", "u", rpst.cmd.Undo, { noremap = true, buffer = true, nowait = true } },
{ "n", "<C-r>", rpst.cmd.Redo, { noremap = true, buffer = true, nowait = true } },
{ "n", "J", rpst.cmd.NavigateDown, { noremap = true, buffer = true, nowait = true } },
{ "n", "K", rpst.cmd.NavigateUp, { noremap = true, buffer = true, nowait = true } },
{ "n", "md", Dump, { noremap = true, buffer = true, nowait = true } },
{ "n", "ml", Load, { noremap = true, buffer = true, nowait = true } },
{ "n", "gn", rpst.cmd.NextUnaligned, { noremap = true, buffer = true, nowait = true } },
{ "n", "gN", rpst.cmd.PrevUnaligned, { noremap = true, buffer = true, nowait = true } },
{ "n", "mt", mt.cmd.MatchToggle, { noremap = true, buffer = true, nowait = true } },
{ "n", "m;", mt.cmd.ListMatches, { noremap = true, buffer = true, nowait = true } },
{ "n", "ma", mt.cmd.MatchAdd, { noremap = true, buffer = true, nowait = true } },
{ "v", "ma", mt.cmd.MatchAddVisual, { noremap = true, buffer = true, nowait = true } },
},
-- automatically enable mappings for *interlaced.txt files
setup_mappings_now = (((vim.api.nvim_buf_get_name(vim.api.nvim_get_current_buf())):find("interlaced%.txt$")) ~= nil),
-- sentence separator to insert between when push- or pull-ing up
language_separator = { ["1"] = "", ["2"] = " " },
-- save on text re-position, i.e., pushing, pulling, sentence splitting. But causes delay for re-position, better turn this off
auto_save = false,
cmd_prefix = "It",
lang_num = 2,
---@type function|nil
enable_keybindings_hook = function()
-- 1. It costs too much RAM to remember changes of an interlaced buffer,
-- because re-position changes every line from the cursor below, and the
-- builtin undo mechanism stores all of that. One `ItPushUp` at the
-- beginning of an interlaced buffer with 190k lines increases memory
-- use by 100M. It is recommended to turn off the builtin undo history
-- to avoid memory creep.
-- 2. The plugin manages an undo history itself by remembering not the text
-- changes but re-position operations. You can use that to undo and redo
-- through e.g., the keybindings set above on `rpst.cmd.Undo` and
-- `rpst.cmd.Redo`.
-- 3. Note that the plugin only remembers re-position operations, i.e.,
-- `ItPushUp(Pair)`, `ItPullBelow(Pair)`, `ItPushDown(RightPart)`, and
-- `ItLeaveAlone`. Others like `ItInterlace`, `ItDeinterlace` or normal
-- text changes like inserting, pasting are forgotten, so take care :).
vim.opt_local.undolevels = -1
end,
---@type function|nil
disable_keybindings_hook = nil,
}
return config

Commands

:ItEnableKeybindings applies keybindings specified in the mappings field of the table passed to require("interlaced").setup(). Original keymaps are backed up.

:ItDisableKeybindings cancels mappings keybindings and restores backed up keymaps.

:ItSplitEnglishSentences identifies English sentence endings and insert a newline after each of them. Works linewise on the range when provided, the whole buffer if not.

:ItSplitChineseSentences ibidem but identifies Chinese sentence endings.

:ItInterlaceWithL1 {filepath} mixes non-empty lines from current buffer with those from filepath into empty-line-separated pairs of lines. In each pair, lines from filepath are above those from current buffer. mappings keybindings are enabled if they have not been previously.

:ItInterlaceWithL2 {filepath} ibidem but lines from filepath are below those from current buffer.

:[range]ItInterlace [num] mixes non-empty lines from current buffer into num empty-line-separated groups. If num is not provided, lang_num field of the config table will be used. Works on the range when provided, the whole buffer if not.

:ItDeinterlace

:ItMatchAdd opens a matches window to edit a pattern to be highlighted. The window has 3 columns: match id, highlight group, and pattern. On pressing <Enter> in insert/normal mode, matchadd() will be called with the 3 values (see :h matchadd()). If match id is left as _, a random one will be chosen by matchadd() . If highlight group is left as _, a random one will be chosen from the plugin's predefined ones.

:ItMatchAddVisual ibidem but populates the pattern column with the visually selected text.

:ItListMatches opens the matches window. You can edit highlight groups or pattern there and press <Enter> to apply the change.

:ItClearMatches removes all matches. This action cannot be undone.

:ItMatchToggle turns on/off highlighting for the matches.

:ItListHighlights shows the predefined highlight groups of this plugin.

:ItSwapWithAbove swaps current line with the counterpart line from the chunk above.

:ItSwapWithBelow ibidem but from the chunk below.

:ItPushUp appends current line up to the end of its counterpart at the chunk above. Subsequent counterpart lines are moved up correspondingly.

:ItPushUpPair ibidem but works every line in the current chunk.

:ItPullBelow applies ItPushUp on the counterpart of the current line at the chunk below.

:ItPullBelowPair ibidem but on every line in the current below.

:ItPushDownRightPart moves the text from the cursor position to the end of the current line down to its counterpart line at the chunk below. Subsequent counterpart lines are moved down correspondingly. The current line is left with the text leftside of the cursor.

:ItPushDown ibidem but works on the whole current line. The current line is left as empty.

:ItLeaveAlone pushes down all lines (except the cursor line) in the current chunk, puts a - as placeholder at each, and moves cursor down to the next chunk.

:ItNextUnaligned finds the next chunk has different kinds of highlighted matches across its lines and puts cursor there.

:ItPrevUnaligned ibidem but finds the previous chunk.

:ItSetLangNum {num} changes language number, i.e., how many lines should be in each chunk. This affects re-positioning actions: ItPushUp(Pair), ItPullBelow(Pair), ItPushDown(RightPart), ItSwapWithAbove, ItSwapWithBelow, and ItLeaveAlone. When called without argument or with a single ? it shows the current value.

:ItSetSeparator {num} {str} changes sentence separator to str for the numth language, i.e., what should be inserted between on ItPushUp(Pair) and ItPullBelow(Pair). When called without argument or with a single ? it shows current values.

:[count]ItNavigateDown moves cursor down by lang_num + 1 lines.

:[count]ItNavigateUp moves cursor up by lang_num + 1 lines.

:[count]ItUndo undoes the last re-positioning action. The undo list remembers at most 100 actions and forgets oldest ones thereafter.

:[count]ItRedo undoes the last ItUnDo.

:ItToggleChunkNr shows/hides chunk number at the right-hand side.

:ItDump [filepath] saves workspace to filepath: cursor position, matches, language separator, and lang_num. Undo and redo lists are not saved. Uses ./.interlaced.json when called without argument.

:ItLoad [filepath] loads workspace from filepath. Uses ./.interlaced.json when called without argument.

Releases

No releases published

Packages

No packages published

Languages