aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2023-03-17 13:46:55 +0100
committerMatěj Cepl <mcepl@cepl.eu>2023-03-17 13:46:55 +0100
commit5c29c9df1c94873f924b8b8396c61c7814ce7c6c (patch)
tree4fd3a780c49004e461d75e4b3485be73408441af
parent56db06a6005da8903ca246d3c283153f0c721b00 (diff)
downloadvim-diff_navigator-5c29c9df1c94873f924b8b8396c61c7814ce7c6c.tar.gz
First working version of hunk module.
Parsing works, module function createHunkHeader works as well, and both tested on the good path.
-rw-r--r--ftplugin/diff_navigator.lua (renamed from ftplugin/diff_navigator.lua.new)80
-rw-r--r--ftplugin/hunk.lua34
-rw-r--r--ftplugin/hunk_spec.lua46
3 files changed, 108 insertions, 52 deletions
diff --git a/ftplugin/diff_navigator.lua.new b/ftplugin/diff_navigator.lua
index 96f09da..f2b5e0d 100644
--- a/ftplugin/diff_navigator.lua.new
+++ b/ftplugin/diff_navigator.lua
@@ -64,6 +64,8 @@ local function checkFilterDiff()
return true
end
+local hnk = require('hunk')
+
-- Given the linenumber of the hunk returned its parsed content
--
-- From http://www.clearchain.com/blog/posts/splitting-a-patch
@@ -78,24 +80,6 @@ end
-- hunk (this includes lines marked with "-")
-- the third number is the starting line for this hunk in newfile
-- the last number is the number of lines after the hunk has been applied.
-function parseHunkHeader(lineno)
- local inline = vim.fn.getline(lineno)
- -- Thanks to somian from #vim IRC channel for this incredible RE
- local hunk_nos = vim.fn.substitute(inline,
- '\\_^\\S\\S\\s\\+-\\(\\d\\+\\),\\(\\d\\+\\)\\s\\++\\(\\d\\+\\),\\(\\d\\+\\)\\s\\+\\S\\S\\(\\_.*\\)',
- "\\\\1,\\\\2,\\\\3,\\\\4,\\\\5","")
- local result = hunk_nos:split(",")
-
- return {
- ['line'] = lineno,
- ['oldFirst'] = result[1],
- ['oldCount'] = result[2],
- ['newFirst'] = result[3],
- ['newCount'] = result[4],
- ['remainderLine'] = table.concat(result, ",", 5)
- }
-end
-
-- vim.api.nvim_eval('"README.md" =~ glob2regpat("/home/nvim/*.md")') ~= 0
-- is equivalent of
-- "README.md" =~ glob2regpat("/home/nvim/*.md")
@@ -109,13 +93,7 @@ function getCurrentHunkHeader()
lineno = vim.fn.search('^@@[ +-\\,\\d]*@@.*$', 'bncW')
end
- return parseHunkHeader(lineno)
-end
-
--- Generate hunk header line
-function createHunkHeader(oldStart, oldLen, newStart, newLen, remaind)
- return "@@ -" .. oldStart .. "," .. oldLen ..
- " +" .. newStart .. "," .. newLen .. " @@" .. remaind
+ return hnk.Header.parse(vim.fn.getline(lineno), lineno)
end
-- Return number of lines in the range between start and end line (both
@@ -156,9 +134,7 @@ function DiffShowHunk()
-- if the current line begins with '+++' or '---', then it makes
-- sense to search forwards
local hunk_header = getCurrentHunkHeader()
- local hunk_annotation = vim.fn.substitute(vim.fn.getline(hunk_header['line']),
- '^@@[ +-\\,\\d]*@@\\s*\\(.*\\)$', '\\1', '')
- print(hunk_annotation)
+ print(hunk_header.remainderLine)
end
-- Skip to next hunk
@@ -228,7 +204,7 @@ function DiffSplitHunk()
local new_start_del_len = diff_old
local new_start_add_start = old_cur_header['newFirst']
local new_start_add_len = diff_new
- vim.fn.setreg('x', createHunkHeader(new_start_del_start, new_start_del_len,
+ vim.fn.setreg('x', hnk.createHunkHeader(new_start_del_start, new_start_del_len,
new_start_add_start, new_start_add_len,
old_cur_header['remainderLine']))
local window_state = vim.cmd.winsaveview()
@@ -244,7 +220,7 @@ function DiffSplitHunk()
local new_pos_del_len = old_cur_header['oldCount'] - diff_old
local new_pos_add_start = old_cur_header['newFirst'] + diff_new
local new_pos_add_len = old_cur_header['newCount'] - diff_new
- vim.fn.setreg('x', createHunkHeader(new_pos_del_start, new_pos_del_len,
+ vim.fn.setreg('x', hnk.createHunkHeader(new_pos_del_start, new_pos_del_len,
new_pos_add_start, new_pos_add_len, ""))
vim.cmd('normal! O<Esc>\"xP')
end
@@ -286,7 +262,7 @@ function DiffDeleteHunk()
-- recalculate current hunk header
while (not last_hunk_in_file) do
- local cur_header = parseHunkHeader(vim.fn.line("."))
+ 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 .. ",",
@@ -307,25 +283,25 @@ function DiffDeleteHunk()
vim.fn.setpos(".", {0, new_header_line, 1, 0})
end
end
-
--- -- Define new commands
-vim.cmd('command DiffAnnotate DiffAnnotate()')
-vim.cmd('command DiffShowHunk DiffShowHunk()')
-vim.cmd('command DiffNextHunk DiffNextHunk()')
-vim.cmd('command DiffPrevHunk DiffPrevHunk()')
-vim.cmd('command DiffNextFile DiffNextFile()')
-vim.cmd('command DiffPrevFile DiffPrevFile()')
-vim.cmd('command DiffSplitHunk DiffSplitHunk()')
-vim.cmd('command DiffDeleteHunk DiffDeleteHunk()')
--
-
--- Default },{,(,) do not make much sense in diffs, so remap them to
--- make something useful
-vim.keymap.set('n', '<Leader>ex3', vim.treesitter.start)
-vim.keymap.set('n', '}', DiffNextFile)
-vim.keymap.set('n', '{', DiffPrevFile)
-vim.keymap.set('n', ')', DiffNextHunk)
-vim.keymap.set('n', '(', DiffPrevHunk)
-vim.keymap.set('n', '!', DiffShowHunk)
-vim.keymap.set('n', '<leader>s', DiffSplitHunk)
-vim.keymap.set('n', '<leader>s', DiffDeleteHunk)
+-- -- -- Define new commands
+-- vim.cmd('command DiffAnnotate DiffAnnotate()')
+-- vim.cmd('command DiffShowHunk DiffShowHunk()')
+-- vim.cmd('command DiffNextHunk DiffNextHunk()')
+-- vim.cmd('command DiffPrevHunk DiffPrevHunk()')
+-- vim.cmd('command DiffNextFile DiffNextFile()')
+-- vim.cmd('command DiffPrevFile DiffPrevFile()')
+-- vim.cmd('command DiffSplitHunk DiffSplitHunk()')
+-- vim.cmd('command DiffDeleteHunk DiffDeleteHunk()')
+-- --
+--
+-- -- Default },{,(,) do not make much sense in diffs, so remap them to
+-- -- make something useful
+-- vim.keymap.set('n', '<Leader>ex3', vim.treesitter.start)
+-- vim.keymap.set('n', '}', DiffNextFile)
+-- vim.keymap.set('n', '{', DiffPrevFile)
+-- vim.keymap.set('n', ')', DiffNextHunk)
+-- vim.keymap.set('n', '(', DiffPrevHunk)
+-- vim.keymap.set('n', '!', DiffShowHunk)
+-- vim.keymap.set('n', '<leader>s', DiffSplitHunk)
+-- vim.keymap.set('n', '<leader>s', DiffDeleteHunk)
diff --git a/ftplugin/hunk.lua b/ftplugin/hunk.lua
new file mode 100644
index 0000000..c01e0a9
--- /dev/null
+++ b/ftplugin/hunk.lua
@@ -0,0 +1,34 @@
+-- TODO: show current hunk in status line
+-- TODO: incorporate more patchutils functionality
+
+-- FIXME https://www.reddit.com/r/neovim/comments/unwvkw/github_hkuptyrunesnvim_lua_test_framework_for/
+-- FIXME https://github.com/hkupty/runes.nvim
+
+pretty = require("pl.pretty")
+
+local M = {}
+
+-- Header object
+M.Header = {}
+
+function M.Header:parse(inline, lineNo)
+ local pat = "@@%s+%-(%d+),(%d+)%s+%+(%d+),(%d+)%s+@@%s*(.*)"
+ local of, oc, nf, nc, rem = inline:match(pat)
+
+ return {
+ line = lineNo,
+ oldFirst = tonumber(of),
+ oldCount = tonumber(oc),
+ newFirst = tonumber(nf),
+ newCount = tonumber(nc),
+ remainderLine = rem
+ }
+end
+
+-- Generate hunk header line
+function M.createHunkHeader(oldStart, oldLen, newStart, newLen, remaind)
+ return "@@ -" .. oldStart .. "," .. oldLen ..
+ " +" .. newStart .. "," .. newLen .. " @@ " .. remaind
+end
+
+return M
diff --git a/ftplugin/hunk_spec.lua b/ftplugin/hunk_spec.lua
new file mode 100644
index 0000000..c640afb
--- /dev/null
+++ b/ftplugin/hunk_spec.lua
@@ -0,0 +1,46 @@
+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"
+ end)
+
+ before_each(function()
+ header = hk.Header:parse(test_header)
+ end)
+
+ it("it is not nil", function()
+ assert.is_not_nil(header)
+ end)
+
+ 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)
+ end)
+
+ it("attributes are set correctly", function()
+ assert.are.equal(20, header.oldFirst)
+ assert.are.equal(8, header.oldCount)
+ assert.are.equal(20, header.newFirst)
+ assert.are.equal(17, header.newCount)
+ end)
+
+ it("remainder of the line is preserved as well", function()
+ assert.are.equal("Hunk #1, a/tests/test_ec_curves.py", header.remainderLine)
+ end)
+end)
+
+describe("Class functions", function()
+ local hk, header, test_header
+
+ setup(function()
+ hk = require("hunk")
+ end)
+
+ it("generates correct header", function()
+ local header_str = hk.createHunkHeader(12,15,25,30,"something")
+ local exp_str = "@@ -12,15 +25,30 @@ something"
+ assert.are.equal(exp_str, header_str)
+ end)
+end)