Formatting in NeoVim (and maybe just) Vim - bdatko/nvim GitHub Wiki
Default kep mappings for formatting?
I see in the lsp-defaults there some defaults for formatting
gq
- text formattinggw
- text formatting with no cursor movement
Why do I need to have a separate keymap?
- currently using
vim.lsp.buf.format
... so doesgq
orgw
usevim.lsp.buf.format
What are the implementation for gq
or gw
?
Were the implementations changed when they added grn
, gra
, grr
, into NeoVim?
Format Code The Vim Way
- From YouTube https://www.youtube.com/watch?v=tM_uIwSucPU
- Published 2021-03-23
If you want to handle just indentation then use =
key then apply motion
The equal key uses a bunch of different options first check
equalprg
--> external program to handle the indentation- if not set (?) vim will fall back to internal formatting builtin
- indentexpr
See indent.txt
=
just for indentation while gq
if for full text formatting
gq{motion}
will determine what to use
- Check to see if formatexpr "a function for formatting your text"
- If (1.) isn't set it will use
formatprg
- just use
textwidth
andformatoptions
The author of the video demos using a Python file using the black formatting tool. He first clears the "formatexpr"
using :set formatexpr=
Then he sets formatprg
by :set formatprg=black\ -q\ -
- spaces need to be escaped
- the hyphen is
stdin
Answering the question:
- Do I need to have a separate keymap for selective formatting?
- Does
gq
orgw
usevim.lsp.buf.format
?
Using :echo &formatexpr
I can see in NeoVim is using
formatexpr=v:lua.lsp.formatexpr()
v:
I think this is a vim script calling lua from the vim script namespace
Learned we could of called this option only using lua through :lua print(vim.o.formatexpr)
Also learned the command :echo &formatexpr
<-- all of this is vim script and the ampersand is id-ing the next word in an option not a variable
"Options as variables" - Learn Vimscript the Hard Way
- Using an ampersand in front of of a name tells Vim that you're referring to the option, not a variable that happens to have the same name
"Format a text-object/motion
using LSP" from NeoVim discourse
- someone notes:
formatexpr
is already mapped tovim.lsp.formatexpr()
which leverages thevim.lsp.buf.format(opts)
- not sure where this is documented but this sounds reasonable
gq
commands / pattern
Some useful - from
usr_10.txt
gggqG
- see section 10.7 -gg
takes you to the first line,gq
is the format operator andG
the motion that jumps to the last linegqq
- Format the current line. If you add a count format that many lines
perplexity search
Searched: When using NeoVim do I need to have a separate keymap for selective formatting Does gq or gw use vim.lsp.buf.format? What are the implementation for gq or gw?
No, NeoVim does not automatically use vim.lsp.buf.format
with gq
/gw
unless configured; by default, gq
and gw
use the formatexpr
option, which may invoke LSP formatting if set up, but you often need a separate keymap to directly map selective formatting to vim.lsp.buf.format
.
gq
/gw
Default Behavior of By default, gq
and gw
in NeoVim are used for formatting text according to the buffer's formatexpr
setting. If you have LSP enabled and the server supports documentRangeFormattingProvider
, NeoVim may automatically set formatexpr
to v:lua.vim.lsp.formatexpr()
. In this case, gq
/gw
will use the LSP's formatting capabilities. However, certain plugin setups or multiple formatter sources can result in gq
/gw
doing nothing, unless configuration is explicit.
vim.lsp.buf.format
Mapping Formatting to
For reliable and selective formatting (such as formatting only the current selection), most NeoVim users create a custom keymap that directly calls vim.lsp.buf.format({ async = true })
for the buffer or selection. This method ensures that formatting is handled by the LSP, bypassing potential conflicts or inactions from formatexpr
/gq
/gw
defaults :
- Example keymap:
vim.keymap.set({'n', 'x'}, 'gq', function()
vim.lsp.buf.format({async = false, timeout_ms = 10000})
end, { buffer = event.buf })
This setup allows gq
(in normal and visual mode) to use LSP formatting for the selected text or buffer.
gq
/gw
Implementation Details
gq
generally calls the internal Vim/NeoVim formatting based onformatexpr
(often used for text reformatting, such as line wrapping in markdown). reference 1, reference 2- If LSP is configured and provides formatting,
formatexpr
can be set to the LSP handler, which meansgq
will use LSP formatting for the selected range. Avoiding LSP formatting conflicts gw
works similarly togq
: it is often just an alias for reformatting text with the selected method, based on current buffer options. reference
Recommendations for Selective Formatting
- Set a specific keymap (e.g.,
gq
in visual mode) to runvim.lsp.buf.format()
for formatting selections, rather than relying solely on default behavior. reference 1, reference 2 - This provides more predictable and configurable results, especially with multiple language servers or plugin conflicts. reference 1
In summary:
gq
/gw
do not inherently use vim.lsp.buf.format
without explicit configuration; for robust selective formatting with NeoVim's LSP, mapping a key (such as gq
) to vim.lsp.buf.format
is recommended, and gq
/gw
default to formatexpr
, which only uses LSP formatting if set to the correct handler.