aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2023-03-25 13:36:20 +0100
committerMatěj Cepl <mcepl@cepl.eu>2023-03-25 13:42:49 +0100
commit3f1d8238e88a3f55dd6e34e9023c9ab1aa44ffaf (patch)
tree23ec74b12d0a9cde06c250e5e34175818b4e0fe3
parentbc17b1a4318ac5de88c2024eb48252a5da14799c (diff)
downloadvim-diff_navigator-3f1d8238e88a3f55dd6e34e9023c9ab1aa44ffaf.tar.gz
Hide vis/vim complexity behind getline shim.
-rw-r--r--ftplugin/diff_navigator.lua26
-rw-r--r--ftplugin/hunk.lua42
-rw-r--r--ftplugin/hunk_spec.lua20
3 files changed, 65 insertions, 23 deletions
diff --git a/ftplugin/diff_navigator.lua b/ftplugin/diff_navigator.lua
index c36cfab..d0789d9 100644
--- a/ftplugin/diff_navigator.lua
+++ b/ftplugin/diff_navigator.lua
@@ -42,14 +42,6 @@ vim.g.loaded_diff_navigator = 1
-- Utility functions
--- from http://lua-users.org/wiki/SplitJoin
-local split = function(self, sep)
- local sep, fields = sep or ":", {}
- local pattern = string.format("([^%s]+)", sep)
- self:gsub(pattern, function(c) fields[#fields+1] = c end)
- return fields
-end
-
local function executable(cmd)
-- calling /bin/sh -c even for users with default shells
-- which are not POSIX compatible (squinting at fish)
@@ -87,13 +79,13 @@ local hnk = require('hunk')
-- Get hunk header from the hunk surrounding cursor
function getCurrentHunkHeader()
local lineno = 0
- if (vim.api.nvim_eval('getline(".") =~ "^+++ \\|^--- "') ~= 0) then
+ if (vim.api.nvim_eval(getline(".") .. ' =~ "^+++ \\|^--- "') ~= 0) then
lineno = vim.fn.search('^@@[ +-\\,\\d]*@@.*$', 'ncW')
else
lineno = vim.fn.search('^@@[ +-\\,\\d]*@@.*$', 'bncW')
end
- return hnk.Header.parse(vim.fn.getline(lineno), lineno)
+ return hnk.Header.parse(lineno)
end
@@ -169,7 +161,7 @@ function DiffSplitHunk()
--
-- Start line below header and stop one line above the current line
local diff_lines = hnk.countLines(old_cur_header['line'] + 1,
- cur_line_no - 1, vim.fn.getline)
+ cur_line_no - 1)
local diff_old = diff_lines[1]
local diff_new = diff_lines[2]
@@ -231,7 +223,7 @@ function DiffDeleteHunk()
-- we are in the middle of the file ... it's a bit more complicated
else
local count_lines = hnk.countLines(start_hunk_line + 1,
- next_hunk_line - 1, vim.fn.getline)
+ next_hunk_line - 1)
local added_lines = count_lines[2] - count_lines[1]
vim.fn.setpos(".", {0, next_hunk_line, 1, 0})
vim.cmd("normal " .. start_hunk_line .. "," .. (next_hunk_line - 1) .. "d")
@@ -244,16 +236,16 @@ function DiffDeleteHunk()
local cur_header = hnk.parse(vim.fn.line("."))
local old_line = cur_header['newFirst']
local new_line = old_line - added_lines
- vim.fn.setreg('x', vim.fn.substitute(vim.fn.getline("."), "+" .. old_line .. ",",
+ vim.fn.setreg('x', vim.fn.substitute(hnk.getline("."), "+" .. old_line .. ",",
"+" .. new_line .. ",", ""))
vim.cmd('normal ^d$"xp')
-- check the next hunk
- local next_hunk_line = vim.fn.search('\\_^@@[ +-\\,\\d]*@@\\_.*\\_$', 'nW')
- local start_of_next_file_line = vim.fn.search('^--- .*$', 'ncW')
+ next_hunk_line = vim.fn.search('\\_^@@[ +-\\,\\d]*@@\\_.*\\_$', 'nW')
+ start_of_next_file_line = vim.fn.search('^--- .*$', 'ncW')
if (start_of_next_file_line < next_hunk_line) then
- local next_hunk_line = start_of_next_file_line
- local last_hunk_in_file = 1
+ next_hunk_line = start_of_next_file_line
+ last_hunk_in_file = 1
end
vim.fn.setpos(".", {0, next_hunk_line, 1, 0})
end
diff --git a/ftplugin/hunk.lua b/ftplugin/hunk.lua
index db8ac06..d450cb6 100644
--- a/ftplugin/hunk.lua
+++ b/ftplugin/hunk.lua
@@ -11,8 +11,18 @@ local M = {}
-- Header object
M.Header = {}
-function M.Header:parse(inline, lineNo)
+function M.Header:parse(lineNo)
+ local inline
local pat = "@@%s+%-(%d+),(%d+)%s+%+(%d+),(%d+)%s+@@%s*(.*)"
+
+ if (lineNo == "." or type(lineNo) == "number") then
+ -- to convert lineNo into proper number, if it was "." originally
+ inline, lineNo = M.getline(lineNo)
+ else
+ inline = lineNo
+ lineNo = 0
+ end
+
local of, oc, nf, nc, rem = inline:match(pat)
return {
@@ -33,15 +43,41 @@ function M.createHunkHeader(oldStart, oldLen, newStart, newLen, remaind)
" +" .. newStart .. "," .. newLen .. " @@ " .. remaind
end
+-- Compatibility shim for getline()
+function M.getline(where, endWhere)
+ if vis ~= nil then
+ local win = vis.win
+ local line = where
+
+ if where == "." then
+ line = win.selection.line
+ end
+ if endWhere == nil then
+ return win.file.lines[line], line
+ end
+
+ -- now endWhere ~= nil and we need to return an array
+ local out = {}
+ for i=line, endWhere do
+ table.insert(out, win.file.lines[i])
+ end
+
+ return out, line
+ else
+ return vim.fn.getline(where), vim.fn.line(where)
+ end
+ end
+
+
-- Return number of lines in the range between start and end line (both
-- inclusive) which are from the state before patch and the one after
-- patch is applied.
-function M.countLines(start, endline, getlfn)
+function M.countLines(start, endline)
local context_lines = 0
local old_lines = 0
local new_lines = 0
- for line in pairs(getlfn(start, endline)) do
+ for line, _ in pairs(M.getline(start, endline)) do
local first_char = line:sub(1, 1)
if first_char == ' ' then
local context_lines = context_lines + 1
diff --git a/ftplugin/hunk_spec.lua b/ftplugin/hunk_spec.lua
index 13d14f3..75918bb 100644
--- a/ftplugin/hunk_spec.lua
+++ b/ftplugin/hunk_spec.lua
@@ -2,8 +2,15 @@ describe("Parsing of a hunk header", function()
local hk, header, test_header
setup(function()
- hk = require("hunk")
test_header = "@@ -20,8 +20,17 @@ Hunk #1, a/tests/test_ec_curves.py"
+ hk = require("hunk")
+ hk.old_getline = hk.getline
+ hk.getline = function(where) return test_header end
+ end)
+
+ teardown(function()
+ hk.getline = hk.old_getline
+ hk.old_getline = nil
end)
before_each(function()
@@ -16,7 +23,7 @@ describe("Parsing of a hunk header", function()
it("original line number is preserved in the attribute line", function()
-- not relevant here, because parse() method was run without line#
- assert.is_nil(header.line)
+ assert.is.equal(header.line, 0)
end)
it("attributes are set correctly", function()
@@ -36,6 +43,13 @@ describe("Class functions", function()
setup(function()
hk = require("hunk")
+ hk.old_getline = hk.getline
+ hk.getline = function(beg, fin) return {"a", "b"} end
+ end)
+
+ teardown(function()
+ hk.getline = hk.old_getline
+ hk.old_getline = nil
end)
-- TODO some protection of hk.createHunkHeader() against bad
@@ -48,7 +62,7 @@ describe("Class functions", function()
end)
it("counts lines in chunk correctly", function()
- local header_str = hk.countLines(12,15, function(beg, fin) return {} end)
+ -- local header_str = hk.countLines(12,15)
pending("This test is pending ...")
end)
end)