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 formatting
  • gw - text formatting with no cursor movement

Why do I need to have a separate keymap?

  • currently using vim.lsp.buf.format ... so does gq or gw use vim.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

If you want to handle just indentation then use = key then apply motion

The equal key uses a bunch of different options first check

  1. equalprg --> external program to handle the indentation
  2. if not set (?) vim will fall back to internal formatting builtin
  3. indentexpr

See indent.txt

= just for indentation while gq if for full text formatting

gq{motion} will determine what to use

  1. Check to see if formatexpr "a function for formatting your text"
  2. If (1.) isn't set it will use formatprg
  3. just use textwidth and formatoptions

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 or gw use vim.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 to vim.lsp.formatexpr() which leverages the vim.lsp.buf.format(opts)
  • not sure where this is documented but this sounds reasonable

Some useful gq commands / pattern

  • from usr_10.txt
  • gggqG - see section 10.7 - gg takes you to the first line, gq is the format operator and G the motion that jumps to the last line
  • gqq - 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.

Default Behavior of gq/gw

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.

Mapping Formatting to vim.lsp.buf.format

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 on formatexpr (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 means gq will use LSP formatting for the selected range. Avoiding LSP formatting conflicts
  • gw works similarly to gq: 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 run vim.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.