Skip to main content

Formatting

FtVim uses conform.nvim for code formatting, providing fast and reliable formatting with support for many formatters.

Default Configuration​

FtVim comes with these formatters pre-configured:

LanguageFormatter
Luastylua
Shell/Bashshfmt

These formatters are automatically installed via Mason. The extras add more: c_formatter_42 for C (42), clang-format for C++ (C++) and prettier for web files (Web).

Formatting Keymaps​

KeymapModeDescription
<leader>cfNormal, VisualFormat buffer or selection
<leader>ufNormalToggle format on save

Manual Formatting​

To format the current buffer, press <leader>cf in normal mode.

To format a selection, select the text in visual mode and press <leader>cf.

You can also use the command:

:lua require("conform").format()

Format on Save​

Format on save is disabled by default in FtVim. Toggle it for the session with <leader>uf, or enable it permanently in ~/.config/nvim/lua/config/options.lua:

vim.g.ftvim_autoformat = true

To enable or disable it for a single buffer, set vim.b.ftvim_autoformat (it overrides the global option):

vim.api.nvim_create_autocmd("FileType", {
pattern = { "markdown" },
callback = function()
vim.b.ftvim_autoformat = false
end,
})

Custom Format on Save​

For full control, override conform's format_on_save (this replaces FtVim's toggle):

-- ~/.config/nvim/lua/plugins/formatting.lua
return {
{
"stevearc/conform.nvim",
opts = {
format_on_save = {
timeout_ms = 500, -- Timeout for formatting
lsp_format = "fallback", -- Use LSP if no formatter is configured
},
},
},
}

Disable Format on Save for Specific Filetypes​

return {
{
"stevearc/conform.nvim",
opts = {
format_on_save = function(bufnr)
-- Disable for certain filetypes
local ignore_filetypes = { "sql", "java" }
if vim.tbl_contains(ignore_filetypes, vim.bo[bufnr].filetype) then
return nil
end
return {
timeout_ms = 500,
lsp_format = "fallback",
}
end,
},
},
}

Adding New Formatters​

Step 1: Install the Formatter​

Add the formatter to Mason's ensure_installed list:

return {
{
"mason-org/mason.nvim",
opts = {
ensure_installed = {
"prettier", -- JavaScript/TypeScript/JSON/etc.
"black", -- Python
"clang-format", -- C/C++
},
},
},
}

Or install manually via :Mason.

Step 2: Configure the Formatter​

Add the formatter to conform.nvim:

return {
{
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
javascript = { "prettier" },
typescript = { "prettier" },
json = { "prettier" },
python = { "black" },
c = { "clang-format" },
cpp = { "clang-format" },
},
},
},
}

Using Multiple Formatters​

Run formatters in sequence:

formatters_by_ft = {
python = { "isort", "black" }, -- Run isort first, then black
}

Use the first available formatter:

formatters_by_ft = {
javascript = { "prettierd", "prettier", stop_after_first = true },
}

Customizing Formatter Options​

Override formatter settings:

return {
{
"stevearc/conform.nvim",
opts = {
formatters = {
stylua = {
prepend_args = { "--indent-type", "Spaces", "--indent-width", "2" },
},
shfmt = {
prepend_args = { "-i", "2" }, -- 2-space indent
},
prettier = {
prepend_args = { "--tab-width", "2", "--single-quote" },
},
},
},
},
}

Disabling Formatting​

For Specific Filetypes​

return {
{
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
-- Set to empty table to disable
markdown = {},
},
},
},
}

Disable LSP Fallback​

return {
{
"stevearc/conform.nvim",
opts = {
default_format_opts = {
lsp_format = "never", -- Don't use LSP for formatting
},
},
},
}

Troubleshooting​

Check Conform Status​

:ConformInfo

Shows configured formatters and their status for the current buffer.

Common Issues​

Formatter not working:

  1. Check :ConformInfo to see if the formatter is detected
  2. Ensure the formatter is installed (:Mason)
  3. Verify the formatter binary is in your PATH

Formatting slow:

  1. Some formatters (like prettier) can be slow on large files
  2. Consider using faster alternatives (e.g., prettierd instead of prettier)
  3. Increase timeout_ms if needed

Format on save not working:

  1. Ensure it is enabled (<leader>uf or vim.g.ftvim_autoformat = true), it is disabled by default
  2. Check :ConformInfo for the formatter status
  3. Look for errors with :messages
LanguageFormatterNotes
LuastyluaDefault in FtVim
Shell/BashshfmtDefault in FtVim
JavaScript/TypeScriptprettier or prettierdprettierd is faster
Pythonblack or ruff_formatruff is faster
Gogofmt or goimportsgoimports also organizes imports
RustrustfmtComes with Rust toolchain
C (42)c_formatter_4242 extra
C/C++clang-formatHighly configurable, C++ extra
JSONprettier or jqjq for JSON-only projects
YAMLprettier or yamlfmt
Markdownprettier
HTML/CSSprettier

Example: Complete Formatting Setup​

Here's a full example for a web development setup:

return {
-- Install formatters
{
"mason-org/mason.nvim",
opts = {
ensure_installed = {
"prettierd",
"eslint_d",
},
},
},

-- Configure formatting
{
"stevearc/conform.nvim",
opts = {
formatters_by_ft = {
javascript = { "prettierd" },
typescript = { "prettierd" },
javascriptreact = { "prettierd" },
typescriptreact = { "prettierd" },
json = { "prettierd" },
html = { "prettierd" },
css = { "prettierd" },
markdown = { "prettierd" },
},
},
},
}

Then enable format on save with vim.g.ftvim_autoformat = true or <leader>uf.

tip

The Web extra already sets up prettier for these filetypes.