diff options
-rw-r--r-- | runtime/doc/pattern.txt | 43 | ||||
-rw-r--r-- | runtime/mswin.vim | 45 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 1 | ||||
-rw-r--r-- | src/nvim/globals.h | 8 | ||||
-rw-r--r-- | src/nvim/regexp.c | 6 | ||||
-rw-r--r-- | src/nvim/regexp_nfa.c | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_normal.vim | 46 | ||||
-rw-r--r-- | src/nvim/testdir/test_regexp_utf8.vim | 67 | ||||
-rw-r--r-- | test/functional/ui/wildmode_spec.lua | 23 |
9 files changed, 175 insertions, 70 deletions
diff --git a/runtime/doc/pattern.txt b/runtime/doc/pattern.txt index ab78b8b71c..cc485b655d 100644 --- a/runtime/doc/pattern.txt +++ b/runtime/doc/pattern.txt @@ -1071,25 +1071,27 @@ x A single character, with no special meaning, matches itself - A character class expression is evaluated to the set of characters belonging to that character class. The following character classes are supported: - Name Contents ~ -*[:alnum:]* [:alnum:] ASCII letters and digits -*[:alpha:]* [:alpha:] ASCII letters -*[:blank:]* [:blank:] space and tab characters -*[:cntrl:]* [:cntrl:] control characters -*[:digit:]* [:digit:] decimal digits -*[:graph:]* [:graph:] printable characters excluding space -*[:lower:]* [:lower:] lowercase letters (all letters when + Name Func Contents ~ +*[:alnum:]* [:alnum:] isalnum ASCII letters and digits +*[:alpha:]* [:alpha:] isalpha ASCII letters +*[:blank:]* [:blank:] space and tab +*[:cntrl:]* [:cntrl:] iscntrl ASCII control characters +*[:digit:]* [:digit:] decimal digits '0' to '9' +*[:graph:]* [:graph:] isgraph ASCII printable characters excluding + space +*[:lower:]* [:lower:] (1) lowercase letters (all letters when 'ignorecase' is used) -*[:print:]* [:print:] printable characters including space -*[:punct:]* [:punct:] ASCII punctuation characters -*[:space:]* [:space:] whitespace characters -*[:upper:]* [:upper:] uppercase letters (all letters when +*[:print:]* [:print:] (2) printable characters including space +*[:punct:]* [:punct:] ispunct ASCII punctuation characters +*[:space:]* [:space:] whitespace characters: space, tab, CR, + NL, vertical tab, form feed +*[:upper:]* [:upper:] (3) uppercase letters (all letters when 'ignorecase' is used) -*[:xdigit:]* [:xdigit:] hexadecimal digits -*[:return:]* [:return:] the <CR> character -*[:tab:]* [:tab:] the <Tab> character -*[:escape:]* [:escape:] the <Esc> character -*[:backspace:]* [:backspace:] the <BS> character +*[:xdigit:]* [:xdigit:] hexadecimal digits: 0-9, a-f, A-F +*[:return:]* [:return:] the <CR> character +*[:tab:]* [:tab:] the <Tab> character +*[:escape:]* [:escape:] the <Esc> character +*[:backspace:]* [:backspace:] the <BS> character The brackets in character class expressions are additional to the brackets delimiting a collection. For example, the following is a plausible pattern for a Unix filename: "[-./[:alnum:]_~]\+" That is, @@ -1100,6 +1102,13 @@ x A single character, with no special meaning, matches itself regexp engine. See |two-engines|. In the future these items may work for multi-byte characters. For now, to get all "alpha" characters you can use: [[:lower:][:upper:]]. + + The "Func" column shows what library function is used. The + implementation depends on the system. Otherwise: + (1) Uses islower() for ASCII and Vim builtin rules for other + characters when built with the |+multi_byte| feature. + (2) Uses Vim builtin rules + (3) As with (1) but using isupper() */[[=* *[==]* - An equivalence class. This means that characters are matched that have almost the same meaning, e.g., when ignoring accents. This diff --git a/runtime/mswin.vim b/runtime/mswin.vim index ca280d227c..da869a9fc7 100644 --- a/runtime/mswin.vim +++ b/runtime/mswin.vim @@ -1,7 +1,7 @@ " Set options and add mapping such that Vim behaves a lot like MS-Windows " " Maintainer: Bram Moolenaar <Bram@vim.org> -" Last change: 2012 Jul 25 +" Last change: 2017 Oct 28 " bail out if this isn't wanted (mrsvim.vim uses this). if exists("g:skip_loading_mswin") && g:skip_loading_mswin @@ -23,20 +23,22 @@ set backspace=indent,eol,start whichwrap+=<,>,[,] " backspace in Visual mode deletes selection vnoremap <BS> d -" CTRL-X and SHIFT-Del are Cut -vnoremap <C-X> "+x -vnoremap <S-Del> "+x +if has("clipboard") + " CTRL-X and SHIFT-Del are Cut + vnoremap <C-X> "+x + vnoremap <S-Del> "+x -" CTRL-C and CTRL-Insert are Copy -vnoremap <C-C> "+y -vnoremap <C-Insert> "+y + " CTRL-C and CTRL-Insert are Copy + vnoremap <C-C> "+y + vnoremap <C-Insert> "+y -" CTRL-V and SHIFT-Insert are Paste -map <C-V> "+gP -map <S-Insert> "+gP + " CTRL-V and SHIFT-Insert are Paste + map <C-V> "+gP + map <S-Insert> "+gP -cmap <C-V> <C-R>+ -cmap <S-Insert> <C-R>+ + cmap <C-V> <C-R>+ + cmap <S-Insert> <C-R>+ +endif " Pasting blockwise and linewise selections is not possible in Insert and " Visual mode without the +virtualedit feature. They are pasted as if they @@ -44,8 +46,10 @@ cmap <S-Insert> <C-R>+ " Uses the paste.vim autoload script. " Use CTRL-G u to have CTRL-Z only undo the paste. -exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i'] -exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v'] +if 1 + exe 'inoremap <script> <C-V> <C-G>u' . paste#paste_cmd['i'] + exe 'vnoremap <script> <C-V> ' . paste#paste_cmd['v'] +endif imap <S-Insert> <C-V> vmap <S-Insert> <C-V> @@ -99,6 +103,19 @@ inoremap <C-F4> <C-O><C-W>c cnoremap <C-F4> <C-C><C-W>c onoremap <C-F4> <C-C><C-W>c +if has("gui") + " CTRL-F is the search dialog + noremap <expr> <C-F> has("gui_running") ? ":promptfind\<CR>" : "/" + inoremap <expr> <C-F> has("gui_running") ? "\<C-\>\<C-O>:promptfind\<CR>" : "\<C-\>\<C-O>/" + cnoremap <expr> <C-F> has("gui_running") ? "\<C-\>\<C-C>:promptfind\<CR>" : "\<C-\>\<C-O>/" + + " CTRL-H is the replace dialog, + " but in console, it might be backspace, so don't map it there + nnoremap <expr> <C-H> has("gui_running") ? ":promptrepl\<CR>" : "\<C-H>" + inoremap <expr> <C-H> has("gui_running") ? "\<C-\>\<C-O>:promptrepl\<CR>" : "\<C-H>" + cnoremap <expr> <C-H> has("gui_running") ? "\<C-\>\<C-C>:promptrepl\<CR>" : "\<C-H>" +endif + " restore 'cpoptions' set cpo& if 1 diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 96388a2a9d..f62b0a2060 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -641,6 +641,7 @@ static int command_line_execute(VimState *state, int key) save_p_ls = -1; } else { win_redraw_last_status(topframe); + wild_menu_showing = 0; // must be before redraw_statuslines #8385 redraw_statuslines(); } KeyTyped = skt; diff --git a/src/nvim/globals.h b/src/nvim/globals.h index 4aa0ef7def..2860817f79 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -745,11 +745,9 @@ EXTERN int State INIT(= NORMAL); /* This is the current state of the EXTERN bool finish_op INIT(= false); // true while an operator is pending EXTERN long opcount INIT(= 0); // count for pending operator -/* - * ex mode (Q) state - */ -EXTERN int exmode_active INIT(= 0); /* zero, EXMODE_NORMAL or EXMODE_VIM */ -EXTERN int ex_no_reprint INIT(= FALSE); /* no need to print after z or p */ +// Ex Mode (Q) state +EXTERN int exmode_active INIT(= 0); // zero, EXMODE_NORMAL or EXMODE_VIM +EXTERN int ex_no_reprint INIT(= false); // no need to print after z or p EXTERN int Recording INIT(= FALSE); /* TRUE when recording into a reg. */ EXTERN int Exec_reg INIT(= FALSE); /* TRUE when executing a register */ diff --git a/src/nvim/regexp.c b/src/nvim/regexp.c index e4de43b49e..ee7d6d8500 100644 --- a/src/nvim/regexp.c +++ b/src/nvim/regexp.c @@ -2328,21 +2328,21 @@ collection: regc('\t'); break; case CLASS_CNTRL: - for (cu = 1; cu <= 255; cu++) { + for (cu = 1; cu <= 127; cu++) { if (iscntrl(cu)) { regmbc(cu); } } break; case CLASS_DIGIT: - for (cu = 1; cu <= 255; cu++) { + for (cu = 1; cu <= 127; cu++) { if (ascii_isdigit(cu)) { regmbc(cu); } } break; case CLASS_GRAPH: - for (cu = 1; cu <= 255; cu++) { + for (cu = 1; cu <= 127; cu++) { if (isgraph(cu)) { regmbc(cu); } diff --git a/src/nvim/regexp_nfa.c b/src/nvim/regexp_nfa.c index 98fae858f6..0b8e979ca2 100644 --- a/src/nvim/regexp_nfa.c +++ b/src/nvim/regexp_nfa.c @@ -4358,16 +4358,18 @@ static int check_char_class(int class, int c) return OK; break; case NFA_CLASS_CNTRL: - if (c >= 1 && c <= 255 && iscntrl(c)) + if (c >= 1 && c <= 127 && iscntrl(c)) { return OK; + } break; case NFA_CLASS_DIGIT: if (ascii_isdigit(c)) return OK; break; case NFA_CLASS_GRAPH: - if (c >= 1 && c <= 255 && isgraph(c)) + if (c >= 1 && c <= 127 && isgraph(c)) { return OK; + } break; case NFA_CLASS_LOWER: if (mb_islower(c) && c != 170 && c != 186) { diff --git a/src/nvim/testdir/test_normal.vim b/src/nvim/testdir/test_normal.vim index 1d15c7f83d..10d4c5dd94 100644 --- a/src/nvim/testdir/test_normal.vim +++ b/src/nvim/testdir/test_normal.vim @@ -2314,28 +2314,36 @@ func! Test_normal53_digraph() bw! endfunc -func! Test_normal54_Ctrl_bsl() - new - call setline(1, 'abcdefghijklmn') - exe "norm! df\<c-\>\<c-n>" - call assert_equal(['abcdefghijklmn'], getline(1,'$')) - exe "norm! df\<c-\>\<c-g>" - call assert_equal(['abcdefghijklmn'], getline(1,'$')) - exe "norm! df\<c-\>m" - call assert_equal(['abcdefghijklmn'], getline(1,'$')) +func Test_normal54_Ctrl_bsl() + new + call setline(1, 'abcdefghijklmn') + exe "norm! df\<c-\>\<c-n>" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\<c-\>\<c-g>" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) + exe "norm! df\<c-\>m" + call assert_equal(['abcdefghijklmn'], getline(1,'$')) if !has("multi_byte") return endif - call setline(2, 'abcdefghijklmnāf') - norm! 2gg0 - exe "norm! df\<Char-0x101>" - call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) - norm! 1gg0 - exe "norm! df\<esc>" - call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) - - " clean up - bw! + call setline(2, 'abcdefghijklmnāf') + norm! 2gg0 + exe "norm! df\<Char-0x101>" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + norm! 1gg0 + exe "norm! df\<esc>" + call assert_equal(['abcdefghijklmn', 'f'], getline(1,'$')) + + " clean up + bw! +endfunc + +func Test_normal_large_count() + " This may fail with 32bit long, how do we detect that? + new + normal o + normal 6666666666dL + bwipe! endfunc " Test for the gr (virtual replace) command diff --git a/src/nvim/testdir/test_regexp_utf8.vim b/src/nvim/testdir/test_regexp_utf8.vim index a2f4286d4f..ecd686743e 100644 --- a/src/nvim/testdir/test_regexp_utf8.vim +++ b/src/nvim/testdir/test_regexp_utf8.vim @@ -35,12 +35,21 @@ func s:classes_test() set isprint=@,161-255 call assert_equal('Motörhead', matchstr('Motörhead', '[[:print:]]\+')) + let alnumchars = '' let alphachars = '' + let backspacechar = '' + let blankchars = '' + let cntrlchars = '' + let digitchars = '' + let escapechar = '' + let graphchars = '' let lowerchars = '' - let upperchars = '' - let alnumchars = '' let printchars = '' let punctchars = '' + let returnchar = '' + let spacechars = '' + let tabchar = '' + let upperchars = '' let xdigitchars = '' let i = 1 while i <= 255 @@ -48,21 +57,48 @@ func s:classes_test() if c =~ '[[:alpha:]]' let alphachars .= c endif - if c =~ '[[:lower:]]' - let lowerchars .= c - endif - if c =~ '[[:upper:]]' - let upperchars .= c - endif if c =~ '[[:alnum:]]' let alnumchars .= c endif + if c =~ '[[:backspace:]]' + let backspacechar .= c + endif + if c =~ '[[:blank:]]' + let blankchars .= c + endif + if c =~ '[[:cntrl:]]' + let cntrlchars .= c + endif + if c =~ '[[:digit:]]' + let digitchars .= c + endif + if c =~ '[[:escape:]]' + let escapechar .= c + endif + if c =~ '[[:graph:]]' + let graphchars .= c + endif + if c =~ '[[:lower:]]' + let lowerchars .= c + endif if c =~ '[[:print:]]' let printchars .= c endif if c =~ '[[:punct:]]' let punctchars .= c endif + if c =~ '[[:return:]]' + let returnchar .= c + endif + if c =~ '[[:space:]]' + let spacechars .= c + endif + if c =~ '[[:tab:]]' + let tabchar .= c + endif + if c =~ '[[:upper:]]' + let upperchars .= c + endif if c =~ '[[:xdigit:]]' let xdigitchars .= c endif @@ -70,11 +106,22 @@ func s:classes_test() endwhile call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alphachars) - call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars) - call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars) call assert_equal('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', alnumchars) + call assert_equal("\b", backspacechar) + call assert_equal("\t ", blankchars) + " Commented out: it succeeds on Linux and Windows, but fails on macOs in Travis. + " call assert_equal("\x01\x02\x03\x04\x05\x06\x07\b\t\n\x0b\f\r\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\e\x1c\x1d\x1e\x1f\x7f", cntrlchars) + call assert_equal("0123456789", digitchars) + call assert_equal("\<Esc>", escapechar) + " Commented out: it succeeds on Linux and Windows, but fails on macOs in Travis. + " call assert_equal('!"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', graphchars) + call assert_equal('abcdefghijklmnopqrstuvwxyzµßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ', lowerchars) call assert_equal(' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ¡¢£¤¥¦§¨©ª«¬®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ', printchars) call assert_equal('!"#$%&''()*+,-./:;<=>?@[\]^_`{|}~', punctchars) + call assert_equal('ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞ', upperchars) + call assert_equal("\r", returnchar) + call assert_equal("\t\n\x0b\f\r ", spacechars) + call assert_equal("\t", tabchar) call assert_equal('0123456789ABCDEFabcdef', xdigitchars) endfunc diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua index c6ddc78618..b60d520ca0 100644 --- a/test/functional/ui/wildmode_spec.lua +++ b/test/functional/ui/wildmode_spec.lua @@ -31,6 +31,29 @@ describe("'wildmenu'", function() ]]) end) + it(':sign <tab> <space> hides wildmenu #8453', function() + command('set wildmode=full') + -- only a regression if status-line open + command('set laststatus=2') + command('set wildmenu') + feed(':sign <tab>') + screen:expect([[ + | + ~ | + ~ | + define jump list > | + :sign define^ | + ]]) + feed('<space>') + screen:expect([[ + | + ~ | + ~ | + [No Name] | + :sign define ^ | + ]]) + end) + it('does not crash after cycling back to original text', function() command('set wildmode=full') feed(':j<Tab><Tab><Tab>') |