diff options
author | Matěj Cepl <mcepl@cepl.eu> | 2023-03-17 13:46:55 +0100 |
---|---|---|
committer | Matěj Cepl <mcepl@cepl.eu> | 2023-03-17 13:46:55 +0100 |
commit | 5c29c9df1c94873f924b8b8396c61c7814ce7c6c (patch) | |
tree | 4fd3a780c49004e461d75e4b3485be73408441af | |
parent | 56db06a6005da8903ca246d3c283153f0c721b00 (diff) | |
download | vim-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.lua | 34 | ||||
-rw-r--r-- | ftplugin/hunk_spec.lua | 46 |
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) |