diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index e5fc361f1c..fd062b2daa 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -52,9 +52,6 @@ effects. Be careful not to destroy your text. ============================================================================== 2. Defining autocommands *autocmd-define* -Note: The ":autocmd" command cannot be followed by another command, since any -'|' is considered part of the command. - *:au* *:autocmd* :au[tocmd] [group] {event} {pat} [nested] {cmd} Add {cmd} to the list of commands that Vim will @@ -67,6 +64,12 @@ Note: The ":autocmd" command cannot be followed by another command, since any The special pattern or defines a buffer-local autocommand. See |autocmd-buflocal|. +Note: The ":autocmd" command can only be followed by another command when the +'|' appears before {cmd}. This works: > + :augroup mine | au! BufRead | augroup END +But this sees "augroup" as part of the defined command: > + :augroup mine | au BufRead * set tw=70 | augroup END + Note that special characters (e.g., "%", "") in the ":autocmd" arguments are not expanded when the autocommand is defined. These will be expanded when the Event is recognized, and the {cmd} is executed. The only diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 5d3b6fb0cf..d2ae55eea6 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2636,11 +2636,17 @@ A jump table for the options with a short description can be found at |Q_op|. Change the way text is displayed. This is comma separated list of flags: lastline When included, as much as possible of the last line - in a window will be displayed. When not included, a - last line that doesn't fit is replaced with "@" lines. + in a window will be displayed. "@@@" is put in the + last columns of the last screen line to indicate the + rest of the line is not displayed. + truncate Like "lastline", but "@@@" is displayed in the first + column of the last screen line. Overrules "lastline". uhex Show unprintable characters hexadecimal as instead of using ^C and ~C. + When neither "lastline" or "truncate" is included, a last line that + doesn't fit is replaced with "@" lines. + *'eadirection'* *'ead'* 'eadirection' 'ead' string (default "both") global diff --git a/src/auto/configure b/src/auto/configure index c6bba8130e..e0ecbbd679 100755 --- a/src/auto/configure +++ b/src/auto/configure @@ -759,6 +759,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -894,6 +895,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' @@ -1146,6 +1148,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1283,7 +1294,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1436,6 +1447,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1520,7 +1532,7 @@ Optional Packages: --with-view-name=NAME what to call the View executable --with-global-runtime=DIR global runtime directory in 'runtimepath' --with-modified-by=NAME name of who modified a release version - --with-features=TYPE tiny, small, normal, big or huge (default: normal) + --with-features=TYPE tiny, small, normal, big or huge (default: huge) --with-compiledby=NAME name to show in :version message --with-lua-prefix=PFX Prefix where Lua is installed. --with-luajit Link with LuaJIT instead of Lua. diff --git a/src/configure.in b/src/configure.in index 4e24c45492..c1a2da36ca 100644 --- a/src/configure.in +++ b/src/configure.in @@ -456,7 +456,7 @@ fi dnl Check user requested features. AC_MSG_CHECKING(--with-features argument) -AC_ARG_WITH(features, [ --with-features=TYPE tiny, small, normal, big or huge (default: normal)], +AC_ARG_WITH(features, [ --with-features=TYPE tiny, small, normal, big or huge (default: huge)], features="$withval"; AC_MSG_RESULT($features), features="huge"; AC_MSG_RESULT(Defaulting to huge)) diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 7d8196cdc0..2afa5e733a 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -4008,6 +4008,7 @@ do_ecmd( } vim_free(new_name); au_new_curbuf.br_buf = NULL; + au_new_curbuf.br_buf_free_count = 0; #endif } @@ -4389,6 +4390,7 @@ delbuf_msg(char_u *name) name == NULL ? (char_u *)"" : name); vim_free(name); au_new_curbuf.br_buf = NULL; + au_new_curbuf.br_buf_free_count = 0; } #endif diff --git a/src/fileio.c b/src/fileio.c index d26bcf9fe2..d53dff5dd8 100644 --- a/src/fileio.c +++ b/src/fileio.c @@ -8138,8 +8138,8 @@ event_name2nr(char_u *start, char_u **end) int i; int len; - /* the event name ends with end of line, a blank or a comma */ - for (p = start; *p && !vim_iswhite(*p) && *p != ','; ++p) + /* the event name ends with end of line, '|', a blank or a comma */ + for (p = start; *p && !vim_iswhite(*p) && *p != ',' && *p != '|'; ++p) ; for (i = 0; event_names[i].name != NULL; ++i) { @@ -8191,7 +8191,7 @@ find_end_event( } else { - for (pat = arg; *pat && !vim_iswhite(*pat); pat = p) + for (pat = arg; *pat && *pat != '|' && !vim_iswhite(*pat); pat = p) { if ((int)event_name2nr(pat, &p) >= (int)NUM_EVENTS) { @@ -8324,8 +8324,9 @@ au_event_restore(char_u *old_ei) * Mostly a {group} argument can optionally appear before . */ void -do_autocmd(char_u *arg, int forceit) +do_autocmd(char_u *arg_in, int forceit) { + char_u *arg = arg_in; char_u *pat; char_u *envpat = NULL; char_u *cmd; @@ -8334,12 +8335,20 @@ do_autocmd(char_u *arg, int forceit) int nested = FALSE; int group; - /* - * Check for a legal group name. If not, use AUGROUP_ALL. - */ - group = au_get_grouparg(&arg); - if (arg == NULL) /* out of memory */ - return; + if (*arg == '|') + { + arg = (char_u *)""; + group = AUGROUP_ALL; /* no argument, use all groups */ + } + else + { + /* + * Check for a legal group name. If not, use AUGROUP_ALL. + */ + group = au_get_grouparg(&arg); + if (arg == NULL) /* out of memory */ + return; + } /* * Scan over the events. @@ -8349,53 +8358,61 @@ do_autocmd(char_u *arg, int forceit) if (pat == NULL) return; - /* - * Scan over the pattern. Put a NUL at the end. - */ pat = skipwhite(pat); - cmd = pat; - while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\')) - cmd++; - if (*cmd) - *cmd++ = NUL; - - /* Expand environment variables in the pattern. Set 'shellslash', we want - * forward slashes here. */ - if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) + if (*pat == '|') { -#ifdef BACKSLASH_IN_FILENAME - int p_ssl_save = p_ssl; - - p_ssl = TRUE; -#endif - envpat = expand_env_save(pat); -#ifdef BACKSLASH_IN_FILENAME - p_ssl = p_ssl_save; -#endif - if (envpat != NULL) - pat = envpat; + pat = (char_u *)""; + cmd = (char_u *)""; } - - /* - * Check for "nested" flag. - */ - cmd = skipwhite(cmd); - if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6])) + else { - nested = TRUE; - cmd = skipwhite(cmd + 6); - } + /* + * Scan over the pattern. Put a NUL at the end. + */ + cmd = pat; + while (*cmd && (!vim_iswhite(*cmd) || cmd[-1] == '\\')) + cmd++; + if (*cmd) + *cmd++ = NUL; - /* - * Find the start of the commands. - * Expand in it. - */ - if (*cmd != NUL) - { - cmd = expand_sfile(cmd); - if (cmd == NULL) /* some error */ - return; - need_free = TRUE; + /* Expand environment variables in the pattern. Set 'shellslash', we want + * forward slashes here. */ + if (vim_strchr(pat, '$') != NULL || vim_strchr(pat, '~') != NULL) + { +#ifdef BACKSLASH_IN_FILENAME + int p_ssl_save = p_ssl; + + p_ssl = TRUE; +#endif + envpat = expand_env_save(pat); +#ifdef BACKSLASH_IN_FILENAME + p_ssl = p_ssl_save; +#endif + if (envpat != NULL) + pat = envpat; + } + + /* + * Check for "nested" flag. + */ + cmd = skipwhite(cmd); + if (*cmd != NUL && STRNCMP(cmd, "nested", 6) == 0 && vim_iswhite(cmd[6])) + { + nested = TRUE; + cmd = skipwhite(cmd + 6); + } + + /* + * Find the start of the commands. + * Expand in it. + */ + if (*cmd != NUL) + { + cmd = expand_sfile(cmd); + if (cmd == NULL) /* some error */ + return; + need_free = TRUE; + } } /* @@ -8412,7 +8429,7 @@ do_autocmd(char_u *arg, int forceit) */ last_event = (event_T)-1; /* for listing the event name */ last_group = AUGROUP_ERROR; /* for listing the group name */ - if (*arg == '*' || *arg == NUL) + if (*arg == '*' || *arg == NUL || *arg == '|') { for (event = (event_T)0; (int)event < (int)NUM_EVENTS; event = (event_T)((int)event + 1)) @@ -8422,7 +8439,7 @@ do_autocmd(char_u *arg, int forceit) } else { - while (*arg && !vim_iswhite(*arg)) + while (*arg && *arg != '|' && !vim_iswhite(*arg)) if (do_autocmd_event(event_name2nr(arg, &arg), pat, nested, cmd, forceit, group) == FAIL) break; @@ -8447,7 +8464,8 @@ au_get_grouparg(char_u **argp) char_u *arg = *argp; int group = AUGROUP_ALL; - p = skiptowhite(arg); + for (p = arg; *p && !vim_iswhite(*p) && *p != '|'; ++p) + ; if (p > arg) { group_name = vim_strnsave(arg, (int)(p - arg)); diff --git a/src/globals.h b/src/globals.h index fedf6c009c..73be9a2b3c 100644 --- a/src/globals.h +++ b/src/globals.h @@ -384,7 +384,7 @@ EXTERN int keep_filetype INIT(= FALSE); /* value for did_filetype when /* When deleting the current buffer, another one must be loaded. If we know * which one is preferred, au_new_curbuf is set to it */ -EXTERN bufref_T au_new_curbuf INIT(= {NULL}); +EXTERN bufref_T au_new_curbuf INIT(= {NULL COMMA 0}); /* When deleting a buffer/window and autocmd_busy is TRUE, do not free the * buffer/window. but link it in the list starting with @@ -1359,11 +1359,8 @@ EXTERN int term_is_xterm INIT(= FALSE); /* xterm-like 'term' */ #ifdef BACKSLASH_IN_FILENAME EXTERN char psepc INIT(= '\\'); /* normal path separator character */ EXTERN char psepcN INIT(= '/'); /* abnormal path separator character */ -EXTERN char pseps[2] /* normal path separator string */ -# ifdef DO_INIT - = {'\\', 0} -# endif - ; +/* normal path separator string */ +EXTERN char pseps[2] INIT(= {'\\' COMMA 0}); #endif #ifdef FEAT_VIRTUALEDIT diff --git a/src/option.h b/src/option.h index 0e7153b524..1b5d3a3c2a 100644 --- a/src/option.h +++ b/src/option.h @@ -454,10 +454,11 @@ EXTERN char_u *p_dir; /* 'directory' */ EXTERN char_u *p_dy; /* 'display' */ EXTERN unsigned dy_flags; #ifdef IN_OPTION_C -static char *(p_dy_values[]) = {"lastline", "uhex", NULL}; +static char *(p_dy_values[]) = {"lastline", "truncate", "uhex", NULL}; #endif #define DY_LASTLINE 0x001 -#define DY_UHEX 0x002 +#define DY_TRUNCATE 0x002 +#define DY_UHEX 0x004 EXTERN int p_ed; /* 'edcompatible' */ #ifdef FEAT_WINDOWS EXTERN char_u *p_ead; /* 'eadirection' */ diff --git a/src/screen.c b/src/screen.c index c1d47280e9..b8f5410473 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2018,7 +2018,7 @@ win_update(win_T *wp) && wp->w_lines[idx].wl_valid && wp->w_lines[idx].wl_lnum == lnum && lnum > wp->w_topline - && !(dy_flags & DY_LASTLINE) + && !(dy_flags & (DY_LASTLINE | DY_TRUNCATE)) && srow + wp->w_lines[idx].wl_size > wp->w_height #ifdef FEAT_DIFF && diff_check_fill(wp, lnum) == 0 @@ -2139,6 +2139,21 @@ win_update(win_T *wp) wp->w_filler_rows = wp->w_height - srow; } #endif + else if (dy_flags & DY_TRUNCATE) /* 'display' has "truncate" */ + { + int scr_row = W_WINROW(wp) + wp->w_height - 1; + + /* + * Last line isn't finished: Display "@@@" in the last screen line. + */ + screen_puts_len((char_u *)"@@", 2, scr_row, W_WINCOL(wp), + hl_attr(HLF_AT)); + screen_fill(scr_row, scr_row + 1, + (int)W_WINCOL(wp) + 2, (int)W_ENDCOL(wp), + '@', ' ', hl_attr(HLF_AT)); + set_empty_rows(wp, srow); + wp->w_botline = lnum; + } else if (dy_flags & DY_LASTLINE) /* 'display' has "lastline" */ { /* diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim index 580c42fe4d..b9d5cfe27b 100644 --- a/src/testdir/test_autocmd.vim +++ b/src/testdir/test_autocmd.vim @@ -19,6 +19,7 @@ if has('timers') call timer_start(100, 'ExitInsertMode') call feedkeys('a', 'x!') call assert_equal(1, g:triggered) + au! CursorHoldI endfunc func Test_cursorhold_insert_ctrl_x() @@ -29,6 +30,7 @@ if has('timers') " CursorHoldI does not trigger after CTRL-X call feedkeys("a\", 'x!') call assert_equal(0, g:triggered) + au! CursorHoldI endfunc endif @@ -58,6 +60,7 @@ function Test_bufunload() bwipeout call assert_equal(["bufunload", "bufdelete", "bufwipeout"], s:li) + au! test_bufunload_group augroup! test_bufunload_group endfunc @@ -120,3 +123,31 @@ func Test_win_tab_autocmd() augroup END unlet g:record endfunc + +func s:AddAnAutocmd() + augroup vimBarTest + au BufReadCmd * echo 'hello' + augroup END + call assert_equal(3, len(split(execute('au vimBarTest'), "\n"))) +endfunc + +func Test_early_bar() + " test that a bar is recognized before the {event} + call s:AddAnAutocmd() + augroup vimBarTest | au! | augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + + call s:AddAnAutocmd() + augroup vimBarTest| au!| augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + + " test that a bar is recognized after the {event} + call s:AddAnAutocmd() + augroup vimBarTest| au!BufReadCmd| augroup END + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) + + " test that a bar is recognized after the {group} + call s:AddAnAutocmd() + au! vimBarTest|echo 'hello' + call assert_equal(1, len(split(execute('au vimBarTest'), "\n"))) +endfunc diff --git a/src/testdir/test_netbeans.vim b/src/testdir/test_netbeans.vim index 240271e7a2..97c3e79426 100644 --- a/src/testdir/test_netbeans.vim +++ b/src/testdir/test_netbeans.vim @@ -27,6 +27,7 @@ func Nb_basic(port) " Opening Makefile will result in a setDot command call WaitFor('len(readfile("Xnetbeans")) > 4') + call WaitFor('getcurpos()[1] == 2') let pos = getcurpos() call assert_equal(2, pos[1]) call assert_equal(20, pos[2]) diff --git a/src/userfunc.c b/src/userfunc.c index 32bcceece2..30eeb347fb 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -2640,11 +2640,11 @@ ex_delfunction(exarg_T *eap) void func_unref(char_u *name) { - ufunc_T *fp; + ufunc_T *fp = NULL; if (name == NULL) return; - else if (isdigit(*name)) + if (isdigit(*name)) { fp = find_func(name); if (fp == NULL) @@ -2654,25 +2654,18 @@ func_unref(char_u *name) #endif EMSG2(_(e_intern2), "func_unref()"); } - else if (--fp->uf_refcount <= 0) - { - /* Only delete it when it's not being used. Otherwise it's done - * when "uf_calls" becomes zero. */ - if (fp->uf_calls == 0) - func_free(fp); - } } else if (STRNCMP(name, "", 8) == 0) { /* fail silently, when lambda function isn't found. */ fp = find_func(name); - if (fp != NULL && --fp->uf_refcount <= 0) - { - /* Only delete it when it's not being used. Otherwise it's done - * when "uf_calls" becomes zero. */ - if (fp->uf_calls == 0) - func_free(fp); - } + } + if (fp != NULL && --fp->uf_refcount <= 0) + { + /* Only delete it when it's not being used. Otherwise it's done + * when "uf_calls" becomes zero. */ + if (fp->uf_calls == 0) + func_free(fp); } } diff --git a/src/version.c b/src/version.c index f18cf92251..78ee3ba4a5 100644 --- a/src/version.c +++ b/src/version.c @@ -773,6 +773,20 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2109, +/**/ + 2108, +/**/ + 2107, +/**/ + 2106, +/**/ + 2105, +/**/ + 2104, +/**/ + 2103, /**/ 2102, /**/ diff --git a/src/vim.h b/src/vim.h index a344998e5c..b93efd418a 100644 --- a/src/vim.h +++ b/src/vim.h @@ -1768,6 +1768,7 @@ int vim_memcmp(void *, void *, size_t); # ifndef INIT # define INIT(x) x # define DO_INIT +# define COMMA , # endif #endif