diff options
-rw-r--r-- | runtime/doc/news.txt | 2 | ||||
-rw-r--r-- | runtime/doc/options.txt | 2 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 2 | ||||
-rw-r--r-- | runtime/ftplugin/sh.vim | 17 | ||||
-rw-r--r-- | runtime/lua/vim/_editor.lua | 3 | ||||
-rw-r--r-- | src/nvim/eval.c | 2 | ||||
-rw-r--r-- | src/nvim/options.lua | 4 | ||||
-rw-r--r-- | src/nvim/window.c | 9 | ||||
-rw-r--r-- | test/functional/core/path_spec.lua | 40 | ||||
-rw-r--r-- | test/functional/lua/vim_spec.lua | 8 | ||||
-rw-r--r-- | test/old/testdir/setup.vim | 3 | ||||
-rw-r--r-- | test/old/testdir/test_fold.vim | 9 |
12 files changed, 84 insertions, 17 deletions
diff --git a/runtime/doc/news.txt b/runtime/doc/news.txt index f0d01f92e7..b0f3b76587 100644 --- a/runtime/doc/news.txt +++ b/runtime/doc/news.txt @@ -203,6 +203,8 @@ The following changes to existing APIs or features add new behavior. option, which allows for rendering e.g., diagnostic severities differently. • Defaults: + • On Windows 'isfname' does not include ":". Drive letters are handled + correctly without it. (Use |gF| for filepaths suffixed with ":line:col"). • 'comments' includes "fb:•". • 'shortmess' includes the "C" flag. • Automatic linting of treesitter query files (see |ft-query-plugin|). diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index bc207d7755..283c1e3612 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3453,7 +3453,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'isfname'* *'isf'* 'isfname' 'isf' string (default for Windows: - "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=" + "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],@-@,!,~,=" otherwise: "@,48-57,/,.,-,_,+,,,#,$,%,~,=") global The characters specified by this option are included in file names and diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index e9c04443a6..4161d3b21e 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -53,6 +53,8 @@ Defaults *nvim-defaults* - 'hlsearch' is enabled - 'include' defaults to "". The C ftplugin sets it to "^\\s*#\\s*include" - 'incsearch' is enabled +- 'isfname' does not include ":" (on Windows). Drive letters are handled + correctly without it. (Use |gF| for filepaths suffixed with ":line:col"). - 'joinspaces' is disabled - 'langnoremap' is enabled - 'langremap' is disabled diff --git a/runtime/ftplugin/sh.vim b/runtime/ftplugin/sh.vim index c227838d18..c1a6bc5ade 100644 --- a/runtime/ftplugin/sh.vim +++ b/runtime/ftplugin/sh.vim @@ -3,7 +3,8 @@ " Maintainer: Doug Kearns <dougkearns@gmail.com> " Previous Maintainer: Dan Sharp " Contributor: Enno Nagel <ennonagel+vim@gmail.com> -" Last Change: 2023 Aug 29 +" Eisuke Kawashima +" Last Change: 2023 Sep 28 if exists("b:did_ftplugin") finish @@ -39,16 +40,16 @@ if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter") let b:undo_ftplugin ..= " | unlet! b:browsefilter" endif -if (exists("b:is_bash") && (b:is_bash == 1)) +if get(b:, "is_bash", 0) if !has("gui_running") && executable("less") - command! -buffer -nargs=1 Help silent exe '!bash -c "{ help "<args>" 2>/dev/null || man "<args>"; } | LESS= less"' | redraw! - elseif has('terminal') - command! -buffer -nargs=1 Help silent exe ':term bash -c "help "<args>" 2>/dev/null || man "<args>""' + command! -buffer -nargs=1 ShKeywordPrg silent exe '!bash -c "{ help "<args>" 2>/dev/null || man "<args>"; } | LESS= less"' | redraw! + elseif has("terminal") + command! -buffer -nargs=1 ShKeywordPrg silent exe ':term bash -c "help "<args>" 2>/dev/null || man "<args>""' else - command! -buffer -nargs=1 Help echo system('bash -c "help <args>" 2>/dev/null || man "<args>"') + command! -buffer -nargs=1 ShKeywordPrg echo system('bash -c "help <args>" 2>/dev/null || man "<args>"') endif - setlocal keywordprg=:Help - let b:undo_ftplugin ..= " | setl kp< | sil! delc -buffer Help" + setlocal keywordprg=:ShKeywordPrg + let b:undo_ftplugin ..= " | setl kp< | sil! delc -buffer ShKeywordPrg" endif let &cpo = s:save_cpo diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 1ba7d6163d..bbe93bfbc8 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -548,6 +548,9 @@ function vim.region(bufnr, pos1, pos2, regtype, inclusive) else c2 = #bufline + 1 end + elseif regtype == 'V' then -- linewise selection, always return whole line + c1 = 0 + c2 = -1 else c1 = (l == pos1[1]) and pos1[2] or 0 c2 = (l == pos2[1]) and (pos2[2] + (inclusive and 1 or 0)) or -1 diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 9a90e430a7..12226dac91 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -1299,7 +1299,7 @@ int eval_foldexpr(win_T *wp, int *cp) // If the result is a string, check if there is a non-digit before // the number. char *s = tv.vval.v_string; - if (!ascii_isdigit(*s) && *s != '-') { + if (*s != NUL && !ascii_isdigit(*s) && *s != '-') { *cp = (uint8_t)(*s++); } retval = atol(s); diff --git a/src/nvim/options.lua b/src/nvim/options.lua index a0b9306908..e70fe8614f 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -4298,9 +4298,9 @@ return { defaults = { condition = 'BACKSLASH_IN_FILENAME', if_false = '@,48-57,/,.,-,_,+,,,#,$,%,~,=', - if_true = '@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=', + if_true = '@,48-57,/,\\,.,-,_,+,,,#,$,%,{,},[,],@-@,!,~,=', doc = [[for Windows: - "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],:,@-@,!,~,=" + "@,48-57,/,\,.,-,_,+,,,#,$,%,{,},[,],@-@,!,~,=" otherwise: "@,48-57,/,.,-,_,+,,,#,$,%,~,="]], }, deny_duplicates = true, diff --git a/src/nvim/window.c b/src/nvim/window.c index 41199306fa..16bb7f5df7 100644 --- a/src/nvim/window.c +++ b/src/nvim/window.c @@ -6943,11 +6943,13 @@ char *file_name_in_line(char *line, int col, int options, int count, char *rel_f bool is_url = false; // Search backward for first char of the file name. - // Go one char back to ":" before "//" even when ':' is not in 'isfname'. + // Go one char back to ":" before "//", or to the drive letter before ":\" (even if ":" + // is not in 'isfname'). while (ptr > line) { if ((len = (size_t)(utf_head_off(line, ptr - 1))) > 0) { ptr -= len + 1; } else if (vim_isfilec((uint8_t)ptr[-1]) + || (len >= 2 && path_has_drive_letter(ptr - 2)) || ((options & FNAME_HYP) && path_is_url(ptr - 1))) { ptr--; } else { @@ -6957,14 +6959,13 @@ char *file_name_in_line(char *line, int col, int options, int count, char *rel_f // Search forward for the last char of the file name. // Also allow ":/" when ':' is not in 'isfname'. - len = 0; + len = path_has_drive_letter(ptr) ? 2 : 0; while (vim_isfilec((uint8_t)ptr[len]) || (ptr[len] == '\\' && ptr[len + 1] == ' ') || ((options & FNAME_HYP) && path_is_url(ptr + len)) || (is_url && vim_strchr(":?&=", (uint8_t)ptr[len]) != NULL)) { // After type:// we also include :, ?, & and = as valid characters, so that // http://google.com:8080?q=this&that=ok works. - if ((ptr[len] >= 'A' && ptr[len] <= 'Z') - || (ptr[len] >= 'a' && ptr[len] <= 'z')) { + if ((ptr[len] >= 'A' && ptr[len] <= 'Z') || (ptr[len] >= 'a' && ptr[len] <= 'z')) { if (in_type && path_is_url(ptr + len + 1)) { is_url = true; } diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua index 6c677d76d1..06fa13dca5 100644 --- a/test/functional/core/path_spec.lua +++ b/test/functional/core/path_spec.lua @@ -81,7 +81,7 @@ describe('expand wildcard', function() end) end) -describe('file search', function() +describe('file search (gf, <cfile>)', function() before_each(clear) it('find multibyte file name in line #20517', function() @@ -91,4 +91,42 @@ describe('file search', function() feed('gf') eq('filename_with_unicode_ααα', eval('expand("%:t")')) end) + + it('matches Windows drive-letter filepaths (without ":" in &isfname)', function() + local iswin = is_os('win') + local function test_cfile(input, expected, expected_win) + expected = (iswin and expected_win or expected) or input + command('%delete') + insert(input) + command('norm! 0') + eq(expected, eval('expand("<cfile>")')) + end + + test_cfile([[c:/d:/foo/bar.txt]]) -- TODO(justinmk): should return "d:/foo/bar.txt" ? + test_cfile([[//share/c:/foo/bar/]]) + test_cfile([[file://c:/foo/bar]]) + test_cfile([[file://c:/foo/bar:42]]) + test_cfile([[file://c:/foo/bar:42:666]]) + test_cfile([[https://c:/foo/bar]]) + test_cfile([[\foo\bar]], [[foo]], [[\foo\bar]]) + test_cfile([[/foo/bar]], [[/foo/bar]]) + test_cfile([[c:\foo\bar]], [[c:]], [[c:\foo\bar]]) + test_cfile([[c:\foo\bar:42:666]], [[c:]], [[c:\foo\bar]]) + test_cfile([[c:/foo/bar]]) + test_cfile([[c:/foo/bar:42]], [[c:/foo/bar]]) + test_cfile([[c:/foo/bar:42:666]], [[c:/foo/bar]]) + test_cfile([[c:foo\bar]], [[c]]) + test_cfile([[c:foo/bar]], [[c]]) + test_cfile([[c:foo]], [[c]]) + -- Examples from: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#example-ways-to-refer-to-the-same-file + test_cfile([[c:\temp\test-file.txt]], [[c:]], [[c:\temp\test-file.txt]]) + test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]]) + test_cfile([[\\LOCALHOST\c$\temp\test-file.txt]], [[LOCALHOST]], [[\\LOCALHOST\c$\temp\test-file.txt]]) + -- not supported yet + test_cfile([[\\.\c:\temp\test-file.txt]], [[.]], [[\\.\c]]) + -- not supported yet + test_cfile([[\\?\c:\temp\test-file.txt]], [[c:]], [[\\]]) + test_cfile([[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]], [[.]], [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]]) + test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]]) + end) end) diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua index bd3d8f5247..c69990d84b 100644 --- a/test/functional/lua/vim_spec.lua +++ b/test/functional/lua/vim_spec.lua @@ -2401,6 +2401,14 @@ describe('lua stdlib', function() insert([[αα]]) eq({0,5}, exec_lua[[ return vim.region(0,{0,0},{0,4},'3',true)[0] ]]) end) + it('linewise', function() + insert(dedent( [[ + text tααt tααt text + text tαxt txtα tex + text tαxt tαxt + ]])) + eq({0,-1}, exec_lua[[ return vim.region(0,{1,5},{1,14},'V',true)[1] ]]) + end) it('getpos() input', function() insert('getpos') eq({0,6}, exec_lua[[ return vim.region(0,{0,0},'.','v',true)[0] ]]) diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim index 096ddba40b..b0c2a15a3f 100644 --- a/test/old/testdir/setup.vim +++ b/test/old/testdir/setup.vim @@ -26,6 +26,9 @@ if exists('s:did_load') set sessionoptions+=options set viewoptions+=options set switchbuf= + if has('win32') + set isfname+=: + endif if g:testname !~ 'test_mapping.vim$' " Make "Q" switch to Ex mode. " This does not work for all tests. diff --git a/test/old/testdir/test_fold.vim b/test/old/testdir/test_fold.vim index ccd1bfecf8..e529a94174 100644 --- a/test/old/testdir/test_fold.vim +++ b/test/old/testdir/test_fold.vim @@ -1569,4 +1569,13 @@ func Test_foldcolumn_linebreak_control_char() bwipe! endfunc +" This used to cause invalid memory access +func Test_foldexpr_return_empty_string() + new + setlocal foldexpr='' foldmethod=expr + redraw + + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab |