diff --git a/.github/CODEOWNERS_vim b/.github/CODEOWNERS_vim index b95e493ec2..4972e38bc5 100644 --- a/.github/CODEOWNERS_vim +++ b/.github/CODEOWNERS_vim @@ -142,6 +142,7 @@ runtime/syntax/csh.vim @cecamp runtime/syntax/cucumber.vim @tpope runtime/syntax/datascript.vim @dpelle runtime/syntax/dcl.vim @cecamp +runtime/syntax/desktop.vim @e-kwsm runtime/syntax/doxygen.vim @frogonwheels runtime/syntax/dtd.vim @chrisbra runtime/syntax/elmfilt.vim @cecamp @@ -152,6 +153,7 @@ runtime/syntax/gitcommit.vim @tpope runtime/syntax/gitconfig.vim @tpope runtime/syntax/gitrebase.vim @tpope runtime/syntax/gprof.vim @dpelle +runtime/syntax/groff.vim @jmarshall runtime/syntax/haml.vim @tpope runtime/syntax/haskell.vim @coot runtime/syntax/hgcommit.vim @k-takata @@ -162,10 +164,10 @@ runtime/syntax/lisp.vim @cecamp runtime/syntax/lynx.vim @dkearns runtime/syntax/mailcap.vim @dkearns runtime/syntax/make.vim @rohieb -runtime/syntax/make.vim @rohieb runtime/syntax/maple.vim @cecamp runtime/syntax/markdown.vim @tpope runtime/syntax/netrw.vim @cecamp +runtime/syntax/nroff.vim @jmarshall runtime/syntax/nsis.vim @k-takata runtime/syntax/pdf.vim @tpope runtime/syntax/php.vim @TysonAndre @@ -180,7 +182,9 @@ runtime/syntax/sh.vim @cecamp runtime/syntax/sm.vim @cecamp runtime/syntax/spec.vim @ignatenkobrain runtime/syntax/sqloracle.vim @chrisbra +runtime/syntax/sshconfig.vim @Jakuje runtime/syntax/sshdconfig.vim @Jakuje +runtime/syntax/sudoers.vim @e-kwsm runtime/syntax/tags.vim @cecamp runtime/syntax/teraterm.vim @k-takata runtime/syntax/tex.vim @cecamp diff --git a/runtime/doc/autocmd.txt b/runtime/doc/autocmd.txt index 929146ccf5..7737355d51 100644 --- a/runtime/doc/autocmd.txt +++ b/runtime/doc/autocmd.txt @@ -1,4 +1,4 @@ -*autocmd.txt* For Vim version 8.2. Last change: 2021 Jan 28 +*autocmd.txt* For Vim version 8.2. Last change: 2021 Mar 13 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1526,9 +1526,11 @@ option will not cause any commands to be executed. *:doautoa* *:doautoall* :doautoa[ll] [] [group] {event} [fname] Like ":doautocmd", but apply the autocommands to each - loaded buffer. Note that [fname] is used to select - the autocommands, not the buffers to which they are - applied. + loaded buffer. The current buffer is done last. + + Note that [fname] is used to select the autocommands, + not the buffers to which they are applied. + Careful: Don't use this for autocommands that delete a buffer, change to another buffer or change the contents of a buffer; the result is unpredictable. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 32a9de99e9..e0850c7d30 100644 --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -1,4 +1,4 @@ -*eval.txt* For Vim version 8.2. Last change: 2021 Mar 10 +*eval.txt* For Vim version 8.2. Last change: 2021 Mar 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -5119,6 +5119,13 @@ getbufinfo([{dict}]) listed TRUE if the buffer is listed. lnum Line number used for the buffer when opened in the current window. + Only valid if the buffer has been + displayed in the window in the past. + If you want the line number of the + last known cursor position in a given + window, use |line()|: > + :echo line('.', {winid}) +< linecount Number of lines in the buffer (only valid when loaded) loaded TRUE if the buffer is loaded. @@ -6107,12 +6114,12 @@ getwininfo([{winid}]) *getwininfo()* width window width winbar 1 if the window has a toolbar, 0 otherwise - wincol leftmost screen column of the window, - col from |win_screenpos()| + wincol leftmost screen column of the window; + "col" from |win_screenpos()| winid |window-ID| winnr window number - winrow topmost screen column of the window, - row from |win_screenpos()| + winrow topmost screen line of the window; + "row" from |win_screenpos()| Can also be used as a |method|: > GetWinnr()->getwininfo() @@ -12827,8 +12834,8 @@ text... it can no longer be changed (until it is unlocked). A locked variable can be deleted: > :lockvar v - :let v = 'asdf' " fails! - :unlet v + :let v = 'asdf' " fails! + :unlet v " works < *E741* *E940* If you try to change a locked variable you get an error message: "E741: Value is locked: {name}". diff --git a/runtime/doc/index.txt b/runtime/doc/index.txt index 447eb7bff1..52dd700c5d 100644 --- a/runtime/doc/index.txt +++ b/runtime/doc/index.txt @@ -1,4 +1,4 @@ -*index.txt* For Vim version 8.2. Last change: 2021 Feb 14 +*index.txt* For Vim version 8.2. Last change: 2021 Mar 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -1294,6 +1294,7 @@ tag command action ~ |:edit| :e[dit] edit a file |:earlier| :ea[rlier] go to older change, undo |:echo| :ec[ho] echoes the result of expressions +|:echoconsole| :echoc[onsole] like :echomsg but write to stdout |:echoerr| :echoe[rr] like :echo, show like an error and use history |:echohl| :echoh[l] set highlighting for echo commands |:echomsg| :echom[sg] same as :echo, put message in history diff --git a/runtime/doc/map.txt b/runtime/doc/map.txt index 873d5d6d7a..47e706bc22 100644 --- a/runtime/doc/map.txt +++ b/runtime/doc/map.txt @@ -1,4 +1,4 @@ -*map.txt* For Vim version 8.2. Last change: 2020 Dec 10 +*map.txt* For Vim version 8.2. Last change: 2021 Mar 17 VIM REFERENCE MANUAL by Bram Moolenaar @@ -271,8 +271,8 @@ typeahead, before the previous command has been executed. For example: > endfunc nnoremap x StoreColumn() nmap ! f!x -You will notice that g:column has the value from before executing "fx", -because "z" is evaluated before "fx" is executed. +You will notice that g:column has the value from before executing "f!", +because "x" is evaluated before "f!" is executed. This can be solved by inserting before the character that is expression-mapped: > nmap ! f!x diff --git a/runtime/doc/motion.txt b/runtime/doc/motion.txt index d6215a4c61..4dc0e2e28c 100644 --- a/runtime/doc/motion.txt +++ b/runtime/doc/motion.txt @@ -1,4 +1,4 @@ -*motion.txt* For Vim version 8.2. Last change: 2020 Oct 18 +*motion.txt* For Vim version 8.2. Last change: 2021 Mar 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -942,8 +942,7 @@ These commands are not marks themselves, but jump to a mark: line. *]`* -]` [count] times to lowercase mark after the cursor. {not - in Vi} +]` [count] times to lowercase mark after the cursor. *['* [' [count] times to previous line with a lowercase mark @@ -1037,6 +1036,12 @@ CTRL-I Go to [count] newer cursor position in jump list (not a motion command). {not available without the |+jumplist| feature} + NOTE: In the GUI and in a terminal supporting + |modifyOtherKeys|, CTRL-I can be mapped separately + from , on the condition that CTRL-I is + mapped before , otherwise the mapping applies to + both. + *:ju* *:jumps* :ju[mps] Print the jump list (not a motion command). {not available without the |+jumplist| feature} @@ -1054,11 +1059,11 @@ The maximum number of entries is fixed at 100. For example, after three jump commands you have this jump list: - jump line col file/text ~ - 3 1 0 some text ~ - 2 70 0 another line ~ - 1 1154 23 end. ~ - > ~ + jump line col file/text ~ + 3 1 0 some text ~ + 2 70 0 another line ~ + 1 1154 23 end. ~ + > ~ The "file/text" column shows the file name, or the text at the jump if it is in the current file (an indent is removed and a long line is truncated to fit @@ -1067,11 +1072,11 @@ in the window). You are currently in line 1167. If you then use the CTRL-O command, the cursor is put in line 1154. This results in: - jump line col file/text ~ - 2 1 0 some text ~ - 1 70 0 another line ~ - > 0 1154 23 end. ~ - 1 1167 0 foo bar ~ + jump line col file/text ~ + 2 1 0 some text ~ + 1 70 0 another line ~ + > 0 1154 23 end. ~ + 1 1167 0 foo bar ~ The pointer will be set at the last used jump position. The next CTRL-O command will use the entry above it, the next CTRL-I command will use the @@ -1098,12 +1103,12 @@ that calling setpos() does not do this. After the CTRL-O command that got you into line 1154 you could give another jump command (e.g., "G"). The jump list would then become: - jump line col file/text ~ - 4 1 0 some text ~ - 3 70 0 another line ~ - 2 1167 0 foo bar ~ - 1 1154 23 end. ~ - > ~ + jump line col file/text ~ + 4 1 0 some text ~ + 3 70 0 another line ~ + 2 1167 0 foo bar ~ + 1 1154 23 end. ~ + > ~ The line numbers will be adjusted for deleted and inserted lines. This fails if you stop editing a file without writing, like with ":n!". @@ -1152,7 +1157,7 @@ Note that when text has been inserted or deleted the cursor position might be a bit different from the position of the change. Especially when lines have been deleted. -When the |:keepjumps| command modifier is used the position of a change is not +When the `:keepjumps` command modifier is used the position of a change is not remembered. *:changes* @@ -1193,7 +1198,7 @@ remembered. #if, #ifdef, #else, #elif, #endif C preprocessor conditionals (when the cursor is on the # or no ([{ - following) + is following) For other items the matchit plugin can be used, see |matchit-install|. This plugin also helps to skip matches in comments. @@ -1222,19 +1227,16 @@ remembered. #if/#else/#endif makes the movement linewise. *[(* -[( go to [count] previous unmatched '('. +[( Go to [count] previous unmatched '('. |exclusive| motion. - *[{* -[{ go to [count] previous unmatched '{'. +[{ Go to [count] previous unmatched '{'. |exclusive| motion. - *])* -]) go to [count] next unmatched ')'. +]) Go to [count] next unmatched ')'. |exclusive| motion. - *]}* -]} go to [count] next unmatched '}'. +]} Go to [count] next unmatched '}'. |exclusive| motion. The above four commands can be used to go to the start or end of the current @@ -1268,7 +1270,7 @@ bring you back to the switch statement. class. When no '}' is found before the cursor this is an error. |exclusive| motion. -The above two commands assume that the file contains a class with methods. +The above four commands assume that the file contains a class with methods. The class definition is surrounded in '{' and '}'. Each method in the class is also surrounded with '{' and '}'. This applies to the Java language. The file looks like this: > @@ -1282,17 +1284,21 @@ file looks like this: > body_two(); } } + +[To try this out copy the text and put it in a new buffer, the help text above +confuses the jump commands] + Starting with the cursor on "body_two()", using "[m" will jump to the '{' at the start of "method_two()" (obviously this is much more useful when the method is long!). Using "2[m" will jump to the start of "method_one()". Using "3[m" will jump to the start of the class. *[#* -[# go to [count] previous unmatched "#if" or "#else". +[# Go to [count] previous unmatched "#if" or "#else". |exclusive| motion. *]#* -]# go to [count] next unmatched "#else" or "#endif". +]# Go to [count] next unmatched "#else" or "#endif". |exclusive| motion. These two commands work in C programs that contain #if/#else/#endif @@ -1300,11 +1306,11 @@ constructs. It brings you to the start or end of the #if/#else/#endif where the current line is included. You can then use "%" to go to the matching line. *[star* *[/* -[* or [/ go to [count] previous start of a C comment "/*". +[* or [/ Go to [count] previous start of a C comment "/*". |exclusive| motion. *]star* *]/* -]* or ]/ go to [count] next end of a C comment "*/". +]* or ]/ Go to [count] next end of a C comment "*/". |exclusive| motion. diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 3f082709ef..6c42d4c4ae 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -1,4 +1,4 @@ -*options.txt* For Vim version 8.2. Last change: 2021 Feb 13 +*options.txt* For Vim version 8.2. Last change: 2021 Mar 29 VIM REFERENCE MANUAL by Bram Moolenaar @@ -746,6 +746,15 @@ A jump table for the options with a short description can be found at |Q_op|. or selected. Note: When this option is on some plugins may not work. + *'autoshelldir'* *'asd'* *'noautoshelldir'* *'noasd'* +'autoshelldir' 'asd' boolean (default off) + global + When on, Vim will change the current working directory whenever you + change the directory of the shell running in a terminal window. You + need proper setting-up, so whenever the shell's pwd changes an OSC 7 + escape sequence will be emitted. For example, on Linux, you can source + /etc/profile.d/vte.sh in your shell profile if you use bash or zsh. + *'arabic'* *'arab'* *'noarabic'* *'noarab'* 'arabic' 'arab' boolean (default off) local to window @@ -3951,7 +3960,7 @@ A jump table for the options with a short description can be found at |Q_op|. *'go-v'* 'v' Use a vertical button layout for dialogs. When not included, a horizontal layout is preferred, but when it doesn't fit a - vertical layout is used anyway. + vertical layout is used anyway. Not supported in GTK 3. *'go-p'* 'p' Use Pointer callbacks for X11 GUI. This is required for some window managers. If the cursor is not blinking or hollow at @@ -9000,15 +9009,15 @@ A jump table for the options with a short description can be found at |Q_op|. *'window'* *'wi'* 'window' 'wi' number (default screen height - 1) global - Window height. Do not confuse this with the height of the Vim window, - use 'lines' for that. - Used for |CTRL-F| and |CTRL-B| when there is only one window and the - value is smaller than 'lines' minus one. The screen will scroll - 'window' minus two lines, with a minimum of one. + Window height used for |CTRL-F| and |CTRL-B| when there is only one + window and the value is smaller than 'lines' minus one. The screen + will scroll 'window' minus two lines, with a minimum of one. When 'window' is equal to 'lines' minus one CTRL-F and CTRL-B scroll in a much smarter way, taking care of wrapping lines. When resizing the Vim window, the value is smaller than 1 or more than or equal to 'lines' it will be set to 'lines' minus 1. + Note: Do not confuse this with the height of the Vim window, use + 'lines' for that. *'winheight'* *'wh'* *E591* 'winheight' 'wh' number (default 1) diff --git a/runtime/doc/quickref.txt b/runtime/doc/quickref.txt index 0e4297f335..f994261088 100644 --- a/runtime/doc/quickref.txt +++ b/runtime/doc/quickref.txt @@ -1,4 +1,4 @@ -*quickref.txt* For Vim version 8.2. Last change: 2020 Aug 15 +*quickref.txt* For Vim version 8.2. Last change: 2021 Mar 29 VIM REFERENCE MANUAL by Bram Moolenaar @@ -605,6 +605,7 @@ Short explanation of each option: *option-list* 'ambiwidth' 'ambw' what to do with Unicode chars of ambiguous width 'antialias' 'anti' Mac OS X: use smooth, antialiased fonts 'autochdir' 'acd' change directory to the file in the current window +'autoshelldir' 'asd' change directory to the shell's current directory 'arabic' 'arab' for Arabic as a default second language 'arabicshape' 'arshape' do shaping for Arabic characters 'autoindent' 'ai' take indent for new line from previous line diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 79557dcc76..4e6ddafd89 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -2236,9 +2236,10 @@ can use them. For example, Linux and BSD distributions use groff as their default text processing package. In order to activate the extra syntax highlighting -features for groff, add the following option to your start-up files: > +features for groff, arrange for files to be recognized as groff (see +|ft-groff-syntax|) or add the following option to your start-up files: > - :let b:nroff_is_groff = 1 + :let nroff_is_groff = 1 Groff is different from the old AT&T n/troff that you may still find in Solaris. Groff macro and request names can be longer than 2 characters and diff --git a/runtime/doc/tags b/runtime/doc/tags index d53784fc91..8bf13b8089 100644 --- a/runtime/doc/tags +++ b/runtime/doc/tags @@ -57,11 +57,13 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX* 'ari' options.txt /*'ari'* 'arshape' options.txt /*'arshape'* 'as' todo.txt /*'as'* +'asd' options.txt /*'asd'* 'autochdir' options.txt /*'autochdir'* 'autoindent' options.txt /*'autoindent'* 'autoprint' vi_diff.txt /*'autoprint'* 'autoread' options.txt /*'autoread'* 'autosave' todo.txt /*'autosave'* +'autoshelldir' options.txt /*'autoshelldir'* 'autowrite' options.txt /*'autowrite'* 'autowriteall' options.txt /*'autowriteall'* 'aw' options.txt /*'aw'* @@ -520,10 +522,12 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX* 'noari' options.txt /*'noari'* 'noarshape' options.txt /*'noarshape'* 'noas' todo.txt /*'noas'* +'noasd' options.txt /*'noasd'* 'noautochdir' options.txt /*'noautochdir'* 'noautoindent' options.txt /*'noautoindent'* 'noautoread' options.txt /*'noautoread'* 'noautosave' todo.txt /*'noautosave'* +'noautoshelldir' options.txt /*'noautoshelldir'* 'noautowrite' options.txt /*'noautowrite'* 'noautowriteall' options.txt /*'noautowriteall'* 'noaw' options.txt /*'noaw'* @@ -2420,6 +2424,8 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX* :ec eval.txt /*:ec* :echo eval.txt /*:echo* :echo-redraw eval.txt /*:echo-redraw* +:echoc eval.txt /*:echoc* +:echoconsole eval.txt /*:echoconsole* :echoe eval.txt /*:echoe* :echoerr eval.txt /*:echoerr* :echoh eval.txt /*:echoh* @@ -9311,6 +9317,7 @@ str2float() eval.txt /*str2float()* str2list() eval.txt /*str2list()* str2nr() eval.txt /*str2nr()* strcasestr() eval.txt /*strcasestr()* +strcharlen() eval.txt /*strcharlen()* strcharpart() eval.txt /*strcharpart()* strchars() eval.txt /*strchars()* strchr() eval.txt /*strchr()* diff --git a/runtime/doc/textprop.txt b/runtime/doc/textprop.txt index ac513309b2..2a6f405596 100644 --- a/runtime/doc/textprop.txt +++ b/runtime/doc/textprop.txt @@ -1,4 +1,4 @@ -*textprop.txt* For Vim version 8.2. Last change: 2020 Oct 14 +*textprop.txt* For Vim version 8.2. Last change: 2021 Mar 22 VIM REFERENCE MANUAL by Bram Moolenaar @@ -260,8 +260,8 @@ prop_type_add({name}, {props}) *prop_type_add()* *E969* *E970* properties the one with the highest priority will be used; negative values can be used, the default priority is zero - combine when TRUE combine the highlight with any - syntax highlight; when omitted or FALSE syntax + combine when omitted or TRUE combine the highlight + with any syntax highlight; when FALSE syntax highlight will not be used start_incl when TRUE inserts at the start position will be included in the text property diff --git a/runtime/doc/todo.txt b/runtime/doc/todo.txt index 2486d9d50f..8e70f36e86 100644 --- a/runtime/doc/todo.txt +++ b/runtime/doc/todo.txt @@ -1,4 +1,4 @@ -*todo.txt* For Vim version 8.2. Last change: 2021 Mar 11 +*todo.txt* For Vim version 8.2. Last change: 2021 Mar 29 VIM REFERENCE MANUAL by Bram Moolenaar @@ -39,48 +39,9 @@ browser use: https://github.com/vim/vim/issues/1234 -------------------- Known bugs and current work ----------------------- Vim9 - Make everything work: -- Does this work now: Implement using imported items at script level from - "import * as X" in -- import of item that isn't exported: error should mention missing "export"? -- no error for using :import in legacy script? -- Disallow :open ? -- Check: what if 'cpo' is intentionally changed in Vim9 script, does it get - restored at the end? -- ISN_CHECKTYPE could use check_argtype() -- Using a script variable inside a :def function doesn't work if the variable - is inside a block, see Test_nested_function(). Should it work? -- give error for variable name: - var p = function('NoSuchFunc') -- When indexing a string, should we include composing characters? #6563 - string[0] - first character including its composing characters. - string[0 : 0] - same - If you don't want that use strcharpart(). - Also, add optional arg to strcharpart() to include composing chars, to - make it consistent with strchars(). - Add strcharlen(), like strchars() but like skipcc is always set -- Make closures work better: - - Create closure in a loop. Need to make a list of them. -- If a :def function is called with a function reference, compile it to get - the function type. - def Filter(x: string, Cond: func(string): bool) - Filter(x, (v) => v =~ '^b') -- Make inline function work, to be used as a funcref: - var Ref = (arg: type): type => { - statement - return expr - } - var Ref = (arg: type) => { - statement - statement - } - For builtin functions using tv_get_string*() use check_for_string() to be - more strict about the argument type. -- Implement :lockvar and :unlockvar. How about local variables? Perhaps only - allow this for global variables. Use :final or :const otherwise. -- Allow function names that will be script-local to start with lower case - letter? Or also require names with s: prefix to use upper case? - Also apply this function references "var ref = SomeFunc" -- Support passing v:none to use the default argument value. (#6504) + more strict about the argument type (not a bool). + done: balloon_() - Run the same tests in :def and Vim9 script, like in Test_expr7_not() - Check many more builtin function arguments at compile time. - make 0 == 'string' fail on the script level, like inside :def. @@ -280,6 +241,23 @@ Terminal emulator window: Include patch #6290: recognize shell directory change. Valgrind reports memory leaks in test_options. +Valgrind reports overlapping memcpy in + test_conceal.3 + test_edit.1 + test_functions.4 + test_ins_complete.3 + test_method + test_normal + test_popupwin.35 et al. + test_search_stat +Using uninitialized value in test_crypt (can't explain why). +Memory leak in test_debugger +Memory leak in test_paste, using XtOpenDisplay several times +OLD: +TODO: be able to run all parts of test_alot with valgrind separately +Memory leak in test_alot with pyeval() (allocating partial) +Memory leak in test_alot with expand() +Memory leaks in test_channel? (or is it because of fork()) test_arglist func Test_all_not_allowed_from_cmdwin() hangs on MS-Windows. @@ -298,6 +276,11 @@ interrupt does not work. Where to add ui_breakcheck()? Remove SPACE_IN_FILENAME ? It is only used for completion. +Add optional argument to virtcol() that specifies "start", "cursor" or "end" +to tell which value from getvvcol() should be used. (#7964) +Value returned by virtcol() changes depending on how lines wrap. This is +inconsistent with the documentation. + Making breakat support multibyte characters (Yasuhiro Matsumoto, #6598) Scroll doesn't work correctly, why? @@ -592,7 +575,7 @@ The quoting of the [command] argument of :terminal is not clearly documented. Give a few examples. (#4288) Opening a file with --remote-tab-silent that matches 'wildignore' does not -work, results in (E479: No match". (#4610) +work, results in "E479: No match". (#4610) 7 Add an option to add one pixel column to the character width? Lucida Console italic is wider than the normal font ("d" overlaps with next char). @@ -781,14 +764,6 @@ Make ":interactive !cmd" stop termcap mode, also when used in an autocommand. Add buffer argument to undotree(). (#4001) -Memory leak in test_debugger -Using uninitialized value in test_crypt (can't explain why). -Memory leak in test_terminal_fail -TODO: be able to run all parts of test_alot with valgrind separately -Memory leak in test_alot with pyeval() (allocating partial) -Memory leak in test_alot with expand() -Memory leaks in test_channel? (or is it because of fork()) - matchaddpos() gets slow with many matches. Proposal by Rick Howe, 2018 Jul 19. @@ -1509,9 +1484,6 @@ specifically? First try with the parens, then without. Patch to add :mapgroup, put mappings in a group like augroup. (Yasuhiro Matsumoto, 2016 Feb 19) -Value returned by virtcol() changes depending on how lines wrap. This is -inconsistent with the documentation. - Can we cache the syntax attributes, so that updates for 'relativenumber' and 'cursorline'/'cursorcolumn' are a lot faster? Thus store the attributes before combining them. @@ -2466,9 +2438,6 @@ backslash? (Robert Vibrant, 2008 Jun 5) When 'rightleft' is set, cursorcolumn isn't highlighted after the end of a line. It's also wrong in folds. (Dominique Pelle, 2010 Aug 21) -Using an insert mode expression mapping, cursor is not in the expected -position. (ZyX, 2010 Aug 29) - After using for command line completion after ":ta blah" and getting E33 (no tags file), further editing the command to e.g., ":echo 'blah'", the command is not executed. Fix by Ian Kelling? diff --git a/runtime/doc/usr_41.txt b/runtime/doc/usr_41.txt index 0d17298fb0..891719ab77 100644 --- a/runtime/doc/usr_41.txt +++ b/runtime/doc/usr_41.txt @@ -1,4 +1,4 @@ -*usr_41.txt* For Vim version 8.2. Last change: 2021 Feb 01 +*usr_41.txt* For Vim version 8.2. Last change: 2021 Mar 14 VIM USER MANUAL - by Bram Moolenaar diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt index 794b86ca28..a0dc3a33f1 100644 --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -1,4 +1,4 @@ -*various.txt* For Vim version 8.2. Last change: 2021 Mar 02 +*various.txt* For Vim version 8.2. Last change: 2021 Mar 23 VIM REFERENCE MANUAL by Bram Moolenaar @@ -727,7 +727,7 @@ K Run a program to lookup the keyword under the feature} *:sl!* *:sleep!* -:[N]sl[eep]! [N] [m] Same as above, but hide the cursor +:[N]sl[eep]! [N] [m] Same as above, but hide the cursor. *:xrestore* *:xr* :xr[estore] [display] Reinitializes the connection to the X11 server. Useful diff --git a/runtime/doc/version7.txt b/runtime/doc/version7.txt index 9e8c8917a5..45de6019d3 100644 --- a/runtime/doc/version7.txt +++ b/runtime/doc/version7.txt @@ -2302,7 +2302,7 @@ value didn't fill the whole screen. (SungHyun Nam) Win32 installer: The generated _vimrc contained an absolute path to diff.exe. After upgrading it becomes invalid. Now use $VIMRUNTIME instead. -The command line was cleared to often when 'showmode' was set and ":silent +The command line was cleared too often when 'showmode' was set and ":silent normal vy" was used. Don't clear the command line unless the mode was actually displayed. Added the "mode_displayed" variable. diff --git a/runtime/doc/version8.txt b/runtime/doc/version8.txt index 67ca8a0ba4..ab4b7d8068 100644 --- a/runtime/doc/version8.txt +++ b/runtime/doc/version8.txt @@ -1776,7 +1776,7 @@ Files: runtime/doc/change.txt, runtime/doc/eval.txt, Patch 7.4.219 Problem: When 'relativenumber' or 'cursorline' are set the window is - redrawn much to often. (Patrick Hemmer, Dominique Pelle) + redrawn much too often. (Patrick Hemmer, Dominique Pelle) Solution: Check the VALID_CROW flag instead of VALID_WROW. Files: src/move.c diff --git a/runtime/doc/vim9.txt b/runtime/doc/vim9.txt index 4e8016c9db..974ee6af6b 100644 --- a/runtime/doc/vim9.txt +++ b/runtime/doc/vim9.txt @@ -1,4 +1,4 @@ -*vim9.txt* For Vim version 8.2. Last change: 2021 Mar 03 +*vim9.txt* For Vim version 8.2. Last change: 2021 Mar 30 VIM REFERENCE MANUAL by Bram Moolenaar @@ -125,6 +125,10 @@ that starts a comment: > var name = value # comment var name = value# error! +Do not start a comment with #{, it looks like the legacy dictionary literal +and produces an error where this might be confusing. #{{ or #{{{ are OK, +these can be used to start a fold. + In legacy Vim script # is also used for the alternate file name. In Vim9 script you need to use %% instead. Instead of ## use %%% (stands for all arguments). @@ -164,6 +168,15 @@ list type, similar to TypeScript. For example, a list of numbers: > for item in itemlist ... +When a function argument is optional (it has a default value) passing `v:none` +as the argument results in using the default value. This is useful when you +want to specify a value for an argument that comes after an argument that +should use its default value. Example: > + def MyFunc(one = 'one', last = 'last) + ... + enddef + MyFunc(v:none, 'LAST') # first argument uses default value 'one' + Functions and variables are script-local by default ~ *vim9-scopes* @@ -190,6 +203,12 @@ search for the function: However, it is recommended to always use "g:" to refer to a global function for clarity. +Since a script-local function reference can be used without "s:" the name must +start with an upper case letter even when using the "s:" prefix. In legacy +script "s:funcref" could be used, because it could not be referred to with +"funcref". In Vim9 script it can, therefore "s:Funcref" must be used to avoid +that the name interferes with builtin functions. + In all cases the function must be defined before used. That is when it is called, when `:defcompile` causes it to be compiled, or when code that calls it is being compiled (to figure out the return type). @@ -279,6 +298,9 @@ without any command. The same for global, window, tab, buffer and Vim variables, because they are not really declared. They can also be deleted with `:unlet`. +`:lockvar` does not work on local variables. Use `:const` and `:final` +instead. + Variables, functions and function arguments cannot shadow previously defined or imported variables and functions in the same script file. Variables may shadow Ex commands, rename the variable if needed. @@ -409,7 +431,18 @@ Additionally, a lambda can contain statements in {}: > g:was_called = 'yes' return expression } -NOT IMPLEMENTED YET + +The ending "}" must be at the start of a line. It can be followed by other +characters, e.g.: > + var d = mapnew(dict, (k, v): string => { + return 'value' + }) +No command can follow the "{", only a comment can be used there. + +Rationale: The "}" cannot be after a command because it would require parsing +the commands to find it. For consistency with that no command can follow the +"{". Unfortunately this means using "() => { command }" does not work, line +breaks are always required. *vim9-curly* To avoid the "{" of a dictionary literal to be recognized as a statement block @@ -705,6 +738,7 @@ In legacy script this results in the character 0xc3 (an illegal byte), in Vim9 script this results in the string 'á'. A negative index is counting from the end, "[-1]" is the last character. To exclude the last character use |slice()|. +To count composing characters separately use |strcharpart()|. If the index is out of range then an empty string results. In legacy script "++var" and "--var" would be silently accepted and have no @@ -892,6 +926,27 @@ For these the backtick expansion can be used. Example: > g/pattern/s/^/`=newText`/ enddef +Closures defined in a loop will share the same context. For example: > + var flist: list + for i in range(10) + var inloop = i + flist[i] = () => inloop + endfor + +The "inloop" variable will exist only once, all closures put in the list refer +to the same instance, which in the end will have the value 9. This is +efficient. If you do want a separate context for each closure call a function +to define it: > + def GetFunc(i: number): func + var inloop = i + return () => inloop + enddef + + var flist: list + for i in range(10) + flist[i] = GetFunc(i) + endfor + ============================================================================== 4. Types *vim9-types* diff --git a/runtime/doc/windows.txt b/runtime/doc/windows.txt index 69de9bafe6..b3905be9b4 100644 --- a/runtime/doc/windows.txt +++ b/runtime/doc/windows.txt @@ -1,4 +1,4 @@ -*windows.txt* For Vim version 8.2. Last change: 2021 Feb 06 +*windows.txt* For Vim version 8.2. Last change: 2021 Mar 21 VIM REFERENCE MANUAL by Bram Moolenaar @@ -790,7 +790,7 @@ can also get to them with the buffer list commands, like ":bnext". Examples: > - :windo set nolist nofoldcolumn | normal zn + :windo set nolist foldcolumn=0 | normal! zn This resets the 'list' option and disables folding in all windows. > @@ -798,7 +798,7 @@ This resets the 'list' option and disables folding in all windows. > This resets the 'fileencoding' in each buffer and writes it if this changed the buffer. The result is that all buffers will use the 'encoding' encoding -(if conversion works properly). +(if conversion succeeds). ============================================================================== 9. Tag or file name under the cursor *window-tag* diff --git a/runtime/filetype.vim b/runtime/filetype.vim index 2b6627427b..c34b63b617 100644 --- a/runtime/filetype.vim +++ b/runtime/filetype.vim @@ -1,7 +1,7 @@ " Vim support file to detect file types " " Maintainer: Bram Moolenaar -" Last Change: 2021 Mar 12 +" Last Change: 2021 Mar 19 " Listen very carefully, I will say this only once if exists("did_load_filetypes") diff --git a/runtime/ftplugin/lisp.vim b/runtime/ftplugin/lisp.vim index 9825d2484a..db3ac96631 100644 --- a/runtime/ftplugin/lisp.vim +++ b/runtime/ftplugin/lisp.vim @@ -4,7 +4,7 @@ " URL: http://sites.google.com/site/khorser/opensource/vim " Original author: Dorai Sitaram " Original URL: http://www.ccs.neu.edu/~dorai/vimplugins/vimplugins.html -" Last Change: Oct 23, 2013 +" Last Change: Mar 10, 2021 " Only do this when not done yet for this buffer if exists("b:did_ftplugin") diff --git a/runtime/indent/cdl.vim b/runtime/indent/cdl.vim index 5fae7b9046..4f9b7a8967 100644 --- a/runtime/indent/cdl.vim +++ b/runtime/indent/cdl.vim @@ -62,10 +62,14 @@ fun! CdlGetIndent(lnum) " PREVIOUS LINE let ind = indent(lnum) let line = getline(lnum) - let f = -1 " wether a '=' is a conditional or a asignment, -1 means we don't know yet - " one 'closing' element at the beginning of the line has already reduced the - " indent, but 'else', 'elseif' & 'then' increment it for the next line - " '=' at the beginning has already de right indent (increased for asignments) + + " Whether a '=' is a conditional or an assignment. -1 means we don't know + " yet. + " One 'closing' element at the beginning of the line has already reduced the + " indent, but 'else', 'elseif' & 'then' increment it for the next line. + " '=' at the beginning already has the right indent (increased for + " asignments). + let f = -1 let inicio = matchend(line, '^\c\s*\(else\a*\|then\|endif\|/[*/]\|[);={]\)') if inicio > 0 let c = line[inicio-1] diff --git a/runtime/optwin.vim b/runtime/optwin.vim index d0fc1b2261..547cec1c7c 100644 --- a/runtime/optwin.vim +++ b/runtime/optwin.vim @@ -266,6 +266,8 @@ if exists("+autochdir") call AddOption("autochdir", gettext("change to directory of file in buffer")) call BinOptionG("acd", &acd) endif +call AddOption("autoshelldir", gettext("change to pwd of shell in terminal buffer")) +call BinOptionG("asd", &asd) call AddOption("wrapscan", gettext("search commands wrap around the end of the buffer")) call BinOptionG("ws", &ws) call AddOption("incsearch", gettext("show match for partly typed search command")) diff --git a/runtime/syntax/dot.vim b/runtime/syntax/dot.vim index 0fdd6ea080..68a0f57a98 100644 --- a/runtime/syntax/dot.vim +++ b/runtime/syntax/dot.vim @@ -1,16 +1,22 @@ -" Vim syntax file " Language: Dot " Filenames: *.dot " Maintainer: Markus Mottl " URL: http://www.ocaml.info/vim/syntax/dot.vim -" Last Change: 2011 May 17 - improved identifier matching + two new keywords +" Last Change: 2021 Mar 24 - better attr + escape string matching, new keywords (Farbod Salamat-Zadeh) +" 2011 May 17 - improved identifier matching + two new keywords " 2001 May 04 - initial version -" quit when a syntax file was already loaded -if exists("b:current_syntax") +" For version 5.x: Clear all syntax items +" For version 6.x: Quit when a syntax file was already loaded +if version < 600 + syntax clear +elseif exists("b:current_syntax") finish endif +let s:keepcpo = &cpo +set cpo&vim + " Errors syn match dotParErr ")" syn match dotBrackErr "]" @@ -29,39 +35,43 @@ syn keyword dotTodo contained TODO FIXME XXX " Strings syn region dotString start=+"+ skip=+\\\\\|\\"+ end=+"+ +" Escape strings +syn match dotEscString /\v\\(N|G|E|T|H|L)/ containedin=dotString +syn match dotEscString /\v\\(n|l|r)/ containedin=dotString + " General keywords -syn keyword dotKeyword digraph node edge subgraph +syn keyword dotKeyword graph digraph subgraph node edge strict -" Graph attributes -syn keyword dotType center layers margin mclimit name nodesep nslimit -syn keyword dotType ordering page pagedir rank rankdir ranksep ratio -syn keyword dotType rotate size - -" Node attributes -syn keyword dotType distortion fillcolor fontcolor fontname fontsize -syn keyword dotType height layer orientation peripheries regular -syn keyword dotType shape shapefile sides skew width - -" Edge attributes -syn keyword dotType arrowhead arrowsize arrowtail constraint decorateP -syn keyword dotType dir headclip headlabel headport labelangle labeldistance -syn keyword dotType labelfontcolor labelfontname labelfontsize -syn keyword dotType minlen port_label_distance samehead sametail -syn keyword dotType tailclip taillabel tailport weight - -" Shared attributes (graphs, nodes, edges) -syn keyword dotType color - -" Shared attributes (graphs and edges) -syn keyword dotType bgcolor label URL - -" Shared attributes (nodes and edges) -syn keyword dotType fontcolor fontname fontsize layer style +" Node, edge and graph attributes +syn keyword dotType _background area arrowhead arrowsize arrowtail bb bgcolor + \ center charset class clusterrank color colorscheme comment compound + \ concentrate constraint Damping decorate defaultdist dim dimen dir + \ diredgeconstraints distortion dpi edgehref edgetarget edgetooltip + \ edgeURL epsilon esep fillcolor fixedsize fontcolor fontname fontnames + \ fontpath fontsize forcelabels gradientangle group head_lp headclip + \ headhref headlabel headport headtarget headtooltip headURL height href + \ id image imagepath imagepos imagescale inputscale K label label_scheme + \ labelangle labeldistance labelfloat labelfontcolor labelfontname + \ labelfontsize labelhref labeljust labelloc labeltarget labeltooltip + \ labelURL landscape layer layerlistsep layers layerselect layersep + \ layout len levels levelsgap lhead lheight lp ltail lwidth margin + \ maxiter mclimit mindist minlen mode model mosek newrank nodesep + \ nojustify normalize notranslate nslimit nslimit1 ordering orientation + \ outputorder overlap overlap_scaling overlap_shrink pack packmode pad + \ page pagedir pencolor penwidth peripheries pin pos quadtree quantum + \ rank rankdir ranksep ratio rects regular remincross repulsiveforce + \ resolution root rotate rotation samehead sametail samplepoints scale + \ searchsize sep shape shapefile showboxes sides size skew smoothing + \ sortv splines start style stylesheet tail_lp tailclip tailhref + \ taillabel tailport tailtarget tailtooltip tailURL target tooltip + \ truecolor URL vertices viewport voro_margin weight width xdotversion + \ xlabel xlp z " Special chars syn match dotKeyChar "=" syn match dotKeyChar ";" syn match dotKeyChar "->" +syn match dotKeyChar "--" " Identifier syn match dotIdentifier /\<\w\+\(:\w\+\)\?\>/ @@ -71,27 +81,41 @@ syn sync minlines=50 syn sync maxlines=500 " Define the default highlighting. -" Only when an item doesn't have highlighting yet +" For version 5.7 and earlier: only when not done already +" For version 5.8 and later: only when an item doesn't have highlighting yet +if version >= 508 || !exists("did_dot_syntax_inits") + if version < 508 + let did_dot_syntax_inits = 1 + command -nargs=+ HiLink hi link + else + command -nargs=+ HiLink hi def link + endif -hi def link dotParErr Error -hi def link dotBraceErr Error -hi def link dotBrackErr Error + HiLink dotParErr Error + HiLink dotBraceErr Error + HiLink dotBrackErr Error -hi def link dotComment Comment -hi def link dotTodo Todo + HiLink dotComment Comment + HiLink dotTodo Todo -hi def link dotParEncl Keyword -hi def link dotBrackEncl Keyword -hi def link dotBraceEncl Keyword + HiLink dotParEncl Keyword + HiLink dotBrackEncl Keyword + HiLink dotBraceEncl Keyword -hi def link dotKeyword Keyword -hi def link dotType Type -hi def link dotKeyChar Keyword + HiLink dotKeyword Keyword + HiLink dotType Type + HiLink dotKeyChar Keyword -hi def link dotString String -hi def link dotIdentifier Identifier + HiLink dotString String + HiLink dotEscString Keyword + HiLink dotIdentifier Identifier + delcommand HiLink +endif let b:current_syntax = "dot" +let &cpo = s:keepcpo +unlet s:keepcpo + " vim: ts=8 diff --git a/runtime/syntax/groff.vim b/runtime/syntax/groff.vim index 2cc7ccf704..c076c8d973 100644 --- a/runtime/syntax/groff.vim +++ b/runtime/syntax/groff.vim @@ -1,7 +1,7 @@ " VIM syntax file " Language: groff -" Maintainer: Alejandro López-Valencia -" URL: http://dradul.tripod.com/vim +" Maintainer: John Marshall +" Previous Maintainer: Pedro Alejandro López-Valencia " Last Change: 2003-05-08-12:41:13 GMT-5. " This uses the nroff.vim syntax file. diff --git a/runtime/syntax/javascript.vim b/runtime/syntax/javascript.vim index 8a5e10b261..1ab1c2db11 100644 --- a/runtime/syntax/javascript.vim +++ b/runtime/syntax/javascript.vim @@ -7,7 +7,7 @@ " (ss) repaired several quoting and grouping glitches " (ss) fixed regex parsing issue with multiple qualifiers [gi] " (ss) additional factoring of keywords, globals, and members -" Last Change: 2020 May 14 +" Last Change: 2021 Mar 30 " 2013 Jun 12: adjusted javaScriptRegexpString (Kevin Locke) " 2018 Apr 14: adjusted javaScriptRegexpString (LongJohnCoder) @@ -41,6 +41,7 @@ syn region javaScriptEmbed start=+${+ end=+}+ contains=@javaScriptEmbed syn match javaScriptSpecialCharacter "'\\.'" syn match javaScriptNumber "-\=\<\d\+L\=\>\|0[xX][0-9a-fA-F]\+\>" +syn match javaScriptNumber "-\=\<\d\+\%(_\d\+\)*\>" syn region javaScriptRegexpString start=+[,(=+]\s*/[^/*]+ms=e-1,me=e-1 skip=+\\\\\|\\/+ end=+/[gimuys]\{0,2\}\s*$+ end=+/[gimuys]\{0,2\}\s*[+;.,)\]}]+me=e-1 end=+/[gimuys]\{0,2\}\s\+\/+me=e-1 contains=@htmlPreproc,javaScriptComment oneline syn keyword javaScriptConditional if else switch diff --git a/runtime/syntax/nroff.vim b/runtime/syntax/nroff.vim index 04532e04bf..5667042515 100644 --- a/runtime/syntax/nroff.vim +++ b/runtime/syntax/nroff.vim @@ -1,16 +1,9 @@ " VIM syntax file " Language: nroff/groff -" Maintainer: Pedro Alejandro López-Valencia -" URL: http://vorbote.wordpress.com/ -" Last Change: 2012 Feb 2 -" -" {{{1 Acknowledgements -" -" ACKNOWLEDGEMENTS: -" -" My thanks to Jérôme Plût , who was the -" creator and maintainer of this syntax file for several years. -" May I be as good at it as he has been. +" Maintainer: John Marshall +" Previous Maintainer: Pedro Alejandro López-Valencia +" Previous Maintainer: Jérôme Plût +" Last Change: 2021 Mar 28 " " {{{1 Todo " @@ -31,6 +24,13 @@ endif let s:cpo_save = &cpo set cpo&vim +if exists("nroff_is_groff") + let b:nroff_is_groff = 1 +endif + +syn spell toplevel +syn case match + " " {{{1 plugin settings... " @@ -48,7 +48,7 @@ endif " setlocal paragraphs+=XP " -" {{{2 Activate navigation to preporcessor sections. +" {{{2 Activate navigation to preprocessor sections. " if exists("b:preprocs_as_sections") setlocal sections=EQTSPS[\ G1GS @@ -169,9 +169,9 @@ endif " syn region nroffEquation start=/^\.\s*EQ\>/ end=/^\.\s*EN\>/ -syn region nroffTable start=/^\.\s*TS\>/ end=/^\.\s*TE\>/ +syn region nroffTable start=/^\.\s*TS\>/ end=/^\.\s*TE\>/ contains=@Spell syn region nroffPicture start=/^\.\s*PS\>/ end=/^\.\s*PE\>/ -syn region nroffRefer start=/^\.\s*\[\>/ end=/^\.\s*\]\>/ +syn region nroffRefer start=/^\.\s*\[\>/ end=/^\.\s*\]\>/ contains=@Spell syn region nroffGrap start=/^\.\s*G1\>/ end=/^\.\s*G2\>/ syn region nroffGremlin start=/^\.\s*GS\>/ end=/^\.\s*GE|GF\>/ @@ -179,11 +179,11 @@ syn region nroffGremlin start=/^\.\s*GS\>/ end=/^\.\s*GE|GF\>/ " ------------------------------------------------------------ syn region nroffIgnore start=/^[.']\s*ig/ end=/^['.]\s*\./ -syn match nroffComment /\(^[.']\s*\)\=\\".*/ contains=nroffTodo -syn match nroffComment /^'''.*/ contains=nroffTodo +syn match nroffComment /\(^[.']\s*\)\=\\".*/ contains=nroffTodo,@Spell +syn match nroffComment /^'''.*/ contains=nroffTodo,@Spell if exists("b:nroff_is_groff") - syn match nroffComment "\\#.*$" contains=nroffTodo + syn match nroffComment "\\#.*$" contains=nroffTodo,@Spell endif syn keyword nroffTodo TODO XXX FIXME contained @@ -198,7 +198,7 @@ syn keyword nroffTodo TODO XXX FIXME contained " hi def link nroffEscChar nroffSpecialChar -hi def link nroffEscCharAr nroffSpecialChar +hi def link nroffEscCharArg nroffSpecialChar hi def link nroffSpecialChar SpecialChar hi def link nroffSpace Delimiter @@ -211,7 +211,7 @@ hi def link nroffEscPar nroffEscape hi def link nroffEscRegPar nroffEscape hi def link nroffEscArg nroffEscape hi def link nroffSize nroffEscape -hi def link nroffEscape Preproc +hi def link nroffEscape PreProc hi def link nroffIgnore Comment hi def link nroffComment Comment diff --git a/runtime/syntax/sshconfig.vim b/runtime/syntax/sshconfig.vim index d0752aebcb..ae3c7dd8cc 100644 --- a/runtime/syntax/sshconfig.vim +++ b/runtime/syntax/sshconfig.vim @@ -1,14 +1,15 @@ " Vim syntax file " Language: OpenSSH client configuration file (ssh_config) " Author: David Necas (Yeti) -" Maintainer: Dominik Fischer +" Maintainer: Jakub Jelen +" Previous Maintainer: Dominik Fischer " Contributor: Leonard Ehrenfried " Contributor: Karsten Hopp " Contributor: Dean, Adam Kenneth -" Last Change: 2020 Feb 12 +" Last Change: 2021 Mar 29 " Added RemoteCommand from pull request #4809 " Included additional keywords from Martin. -" SSH Version: 7.4p1 +" SSH Version: 8.5p1 " " Setup @@ -174,6 +175,7 @@ syn keyword sshconfigKeyword HostKeyAlgorithms syn keyword sshconfigKeyword HostKeyAlias syn keyword sshconfigKeyword HostName syn keyword sshconfigKeyword HostbasedAuthentication +syn keyword sshconfigKeyword HostbasedAcceptedAlgorithms syn keyword sshconfigKeyword HostbasedKeyTypes syn keyword sshconfigKeyword IPQoS syn keyword sshconfigKeyword IdentitiesOnly @@ -185,9 +187,11 @@ syn keyword sshconfigKeyword IPQoS syn keyword sshconfigKeyword KbdInteractiveAuthentication syn keyword sshconfigKeyword KbdInteractiveDevices syn keyword sshconfigKeyword KexAlgorithms +syn keyword sshconfigKeyword KnownHostsCommand syn keyword sshconfigKeyword LocalCommand syn keyword sshconfigKeyword LocalForward syn keyword sshconfigKeyword LogLevel +syn keyword sshconfigKeyword LogVerbose syn keyword sshconfigKeyword MACs syn keyword sshconfigKeyword Match syn keyword sshconfigKeyword NoHostAuthenticationForLocalhost @@ -195,11 +199,13 @@ syn keyword sshconfigKeyword NumberOfPasswordPrompts syn keyword sshconfigKeyword PKCS11Provider syn keyword sshconfigKeyword PasswordAuthentication syn keyword sshconfigKeyword PermitLocalCommand +syn keyword sshconfigKeyword PermitRemoteOpen syn keyword sshconfigKeyword Port syn keyword sshconfigKeyword PreferredAuthentications syn keyword sshconfigKeyword ProxyCommand syn keyword sshconfigKeyword ProxyJump syn keyword sshconfigKeyword ProxyUseFDPass +syn keyword sshconfigKeyword PubkeyAcceptedAlgorithms syn keyword sshconfigKeyword PubkeyAcceptedKeyTypes syn keyword sshconfigKeyword PubkeyAuthentication syn keyword sshconfigKeyword RekeyLimit diff --git a/runtime/syntax/sshdconfig.vim b/runtime/syntax/sshdconfig.vim index 8534ff6332..6b0d2af4d1 100644 --- a/runtime/syntax/sshdconfig.vim +++ b/runtime/syntax/sshdconfig.vim @@ -7,8 +7,8 @@ " Contributor: Leonard Ehrenfried " Contributor: Karsten Hopp " Originally: 2009-07-09 -" Last Change: 2020-10-20 -" SSH Version: 8.4p1 +" Last Change: 2021-03-29 +" SSH Version: 8.5p1 " " Setup @@ -195,6 +195,7 @@ syn keyword sshdconfigKeyword HostCertificate syn keyword sshdconfigKeyword HostKey syn keyword sshdconfigKeyword HostKeyAgent syn keyword sshdconfigKeyword HostKeyAlgorithms +syn keyword sshdconfigKeyword HostbasedAcceptedAlgorithms syn keyword sshdconfigKeyword HostbasedAcceptedKeyTypes syn keyword sshdconfigKeyword HostbasedAuthentication syn keyword sshdconfigKeyword HostbasedUsesNameFromPacketOnly @@ -213,6 +214,7 @@ syn keyword sshdconfigKeyword KexAlgorithms syn keyword sshdconfigKeyword KeyRegenerationInterval syn keyword sshdconfigKeyword ListenAddress syn keyword sshdconfigKeyword LogLevel +syn keyword sshdconfigKeyword LogVerbose syn keyword sshdconfigKeyword LoginGraceTime syn keyword sshdconfigKeyword MACs syn keyword sshdconfigKeyword Match @@ -220,6 +222,8 @@ syn keyword sshdconfigKeyword MaxAuthTries syn keyword sshdconfigKeyword MaxSessions syn keyword sshdconfigKeyword MaxStartups syn keyword sshdconfigKeyword PasswordAuthentication +syn keyword sshdconfigKeyword PerSourceMaxStartups +syn keyword sshdconfigKeyword PerSourceNetBlockSize syn keyword sshdconfigKeyword PermitBlacklistedKeys syn keyword sshdconfigKeyword PermitEmptyPasswords syn keyword sshdconfigKeyword PermitListen @@ -234,6 +238,7 @@ syn keyword sshdconfigKeyword Port syn keyword sshdconfigKeyword PrintLastLog syn keyword sshdconfigKeyword PrintMotd syn keyword sshdconfigKeyword Protocol +syn keyword sshdconfigKeyword PubkeyAcceptedAlgorithms syn keyword sshdconfigKeyword PubkeyAcceptedKeyTypes syn keyword sshdconfigKeyword PubkeyAuthentication syn keyword sshdconfigKeyword PubkeyAuthOptions diff --git a/runtime/syntax/sudoers.vim b/runtime/syntax/sudoers.vim index 019b0ada32..bf2d337d9e 100644 --- a/runtime/syntax/sudoers.vim +++ b/runtime/syntax/sudoers.vim @@ -1,7 +1,8 @@ " Vim syntax file " Language: sudoers(5) configuration files +" Maintainer: Eisuke Kawashima ( e.kawaschima+vim AT gmail.com ) " Previous Maintainer: Nikolai Weibull -" Latest Revision: 2018-08-18 +" Latest Revision: 2021 Mar 15 " Recent Changes: Support for #include and #includedir. " Added many new options (Samuel D. Leslie) @@ -26,7 +27,7 @@ syn cluster sudoersCmndSpecList contains=sudoersUserRunasBegin,sudoersPASS syn keyword sudoersTodo contained TODO FIXME XXX NOTE syn region sudoersComment display oneline start='#' end='$' contains=sudoersTodo -syn region sudoersInclude display oneline start='#\(include\|includedir\)' end='$' +syn region sudoersInclude display oneline start='[#@]\%(include\|includedir\)\>' end='$' syn keyword sudoersAlias User_Alias Runas_Alias nextgroup=sudoersUserAlias skipwhite skipnl syn keyword sudoersAlias Host_Alias nextgroup=sudoersHostAlias skipwhite skipnl @@ -201,7 +202,7 @@ syn keyword sudoersBooleanParameter contained skipwhite skipnl \ shell_noargs \ stay_setuid \ sudoedit_checkdir - \ sudoedit_fellow + \ sudoedit_follow \ syslog_pid \ targetpw \ tty_tickets diff --git a/src/charset.c b/src/charset.c index d06a273643..db0c146f88 100644 --- a/src/charset.c +++ b/src/charset.c @@ -2005,7 +2005,8 @@ hex2nr(int c) return c - '0'; } -#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) || defined(PROTO) +#if defined(FEAT_TERMRESPONSE) || defined(FEAT_GUI_GTK) \ + || defined(PROTO) || defined(FEAT_AUTOSHELLDIR) /* * Convert two hex characters to a byte. * Return -1 if one of the characters is not hex. diff --git a/src/cmdexpand.c b/src/cmdexpand.c index a32eb2ce1d..9745aa83ae 100644 --- a/src/cmdexpand.c +++ b/src/cmdexpand.c @@ -1020,8 +1020,9 @@ set_one_cmd_context( p = cmd; while (ASCII_ISALPHA(*p) || *p == '*') // Allow * wild card ++p; - // a user command may contain digits - if (ASCII_ISUPPER(cmd[0])) + // A user command may contain digits. + // Include "9" for "vim9*" commands; "vim9cmd" and "vim9script". + if (ASCII_ISUPPER(cmd[0]) || STRNCMP("vim9", cmd, 4) == 0) while (ASCII_ISALNUM(*p) || *p == '*') ++p; // for python 3.x: ":py3*" commands completion diff --git a/src/drawscreen.c b/src/drawscreen.c index 5461b91f2c..066bc7622e 100644 --- a/src/drawscreen.c +++ b/src/drawscreen.c @@ -377,6 +377,20 @@ update_screen(int type_arg) return OK; } +/* + * Return the row for drawing the statusline and the ruler of window "wp". + */ + static int +statusline_row(win_T *wp) +{ +#if defined(FEAT_PROP_POPUP) + // If the window is really zero height the winbar isn't displayed. + if (wp->w_frame->fr_height == wp->w_status_height && !popup_is_popup(wp)) + return wp->w_winrow; +#endif + return W_WINROW(wp) + wp->w_height; +} + /* * Redraw the status line of window wp. * @@ -401,6 +415,8 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) return; busy = TRUE; + row = statusline_row(wp); + wp->w_redr_status = FALSE; if (wp->w_status_height == 0) { @@ -500,7 +516,6 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) len = this_ru_col - 1; } - row = W_WINROW(wp) + wp->w_height; screen_puts(p, row, wp->w_wincol, attr); screen_fill(row, row + 1, len + wp->w_wincol, this_ru_col + wp->w_wincol, fillchar, fillchar, attr); @@ -524,8 +539,7 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED) fillchar = fillchar_status(&attr, wp); else fillchar = fillchar_vsep(&attr); - screen_putchar(fillchar, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp), - attr); + screen_putchar(fillchar, row, W_ENDCOL(wp), attr); } busy = FALSE; } @@ -680,7 +694,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum) cursor_off(); if (wp->w_status_height) { - row = W_WINROW(wp) + wp->w_height; + row = statusline_row(wp); fillchar = fillchar_status(&attr, wp); off = wp->w_wincol; width = wp->w_width; @@ -1468,8 +1482,13 @@ win_update(win_T *wp) wp->w_lines_valid = 0; } - // Window is zero-height: nothing to draw. - if (wp->w_height + WINBAR_HEIGHT(wp) == 0) + // Window frame is zero-height: nothing to draw. + if (wp->w_height + WINBAR_HEIGHT(wp) == 0 + || (wp->w_frame->fr_height == wp->w_status_height +#if defined(FEAT_PROP_POPUP) + && !popup_is_popup(wp) +#endif + )) { wp->w_redr_type = 0; return; diff --git a/src/errors.h b/src/errors.h index cb0f84652d..0225531cb0 100644 --- a/src/errors.h +++ b/src/errors.h @@ -391,3 +391,7 @@ EXTERN char e_misplaced_command_modifier[] INIT(= N_("E1176: Misplaced command modifier")); EXTERN char e_for_loop_on_str_not_supported[] INIT(= N_("E1177: For loop on %s not supported")); +EXTERN char e_cannot_lock_unlock_local_variable[] + INIT(= N_("E1178: Cannot lock or unlock a local variable")); +EXTERN char e_failed_to_extract_pwd_from_str_check_your_shell_config[] + INIT(= N_("E1179: Failed to extract PWD from %s, check your shell's config related to OSC 7")); diff --git a/src/evalvars.c b/src/evalvars.c index 0f2d785b59..4544cf83ff 100644 --- a/src/evalvars.c +++ b/src/evalvars.c @@ -3170,6 +3170,7 @@ set_var_const( hashtab_T *ht; int is_script_local; int vim9script = in_vim9script(); + int var_in_vim9script; ht = find_var_ht(name, &varname); if (ht == NULL || *varname == NUL) @@ -3188,6 +3189,7 @@ set_var_const( vim9_declare_error(name); goto failed; } + var_in_vim9script = is_script_local && current_script_is_vim9(); di = find_var_in_ht(ht, 0, varname, TRUE); @@ -3219,16 +3221,17 @@ set_var_const( goto failed; } - if (is_script_local && vim9script) + if (is_script_local && vim9script + && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) + { + semsg(_(e_redefining_script_item_str), name); + goto failed; + } + + if (var_in_vim9script) { where_T where; - if ((flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0) - { - semsg(_(e_redefining_script_item_str), name); - goto failed; - } - // check the type and adjust to bool if needed where.wt_index = var_idx; where.wt_variable = TRUE; @@ -3246,7 +3249,7 @@ set_var_const( // A Vim9 script-local variable is also present in sn_all_vars and // sn_var_vals. It may set "type" from "tv". - if (is_script_local && vim9script) + if (var_in_vim9script) update_vim9_script_var(FALSE, di, flags, tv, &type); } @@ -3310,7 +3313,7 @@ set_var_const( } // add a new variable - if (vim9script && is_script_local && (flags & ASSIGN_NO_DECL)) + if (var_in_vim9script && (flags & ASSIGN_NO_DECL)) { semsg(_(e_unknown_variable_str), name); goto failed; @@ -3344,7 +3347,7 @@ set_var_const( // A Vim9 script-local variable is also added to sn_all_vars and // sn_var_vals. It may set "type" from "tv". - if (is_script_local && vim9script) + if (var_in_vim9script) update_vim9_script_var(TRUE, di, flags, tv, &type); } @@ -3455,8 +3458,10 @@ var_wrong_func_name( char_u *name, // points to start of variable name int new_var) // TRUE when creating the variable { - // Allow for w: b: s: and t:. - if (!(vim_strchr((char_u *)"wbst", name[0]) != NULL && name[1] == ':') + // Allow for w: b: s: and t:. In Vim9 script s: is not allowed, because + // the name can be used without the s: prefix. + if (!((vim_strchr((char_u *)"wbt", name[0]) != NULL + || (!in_vim9script() && name[0] == 's')) && name[1] == ':') && !ASCII_ISUPPER((name[0] != NUL && name[1] == ':') ? name[2] : name[0])) { diff --git a/src/ex_docmd.c b/src/ex_docmd.c index f9cd5d28b8..3a8c8d4df9 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -3559,7 +3559,7 @@ find_ex_command( } else if (*p == '9' && STRNCMP("vim9", eap->cmd, 4) == 0) { - // include "9" for "vim9script" + // include "9" for "vim9*" commands; "vim9cmd" and "vim9script". ++p; while (ASCII_ISALPHA(*p)) ++p; diff --git a/src/feature.h b/src/feature.h index 982502232e..f80cd777ef 100644 --- a/src/feature.h +++ b/src/feature.h @@ -1165,6 +1165,12 @@ # define FEAT_SYN_HL #endif +/* + * +autoshelldir 'autoshelldir' option. + */ +#if defined(FEAT_TERMINAL) +# define FEAT_AUTOSHELLDIR +#endif /* * +textprop and +popupwin Text PROPerties and POPUP windows */ diff --git a/src/gui_motif.c b/src/gui_motif.c index a9845b28f5..67f9c632a1 100644 --- a/src/gui_motif.c +++ b/src/gui_motif.c @@ -1996,7 +1996,11 @@ do_mnemonic(Widget w, unsigned int keycode) * Callback routine for dialog mnemonic processing. */ static void -mnemonic_event(Widget w, XtPointer call_data UNUSED, XKeyEvent *event) +mnemonic_event( + Widget w, + XtPointer call_data UNUSED, + XKeyEvent *event, + Boolean *b UNUSED) { do_mnemonic(w, event->keycode); } @@ -3565,7 +3569,8 @@ find_replace_callback( find_replace_keypress( Widget w UNUSED, SharedFindReplace *frdp, - XKeyEvent *event) + XKeyEvent *event, + Boolean *b UNUSED) { KeySym keysym; diff --git a/src/gui_x11.c b/src/gui_x11.c index 14a0b8085f..92bbfc36fa 100644 --- a/src/gui_x11.c +++ b/src/gui_x11.c @@ -1753,7 +1753,13 @@ gui_mch_init_font( // A font name equal "*" is indicating, that we should activate the font // selection dialogue to get a new font name. So let us do it here. if (font_name != NULL && STRCMP(font_name, "*") == 0) + { font_name = gui_xm_select_font(hl_get_font_name()); + + // Do not reset to default font except on GUI startup. + if (font_name == NULL && !gui.starting) + return OK; + } #endif #ifdef FEAT_XFONTSET diff --git a/src/option.h b/src/option.h index 7d23d6c60b..29f41601cb 100644 --- a/src/option.h +++ b/src/option.h @@ -383,6 +383,9 @@ EXTERN char_u *p_ambw; // 'ambiwidth' #ifdef FEAT_AUTOCHDIR EXTERN int p_acd; // 'autochdir' #endif +#ifdef FEAT_AUTOSHELLDIR +EXTERN int p_asd; // 'autoshelldir' +#endif EXTERN int p_ai; // 'autoindent' EXTERN int p_bin; // 'binary' EXTERN int p_bomb; // 'bomb' diff --git a/src/optiondefs.h b/src/optiondefs.h index 624b52eb22..79c62d6ae0 100644 --- a/src/optiondefs.h +++ b/src/optiondefs.h @@ -411,6 +411,15 @@ static struct vimoption options[] = #else (char_u *)NULL, PV_NONE, {(char_u *)0L, (char_u *)0L} +#endif + SCTX_INIT}, + {"autoshelldir", "asd", P_BOOL|P_VI_DEF, +#ifdef FEAT_AUTOSHELLDIR + (char_u *)&p_asd, PV_NONE, + {(char_u *)FALSE, (char_u *)0L} +#else + (char_u *)NULL, PV_NONE, + {(char_u *)0L, (char_u *)0L} #endif SCTX_INIT}, {"autoindent", "ai", P_BOOL|P_VI_DEF, diff --git a/src/proto/vim9script.pro b/src/proto/vim9script.pro index a7d821c0d8..c43120c452 100644 --- a/src/proto/vim9script.pro +++ b/src/proto/vim9script.pro @@ -1,5 +1,6 @@ /* vim9script.c */ int in_vim9script(void); +int current_script_is_vim9(void); void ex_vim9script(exarg_T *eap); int not_in_vim9(exarg_T *eap); int vim9_bad_comment(char_u *p); diff --git a/src/structs.h b/src/structs.h index 27d83c5391..fcd1c67d65 100644 --- a/src/structs.h +++ b/src/structs.h @@ -1607,8 +1607,6 @@ typedef struct type_T **uf_arg_types; // argument types (count == uf_args.ga_len) type_T *uf_ret_type; // return type garray_T uf_type_list; // types used in arg and return types - int *uf_def_arg_idx; // instruction indexes for evaluating - // uf_def_args; length: uf_def_args.ga_len + 1 partial_T *uf_partial; // for closure created inside :def function: // information about the context diff --git a/src/terminal.c b/src/terminal.c index f69fbeb16c..e353e3d538 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -4297,6 +4297,73 @@ handle_call_command(term_T *term, channel_T *channel, listitem_T *item) ch_log(channel, "Calling function %s failed", func); } +/* + * URL decoding (also know as Percent-encoding). + * + * Note this function currently is only used for decoding shell's + * OSC 7 escape sequence which we can assume all bytes are valid + * UTF-8 bytes. Thus we don't need to deal with invalid UTF-8 + * encoding bytes like 0xfe, 0xff. + */ + static size_t +url_decode(const char *src, const size_t len, char_u *dst) +{ + size_t i = 0, j = 0; + + while (i < len) + { + if (src[i] == '%' && i + 2 < len) + { + dst[j] = hexhex2nr((char_u *)&src[i + 1]); + j++; + i += 3; + } + else + { + dst[j] = src[i]; + i++; + j++; + } + } + dst[j] = '\0'; + return j; +} + +/* + * Sync terminal buffer's cwd with shell's pwd with the help of OSC 7. + * + * The OSC 7 sequence has the format of + * "\033]7;file://HOSTNAME/CURRENT/DIR\033\\" + * and what VTerm provides via VTermStringFragment is + * "file://HOSTNAME/CURRENT/DIR" + */ + static void +sync_shell_dir(VTermStringFragment *frag) +{ + int offset = 7; // len of "file://" is 7 + char *pos = (char *)frag->str + offset; + char_u *new_dir; + + // remove HOSTNAME to get PWD + while (*pos != '/' && offset < frag->len) + { + offset += 1; + pos += 1; + } + + if (offset >= frag->len) + { + semsg(_(e_failed_to_extract_pwd_from_str_check_your_shell_config), + frag->str); + return; + } + + new_dir = alloc(frag->len - offset + 1); + url_decode(pos, frag->len-offset, new_dir); + changedir_func(new_dir, TRUE, CDSCOPE_WINDOW); + vim_free(new_dir); +} + /* * Called by libvterm when it cannot recognize an OSC sequence. * We recognize a terminal API command. @@ -4311,7 +4378,13 @@ parse_osc(int command, VTermStringFragment frag, void *user) : term->tl_job->jv_channel; garray_T *gap = &term->tl_osc_buf; - // We recognize only OSC 5 1 ; {command} + // We recognize only OSC 5 1 ; {command} and OSC 7 ; {command} + if (p_asd && command == 7) + { + sync_shell_dir(&frag); + return 1; + } + if (command != 51) return 0; diff --git a/src/testdir/check.vim b/src/testdir/check.vim index 6bb1dd6559..216b37bc52 100644 --- a/src/testdir/check.vim +++ b/src/testdir/check.vim @@ -92,6 +92,14 @@ func CheckLinux() endif endfunc +" Command to check for not running on a BSD system. +command CheckNotBSD call CheckNotBSD() +func CheckNotBSD() + if has('bsd') + throw 'Skipped: does not work on BSD' + endif +endfunc + " Command to check that making screendumps is supported. " Caller must source screendump.vim command CheckScreendump call CheckScreendump() diff --git a/src/testdir/dumps/Test_winbar_not_visible.dump b/src/testdir/dumps/Test_winbar_not_visible.dump new file mode 100644 index 0000000000..894ac21eaf --- /dev/null +++ b/src/testdir/dumps/Test_winbar_not_visible.dump @@ -0,0 +1,10 @@ +|[+1&#ffffff0|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +> +0&&@74 +|~+0#4040ff13&| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|~| @73 +|[+3#0000000&|N|o| |N|a|m|e|]| @47|0|,|0|-|1| @9|A|l@1 +| +0&&@74 diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim index 05d90f74d1..531837b223 100644 --- a/src/testdir/test_cmdline.vim +++ b/src/testdir/test_cmdline.vim @@ -871,6 +871,10 @@ func Test_cmdline_complete_various() call feedkeys(":py3\\\"\", 'xt') call assert_equal('"py3 py3do py3file', @:) + " completion for the :vim9 commands + call feedkeys(":vim9\\\"\", 'xt') + call assert_equal('"vim9cmd vim9script', @:) + " redir @" is not the start of a comment. So complete after that call feedkeys(":redir @\" | cwin\t\\"\", 'xt') call assert_equal('"redir @" | cwindow', @:) diff --git a/src/testdir/test_terminal3.vim b/src/testdir/test_terminal3.vim index 037d935582..f4cc38acb0 100644 --- a/src/testdir/test_terminal3.vim +++ b/src/testdir/test_terminal3.vim @@ -475,6 +475,37 @@ func Test_term_mouse() call delete('Xbuf') endfunc +" Test for sync buffer cwd with shell's pwd +func Test_terminal_sync_shell_dir() + CheckUnix + " The test always use sh (see src/testdir/unix.vim). + " However, BSD's sh doesn't seem to play well with OSC 7 escape sequence. + CheckNotBSD + + set asd + " , is + " 1. a valid character for directory names + " 2. a reserved character in url-encoding + let chars = ",a" + " "," is url-encoded as '%2C' + let chars_url = "%2Ca" + let tmpfolder = fnamemodify(tempname(),':h').'/'.chars + let tmpfolder_url = fnamemodify(tempname(),':h').'/'.chars_url + call mkdir(tmpfolder, "p") + let buf = Run_shell_in_terminal({}) + call term_sendkeys(buf, "echo -ne $'\\e\]7;file://".tmpfolder_url."\\a'\") + "call term_sendkeys(buf, "cd ".tmpfolder."\") + call TermWait(buf) + if has("mac") + let expected = "/private".tmpfolder + else + let expected = tmpfolder + endif + call assert_equal(expected, getcwd(winnr())) + + set noasd +endfunc + " Test for modeless selection in a terminal func Test_term_modeless_selection() CheckUnix diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim index b9851a77f5..05e65e1ecf 100644 --- a/src/testdir/test_vim9_assign.vim +++ b/src/testdir/test_vim9_assign.vim @@ -1654,5 +1654,31 @@ def Test_assign_command_modifier() CheckDefAndScriptSuccess(lines) enddef +def Test_script_funcref_case() + var lines =<< trim END + var Len = (s: string): number => len(s) + 1 + assert_equal(5, Len('asdf')) + END + CheckDefAndScriptSuccess(lines) + + lines =<< trim END + var len = (s: string): number => len(s) + 1 + END + CheckDefAndScriptFailure(lines, 'E704:') + + lines =<< trim END + vim9script + var s:Len = (s: string): number => len(s) + 2 + assert_equal(6, Len('asdf')) + END + CheckScriptSuccess(lines) + + lines =<< trim END + vim9script + var s:len = (s: string): number => len(s) + 1 + END + CheckScriptFailure(lines, 'E704:') +enddef + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_builtin.vim b/src/testdir/test_vim9_builtin.vim index 73251c0bac..8f112174e5 100644 --- a/src/testdir/test_vim9_builtin.vim +++ b/src/testdir/test_vim9_builtin.vim @@ -123,6 +123,10 @@ def Test_append() var res2: bool = append(3, 'two') assert_equal(false, res2) assert_equal(['0', 'one', '1', 'two', '2'], getline(1, 6)) + + append(0, 'zero') + assert_equal('zero', getline(1)) + bwipe! enddef def Test_balloon_show() diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim index bc4cfa6e16..3b479f31d5 100644 --- a/src/testdir/test_vim9_cmd.vim +++ b/src/testdir/test_vim9_cmd.vim @@ -1135,4 +1135,42 @@ def Test_windo_missing_endif() CheckDefExecFailure(lines, 'E171:', 1) enddef +let s:theList = [1, 2, 3] + +def Test_lockvar() + s:theList[1] = 22 + assert_equal([1, 22, 3], s:theList) + lockvar s:theList + assert_fails('theList[1] = 77', 'E741:') + unlockvar s:theList + s:theList[1] = 44 + assert_equal([1, 44, 3], s:theList) + + var lines =<< trim END + vim9script + var theList = [1, 2, 3] + def SetList() + theList[1] = 22 + assert_equal([1, 22, 3], theList) + lockvar theList + theList[1] = 77 + enddef + SetList() + END + CheckScriptFailure(lines, 'E1119', 4) + + lines =<< trim END + var theList = [1, 2, 3] + lockvar theList + END + CheckDefFailure(lines, 'E1178', 2) + + lines =<< trim END + var theList = [1, 2, 3] + unlockvar theList + END + CheckDefFailure(lines, 'E1178', 2) +enddef + + " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker diff --git a/src/testdir/test_vim9_disassemble.vim b/src/testdir/test_vim9_disassemble.vim index 407e2611ff..e24e72f06b 100644 --- a/src/testdir/test_vim9_disassemble.vim +++ b/src/testdir/test_vim9_disassemble.vim @@ -641,18 +641,25 @@ def Test_disassemble_update_instr() enddef -def FuncWithDefault(arg: string = 'default'): string - return arg +def FuncWithDefault(arg: string = 'default', nr = 77): string + return arg .. nr enddef def Test_disassemble_call_default() var res = execute('disass FuncWithDefault') assert_match('FuncWithDefault\_s*' .. + '\d JUMP_IF_ARG_SET arg\[-2\] -> 3\_s*' .. '\d PUSHS "default"\_s*' .. + '\d STORE arg\[-2]\_s*' .. + '3 JUMP_IF_ARG_SET arg\[-1\] -> 6\_s*' .. + '\d PUSHNR 77\_s*' .. '\d STORE arg\[-1]\_s*' .. - 'return arg\_s*' .. + 'return arg .. nr\_s*' .. + '6 LOAD arg\[-2]\_s*' .. '\d LOAD arg\[-1]\_s*' .. - '\d RETURN', + '\d 2STRING stack\[-1]\_s*' .. + '\d\+ CONCAT\_s*' .. + '\d\+ RETURN', res) enddef diff --git a/src/testdir/test_vim9_func.vim b/src/testdir/test_vim9_func.vim index 5faae82705..957b632e12 100644 --- a/src/testdir/test_vim9_func.vim +++ b/src/testdir/test_vim9_func.vim @@ -308,21 +308,38 @@ def MyDefaultSecond(name: string, second: bool = true): string return second ? name : 'none' enddef + def Test_call_default_args() MyDefaultArgs()->assert_equal('string') + MyDefaultArgs(v:none)->assert_equal('string') MyDefaultArgs('one')->assert_equal('one') - assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 3, 'Test_call_default_args') + assert_fails('MyDefaultArgs("one", "two")', 'E118:', '', 4, 'Test_call_default_args') MyDefaultSecond('test')->assert_equal('test') MyDefaultSecond('test', true)->assert_equal('test') MyDefaultSecond('test', false)->assert_equal('none') + var lines =<< trim END + def MyDefaultThird(name: string, aa = 'aa', bb = 'bb'): string + return name .. aa .. bb + enddef + + MyDefaultThird('->')->assert_equal('->aabb') + MyDefaultThird('->', v:none)->assert_equal('->aabb') + MyDefaultThird('->', 'xx')->assert_equal('->xxbb') + MyDefaultThird('->', v:none, v:none)->assert_equal('->aabb') + MyDefaultThird('->', 'xx', v:none)->assert_equal('->xxbb') + MyDefaultThird('->', v:none, 'yy')->assert_equal('->aayy') + MyDefaultThird('->', 'xx', 'yy')->assert_equal('->xxyy') + END + CheckDefAndScriptSuccess(lines) + CheckScriptFailure(['def Func(arg: number = asdf)', 'enddef', 'defcompile'], 'E1001:') delfunc g:Func CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string') delfunc g:Func - var lines =<< trim END + lines =<< trim END vim9script def Func(a = b == 0 ? 1 : 2, b = 0) enddef diff --git a/src/testdir/test_vim9_script.vim b/src/testdir/test_vim9_script.vim index 1169c86924..cd8ac091d6 100644 --- a/src/testdir/test_vim9_script.vim +++ b/src/testdir/test_vim9_script.vim @@ -3220,6 +3220,35 @@ def Test_source_vim9_from_legacy() delete('Xvim9_script.vim') enddef +def Test_declare_script_in_func() + var lines =<< trim END + vim9script + func Declare() + let s:local = 123 + endfunc + Declare() + assert_equal(123, local) + + var error: string + try + local = 'asdf' + catch + error = v:exception + endtry + assert_match('E1012: Type mismatch; expected number but got string', error) + + lockvar local + try + local = 999 + catch + error = v:exception + endtry + assert_match('E741: Value is locked: local', error) + END + CheckScriptSuccess(lines) +enddef + + func Test_vim9script_not_global() " check that items defined in Vim9 script are script-local, not global let vim9lines =<< trim END diff --git a/src/testdir/test_winbar.vim b/src/testdir/test_winbar.vim index 3412ce5761..2cbdd013c4 100644 --- a/src/testdir/test_winbar.vim +++ b/src/testdir/test_winbar.vim @@ -4,6 +4,7 @@ source check.vim CheckFeature menu source shared.vim +source screendump.vim func Test_add_remove_menu() new @@ -121,4 +122,23 @@ func Test_redraw_after_scroll() bwipe! endfunc +func Test_winbar_not_visible() + CheckScreendump + + let lines =<< trim END + split + nnoremenu WinBar.Test :test + set winminheight=0 + wincmd j + wincmd _ + END + call writefile(lines, 'XtestWinbarNotVisble') + let buf = RunVimInTerminal('-S XtestWinbarNotVisble', #{rows: 10}) + call VerifyScreenDump(buf, 'Test_winbar_not_visible', {}) + + " clean up + call StopVimInTerminal(buf) + call delete('XtestWinbarNotVisble') +endfunction + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/typval.c b/src/typval.c index 8030c6953f..cf1208d586 100644 --- a/src/typval.c +++ b/src/typval.c @@ -1621,11 +1621,12 @@ tv_get_lnum(typval_T *argvars) if (argvars[0].v_type != VAR_STRING || !in_vim9script()) lnum = (linenr_T)tv_get_number_chk(&argvars[0], NULL); - if (lnum <= 0) // no valid number, try using arg like line() + if (lnum <= 0 && argvars[0].v_type != VAR_NUMBER) { int fnum; pos_T *fp = var2fpos(&argvars[0], TRUE, &fnum, FALSE); + // no valid number, try using arg like line() if (fp != NULL) lnum = fp->lnum; } diff --git a/src/userfunc.c b/src/userfunc.c index ba7e0c3da2..1139573c63 100644 --- a/src/userfunc.c +++ b/src/userfunc.c @@ -1914,7 +1914,6 @@ func_clear_items(ufunc_T *fp) ga_clear_strings(&(fp->uf_def_args)); ga_clear_strings(&(fp->uf_lines)); VIM_CLEAR(fp->uf_arg_types); - VIM_CLEAR(fp->uf_def_arg_idx); VIM_CLEAR(fp->uf_block_ids); VIM_CLEAR(fp->uf_va_name); clear_type_list(&fp->uf_type_list); @@ -2049,14 +2048,6 @@ copy_func(char_u *lambda, char_u *global, ectx_T *ectx) mch_memmove(fp->uf_arg_types, ufunc->uf_arg_types, sizeof(type_T *) * fp->uf_args.ga_len); } - if (ufunc->uf_def_arg_idx != NULL) - { - fp->uf_def_arg_idx = ALLOC_MULT(int, fp->uf_def_args.ga_len + 1); - if (fp->uf_def_arg_idx == NULL) - goto failed; - mch_memmove(fp->uf_def_arg_idx, ufunc->uf_def_arg_idx, - sizeof(int) * fp->uf_def_args.ga_len + 1); - } if (ufunc->uf_va_name != NULL) { fp->uf_va_name = vim_strsave(ufunc->uf_va_name); diff --git a/src/version.c b/src/version.c index 6ae8f7cae5..07036f8b46 100644 --- a/src/version.c +++ b/src/version.c @@ -765,6 +765,32 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2681, +/**/ + 2680, +/**/ + 2679, +/**/ + 2678, +/**/ + 2677, +/**/ + 2676, +/**/ + 2675, +/**/ + 2674, +/**/ + 2673, +/**/ + 2672, +/**/ + 2671, +/**/ + 2670, +/**/ + 2669, /**/ 2668, /**/ diff --git a/src/vim9.h b/src/vim9.h index a0757fd31f..0c8a949e87 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -92,6 +92,7 @@ typedef enum { // expression operations ISN_JUMP, // jump if condition is matched isn_arg.jump + ISN_JUMP_IF_ARG_SET, // jump if argument is already set, uses isn_arg.jumparg // loop ISN_FOR, // get next item from a list, uses isn_arg.forloop @@ -203,6 +204,12 @@ typedef struct { int jump_where; // position to jump to } jump_T; +// arguments to ISN_JUMP_IF_ARG_SET +typedef struct { + int jump_arg_off; // argument index, negative + int jump_where; // position to jump to +} jumparg_T; + // arguments to ISN_FOR typedef struct { int for_idx; // loop variable index @@ -346,6 +353,7 @@ struct isn_S { job_T *job; partial_T *partial; jump_T jump; + jumparg_T jumparg; forloop_T forloop; try_T try; trycont_T trycont; diff --git a/src/vim9compile.c b/src/vim9compile.c index c1adb36c67..72387610df 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -1629,6 +1629,22 @@ generate_JUMP(cctx_T *cctx, jumpwhen_T when, int where) return OK; } +/* + * Generate an ISN_JUMP_IF_ARG_SET instruction. + */ + static int +generate_JUMP_IF_ARG_SET(cctx_T *cctx, int arg_off) +{ + isn_T *isn; + + RETURN_OK_IF_SKIP(cctx); + if ((isn = generate_instr(cctx, ISN_JUMP_IF_ARG_SET)) == NULL) + return FAIL; + isn->isn_arg.jumparg.jump_arg_off = arg_off; + // jump_where is set later + return OK; +} + static int generate_FOR(cctx_T *cctx, int loop_idx) { @@ -1834,6 +1850,13 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) type_T *expected; type_T *actual; + actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; + if (actual == &t_special + && i >= regular_args - ufunc->uf_def_args.ga_len) + { + // assume v:none used for default argument value + continue; + } if (i < regular_args) { if (ufunc->uf_arg_types == NULL) @@ -1845,7 +1868,6 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount) expected = &t_any; else expected = ufunc->uf_va_type->tt_member; - actual = ((type_T **)stack->ga_data)[stack->ga_len - argcount + i]; if (need_type(actual, expected, -argcount + i, i + 1, cctx, TRUE, FALSE) == FAIL) { @@ -1961,6 +1983,9 @@ generate_PCALL( if (varargs && i >= type->tt_argcount - 1) expected = type->tt_args[ type->tt_argcount - 1]->tt_member; + else if (i >= type->tt_min_argcount + && actual == &t_special) + expected = &t_any; else expected = type->tt_args[i]; if (need_type(actual, expected, offset, i + 1, @@ -6707,6 +6732,58 @@ compile_unlet( return ret; } +/* + * Callback passed to ex_unletlock(). + */ + static int +compile_lock_unlock( + lval_T *lvp, + char_u *name_end, + exarg_T *eap, + int deep UNUSED, + void *coookie) +{ + cctx_T *cctx = coookie; + int cc = *name_end; + char_u *p = lvp->ll_name; + int ret = OK; + size_t len; + char_u *buf; + + if (cctx->ctx_skip == SKIP_YES) + return OK; + + // Cannot use :lockvar and :unlockvar on local variables. + if (p[1] != ':') + { + char_u *end = skip_var_one(p, FALSE); + + if (lookup_local(p, end - p, NULL, cctx) == OK) + { + emsg(_(e_cannot_lock_unlock_local_variable)); + return FAIL; + } + } + + // Checking is done at runtime. + *name_end = NUL; + len = name_end - p + 20; + buf = alloc(len); + if (buf == NULL) + ret = FAIL; + else + { + vim_snprintf((char *)buf, len, "%s %s", + eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar", + p); + ret = generate_EXEC(cctx, buf); + + vim_free(buf); + *name_end = cc; + } + return ret; +} + /* * compile "unlet var", "lock var" and "unlock var" * "arg" points to "var". @@ -6714,16 +6791,9 @@ compile_unlet( static char_u * compile_unletlock(char_u *arg, exarg_T *eap, cctx_T *cctx) { - char_u *p = arg; - - if (eap->cmdidx != CMD_unlet) - { - emsg("Sorry, :lock and unlock not implemented yet"); - return NULL; - } - - ex_unletlock(eap, p, 0, GLV_NO_AUTOLOAD | GLV_COMPILING, - compile_unlet, cctx); + ex_unletlock(eap, arg, 0, GLV_NO_AUTOLOAD | GLV_COMPILING, + eap->cmdidx == CMD_unlet ? compile_unlet : compile_lock_unlock, + cctx); return eap->nextcmd == NULL ? (char_u *)"" : eap->nextcmd; } @@ -8318,12 +8388,6 @@ compile_def_function( int did_set_arg_type = FALSE; // Produce instructions for the default values of optional arguments. - // Store the instruction index in uf_def_arg_idx[] so that we know - // where to start when the function is called, depending on the number - // of arguments. - ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1); - if (ufunc->uf_def_arg_idx == NULL) - goto erret; SOURCING_LNUM = 0; // line number unknown for (i = 0; i < count; ++i) { @@ -8332,11 +8396,16 @@ compile_def_function( int arg_idx = first_def_arg + i; where_T where; int r; + int jump_instr_idx = instr->ga_len; + isn_T *isn; + + // Use a JUMP_IF_ARG_SET instruction to skip if the value was given. + if (generate_JUMP_IF_ARG_SET(&cctx, i - count - off) == FAIL) + goto erret; // Make sure later arguments are not found. ufunc->uf_args.ga_len = i; - ufunc->uf_def_arg_idx[i] = instr->ga_len; arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i]; r = compile_expr0(&arg, &cctx); @@ -8361,8 +8430,11 @@ compile_def_function( if (generate_STORE(&cctx, ISN_STORE, i - count - off, NULL) == FAIL) goto erret; + + // set instruction index in JUMP_IF_ARG_SET to here + isn = ((isn_T *)instr->ga_data) + jump_instr_idx; + isn->isn_arg.jumparg.jump_where = instr->ga_len; } - ufunc->uf_def_arg_idx[count] = instr->ga_len; if (did_set_arg_type) set_function_type(ufunc); @@ -9069,6 +9141,7 @@ delete_instr(isn_T *isn) case ISN_FOR: case ISN_GETITEM: case ISN_JUMP: + case ISN_JUMP_IF_ARG_SET: case ISN_LISTAPPEND: case ISN_LISTINDEX: case ISN_LISTSLICE: diff --git a/src/vim9execute.c b/src/vim9execute.c index b80d533c91..f15b93d867 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -96,35 +96,6 @@ ufunc_argcount(ufunc_T *ufunc) return ufunc->uf_args.ga_len + (ufunc->uf_va_name != NULL ? 1 : 0); } -/* - * Set the instruction index, depending on omitted arguments, where the default - * values are to be computed. If all optional arguments are present, start - * with the function body. - * The expression evaluation is at the start of the instructions: - * 0 -> EVAL default1 - * STORE arg[-2] - * 1 -> EVAL default2 - * STORE arg[-1] - * 2 -> function body - */ - static void -init_instr_idx(ufunc_T *ufunc, int argcount, ectx_T *ectx) -{ - if (ufunc->uf_def_args.ga_len == 0) - ectx->ec_iidx = 0; - else - { - int defcount = ufunc->uf_args.ga_len - argcount; - - // If there is a varargs argument defcount can be negative, no defaults - // to evaluate then. - if (defcount < 0) - defcount = 0; - ectx->ec_iidx = ufunc->uf_def_arg_idx[ - ufunc->uf_def_args.ga_len - defcount]; - } -} - /* * Create a new list from "count" items at the bottom of the stack. * When "count" is zero an empty list is added to the stack. @@ -363,8 +334,8 @@ call_dfunc( current_sctx.sc_sid = ufunc->uf_script_ctx.sc_sid; } - // Decide where to start execution, handles optional arguments. - init_instr_idx(ufunc, argcount, ectx); + // Start execution at the first instruction. + ectx->ec_iidx = 0; return OK; } @@ -1367,11 +1338,21 @@ call_def_function( && (ufunc->uf_va_name != NULL || idx < ufunc->uf_args.ga_len); ++idx) { - if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len - && check_typval_arg_type(ufunc->uf_arg_types[idx], &argv[idx], - idx + 1) == FAIL) - goto failed_early; - copy_tv(&argv[idx], STACK_TV_BOT(0)); + if (idx >= ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len + && argv[idx].v_type == VAR_SPECIAL + && argv[idx].vval.v_number == VVAL_NONE) + { + // Use the default value. + STACK_TV_BOT(0)->v_type = VAR_UNKNOWN; + } + else + { + if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len + && check_typval_arg_type( + ufunc->uf_arg_types[idx], &argv[idx], idx + 1) == FAIL) + goto failed_early; + copy_tv(&argv[idx], STACK_TV_BOT(0)); + } ++ectx.ec_stack.ga_len; } @@ -1505,8 +1486,8 @@ call_def_function( where.wt_index = 0; where.wt_variable = FALSE; - // Decide where to start execution, handles optional arguments. - init_instr_idx(ufunc, argc, &ectx); + // Start execution at the first instruction. + ectx.ec_iidx = 0; for (;;) { @@ -2738,6 +2719,16 @@ call_def_function( } break; + // Jump if an argument with a default value was already set and not + // v:none. + case ISN_JUMP_IF_ARG_SET: + tv = STACK_TV_VAR(iptr->isn_arg.jumparg.jump_arg_off); + if (tv->v_type != VAR_UNKNOWN + && !(tv->v_type == VAR_SPECIAL + && tv->vval.v_number == VVAL_NONE)) + ectx.ec_iidx = iptr->isn_arg.jumparg.jump_where; + break; + // top of a for loop case ISN_FOR: { @@ -4517,6 +4508,12 @@ ex_disassemble(exarg_T *eap) } break; + case ISN_JUMP_IF_ARG_SET: + smsg("%4d JUMP_IF_ARG_SET arg[%d] -> %d", current, + iptr->isn_arg.jumparg.jump_arg_off + STACK_FRAME_SIZE, + iptr->isn_arg.jump.jump_where); + break; + case ISN_FOR: { forloop_T *forloop = &iptr->isn_arg.forloop; diff --git a/src/vim9script.c b/src/vim9script.c index 8806de3137..9839a06cfb 100644 --- a/src/vim9script.c +++ b/src/vim9script.c @@ -17,16 +17,32 @@ # include "vim9.h" #endif +/* + * Return TRUE when currently using Vim9 script syntax. + * Does not go up the stack, a ":function" inside vim9script uses legacy + * syntax. + */ int in_vim9script(void) { - // Do not go up the stack, a ":function" inside vim9script uses legacy - // syntax. "sc_version" is also set when compiling a ":def" function in - // legacy script. + // "sc_version" is also set when compiling a ":def" function in legacy + // script. return current_sctx.sc_version == SCRIPT_VERSION_VIM9 || (cmdmod.cmod_flags & CMOD_VIM9CMD); } +/* + * Return TRUE if the current script is Vim9 script. + * This also returns TRUE in a legacy function in a Vim9 script. + */ + int +current_script_is_vim9(void) +{ + return SCRIPT_ID_VALID(current_sctx.sc_sid) + && SCRIPT_ITEM(current_sctx.sc_sid)->sn_version + == SCRIPT_VERSION_VIM9; +} + /* * ":vim9script". */