diff options
author | Matěj Cepl <mcepl@redhat.com> | 2013-09-05 15:22:33 +0200 |
---|---|---|
committer | Matěj Cepl <mcepl@cepl.eu> | 2015-02-06 13:16:39 +0100 |
commit | e4d9685d577ef361d3ea073de129ceea98fb9194 (patch) | |
tree | 6637e6a60356cc8dbd4bbc8b18a3387a2c87c259 | |
parent | ab18682faed46e837e1bf2919d6b0d6b977e1b32 (diff) | |
download | vim-diff_navigator-e4d9685d577ef361d3ea073de129ceea98fb9194.tar.gz |
Add DiffSplitHunk function.
Splits the hunk in which the cursor is making sure that all surrounding
hunk headers are correct (i.e., adjusts the original hunk header).
10 files changed, 430 insertions, 61 deletions
diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/body b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/body new file mode 100644 index 0000000..8a9959a --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/body @@ -0,0 +1,4 @@ +Something similar to what Emacs EDiff does. +Also it should be possible to use splitdiff? +(Although it is rather brutal ... we want one diff, +not messy temp files all around) diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/values b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/values new file mode 100644 index 0000000..3a56077 --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/2734cfa4-242a-4b3a-8141-3251b444d3f3/values @@ -0,0 +1,29 @@ +{ + + + + + + + "Author": "Mat\u011bj Cepl <mcepl@redhat.com>", + + + + + + + "Content-type": "text/plain", + + + + + + + "Date": "Thu, 05 Sep 2013 13:06:37 +0000" + + + + + + +} diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/body b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/body new file mode 100644 index 0000000..eb57f47 --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/body @@ -0,0 +1,5 @@ +Splitdiff is a bad idea ... splits just on the level of files, not +hunks. + +For more information about the format, see +https://en.wikipedia.org/wiki/Diff#Unified_format diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/values b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/values new file mode 100644 index 0000000..5139834 --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/comments/33c92587-7117-40d5-be4a-6241ce251d75/values @@ -0,0 +1,29 @@ +{ + + + + + + + "Author": "Mat\u011bj Cepl <mcepl@redhat.com>", + + + + + + + "Content-type": "text/plain", + + + + + + + "Date": "Thu, 05 Sep 2013 13:22:15 +0000" + + + + + + +} diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/values b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/values new file mode 100644 index 0000000..71bc97b --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/bugs/ca31d12d-ef83-4275-a364-7802b2ad35b0/values @@ -0,0 +1,50 @@ +{ + + + + + + + "creator": "Mat\u011bj Cepl <mcepl@redhat.com>", + + + + + + + "reporter": "Mat\u011bj Cepl <mcepl@redhat.com>", + + + + + + + "severity": "minor", + + + + + + + "status": "open", + + + + + + + "summary": "Split patch", + + + + + + + "time": "Thu, 05 Sep 2013 13:05:53 +0000" + + + + + + +} diff --git a/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/settings b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/settings new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/.be/737c1d14-cca7-4efd-be60-fca75b19ef73/settings @@ -0,0 +1 @@ +{} diff --git a/.be/version b/.be/version new file mode 100644 index 0000000..38d39ae --- /dev/null +++ b/.be/version @@ -0,0 +1 @@ +Bugs Everywhere Directory v1.5 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..55292ee --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.be/id-cache diff --git a/ftplugin/diff_navigator.vim b/ftplugin/diff_navigator.vim index fa4f5b1..81eed48 100644 --- a/ftplugin/diff_navigator.vim +++ b/ftplugin/diff_navigator.vim @@ -23,84 +23,223 @@ " Only do this when not done yet for this buffer +" Usually, not needed, just for the keeping normal API if exists("b:did_ftplugin") finish endif let b:did_ftplugin = 1 -" Annotate each hunk with it's number and name of the changed file -if !exists("*s:DiffAnnotate") - function s:DiffAnnotate() - if !executable('filterdiff') - echohl WarningMsg - echo "You need to install filterdiff first (part of patchutils)" - echohl None - return - endif - let l:cursorpos = winsaveview() - %!filterdiff --annotate - call winrestview(cursorpos) - endfunction +" Load this plugin only once +if exists("g:loaded_diff_navigator") + finish endif +let g:loaded_diff_navigator = 1 + +function s:checkFilterDiff() + if !executable('filterdiff') + echohl WarningMsg + echo "You need to install filterdiff first (part of patchutils)" + echohl None + return 0 + endif + return 1 +endfunction + +" Given the linenumber of the hunk returned its parsed content +" +" From http://www.clearchain.com/blog/posts/splitting-a-patch +" ----------------------------------------------------------- +" +" here’s at least some info about the format of a patch file. +" +" @@ -143,6 +143,13 @@ +" +" the first number is the starting line for this hunk in oldfile +" the second number is the number of original source lines in this +" 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 s:parseHunkHeader(lineno) + let inline = getline(a:lineno) + " Thanks for somian from #vim IRC channel for this incredible RE + let hunk_nos = substitute(inline, + \ '\_^\S\S\s\+-\(\d\+\),\(\d\+\)\s\++\(\d\+\),\(\d\+\)\s\+\S\S\(\_.*\)', + \ "\\1,\\2,\\3,\\4,\\5","") + let result = split(hunk_nos, ",") + + return { + \ 'line': a:lineno, + \ 'oldFirst': result[0], + \ 'oldCount': result[1], + \ 'newFirst': result[2], + \ 'newCount': result[3], + \ 'remainderLine': result[4] + \ } +endfunction + +" Get hunk header from the hunk surrounding cursor +function s:getCurrentHunkHeader() + if getline(".") =~ '^+++ \|^--- ' + let lineno = search('^@@[ +-\,\d]*@@.*$', 'ncW') + else + let lineno = search('^@@[ +-\,\d]*@@.*$', 'bncW') + endif + + return s:parseHunkHeader(lineno) +endfunction + +" Generate hunk header line +function s:createHunkHeader(oldStart, oldLen, newStart, newLen, remaind) + return "@@ -" . a:oldStart . "," . a:oldLen . + \ " +" . a:newStart . "," . a:newLen . " @@" . a:remaind +endfunction + +" 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 s:countLines(start, end) + let context_lines = 0 + let old_lines = 0 + let new_lines = 0 + + for line in getline(a:start, a:end) + let first_char = strpart(line, 0, 1) + if first_char == ' ' + context_lines += 1 + elseif first_char == '-' + old_lines += 1 + elseif first_char == '+' + new_lines += 1 + else + endif + endfor + + return [context_lines + old_lines, context_lines + new_lines] +endfunction + +" ------------------------------------------------------------- + +" Annotate each hunk with it's number and name of the changed file +function s:DiffAnnotate() + if s:checkFilterDiff() + let l:cursorpos = winsaveview() + %!filterdiff --annotate + call winrestview(cursorpos) + endif +endfunction " Print annotation of current hunk -if !exists("*s:DiffShowHunk") - function s:DiffShowHunk() - " if the current line begins with '+++' or '---', then it makes sense to search - " forwards - if getline(".") =~ '^+++ \|^--- ' - let l:lineno = search('^@@[ +-\,\d]*@@.*$', 'ncW') - else - let l:lineno = search('^@@[ +-\,\d]*@@.*$', 'bncW') - endif - if l:lineno == 0 - return - endif - let l:hunk_annotation = substitute(getline(lineno), '^@@[ +-\,\d]*@@\s*\(.*\)$', '\1', '') - echo l:hunk_annotation - endfunction -endif +function s:DiffShowHunk() + " if the current line begins with '+++' or '---', then it makes + " sense to search forwards + let hunk_header = s:getCurrentHunkHeader() + let l:hunk_annotation = substitute(getline(hunk_header['line']), + \ '^@@[ +-\,\d]*@@\s*\(.*\)$', '\1', '') + echo l:hunk_annotation +endfunction " Skip to next hunk -if !exists("*s:DiffNextHunk") - function s:DiffNextHunk() - call search('^@@[ +-\,\d]*@@', 'sW') - endfunction -endif +function s:DiffNextHunk() + call search('^@@[ +-\,\d]*@@', 'sW') +endfunction " Skip to previous hunk -if !exists("*s:DiffPrevHunk") - function s:DiffPrevHunk() - call search('^@@[ +-\,\d]*@@', 'bsW') - endfunction -endif +function s:DiffPrevHunk() + call search('^@@[ +-\,\d]*@@', 'bsW') +endfunction " Skip to next changed file -if !exists("*s:DiffNextFile") - function s:DiffNextFile() - call search('^--- ', 'sW') - endfunction -endif +function s:DiffNextFile() + call search('^--- ', 'sW') +endfunction -" Skip to previous changed file -if !exists("*s:DiffPrevFile") - function s:DiffPrevFile() - call search('^--- ', 'bsW') - endfunction -endif +" Skip to previous changed file +function s:DiffPrevFile() + call search('^--- ', 'bsW') +endfunction + +function s:DiffSplitHunk() + let old_cur_header = s:getCurrentHunkHeader() + let cur_line_no = line(".") + + " With this hunk: + " + " @@ -20,8 +20,17 @@ Hunk #1, a/tests/test_ec_curves.py + " + " import unittest + " #import sha + " -from M2Crypto import EC, Rand + " -from test_ecdsa import ECDSATestCase as ECDSATest + " +try: + " + from M2Crypto import EC, Rand +"-- " + from test_ecdsa import ECDSATestCase as ECDSATest + " +# AttributeError: 'module' object has no attribute 'ec_init' + " +#except AttributeError: + " +except: + " + EC_Module_Available = False + " + print("No EC modules available") + " +else: + " + EC_Module_Available = True + " + print("EC modules are available") + " + " creates above the line + " @@ -25,3 +25,12 @@ + " + " and the original hunk line is now + " @@ -20,5 +20,5 @@ Hunk #1, a/tests/test_ec_curves.py + " + " + " Start line below header and stop one line above the current line + let diff_lines = s:countLines(old_cur_header['line'] + 1, + \ cur_line_no - 1) + let diff_old = diff_lines[0] + let diff_new = diff_lines[1] + + " IN THE NEW START HUNK HEADER + " 1. length is number of lines above the current position which + " are either context or deleted lines (-) + " 2. length is number of lines above the current position which + " are either context or added lines (+) + " Start positions are same as well the stuff after the second @@ + let new_start_del_start = old_cur_header['oldFirst'] + let new_start_del_len = diff_old + let new_start_add_start = old_cur_header['newFirst'] + let new_start_add_len = diff_new + let @x = s:createHunkHeader(new_start_del_start, new_start_del_len, + \ new_start_add_start, new_start_add_len, + \ old_cur_header['remainderLine']) + let window_state = winsaveview() + " write the new original header line + setpos(".", old_cur_header['line']) + normal ^d$"xp + winrestview(window_state) -command! -buffer DiffAnnotate call s:DiffAnnotate() -command! -buffer DiffShowHunk call s:DiffShowHunk() -command! -buffer DiffNextHunk call s:DiffNextHunk() -command! -buffer DiffPrevHunk call s:DiffPrevHunk() -command! -buffer DiffNextFile call s:DiffNextFile() -command! -buffer DiffPrevFile call s:DiffPrevFile() + " IN THE NEW HUNK HEADER + " new lengths = original len - new len + " new starts = original start + (difference) + let new_pos_del_start = old_cur_header['oldFirst'] + diff_old + let new_pos_del_len = old_cur_header['oldCount'] - diff_old + let new_pos_add_start = old_cur_header['newFirst'] + diff_new + let new_pos_add_len = old_cur_header['newCount'] - diff_new + let @x = s:createHunkHeader(new_pos_del_start, new_pos_del_len, + \ new_pos_add_start, new_pos_add_len, "") + execute "normal! O\<Esc>\"xP" + +endfunction + +" Define new commands +command DiffAnnotate call s:DiffAnnotate() +command DiffShowHunk call s:DiffShowHunk() +command DiffNextHunk call s:DiffNextHunk() +command DiffPrevHunk call s:DiffPrevHunk() +command DiffNextFile call s:DiffNextFile() +command DiffPrevFile call s:DiffPrevFile() " Default },{,(,) do not make much sense in diffs, so remap them to " make something useful -nnoremap <buffer> } :DiffNextFile<CR> -nnoremap <buffer> { :DiffPrevFile<CR> -nnoremap <buffer> ) :DiffNextHunk<CR> -nnoremap <buffer> ( :DiffPrevHunk<CR> - +nnoremap <script> } :call <SID>DiffNextFile()<CR> +nnoremap <script> { :call <SID>DiffPrevFile()<CR> +nnoremap <script> ) :call <SID>DiffNextHunk()<CR> +nnoremap <script> ( :call <SID>DiffPrevHunk()<CR> +nnoremap <script> ! :call <SID>DiffShowHunk()<CR> diff --git a/test.patch b/test.patch new file mode 100644 index 0000000..63084cb --- /dev/null +++ b/test.patch @@ -0,0 +1,110 @@ +--- a/tests/test_ec_curves.py ++++ b/tests/test_ec_curves.py +@@ -20,8 +20,17 @@ Hunk #1, a/tests/test_ec_curves.py + + import unittest + #import sha +-from M2Crypto import EC, Rand +-from test_ecdsa import ECDSATestCase as ECDSATest ++try: ++ from M2Crypto import EC, Rand ++ from test_ecdsa import ECDSATestCase as ECDSATest ++# AttributeError: 'module' object has no attribute 'ec_init' ++#except AttributeError: ++except: ++ EC_Module_Available = False ++ print("No EC modules available") ++else: ++ EC_Module_Available = True ++ print("EC modules are available") + + + curves = [ +@@ -108,6 +117,9 @@ Hunk #2, a/tests/test_ec_curves.py curves = [ + # ('ipsec4', 185), + #] + ++ ++@unittest.skipUnless(EC_Module_Available, ++ 'Requires EC modules compiled into OpenSSL') + class ECCurveTests(unittest.TestCase): + #data = sha.sha('Kilroy was here!').digest() # 160 bits + data = "digest" # keep short (48 bits) so lesser curves +@@ -153,7 +165,8 @@ Hunk #3, a/tests/test_ec_curves.py def suite(): + + + if __name__ == '__main__': +- Rand.load_file('randpool.dat', -1) ++ print("EC_Module_Available = %s" % EC_Module_Available) ++ Rand.load_file('randpool.dat', -1) + unittest.TextTestRunner().run(suite()) + Rand.save_file('randpool.dat') + +--- a/tests/test_ecdh.py ++++ b/tests/test_ecdh.py +@@ -8,9 +8,20 @@ Hunk #1, a/tests/test_ecdh.py Portions copyright (c) 2005-2006 Vrije U + + + import unittest +-from M2Crypto import EC, BIO, Rand, m2 + import sys ++try: ++ from M2Crypto import EC, BIO, Rand, m2 ++# AttributeError: 'module' object has no attribute 'ec_init' ++except: ++ EC_Module_Available = False ++ print("No EC modules available") ++else: ++ EC_Module_Available = True ++ print("EC modules are available") + ++ ++@unittest.skipUnless(EC_Module_Available, ++ 'Requires EC modules compiled into OpenSSL') + class ECDHTestCase(unittest.TestCase): + + privkey = 'tests/ec.priv.pem' +@@ -43,7 +54,8 @@ Hunk #2, a/tests/test_ecdh.py def suite(): + + + if __name__=='__main__': +- Rand.load_file('randpool.dat', -1) ++ print("EC_Module_Available = %s" % EC_Module_Available) ++ Rand.load_file('randpool.dat', -1) + unittest.TextTestRunner().run(suite()) + Rand.save_file('randpool.dat') + +--- a/tests/test_ecdsa.py ++++ b/tests/test_ecdsa.py +@@ -8,8 +8,20 @@ Hunk #1, a/tests/test_ecdsa.py Portions copyright (c) 2005-2006 Vrije U + + import unittest + import sha +-from M2Crypto import EC, BIO, Rand, m2 ++try: ++ from M2Crypto import EC, BIO, Rand, m2 ++# AttributeError: 'module' object has no attribute 'ec_init' ++#except AttributeError: ++except: ++ EC_Module_Available = False ++ print("No EC modules available") ++else: ++ EC_Module_Available = True ++ print("EC modules are available") + ++ ++@unittest.skipUnless(EC_Module_Available, ++ 'Requires EC modules compiled into OpenSSL') + class ECDSATestCase(unittest.TestCase): + + errkey = 'tests/rsa.priv.pem' +@@ -69,7 +81,8 @@ Hunk #2, a/tests/test_ecdsa.py def suite(): + + + if __name__ == '__main__': +- Rand.load_file('randpool.dat', -1) ++ print("EC_Module_Available = %s" % EC_Module_Available) ++ Rand.load_file('randpool.dat', -1) + unittest.TextTestRunner().run(suite()) + Rand.save_file('randpool.dat') + |