Compare commits

...

19 Commits

Author SHA1 Message Date
Bram Moolenaar
ccb47a2899 patch 8.2.2383: focus escape sequences are not named
Problem:    Focus escape sequences are not named in ":set termcap" output.
Solution:   Add the names to the list. (closes #7718)
2021-01-21 13:36:43 +01:00
Bram Moolenaar
b1f2857096 patch 8.2.2382: build failure
Problem:    Build failure.
Solution:   Add missing changes.
2021-01-21 13:03:20 +01:00
Bram Moolenaar
c5f59fab23 patch 8.2.2381: Vim9: divide by zero does not abort expression execution
Problem:    Vim9: divide by zero does not abort expression execution.
Solution:   Use a "failed" flag. (issue #7704)
2021-01-21 12:34:14 +01:00
Bram Moolenaar
a0f7f73ebb patch 8.2.2380: Vim9: occasional crash when using try/catch and a timer
Problem:    Vim9: occasional crash when using try/catch and a timer.
Solution:   Save and restore "need_rethrow" when invoking a timer callback.
            (closes #7708)
2021-01-20 22:22:49 +01:00
Bram Moolenaar
77a849c4b3 patch 8.2.2379: do spell suggestions twice if 'spellsuggest' contains number
Problem:    Finding spell suggestions twice if 'spellsuggest' contains number.
Solution:   Only do internal suggestions once.  (closes #7713)
2021-01-20 21:42:33 +01:00
Bram Moolenaar
99880f96cf patch 8.2.2378: Vim9: no error message for dividing by zero
Problem:    Vim9: no error message for dividing by zero.
Solution:   Give an error message. (issue #7704)
2021-01-20 21:23:14 +01:00
Bram Moolenaar
a28639e711 patch 8.2.2377: Vim9: crash when using a range after another expression
Problem:    Vim9: crash when using a range after another expression.
Solution:   Set the variable type to number. Fix using :put with a range and
            the "=" register. (closes #7706)
2021-01-19 22:48:09 +01:00
Bram Moolenaar
e64f83cc6a patch 8.2.2376: Vim9: crash when dividing by zero in compiled code
Problem:    Vim9: crash when dividing by zero in compiled code using
            constants.
Solution:   Call num_divide() and num_modulus(). (closes #7704)
2021-01-19 22:16:41 +01:00
Bram Moolenaar
09fbedc8dc patch 8.2.2375: test for RGB color skipped in the terminal
Problem:    Test for RGB color skipped in the terminal.
Solution:   Run the GUI if possible.
2021-01-19 17:22:58 +01:00
Bram Moolenaar
98a29d00a4 Update runtime files. 2021-01-18 19:55:44 +01:00
Bram Moolenaar
82aa6e09e0 patch 8.2.2374: accessing uninitialized memory in test_undo
Problem:    Accessing uninitialized memory in test_undo.
Solution:   Do not look in typebuf.tb_buf if it is empty. (Dominique Pellé,
            closes #7697)
2021-01-17 22:04:02 +01:00
Bram Moolenaar
f30a14db3b patch 8.2.2373: Vim9: list assignment only accepts a number index
Problem:    Vim9: list assignment only accepts a number index.
Solution:   Accept "any" and do a runtime type check. (closes #7694)
2021-01-17 21:51:24 +01:00
Bram Moolenaar
585587dadb patch 8.2.2372: confusing error message for wrong :let command
Problem:    Confusing error message for wrong :let command.
Solution:   Only check for type in Vim9 script.
2021-01-17 20:52:13 +01:00
Bram Moolenaar
036d07144e patch 8.2.2371: Vim9: crash when using types in :for with unpack
Problem:    Vim9: crash when using types in :for with unpack.
Solution:   Check for skip_var_list() failing. Pass include_type to
            skip_var_one(). Skip type when compiling. (closes #7694)
2021-01-17 20:23:38 +01:00
Bram Moolenaar
1430ceeb2d patch 8.2.2370: Vim9: command fails in catch block
Problem:    Vim9: command fails in catch block.
Solution:   Reset force_abort and need_rethrow. (closes #7692)
2021-01-17 19:20:32 +01:00
Bram Moolenaar
3af15ab788 patch 8.2.2369: Vim9: functions return true/false but can't be used as bool
Problem:    Vim9: functions return true/false but can't be used as bool.
Solution:   Add ret_number_bool(). (closes #7693)
2021-01-17 16:16:23 +01:00
Bram Moolenaar
85773bf32b patch 8.2.2368: insufficient tests for setting options
Problem:    Insufficient tests for setting options.
Solution:   Add a few tests. (Dominique Pellé, closes #7695)
2021-01-17 13:48:03 +01:00
Bram Moolenaar
239f8d9326 patch 8.2.2367: test failures on some less often used systems
Problem:    Test failures on some less often used systems.
Solution:   Adjust printf formats and types. (James McCoy, closes #7691)
2021-01-17 13:21:20 +01:00
Bram Moolenaar
e2edc2ed4a patch 8.2.2366: when using ":sleep" the cursor is always displayed
Problem:    When using ":sleep" the cursor is always displayed.
Solution:   Do not display the cursor when using ":sleep!". (Jeremy Lerner,
            closes #7688)
2021-01-16 20:21:23 +01:00
46 changed files with 564 additions and 264 deletions

View File

@@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 13
*eval.txt* For Vim version 8.2. Last change: 2021 Jan 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -4084,8 +4084,9 @@ delete({fname} [, {flags}]) *delete()*
A symbolic link itself is deleted, not what it points to.
The result is a Number, which is 0 if the delete operation was
successful and -1 when the deletion failed or partly failed.
The result is a Number, which is 0/false if the delete
operation was successful and -1/true when the deletion failed
or partly failed.
Use |remove()| to delete an item from a |List|.
To delete a line from the buffer use |:delete| or
@@ -6222,8 +6223,8 @@ has({feature} [, {check}])
has_key({dict}, {key}) *has_key()*
The result is a Number, which is 1 if |Dictionary| {dict} has
an entry with key {key}. Zero otherwise.
The result is a Number, which is TRUE if |Dictionary| {dict}
has an entry with key {key}. FALSE otherwise.
Can also be used as a |method|: >
mydict->has_key(key)
@@ -6266,16 +6267,16 @@ haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()*
GetWinnr()->haslocaldir()
hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
The result is a Number, which is 1 if there is a mapping that
contains {what} in somewhere in the rhs (what it is mapped to)
and this mapping exists in one of the modes indicated by
{mode}.
The result is a Number, which is TRUE if there is a mapping
that contains {what} in somewhere in the rhs (what it is
mapped to) and this mapping exists in one of the modes
indicated by {mode}.
When {abbr} is there and it is |TRUE| use abbreviations
instead of mappings. Don't forget to specify Insert and/or
Command-line mode.
Both the global mappings and the mappings local to the current
buffer are checked for a match.
If no matching mapping is found 0 is returned.
If no matching mapping is found FALSE is returned.
The following characters are recognized in {mode}:
n Normal mode
v Visual and Select mode
@@ -6311,8 +6312,8 @@ histadd({history}, {item}) *histadd()*
character is sufficient.
If {item} does already exist in the history, it will be
shifted to become the newest entry.
The result is a Number: 1 if the operation was successful,
otherwise 0 is returned.
The result is a Number: TRUE if the operation was successful,
otherwise FALSE is returned.
Example: >
:call histadd("input", strftime("%Y %b %d"))
@@ -6335,8 +6336,8 @@ histdel({history} [, {item}]) *histdel()*
an index, see |:history-indexing|. The respective entry will
be removed if it exists.
The result is a Number: 1 for a successful operation,
otherwise 0 is returned.
The result is TRUE for a successful operation, otherwise FALSE
is returned.
Examples:
Clear expression register history: >
@@ -6388,7 +6389,7 @@ histnr({history}) *histnr()*
GetHistory()->histnr()
<
hlexists({name}) *hlexists()*
The result is a Number, which is non-zero if a highlight group
The result is a Number, which is TRUE if a highlight group
called {name} exists. This is when the group has been
defined in some way. Not necessarily when highlighting has
been defined for it, it may also have been used for a syntax
@@ -6561,7 +6562,7 @@ inputrestore() *inputrestore()*
Restore typeahead that was saved with a previous |inputsave()|.
Should be called the same number of times inputsave() is
called. Calling it more often is harmless though.
Returns 1 when there is nothing to restore, 0 otherwise.
Returns TRUE when there is nothing to restore, FALSE otherwise.
inputsave() *inputsave()*
Preserve typeahead (also from mappings) and clear it, so that
@@ -6569,7 +6570,7 @@ inputsave() *inputsave()*
followed by a matching inputrestore() after the prompt. Can
be used several times, in which case there must be just as
many inputrestore() calls.
Returns 1 when out of memory, 0 otherwise.
Returns TRUE when out of memory, FALSE otherwise.
inputsecret({prompt} [, {text}]) *inputsecret()*
This function acts much like the |input()| function with but
@@ -7045,7 +7046,7 @@ listener_flush([{buf}]) *listener_flush()*
listener_remove({id}) *listener_remove()*
Remove a listener previously added with listener_add().
Returns zero when {id} could not be found, one when {id} was
Returns FALSE when {id} could not be found, TRUE when {id} was
removed.
Can also be used as a |method|: >
@@ -7728,8 +7729,8 @@ mkdir({name} [, {path} [, {prot}]])
flag is passed (since patch 8.0.1708). However, without the
"p" option the call will fail.
The function result is a Number, which is 1 if the call was
successful or 0 if the directory creation failed or partly
The function result is a Number, which is TRUE if the call was
successful or FALSE if the directory creation failed or partly
failed.
Not available on all systems. To check use: >
@@ -9205,6 +9206,7 @@ server2client({clientid}, {string}) *server2client()*
Send a reply string to {clientid}. The most recent {clientid}
that sent a string can be retrieved with expand("<client>").
{only available when compiled with the |+clientserver| feature}
Returns zero for success, -1 for failure.
Note:
This id has to be stored before the next command can be
received. I.e. before returning from the received command and
@@ -9342,8 +9344,8 @@ setcmdpos({pos}) *setcmdpos()*
before inserting the resulting text.
When the number is too big the cursor is put at the end of the
line. A number smaller than one has undefined results.
Returns 0 when successful, 1 when not editing the command
line.
Returns FALSE when successful, TRUE when not editing the
command line.
Can also be used as a |method|: >
GetPos()->setcmdpos()
@@ -9402,8 +9404,8 @@ setline({lnum}, {text}) *setline()*
When {lnum} is just below the last line the {text} will be
added below the last line.
If this succeeds, 0 is returned. If this fails (most likely
because {lnum} is invalid) 1 is returned.
If this succeeds, FALSE is returned. If this fails (most likely
because {lnum} is invalid) TRUE is returned.
Example: >
:call setline(5, strftime("%c"))
@@ -11378,7 +11380,7 @@ win_gettype([{nr}]) *win_gettype()*
win_gotoid({expr}) *win_gotoid()*
Go to window with ID {expr}. This may also change the current
tabpage.
Return 1 if successful, 0 if the window cannot be found.
Return TRUE if successful, FALSE if the window cannot be found.
Can also be used as a |method|: >
GetWinid()->win_gotoid()

View File

@@ -147,6 +147,7 @@ can be used to overrule the filetype used for certain extensions:
*.w g:filetype_w |ft-cweb-syntax|
*.i g:filetype_i |ft-progress-syntax|
*.p g:filetype_p |ft-pascal-syntax|
*.pp g:filetype_pp |ft-pascal-syntax|
*.sh g:bash_is_sh |ft-sh-syntax|
*.tex g:tex_flavor |ft-tex-plugin|

View File

@@ -1,4 +1,4 @@
*index.txt* For Vim version 8.2. Last change: 2020 Oct 05
*index.txt* For Vim version 8.2. Last change: 2021 Jan 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -1590,6 +1590,8 @@ tag command action ~
|:sign| :sig[n] manipulate signs
|:silent| :sil[ent] run a command silently
|:sleep| :sl[eep] do nothing for a few seconds
|:sleep!| :sl[eep]! do nothing for a few seconds, without the
cursor visible
|:slast| :sla[st] split window and go to last file in the
argument list
|:smagic| :sm[agic] :substitute with 'magic'

View File

@@ -3273,7 +3273,7 @@ A jump table for the options with a short description can be found at |Q_op|.
See the 'endofline' option.
*'fkmap'* *'fk'* *'nofkmap'* *'nofk'*
'fkmap' 'fk' boolean (default off) *E198*
'fkmap' 'fk' boolean (default off)
global
{only available when compiled with the |+rightleft|
feature}
@@ -5221,7 +5221,7 @@ A jump table for the options with a short description can be found at |Q_op|.
NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset.
*'mouse'* *E538*
*'mouse'*
'mouse' string (default "", "a" for GUI and Win32,
set to "a" or "nvi" in |defaults.vim|)
global

View File

@@ -588,8 +588,6 @@ properties. It is in one of four forms:
If you want to create a new buffer yourself use |bufadd()| and pass the buffer
number to popup_create().
It is not possible to use the buffer of a terminal window. *E278* You CAN
create a hidden terminal buffer and use that one in a popup window.
The second argument of |popup_create()| is a dictionary with options:
line Screen line where to position the popup. Can use a

View File

@@ -2335,11 +2335,12 @@ http://papp.plan9.de.
PASCAL *pascal.vim* *ft-pascal-syntax*
Files matching "*.p" could be Progress or Pascal. If the automatic detection
doesn't work for you, or you don't edit Progress at all, use this in your
startup vimrc: >
Files matching "*.p" could be Progress or Pascal and those matching "*.pp"
could be Puppet or Pascal. If the automatic detection doesn't work for you,
or you only edit Pascal files, use this in your startup vimrc: >
:let filetype_p = "pascal"
:let filetype_p = "pascal"
:let filetype_pp = "pascal"
The Pascal syntax file has been extended to take into account some extensions
provided by Turbo Pascal, Free Pascal Compiler and GNU Pascal Compiler.

View File

@@ -1045,6 +1045,8 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
't_da' term.txt /*'t_da'*
't_db' term.txt /*'t_db'*
't_dl' term.txt /*'t_dl'*
't_fd' term.txt /*'t_fd'*
't_fe' term.txt /*'t_fe'*
't_fs' term.txt /*'t_fs'*
't_k1' term.txt /*'t_k1'*
't_k2' term.txt /*'t_k2'*
@@ -3112,9 +3114,11 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
:sip change.txt /*:sip*
:sir change.txt /*:sir*
:sl various.txt /*:sl*
:sl! various.txt /*:sl!*
:sla windows.txt /*:sla*
:slast windows.txt /*:slast*
:sleep various.txt /*:sleep*
:sleep! various.txt /*:sleep!*
:sm change.txt /*:sm*
:smagic change.txt /*:smagic*
:smap map.txt /*:smap*
@@ -4028,7 +4032,6 @@ E194 message.txt /*E194*
E195 starting.txt /*E195*
E196 various.txt /*E196*
E197 mlang.txt /*E197*
E198 options.txt /*E198*
E199 cmdline.txt /*E199*
E20 motion.txt /*E20*
E200 autocmd.txt /*E200*
@@ -4114,7 +4117,6 @@ E274 eval.txt /*E274*
E275 textprop.txt /*E275*
E276 eval.txt /*E276*
E277 remote.txt /*E277*
E278 popup.txt /*E278*
E279 terminal.txt /*E279*
E28 syntax.txt /*E28*
E280 if_tcl.txt /*E280*
@@ -4180,7 +4182,6 @@ E337 gui.txt /*E337*
E338 editing.txt /*E338*
E339 message.txt /*E339*
E34 various.txt /*E34*
E340 vi_diff.txt /*E340*
E341 message.txt /*E341*
E342 message.txt /*E342*
E343 options.txt /*E343*
@@ -4388,7 +4389,6 @@ E534 options.txt /*E534*
E535 options.txt /*E535*
E536 options.txt /*E536*
E537 options.txt /*E537*
E538 options.txt /*E538*
E539 options.txt /*E539*
E54 pattern.txt /*E54*
E540 options.txt /*E540*
@@ -6351,6 +6351,7 @@ expression-commands eval.txt /*expression-commands*
expression-syntax eval.txt /*expression-syntax*
exrc starting.txt /*exrc*
extend() eval.txt /*extend()*
extendnew() eval.txt /*extendnew()*
extension-removal cmdline.txt /*extension-removal*
extensions-improvements todo.txt /*extensions-improvements*
f motion.txt /*f*
@@ -8680,6 +8681,7 @@ read-in-close-cb channel.txt /*read-in-close-cb*
read-messages insert.txt /*read-messages*
read-only-share editing.txt /*read-only-share*
read-stdin version5.txt /*read-stdin*
readblob() eval.txt /*readblob()*
readdir() eval.txt /*readdir()*
readdirex() eval.txt /*readdirex()*
readfile() eval.txt /*readfile()*
@@ -8945,6 +8947,7 @@ sinh() eval.txt /*sinh()*
skeleton autocmd.txt /*skeleton*
skip_defaults_vim starting.txt /*skip_defaults_vim*
slice eval.txt /*slice*
slice() eval.txt /*slice()*
slow-fast-terminal term.txt /*slow-fast-terminal*
slow-start starting.txt /*slow-start*
slow-terminal term.txt /*slow-terminal*
@@ -9340,6 +9343,8 @@ t_f6 version4.txt /*t_f6*
t_f7 version4.txt /*t_f7*
t_f8 version4.txt /*t_f8*
t_f9 version4.txt /*t_f9*
t_fd term.txt /*t_fd*
t_fe term.txt /*t_fe*
t_float-variable eval.txt /*t_float-variable*
t_fs term.txt /*t_fs*
t_func-variable eval.txt /*t_func-variable*
@@ -9714,6 +9719,7 @@ type-inference vim9.txt /*type-inference*
type-mistakes tips.txt /*type-mistakes*
typecorr-settings usr_41.txt /*typecorr-settings*
typecorr.txt usr_41.txt /*typecorr.txt*
typename() eval.txt /*typename()*
u undo.txt /*u*
uganda uganda.txt /*uganda*
uganda.txt uganda.txt /*uganda.txt*
@@ -10314,6 +10320,7 @@ xterm-command-server term.txt /*xterm-command-server*
xterm-copy-paste term.txt /*xterm-copy-paste*
xterm-cursor-keys term.txt /*xterm-cursor-keys*
xterm-end-home-keys term.txt /*xterm-end-home-keys*
xterm-focus-event term.txt /*xterm-focus-event*
xterm-function-keys term.txt /*xterm-function-keys*
xterm-modifier-keys term.txt /*xterm-modifier-keys*
xterm-mouse options.txt /*xterm-mouse*

View File

@@ -1,4 +1,4 @@
*term.txt* For Vim version 8.2. Last change: 2020 Dec 29
*term.txt* For Vim version 8.2. Last change: 2021 Jan 14
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -373,9 +373,9 @@ Added by Vim (there are no standard codes for these):
t_Ri restore icon text from stack *t_Ri* *'t_Ri'*
t_TE end of "raw" mode *t_TE* *'t_TE'*
t_TI put terminal into "raw" mode *t_TI* *'t_TI'*
t_fd disable focus-event tracking *t_TI* *'t_TI'*
t_fd disable focus-event tracking *t_fd* *'t_fd'*
|xterm-focus-event|
t_fe enable focus-event tracking *t_TI* *'t_TI'*
t_fe enable focus-event tracking *t_fe* *'t_fe'*
|xterm-focus-event|
Some codes have a start, middle and end part. The start and end are defined

View File

@@ -1,4 +1,4 @@
*todo.txt* For Vim version 8.2. Last change: 2021 Jan 11
*todo.txt* For Vim version 8.2. Last change: 2021 Jan 17
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -38,15 +38,7 @@ browser use: https://github.com/vim/vim/issues/1234
*known-bugs*
-------------------- Known bugs and current work -----------------------
no error for:
echo extend([0], ['a', true])
like it does for:
echo extend([0], ['a'])
At script level this does not give an error:
echo map([0], (_, v) => [])
Or:
var l: list<number> = [0]
echo map(l, (_, v) => [])
test_autocmd failure in Windows: Something wrong with system()?
Vim9 - Make everything work:
- Expand `=expr` in :next, :argedit, :argadd, :argdelete, :drop
@@ -117,6 +109,8 @@ Vim9 - Make everything work:
- compile "skip" argument of searchpair()
- compile "expr" and "call" expression of a channel in channel_exe_cmd()?
- give an error for "echo Func()" if Func() does not return anything.
- Using "windo echo expr" does not accept a line break inside "expr" (in a
:def function and at script level in a not executed block). #7681
Once Vim9 is stable:
- Change the help to prefer Vim9 syntax where appropriate
@@ -287,6 +281,9 @@ Have another look at the implementation.
Patch to implement the vimtutor with a plugin: #6414
Was originally written by Felipe Morales.
Adding "10" to 'spellsuggest' causes spell suggestions to become very slow.
(#4087)
Patch to find Python dll using registry key. (#7540)
Remove SPACE_IN_FILENAME ? It is only used for completion.
@@ -479,9 +476,6 @@ Help for ":argadd fname" says that if "fname" is already in the argument list
that entry is used. But instead it's always added. (#6210)
Add flag AL_FIND_ADD, if there is one argument find it in the list.
Adding "10" to 'spellsuggest' causes spell suggestions to become very slow.
(#4087)
behavior of i_CTRl-R_CTRL-R differs from documentation. (Paul Desmond Parker,
#5771)
@@ -556,14 +550,6 @@ when "qq" is mapped and after the first "q" the mouse is moved outside of the
gvim window (with focus follows mouse), then the K_FOCUSLOST key is put in the
input buffer. (#5302)
xterm should be able to pass focus changes to Vim, so that Vim can check for
buffers that changed. Perhaps in misc.c, function selectwindow().
Xterm 224 supports it!
Patch to make FocusGained and FocusLost work in modern terminals. (Hayaki
Saito, 2013 Apr 24) Update 2016 Aug 12.
Also see issue #609.
We could add the enable/disable sequences to t_ti/t_te or t_ks/t_ke.
:buffer completion does not escape "+" properly and results in a regexp error.
(#5467)

View File

@@ -1,4 +1,4 @@
*usr_41.txt* For Vim version 8.2. Last change: 2021 Jan 08
*usr_41.txt* For Vim version 8.2. Last change: 2021 Jan 13
VIM USER MANUAL - by Bram Moolenaar

View File

@@ -1,4 +1,4 @@
*various.txt* For Vim version 8.2. Last change: 2020 Nov 16
*various.txt* For Vim version 8.2. Last change: 2021 Jan 16
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -411,7 +411,7 @@ N *+mouse_sysmouse* Unix only: *BSD console mouse handling |sysmouse|
B *+mouse_sgr* Unix only: sgr mouse handling |sgr-mouse|
B *+mouse_urxvt* Unix only: urxvt mouse handling |urxvt-mouse|
N *+mouse_xterm* Unix only: xterm mouse handling |xterm-mouse|
N *+multi_byte* 16 and 32 bit characters |multibyte|
T *+multi_byte* Unicode support, 16 and 32 bit characters |multibyte|
*+multi_byte_ime* Win32 input method for multibyte chars |multibyte-ime|
N *+multi_lang* non-English language support |multi-lang|
m *+mzscheme* Mzscheme interface |mzscheme|
@@ -707,12 +707,12 @@ K Run a program to lookup the keyword under the
not more than one line.
[N]gs *gs* *:sl* *:sleep*
:[N]sl[eep] [N] [m] Do nothing for [N] seconds. When [m] is included,
:[N]sl[eep] [N][m] Do nothing for [N] seconds. When [m] is included,
sleep for [N] milliseconds. The count for "gs" always
uses seconds. The default is one second. >
:sleep "sleep for one second
:5sleep "sleep for five seconds
:sleep 100m "sleep for a hundred milliseconds
:sleep 100m "sleep for 100 milliseconds
10gs "sleep for ten seconds
< Can be interrupted with CTRL-C (CTRL-Break on
MS-Windows). "gs" stands for "goto sleep".
@@ -722,6 +722,9 @@ K Run a program to lookup the keyword under the
available when compiled with the |+netbeans_intg|
feature}
*:sl!* *:sleep!*
:[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
after the X server restarts, e.g. when running Vim for

View File

@@ -9661,7 +9661,7 @@ Solution: Check for tcsetattr() to return an error, retry when it does.
Files: src/os_unix.c
Patch 6.2f.018
Problem: Mac OS X 10.2: OK is defined to zero in cursus.h while Vim uses
Problem: Mac OS X 10.2: OK is defined to zero in curses.h while Vim uses
one. Redefining it causes a warning message.
Solution: Undefine OK before defining it to one. (Taro Muraoka)
Files: src/vim.h

View File

@@ -73,7 +73,7 @@ edit the termcap entry and try again. Vim has the |terminal-options|.
Vim has only a few limits for the files that can be edited {Vi: can not handle
<Nul> characters and characters above 128, has limited line length, many other
limits}.
*E340*
Maximum line length 2147483647 characters. Longer lines are split.
Maximum number of lines 2147483647 lines.
Maximum file size 2147483647 bytes (2 Gbyte) when a long integer is

View File

@@ -1,4 +1,4 @@
*vim9.txt* For Vim version 8.2. Last change: 2021 Jan 10
*vim9.txt* For Vim version 8.2. Last change: 2021 Jan 15
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -487,6 +487,9 @@ Now "exit_cb: Func})" is actually a valid command: save any changes to the
file "_cb: Func})" and exit. To avoid this kind of mistake in Vim9 script
there must be white space between most command names and the argument.
However, the argument of a command that is a command won't be recognized. For
example, after "windo echo expr" a line break inside "expr" will not be seen.
Notes:
- "enddef" cannot be used at the start of a continuation line, it ends the
@@ -527,17 +530,17 @@ that using a literal key is much more common than using an expression, and
considering that JavaScript uses this syntax, using the {} form for dictionary
literals is considered a much more useful syntax. In Vim9 script the {} form
uses literal keys: >
let dict = {key: value}
var dict = {key: value}
This works for alphanumeric characters, underscore and dash. If you want to
use another character, use a single or double quoted string: >
let dict = {'key with space': value}
let dict = {"key\twith\ttabs": value}
let dict = {'': value} # empty key
var dict = {'key with space': value}
var dict = {"key\twith\ttabs": value}
var dict = {'': value} # empty key
In case the key needs to be an expression, square brackets can be used, just
like in JavaScript: >
let dict = {["key" .. nr]: value}
var dict = {["key" .. nr]: value}
No :xit, :t, :append, :change or :insert ~
@@ -552,6 +555,29 @@ Comparators ~
The 'ignorecase' option is not used for comparators that use strings.
For loop ~
Legacy Vim script has some tricks to make a for loop over a list handle
deleting items at the current or previous item. In Vim9 script it just uses
the index, if items are deleted then items in the list will be skipped.
Example legacy script: >
let l = [1, 2, 3, 4]
for i in l
echo i
call remove(l, index(l, i))
endfor
Would echo:
1
2
3
4
In compiled Vim9 script you get:
1
3
Generally, you should not change the list that is iterated over. Make a copy
first if needed.
White space ~
Vim9 script enforces proper use of white space. This is no longer allowed: >
@@ -576,15 +602,17 @@ the start and end: >
White space is not allowed:
- Between a function name and the "(": >
call Func (arg) # Error!
call Func
Func (arg) # Error!
Func
\ (arg) # Error!
call Func(arg) # OK
call Func(
\ arg) # OK
call Func(
\ arg # OK
\ )
Func
(arg) # Error!
Func(arg) # OK
Func(
arg) # OK
Func(
arg # OK
)
Conditions and expressions ~
@@ -648,12 +676,13 @@ for v:null. When converting a boolean to a string "false" and "true" are
used, not "v:false" and "v:true" like in legacy script. "v:none" is not
changed, it is only used in JSON and has no equivalent in other languages.
Indexing a string with [idx] or [idx, idx] uses character indexes instead of
Indexing a string with [idx] or [idx : idx] uses character indexes instead of
byte indexes. Example: >
echo 'bár'[1]
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()|.
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
@@ -670,21 +699,22 @@ same time tries to support the legacy Vim commands. Some compromises had to
be made. Here is a summary of what might be unexpected.
Ex command ranges need to be prefixed with a colon. >
-> # legacy Vim: shifts the previous line to the right
->func() # Vim9: method call in continuation line
:-> # Vim9: shifts the previous line to the right
-> legacy Vim: shifts the previous line to the right
->func() Vim9: method call in a continuation line
:-> Vim9: shifts the previous line to the right
%s/a/b # legacy Vim: substitute on all lines
%s/a/b legacy Vim: substitute on all lines
x = alongname
% another # Vim9: line continuation without a backslash
:%s/a/b # Vim9: substitute on all lines
'text'->func() # Vim9: method call
:'t # legacy Vim: jump to mark m
% another Vim9: modulo operator in a continuation line
:%s/a/b Vim9: substitute on all lines
't legacy Vim: jump to mark t
'text'->func() Vim9: method call
:'t Vim9: jump to mark t
Some Ex commands can be confused with assignments in Vim9 script: >
g:name = value # assignment
g:pattern:cmd # invalid command - ERROR
:g:pattern:cmd # :global command
g:name = value # assignment
g:pattern:cmd # invalid command - ERROR
:g:pattern:cmd # :global command
Functions defined with `:def` compile the whole function. Legacy functions
can bail out, and the following lines are not parsed: >
@@ -704,7 +734,7 @@ Vim9 functions are compiled as a whole: >
For a workaround, split it in two functions: >
func Maybe()
if has('feature')
call MaybyInner()
call MaybeInner()
endif
endfunc
if has('feature')
@@ -720,7 +750,7 @@ evaluates to false: >
endif
enddef
< *vim9-user-command*
Another side effect of compiling a function is that the precense of a user
Another side effect of compiling a function is that the presence of a user
command is checked at compile time. If the user command is defined later an
error will result. This works: >
command -nargs=1 MyCommand echom <q-args>
@@ -1090,7 +1120,7 @@ actually needed. A recommended mechanism:
1. In the plugin define user commands, functions and/or mappings that refer to
an autoload script. >
command -nargs=1 SearchForStuff call searchfor#Stuff(<f-args>)
command -nargs=1 SearchForStuff searchfor#Stuff(<f-args>)
< This goes in .../plugin/anyname.vim. "anyname.vim" can be freely chosen.
@@ -1183,12 +1213,12 @@ When compiling lines of Vim commands into instructions as much as possible
should be done at compile time. Postponing it to runtime makes the execution
slower and means mistakes are found only later. For example, when
encountering the "+" character and compiling this into a generic add
instruction, at execution time the instruction would have to inspect the type
of the arguments and decide what kind of addition to do. And when the
type is dictionary throw an error. If the types are known to be numbers then
an "add number" instruction can be used, which is faster. The error can be
given at compile time, no error handling is needed at runtime, since adding
two numbers cannot fail.
instruction, at runtime the instruction would have to inspect the type of the
arguments and decide what kind of addition to do. And when the type is
dictionary throw an error. If the types are known to be numbers then an "add
number" instruction can be used, which is faster. The error can be given at
compile time, no error handling is needed at runtime, since adding two numbers
cannot fail.
The syntax for types, using <type> for compound types, is similar to Java. It
is easy to understand and widely used. The type names are what were used in

View File

@@ -1,7 +1,7 @@
" Vim filetype plugin
" Language: Vim
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2021 Jan 05
" Last Change: 2021 Jan 12
" Only do this when not done yet for this buffer
if exists("b:did_ftplugin")
@@ -51,12 +51,12 @@ setlocal keywordprg=:help
if "\n" .. getline(1, 10)->join("\n") =~# '\n\s*vim9\%[script]\>'
" Set 'comments' to format dashed lists in comments
setlocal com=sO:#\ -,mO:#\ \ ,eO:##,:#
" Comments start with a double quote in a legacy script;
" with # in a Vim9 script
setlocal commentstring=\"%s
" Comments starts with # in Vim9 script
setlocal commentstring=#%s
else
setlocal com=sO:\"\ -,mO:\"\ \ ,:\"
setlocal commentstring=#%s
" Comments starts with a double quote in legacy script
setlocal commentstring=\"%s
endif

View File

@@ -1,7 +1,7 @@
" Vim syntax file
" Language: C
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2020 Aug 28
" Last Change: 2021 Jan 11
" Quit when a (custom) syntax file was already loaded
if exists("b:current_syntax")
@@ -13,6 +13,9 @@ set cpo&vim
let s:ft = matchstr(&ft, '^\([^.]\)\+')
" check if this was included from cpp.vim
let s:in_cpp_family = exists("b:filetype_in_cpp_family")
" Optional embedded Autodoc parsing
" To enable it add: let g:c_autodoc = 1
" to your .vimrc
@@ -55,7 +58,7 @@ if !exists("c_no_cformat")
endif
" cCppString: same as cString, but ends at end of line
if s:ft ==# "cpp" && !exists("cpp_no_cpp11") && !exists("c_no_cformat")
if s:in_cpp_family && !exists("cpp_no_cpp11") && !exists("c_no_cformat")
" ISO C++11
syn region cString start=+\(L\|u\|u8\|U\|R\|LR\|u8R\|uR\|UR\)\="+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,cFormat,@Spell extend
syn region cCppString start=+\(L\|u\|u8\|U\|R\|LR\|u8R\|uR\|UR\)\="+ skip=+\\\\\|\\"\|\\$+ excludenl end=+"+ end='$' contains=cSpecial,cFormat,@Spell
@@ -87,7 +90,7 @@ syn match cSpecialCharacter display "L\='\\\o\{1,3}'"
syn match cSpecialCharacter display "'\\x\x\{1,2}'"
syn match cSpecialCharacter display "L'\\x\x\+'"
if (s:ft ==# "c" && !exists("c_no_c11")) || (s:ft ==# "cpp" && !exists("cpp_no_cpp11"))
if (s:ft ==# "c" && !exists("c_no_c11")) || (s:in_cpp_family && !exists("cpp_no_cpp11"))
" ISO C11 or ISO C++ 11
if exists("c_no_cformat")
syn region cString start=+\%(U\|u8\=\)"+ skip=+\\\\\|\\"+ end=+"+ contains=cSpecial,@Spell extend
@@ -130,7 +133,7 @@ endif
" But avoid matching <::.
syn cluster cParenGroup contains=cParenError,cIncluded,cSpecial,cCommentSkip,cCommentString,cComment2String,@cCommentGroup,cCommentStartError,cUserLabel,cBitField,cOctalZero,@cCppOutInGroup,cFormat,cNumber,cFloat,cOctal,cOctalError,cNumbersCom
if exists("c_no_curly_error")
if s:ft ==# 'cpp' && !exists("cpp_no_cpp11")
if s:in_cpp_family && !exists("cpp_no_cpp11")
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,@cStringGroup,@Spell
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
@@ -144,7 +147,7 @@ if exists("c_no_curly_error")
syn match cErrInParen display contained "^[{}]\|^<%\|^%>"
endif
elseif exists("c_no_bracket_error")
if s:ft ==# 'cpp' && !exists("cpp_no_cpp11")
if s:in_cpp_family && !exists("cpp_no_cpp11")
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,@cStringGroup,@Spell
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cParen,cString,@Spell
@@ -158,7 +161,7 @@ elseif exists("c_no_bracket_error")
syn match cErrInParen display contained "[{}]\|<%\|%>"
endif
else
if s:ft ==# 'cpp' && !exists("cpp_no_cpp11")
if s:in_cpp_family && !exists("cpp_no_cpp11")
syn region cParen transparent start='(' end=')' contains=ALLBUT,@cParenGroup,cCppParen,cErrInBracket,cCppBracket,@cStringGroup,@Spell
" cCppParen: same as cParen but ends at end-of-line; used in cDefine
syn region cCppParen transparent start='(' skip='\\$' excludenl end=')' end='$' contained contains=ALLBUT,@cParenGroup,cErrInBracket,cParen,cBracket,cString,@Spell
@@ -278,7 +281,7 @@ syn keyword cStorageClass static register auto volatile extern const
if exists("c_gnu")
syn keyword cStorageClass inline __attribute__
endif
if !exists("c_no_c99") && s:ft !=# 'cpp'
if !exists("c_no_c99") && !s:in_cpp_family
syn keyword cStorageClass inline restrict
endif
if !exists("c_no_c11")
@@ -420,7 +423,7 @@ endif
syn cluster cLabelGroup contains=cUserLabel
syn match cUserCont display "^\s*\zs\I\i*\s*:$" contains=@cLabelGroup
syn match cUserCont display ";\s*\zs\I\i*\s*:$" contains=@cLabelGroup
if s:ft ==# 'cpp'
if s:in_cpp_family
syn match cUserCont display "^\s*\zs\%(class\|struct\|enum\)\@!\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
syn match cUserCont display ";\s*\zs\%(class\|struct\|enum\)\@!\I\i*\s*:[^:]"me=e-1 contains=@cLabelGroup
else

View File

@@ -2,13 +2,16 @@
" Language: C++
" Current Maintainer: vim-jp (https://github.com/vim-jp/vim-cpp)
" Previous Maintainer: Ken Shan <ccshan@post.harvard.edu>
" Last Change: 2019 Dec 18
" Last Change: 2021 Jan 12
" quit when a syntax file was already loaded
if exists("b:current_syntax")
finish
endif
" inform C syntax that the file was included from cpp.vim
let b:filetype_in_cpp_family = 1
" Read the C syntax to start with
runtime! syntax/c.vim
unlet b:current_syntax

View File

@@ -1586,7 +1586,7 @@ decodeModifyOtherKeys(int c)
// Recognize:
// form 0: {lead}{key};{modifier}u
// form 1: {lead}27;{modifier};{key}~
if ((c == CSI || (c == ESC && *p == '[')) && typebuf.tb_len >= 4)
if (typebuf.tb_len >= 4 && (c == CSI || (c == ESC && *p == '[')))
{
idx = (*p == '[');
if (p[idx] == '2' && p[idx + 1] == '7' && p[idx + 2] == ';')

View File

@@ -84,7 +84,7 @@ EXTERN char e_const_requires_a_value[]
EXTERN char e_type_or_initialization_required[]
INIT(= N_("E1022: Type or initialization required"));
EXTERN char e_using_number_as_bool_nr[]
INIT(= N_("E1023: Using a Number as a Bool: %d"));
INIT(= N_("E1023: Using a Number as a Bool: %lld"));
EXTERN char e_using_number_as_string[]
INIT(= N_("E1024: Using a Number as a String"));
EXTERN char e_using_rcurly_outside_if_block_scope[]
@@ -343,3 +343,5 @@ EXTERN char e_mismatched_enddef[]
INIT(= N_("E1152: Mismatched enddef"));
EXTERN char e_invalid_operation_for_bool[]
INIT(= N_("E1153: Invalid operation for bool"));
EXTERN char e_divide_by_zero[]
INIT(= N_("E1154: Divide by zero"));

View File

@@ -57,14 +57,21 @@ static char_u *make_expanded_name(char_u *in_start, char_u *expr_start, char_u *
/*
* Return "n1" divided by "n2", taking care of dividing by zero.
* If "failed" is not NULL set it to TRUE when dividing by zero fails.
*/
varnumber_T
num_divide(varnumber_T n1, varnumber_T n2)
num_divide(varnumber_T n1, varnumber_T n2, int *failed)
{
varnumber_T result;
if (n2 == 0) // give an error message?
if (n2 == 0)
{
if (in_vim9script())
{
emsg(_(e_divide_by_zero));
if (failed != NULL)
*failed = TRUE;
}
if (n1 == 0)
result = VARNUM_MIN; // similar to NaN
else if (n1 < 0)
@@ -80,11 +87,17 @@ num_divide(varnumber_T n1, varnumber_T n2)
/*
* Return "n1" modulus "n2", taking care of dividing by zero.
* If "failed" is not NULL set it to TRUE when dividing by zero fails.
*/
varnumber_T
num_modulus(varnumber_T n1, varnumber_T n2)
num_modulus(varnumber_T n1, varnumber_T n2, int *failed)
{
// Give an error when n2 is 0?
if (n2 == 0 && in_vim9script())
{
emsg(_(e_divide_by_zero));
if (failed != NULL)
*failed = TRUE;
}
return (n2 == 0) ? 0 : (n1 % n2);
}
@@ -1513,6 +1526,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
varnumber_T n;
char_u numbuf[NUMBUFLEN];
char_u *s;
int failed = FALSE;
// Can't do anything with a Funcref, Dict, v:true on the right.
if (tv2->v_type != VAR_FUNC && tv2->v_type != VAR_DICT
@@ -1596,8 +1610,10 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
case '+': n += tv_get_number(tv2); break;
case '-': n -= tv_get_number(tv2); break;
case '*': n *= tv_get_number(tv2); break;
case '/': n = num_divide(n, tv_get_number(tv2)); break;
case '%': n = num_modulus(n, tv_get_number(tv2)); break;
case '/': n = num_divide(n, tv_get_number(tv2),
&failed); break;
case '%': n = num_modulus(n, tv_get_number(tv2),
&failed); break;
}
clear_tv(tv1);
tv1->v_type = VAR_NUMBER;
@@ -1616,7 +1632,7 @@ tv_op(typval_T *tv1, typval_T *tv2, char_u *op)
tv1->v_type = VAR_STRING;
tv1->vval.v_string = s;
}
return OK;
return failed ? FAIL : OK;
case VAR_FLOAT:
#ifdef FEAT_FLOAT
@@ -3193,12 +3209,16 @@ eval6(
else
#endif
{
int failed = FALSE;
if (op == '*')
n1 = n1 * n2;
else if (op == '/')
n1 = num_divide(n1, n2);
n1 = num_divide(n1, n2, &failed);
else
n1 = num_modulus(n1, n2);
n1 = num_modulus(n1, n2, &failed);
if (failed)
return FAIL;
rettv->v_type = VAR_NUMBER;
rettv->vval.v_number = n1;

View File

@@ -449,6 +449,11 @@ ret_bool(int argcount UNUSED, type_T **argtypes UNUSED)
return &t_bool;
}
static type_T *
ret_number_bool(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_number_bool;
}
static type_T *
ret_number(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_number;
@@ -690,9 +695,9 @@ static funcentry_T global_functions[] =
{"and", 2, 2, FEARG_1, NULL,
ret_number, f_and},
{"append", 2, 2, FEARG_2, NULL,
ret_number, f_append},
ret_number_bool, f_append},
{"appendbufline", 3, 3, FEARG_3, NULL,
ret_number, f_appendbufline},
ret_number_bool, f_appendbufline},
{"argc", 0, 1, 0, NULL,
ret_number, f_argc},
{"argidx", 0, 0, 0, NULL,
@@ -704,29 +709,29 @@ static funcentry_T global_functions[] =
{"asin", 1, 1, FEARG_1, NULL,
ret_float, FLOAT_FUNC(f_asin)},
{"assert_beeps", 1, 2, FEARG_1, NULL,
ret_number, f_assert_beeps},
ret_number_bool, f_assert_beeps},
{"assert_equal", 2, 3, FEARG_2, NULL,
ret_number, f_assert_equal},
ret_number_bool, f_assert_equal},
{"assert_equalfile", 2, 3, FEARG_1, NULL,
ret_number, f_assert_equalfile},
ret_number_bool, f_assert_equalfile},
{"assert_exception", 1, 2, 0, NULL,
ret_number, f_assert_exception},
ret_number_bool, f_assert_exception},
{"assert_fails", 1, 5, FEARG_1, NULL,
ret_number, f_assert_fails},
ret_number_bool, f_assert_fails},
{"assert_false", 1, 2, FEARG_1, NULL,
ret_number, f_assert_false},
ret_number_bool, f_assert_false},
{"assert_inrange", 3, 4, FEARG_3, NULL,
ret_number, f_assert_inrange},
ret_number_bool, f_assert_inrange},
{"assert_match", 2, 3, FEARG_2, NULL,
ret_number, f_assert_match},
ret_number_bool, f_assert_match},
{"assert_notequal", 2, 3, FEARG_2, NULL,
ret_number, f_assert_notequal},
ret_number_bool, f_assert_notequal},
{"assert_notmatch", 2, 3, FEARG_2, NULL,
ret_number, f_assert_notmatch},
ret_number_bool, f_assert_notmatch},
{"assert_report", 1, 1, FEARG_1, NULL,
ret_number, f_assert_report},
ret_number_bool, f_assert_report},
{"assert_true", 1, 2, FEARG_1, NULL,
ret_number, f_assert_true},
ret_number_bool, f_assert_true},
{"atan", 1, 1, FEARG_1, NULL,
ret_float, FLOAT_FUNC(f_atan)},
{"atan2", 2, 2, FEARG_1, NULL,
@@ -762,19 +767,19 @@ static funcentry_T global_functions[] =
{"bufadd", 1, 1, FEARG_1, NULL,
ret_number, f_bufadd},
{"bufexists", 1, 1, FEARG_1, NULL,
ret_number, f_bufexists},
ret_number_bool, f_bufexists},
{"buffer_exists", 1, 1, FEARG_1, NULL, // obsolete
ret_number, f_bufexists},
ret_number_bool, f_bufexists},
{"buffer_name", 0, 1, FEARG_1, NULL, // obsolete
ret_string, f_bufname},
{"buffer_number", 0, 1, FEARG_1, NULL, // obsolete
ret_number, f_bufnr},
{"buflisted", 1, 1, FEARG_1, NULL,
ret_number, f_buflisted},
ret_number_bool, f_buflisted},
{"bufload", 1, 1, FEARG_1, NULL,
ret_void, f_bufload},
{"bufloaded", 1, 1, FEARG_1, NULL,
ret_number, f_bufloaded},
ret_number_bool, f_bufloaded},
{"bufname", 0, 1, FEARG_1, NULL,
ret_string, f_bufname},
{"bufnr", 0, 2, FEARG_1, NULL,
@@ -794,7 +799,7 @@ static funcentry_T global_functions[] =
{"ceil", 1, 1, FEARG_1, NULL,
ret_float, FLOAT_FUNC(f_ceil)},
{"ch_canread", 1, 1, FEARG_1, NULL,
ret_number, JOB_FUNC(f_ch_canread)},
ret_number_bool, JOB_FUNC(f_ch_canread)},
{"ch_close", 1, 1, FEARG_1, NULL,
ret_void, JOB_FUNC(f_ch_close)},
{"ch_close_in", 1, 1, FEARG_1, NULL,
@@ -852,7 +857,7 @@ static funcentry_T global_functions[] =
{"complete_add", 1, 1, FEARG_1, NULL,
ret_number, f_complete_add},
{"complete_check", 0, 0, 0, NULL,
ret_number, f_complete_check},
ret_number_bool, f_complete_check},
{"complete_info", 0, 1, FEARG_1, NULL,
ret_dict_any, f_complete_info},
{"confirm", 1, 4, FEARG_1, NULL,
@@ -880,19 +885,19 @@ static funcentry_T global_functions[] =
{"deepcopy", 1, 2, FEARG_1, NULL,
ret_first_arg, f_deepcopy},
{"delete", 1, 2, FEARG_1, NULL,
ret_number, f_delete},
ret_number_bool, f_delete},
{"deletebufline", 2, 3, FEARG_1, NULL,
ret_number, f_deletebufline},
ret_number_bool, f_deletebufline},
{"did_filetype", 0, 0, 0, NULL,
ret_number, f_did_filetype},
ret_number_bool, f_did_filetype},
{"diff_filler", 1, 1, FEARG_1, NULL,
ret_number, f_diff_filler},
{"diff_hlID", 2, 2, FEARG_1, NULL,
ret_number, f_diff_hlID},
{"echoraw", 1, 1, FEARG_1, NULL,
ret_number, f_echoraw},
ret_void, f_echoraw},
{"empty", 1, 1, FEARG_1, NULL,
ret_number, f_empty},
ret_number_bool, f_empty},
{"environ", 0, 0, 0, NULL,
ret_dict_string, f_environ},
{"escape", 2, 2, FEARG_1, NULL,
@@ -900,7 +905,7 @@ static funcentry_T global_functions[] =
{"eval", 1, 1, FEARG_1, NULL,
ret_any, f_eval},
{"eventhandler", 0, 0, 0, NULL,
ret_number, f_eventhandler},
ret_number_bool, f_eventhandler},
{"executable", 1, 1, FEARG_1, NULL,
ret_number, f_executable},
{"execute", 1, 2, FEARG_1, NULL,
@@ -908,7 +913,7 @@ static funcentry_T global_functions[] =
{"exepath", 1, 1, FEARG_1, NULL,
ret_string, f_exepath},
{"exists", 1, 1, FEARG_1, NULL,
ret_number, f_exists},
ret_number_bool, f_exists},
{"exp", 1, 1, FEARG_1, NULL,
ret_float, FLOAT_FUNC(f_exp)},
{"expand", 1, 3, FEARG_1, NULL,
@@ -922,9 +927,9 @@ static funcentry_T global_functions[] =
{"feedkeys", 1, 2, FEARG_1, NULL,
ret_void, f_feedkeys},
{"file_readable", 1, 1, FEARG_1, NULL, // obsolete
ret_number, f_filereadable},
ret_number_bool, f_filereadable},
{"filereadable", 1, 1, FEARG_1, NULL,
ret_number, f_filereadable},
ret_number_bool, f_filereadable},
{"filewritable", 1, 1, FEARG_1, NULL,
ret_number, f_filewritable},
{"filter", 2, 2, FEARG_1, NULL,
@@ -1010,7 +1015,7 @@ static funcentry_T global_functions[] =
{"getftype", 1, 1, FEARG_1, NULL,
ret_string, f_getftype},
{"getimstatus", 0, 0, 0, NULL,
ret_number, f_getimstatus},
ret_number_bool, f_getimstatus},
{"getjumplist", 0, 2, FEARG_1, NULL,
ret_list_any, f_getjumplist},
{"getline", 1, 2, FEARG_1, NULL,
@@ -1062,21 +1067,21 @@ static funcentry_T global_functions[] =
{"globpath", 2, 5, FEARG_2, NULL,
ret_any, f_globpath},
{"has", 1, 2, 0, NULL,
ret_number, f_has},
ret_number_bool, f_has},
{"has_key", 2, 2, FEARG_1, NULL,
ret_number, f_has_key},
ret_number_bool, f_has_key},
{"haslocaldir", 0, 2, FEARG_1, NULL,
ret_number, f_haslocaldir},
{"hasmapto", 1, 3, FEARG_1, NULL,
ret_number, f_hasmapto},
ret_number_bool, f_hasmapto},
{"highlightID", 1, 1, FEARG_1, NULL, // obsolete
ret_number, f_hlID},
{"highlight_exists",1, 1, FEARG_1, NULL, // obsolete
ret_number, f_hlexists},
ret_number_bool, f_hlexists},
{"histadd", 2, 2, FEARG_2, NULL,
ret_number, f_histadd},
ret_number_bool, f_histadd},
{"histdel", 1, 2, FEARG_1, NULL,
ret_number, f_histdel},
ret_number_bool, f_histdel},
{"histget", 1, 2, FEARG_1, NULL,
ret_string, f_histget},
{"histnr", 1, 1, FEARG_1, NULL,
@@ -1084,7 +1089,7 @@ static funcentry_T global_functions[] =
{"hlID", 1, 1, FEARG_1, NULL,
ret_number, f_hlID},
{"hlexists", 1, 1, FEARG_1, NULL,
ret_number, f_hlexists},
ret_number_bool, f_hlexists},
{"hostname", 0, 0, 0, NULL,
ret_string, f_hostname},
{"iconv", 3, 3, FEARG_1, NULL,
@@ -1100,9 +1105,9 @@ static funcentry_T global_functions[] =
{"inputlist", 1, 1, FEARG_1, NULL,
ret_number, f_inputlist},
{"inputrestore", 0, 0, 0, NULL,
ret_number, f_inputrestore},
ret_number_bool, f_inputrestore},
{"inputsave", 0, 0, 0, NULL,
ret_number, f_inputsave},
ret_number_bool, f_inputsave},
{"inputsecret", 1, 2, FEARG_1, NULL,
ret_string, f_inputsecret},
{"insert", 2, 3, FEARG_1, arg3_insert,
@@ -1112,13 +1117,13 @@ static funcentry_T global_functions[] =
{"invert", 1, 1, FEARG_1, NULL,
ret_number, f_invert},
{"isdirectory", 1, 1, FEARG_1, NULL,
ret_number, f_isdirectory},
ret_number_bool, f_isdirectory},
{"isinf", 1, 1, FEARG_1, NULL,
ret_number, MATH_FUNC(f_isinf)},
{"islocked", 1, 1, FEARG_1, NULL,
ret_number, f_islocked},
ret_number_bool, f_islocked},
{"isnan", 1, 1, FEARG_1, NULL,
ret_number, MATH_FUNC(f_isnan)},
ret_number_bool, MATH_FUNC(f_isnan)},
{"items", 1, 1, FEARG_1, NULL,
ret_list_any, f_items},
{"job_getchannel", 1, 1, FEARG_1, NULL,
@@ -1132,7 +1137,7 @@ static funcentry_T global_functions[] =
{"job_status", 1, 1, FEARG_1, NULL,
ret_string, JOB_FUNC(f_job_status)},
{"job_stop", 1, 2, FEARG_1, NULL,
ret_number, JOB_FUNC(f_job_stop)},
ret_number_bool, JOB_FUNC(f_job_stop)},
{"join", 1, 2, FEARG_1, NULL,
ret_string, f_join},
{"js_decode", 1, 1, FEARG_1, NULL,
@@ -1166,7 +1171,7 @@ static funcentry_T global_functions[] =
{"listener_flush", 0, 1, FEARG_1, NULL,
ret_void, f_listener_flush},
{"listener_remove", 1, 1, FEARG_1, NULL,
ret_number, f_listener_remove},
ret_number_bool, f_listener_remove},
{"localtime", 0, 0, 0, NULL,
ret_number, f_localtime},
{"log", 1, 1, FEARG_1, NULL,
@@ -1200,7 +1205,7 @@ static funcentry_T global_functions[] =
{"matcharg", 1, 1, FEARG_1, NULL,
ret_list_string, f_matcharg},
{"matchdelete", 1, 2, FEARG_1, NULL,
ret_number, f_matchdelete},
ret_number_bool, f_matchdelete},
{"matchend", 2, 4, FEARG_1, NULL,
ret_number, f_matchend},
{"matchfuzzy", 2, 3, FEARG_1, NULL,
@@ -1226,7 +1231,7 @@ static funcentry_T global_functions[] =
{"min", 1, 1, FEARG_1, NULL,
ret_any, f_min},
{"mkdir", 1, 3, FEARG_1, NULL,
ret_number, f_mkdir},
ret_number_bool, f_mkdir},
{"mode", 0, 1, FEARG_1, NULL,
ret_string, f_mode},
{"mzeval", 1, 1, FEARG_1, NULL,
@@ -1332,7 +1337,7 @@ static funcentry_T global_functions[] =
{"pum_getpos", 0, 0, 0, NULL,
ret_dict_number, f_pum_getpos},
{"pumvisible", 0, 0, 0, NULL,
ret_number, f_pumvisible},
ret_number_bool, f_pumvisible},
{"py3eval", 1, 1, FEARG_1, NULL,
ret_any,
#ifdef FEAT_PYTHON3
@@ -1396,7 +1401,7 @@ static funcentry_T global_functions[] =
{"remove", 2, 3, FEARG_1, NULL,
ret_remove, f_remove},
{"rename", 2, 2, FEARG_1, NULL,
ret_number, f_rename},
ret_number_bool, f_rename},
{"repeat", 2, 2, FEARG_1, NULL,
ret_first_arg, f_repeat},
{"resolve", 1, 1, FEARG_1, NULL,
@@ -1432,7 +1437,7 @@ static funcentry_T global_functions[] =
{"searchcount", 0, 1, FEARG_1, NULL,
ret_dict_any, f_searchcount},
{"searchdecl", 1, 3, FEARG_1, NULL,
ret_number, f_searchdecl},
ret_number_bool, f_searchdecl},
{"searchpair", 3, 7, 0, NULL,
ret_number, f_searchpair},
{"searchpairpos", 3, 7, 0, NULL,
@@ -1440,45 +1445,45 @@ static funcentry_T global_functions[] =
{"searchpos", 1, 5, FEARG_1, NULL,
ret_list_number, f_searchpos},
{"server2client", 2, 2, FEARG_1, NULL,
ret_number, f_server2client},
ret_number_bool, f_server2client},
{"serverlist", 0, 0, 0, NULL,
ret_string, f_serverlist},
{"setbufline", 3, 3, FEARG_3, NULL,
ret_number, f_setbufline},
ret_number_bool, f_setbufline},
{"setbufvar", 3, 3, FEARG_3, NULL,
ret_void, f_setbufvar},
{"setcellwidths", 1, 1, FEARG_1, NULL,
ret_void, f_setcellwidths},
{"setcharpos", 2, 2, FEARG_2, NULL,
ret_number, f_setcharpos},
ret_number_bool, f_setcharpos},
{"setcharsearch", 1, 1, FEARG_1, NULL,
ret_void, f_setcharsearch},
{"setcmdpos", 1, 1, FEARG_1, NULL,
ret_number, f_setcmdpos},
{"setcursorcharpos", 1, 3, FEARG_1, NULL,
ret_number, f_setcursorcharpos},
ret_number_bool, f_setcmdpos},
{"setcursorcharpos", 1, 3, FEARG_1, NULL,
ret_number_bool, f_setcursorcharpos},
{"setenv", 2, 2, FEARG_2, NULL,
ret_void, f_setenv},
{"setfperm", 2, 2, FEARG_1, NULL,
ret_number, f_setfperm},
ret_number_bool, f_setfperm},
{"setline", 2, 2, FEARG_2, NULL,
ret_number, f_setline},
ret_number_bool, f_setline},
{"setloclist", 2, 4, FEARG_2, NULL,
ret_number, f_setloclist},
ret_number_bool, f_setloclist},
{"setmatches", 1, 2, FEARG_1, NULL,
ret_number, f_setmatches},
ret_number_bool, f_setmatches},
{"setpos", 2, 2, FEARG_2, NULL,
ret_number, f_setpos},
ret_number_bool, f_setpos},
{"setqflist", 1, 3, FEARG_1, NULL,
ret_number, f_setqflist},
ret_number_bool, f_setqflist},
{"setreg", 2, 3, FEARG_2, NULL,
ret_number, f_setreg},
ret_number_bool, f_setreg},
{"settabvar", 3, 3, FEARG_3, NULL,
ret_void, f_settabvar},
{"settabwinvar", 4, 4, FEARG_4, NULL,
ret_void, f_settabwinvar},
{"settagstack", 2, 3, FEARG_2, NULL,
ret_number, f_settagstack},
ret_number_bool, f_settagstack},
{"setwinvar", 3, 3, FEARG_3, NULL,
ret_void, f_setwinvar},
{"sha256", 1, 1, FEARG_1, NULL,
@@ -1506,9 +1511,9 @@ static funcentry_T global_functions[] =
{"sign_placelist", 1, 1, FEARG_1, NULL,
ret_list_number, SIGN_FUNC(f_sign_placelist)},
{"sign_undefine", 0, 1, FEARG_1, NULL,
ret_number, SIGN_FUNC(f_sign_undefine)},
ret_number_bool, SIGN_FUNC(f_sign_undefine)},
{"sign_unplace", 1, 2, FEARG_1, NULL,
ret_number, SIGN_FUNC(f_sign_unplace)},
ret_number_bool, SIGN_FUNC(f_sign_unplace)},
{"sign_unplacelist", 1, 2, FEARG_1, NULL,
ret_list_number, SIGN_FUNC(f_sign_unplacelist)},
{"simplify", 1, 1, FEARG_1, NULL,
@@ -1788,7 +1793,7 @@ static funcentry_T global_functions[] =
{"win_gettype", 0, 1, FEARG_1, NULL,
ret_string, f_win_gettype},
{"win_gotoid", 1, 1, FEARG_1, NULL,
ret_number, f_win_gotoid},
ret_number_bool, f_win_gotoid},
{"win_id2tabwin", 1, 1, FEARG_1, NULL,
ret_list_number, f_win_id2tabwin},
{"win_id2win", 1, 1, FEARG_1, NULL,
@@ -1796,7 +1801,7 @@ static funcentry_T global_functions[] =
{"win_screenpos", 1, 1, FEARG_1, NULL,
ret_list_number, f_win_screenpos},
{"win_splitmove", 2, 3, FEARG_1, NULL,
ret_number, f_win_splitmove},
ret_number_bool, f_win_splitmove},
{"winbufnr", 1, 1, FEARG_1, NULL,
ret_number, f_winbufnr},
{"wincol", 0, 0, 0, NULL,
@@ -1822,7 +1827,7 @@ static funcentry_T global_functions[] =
{"wordcount", 0, 0, 0, NULL,
ret_dict_number, f_wordcount},
{"writefile", 2, 3, FEARG_1, NULL,
ret_number, f_writefile},
ret_number_bool, f_writefile},
{"xor", 2, 2, FEARG_1, NULL,
ret_number, f_xor},
};
@@ -2567,7 +2572,7 @@ f_charidx(typval_T *argvars, typval_T *rettv)
{
char_u *str;
varnumber_T idx;
int countcc = FALSE;
varnumber_T countcc = FALSE;
char_u *p;
int len;
int (*ptr2len)(char_u *);
@@ -2588,7 +2593,7 @@ f_charidx(typval_T *argvars, typval_T *rettv)
return;
if (argvars[2].v_type != VAR_UNKNOWN)
countcc = (int)tv_get_bool(&argvars[2]);
countcc = tv_get_bool(&argvars[2]);
if (countcc < 0 || countcc > 1)
{
semsg(_(e_using_number_as_bool_nr), countcc);
@@ -2848,11 +2853,11 @@ f_debugbreak(typval_T *argvars, typval_T *rettv)
static void
f_deepcopy(typval_T *argvars, typval_T *rettv)
{
int noref = 0;
varnumber_T noref = 0;
int copyID;
if (argvars[1].v_type != VAR_UNKNOWN)
noref = (int)tv_get_bool_chk(&argvars[1], NULL);
noref = tv_get_bool_chk(&argvars[1], NULL);
if (noref < 0 || noref > 1)
semsg(_(e_using_number_as_bool_nr), noref);
else
@@ -8310,7 +8315,7 @@ f_setcharsearch(typval_T *argvars, typval_T *rettv UNUSED)
* "setcursorcharpos" function
*/
static void
f_setcursorcharpos(typval_T *argvars, typval_T *rettv UNUSED)
f_setcursorcharpos(typval_T *argvars, typval_T *rettv)
{
set_cursorpos(argvars, rettv, TRUE);
}
@@ -9185,12 +9190,12 @@ f_strlen(typval_T *argvars, typval_T *rettv)
f_strchars(typval_T *argvars, typval_T *rettv)
{
char_u *s = tv_get_string(&argvars[0]);
int skipcc = FALSE;
varnumber_T skipcc = FALSE;
varnumber_T len = 0;
int (*func_mb_ptr2char_adv)(char_u **pp);
if (argvars[1].v_type != VAR_UNKNOWN)
skipcc = (int)tv_get_bool(&argvars[1]);
skipcc = tv_get_bool(&argvars[1]);
if (skipcc < 0 || skipcc > 1)
semsg(_(e_using_number_as_bool_nr), skipcc);
else

View File

@@ -1019,7 +1019,7 @@ skip_var_list(
for (;;)
{
p = skipwhite(p + 1); // skip whites after '[', ';' or ','
s = skip_var_one(p, FALSE);
s = skip_var_one(p, include_type);
if (s == p)
{
if (!silent)
@@ -1061,17 +1061,21 @@ skip_var_list(
char_u *
skip_var_one(char_u *arg, int include_type)
{
char_u *end;
char_u *end;
int vim9 = in_vim9script();
if (*arg == '@' && arg[1] != NUL)
return arg + 2;
end = find_name_end(*arg == '$' || *arg == '&' ? arg + 1 : arg,
NULL, NULL, FNE_INCL_BR | FNE_CHECK_START);
if (include_type && in_vim9script())
// "a: type" is declaring variable "a" with a type, not "a:".
// Same for "s: type".
if (vim9 && end == arg + 2 && end[-1] == ':')
--end;
if (include_type && vim9)
{
// "a: type" is declaring variable "a" with a type, not "a:".
if (end == arg + 2 && end[-1] == ':')
--end;
if (*end == ':')
end = skip_type(skipwhite(end + 1), FALSE);
}
@@ -1406,8 +1410,10 @@ ex_let_one(
case '+': n = numval + n; break;
case '-': n = numval - n; break;
case '*': n = numval * n; break;
case '/': n = (long)num_divide(numval, n); break;
case '%': n = (long)num_modulus(numval, n); break;
case '/': n = (long)num_divide(numval, n,
&failed); break;
case '%': n = (long)num_modulus(numval, n,
&failed); break;
}
}
else if (opt_type == gov_string

View File

@@ -1365,7 +1365,7 @@ EXCMD(CMD_silent, "silent", ex_wrongmodifier,
EX_NEEDARG|EX_EXTRA|EX_BANG|EX_NOTRLCOM|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
ADDR_NONE),
EXCMD(CMD_sleep, "sleep", ex_sleep,
EX_RANGE|EX_COUNT|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
EX_BANG|EX_RANGE|EX_COUNT|EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
ADDR_OTHER),
EXCMD(CMD_slast, "slast", ex_last,
EX_EXTRA|EX_BANG|EX_CMDARG|EX_ARGOPT|EX_TRLBAR,

View File

@@ -7225,14 +7225,17 @@ ex_sleep(exarg_T *eap)
case NUL: len *= 1000L; break;
default: semsg(_(e_invarg2), eap->arg); return;
}
do_sleep(len);
// Hide the cursor if invoked with !
do_sleep(len, eap->forceit);
}
/*
* Sleep for "msec" milliseconds, but keep checking for a CTRL-C every second.
* Hide the cursor if "hide_cursor" is TRUE.
*/
void
do_sleep(long msec)
do_sleep(long msec, int hide_cursor)
{
long done = 0;
long wait_now;
@@ -7244,7 +7247,11 @@ do_sleep(long msec)
ELAPSED_INIT(start_tv);
# endif
cursor_on();
if (hide_cursor)
cursor_off();
else
cursor_on();
out_flush_cursor(FALSE, FALSE);
while (!got_int && done < msec)
{

View File

@@ -925,7 +925,7 @@ list_slice_or_index(
if (!range)
{
if (verbose)
semsg(_(e_listidx), n1_arg);
semsg(_(e_listidx), (long)n1_arg);
return FAIL;
}
n1 = n1 < 0 ? 0 : len;
@@ -1452,7 +1452,7 @@ list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
listitem_T *item, *item2;
listitem_T *li;
int error = FALSE;
int idx;
long idx;
if ((l = argvars[0].vval.v_list) == NULL
|| value_check_lock(l->lv_lock, arg_errmsg, TRUE))
@@ -1475,7 +1475,7 @@ list_remove(typval_T *argvars, typval_T *rettv, char_u *arg_errmsg)
else
{
// Remove range of items, return list with values.
int end = (long)tv_get_number_chk(&argvars[2], &error);
long end = (long)tv_get_number_chk(&argvars[2], &error);
if (error)
; // type error: do nothing

View File

@@ -2531,6 +2531,8 @@ static struct key_name_entry
{K_CURSORHOLD, (char_u *)"CursorHold"},
{K_IGNORE, (char_u *)"Ignore"},
{K_COMMAND, (char_u *)"Cmd"},
{K_FOCUSGAINED, (char_u *)"FocusGained"},
{K_FOCUSLOST, (char_u *)"FocusLost"},
{0, NULL}
// NOTE: When adding a long name update MAX_KEY_NAME_LEN.
};

View File

@@ -993,7 +993,7 @@ getcount:
// something different from CTRL-N. Can't be avoided.
while ((c = vpeekc()) <= 0 && towait > 0L)
{
do_sleep(towait > 50L ? 50L : towait);
do_sleep(towait > 50L ? 50L : towait, FALSE);
towait -= 50L;
}
if (c > 0)
@@ -6230,7 +6230,7 @@ nv_g_cmd(cmdarg_T *cap)
* "gs": Goto sleep.
*/
case 's':
do_sleep(cap->count1 * 1000L);
do_sleep(cap->count1 * 1000L, FALSE);
break;
/*

View File

@@ -1,6 +1,6 @@
/* eval.c */
varnumber_T num_divide(varnumber_T n1, varnumber_T n2);
varnumber_T num_modulus(varnumber_T n1, varnumber_T n2);
varnumber_T num_divide(varnumber_T n1, varnumber_T n2, int *failed);
varnumber_T num_modulus(varnumber_T n1, varnumber_T n2, int *failed);
void eval_init(void);
void eval_clear(void);
void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip);

View File

@@ -42,7 +42,7 @@ void free_cd_dir(void);
void post_chdir(cdscope_T scope);
int changedir_func(char_u *new_dir, int forceit, cdscope_T scope);
void ex_cd(exarg_T *eap);
void do_sleep(long msec);
void do_sleep(long msec, int hide_cursor);
void ex_may_print(exarg_T *eap);
void ex_redraw(exarg_T *eap);
int vim_mkdir_emsg(char_u *name, int prot);

View File

@@ -770,6 +770,7 @@ spell_find_suggest(
int c;
int i;
langp_T *lp;
int did_intern = FALSE;
// Set the info in "*su".
CLEAR_POINTER(su);
@@ -863,12 +864,13 @@ spell_find_suggest(
else if (STRNCMP(buf, "file:", 5) == 0)
// Use list of suggestions in a file.
spell_suggest_file(su, buf + 5);
else
else if (!did_intern)
{
// Use internal method.
// Use internal method once.
spell_suggest_intern(su, interactive);
if (sps_flags & SPS_DOUBLE)
do_combine = TRUE;
did_intern = TRUE;
}
}

View File

@@ -2713,7 +2713,7 @@ out_str_cf(char_u *s)
else
{
++p;
do_sleep(duration);
do_sleep(duration, FALSE);
}
# else
// Rely on the terminal library to sleep.

View File

@@ -246,6 +246,7 @@ NEW_TESTS = \
test_shortpathname \
test_signals \
test_signs \
test_sleep \
test_smartindent \
test_sort \
test_sound \
@@ -472,6 +473,7 @@ NEW_TESTS_RES = \
test_shortpathname.res \
test_signals.res \
test_signs.res \
test_sleep.res \
test_smartindent.res \
test_sort.res \
test_sound.res \

View File

@@ -781,8 +781,9 @@ func Test_highlight_User()
endfunc
" Test for using RGB color values in a highlight group
func Test_highlight_RGB_color()
CheckGui
func Test_xxlast_highlight_RGB_color()
CheckCanRunGui
gui -f
hi MySearch guifg=#110000 guibg=#001100 guisp=#000011
call assert_equal('#110000', synIDattr(synIDtrans(hlID('MySearch')), 'fg#'))
call assert_equal('#001100', synIDattr(synIDtrans(hlID('MySearch')), 'bg#'))

View File

@@ -371,8 +371,14 @@ func Test_set_errors()
call assert_fails('set foldmarker=x', 'E536:')
call assert_fails('set commentstring=x', 'E537:')
call assert_fails('set complete=x', 'E539:')
call assert_fails('set rulerformat=%-', 'E539:')
call assert_fails('set rulerformat=%(', 'E542:')
call assert_fails('set rulerformat=%15(%%', 'E542:')
call assert_fails('set statusline=%$', 'E539:')
call assert_fails('set statusline=%{', 'E540:')
call assert_fails('set statusline=%(', 'E542:')
call assert_fails('set statusline=%)', 'E542:')
if has('cursorshape')
" This invalid value for 'guicursor' used to cause Vim to crash.
call assert_fails('set guicursor=i-ci,r-cr:h', 'E545:')
@@ -406,11 +412,22 @@ func Test_set_errors()
call assert_fails('set wildchar=<abc>', 'E474:')
call assert_fails('set cmdheight=1a', 'E521:')
call assert_fails('set invcmdheight', 'E474:')
if has('python') && has('python3')
if has('python') || has('python3')
call assert_fails('set pyxversion=6', 'E474:')
endif
call assert_fails("let &tabstop='ab'", 'E521:')
call assert_fails('set spellcapcheck=%\\(', 'E54:')
call assert_fails('set sessionoptions=curdir,sesdir', 'E474:')
call assert_fails('set foldmarker={{{,', 'E474:')
call assert_fails('set sessionoptions=sesdir,curdir', 'E474:')
call assert_fails('set listchars=trail:· ambiwidth=double', 'E834:')
set listchars&
call assert_fails('set fillchars=stl:· ambiwidth=double', 'E835:')
set fillchars&
call assert_fails('set fileencoding=latin1,utf-8', 'E474:')
set nomodifiable
call assert_fails('set fileencoding=latin1', 'E21:')
set modifiable&
endfunc
func CheckWasSet(name)

View File

@@ -0,0 +1,26 @@
" Test for sleep and sleep! commands
func! s:get_time_ms()
let timestr = reltimestr(reltime())
let dotidx = stridx(timestr, '.')
let sec = str2nr(timestr[:dotidx])
let msec = str2nr(timestr[dotidx + 1:])
return (sec * 1000) + (msec / 1000)
endfunc
func! s:assert_takes_longer(cmd, time_ms)
let start = s:get_time_ms()
execute a:cmd
let end = s:get_time_ms()
call assert_true(end - start >=# a:time_ms)
endfun
func! Test_sleep_bang()
call s:assert_takes_longer('sleep 50m', 50)
call s:assert_takes_longer('sleep! 50m', 50)
call s:assert_takes_longer('sl 50m', 50)
call s:assert_takes_longer('sl! 50m', 50)
call s:assert_takes_longer('1sleep', 1000)
endfunc
" vim: shiftwidth=2 sts=2 expandtab

View File

@@ -350,7 +350,7 @@ def Test_assign_index()
var lines: list<string>
lines['a'] = 'asdf'
END
CheckDefFailure(lines, 'E39:', 2)
CheckDefFailure(lines, 'E1012:', 2)
lines =<< trim END
var lines: string
@@ -561,6 +561,15 @@ def Test_assignment_list()
CheckDefExecFailure(lines, 'E1147:', 2)
enddef
def Test_assignment_list_any_index()
var l: list<number> = [1, 2]
for [x, y, _]
in [[0, 1, ''], [1, 3, '']]
l[x] = l[x] + y
endfor
assert_equal([2, 5], l)
enddef
def Test_assignment_list_vim9script()
var lines =<< trim END
vim9script
@@ -1405,7 +1414,7 @@ def Test_unlet()
CheckDefExecFailure([
'var ll = [1]',
'unlet ll[g:astring]',
], 'E39:', 2)
], 'E1012:', 2)
CheckDefExecFailure([
'var dd = test_null_dict()',
'unlet dd["a"]',
@@ -1480,6 +1489,30 @@ def Test_unlet()
assert_equal('', $ENVVAR)
enddef
def Test_expr_error_no_assign()
var lines =<< trim END
vim9script
var x = invalid
echo x
END
CheckScriptFailureList(lines, ['E121:', 'E121:'])
lines =<< trim END
vim9script
var x = 1 / 0
echo x
END
CheckScriptFailureList(lines, ['E1154:', 'E121:'])
lines =<< trim END
vim9script
var x = 1 % 0
echo x
END
CheckScriptFailureList(lines, ['E1154:', 'E121:'])
enddef
def Test_assign_command_modifier()
var lines =<< trim END
var verbose = 0

View File

@@ -115,6 +115,21 @@ def Test_add_blob()
CheckDefExecFailure(lines, 'E1131:', 2)
enddef
def Test_append()
new
setline(1, range(3))
var res1: number = append(1, 'one')
assert_equal(0, res1)
var res2: bool = append(3, 'two')
assert_equal(false, res2)
assert_equal(['0', 'one', '1', 'two', '2'], getline(1, 6))
enddef
def Test_buflisted()
var res: bool = buflisted('asdf')
assert_equal(false, res)
enddef
def Test_bufname()
split SomeFile
bufname('%')->assert_equal('SomeFile')
@@ -199,6 +214,11 @@ def Test_cursor()
CheckDefExecAndScriptFailure(lines, 'E475:')
enddef
def Test_delete()
var res: bool = delete('doesnotexist')
assert_equal(true, res)
enddef
def Test_executable()
assert_false(executable(""))
assert_false(executable(test_null_string()))

View File

@@ -750,6 +750,10 @@ def Test_put_command()
:+2put! a
assert_equal('aaa', getline(4))
[]->mapnew(() => 0)
:$put ='end'
assert_equal('end', getline('$'))
bwipe!
CheckDefFailure(['put =xxx'], 'E1001:')

View File

@@ -762,7 +762,7 @@ def Test_disassemble_const_expr()
'if has("gui_running")\_s*' ..
'\d PUSHS "gui_running"\_s*' ..
'\d BCALL has(argc 1)\_s*' ..
'\d COND2BOOL\_s*' ..
'\d 2BOOL (!!val)\_s*' ..
'\d JUMP_IF_FALSE -> \d\_s*' ..
' echo "yes"\_s*' ..
'\d PUSHS "yes"\_s*' ..

View File

@@ -1403,6 +1403,9 @@ def Test_expr6()
CheckDefFailure(["var x = 6 * xxx"], 'E1001:', 1)
CheckDefFailure(["var d = 6 * "], 'E1097:', 3)
CheckDefExecAndScriptFailure(['echo 1 / 0'], 'E1154', 1)
CheckDefExecAndScriptFailure(['echo 1 % 0'], 'E1154', 1)
enddef
def Test_expr6_vim9script()

View File

@@ -558,6 +558,43 @@ def Test_try_catch_throw()
assert_equal(411, n)
enddef
def Test_cnext_works_in_catch()
var lines =<< trim END
vim9script
au BufEnter * eval 0
writefile(['text'], 'Xfile1')
writefile(['text'], 'Xfile2')
var items = [
{lnum: 1, filename: 'Xfile1', valid: true},
{lnum: 1, filename: 'Xfile2', valid: true}
]
setqflist([], ' ', {items: items})
cwindow
def CnextOrCfirst()
# if cnext fails, cfirst is used
try
cnext
catch
cfirst
endtry
enddef
CnextOrCfirst()
CnextOrCfirst()
writefile([getqflist({idx: 0}).idx], 'Xresult')
qall
END
writefile(lines, 'XCatchCnext')
RunVim([], [], '--clean -S XCatchCnext')
assert_equal(['1'], readfile('Xresult'))
delete('Xfile1')
delete('Xfile2')
delete('XCatchCnext')
delete('Xresult')
enddef
def Test_throw_skipped()
if 0
throw dontgethere
@@ -2023,6 +2060,12 @@ def Test_for_loop()
total += nr
endfor
assert_equal(6, total)
var res = ""
for [n: number, s: string] in [[1, 'a'], [2, 'b']]
res ..= n .. s
endfor
assert_equal('1a2b', res)
enddef
def Test_for_loop_fails()

View File

@@ -69,6 +69,19 @@ def CheckScriptFailure(lines: list<string>, error: string, lnum = -3)
endtry
enddef
def CheckScriptFailureList(lines: list<string>, errors: list<string>, lnum = -3)
var cwd = getcwd()
var fname = 'XScriptFailure' .. s:sequence
s:sequence += 1
writefile(lines, fname)
try
assert_fails('so ' .. fname, errors, lines, lnum)
finally
chdir(cwd)
delete(fname)
endtry
enddef
def CheckScriptSuccess(lines: list<string>)
var cwd = getcwd()
var fname = 'XScriptSuccess' .. s:sequence

View File

@@ -478,6 +478,7 @@ check_due_timer(void)
int save_must_redraw = must_redraw;
int save_trylevel = trylevel;
int save_did_throw = did_throw;
int save_need_rethrow = need_rethrow;
int save_ex_pressedreturn = get_pressedreturn();
int save_may_garbage_collect = may_garbage_collect;
except_T *save_current_exception = current_exception;
@@ -493,6 +494,7 @@ check_due_timer(void)
must_redraw = 0;
trylevel = 0;
did_throw = FALSE;
need_rethrow = FALSE;
current_exception = NULL;
may_garbage_collect = FALSE;
save_vimvars(&vvsave);
@@ -513,6 +515,7 @@ check_due_timer(void)
called_emsg = save_called_emsg;
trylevel = save_trylevel;
did_throw = save_did_throw;
need_rethrow = save_need_rethrow;
current_exception = save_current_exception;
restore_vimvars(&vvsave);
if (must_redraw != 0)

View File

@@ -750,6 +750,42 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
2383,
/**/
2382,
/**/
2381,
/**/
2380,
/**/
2379,
/**/
2378,
/**/
2377,
/**/
2376,
/**/
2375,
/**/
2374,
/**/
2373,
/**/
2372,
/**/
2371,
/**/
2370,
/**/
2369,
/**/
2368,
/**/
2367,
/**/
2366,
/**/
2365,
/**/

View File

@@ -4291,20 +4291,25 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
&& ppconst->pp_tv[ppconst_used].v_type == VAR_NUMBER
&& ppconst->pp_tv[ppconst_used + 1].v_type == VAR_NUMBER)
{
typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
varnumber_T res = 0;
typval_T *tv1 = &ppconst->pp_tv[ppconst_used];
typval_T *tv2 = &ppconst->pp_tv[ppconst_used + 1];
varnumber_T res = 0;
int failed = FALSE;
// both are numbers: compute the result
switch (*op)
{
case '*': res = tv1->vval.v_number * tv2->vval.v_number;
break;
case '/': res = tv1->vval.v_number / tv2->vval.v_number;
case '/': res = num_divide(tv1->vval.v_number,
tv2->vval.v_number, &failed);
break;
case '%': res = tv1->vval.v_number % tv2->vval.v_number;
case '%': res = num_modulus(tv1->vval.v_number,
tv2->vval.v_number, &failed);
break;
}
if (failed)
return FAIL;
tv1->vval.v_number = res;
--ppconst->pp_used;
}
@@ -5802,12 +5807,9 @@ compile_assign_unlet(
if (dest_type == VAR_DICT && may_generate_2STRING(-1, cctx) == FAIL)
return FAIL;
if (dest_type == VAR_LIST
&& ((type_T **)stack->ga_data)[stack->ga_len - 1]->tt_type
!= VAR_NUMBER)
{
emsg(_(e_number_exp));
&& need_type(((type_T **)stack->ga_data)[stack->ga_len - 1],
&t_number, -1, 0, cctx, FALSE, FALSE) == FAIL)
return FAIL;
}
}
// Load the dict or list. On the stack we then have:
@@ -6884,6 +6886,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
int idx;
p = skip_var_list(arg_start, TRUE, &var_count, &semicolon, FALSE);
if (p == NULL)
return NULL;
if (var_count == 0)
var_count = 1;
@@ -7018,6 +7022,8 @@ compile_for(char_u *arg_start, cctx_T *cctx)
generate_STORE(cctx, ISN_STORE, var_lvar->lv_idx, NULL);
}
if (*p == ':')
p = skip_type(skipwhite(p + 1), FALSE);
if (*p == ',' || *p == ';')
++p;
arg = skipwhite(p);

View File

@@ -1935,8 +1935,8 @@ call_def_function(
if (status == OK && dest_type == VAR_LIST)
{
varnumber_T lidx = tv_idx->vval.v_number;
list_T *list = tv_dest->vval.v_list;
long lidx = (long)tv_idx->vval.v_number;
list_T *list = tv_dest->vval.v_list;
if (list == NULL)
{
@@ -2121,7 +2121,7 @@ call_def_function(
else
{
list_T *l = tv_dest->vval.v_list;
varnumber_T n = tv_idx->vval.v_number;
long n = (long)tv_idx->vval.v_number;
listitem_T *li = NULL;
li = list_find(l, n);
@@ -2572,6 +2572,7 @@ call_def_function(
trycmd->tcd_caught = TRUE;
}
did_emsg = got_int = did_throw = FALSE;
force_abort = need_rethrow = FALSE;
catch_exception(current_exception);
}
break;
@@ -2950,13 +2951,21 @@ call_def_function(
else
#endif
{
int failed = FALSE;
switch (iptr->isn_arg.op.op_type)
{
case EXPR_MULT: n1 = n1 * n2; break;
case EXPR_DIV: n1 = num_divide(n1, n2); break;
case EXPR_DIV: n1 = num_divide(n1, n2, &failed);
if (failed)
goto on_error;
break;
case EXPR_SUB: n1 = n1 - n2; break;
case EXPR_ADD: n1 = n1 + n2; break;
default: n1 = num_modulus(n1, n2); break;
default: n1 = num_modulus(n1, n2, &failed);
if (failed)
goto on_error;
break;
}
clear_tv(tv1);
clear_tv(tv2);
@@ -3325,10 +3334,6 @@ call_def_function(
exarg_T ea;
char *errormsg;
if (GA_GROW(&ectx.ec_stack, 1) == FAIL)
goto failed;
++ectx.ec_stack.ga_len;
tv = STACK_TV_BOT(-1);
ea.line2 = 0;
ea.addr_count = 0;
ea.addr_type = ADDR_LINES;
@@ -3336,6 +3341,13 @@ call_def_function(
ea.skip = FALSE;
if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
goto on_error;
if (GA_GROW(&ectx.ec_stack, 1) == FAIL)
goto failed;
++ectx.ec_stack.ga_len;
tv = STACK_TV_BOT(-1);
tv->v_type = VAR_NUMBER;
tv->v_lock = 0;
if (ea.addr_count == 0)
tv->vval.v_number = curwin->w_cursor.lnum;
else
@@ -3350,18 +3362,6 @@ call_def_function(
char_u *expr = NULL;
int dir = FORWARD;
if (regname == '=')
{
tv = STACK_TV_BOT(-1);
if (tv->v_type == VAR_STRING)
expr = tv->vval.v_string;
else
{
expr = typval2string(tv, TRUE); // allocates value
clear_tv(tv);
}
--ectx.ec_stack.ga_len;
}
if (lnum < -2)
{
// line number was put on the stack by ISN_RANGE
@@ -3376,6 +3376,19 @@ call_def_function(
dir = BACKWARD;
else if (lnum >= 0)
curwin->w_cursor.lnum = iptr->isn_arg.put.put_lnum;
if (regname == '=')
{
tv = STACK_TV_BOT(-1);
if (tv->v_type == VAR_STRING)
expr = tv->vval.v_string;
else
{
expr = typval2string(tv, TRUE); // allocates value
clear_tv(tv);
}
--ectx.ec_stack.ga_len;
}
check_cursor();
do_put(regname, expr, dir, 1L, PUT_LINE|PUT_CURSLINE);
vim_free(expr);