Skip to content

Commit

Permalink
feat: add option to remove all leading whitespace from items (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
stevearc committed Dec 24, 2024
1 parent 9782132 commit da7e910
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 18 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ require("quicker").setup({
soft_cross = "",
soft_end = "",
},
-- Trim the leading whitespace from results
trim_leading_whitespace = true,
-- How to trim the leading whitespace from results. Can be 'all', 'common', or false
trim_leading_whitespace = "common",
-- Maximum width of the filename column
max_filename_width = function()
return math.floor(math.min(95, vim.o.columns / 2))
Expand Down
4 changes: 2 additions & 2 deletions doc/quicker.txt
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ OPTIONS *quicker-option
soft_cross = "╂",
soft_end = "┨",
},
-- Trim the leading whitespace from results
trim_leading_whitespace = true,
-- How to trim the leading whitespace from results. Can be 'all', 'common', or false
trim_leading_whitespace = "common",
-- Maximum width of the filename column
max_filename_width = function()
return math.floor(math.min(95, vim.o.columns / 2))
Expand Down
15 changes: 11 additions & 4 deletions lua/quicker/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ local default_config = {
soft_cross = "",
soft_end = "",
},
-- Trim the leading whitespace from results
trim_leading_whitespace = true,
-- How to trim the leading whitespace from results. Can be 'all', 'common', or false
trim_leading_whitespace = "common",
-- Maximum width of the filename column
max_filename_width = function()
return math.floor(math.min(95, vim.o.columns / 2))
Expand All @@ -65,6 +65,8 @@ local default_config = {
end,
}

---@alias quicker.TrimEnum "all"|"common"|false

---@class quicker.Config
---@field on_qf fun(bufnr: number)
---@field opts table<string, any>
Expand All @@ -75,7 +77,7 @@ local default_config = {
---@field edit quicker.EditConfig
---@field type_icons table<string, string>
---@field borders quicker.Borders
---@field trim_leading_whitespace boolean
---@field trim_leading_whitespace quicker.TrimEnum
---@field max_filename_width fun(): integer
---@field header_length fun(type: "hard"|"soft", start_col: integer): integer
local M = {}
Expand All @@ -90,7 +92,7 @@ local M = {}
---@field edit? quicker.SetupEditConfig
---@field type_icons? table<string, string> Map of quickfix item type to icon
---@field borders? quicker.SetupBorders Characters used for drawing the borders
---@field trim_leading_whitespace? boolean Trim the leading whitespace from results
---@field trim_leading_whitespace? quicker.TrimEnum How to trim the leading whitespace from results
---@field max_filename_width? fun(): integer Maximum width of the filename column
---@field header_length? fun(type: "hard"|"soft", start_col: integer): integer How far the header should extend to the right

Expand All @@ -104,6 +106,11 @@ M.setup = function(opts)
M[k] = v
end

-- Shim for when this was only a boolean. 'true' meant 'common'
if M.trim_leading_whitespace == true then
M.trim_leading_whitespace = "common"
end

-- Remove the default opts values if use_default_opts is false
if not new_conf.use_default_opts then
M.opts = opts.opts or {}
Expand Down
16 changes: 12 additions & 4 deletions lua/quicker/display.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ end
---@return table<integer, string>
local function calc_whitespace_prefix(items)
local prefixes = {}
if not config.trim_leading_whitespace then
if config.trim_leading_whitespace ~= "common" then
return prefixes
end

Expand Down Expand Up @@ -495,24 +495,32 @@ function M.quickfixtextfunc(info)
end

-- Construct the lines and save the filename + lnum to render as virtual text later
local trimmed_text
if config.trim_leading_whitespace == "all" then
trimmed_text = item.text:gsub("^%s*", "")
elseif config.trim_leading_whitespace == "common" then
trimmed_text = remove_prefix(item.text, prefixes[item.bufnr])
else
trimmed_text = item.text
end
if item.valid == 1 then
-- Matching line
local lnum = item.lnum == 0 and " " or item.lnum
local filename = rpad(M.get_filename_from_item(item), col_width)
table.insert(locations, get_virt_text(lnum))
table.insert(ret, filename .. EM_QUAD .. remove_prefix(item.text, prefixes[item.bufnr]))
table.insert(ret, filename .. EM_QUAD .. trimmed_text)
elseif user_data.lnum then
-- Non-matching line from quicker.nvim context lines
local filename = string.rep(" ", col_width)
table.insert(locations, get_virt_text(user_data.lnum))
table.insert(ret, filename .. EM_QUAD .. remove_prefix(item.text, prefixes[item.bufnr]))
table.insert(ret, filename .. EM_QUAD .. trimmed_text)
else
-- Other non-matching line
local lnum = item.lnum == 0 and " " or item.lnum
local filename = rpad(M.get_filename_from_item(item), col_width)
table.insert(locations, get_virt_text(lnum))
invalid_filenames[#locations] = true
table.insert(ret, filename .. EM_QUAD .. remove_prefix(item.text, prefixes[item.bufnr]))
table.insert(ret, filename .. EM_QUAD .. trimmed_text)
end
end

Expand Down
9 changes: 7 additions & 2 deletions lua/quicker/editor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -217,10 +217,15 @@ local function save_changes(bufnr, loclist_win)
if not vim.api.nvim_buf_is_loaded(item.bufnr) then
vim.fn.bufload(item.bufnr)
end
local src_line = vim.api.nvim_buf_get_lines(item.bufnr, item.lnum - 1, item.lnum, false)[1]

-- add the whitespace prefix back to the parsed line text
text = (prefixes[item.bufnr] or "") .. text
if config.trim_leading_whitespace == "common" then
text = (prefixes[item.bufnr] or "") .. text
elseif config.trim_leading_whitespace == "all" and src_line then
text = src_line:match("^%s*") .. text
end

local src_line = vim.api.nvim_buf_get_lines(item.bufnr, item.lnum - 1, item.lnum, false)[1]
if src_line and text ~= src_line then
if text:gsub("^%s*", "") == src_line:gsub("^%s*", "") then
-- If they only disagree in their leading whitespace, just take the changes after the
Expand Down
72 changes: 70 additions & 2 deletions tests/editor_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ describe("editor", function()
test_util.assert_snapshot(bufnr, "edit_delim")
end)

it("can edit lines with trimmed whitespace", function()
require("quicker.config").trim_leading_whitespace = true
it("can edit lines with trimmed common whitespace", function()
require("quicker.config").trim_leading_whitespace = "common"
vim.cmd.edit({
args = {
test_util.make_tmp_file("edit_whitespace.txt", {
Expand Down Expand Up @@ -276,4 +276,72 @@ describe("editor", function()
vim.cmd.write()
test_util.assert_snapshot(bufnr, "edit_whitespace")
end)

it("can edit lines with trimmed all whitespace", function()
require("quicker.config").trim_leading_whitespace = "all"
vim.cmd.edit({
args = {
test_util.make_tmp_file("edit_whitespace.txt", {
" line 1",
" line 2",
" line 3",
" line 4",
}),
},
})
local bufnr = vim.api.nvim_get_current_buf()
vim.fn.setqflist({
{
bufnr = bufnr,
text = " line 2",
lnum = 2,
},
{
bufnr = bufnr,
text = " line 3",
lnum = 3,
},
})
vim.cmd.copen()
wait_virt_text()
test_util.assert_snapshot(0, "edit_all_whitespace_qf")
replace_text(1, "foo")
replace_text(2, "bar")
vim.cmd.write()
test_util.assert_snapshot(bufnr, "edit_all_whitespace")
end)

it("can edit lines with untrimmed whitespace", function()
require("quicker.config").trim_leading_whitespace = false
vim.cmd.edit({
args = {
test_util.make_tmp_file("edit_whitespace.txt", {
" line 1",
" line 2",
" line 3",
" line 4",
}),
},
})
local bufnr = vim.api.nvim_get_current_buf()
vim.fn.setqflist({
{
bufnr = bufnr,
text = " line 2",
lnum = 2,
},
{
bufnr = bufnr,
text = " line 3",
lnum = 3,
},
})
vim.cmd.copen()
wait_virt_text()
test_util.assert_snapshot(0, "edit_none_whitespace_qf")
replace_text(1, "foo")
replace_text(2, "bar")
vim.cmd.write()
test_util.assert_snapshot(bufnr, "edit_none_whitespace")
end)
end)
4 changes: 4 additions & 0 deletions tests/snapshots/edit_all_whitespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
line 1
foo
bar
line 4
2 changes: 2 additions & 0 deletions tests/snapshots/edit_all_whitespace_qf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tests/tmp/edit_whitespace.txt ┃ 2┃line 2
tests/tmp/edit_whitespace.txt ┃ 3┃line 3
4 changes: 4 additions & 0 deletions tests/snapshots/edit_none_whitespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
line 1
foo
bar
line 4
2 changes: 2 additions & 0 deletions tests/snapshots/edit_none_whitespace_qf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tests/tmp/edit_whitespace.txt ┃ 2┃ line 2
tests/tmp/edit_whitespace.txt ┃ 3┃ line 3
2 changes: 2 additions & 0 deletions tests/snapshots/trim_all_whitespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tests/tmp/whitespace_1.txt ┃ 2┃line 2
tests/tmp/whitespace_1.txt ┃ 3┃line 3
29 changes: 27 additions & 2 deletions tests/whitespace_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ local test_util = require("tests.test_util")

describe("whitespace", function()
before_each(function()
require("quicker.config").trim_leading_whitespace = true
require("quicker.config").trim_leading_whitespace = "common"
end)
after_each(function()
test_util.reset_editor()
end)

it("removes leading whitespace from valid results", function()
it("removes common leading whitespace from valid results", function()
local bufnr = vim.fn.bufadd(test_util.make_tmp_file("whitespace.txt", {
" line 1",
" line 2",
Expand Down Expand Up @@ -55,4 +55,29 @@ describe("whitespace", function()
vim.cmd.copen()
test_util.assert_snapshot(0, "trim_mixed_whitespace")
end)

it("removes all leading whitespace", function()
require("quicker.config").trim_leading_whitespace = "all"
local bufnr = vim.fn.bufadd(test_util.make_tmp_file("whitespace_1.txt", {
" line 1",
" line 2",
" line 3",
"",
" line 4",
}))
vim.fn.setqflist({
{
bufnr = bufnr,
text = " line 2",
lnum = 2,
},
{
bufnr = bufnr,
text = " line 3",
lnum = 3,
},
})
vim.cmd.copen()
test_util.assert_snapshot(0, "trim_all_whitespace")
end)
end)

0 comments on commit da7e910

Please sign in to comment.