aboutsummaryrefslogtreecommitdiff
path: root/lua/hobs/util.lua
diff options
context:
space:
mode:
authorJosh Rahm <rahm@josher.dev>2026-08-11 11:19:05 -0600
committerJosh Rahm <rahm@josher.dev>2026-08-11 11:19:05 -0600
commitd7829c069b09d2115daa1aa33a729dd9ffee301e (patch)
tree4b4845c79c0df4b3879249e83ebbea44239f5cef /lua/hobs/util.lua
parentd2eadb42ffde7f07b4c2d46efc3724d565ec8255 (diff)
downloadhobs.nvim-d7829c069b09d2115daa1aa33a729dd9ffee301e.tar.gz
hobs.nvim-d7829c069b09d2115daa1aa33a729dd9ffee301e.tar.bz2
hobs.nvim-d7829c069b09d2115daa1aa33a729dd9ffee301e.zip
[refactor] break up some of the mega lua file.
Diffstat (limited to 'lua/hobs/util.lua')
-rw-r--r--lua/hobs/util.lua101
1 files changed, 101 insertions, 0 deletions
diff --git a/lua/hobs/util.lua b/lua/hobs/util.lua
new file mode 100644
index 0000000..5cda17c
--- /dev/null
+++ b/lua/hobs/util.lua
@@ -0,0 +1,101 @@
+local M = {}
+
+---
+-- Validate that `search_lines` matches exactly once in `buffer_lines`.
+-- Returns the start index (1-based) and end index (inclusive) of the match,
+-- or errors if there is not exactly one match.
+local function find_exact_match(buffer_lines, search_lines)
+ local search_text = table.concat(search_lines, "\n")
+
+ local matches = {}
+ local search_len = #search_lines
+
+ for i = 1, #buffer_lines - search_len + 1 do
+ local candidate = table.concat(vim.list_slice(buffer_lines, i, i + search_len - 1), "\n")
+ if candidate == search_text then
+ table.insert(matches, { start = i, end_ = i + search_len - 1 })
+ end
+ end
+
+ if #matches == 0 then
+ error("search text not found in buffer")
+ elseif #matches > 1 then
+ error("search text matches multiple times")
+ end
+
+ return matches[1].start, matches[1].end_
+end
+
+---
+-- Insert `lines` before the lines matched by `search_lines`.
+-- Returns a new table of lines with the insertion applied.
+-- Errors if `search_lines` does not match exactly once.
+function M.insert_before(buffer_lines, search_lines, insert_lines)
+ local start, end_ = find_exact_match(buffer_lines, search_lines)
+
+ local result = {}
+
+ for i = 1, start - 1 do
+ table.insert(result, buffer_lines[i])
+ end
+
+ for _, line in ipairs(insert_lines) do
+ table.insert(result, line)
+ end
+
+ for i = start, #buffer_lines do
+ table.insert(result, buffer_lines[i])
+ end
+
+ return result
+end
+
+---
+-- Append `lines` after the lines matched by `search_lines`.
+-- Returns a new table of lines with the append applied.
+-- Errors if `search_lines` does not match exactly once.
+function M.append_after(buffer_lines, search_lines, append_lines)
+ local start, end_ = find_exact_match(buffer_lines, search_lines)
+
+ local result = {}
+
+ for i = 1, end_ do
+ table.insert(result, buffer_lines[i])
+ end
+
+ for _, line in ipairs(append_lines) do
+ table.insert(result, line)
+ end
+
+ for i = end_ + 1, #buffer_lines do
+ table.insert(result, buffer_lines[i])
+ end
+
+ return result
+end
+
+---
+-- Replace the lines matched by `search_lines` with `replace_lines`.
+-- Returns a new table of lines with the replacement applied.
+-- Errors if `search_lines` does not match exactly once.
+function M.replace(buffer_lines, search_lines, replace_lines)
+ local start, end_ = find_exact_match(buffer_lines, search_lines)
+
+ local result = {}
+
+ for i = 1, start - 1 do
+ table.insert(result, buffer_lines[i])
+ end
+
+ for _, line in ipairs(replace_lines) do
+ table.insert(result, line)
+ end
+
+ for i = end_ + 1, #buffer_lines do
+ table.insert(result, buffer_lines[i])
+ end
+
+ return result
+end
+
+return M