Documentation should be uniform, concise, and easy to read. This plugin aims to reform neovim to feel more like an IDE with a few QoL improvements (all fully customizable).
- fully customizable - all options expandable with your own functions for dynamic decissions
docmd
: reformat lsp docs for a consistent docs structure- identical look across supported languages (including vim docs in
lua
) - per-ft configurable
- opt-in support for all places using lsp docs
- signature help with param highlighting included (
cmp-nvim-lsp-signature-help
) and builtin
- signature help with param highlighting included (
- speed is key - written in
C
with simplified utf8 support - support more languages -
Rust
,go
…
- identical look across supported languages (including vim docs in
link
: clickable links like any other IDE- keybind creation builtin, but fully optional
- modular handlers by vimregex/luaptn → a lot can be used for a match (see also
toggle
module)- handler for stacktrace filepaths with cursor position supporting terminal line-wrapping
- uri handlers, nvim plugin link handler… (see default config)
vim
.ui
.input
/select
as popups floating at the cursor (instead of cmdline)- … - see config
Installation with lazy.nvim
return {
'litoj/reform.nvim',
opts = {}, -- put your config here
event = 'VeryLazy', -- or LspAttach and `key = {your link mapping}`
}
-- table of config options for `input` and `select`:
local util_win = {
title_pos = 'center', -- ↓ title of the prompt replaces `''`
title = {{'[', 'FloatBorder'}, {'', 'FloatTitle'}, {']', 'FloatBorder'}},
relative = 'cursor',
border = 'rounded',
}
require'reform'.setup {
docmd = true|{ -- reformat language-server's docs markdown to have a consistent structure
override = {
convert = true|fun(), -- main lspdocs-to-markdown conversion
stylize = true|fun(), -- docs-display buffer highlighting
convert_sig = true|fun(), -- signature-help docs composition
cmp_doc = true|fun(), -- cmp preview docs parsing
cmp_sig = true|fun(), -- cmp signature help docs parsing
},
ft = true|{ -- filetypes allowed for parsing (default=all/ ft=true)
-- lang = name of supported language; boolean/formatter
lang = true|fun(docs: string, vim.bo.ft): string[]
},
labels = {cs = 'c_sharp'}, -- fixes of md ft labels for file previews
no_preview = {csharp = true}, -- always parse docs with these code labels
debug = false|'', -- filename/'"io' for input+output save to register(s) or true to print src
},
ui = true|{ -- vim.ui.input (used in vim.lsp.buf.rename)
win = {
input = { height = 1, row = -3}+util_win,
select = { col = -2, row = 1, winhl = 'Id:Repeat,VarDelim:Delimiter'}+util_win,
},
input_mapping = { -- keybinds are replaced per action -> cancel={'<C-q>'} removes <Esc>
cancel = { '<Esc>', '<C-q>' },
confirm = { '<CR>' },
histPrev = { '<Up>', '<A-k>' },
histNext = { '<Down>', '<A-j>' },
},
},
link = true|{ -- under-cursor-regex matcher with configurable actions
mapping = { -- keymapping to open uri links (clicked or under cursor)
{{'', 'i'}, '<C-LeftMouse>'}, -- maps to link.mouse(), or manually: mouse=…
{'n', 'gL'}, -- maps to link.key()
},
handlers = { -- return false for failure → try other handlers if matched handler failed
-- Event fields: buf, line, column, mouse (if generated by a mouse click)
-- matches contains all matched groups indexed + matched text `from`/`to` boundaries
{luapat = 'lua(match)', use = fun(match:string, matches, reform.util.Event): false?},
{vimre = 'vim\\(match\\)regex'}, -- or vim regex match
'markdown_url', -- [name](http://url)
'any_url', -- http://url
'markdown_file_uri', -- [name](file:///path/to/file)
'markdown_file_path', -- [name](/file/path)
'reform_vimdoc_ref', -- [VimHelpLink]
'vimdoc_ref', -- |VimHelpLink|
'stacktrace_file_path', -- ~/multiline/path/to/file:line:column
'nvim_plugin', -- 'litoj/reform.nvim'
},
fallback = 'definition' -- action on no match - invalid value / 'noop' means no action
-- git link generation: {copy: boolean, print: boolean, branch:'default'|'current'|fun(ev)}
-- generates links to referenced line in the 'default'/'current'/provided branch
},
toggle = true|{ -- quick toggle/change of values under cursor - uses same system as `link`
mapping = { -- if cursor outside match, move cursor to its start
{{'n', 'i'}, '<A-a>', {action = 'inc', setCol = 'closer'}, -- closer/start/end of match
{{'n', 'i'}, '<A-A>', {action = 'dec', setCol = 'closer'}, -- or dec=…nvim.Keymap[]
{{'n', 'i'}, '<A-C-a>', {action = 'tgl', filter={tolerance={startPost=0,endPre=0}}},
},
filter = {
sorting = { order = 1, matcher = 3, offset = 1, length = 1 }, -- multipliers; least score first
tolerance = {startPost = inf, endPre = 1}, -- how far and in which directions from cursor is OK
},
handlers = {
'int', -- (-)123 - increase decrease or toggle sign
'direction', -- up north east down south west
'bool', -- true/True false/False
'logic', -- & && and | || or
'state', -- enable(d) disable(d)
'toggle', -- on off
'answer', -- yes no
'sign', -- < = + * ^ > ! - / %
},
},
tbl_extras = false|{ -- helpers for debugging table values
diff = {
expand_unique = '…', -- other tables for the field are `nil` → copy or use custom value
},
cut_depth = {
depth = 2, -- at which depth to stop copying tables
cuts = {}, -- what value should be put in cut-off places
},
-- set global print() to our extension for easy table diff and depth lookup
override = {print = true},
},
sig_help = true|{
max_line_offset = 5, -- max cursor position change before repositioning the sig_help window
max_column_offset = 20,
ignore_width_above = 0.8, -- percentage of current window width or absolute value
valid_modes = { i = true, s = true }, -- keep displaying the signature in these modes
require_active_param = false, -- display signature help for activeParameter=-1
auto_show = true, -- show on CursorHoldI, toggleable with sig_help.toggle() mapping
win_config = { border = 'rounded', close_events = {'BufLeave', 'WinScrolled'} },
override = {
lsp_sig = true|fun(), -- `vim.lsp.handlers['textDocument/signatureHelp]` main override
lsc_on_attach = true|fun(), -- lspconfig on_attach - keeps sig_help updated in attached bufs
},
mapping = { (toggle=) {'i', '<C-S-Space>'} },
},
}
- setup function can be called at any time again to change the settings at runtime
Language servers bellow were tested.
- Bash:
bashls
- C/Cpp:
clangd
- Java:
nvim-jdtls
- Lua:
lua-language-server
withneodev
- Typescript/Javascript:
typescript-launguage-server
/typescript-tools.nvim