From: J. Paulo Seibt Date: Wed, 10 Jun 2026 21:07:31 +0000 (+0000) Subject: patch 9.2.0620: runtime(netrw): fix 2match pattern rebuild X-Git-Tag: v9.2.0620^0 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=affd4b5964f0ff10a4a39a93ddf46ad8bd537d1b;p=thirdparty%2Fvim.git patch 9.2.0620: runtime(netrw): fix 2match pattern rebuild Problem: unmarking a regular file when there are directories in the markings list also removes the 2match highlight from those directories. Solution: correctly rebuild the match pattern from the remaining markings, using the right regex trailer for each entry in the list. closes: #20461 Signed-off-by: J. Paulo Seibt Signed-off-by: Christian Brabandt --- diff --git a/runtime/pack/dist/opt/netrw/autoload/netrw.vim b/runtime/pack/dist/opt/netrw/autoload/netrw.vim index f555d66317..fe8d3f11ff 100644 --- a/runtime/pack/dist/opt/netrw/autoload/netrw.vim +++ b/runtime/pack/dist/opt/netrw/autoload/netrw.vim @@ -1,7 +1,7 @@ " Creator: Charles E Campbell " Previous Maintainer: Luca Saccarola " Maintainer: This runtime file is looking for a new maintainer. -" Last Change: 2026 May 28 +" Last Change: 2026 Jun 10 " Copyright: Copyright (C) 2016 Charles E. Campbell {{{1 " Permission is hereby granted to use and distribute this code, " with or without modifications, provided that this copyright @@ -5172,7 +5172,7 @@ endfunction " s:netrwmarkfilelist_# -- holds list of marked files in current-buffer's directory (#==bufnr()) " " Creates a marked file match string -" s:netrwmarfilemtch_# -- used with 2match to display marked files +" s:netrwmarkfilemtch_# -- used with 2match to display marked files " " Creates a buffer version of islocal " b:netrw_islocal @@ -5184,23 +5184,21 @@ function s:NetrwMarkFile(islocal,fname) endif let curdir = s:NetrwGetCurdir(a:islocal) - let ykeep = @@ - let curbufnr= bufnr("%") - let leader= '\%(^\|\s\)\zs' - if a:fname =~ '\a$' - let trailer = '\>[@=|\/\*]\=\ze\%( \|\t\|$\)' - else - let trailer = '[@=|\/\*]\=\ze\%( \|\t\|$\)' - endif + let ykeep = @@ + let curbufnr = bufnr("%") + let leader = '\%(^\|\s\)\zs' + let word_boundary_trailer = '\>[@=|\/\*]\=\ze\%( \|\t\|$\)' + let fallback_trailer = '[@=|\/\*]\=\ze\%( \|\t\|$\)' + let trailer = (a:fname =~ '\a$') ? word_boundary_trailer : fallback_trailer if exists("s:netrwmarkfilelist_".curbufnr) " markfile list pre-exists - let b:netrw_islocal= a:islocal + let b:netrw_islocal = a:islocal if index(s:netrwmarkfilelist_{curbufnr},a:fname) == -1 " append filename to buffer's markfilelist - call add(s:netrwmarkfilelist_{curbufnr},a:fname) - let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer + call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','','')) + let s:netrwmarkfilemtch_{curbufnr} = s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(a:fname,g:netrw_markfileesc).trailer else " remove filename from buffer's markfilelist @@ -5210,35 +5208,34 @@ function s:NetrwMarkFile(islocal,fname) call s:NetrwUnmarkList(curbufnr,curdir) else " rebuild match list to display markings correctly - let s:netrwmarkfilemtch_{curbufnr}= "" - let first = 1 + let s:netrwmarkfilemtch_{curbufnr} = "" + let first = 1 for fname in s:netrwmarkfilelist_{curbufnr} + let curtrailer = (fname =~ '\a$') ? word_boundary_trailer : fallback_trailer + + let match_str = leader.escape(fname, g:netrw_markfileesc).curtrailer if first - let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.leader.escape(fname,g:netrw_markfileesc).trailer + let s:netrwmarkfilemtch_{curbufnr} = match_str else - let s:netrwmarkfilemtch_{curbufnr}= s:netrwmarkfilemtch_{curbufnr}.'\|'.leader.escape(fname,g:netrw_markfileesc).trailer + let s:netrwmarkfilemtch_{curbufnr} = s:netrwmarkfilemtch_{curbufnr}.'\|'.match_str endif - let first= 0 + let first = 0 endfor endif endif else " initialize new markfilelist - let s:netrwmarkfilelist_{curbufnr}= [] + let s:netrwmarkfilelist_{curbufnr} = [] call add(s:netrwmarkfilelist_{curbufnr},substitute(a:fname,'[|@]$','','')) " build initial markfile matching pattern - if a:fname =~ '/$' - let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc) - else - let s:netrwmarkfilemtch_{curbufnr}= leader.escape(a:fname,g:netrw_markfileesc).trailer - endif + let s:netrwmarkfilemtch_{curbufnr} = leader.escape(a:fname,g:netrw_markfileesc).trailer endif " handle global markfilelist if exists("s:netrwmarkfilelist") - let dname= netrw#fs#ComposePath(b:netrw_curdir,a:fname) + let dname = netrw#fs#ComposePath(b:netrw_curdir,a:fname) if index(s:netrwmarkfilelist,dname) == -1 " append new filename to global markfilelist call add(s:netrwmarkfilelist,netrw#fs#ComposePath(b:netrw_curdir,a:fname)) @@ -5251,7 +5248,7 @@ function s:NetrwMarkFile(islocal,fname) endif else " initialize new global-directory markfilelist - let s:netrwmarkfilelist= [] + let s:netrwmarkfilelist = [] call add(s:netrwmarkfilelist,netrw#fs#ComposePath(b:netrw_curdir,a:fname)) endif diff --git a/src/testdir/test_plugin_netrw.vim b/src/testdir/test_plugin_netrw.vim index 22477c68a8..0cb0c38da6 100644 --- a/src/testdir/test_plugin_netrw.vim +++ b/src/testdir/test_plugin_netrw.vim @@ -172,6 +172,30 @@ function Test_MakeBookmark(netrw_curdir, fname) call s:MakeBookmark(a:fname) bw endfunction + +" Test the markings match pattern rebuilt by s:NetrwMarkFile() when unmarking an entry +function Test_NetrwMarkFile_match_pattern_rebuild() + new + let curbufnr = bufnr("%") + + call s:NetrwMarkFile(1, 'fname_dir/') + call s:NetrwMarkFile(1, 'fname_file') + let match_pattern = s:netrwmarkfilemtch_{curbufnr} + + " Assert match pattern after marking and unmarking a directory entry + call s:NetrwMarkFile(1, 'dir/') + call s:NetrwMarkFile(1, 'dir/') + let rebuilt_match_pattern = s:netrwmarkfilemtch_{curbufnr} + call assert_equal(match_pattern, rebuilt_match_pattern) + + " Assert match pattern after marking and unmarking a file entry + call s:NetrwMarkFile(1, 'file') + call s:NetrwMarkFile(1, 'file') + let rebuilt_match_pattern = s:netrwmarkfilemtch_{curbufnr} + call assert_equal(match_pattern, rebuilt_match_pattern) + + bw +endfunction " }}} END @@ -765,6 +789,10 @@ func Test_netrw_bookmark_goto_delete_prompt() bw! endfunc +func Test_netrw_markings_match_pattern_rebuild() + call Test_NetrwMarkFile_match_pattern_rebuild() +endfunc + func Test_netrw_mf_command_injection() CheckUnix CheckExecutable touch diff --git a/src/version.c b/src/version.c index 9159626e38..8538d4ed35 100644 --- a/src/version.c +++ b/src/version.c @@ -754,6 +754,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 620, /**/ 619, /**/