From 76a6345433bc2a600689397fb28165a2e5793720 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 28 Nov 2018 20:38:37 +0100 Subject: [PATCH 01/11] patch 8.1.0550: expression evaluation may repeat an error message Problem: Expression evaluation may repeat an error message. (Jason Franklin) Solution: Increment did_emsg and check for the value when giving an error for the echo command. --- src/eval.c | 3 ++- src/message.c | 4 ++-- src/testdir/test108.ok | 2 -- src/version.c | 2 ++ 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/eval.c b/src/eval.c index 4a3cf99124..a525678354 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; diff --git a/src/message.c b/src/message.c index c2318bd8af..5a990ff604 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/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/version.c b/src/version.c index 1fb70f8826..d8d66f0ef0 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 550, /**/ 549, /**/ From 8ff5af9544a2abc3d344bba017ef96682e098d9d Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Wed, 28 Nov 2018 21:20:38 +0100 Subject: [PATCH 02/11] patch 8.1.0551: expression evaluation may repeat an error message Problem: Expression evaluation may repeat an error message. (Jason Franklin) Solution: Check for the value of did_emsg when giving an error for the :execute command. --- src/eval.c | 4 ++-- src/version.c | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/eval.c b/src/eval.c index a525678354..7dfb981254 100644 --- a/src/eval.c +++ b/src/eval.c @@ -8115,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); @@ -8131,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/version.c b/src/version.c index d8d66f0ef0..29f3ec52e0 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 551, /**/ 550, /**/ From 01a060da74b756b161e595b39a7877cb7612120a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Nov 2018 21:57:55 +0100 Subject: [PATCH 03/11] patch 8.1.0552: saved last search pattern may not be restored Problem: Saved last search pattern may not be restored. Solution: Call restore_last_search_pattern(). Add a check for balancing saving and restoring the last search pattern. --- src/ex_getln.c | 4 ++++ src/search.c | 14 ++++++++++++++ src/version.c | 2 ++ 3 files changed, 20 insertions(+) diff --git a/src/ex_getln.c b/src/ex_getln.c index acccd27321..bfda942783 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/search.c b/src/search.c index 98665f795f..d7aa59278d 100644 --- a/src/search.c +++ b/src/search.c @@ -96,6 +96,7 @@ static struct spat saved_spats[2]; /* 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; # endif @@ -364,6 +365,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); @@ -374,8 +380,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 diff --git a/src/version.c b/src/version.c index 29f3ec52e0..1fc35edd73 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 552, /**/ 551, /**/ From 07dc18ffa4e7ed202f219fe2fd3d6f58246f71f9 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Fri, 30 Nov 2018 22:48:32 +0100 Subject: [PATCH 04/11] patch 8.1.0553: it is not easy to edit a script that was sourced Problem: It is not easy to edit a script that was sourced. Solution: Add a count to ":scriptnames", so that ":script 40" edits the script with script ID 40. --- runtime/doc/repeat.txt | 3 +++ src/Make_all.mak | 1 + src/ex_cmds.h | 22 +++++++++++----------- src/ex_cmds2.c | 15 ++++++++++++++- src/testdir/Make_all.mak | 1 + src/testdir/test_scriptnames.vim | 26 ++++++++++++++++++++++++++ src/version.c | 2 ++ 7 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 src/testdir/test_scriptnames.vim 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/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/ex_cmds.h b/src/ex_cmds.h index c5e0bf4495..335871a01b 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; @@ -1260,8 +1260,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 d6b6f5bf89..c3f26b64c5 100644 --- a/src/ex_cmds2.c +++ b/src/ex_cmds2.c @@ -4690,10 +4690,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/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/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/version.c b/src/version.c index 1fc35edd73..5f61775ac0 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 553, /**/ 552, /**/ From 614ab8aa00346724bfc27980d25985d482269b75 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 1 Dec 2018 11:59:00 +0100 Subject: [PATCH 05/11] patch 8.1.0554: popup menu overlaps with preview window Problem: Popup menu overlaps with preview window. Solution: Adjust the height computation. (Hirohito Higashi, closes #3414) --- src/popupmnu.c | 17 ++++---------- .../Test_popup_and_previewwindow_01.dump | 20 +++++++++++++++++ src/testdir/test_popup.vim | 22 +++++++++++++++++++ src/version.c | 2 ++ 4 files changed, 48 insertions(+), 13 deletions(-) create mode 100644 src/testdir/dumps/Test_popup_and_previewwindow_01.dump 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/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/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/version.c b/src/version.c index 5f61775ac0..6cce56670d 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 554, /**/ 553, /**/ From 2fb8f684d888ad68b283ba8f9505106b5fb725be Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 1 Dec 2018 13:14:45 +0100 Subject: [PATCH 06/11] patch 8.1.0555: crash when last search pat is set but not last substitute pat Problem: Crash when last search pat is set but not last substitute pat. Solution: Do not mix up last search pattern and last subtitute pattern. (closes #3647) --- src/search.c | 2 +- src/testdir/test_search.vim | 12 ++++++++++++ src/version.c | 2 ++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/search.c b/src/search.c index d7aa59278d..6d245caffc 100644 --- a/src/search.c +++ b/src/search.c @@ -1385,7 +1385,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/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/version.c b/src/version.c index 6cce56670d..566f94da55 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 555, /**/ 554, /**/ From ed8bc78d2386d22656ba1d3e5cf739dd12964dce Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sat, 1 Dec 2018 21:08:21 +0100 Subject: [PATCH 07/11] patch 8.1.0556: saving/restoring search patterns share saved last_idx Problem: Saving/restoring search patterns share saved last_idx. Solution: Use a separate saved last_idx for saving search patterns for functions and incremental search. --- src/search.c | 25 ++++++++++++++----------- src/version.c | 2 ++ 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/search.c b/src/search.c index 6d245caffc..0cbbf4fefb 100644 --- a/src/search.c +++ b/src/search.c @@ -93,12 +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 did_save_last_search_spat = 0; -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() */ @@ -310,8 +306,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 } } @@ -329,8 +325,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 } } @@ -354,6 +350,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. @@ -575,7 +578,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. */ diff --git a/src/version.c b/src/version.c index 566f94da55..55a9af65cc 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 556, /**/ 555, /**/ From 5378e1cf0a05121bfa76df2279944ad3b0b5ce4f Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 2 Dec 2018 13:47:03 +0100 Subject: [PATCH 08/11] patch 8.1.0557: Termdebug: gdb may use X.Y for breakpoint number Problem: Termdebug: gdb may use X.Y for breakpoint number. Solution: Handle X.Y breakpoint numbers. (Yasuhiro Matsumoto, close #3641) --- .../dist/opt/termdebug/plugin/termdebug.vim | 182 ++++++++++-------- src/version.c | 2 + 2 files changed, 104 insertions(+), 80 deletions(-) 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/version.c b/src/version.c index 55a9af65cc..bdc8007e50 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 557, /**/ 556, /**/ From d2ec51f399607d2df6ed1155b0bd303e722d6978 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 2 Dec 2018 13:58:00 +0100 Subject: [PATCH 09/11] patch 8.1.0558: some MS-Windows instructions are outdated Problem: Some MS-Windows instructions are outdated. Solution: Update the uninstall instructions and the NSIS README. (Ken Takata, closes #3614) Also update remark about diff.exe. --- nsis/README.txt | 14 ++++++++------ src/version.c | 2 ++ uninstal.txt | 23 ++++++++++------------- 3 files changed, 20 insertions(+), 19 deletions(-) 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/src/version.c b/src/version.c index bdc8007e50..b44f5b8850 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 558, /**/ 557, /**/ 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. From b513d3079bbe3f59a1f1a3d6931939a76cd7e54a Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 2 Dec 2018 14:55:08 +0100 Subject: [PATCH 10/11] patch 8.1.0559: command line completion not sufficiently tested Problem: Command line completion not sufficiently tested. Solution: Add more tests. (Dominique Pelle, closes #3622) --- src/testdir/test_arglist.vim | 12 ++++++++++++ src/testdir/test_filetype.vim | 4 ++++ src/testdir/test_history.vim | 5 +++++ src/testdir/test_messages.vim | 5 +++++ src/testdir/test_syntax.vim | 9 +++++++++ src/version.c | 2 ++ 6 files changed, 37 insertions(+) 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_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/version.c b/src/version.c index b44f5b8850..bbf32f5c3c 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 559, /**/ 558, /**/ From 51a7454cd2c34ee459f104e45768eab3817c099e Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Sun, 2 Dec 2018 18:21:49 +0100 Subject: [PATCH 11/11] patch 8.1.0560: cannot use address type "other" with with user command Problem: Cannot use address type "other" with with user command. Solution: Add "other" to the list. (Daniel Hahler, closes #3655) Also reject "%" for commands with "other". Add some more tests. --- src/ex_docmd.c | 2 ++ src/testdir/test_usercommands.vim | 60 ++++++++++++++++++++++++++++++- src/version.c | 2 ++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ex_docmd.c b/src/ex_docmd.c index d00ca5689d..9040c0d073 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -2998,6 +2998,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: @@ -5940,6 +5941,7 @@ static struct {ADDR_BUFFERS, "buffers"}, {ADDR_WINDOWS, "windows"}, {ADDR_QUICKFIX, "quickfix"}, + {ADDR_OTHER, "other"}, {-1, NULL} }; #endif 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 bbf32f5c3c..355b114808 100644 --- a/src/version.c +++ b/src/version.c @@ -792,6 +792,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 560, /**/ 559, /**/