mirror of
https://github.com/zoriya/vim.git
synced 2025-12-06 07:16:15 +00:00
Compare commits
19 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ccb47a2899 | ||
|
|
b1f2857096 | ||
|
|
c5f59fab23 | ||
|
|
a0f7f73ebb | ||
|
|
77a849c4b3 | ||
|
|
99880f96cf | ||
|
|
a28639e711 | ||
|
|
e64f83cc6a | ||
|
|
09fbedc8dc | ||
|
|
98a29d00a4 | ||
|
|
82aa6e09e0 | ||
|
|
f30a14db3b | ||
|
|
585587dadb | ||
|
|
036d07144e | ||
|
|
1430ceeb2d | ||
|
|
3af15ab788 | ||
|
|
85773bf32b | ||
|
|
239f8d9326 | ||
|
|
e2edc2ed4a |
@@ -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()
|
||||
|
||||
@@ -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|
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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*
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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] == ';')
|
||||
|
||||
@@ -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"));
|
||||
|
||||
38
src/eval.c
38
src/eval.c
@@ -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;
|
||||
|
||||
155
src/evalfunc.c
155
src/evalfunc.c
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
/*
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 \
|
||||
|
||||
@@ -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#'))
|
||||
|
||||
@@ -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)
|
||||
|
||||
26
src/testdir/test_sleep.vim
Normal file
26
src/testdir/test_sleep.vim
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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()))
|
||||
|
||||
@@ -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:')
|
||||
|
||||
@@ -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*' ..
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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,
|
||||
/**/
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user