Skip to content

Latest commit

 

History

History
184 lines (165 loc) · 8.06 KB

File metadata and controls

184 lines (165 loc) · 8.06 KB

reform.nvim

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

Features

  • 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
    • speed is key - written in C with simplified utf8 support
    • support more languages - Rust, go
  • 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}`
}

Config defaults

-- 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
      blink_doc = true|fun() -- blink.cmp docs complete formatted drawing
      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 = '/tmp/reform.dbg', -- filename/'"io' for I+O save to register(s) or false to disable
  },
  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.buf.signature_help()` override
      lsc_on_attach = true|fun(), -- lspconfig hook to auto-update the signature window
    },
    mapping = {
      show_or_cycle = {'i', '<C-S-Space>'}, -- show sighelp or cycle to the next sighelp
      toggle_autoshow = {'n', '<C-S-Space>'}, -- toggle automatic updating and window permanence
    },
  },
  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(), - open link under 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
      inc = { { 'n', 'i' }, '<A-a>', { setCol = 'closer' } }, -- closer/start/end of match
      dec = { { 'n', 'i' }, '<A-A>', { 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},
  },
}
  • setup function can be called at any time again to change the settings at runtime

Formatting-supported langauges

Language servers bellow were tested.

  • Bash: bashls
  • C/Cpp: clangd
  • Java: nvim-jdtls
  • Lua: lua-language-server with neodev
  • Typescript/Javascript: typescript-launguage-server/typescript-tools.nvim

Screenshots: with TS vs. reform.nvim

  • bashls Bash/sh
  • clangd C/C++
  • typescript-language-server Javascript/Typescript
  • jdtls Java
  • luals, including Vim-style documentation Lua