summaryrefslogtreecommitdiffstats
path: root/lua/dotfiles/selection.lua
diff options
context:
space:
mode:
authorThomas Vanbesien <tvanbesi@proton.me>2026-06-24 20:10:00 +0200
committerThomas Vanbesien <tvanbesi@proton.me>2026-06-24 20:10:00 +0200
commitc30ca8b6556673e836e312b555f9a63216ec9660 (patch)
treea879666d407224b04ebcabf20301b63655f57b62 /lua/dotfiles/selection.lua
parent046e3be5982104f9e889edf1490381ea8c3b959f (diff)
downloadnvim-config-c30ca8b6556673e836e312b555f9a63216ec9660.tar.gz
nvim-config-c30ca8b6556673e836e312b555f9a63216ec9660.zip
refactor(nvim): rewrite transform-text plugin
Diffstat (limited to 'lua/dotfiles/selection.lua')
-rw-r--r--lua/dotfiles/selection.lua41
1 files changed, 41 insertions, 0 deletions
diff --git a/lua/dotfiles/selection.lua b/lua/dotfiles/selection.lua
new file mode 100644
index 0000000..33f45b2
--- /dev/null
+++ b/lua/dotfiles/selection.lua
@@ -0,0 +1,41 @@
+-- Apply transformations to the visual selection. The mechanics are generic: read the selected
+-- text, delete it, and put the transformed result in its place. Features wire specific transforms
+-- to keymaps in plugin/50-transform_text.lua.
+--
+-- API:
+-- transform(fn) — replace the selection with fn(selected_text)
+
+local M = {}
+
+-- The visually selected text, joined with newlines. Reads the live selection straight from the
+-- 'v'/'.' marks, so it must be called while the selection is still active.
+local function get_text()
+ return table.concat(
+ vim.fn.getregion(vim.fn.getpos("v"), vim.fn.getpos("."), { type = vim.fn.mode() }),
+ "\n"
+ )
+end
+
+-- Delete the visual selection from the current buffer. getregionpos gives 1-based rows and 1-based
+-- inclusive columns; in charwise 'v' the region's own end is exact, but in other modes we fall back
+-- to the further of the two marks. nvim_buf_set_text wants 0-based rows and an end-exclusive col,
+-- hence the -1 / +0 adjustments.
+local function delete()
+ local mode = vim.fn.mode()
+ local eovisual_pos, cur_pos = vim.fn.getpos("v"), vim.fn.getpos(".")
+ local region = vim.fn.getregionpos(eovisual_pos, cur_pos, { type = mode })[1]
+ local start_row, start_col = unpack(region[1], 2, 3)
+ local end_row, end_col =
+ mode == "v" and region[2][2] or math.max(eovisual_pos[2], cur_pos[2]), region[2][3]
+ vim.api.nvim_buf_set_text(0, start_row - 1, start_col - 1, end_row - 1, end_col, {})
+end
+
+-- Replace the visual selection with fn(selected_text): grab the text, delete it, then put the
+-- transformed string where it was.
+function M.transform(fn)
+ local text = get_text()
+ delete()
+ vim.api.nvim_put({ fn(text) }, "c", true, true)
+end
+
+return M