mirror of
https://github.com/LazyVim/LazyVim.git
synced 2026-07-25 14:01:06 +00:00
feat(format) adds mode for autoformat to apply either to the file or only the modified lines
This commit is contained in:
parent
cb223553ff
commit
2ea8bd564f
6 changed files with 123 additions and 11 deletions
|
|
@ -139,6 +139,8 @@ map("n", "[w", diagnostic_goto(false, "WARN"), { desc = "Prev Warning" })
|
|||
-- toggle options
|
||||
LazyVim.format.snacks_toggle():map("<leader>uf")
|
||||
LazyVim.format.snacks_toggle(true):map("<leader>uF")
|
||||
LazyVim.format.snacks_mode_toggle():map("<leader>um")
|
||||
LazyVim.format.snacks_mode_toggle(true):map("<leader>uM")
|
||||
Snacks.toggle.option("spell", { name = "Spelling" }):map("<leader>us")
|
||||
Snacks.toggle.option("wrap", { name = "Wrap" }):map("<leader>uw")
|
||||
Snacks.toggle.option("relativenumber", { name = "Relative Number" }):map("<leader>uL")
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@ vim.g.maplocalleader = "\\"
|
|||
|
||||
-- LazyVim auto format
|
||||
vim.g.autoformat = true
|
||||
-- LazyVim auto format mode (files | changes)
|
||||
-- if set to changes only format actual changes based on git hunks
|
||||
-- otherwise format all the file
|
||||
vim.g.formatmode = "file"
|
||||
--- LazyVim auto format changes only mode will be ignored
|
||||
--- for these filetypes and fallback to file
|
||||
vim.g.format_range_exclude_ft = { "lua" }
|
||||
|
||||
-- Snacks animations
|
||||
-- Set to `false` to globally disable all snacks animations
|
||||
|
|
|
|||
|
|
@ -139,6 +139,7 @@ return {
|
|||
topdelete = { text = "" },
|
||||
changedelete = { text = "▎" },
|
||||
},
|
||||
attach_to_untracked = true,
|
||||
on_attach = function(buffer)
|
||||
local gs = package.loaded.gitsigns
|
||||
|
||||
|
|
|
|||
|
|
@ -40,8 +40,8 @@ return {
|
|||
name = "conform.nvim",
|
||||
priority = 100,
|
||||
primary = true,
|
||||
format = function(buf)
|
||||
require("conform").format({ bufnr = buf })
|
||||
format = function(buf, range)
|
||||
require("conform").format({ bufnr = buf, range = range })
|
||||
end,
|
||||
sources = function(buf)
|
||||
local ret = require("conform").list_formatters(buf)
|
||||
|
|
|
|||
|
|
@ -9,12 +9,17 @@ local M = setmetatable({}, {
|
|||
---@class LazyFormatter
|
||||
---@field name string
|
||||
---@field primary? boolean
|
||||
---@field format fun(bufnr:number)
|
||||
---@field format fun(bufnr:number, range?:{start:integer[],end:integer[]})
|
||||
---@field sources fun(bufnr:number):string[]
|
||||
---@field priority number
|
||||
|
||||
M.formatters = {} ---@type LazyFormatter[]
|
||||
|
||||
--- Exclude lua from range formatting as stylua does not handle it well
|
||||
--- It will fallback to file formatting
|
||||
---@type string[]
|
||||
M.format_range_exclude_ft = { "lua" }
|
||||
|
||||
---@param formatter LazyFormatter
|
||||
function M.register(formatter)
|
||||
M.formatters[#M.formatters + 1] = formatter
|
||||
|
|
@ -52,13 +57,19 @@ function M.info(buf)
|
|||
buf = buf or vim.api.nvim_get_current_buf()
|
||||
local gaf = vim.g.autoformat == nil or vim.g.autoformat
|
||||
local baf = vim.b[buf].autoformat
|
||||
local gmode = (vim.g.formatmode == nil and "file") or vim.g.formatmode
|
||||
local bmode = vim.b[buf].formatmode
|
||||
if vim.tbl_contains(vim.g.format_range_exclude_ft or M.format_range_exclude_ft, vim.bo[buf].filetype) then
|
||||
bmode = "forced file"
|
||||
end
|
||||
local enabled = M.enabled(buf)
|
||||
local lines = {
|
||||
"# Status",
|
||||
("- [%s] global **%s**"):format(gaf and "x" or " ", gaf and "enabled" or "disabled"),
|
||||
("- [%s] buffer **%s**"):format(
|
||||
"\n# Status",
|
||||
("- [%s] global **%s** (`%s`)"):format(gaf and "x" or " ", gaf and "enabled" or "disabled", gmode),
|
||||
("- [%s] buffer **%s** (`%s`)"):format(
|
||||
enabled and "x" or " ",
|
||||
baf == nil and "inherit" or baf and "enabled" or "disabled"
|
||||
baf == nil and "inherit" or baf and "enabled" or "disabled",
|
||||
bmode == nil and "inherit" or bmode
|
||||
),
|
||||
}
|
||||
local have = false
|
||||
|
|
@ -115,20 +126,26 @@ function M.enable(enable, buf)
|
|||
M.info()
|
||||
end
|
||||
|
||||
---@param opts? {force?:boolean, buf?:number}
|
||||
---@param opts? {force?:boolean, buf?:number, changes?:boolean}
|
||||
function M.format(opts)
|
||||
opts = opts or {}
|
||||
local buf = opts.buf or vim.api.nvim_get_current_buf()
|
||||
if not ((opts and opts.force) or M.enabled(buf)) then
|
||||
return
|
||||
end
|
||||
local range_exclude_ft = vim.g.format_range_exclude_ft or M.format_range_exclude_ft
|
||||
|
||||
local format = M._format_file
|
||||
local mode = (opts.changes and "changes") or M.mode(buf)
|
||||
if mode == "changes" and not vim.tbl_contains(range_exclude_ft, vim.bo[buf].filetype) then
|
||||
format = M._format_changes
|
||||
end
|
||||
local done = false
|
||||
for _, formatter in ipairs(M.resolve(buf)) do
|
||||
if formatter.active then
|
||||
done = true
|
||||
LazyVim.try(function()
|
||||
return formatter.format(buf)
|
||||
return format(formatter, buf)
|
||||
end, { msg = "Formatter `" .. formatter.name .. "` failed" })
|
||||
end
|
||||
end
|
||||
|
|
@ -138,6 +155,46 @@ function M.format(opts)
|
|||
end
|
||||
end
|
||||
|
||||
---@param formatter LazyFormatter
|
||||
---@param buf number
|
||||
function M._format_changes(formatter, buf)
|
||||
if not LazyVim.has("gitsigns.nvim") then
|
||||
return
|
||||
end
|
||||
local hunks = require("gitsigns").get_hunks(buf)
|
||||
if hunks == nil then
|
||||
return
|
||||
end
|
||||
for i = #hunks, 1, -1 do
|
||||
local hunk = hunks[i]
|
||||
if hunk ~= nil and hunk.type ~= "delete" then
|
||||
local start = hunk.added.start
|
||||
local last = start + hunk.added.count
|
||||
local last_hunk_line = vim.api.nvim_buf_get_lines(0, last - 2, last - 1, true)[1]
|
||||
local range = { start = { start, 0 }, ["end"] = { last - 1, last_hunk_line:len() } }
|
||||
formatter.format(buf, range)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
---@param formatter LazyFormatter
|
||||
---@param buf number
|
||||
function M._format_file(formatter, buf)
|
||||
return formatter.format(buf)
|
||||
end
|
||||
|
||||
---@param mode "changes" | "file"
|
||||
---@param buf? boolean
|
||||
function M.setmode(mode, buf)
|
||||
if buf then
|
||||
vim.b.formatmode = mode
|
||||
else
|
||||
vim.g.formatmode = mode
|
||||
vim.b.formatmode = nil
|
||||
end
|
||||
M.info()
|
||||
end
|
||||
|
||||
function M.health()
|
||||
local Config = require("lazy.core.config")
|
||||
local has_plugin = Config.spec.plugins["none-ls.nvim"]
|
||||
|
|
@ -155,6 +212,29 @@ function M.health()
|
|||
end
|
||||
end
|
||||
|
||||
---@param buf? boolean
|
||||
function M.togglemode(buf)
|
||||
local mode = M.mode()
|
||||
if mode == "file" then
|
||||
mode = "changes"
|
||||
else
|
||||
mode = "file"
|
||||
end
|
||||
M.setmode(mode, buf)
|
||||
end
|
||||
|
||||
---@param buf? number
|
||||
---@return "changes" | "file"
|
||||
function M.mode(buf)
|
||||
buf = buf or vim.api.nvim_get_current_buf()
|
||||
local gmode = (vim.g.formatmode == nil and "file") or vim.g.formatmode
|
||||
local bmode = vim.b[buf].formatmode
|
||||
if bmode == nil then
|
||||
return gmode
|
||||
end
|
||||
return bmode
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
M.health()
|
||||
|
||||
|
|
@ -177,6 +257,27 @@ function M.setup()
|
|||
end, { desc = "Show info about the formatters for the current buffer" })
|
||||
end
|
||||
|
||||
---@param buf? boolean
|
||||
function M.snacks_mode_toggle(buf)
|
||||
return Snacks.toggle({
|
||||
name = "Format Changes only (" .. (buf and "Buffer" or "Global") .. ")",
|
||||
get = function()
|
||||
if not buf then
|
||||
local mode = vim.g.formatmode == nil and "file" or vim.g.formatmode
|
||||
return mode == "changes"
|
||||
end
|
||||
return LazyVim.format.mode() == "changes"
|
||||
end,
|
||||
set = function(state)
|
||||
if state then
|
||||
LazyVim.format.setmode("changes", buf)
|
||||
else
|
||||
LazyVim.format.setmode("file", buf)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
---@param buf? boolean
|
||||
function M.snacks_toggle(buf)
|
||||
return Snacks.toggle({
|
||||
|
|
|
|||
|
|
@ -162,8 +162,9 @@ function M.formatter(opts)
|
|||
name = "LSP",
|
||||
primary = true,
|
||||
priority = 1,
|
||||
format = function(buf)
|
||||
M.format(LazyVim.merge({}, filter, { bufnr = buf }))
|
||||
format = function(buf, range)
|
||||
local fopts = LazyVim.merge({}, filter, { bufnr = buf }, { range = range })
|
||||
M.format(fopts)
|
||||
end,
|
||||
sources = function(buf)
|
||||
local clients = M.get_clients(LazyVim.merge({}, filter, { bufnr = buf }))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue