diff --git a/nsis/README.txt b/nsis/README.txt index b61580c9b0..f5348e91ea 100644 --- a/nsis/README.txt +++ b/nsis/README.txt @@ -15,6 +15,7 @@ To build the installable .exe: vimrun.exe, install.exe, uninstal.exe, + tee/tee.exe, xxd/xxd.exe, Then execute tools/rename.bat to rename the executables. (mv command is @@ -29,14 +30,15 @@ To build the installable .exe: 4. Go to the VisVim directory and build VisVim.dll (or get it from a binary archive). -5. Go to the OleVim directory and build OpenWithVim.exe and SendToVim.exe (or - get them from a binary archive). - -6. Get a "diff.exe" program and put it in the "../.." directory (above the - "vim80" directory, it's the same for all Vim versions). +5. Get a "diff.exe" program. If you skip this the built-in diff will always + be used (which is fine for most users). If you do have your own + "diff.exe" put it in the "../.." directory (above the "vim81" directory, + it's the same for all Vim versions). You can find one in previous Vim versions or in this archive: http://www.mossbayeng.com/~ron/vim/diffutils.tar.gz - Also put winpty32.dll and winpty-agent.exe there. + +6 Also put winpty32.dll and winpty-agent.exe in "../.." (above the "vim81" + directory). This is required for the terminal window. 7. Do "make uganda.nsis.txt" in runtime/doc. This requires sed, you may have to do this on Unix. Make sure the file is in DOS file format! diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 8538d0c2f2..6e652202b8 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -334,6 +334,9 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. {not in Vi} {not available when compiled without the |+eval| feature} +:scr[iptnames][!] {scriptId} *:script* + Edit script {scriptId}. Suggested name is ":script". + *:fini* *:finish* *E168* :fini[sh] Stop sourcing a script. Can only be used in a Vim script file. This is a quick way to skip the rest of diff --git a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim index 9f4c26a0ee..61de9a34b4 100644 --- a/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim +++ b/runtime/pack/dist/opt/termdebug/plugin/termdebug.vim @@ -73,6 +73,13 @@ let s:pc_id = 12 let s:break_id = 13 " breakpoint number is added to this let s:stopped = 1 +" Take a breakpoint number as used by GDB and turn it into an integer. +" The breakpoint may contain a dot: 123.4 +func s:Breakpoint2SignNumber(nr) + let t = split(a:nr, '\.') + return t[0] * 1000 + (len(t) == 2 ? t[1] : 0) +endfunction + func s:Highlight(init, old, new) let default = a:init ? 'default ' : '' if a:new ==# 'light' && a:old !=# 'light' @@ -138,9 +145,9 @@ endfunc func s:StartDebug_term(dict) " Open a terminal window without a job, to run the debugged program in. let s:ptybuf = term_start('NONE', { - \ 'term_name': 'debugged program', - \ 'vertical': s:vertical, - \ }) + \ 'term_name': 'debugged program', + \ 'vertical': s:vertical, + \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' return @@ -155,10 +162,10 @@ func s:StartDebug_term(dict) " Create a hidden terminal window to communicate with gdb let s:commbuf = term_start('NONE', { - \ 'term_name': 'gdb communication', - \ 'out_cb': function('s:CommOutput'), - \ 'hidden': 1, - \ }) + \ 'term_name': 'gdb communication', + \ 'out_cb': function('s:CommOutput'), + \ 'hidden': 1, + \ }) if s:commbuf == 0 echoerr 'Failed to open the communication terminal window' exe 'bwipe! ' . s:ptybuf @@ -174,9 +181,9 @@ func s:StartDebug_term(dict) let cmd = [g:termdebugger, '-quiet', '-tty', pty] + gdb_args call ch_log('executing "' . join(cmd) . '"') let s:gdbbuf = term_start(cmd, { - \ 'exit_cb': function('s:EndTermDebug'), - \ 'term_finish': 'close', - \ }) + \ 'exit_cb': function('s:EndTermDebug'), + \ 'term_finish': 'close', + \ }) if s:gdbbuf == 0 echoerr 'Failed to open the gdb terminal window' exe 'bwipe! ' . s:ptybuf @@ -200,18 +207,18 @@ func s:StartDebug_term(dict) let response = '' for lnum in range(1,200) if term_getline(s:gdbbuf, lnum) =~ 'new-ui mi ' - " response can be in the same line or the next line - let response = term_getline(s:gdbbuf, lnum) . term_getline(s:gdbbuf, lnum + 1) - if response =~ 'Undefined command' - echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' - exe 'bwipe! ' . s:ptybuf - exe 'bwipe! ' . s:commbuf - return - endif - if response =~ 'New UI allocated' - " Success! - break - endif + " response can be in the same line or the next line + let response = term_getline(s:gdbbuf, lnum) . term_getline(s:gdbbuf, lnum + 1) + if response =~ 'Undefined command' + echoerr 'Sorry, your gdb is too old, gdb 7.12 is required' + exe 'bwipe! ' . s:ptybuf + exe 'bwipe! ' . s:commbuf + return + endif + if response =~ 'New UI allocated' + " Success! + break + endif endif endfor if response =~ 'New UI allocated' @@ -268,9 +275,9 @@ func s:StartDebug_prompt(dict) call ch_log('executing "' . join(cmd) . '"') let s:gdbjob = job_start(cmd, { - \ 'exit_cb': function('s:EndPromptDebug'), - \ 'out_cb': function('s:GdbOutCallback'), - \ }) + \ 'exit_cb': function('s:EndPromptDebug'), + \ 'out_cb': function('s:GdbOutCallback'), + \ }) if job_status(s:gdbjob) != "run" echoerr 'Failed to start gdb' exe 'bwipe! ' . s:promptbuf @@ -295,8 +302,8 @@ func s:StartDebug_prompt(dict) " Unix: Run the debugged program in a terminal window. Open it below the " gdb window. belowright let s:ptybuf = term_start('NONE', { - \ 'term_name': 'debugged program', - \ }) + \ 'term_name': 'debugged program', + \ }) if s:ptybuf == 0 echoerr 'Failed to open the program terminal window' call job_stop(s:gdbjob) @@ -353,7 +360,8 @@ func s:StartDebugCommon(dict) endif endif - " Contains breakpoints that have been placed, key is the number. + " Contains breakpoints that have been placed, key is a string with the GDB + " breakpoint number. let s:breakpoints = {} augroup TermDebug @@ -466,9 +474,9 @@ func s:DecodeMessage(quotedText) if a:quotedText[i] == '\' let i += 1 if a:quotedText[i] == 'n' - " drop \n - let i += 1 - continue + " drop \n + let i += 1 + continue endif endif let result .= a:quotedText[i] @@ -479,6 +487,9 @@ endfunc " Extract the "name" value from a gdb message with fullname="name". func s:GetFullname(msg) + if a:msg !~ 'fullname' + return '' + endif let name = s:DecodeMessage(substitute(a:msg, '.*fullname=', '', '')) if has('win32') && name =~ ':\\\\' " sometimes the name arrives double-escaped @@ -549,17 +560,17 @@ func s:CommOutput(chan, msg) endif if msg != '' if msg =~ '^\(\*stopped\|\*running\|=thread-selected\)' - call s:HandleCursor(msg) + call s:HandleCursor(msg) elseif msg =~ '^\^done,bkpt=' || msg =~ '^=breakpoint-created,' - call s:HandleNewBreakpoint(msg) + call s:HandleNewBreakpoint(msg) elseif msg =~ '^=breakpoint-deleted,' - call s:HandleBreakpointDelete(msg) + call s:HandleBreakpointDelete(msg) elseif msg =~ '^=thread-group-started' - call s:HandleProgramRun(msg) + call s:HandleProgramRun(msg) elseif msg =~ '^\^done,value=' - call s:HandleEvaluate(msg) + call s:HandleEvaluate(msg) elseif msg =~ '^\^error,msg=' - call s:HandleError(msg) + call s:HandleError(msg) endif endif endfor @@ -650,12 +661,12 @@ func s:DeleteCommands() let curwinid = win_getid(winnr()) for winid in s:winbar_winids if win_gotoid(winid) - aunmenu WinBar.Step - aunmenu WinBar.Next - aunmenu WinBar.Finish - aunmenu WinBar.Cont - aunmenu WinBar.Stop - aunmenu WinBar.Eval + aunmenu WinBar.Step + aunmenu WinBar.Next + aunmenu WinBar.Finish + aunmenu WinBar.Cont + aunmenu WinBar.Stop + aunmenu WinBar.Eval endif endfor call win_gotoid(curwinid) @@ -673,7 +684,7 @@ func s:DeleteCommands() exe 'sign unplace ' . s:pc_id for key in keys(s:breakpoints) - exe 'sign unplace ' . (s:break_id + key) + exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(key)) endfor unlet s:breakpoints @@ -700,7 +711,7 @@ func s:SetBreakpoint() endif " Use the fname:lnum format, older gdb can't handle --source. call s:SendCommand('-break-insert ' - \ . fnameescape(expand('%:p')) . ':' . line('.')) + \ . fnameescape(expand('%:p')) . ':' . line('.')) if do_continue call s:SendCommand('-exec-continue') endif @@ -714,7 +725,7 @@ func s:ClearBreakpoint() if val['fname'] == fname && val['lnum'] == lnum call s:SendCommand('-break-delete ' . key) " Assume this always wors, the reply is simply "^done". - exe 'sign unplace ' . (s:break_id + key) + exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(key)) unlet s:breakpoints[key] break endif @@ -839,14 +850,14 @@ func s:HandleCursor(msg) if lnum =~ '^[0-9]*$' call s:GotoSourcewinOrCreateIt() if expand('%:p') != fnamemodify(fname, ':p') - if &modified - " TODO: find existing window - exe 'split ' . fnameescape(fname) - let s:sourcewin = win_getid(winnr()) - call s:InstallWinbar() - else - exe 'edit ' . fnameescape(fname) - endif + if &modified + " TODO: find existing window + exe 'split ' . fnameescape(fname) + let s:sourcewin = win_getid(winnr()) + call s:InstallWinbar() + else + exe 'edit ' . fnameescape(fname) + endif endif exe lnum exe 'sign unplace ' . s:pc_id @@ -865,10 +876,14 @@ let s:BreakpointSigns = [] func s:CreateBreakpoint(nr) if index(s:BreakpointSigns, a:nr) == -1 call add(s:BreakpointSigns, a:nr) - exe "sign define debugBreakpoint" . a:nr . " text=" . a:nr . " texthl=debugBreakpoint" + exe "sign define debugBreakpoint" . a:nr . " text=" . substitute(a:nr, '\..*', '', '') . " texthl=debugBreakpoint" endif endfunc +func s:SplitMsg(s) + return split(a:s, '{\%([a-z-]\+=[^,]\+,*\)\+}\zs') +endfunction + " Handle setting a breakpoint " Will update the sign that shows the breakpoint func s:HandleNewBreakpoint(msg) @@ -876,50 +891,57 @@ func s:HandleNewBreakpoint(msg) " a watch does not have a file name return endif + for msg in s:SplitMsg(a:msg) + let fname = s:GetFullname(msg) + if empty(fname) + continue + endif + let nr = substitute(msg, '.*number="\([0-9.]*\)\".*', '\1', '') + if empty(nr) + return + endif + call s:CreateBreakpoint(nr) - let nr = substitute(a:msg, '.*number="\([0-9]*\)".*', '\1', '') + 0 - if nr == 0 - return - endif - call s:CreateBreakpoint(nr) + if has_key(s:breakpoints, nr) + let entry = s:breakpoints[nr] + else + let entry = {} + let s:breakpoints[nr] = entry + endif - if has_key(s:breakpoints, nr) - let entry = s:breakpoints[nr] - else - let entry = {} - let s:breakpoints[nr] = entry - endif + let lnum = substitute(msg, '.*line="\([^"]*\)".*', '\1', '') + let entry['fname'] = fname + let entry['lnum'] = lnum - let fname = s:GetFullname(a:msg) - let lnum = substitute(a:msg, '.*line="\([^"]*\)".*', '\1', '') - let entry['fname'] = fname - let entry['lnum'] = lnum - - if bufloaded(fname) - call s:PlaceSign(nr, entry) - endif + if bufloaded(fname) + call s:PlaceSign(nr, entry) + endif + endfor endfunc func s:PlaceSign(nr, entry) - exe 'sign place ' . (s:break_id + a:nr) . ' line=' . a:entry['lnum'] . ' name=debugBreakpoint' . a:nr . ' file=' . a:entry['fname'] + exe 'sign place ' . (s:break_id + s:Breakpoint2SignNumber(a:nr)) . ' line=' . a:entry['lnum'] . ' name=debugBreakpoint' . a:nr . ' file=' . a:entry['fname'] let a:entry['placed'] = 1 endfunc " Handle deleting a breakpoint " Will remove the sign that shows the breakpoint func s:HandleBreakpointDelete(msg) - let nr = substitute(a:msg, '.*id="\([0-9]*\)\".*', '\1', '') + 0 - if nr == 0 + let key = substitute(a:msg, '.*id="\([0-9.]*\)\".*', '\1', '') + if empty(key) return endif - if has_key(s:breakpoints, nr) + for [nr, entry] in items(s:breakpoints) + if stridx(nr, key) != 0 + continue + endif let entry = s:breakpoints[nr] if has_key(entry, 'placed') - exe 'sign unplace ' . (s:break_id + nr) + exe 'sign unplace ' . (s:break_id + s:Breakpoint2SignNumber(nr)) unlet entry['placed'] endif unlet s:breakpoints[nr] - endif + endfor endfunc " Handle the debugged program starting to run. diff --git a/src/Make_all.mak b/src/Make_all.mak index da3a62ca8b..466f17e9e2 100644 --- a/src/Make_all.mak +++ b/src/Make_all.mak @@ -153,6 +153,7 @@ NEW_TESTS = \ test_reltime \ test_retab \ test_ruby \ + test_scriptnames \ test_scroll_opt \ test_scrollbind \ test_search \ diff --git a/src/eval.c b/src/eval.c index 4a3cf99124..7dfb981254 100644 --- a/src/eval.c +++ b/src/eval.c @@ -7999,6 +7999,7 @@ ex_echo(exarg_T *eap) int needclr = TRUE; int atstart = TRUE; char_u numbuf[NUMBUFLEN]; + int did_emsg_before = did_emsg; if (eap->skip) ++emsg_skip; @@ -8016,7 +8017,7 @@ ex_echo(exarg_T *eap) * has been cancelled due to an aborting error, an interrupt, or an * exception. */ - if (!aborting()) + if (!aborting() && did_emsg == did_emsg_before) EMSG2(_(e_invexpr2), p); need_clr_eos = FALSE; break; @@ -8114,7 +8115,7 @@ ex_execute(exarg_T *eap) char_u *p; garray_T ga; int len; - int save_did_emsg; + int save_did_emsg = did_emsg; ga_init2(&ga, 1, 80); @@ -8130,7 +8131,7 @@ ex_execute(exarg_T *eap) * has been cancelled due to an aborting error, an interrupt, or an * exception. */ - if (!aborting()) + if (!aborting() && did_emsg == save_did_emsg) EMSG2(_(e_invexpr2), p); ret = FAIL; break; diff --git a/src/ex_cmds.h b/src/ex_cmds.h index c28c013390..cf5dd73fb4 100644 --- a/src/ex_cmds.h +++ b/src/ex_cmds.h @@ -62,15 +62,15 @@ #define FILE1 (FILES | NOSPC) /* 1 file allowed, defaults to current file */ /* values for cmd_addr_type */ -#define ADDR_LINES 0 -#define ADDR_WINDOWS 1 -#define ADDR_ARGUMENTS 2 -#define ADDR_LOADED_BUFFERS 3 -#define ADDR_BUFFERS 4 -#define ADDR_TABS 5 -#define ADDR_TABS_RELATIVE 6 /* Tab page that only relative */ -#define ADDR_QUICKFIX 7 -#define ADDR_OTHER 99 +#define ADDR_LINES 0 // buffer line numbers +#define ADDR_WINDOWS 1 // window number +#define ADDR_ARGUMENTS 2 // argument number +#define ADDR_LOADED_BUFFERS 3 // buffer number of loaded buffer +#define ADDR_BUFFERS 4 // buffer number +#define ADDR_TABS 5 // tab page number +#define ADDR_TABS_RELATIVE 6 // Tab page that only relative +#define ADDR_QUICKFIX 7 // quickfix list entry number +#define ADDR_OTHER 99 // something else #ifndef DO_DECLARE_EXCMD typedef struct exarg exarg_T; @@ -1266,8 +1266,8 @@ EX(CMD_sbrewind, "sbrewind", ex_brewind, EDITCMD|TRLBAR, ADDR_LINES), EX(CMD_scriptnames, "scriptnames", ex_scriptnames, - TRLBAR|CMDWIN, - ADDR_LINES), + BANG|RANGE|NOTADR|COUNT|TRLBAR|CMDWIN, + ADDR_OTHER), EX(CMD_scriptencoding, "scriptencoding", ex_scriptencoding, WORD1|TRLBAR|CMDWIN, ADDR_LINES), diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c index 069ec43399..8b631ab8d0 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -4763,10 +4763,23 @@ theend: * ":scriptnames" */ void -ex_scriptnames(exarg_T *eap UNUSED) +ex_scriptnames(exarg_T *eap) { int i; + if (eap->addr_count > 0) + { + // :script {scriptId}: edit the script + if (eap->line2 < 1 || eap->line2 > script_items.ga_len) + EMSG(_(e_invarg)); + else + { + eap->arg = SCRIPT_ITEM(eap->line2).sn_name; + do_exedit(eap, NULL); + } + return; + } + for (i = 1; i <= script_items.ga_len && !got_int; ++i) if (SCRIPT_ITEM(i).sn_name != NULL) { diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 07c4f2b5ff..6ee9b27149 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3005,6 +3005,7 @@ parse_cmd_address(exarg_T *eap, char_u **errormsg, int silent) } break; case ADDR_TABS_RELATIVE: + case ADDR_OTHER: *errormsg = (char_u *)_(e_invrange); return FAIL; case ADDR_ARGUMENTS: @@ -5956,6 +5957,7 @@ static struct {ADDR_BUFFERS, "buffers"}, {ADDR_WINDOWS, "windows"}, {ADDR_QUICKFIX, "quickfix"}, + {ADDR_OTHER, "other"}, {-1, NULL} }; #endif diff --git a/src/ex_getln.c b/src/ex_getln.c index 4cb9e73ac8..24df055ca4 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -462,6 +462,7 @@ may_do_incsearch_highlighting( int use_last_pat; // Parsing range may already set the last search pattern. + // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen)) @@ -633,6 +634,7 @@ may_adjust_incsearch_highlighting( int save; // Parsing range may already set the last search pattern. + // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen)) @@ -735,6 +737,7 @@ may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state) int skiplen, patlen; // Parsing range may already set the last search pattern. + // NOTE: must call restore_last_search_pattern() before returning! save_last_search_pattern(); if (!do_incsearch_highlighting(firstc, is_state, &skiplen, &patlen)) @@ -742,6 +745,7 @@ may_add_char_to_search(int firstc, int *c, incsearch_state_T *is_state) restore_last_search_pattern(); return FAIL; } + restore_last_search_pattern(); // Add a character from under the cursor for 'incsearch'. if (is_state->did_incsearch) diff --git a/src/message.c b/src/message.c index 4ba0e04c84..5bd550e8c7 100644 --- a/src/message.c +++ b/src/message.c @@ -636,7 +636,7 @@ emsg(char_u *s) if (cause_errthrow(s, severe, &ignore) == TRUE) { if (!ignore) - did_emsg = TRUE; + ++did_emsg; return TRUE; } @@ -689,7 +689,7 @@ emsg(char_u *s) beep_flush(); /* also includes flush_buffers() */ else flush_buffers(FLUSH_MINIMAL); // flush internal buffers - did_emsg = TRUE; // flag for DoOneCmd() + ++did_emsg; // flag for DoOneCmd() #ifdef FEAT_EVAL did_uncaught_emsg = TRUE; #endif diff --git a/src/popupmnu.c b/src/popupmnu.c index c481d4be73..f3a9f39919 100644 --- a/src/popupmnu.c +++ b/src/popupmnu.c @@ -196,20 +196,11 @@ pum_display( return; #if defined(FEAT_QUICKFIX) - // If there is a preview window at the above avoid drawing over it. - // Do keep at least 10 entries. - if (pvwin != NULL && pum_row < above_row && pum_height > 10) + // If there is a preview window above avoid drawing over it. + if (pvwin != NULL && pum_row < above_row && pum_height > above_row) { - if (pum_win_row - above_row < 10) - { - pum_row = pum_win_row - 10; - pum_height = 10; - } - else - { - pum_row = above_row; - pum_height = pum_win_row - above_row; - } + pum_row = above_row; + pum_height = pum_win_row - above_row; } #endif diff --git a/src/search.c b/src/search.c index be64318454..11fa0db043 100644 --- a/src/search.c +++ b/src/search.c @@ -93,11 +93,8 @@ static int lastc_bytelen = 1; /* >1 for multi-byte char */ /* copy of spats[], for keeping the search patterns while executing autocmds */ static struct spat saved_spats[2]; # ifdef FEAT_SEARCH_EXTRA -/* copy of spats[RE_SEARCH], for keeping the search patterns while incremental - * searching */ -static struct spat saved_last_search_spat; -static int saved_last_idx = 0; -static int saved_no_hlsearch = 0; +static int saved_spats_last_idx = 0; +static int saved_spats_no_hlsearch = 0; # endif static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */ @@ -313,8 +310,8 @@ save_search_patterns(void) if (spats[1].pat != NULL) saved_spats[1].pat = vim_strsave(spats[1].pat); #ifdef FEAT_SEARCH_EXTRA - saved_last_idx = last_idx; - saved_no_hlsearch = no_hlsearch; + saved_spats_last_idx = last_idx; + saved_spats_no_hlsearch = no_hlsearch; #endif } } @@ -332,8 +329,8 @@ restore_search_patterns(void) vim_free(spats[1].pat); spats[1] = saved_spats[1]; #ifdef FEAT_SEARCH_EXTRA - last_idx = saved_last_idx; - set_no_hlsearch(saved_no_hlsearch); + last_idx = saved_spats_last_idx; + set_no_hlsearch(saved_spats_no_hlsearch); #endif } } @@ -357,6 +354,13 @@ free_search_patterns(void) #endif #ifdef FEAT_SEARCH_EXTRA +// copy of spats[RE_SEARCH], for keeping the search patterns while incremental +// searching +static struct spat saved_last_search_spat; +static int did_save_last_search_spat = 0; +static int saved_last_idx = 0; +static int saved_no_hlsearch = 0; + /* * Save and restore the search pattern for incremental highlight search * feature. @@ -368,6 +372,11 @@ free_search_patterns(void) void save_last_search_pattern(void) { + if (did_save_last_search_spat != 0) + IEMSG("did_save_last_search_spat is not zero"); + else + ++did_save_last_search_spat; + saved_last_search_spat = spats[RE_SEARCH]; if (spats[RE_SEARCH].pat != NULL) saved_last_search_spat.pat = vim_strsave(spats[RE_SEARCH].pat); @@ -378,8 +387,16 @@ save_last_search_pattern(void) void restore_last_search_pattern(void) { + if (did_save_last_search_spat != 1) + { + IEMSG("did_save_last_search_spat is not one"); + return; + } + --did_save_last_search_spat; + vim_free(spats[RE_SEARCH].pat); spats[RE_SEARCH] = saved_last_search_spat; + saved_last_search_spat.pat = NULL; # if defined(FEAT_EVAL) set_vv_searchforward(); # endif @@ -570,7 +587,7 @@ set_last_search_pat( saved_spats[idx].pat = NULL; else saved_spats[idx].pat = vim_strsave(spats[idx].pat); - saved_last_idx = last_idx; + saved_spats_last_idx = last_idx; } # ifdef FEAT_SEARCH_EXTRA /* If 'hlsearch' set and search pat changed: need redraw. */ @@ -1380,7 +1397,7 @@ do_search( char_u *trunc; if (*searchstr == NUL) - p = spats[last_idx].pat; + p = spats[0].pat; else p = searchstr; msgbuf = alloc((unsigned)(STRLEN(p) + 40)); diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak index 45f45d7fd8..5b85156737 100644 --- a/src/testdir/Make_all.mak +++ b/src/testdir/Make_all.mak @@ -158,6 +158,7 @@ NEW_TESTS = test_arabic.res \ test_registers.res \ test_retab.res \ test_ruby.res \ + test_scriptnames.res \ test_scrollbind.res \ test_search.res \ test_shortpathname.res \ diff --git a/src/testdir/dumps/Test_popup_and_previewwindow_01.dump b/src/testdir/dumps/Test_popup_and_previewwindow_01.dump new file mode 100644 index 0000000000..71ff3990fe --- /dev/null +++ b/src/testdir/dumps/Test_popup_and_previewwindow_01.dump @@ -0,0 +1,20 @@ +|a+0&#ffffff0|b|0| @71 +|a|b|1| @71 +|a|b|2| @71 +|a|b|3| @71 +|a|b|4| @71 +|a|b|5| @71 +|a|b|6| @71 +|a|b|7| @71 +|a|b|8| @71 +|a+0#0000001#e0e0e08|b|0| @11| +0#0000000#0000001|e+1&#ffffff0|w|]|[|+|]| @34|1|,|1| @11|T|o|p +|a+0#0000001#ffd7ff255|b|1| @11| +0#0000000#0000001| +0&#ffffff0@58 +|a+0#0000001#ffd7ff255|b|2| @11| +0#0000000#0000001| +0&#ffffff0@58 +|a+0#0000001#ffd7ff255|b|3| @11| +0#0000000#0000001| +0&#ffffff0@58 +|a+0#0000001#ffd7ff255|b|4| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58 +|a+0#0000001#ffd7ff255|b|5| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58 +|a+0#0000001#ffd7ff255|b|6| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58 +|a|b|0> @71 +|~+0#4040ff13&| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0|,|1| @10|B|o|t +|-+2&&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |1|0| +0#0000000&@26 diff --git a/src/testdir/test108.ok b/src/testdir/test108.ok index 6315edcc21..7a531dd240 100644 --- a/src/testdir/test108.ok +++ b/src/testdir/test108.ok @@ -28,7 +28,6 @@ undefined var3 on former level: Error detected while processing function Foo[2]..Bar[2]..Bazz: line 3: E121: Undefined variable: var3 -E15: Invalid expression: var3 here var3 is defined with "another var": another var @@ -36,7 +35,6 @@ undefined var2 on former level Error detected while processing function Foo[2]..Bar: line 3: E121: Undefined variable: var2 -E15: Invalid expression: var2 here var2 is defined with 10: 10 diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim index b896c3dec6..cb1117eede 100644 --- a/src/testdir/test_arglist.vim +++ b/src/testdir/test_arglist.vim @@ -396,6 +396,18 @@ func Test_argdelete() %argd endfunc +func Test_argdelete_completion() + args foo bar + + call feedkeys(":argdelete \\\"\", 'tx') + call assert_equal('"argdelete bar foo', @:) + + call feedkeys(":argdelete x \\\"\", 'tx') + call assert_equal('"argdelete x bar foo', @:) + + %argd +endfunc + " Tests for the :next, :prev, :first, :last, :rewind commands func Test_argpos() call Reset_arglist() diff --git a/src/testdir/test_filetype.vim b/src/testdir/test_filetype.vim index d146bd2ce1..fd2f38355f 100644 --- a/src/testdir/test_filetype.vim +++ b/src/testdir/test_filetype.vim @@ -597,3 +597,7 @@ func Test_script_detection() filetype off endfunc +func Test_setfiletype_completion() + call feedkeys(":setfiletype java\\\"\", 'tx') + call assert_equal('"setfiletype java javacc javascript', @:) +endfunc diff --git a/src/testdir/test_history.vim b/src/testdir/test_history.vim index ca31e3f06c..16aad9889e 100644 --- a/src/testdir/test_history.vim +++ b/src/testdir/test_history.vim @@ -104,3 +104,8 @@ function Test_Search_history_window() call assert_equal('a', @/) bwipe! endfunc + +function Test_history_completion() + call feedkeys(":history \\\"\", 'tx') + call assert_equal('"history / : = > ? @ all cmd debug expr input search', @:) +endfunc diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim index a85799e263..de14b81f9a 100644 --- a/src/testdir/test_messages.vim +++ b/src/testdir/test_messages.vim @@ -59,3 +59,8 @@ function! Test_stopinsert_does_not_break_message_output() set cmdheight& endfunction + +func Test_message_completion() + call feedkeys(":message \\\"\", 'tx') + call assert_equal('"message clear', @:) +endfunc diff --git a/src/testdir/test_popup.vim b/src/testdir/test_popup.vim index 9c25687ad3..287d59d901 100644 --- a/src/testdir/test_popup.vim +++ b/src/testdir/test_popup.vim @@ -701,6 +701,28 @@ func Test_popup_and_preview_autocommand() bw! endfunc +func Test_popup_and_previewwindow_dump() + if !CanRunVimInTerminal() + return + endif + call writefile([ + \ 'set previewheight=9', + \ 'silent! pedit', + \ 'call setline(1, map(repeat(["ab"], 10), "v:val. v:key"))', + \ 'exec "norm! G\\"', + \ ], 'Xscript') + let buf = RunVimInTerminal('-S Xscript', {}) + + " Test that popup and previewwindow do not overlap. + call term_sendkeys(buf, "o\\") + sleep 100m + call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {}) + + call term_sendkeys(buf, "\u") + call StopVimInTerminal(buf) + call delete('Xscript') +endfunc + func Test_balloon_split() if !exists('*balloon_split') return diff --git a/src/testdir/test_scriptnames.vim b/src/testdir/test_scriptnames.vim new file mode 100644 index 0000000000..fc6c910bfa --- /dev/null +++ b/src/testdir/test_scriptnames.vim @@ -0,0 +1,26 @@ +" Test for :scriptnames + +func Test_scriptnames() + call writefile(['let did_load_script = 123'], 'Xscripting') + source Xscripting + call assert_equal(123, g:did_load_script) + + let scripts = split(execute('scriptnames'), "\n") + let last = scripts[-1] + call assert_match('\', last) + let lastnr = substitute(last, '\D*\(\d\+\):.*', '\1', '') + exe 'script ' . lastnr + call assert_equal('Xscripting', expand('%:t')) + + call assert_fails('script ' . (lastnr + 1), 'E474:') + call assert_fails('script 0', 'E939:') + + new + call setline(1, 'nothing') + call assert_fails('script ' . lastnr, 'E37:') + exe 'script! ' . lastnr + call assert_equal('Xscripting', expand('%:t')) + + bwipe + call delete('Xscripting') +endfunc diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim index b05ed4271a..eadb128e03 100644 --- a/src/testdir/test_search.vim +++ b/src/testdir/test_search.vim @@ -1142,3 +1142,15 @@ func Test_search_sentence() /\%'( / endfunc + +" Test that there is no crash when there is a last search pattern but no last +" substitute pattern. +func Test_no_last_substitute_pat() + " Use viminfo to set the last search pattern to a string and make the last + " substitute pattern the most recent used and make it empty (NULL). + call writefile(['~MSle0/bar', '~MSle0~&'], 'Xviminfo') + rviminfo! Xviminfo + call assert_fails('normal n', 'E35:') + + call delete('Xviminfo') +endfunc diff --git a/src/testdir/test_syntax.vim b/src/testdir/test_syntax.vim index ffa8e9022b..c0be4a0eff 100644 --- a/src/testdir/test_syntax.vim +++ b/src/testdir/test_syntax.vim @@ -119,6 +119,15 @@ func Test_syntime() bd endfunc +func Test_syntime_completion() + if !has('profile') + return + endif + + call feedkeys(":syntime \\\"\", 'tx') + call assert_equal('"syntime clear off on report', @:) +endfunc + func Test_syntax_list() syntax on let a = execute('syntax list') diff --git a/src/testdir/test_usercommands.vim b/src/testdir/test_usercommands.vim index 21b1c4c0fe..2709988ac6 100644 --- a/src/testdir/test_usercommands.vim +++ b/src/testdir/test_usercommands.vim @@ -154,7 +154,7 @@ func Test_CmdCompletion() call assert_equal('"com -nargs=* + 0 1 ?', @:) call feedkeys(":com -addr=\\\"\", 'tx') - call assert_equal('"com -addr=arguments buffers lines loaded_buffers quickfix tabs windows', @:) + call assert_equal('"com -addr=arguments buffers lines loaded_buffers other quickfix tabs windows', @:) call feedkeys(":com -complete=co\\\"\", 'tx') call assert_equal('"com -complete=color command compiler', @:) @@ -218,3 +218,61 @@ func Test_use_execute_in_completion() call assert_equal('"DoExec hi', @:) delcommand DoExec endfunc + +func Test_addr_all() + command! -addr=lines DoSomething let g:a1 = | let g:a2 = + %DoSomething + call assert_equal(1, g:a1) + call assert_equal(line('$'), g:a2) + + command! -addr=arguments DoSomething let g:a1 = | let g:a2 = + args one two three + %DoSomething + call assert_equal(1, g:a1) + call assert_equal(3, g:a2) + + command! -addr=buffers DoSomething let g:a1 = | let g:a2 = + %DoSomething + for low in range(1, bufnr('$')) + if buflisted(low) + break + endif + endfor + call assert_equal(low, g:a1) + call assert_equal(bufnr('$'), g:a2) + + command! -addr=loaded_buffers DoSomething let g:a1 = | let g:a2 = + %DoSomething + for low in range(1, bufnr('$')) + if bufloaded(low) + break + endif + endfor + call assert_equal(low, g:a1) + for up in range(bufnr('$'), 1, -1) + if bufloaded(up) + break + endif + endfor + call assert_equal(up, g:a2) + + command! -addr=windows DoSomething let g:a1 = | let g:a2 = + new + %DoSomething + call assert_equal(1, g:a1) + call assert_equal(winnr('$'), g:a2) + bwipe + + command! -addr=tabs DoSomething let g:a1 = | let g:a2 = + tabnew + %DoSomething + call assert_equal(1, g:a1) + call assert_equal(len(gettabinfo()), g:a2) + bwipe + + command! -addr=other DoSomething echo 'nothing' + DoSomething + call assert_fails('%DoSomething') + + delcommand DoSomething +endfunc diff --git a/src/version.c b/src/version.c index 4fff642acb..1a878b6e94 100644 --- a/src/version.c +++ b/src/version.c @@ -807,6 +807,28 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 560, +/**/ + 559, +/**/ + 558, +/**/ + 557, +/**/ + 556, +/**/ + 555, +/**/ + 554, +/**/ + 553, +/**/ + 552, +/**/ + 551, +/**/ + 550, /**/ 549, /**/ diff --git a/uninstal.txt b/uninstal.txt index 3b57921ff4..2fb8927740 100644 --- a/uninstal.txt +++ b/uninstal.txt @@ -1,4 +1,4 @@ -Uninstalling Vim on Dos and MS-Windows. +Uninstalling Vim on MS-Windows. There are three ways to remove Vim: @@ -27,12 +27,11 @@ messages to avoid deleting something you want to keep. Here are guidelines for removing Vim by hand: -1. Remove the "Edit with Vim" popup menu entry, if it exists. This will only - be on MS-Windows 95/98/NT. This is done by running the uninstal.exe - program. It removes the registry entries for the "Edit with Vim" popup - menu entry. You only need to run uninstal.exe when you have installed the - menu entry. You can also run uninstal.exe from the Control panel with the - Add/Remove programs application. +1. Remove the "Edit with Vim" popup menu entry, if it exists. This is done by + running the uninstal.exe program. It removes the registry entries for the + "Edit with Vim" popup menu entry. You only need to run uninstal.exe when + you have installed the menu entry. You can also run uninstal.exe from the + Control panel with the Add/Remove programs application. Note that uninstal.exe offers you the option to uninstal other items. You can skip this. @@ -55,8 +54,8 @@ Here are guidelines for removing Vim by hand: skip the next step. 5. Delete the distributed files. If you followed the directions, these will - be located in a directory like "C:\vim\vim80". If the $VIM environment - variable is set, the directory will be $VIM\vim80. Delete the "vim80" + be located in a directory like "C:\vim\vim81". If the $VIM environment + variable is set, the directory will be $VIM\vim81. Delete the "vim81" directory and all that is in it. Warning: If you changed any of the distributed files, or added some of your own files, you might want to save these first. But normally you would not have changed or added files here. @@ -66,10 +65,8 @@ Here are guidelines for removing Vim by hand: another version of Vim. $VIMRUNTIME is mostly not set. Check if $PATH contains the path of the vim directory. Note that $PATH may be set in several places, you will have to find the right one, and only delete the - Vim path from it. You can most likely find the lines that set $PATH, $VIM - and/or $VIMRUNTIME in C:\autoexec.bat. Under Windows NT you might need to - use the "System Properties" editor to change the environment variables, if - they are not in the C:\autoexec.bat file. You can start it by selecting + Vim path from it. You might need to use the "System Properties" editor to + change the environment variables. You can start it by selecting Start/Settings/Control Panel and then "System". 7. If you added a Vim entry in the start menu, delete it.