diff options
| author | Josh Rahm <rahm@josher.dev> | 2026-08-11 11:19:05 -0600 |
|---|---|---|
| committer | Josh Rahm <rahm@josher.dev> | 2026-08-11 11:19:05 -0600 |
| commit | d7829c069b09d2115daa1aa33a729dd9ffee301e (patch) | |
| tree | 4b4845c79c0df4b3879249e83ebbea44239f5cef /lua/hobs/util.lua | |
| parent | d2eadb42ffde7f07b4c2d46efc3724d565ec8255 (diff) | |
| download | hobs.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.lua | 101 |
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 |