aboutsummaryrefslogtreecommitdiffstats
path: root/lua/conform
diff options
context:
space:
mode:
Diffstat (limited to 'lua/conform')
-rw-r--r--lua/conform/formatters/autoflake.lua2
-rw-r--r--lua/conform/formatters/autopep8.lua5
-rw-r--r--lua/conform/formatters/black.lua2
-rw-r--r--lua/conform/formatters/clang_format.lua15
-rw-r--r--lua/conform/formatters/cljstyle.lua2
-rw-r--r--lua/conform/formatters/cmake_format.lua2
-rw-r--r--lua/conform/formatters/dart_format.lua2
-rw-r--r--lua/conform/formatters/dfmt.lua2
-rw-r--r--lua/conform/formatters/elm_format.lua2
-rw-r--r--lua/conform/formatters/erb_format.lua2
-rw-r--r--lua/conform/formatters/eslint_d.lua2
-rw-r--r--lua/conform/formatters/fish_indent.lua2
-rw-r--r--lua/conform/formatters/gdformat.lua2
-rw-r--r--lua/conform/formatters/gofmt.lua2
-rw-r--r--lua/conform/formatters/gofumpt.lua2
-rw-r--r--lua/conform/formatters/goimports.lua2
-rw-r--r--lua/conform/formatters/htmlbeautifier.lua2
-rw-r--r--lua/conform/formatters/isort.lua2
-rw-r--r--lua/conform/formatters/jq.lua2
-rw-r--r--lua/conform/formatters/nixfmt.lua2
-rw-r--r--lua/conform/formatters/nixpkgs_fmt.lua2
-rw-r--r--lua/conform/formatters/ocamlformat.lua2
-rw-r--r--lua/conform/formatters/pg_format.lua2
-rw-r--r--lua/conform/formatters/prettier.lua6
-rw-r--r--lua/conform/formatters/prettierd.lua6
-rw-r--r--lua/conform/formatters/rubocop.lua2
-rw-r--r--lua/conform/formatters/rustfmt.lua2
-rw-r--r--lua/conform/formatters/scalafmt.lua2
-rw-r--r--lua/conform/formatters/shfmt.lua2
-rw-r--r--lua/conform/formatters/sql_formatter.lua2
-rw-r--r--lua/conform/formatters/stylua.lua15
-rw-r--r--lua/conform/formatters/swift_format.lua2
-rw-r--r--lua/conform/formatters/swiftformat.lua2
-rw-r--r--lua/conform/formatters/terraform_fmt.lua2
-rw-r--r--lua/conform/formatters/uncrustify.lua2
-rw-r--r--lua/conform/formatters/xmlformat.lua2
-rw-r--r--lua/conform/formatters/yamlfix.lua2
-rw-r--r--lua/conform/formatters/yamlfmt.lua2
-rw-r--r--lua/conform/formatters/yapf.lua5
-rw-r--r--lua/conform/formatters/zigfmt.lua2
-rw-r--r--lua/conform/init.lua68
-rw-r--r--lua/conform/runner.lua82
-rw-r--r--lua/conform/util.lua14
43 files changed, 211 insertions, 73 deletions
diff --git a/lua/conform/formatters/autoflake.lua b/lua/conform/formatters/autoflake.lua
index 04daf71..c7d0a3b 100644
--- a/lua/conform/formatters/autoflake.lua
+++ b/lua/conform/formatters/autoflake.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/PyCQA/autoflake",
diff --git a/lua/conform/formatters/autopep8.lua b/lua/conform/formatters/autopep8.lua
index 5ed2f83..3945e47 100644
--- a/lua/conform/formatters/autopep8.lua
+++ b/lua/conform/formatters/autopep8.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/hhatto/autopep8",
@@ -6,4 +6,7 @@ return {
},
command = "autopep8",
args = { "-" },
+ range_args = function(ctx)
+ return { "-", "--line-range", tostring(ctx.range.start[1]), tostring(ctx.range["end"][1]) }
+ end,
}
diff --git a/lua/conform/formatters/black.lua b/lua/conform/formatters/black.lua
index 0d892a2..e27ed90 100644
--- a/lua/conform/formatters/black.lua
+++ b/lua/conform/formatters/black.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/psf/black",
diff --git a/lua/conform/formatters/clang_format.lua b/lua/conform/formatters/clang_format.lua
index d2c6d41..44af877 100644
--- a/lua/conform/formatters/clang_format.lua
+++ b/lua/conform/formatters/clang_format.lua
@@ -1,4 +1,5 @@
----@type conform.FormatterConfig
+local util = require("conform.util")
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://www.kernel.org/doc/html/latest/process/clang-format.html",
@@ -6,4 +7,16 @@ return {
},
command = "clang-format",
args = { "-assume-filename", "$FILENAME" },
+ range_args = function(ctx)
+ local start_offset, end_offset = util.get_offsets_from_range(ctx.buf, ctx.range)
+ local length = end_offset - start_offset
+ return {
+ "-assume-filename",
+ "$FILENAME",
+ "--offset",
+ tostring(start_offset),
+ "--length",
+ tostring(length),
+ }
+ end,
}
diff --git a/lua/conform/formatters/cljstyle.lua b/lua/conform/formatters/cljstyle.lua
index ffd8061..21205a5 100644
--- a/lua/conform/formatters/cljstyle.lua
+++ b/lua/conform/formatters/cljstyle.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/greglook/cljstyle",
diff --git a/lua/conform/formatters/cmake_format.lua b/lua/conform/formatters/cmake_format.lua
index 563bcae..0e98108 100644
--- a/lua/conform/formatters/cmake_format.lua
+++ b/lua/conform/formatters/cmake_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/cheshirekow/cmake_format",
diff --git a/lua/conform/formatters/dart_format.lua b/lua/conform/formatters/dart_format.lua
index eb9b39c..e110b06 100644
--- a/lua/conform/formatters/dart_format.lua
+++ b/lua/conform/formatters/dart_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://dart.dev/tools/dart-format",
diff --git a/lua/conform/formatters/dfmt.lua b/lua/conform/formatters/dfmt.lua
index 49c99cb..41dd667 100644
--- a/lua/conform/formatters/dfmt.lua
+++ b/lua/conform/formatters/dfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/dlang-community/dfmt",
diff --git a/lua/conform/formatters/elm_format.lua b/lua/conform/formatters/elm_format.lua
index 23f1408..5b0db5c 100644
--- a/lua/conform/formatters/elm_format.lua
+++ b/lua/conform/formatters/elm_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/avh4/elm-format",
diff --git a/lua/conform/formatters/erb_format.lua b/lua/conform/formatters/erb_format.lua
index dad08ca..65d7d10 100644
--- a/lua/conform/formatters/erb_format.lua
+++ b/lua/conform/formatters/erb_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/nebulab/erb-formatter",
diff --git a/lua/conform/formatters/eslint_d.lua b/lua/conform/formatters/eslint_d.lua
index e036aae..e7a5227 100644
--- a/lua/conform/formatters/eslint_d.lua
+++ b/lua/conform/formatters/eslint_d.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/mantoni/eslint_d.js/",
diff --git a/lua/conform/formatters/fish_indent.lua b/lua/conform/formatters/fish_indent.lua
index 1501072..7e10ed4 100644
--- a/lua/conform/formatters/fish_indent.lua
+++ b/lua/conform/formatters/fish_indent.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://fishshell.com/docs/current/cmds/fish_indent.html",
diff --git a/lua/conform/formatters/gdformat.lua b/lua/conform/formatters/gdformat.lua
index 914bb89..d180f12 100644
--- a/lua/conform/formatters/gdformat.lua
+++ b/lua/conform/formatters/gdformat.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/Scony/godot-gdscript-toolkit",
diff --git a/lua/conform/formatters/gofmt.lua b/lua/conform/formatters/gofmt.lua
index b0b81c3..2bfd6b4 100644
--- a/lua/conform/formatters/gofmt.lua
+++ b/lua/conform/formatters/gofmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://pkg.go.dev/cmd/gofmt",
diff --git a/lua/conform/formatters/gofumpt.lua b/lua/conform/formatters/gofumpt.lua
index 79fb4dc..2d4f9a5 100644
--- a/lua/conform/formatters/gofumpt.lua
+++ b/lua/conform/formatters/gofumpt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/mvdan/gofumpt",
diff --git a/lua/conform/formatters/goimports.lua b/lua/conform/formatters/goimports.lua
index 2361e43..64efea6 100644
--- a/lua/conform/formatters/goimports.lua
+++ b/lua/conform/formatters/goimports.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://pkg.go.dev/golang.org/x/tools/cmd/goimports",
diff --git a/lua/conform/formatters/htmlbeautifier.lua b/lua/conform/formatters/htmlbeautifier.lua
index 3182f99..73b9275 100644
--- a/lua/conform/formatters/htmlbeautifier.lua
+++ b/lua/conform/formatters/htmlbeautifier.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/threedaymonk/htmlbeautifier",
diff --git a/lua/conform/formatters/isort.lua b/lua/conform/formatters/isort.lua
index f6c6e3d..9b02c4e 100644
--- a/lua/conform/formatters/isort.lua
+++ b/lua/conform/formatters/isort.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/PyCQA/isort",
diff --git a/lua/conform/formatters/jq.lua b/lua/conform/formatters/jq.lua
index 50a905d..061ed03 100644
--- a/lua/conform/formatters/jq.lua
+++ b/lua/conform/formatters/jq.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/stedolan/jq",
diff --git a/lua/conform/formatters/nixfmt.lua b/lua/conform/formatters/nixfmt.lua
index 6c5001a..27029d5 100644
--- a/lua/conform/formatters/nixfmt.lua
+++ b/lua/conform/formatters/nixfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/serokell/nixfmt",
diff --git a/lua/conform/formatters/nixpkgs_fmt.lua b/lua/conform/formatters/nixpkgs_fmt.lua
index 6685fe8..9ca6a8a 100644
--- a/lua/conform/formatters/nixpkgs_fmt.lua
+++ b/lua/conform/formatters/nixpkgs_fmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/nix-community/nixpkgs-fmt",
diff --git a/lua/conform/formatters/ocamlformat.lua b/lua/conform/formatters/ocamlformat.lua
index 4ea1b49..0305083 100644
--- a/lua/conform/formatters/ocamlformat.lua
+++ b/lua/conform/formatters/ocamlformat.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/ocaml-ppx/ocamlformat",
diff --git a/lua/conform/formatters/pg_format.lua b/lua/conform/formatters/pg_format.lua
index 87aff66..f016454 100644
--- a/lua/conform/formatters/pg_format.lua
+++ b/lua/conform/formatters/pg_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/darold/pgFormatter",
diff --git a/lua/conform/formatters/prettier.lua b/lua/conform/formatters/prettier.lua
index 6f4bbfb..ea45ffb 100644
--- a/lua/conform/formatters/prettier.lua
+++ b/lua/conform/formatters/prettier.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/prettier/prettier",
@@ -7,6 +7,10 @@ return {
},
command = util.from_node_modules("prettier"),
args = { "--stdin-filepath", "$FILENAME" },
+ range_args = function(ctx)
+ local start_offset, end_offset = util.get_offsets_from_range(ctx.buf, ctx.range)
+ return { "$FILENAME", "--range-start=" .. start_offset, "--range-end=" .. end_offset }
+ end,
cwd = util.root_file({
-- https://prettier.io/docs/en/configuration.html
".prettierrc",
diff --git a/lua/conform/formatters/prettierd.lua b/lua/conform/formatters/prettierd.lua
index 0af6baf..3cdc19e 100644
--- a/lua/conform/formatters/prettierd.lua
+++ b/lua/conform/formatters/prettierd.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/fsouza/prettierd",
@@ -7,6 +7,10 @@ return {
},
command = util.from_node_modules("prettierd"),
args = { "$FILENAME" },
+ range_args = function(ctx)
+ local start_offset, end_offset = util.get_offsets_from_range(ctx.buf, ctx.range)
+ return { "$FILENAME", "--range-start=" .. start_offset, "--range-end=" .. end_offset }
+ end,
cwd = util.root_file({
-- https://prettier.io/docs/en/configuration.html
".prettierrc",
diff --git a/lua/conform/formatters/rubocop.lua b/lua/conform/formatters/rubocop.lua
index 492f379..5e2a143 100644
--- a/lua/conform/formatters/rubocop.lua
+++ b/lua/conform/formatters/rubocop.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/rubocop/rubocop",
diff --git a/lua/conform/formatters/rustfmt.lua b/lua/conform/formatters/rustfmt.lua
index 7b5e322..d8f0f19 100644
--- a/lua/conform/formatters/rustfmt.lua
+++ b/lua/conform/formatters/rustfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/rust-lang/rustfmt",
diff --git a/lua/conform/formatters/scalafmt.lua b/lua/conform/formatters/scalafmt.lua
index 2b9e451..ea82624 100644
--- a/lua/conform/formatters/scalafmt.lua
+++ b/lua/conform/formatters/scalafmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/scalameta/scalafmt",
diff --git a/lua/conform/formatters/shfmt.lua b/lua/conform/formatters/shfmt.lua
index 6e40f0c..29b8615 100644
--- a/lua/conform/formatters/shfmt.lua
+++ b/lua/conform/formatters/shfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/mvdan/sh",
diff --git a/lua/conform/formatters/sql_formatter.lua b/lua/conform/formatters/sql_formatter.lua
index bd92851..9452a61 100644
--- a/lua/conform/formatters/sql_formatter.lua
+++ b/lua/conform/formatters/sql_formatter.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/sql-formatter-org/sql-formatter",
diff --git a/lua/conform/formatters/stylua.lua b/lua/conform/formatters/stylua.lua
index ac482bd..d971932 100644
--- a/lua/conform/formatters/stylua.lua
+++ b/lua/conform/formatters/stylua.lua
@@ -1,5 +1,5 @@
local util = require("conform.util")
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/JohnnyMorganz/StyLua",
@@ -7,6 +7,19 @@ return {
},
command = "stylua",
args = { "--search-parent-directories", "--stdin-filepath", "$FILENAME", "-" },
+ range_args = function(ctx)
+ local start_offset, end_offset = util.get_offsets_from_range(ctx.buf, ctx.range)
+ return {
+ "--search-parent-directories",
+ "--stdin-filepath",
+ "$FILENAME",
+ "--range-start",
+ tostring(start_offset),
+ "--range-end",
+ tostring(end_offset),
+ "-",
+ }
+ end,
cwd = util.root_file({
".stylua.toml",
"stylua.toml",
diff --git a/lua/conform/formatters/swift_format.lua b/lua/conform/formatters/swift_format.lua
index 2b81297..e3e4365 100644
--- a/lua/conform/formatters/swift_format.lua
+++ b/lua/conform/formatters/swift_format.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/apple/swift-format",
diff --git a/lua/conform/formatters/swiftformat.lua b/lua/conform/formatters/swiftformat.lua
index 821a010..ed142ad 100644
--- a/lua/conform/formatters/swiftformat.lua
+++ b/lua/conform/formatters/swiftformat.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/nicklockwood/SwiftFormat",
diff --git a/lua/conform/formatters/terraform_fmt.lua b/lua/conform/formatters/terraform_fmt.lua
index 44edc55..fba8a12 100644
--- a/lua/conform/formatters/terraform_fmt.lua
+++ b/lua/conform/formatters/terraform_fmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://www.terraform.io/docs/cli/commands/fmt.html",
diff --git a/lua/conform/formatters/uncrustify.lua b/lua/conform/formatters/uncrustify.lua
index 3430063..2782e96 100644
--- a/lua/conform/formatters/uncrustify.lua
+++ b/lua/conform/formatters/uncrustify.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/uncrustify/uncrustify",
diff --git a/lua/conform/formatters/xmlformat.lua b/lua/conform/formatters/xmlformat.lua
index 25b48e2..d04c9cc 100644
--- a/lua/conform/formatters/xmlformat.lua
+++ b/lua/conform/formatters/xmlformat.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/pamoller/xmlformatter",
diff --git a/lua/conform/formatters/yamlfix.lua b/lua/conform/formatters/yamlfix.lua
index 1b00e01..7592340 100644
--- a/lua/conform/formatters/yamlfix.lua
+++ b/lua/conform/formatters/yamlfix.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/lyz-code/yamlfix",
diff --git a/lua/conform/formatters/yamlfmt.lua b/lua/conform/formatters/yamlfmt.lua
index 56c6cb6..8f188ab 100644
--- a/lua/conform/formatters/yamlfmt.lua
+++ b/lua/conform/formatters/yamlfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/google/yamlfmt",
diff --git a/lua/conform/formatters/yapf.lua b/lua/conform/formatters/yapf.lua
index 5d7e866..fc3cfeb 100644
--- a/lua/conform/formatters/yapf.lua
+++ b/lua/conform/formatters/yapf.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/google/yapf",
@@ -6,4 +6,7 @@ return {
},
command = "yapf",
args = { "--quiet" },
+ range_args = function(ctx)
+ return { "--quiet", "--lines", string.format("%d-%d", ctx.range.start[1], ctx.range["end"][1]) }
+ end,
}
diff --git a/lua/conform/formatters/zigfmt.lua b/lua/conform/formatters/zigfmt.lua
index 9c93c0b..8097d9c 100644
--- a/lua/conform/formatters/zigfmt.lua
+++ b/lua/conform/formatters/zigfmt.lua
@@ -1,4 +1,4 @@
----@type conform.FormatterConfig
+---@type conform.FileFormatterConfig
return {
meta = {
url = "https://github.com/ziglang/zig",
diff --git a/lua/conform/init.lua b/lua/conform/init.lua
index 1bea2ea..9ba56bb 100644
--- a/lua/conform/init.lua
+++ b/lua/conform/init.lua
@@ -7,26 +7,35 @@ local M = {}
---@field available boolean
---@field available_msg? string
----@class (exact) conform.StaticFormatterConfig
+---@class (exact) conform.FormatterConfig
---@field command string|fun(ctx: conform.Context): string
---@field args? string[]|fun(ctx: conform.Context): string[]
+---@field range_args? fun(ctx: conform.RangeContext): string[]
---@field cwd? fun(ctx: conform.Context): nil|string
---@field require_cwd? boolean When cwd is not found, don't run the formatter (default false)
---@field stdin? boolean Send buffer contents to stdin (default true)
---@field condition? fun(ctx: conform.Context): boolean
---@field exit_codes? integer[] Exit codes that indicate success (default {0})
----@class (exact) conform.FormatterConfig : conform.StaticFormatterConfig
+---@class (exact) conform.FileFormatterConfig : conform.FormatterConfig
---@field meta conform.FormatterMeta
---@class (exact) conform.FormatterMeta
---@field url string
---@field description string
----
+
---@class (exact) conform.Context
---@field buf integer
---@field filename string
---@field dirname string
+---@field range? conform.Range
+
+---@class (exact) conform.RangeContext : conform.Context
+---@field range conform.Range
+
+---@class (exact) conform.Range
+---@field start integer[]
+---@field end integer[]
---@class (exact) conform.RunOptions
---@field run_all_formatters nil|boolean Run all listed formatters instead of stopping at the first one.
@@ -37,7 +46,7 @@ local M = {}
---@type table<string, string[]|conform.FormatterList>
M.formatters_by_ft = {}
----@type table<string, conform.StaticFormatterConfig|fun(): conform.StaticFormatterConfig>
+---@type table<string, conform.FormatterConfig|fun(): conform.FormatterConfig>
M.formatters = {}
M.setup = function(opts)
@@ -167,6 +176,37 @@ local function filter_formatters(formatters, run_options)
return all_info
end
+---@param bufnr integer
+---@param mode "v"|"V"
+---@return table {start={row,col}, end={row,col}} using (1, 0) indexing
+local function range_from_selection(bufnr, mode)
+ -- [bufnum, lnum, col, off]; both row and column 1-indexed
+ local start = vim.fn.getpos("v")
+ local end_ = vim.fn.getpos(".")
+ local start_row = start[2]
+ local start_col = start[3]
+ local end_row = end_[2]
+ local end_col = end_[3]
+
+ -- A user can start visual selection at the end and move backwards
+ -- Normalize the range to start < end
+ if start_row == end_row and end_col < start_col then
+ end_col, start_col = start_col, end_col
+ elseif end_row < start_row then
+ start_row, end_row = end_row, start_row
+ start_col, end_col = end_col, start_col
+ end
+ if mode == "V" then
+ start_col = 1
+ local lines = vim.api.nvim_buf_get_lines(bufnr, end_row - 1, end_row, true)
+ end_col = #lines[1]
+ end
+ return {
+ ["start"] = { start_row, start_col - 1 },
+ ["end"] = { end_row, end_col - 1 },
+ }
+end
+
---Format a buffer
---@param opts? table
--- timeout_ms nil|integer Time in milliseconds to block for formatting. Defaults to 1000. No effect if async = true.
@@ -175,9 +215,10 @@ end
--- formatters nil|string[] List of formatters to run. Defaults to all formatters for the buffer filetype.
--- lsp_fallback nil|boolean Attempt LSP formatting if no formatters are available. Defaults to false.
--- quiet nil|boolean Don't show any notifications for warnings or failures. Defaults to false.
+--- range nil|table Range to format. Table must contain `start` and `end` keys with {row, col} tuples using (1,0) indexing. Defaults to current selection in visual mode
---@return boolean True if any formatters were attempted
M.format = function(opts)
- ---@type {timeout_ms: integer, bufnr: integer, async: boolean, lsp_fallback: boolean, quiet: boolean, formatters?: string[]}
+ ---@type {timeout_ms: integer, bufnr: integer, async: boolean, lsp_fallback: boolean, quiet: boolean, formatters?: string[], range?: conform.Range}
opts = vim.tbl_extend("keep", opts or {}, {
timeout_ms = 1000,
bufnr = 0,
@@ -219,10 +260,21 @@ M.format = function(opts)
local any_formatters = not vim.tbl_isempty(formatters)
if any_formatters then
+ local mode = vim.api.nvim_get_mode().mode
+ if not opts.range and mode == "v" or mode == "V" then
+ opts.range = range_from_selection(opts.bufnr, mode)
+ end
+
if opts.async then
- require("conform.runner").format_async(opts.bufnr, formatters)
+ require("conform.runner").format_async(opts.bufnr, formatters, opts.range)
else
- require("conform.runner").format_sync(opts.bufnr, formatters, opts.timeout_ms, opts.quiet)
+ require("conform.runner").format_sync(
+ opts.bufnr,
+ formatters,
+ opts.timeout_ms,
+ opts.quiet,
+ opts.range
+ )
end
elseif opts.lsp_fallback and supports_lsp_format(opts.bufnr) then
log.debug("Running LSP formatter on %s", vim.api.nvim_buf_get_name(opts.bufnr))
@@ -276,7 +328,7 @@ end
---@private
---@param formatter string
----@return nil|conform.StaticFormatterConfig
+---@return nil|conform.FormatterConfig
M.get_formatter_config = function(formatter)
local config = M.formatters[formatter]
if not config then
diff --git a/lua/conform/runner.lua b/lua/conform/runner.lua
index 7ccaec6..843dae1 100644
--- a/lua/conform/runner.lua
+++ b/lua/conform/runner.lua
@@ -5,35 +5,51 @@ local uv = vim.uv or vim.loop
local M = {}
---@param ctx conform.Context
----@param config conform.StaticFormatterConfig
+---@param config conform.FormatterConfig
M.build_cmd = function(ctx, config)
local command = config.command
if type(command) == "function" then
command = command(ctx)
end
local cmd = { command }
- if config.args then
- local args = config.args
+ local args = {}
+ if ctx.range and config.range_args then
+ ---@cast ctx conform.RangeContext
+ args = config.range_args(ctx)
+ elseif config.args then
if type(config.args) == "function" then
args = config.args(ctx)
+ else
+ ---@diagnostic disable-next-line: cast-local-type
+ args = config.args
end
- ---@cast args string[]
- for _, v in ipairs(args) do
- if v == "$FILENAME" then
- v = ctx.filename
- elseif v == "$DIRNAME" then
- v = ctx.dirname
- end
- table.insert(cmd, v)
+ end
+
+ ---@diagnostic disable-next-line: param-type-mismatch
+ for _, v in ipairs(args) do
+ if v == "$FILENAME" then
+ v = ctx.filename
+ elseif v == "$DIRNAME" then
+ v = ctx.dirname
end
+ table.insert(cmd, v)
end
return cmd
end
+---@param range? conform.Range
+---@param start_a integer
+---@param end_a integer
+local function indices_in_range(range, start_a, end_a)
+ return not range or (start_a <= range["end"][1] and range["start"][1] <= end_a)
+end
+
---@param bufnr integer
---@param original_lines string[]
---@param new_lines string[]
-local function apply_format(bufnr, original_lines, new_lines)
+---@param range? conform.Range
+---@param only_apply_range boolean
+local function apply_format(bufnr, original_lines, new_lines, range, only_apply_range)
local original_text = table.concat(original_lines, "\n")
-- Trim off the final newline from the formatted text because that is baked in to
-- the vim lines representation
@@ -68,18 +84,21 @@ local function apply_format(bufnr, original_lines, new_lines)
count_b = count_b + 1
end
local replacement = util.tbl_slice(new_lines, start_b, start_b + count_b - 1)
- vim.api.nvim_buf_set_lines(bufnr, start_a - 1, start_a - 1 + count_a, true, replacement)
+ local end_a = start_a + count_a
+ if not only_apply_range or indices_in_range(range, start_a, end_a) then
+ vim.api.nvim_buf_set_lines(bufnr, start_a - 1, end_a - 1, true, replacement)
+ end
end
end
---@param bufnr integer
---@param formatter conform.FormatterInfo
+---@param config conform.FormatterConfig
+---@param ctx conform.Context
---@param input_lines string[]
---@param callback fun(err?: string, output?: string[])
----@return integer
-local function run_formatter(bufnr, formatter, input_lines, callback)
- local config = assert(require("conform").get_formatter_config(formatter.name))
- local ctx = M.build_context(bufnr, config)
+---@return integer job_id
+local function run_formatter(bufnr, formatter, config, ctx, input_lines, callback)
local cmd = M.build_cmd(ctx, config)
local cwd = nil
if config.cwd then
@@ -159,9 +178,10 @@ local function run_formatter(bufnr, formatter, input_lines, callback)
end
---@param bufnr integer
----@param config conform.StaticFormatterConfig
+---@param config conform.FormatterConfig
+---@param range? conform.Range
---@return conform.Context
-M.build_context = function(bufnr, config)
+M.build_context = function(bufnr, config, range)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
@@ -193,13 +213,15 @@ M.build_context = function(bufnr, config)
buf = bufnr,
filename = filename,
dirname = dirname,
+ range = range,
}
end
---@param bufnr integer
---@param formatters conform.FormatterInfo[]
+---@param range? conform.Range
---@param callback? fun(err?: string)
-M.format_async = function(bufnr, formatters, callback)
+M.format_async = function(bufnr, formatters, range, callback)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
@@ -207,6 +229,7 @@ M.format_async = function(bufnr, formatters, callback)
local changedtick = vim.b[bufnr].changedtick
local original_lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
local input_lines = original_lines
+ local all_support_range_formatting = true
-- kill previous jobs for buffer
local prev_jid = vim.b[bufnr].conform_jid
@@ -221,7 +244,7 @@ M.format_async = function(bufnr, formatters, callback)
if not formatter then
-- discard formatting if buffer has changed
if vim.b[bufnr].changedtick == changedtick then
- apply_format(bufnr, original_lines, input_lines)
+ apply_format(bufnr, original_lines, input_lines, range, not all_support_range_formatting)
else
log.info(
"Async formatter discarding changes for %s: concurrent modification",
@@ -235,8 +258,10 @@ M.format_async = function(bufnr, formatters, callback)
end
idx = idx + 1
+ local config = assert(require("conform").get_formatter_config(formatter.name))
+ local ctx = M.build_context(bufnr, config, range)
local jid
- jid = run_formatter(bufnr, formatter, input_lines, function(err, output)
+ jid = run_formatter(bufnr, formatter, config, ctx, input_lines, function(err, output)
if err then
-- Only log the error if the job wasn't canceled
if vim.api.nvim_buf_is_valid(bufnr) and jid == vim.b[bufnr].conform_jid then
@@ -250,6 +275,7 @@ M.format_async = function(bufnr, formatters, callback)
input_lines = output
run_next_formatter()
end)
+ all_support_range_formatting = all_support_range_formatting and config.range_args ~= nil
end
run_next_formatter()
end
@@ -258,7 +284,8 @@ end
---@param formatters conform.FormatterInfo[]
---@param timeout_ms integer
---@param quiet boolean
-M.format_sync = function(bufnr, formatters, timeout_ms, quiet)
+---@param range? conform.Range
+M.format_sync = function(bufnr, formatters, timeout_ms, quiet, range)
if bufnr == 0 then
bufnr = vim.api.nvim_get_current_buf()
end
@@ -274,6 +301,7 @@ M.format_sync = function(bufnr, formatters, timeout_ms, quiet)
end
end
+ local all_support_range_formatting = true
for _, formatter in ipairs(formatters) do
local remaining = timeout_ms - (uv.hrtime() / 1e6 - start)
if remaining <= 0 then
@@ -286,13 +314,16 @@ M.format_sync = function(bufnr, formatters, timeout_ms, quiet)
end
local done = false
local result = nil
- run_formatter(bufnr, formatter, input_lines, function(err, output)
+ local config = assert(require("conform").get_formatter_config(formatter.name))
+ local ctx = M.build_context(bufnr, config, range)
+ local jid = run_formatter(bufnr, formatter, config, ctx, input_lines, function(err, output)
if err then
log.error(err)
end
done = true
result = output
end)
+ all_support_range_formatting = all_support_range_formatting and config.range_args ~= nil
local wait_result, wait_reason = vim.wait(remaining, function()
return done
@@ -306,6 +337,7 @@ M.format_sync = function(bufnr, formatters, timeout_ms, quiet)
vim.notify(string.format("Formatter '%s' timed out", formatter.name), vim.log.levels.WARN)
end
end
+ vim.fn.jobstop(jid)
return
end
@@ -317,7 +349,7 @@ M.format_sync = function(bufnr, formatters, timeout_ms, quiet)
end
local final_result = input_lines
- apply_format(bufnr, original_lines, final_result)
+ apply_format(bufnr, original_lines, final_result, range, not all_support_range_formatting)
end
return M
diff --git a/lua/conform/util.lua b/lua/conform/util.lua
index 353c447..d2ca1b9 100644
--- a/lua/conform/util.lua
+++ b/lua/conform/util.lua
@@ -58,6 +58,20 @@ M.save_win_positions = function(bufnr)
end
end
+---@param bufnr integer
+---@param range conform.Range
+---@return integer start_offset
+---@return integer end_offset
+M.get_offsets_from_range = function(bufnr, range)
+ local row = range.start[1] - 1
+ local end_row = range["end"][1] - 1
+ local col = range.start[2]
+ local end_col = range["end"][2]
+ local start_offset = vim.api.nvim_buf_get_offset(bufnr, row) + col
+ local end_offset = vim.api.nvim_buf_get_offset(bufnr, end_row) + end_col
+ return start_offset, end_offset
+end
+
---@generic T : any
---@param tbl T[]
---@param start_idx? number