Compare commits

...

23 Commits

Author SHA1 Message Date
2027973b5b patch 8.2.0479: unloading shared libraries on exit has no purpose
Problem:    Unloading shared libraries on exit has no purpose.
Solution:   Do not unload shared libraries on exit.
2020-03-29 20:51:07 +02:00
5908fdf72f patch 8.2.0478: new buffers are not added to the Buffers menu
Problem:    New buffers are not added to the Buffers menu.
Solution:   Turn number into string. (Yee Cheng Chin, closes #5864)
2020-03-29 20:08:45 +02:00
c58164c5cf patch 8.2.0477: Vim9: error messages not tested
Problem:    Vim9: error messages not tested.
Solution:   Add more tests.
2020-03-29 18:40:30 +02:00
52ea92b19d patch 8.2.0476: terminal nasty callback test fails sometimes
Problem:    Terminal nasty callback test fails sometimes.
Solution:   use term_wait() instead of a sleep. (Yee Cheng Chin,closes #5865)
2020-03-29 17:50:48 +02:00
bf54dbeb5c patch 8.2.0475: channel out_cb test still fails sometimes on Mac
Problem:    Channel out_cb test still fails sometimes on Mac.
Solution:   Use an ever longer timeout.
2020-03-29 16:18:58 +02:00
0fff44152d patch 8.2.0474: cannot use :write when using a plugin with BufWriteCmd
Problem:    Cannot use :write when using a plugin with BufWriteCmd.
Solution:   Reset BF_NOTEDITED after BufWriteCmd. (closes #5807)
2020-03-29 16:06:29 +02:00
8601545338 patch 8.2.0473: variables declared in an outer scope
Problem:    Variables declared in an outer scope.
Solution:   Decleare variables only in the scope where they are used.
2020-03-29 15:12:15 +02:00
360bdbda81 patch 8.2.0472: terminal highlight name is set twice, leaking memory
Problem:    Terminal highlight name is set twice, leaking memory.
Solution:   Delete one.
2020-03-28 22:37:14 +01:00
a30590d3e7 patch 8.2.0471: missing change to compile_list()
Problem:    Missing change to compile_list().
Solution:   Add error message.
2020-03-28 22:06:23 +01:00
7b1b36b1cb patch 8.2.0470: Test_confirm_cmd_cancel() can fail on a slow system
Problem:    Test_confirm_cmd_cancel() can fail on a slow system.
Solution:   Use WaitForAssert(). (Ozaki Kiichi, closes #5861)
2020-03-28 21:48:55 +01:00
ee619e5bc0 patch 8.2.0469: Vim9: no error for missing ] after list
Problem:    Vim9: no error for missing ] after list.
Solution:   Add error message. Add more tests.
2020-03-28 21:38:06 +01:00
7c003aa314 patch 8.2.0468: GUI: pixel dust with some fonts and characters
Problem:    GUI: pixel dust with some fonts and characters.
Solution:   Always redraw the character before the cursor. (Nir Lichtman,
            closes #5549, closes #5856)
2020-03-28 20:44:41 +01:00
33fa29cf74 patch 8.2.0467: Vim9: some errors are not tested
Problem:    Vim9: some errors are not tested
Solution:   Add more tests.  Fix that Vim9 script flag is not reset.
2020-03-28 19:41:33 +01:00
09c569038c patch 8.2.0466: not parsing messages recursively breaks the govim plugin
Problem:    Not parsing messages recursively breaks the govim plugin.
Solution:   When called recursively do handle messages but do not close
            channels.
2020-03-28 18:06:31 +01:00
599c89c82f patch 8.2.0465: Vim9: dead code and wrong return type
Problem:    Vim9: dead code and wrong return type.
Solution:   Remove dead code.  Fix return type.  Add more tests.
2020-03-28 14:53:20 +01:00
495282b6e7 Correct list of patch numbers 2020-03-27 20:59:54 +01:00
14285cb801 patch 8.2.0464: typos and other small problems
Problem:    Typos and other small problems.
Solution:   Fix the typos.  Add missing files to the distribution.
2020-03-27 20:58:37 +01:00
2d9d409ad4 patch 8.2.0464: typos and other small problems
Problem:    Typos and other small problems.
Solution:   Fix the typos.  Add missing file to distribution.
2020-03-27 20:52:45 +01:00
191acfdeca Update runtime files 2020-03-27 20:42:43 +01:00
37bb030cd9 patch 8.2.0462: previewwindow test fails on some systems
Problem:    Previewwindow test fails on some systems. (James McCoy)
Solution:   Wait a bit after sending the "o". (closes #5849)
2020-03-27 20:24:14 +01:00
9207d1f523 patch 8.2.0461: confirm test fails on amd64 system
Problem:    Confirm test fails on amd64 system. (Alimar Riesebieter)
Solution:   Add an extra WaitForAssert(). (Dominique Pelle)
2020-03-27 19:41:02 +01:00
bd5e622bfa patch 8.2.0460: build failure because of wrong feature name
Problem:    Build failure because of wrong feature name.
Solution:   Correct feature name.
2020-03-26 23:13:34 +01:00
15c476023f patch 8.2.0459: cannot check if a function name is correct
Problem:    Cannot check if a function name is correct.
Solution:   Add "?funcname" to exists().
2020-03-26 22:16:48 +01:00
53 changed files with 1283 additions and 730 deletions

View File

@ -12,6 +12,7 @@ SRC_ALL = \
appveyor.yml \
ci/appveyor.bat \
ci/if_ver*.vim \
ci/load-snd-dummy.sh \
src/Make_all.mak \
src/README.md \
src/alloc.h \
@ -151,17 +152,18 @@ SRC_ALL = \
src/testdir/*.py \
src/testdir/lsan-suppress.txt \
src/testdir/sautest/autoload/*.vim \
src/testdir/runtest.vim \
src/testdir/summarize.vim \
src/testdir/check.vim \
src/testdir/shared.vim \
src/testdir/screendump.vim \
src/testdir/view_util.vim \
src/testdir/term_util.vim \
src/testdir/setup.vim \
src/testdir/gui_init.vim \
src/testdir/setup_gui.vim \
src/testdir/gui_preinit.vim \
src/testdir/mouse.vim \
src/testdir/runtest.vim \
src/testdir/screendump.vim \
src/testdir/setup.vim \
src/testdir/setup_gui.vim \
src/testdir/shared.vim \
src/testdir/summarize.vim \
src/testdir/term_util.vim \
src/testdir/view_util.vim \
src/testdir/test[0-9]*.ok \
src/testdir/test[0-9]*a.ok \
src/testdir/test_[a-z]*.ok \

View File

@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.2. Last change: 2020 Mar 22
*eval.txt* For Vim version 8.2. Last change: 2020 Mar 26
VIM REFERENCE MANUAL by Bram Moolenaar
@ -4102,8 +4102,12 @@ exists({expr}) The result is a Number, which is |TRUE| if {expr} is defined,
string)
*funcname built-in function (see |functions|)
or user defined function (see
|user-functions|). Also works for a
variable that is a Funcref.
|user-functions|) that is implemented.
Also works for a variable that is a
Funcref.
?funcname built-in function that could be
implemented; to be used to check if
"funcname" is valid
varname internal variable (see
|internal-variables|). Also works
for |curly-braces-names|, |Dictionary|
@ -5837,8 +5841,10 @@ has({feature} [, {check}])
When {check} is present and not zero: The result is a Number,
which is 1 if the feature {feature} could ever be supported,
zero otherwise. This is useful to check for a typo in
{feature}. Keep in mind that an older Vim version will not
know about a feature added later.
{feature} and to detect dead code. Keep in mind that an older
Vim version will not know about a feature added later and
features that have been abandoned will not be know by the
current Vim version.
Also see |exists()|.

View File

@ -1,4 +1,4 @@
*gui_w32.txt* For Vim version 8.2. Last change: 2019 May 05
*gui_w32.txt* For Vim version 8.2. Last change: 2020 Mar 25
VIM REFERENCE MANUAL by Bram Moolenaar
@ -456,8 +456,12 @@ See the Make_mvc.mak file for instructions, search for XPM.
To try out if XPM support works do this: >
:help
:exe 'sign define vimxpm icon=' . $VIMRUNTIME . '\\vim16x16.xpm'
:exe 'sign place 1 line=1 name=vimxpm file=' . expand('%:p')
:let runtime = escape($VIMRUNTIME, ' \')
:exe 'sign define vimxpm icon=' .. runtime .. '\\vim16x16.xpm'
:exe 'sign place 1 line=1 name=vimxpm file=' .. expand('%:p')
<
You may need to get the vim16x16.xpm file from github:
https://github.com/vim/vim/blob/master/runtime/vim16x16.xpm
vim:tw=78:sw=4:ts=8:noet:ft=help:norl:

View File

@ -1,4 +1,4 @@
*index.txt* For Vim version 8.2. Last change: 2020 Jan 14
*index.txt* For Vim version 8.2. Last change: 2020 Mar 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -1260,11 +1260,12 @@ tag command action ~
|:cunmenu| :cunme[nu] remove menu for Command-line mode
|:cwindow| :cw[indow] open or close quickfix window
|:delete| :d[elete] delete lines
|:delmarks| :delm[arks] delete marks
|:debug| :deb[ug] run a command in debugging mode
|:debuggreedy| :debugg[reedy] read debug mode commands from normal input
|:def| :def define a Vim9 user function
|:delcommand| :delc[ommand] delete user-defined command
|:delfunction| :delf[unction] delete a user function
|:delmarks| :delm[arks] delete marks
|:diffupdate| :dif[fupdate] update 'diff' buffers
|:diffget| :diffg[et] remove differences in current buffer
|:diffoff| :diffo[ff] switch off diff mode
@ -1274,9 +1275,9 @@ tag command action ~
|:diffthis| :diffthis make current window a diff window
|:digraphs| :dig[raphs] show or enter digraphs
|:display| :di[splay] display registers
|:disassemble| :disa[ssemble] disassemble Vim9 user function
|:djump| :dj[ump] jump to #define
|:dl| :dl short for |:delete| with the 'l' flag
|:del| :del[ete]l short for |:delete| with the 'l' flag
|:dlist| :dli[st] list #defines
|:doautocmd| :do[autocmd] apply autocommands to current buffer
|:doautoall| :doautoa[ll] apply autocommands for all loaded buffers
@ -1295,15 +1296,17 @@ tag command action ~
|:else| :el[se] part of an :if command
|:elseif| :elsei[f] part of an :if command
|:emenu| :em[enu] execute a menu by name
|:enddef| :enddef end of a user function started with :def
|:endif| :en[dif] end previous :if
|:endfor| :endfo[r] end previous :for
|:endfunction| :endf[unction] end of a user function
|:endfunction| :endf[unction] end of a user function started with :function
|:endtry| :endt[ry] end previous :try
|:endwhile| :endw[hile] end previous :while
|:enew| :ene[w] edit a new, unnamed buffer
|:ex| :ex same as ":edit"
|:execute| :exe[cute] execute result of expressions
|:exit| :exi[t] same as ":xit"
|:export| :exp[ort] Vim9: export an item from a script
|:exusage| :exu[sage] overview of Ex commands
|:file| :f[ile] show or set the current file name
|:files| :files list all files in the buffer list
@ -1345,6 +1348,7 @@ tag command action ~
|:imap| :im[ap] like ":map" but for Insert mode
|:imapclear| :imapc[lear] like ":mapclear" but for Insert mode
|:imenu| :ime[nu] add menu for Insert mode
|:import| :imp[ort] Vim9: import an item from another script
|:inoremap| :ino[remap] like ":noremap" but for Insert mode
|:inoreabbrev| :inorea[bbrev] like ":noreabbrev" but for Insert mode
|:inoremenu| :inoreme[nu] like ":noremenu" but for Insert mode
@ -1686,6 +1690,7 @@ tag command action ~
|:version| :ve[rsion] print version number and other info
|:verbose| :verb[ose] execute command with 'verbose' set
|:vertical| :vert[ical] make following command split vertically
|:vim9script| :vim9[script] indicates Vim9 script file
|:vimgrep| :vim[grep] search for pattern in files
|:vimgrepadd| :vimgrepa[dd] like :vimgrep, but append to current list
|:visual| :vi[sual] same as ":edit", but turns off "Ex" mode

View File

@ -1,4 +1,4 @@
*insert.txt* For Vim version 8.2. Last change: 2020 Jan 26
*insert.txt* For Vim version 8.2. Last change: 2020 Mar 25
VIM REFERENCE MANUAL by Bram Moolenaar
@ -379,8 +379,8 @@ CTRL-\ CTRL-O like CTRL-O but don't move the cursor *i_CTRL-\_CTRL-O*
CTRL-L when 'insertmode' is set: go to Normal mode *i_CTRL-L*
CTRL-G u break undo sequence, start new change *i_CTRL-G_u*
CTRL-G U don't break undo with next left/right cursor *i_CTRL-G_U*
movement, if the cursor stays within
same the line
movement, if the cursor stays within the
same line
-----------------------------------------------------------------------
Note: If the cursor keys take you out of Insert mode, check the 'noesckeys'

View File

@ -26,7 +26,7 @@ targets personal computing.
10. Mouse key mappings |haiku-mouse|
11. Color names |haiku-colors|
12. Credits |haiku-support-credits|
13. Bugs & things To Do |haiku-bugs|
13. Bugs & to-do |haiku-bugs|
1. General *haiku-general*
@ -83,8 +83,7 @@ Stuff that does not work yet:
still playing with the scrollbar it won't change it itself. I provided a
workaround which kicks in when the window is activated or deactivated (so it
works best with focus- follows-mouse turned on).
- The cursor does not flash (very low priority; I'm not sure I even like it
when it flashes)
- The cursor does not flash.
4. The $VIM directory *haiku-vimdir*
@ -222,12 +221,14 @@ All the changes and patches released under vim-license.
Thank you, all!
13. Bugs & things To Do *haiku-bugs*
The port is under development now and far away from the perfect state. Bug
reports, patches and wishes are welcome.
-Siarzhuk Zharski <imker@gmx.li>
13. Bugs & to-do *haiku-bugs*
The port is under development now and far away from the perfect state. For bug
reports, patches and wishes, please use the Vim mailing list or Vim Github
repository.
Mailing list: https://www.vim.org/maillist.php
Vim Github repository: https://github.com/vim/vim
vim:tw=78:ts=8:ft=help:norl:

View File

@ -1,4 +1,4 @@
*popup.txt* For Vim version 8.2. Last change: 2020 Mar 14
*popup.txt* For Vim version 8.2. Last change: 2020 Mar 21
VIM REFERENCE MANUAL by Bram Moolenaar
@ -151,15 +151,19 @@ different: *E863*
- The popup window can be closed with `popup_close()`, the terminal buffer
then becomes hidden.
- The default Pmenu color is only used for the border and padding. To change
the color of the terminal itself set 'wincolor'.
the color of the terminal itself set the Terminal highlight group before
creating the terminal. Setting 'wincolor' later can work but requires the
program in the terminal to redraw everything.
- The default minimal size is 5 lines of 20 characters; Use the "minwidth" and
"minheight" parameters to set a different value.
- The terminal size will grow if the program running in the terminal writes
text. Set "maxheight" and "maxwidth" to restrict the size.
To run a terminal in a popup window, first create the terminal hidden. Then
pass the buffer number to popup_create(). Example: >
hi link Terminal Search
let buf = term_start(['picker', 'Something'], #{hidden: 1, term_finish: 'close'})
let winid = popup_create(buf, #{minwidth: 50, minheight: 20})
set wincolor=Search
==============================================================================
2. Functions *popup-functions*

View File

@ -1,4 +1,4 @@
*recover.txt* For Vim version 8.2. Last change: 2019 May 07
*recover.txt* For Vim version 8.2. Last change: 2020 Mar 24
VIM REFERENCE MANUAL by Bram Moolenaar
@ -125,7 +125,7 @@ If you want to make sure that your changes are in the swap file use this
command:
*:pre* *:preserve* *E313* *E314*
:pre[serve] Write all text for all buffers into swap file. The
:pre[serve] Write all text for all buffers into swap files. The
original file is no longer needed for recovery.
This sets a flag in the current buffer. When the '&'
flag is present in 'cpoptions' the swap file will not

View File

@ -1,4 +1,4 @@
*todo.txt* For Vim version 8.2. Last change: 2020 Mar 19
*todo.txt* For Vim version 8.2. Last change: 2020 Mar 27
VIM REFERENCE MANUAL by Bram Moolenaar
@ -38,19 +38,10 @@ browser use: https://github.com/vim/vim/issues/1234
*known-bugs*
-------------------- Known bugs and current work -----------------------
Add second argument to has(), return True when the feature can exist at all.
Patch to fix buffer menu. (Yee Cheng Chin, #5787)
Add $TEST_MAY_FAIL, comma separated list of test functions that won't be fatal
when failed.
- When matcning in AfterTheTest() then do not add to s:errors but to
s:warnings. in testdir/runtest.vim
Vim9 script:
- Add vim9 commands to index, so that vim.vim will get them automatically.
See email from Charles March 11 2020.
- "func" inside "vim9script" doesn't work? (Ben Jackson, #5670)
- "let x = x + 1" should say that "x" is not defined (declare local after
evaluating expresion).
- "echo Func()" is an error if Func() does not return anything.
- better implementation for partial and tests for that.
- Make "g:imported = Export.exported" work in Vim9 script.
@ -206,6 +197,9 @@ Patch to add "-d" to xxd. (#5616)
Patch to add Turkish manual. (Emir Sarı, #5641)
Patch to support cindent option to handle pragmas differently.
(Max Rumpf, #5468)
File marks merging has duplicates since 7.4.1925. (Ingo Karkat, #5733)
Running test_gui and test_gui_init with Motif sometimes kills the window
@ -227,6 +221,8 @@ Ready to include? Review the code.
When 'lazyredraw' is set sometimes the title is not updated.
(Jason Franklin, 2020 Feb 3) Looks like a race condition.
Patch to delete BeOS code. (#5817)
Strange sequence of BufWipeout and BufNew events while doing omni-complete.
(Paul Jolly, #5656)
Get BufDelete without preceding BufNew. (Paul Jolly, #5694)
@ -260,9 +256,6 @@ Also #5326: netrw buffers are not restored.
When 'backupdir' has a path ending in double slash (meaning: use full path of
the file) combined with 'patchmode' the file name is wrong. (#5791)
Patch to support cindent option to handle pragmas differently.
(Max Rumpf, #5468)
Patch to make ":verbose pwd" show the scope of the directory. (Takuya
Fujiwara, #5469)
@ -646,24 +639,7 @@ Make ":interactive !cmd" stop termcap mode, also when used in an autocommand.
Add buffer argument to undotree(). (#4001)
Using uninitialized value in test_gn
Using uninitialized value in test_crypt (can't explain why).
memory leak in test_cmdline
==6522== by 0x291AFF: ga_grow (misc2.c:2069)
==6522== by 0x3D5B4B: win_size_save (window.c:5243)
==6522== by 0x222922: open_cmdwin (ex_getln.c:4177)
==6522== by 0x21D472: getcmdline_int (ex_getln.c:1376)
memory leak in test_paste
Memory leak in test_terminal:
==23530== by 0x2640D7: alloc (misc2.c:874)
==23530== by 0x2646D6: vim_strsave (misc2.c:1315)
==23530== by 0x25841D: FullName_save (misc1.c:5443)
==23530== by 0x17CB4F: fix_fname (buffer.c:4794)
==23530== by 0x17CB9A: fname_expand (buffer.c:4838)
==23530== by 0x1759AB: buflist_new (buffer.c:1889)
==23530== by 0x35C923: term_start (terminal.c:421)
==23530== by 0x2AFF30: mch_call_shell_terminal (os_unix.c:4377)
==23530== by 0x2B16BE: mch_call_shell (os_unix.c:5383)
Memory leak in test_terminal_fail
TODO: be able to run all parts of test_alot with valgrind separately
Memory leak in test_alot with pyeval() (allocating partial)

View File

@ -1,4 +1,4 @@
*usr_07.txt* For Vim version 8.2. Last change: 2017 Sep 18
*usr_07.txt* For Vim version 8.2. Last change: 2020 Mar 23
VIM USER MANUAL - by Bram Moolenaar
@ -227,8 +227,8 @@ the file.
FILE MARKS
In chapter 4 was explained how you can place a mark in a file with "mx" and
jump to that position with "`x". That works within one file. If you edit
In section |03.10| was explained how you can place a mark in a file with "mx"
and jump to that position with "`x". That works within one file. If you edit
another file and place marks there, these are specific for that file. Thus
each file has its own set of marks, they are local to the file.
So far we were using marks with a lowercase letter. There are also marks

View File

@ -1,7 +1,7 @@
" Vim filetype plugin file
" Language: man
" Maintainer: SungHyun Nam <goweol@gmail.com>
" Last Change: 2019 Sep 26
" Last Change: 2020 Mar 25
" (fix by Jason Franklin)
" To make the ":Man" command available before editing a manual page, source
@ -96,7 +96,7 @@ func <SID>PreGetPage(cnt)
let sect = a:cnt
let page = expand("<cword>")
endif
call s:GetPage(sect, page)
call s:GetPage('', sect, page)
endfunc
func <SID>GetCmdArg(sect, page)

View File

@ -2,7 +2,7 @@
" You can also use this as a start for your own set of menus.
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2020 Mar 19
" Last Change: 2020 Mar 29
" Note that ":an" (short for ":anoremenu") is often used to make a menu work
" in all modes and avoid side effects from mappings defined by the user.
@ -672,7 +672,7 @@ func s:BMAdd()
call s:BMShow()
else
let name = expand("<afile>")
let num = expand("<abuf>")
let num = expand("<abuf>") + 0 " add zero to convert to a number type
if s:BMCanAdd(name, num)
call <SID>BMFilename(name, num)
let s:bmenu_count += 1

View File

@ -1,7 +1,7 @@
" Vim syntax file
" Language: awk, nawk, gawk, mawk
" Maintainer: Antonio Colombo <azc100@gmail.com>
" Last Change: 2016 Sep 05
" Last Change: 2020 Mar 25
" AWK ref. is: Alfred V. Aho, Brian W. Kernighan, Peter J. Weinberger
" The AWK Programming Language, Addison-Wesley, 1988
@ -9,7 +9,7 @@
" GAWK ref. is: Arnold D. Robbins
" Effective AWK Programming, Third Edition, O'Reilly, 2001
" Effective AWK Programming, Fourth Edition, O'Reilly, 2015
" (also available and updated with the gawk source distribution)
" (up-to-date version available with the gawk source distribution)
" MAWK is a "new awk" meaning it implements AWK ref.
" mawk conforms to the Posix 1003.2 (draft 11.3)
@ -33,14 +33,19 @@ syn keyword awkStatement break continue delete exit
syn keyword awkStatement function getline next
syn keyword awkStatement print printf return
" GAWK ref. Chapter 7-9
syn keyword awkStatement switch nextfile
syn keyword awkStatement case default switch nextfile
syn keyword awkStatement func
" GAWK ref. Chapter 2.7, Including Other Files into Your Program
" GAWK ref. Chapter 2.8, Loading Dynamic Extensions into Your Program
" GAWK ref. Chapter 15, Namespaces
" Directives
syn keyword awkStatement @include @load @namespace
"
" GAWK ref. Chapter 9, Functions
" Numeric Functions
syn keyword awkFunction atan2 cos exp int intdiv log rand sin sqrt srand
syn keyword awkFunction atan2 cos exp int log rand sin sqrt srand
" String Manipulation Functions
syn keyword awkFunction asort asort1 gensub gsub index length match
syn keyword awkFunction asort asorti gensub gsub index length match
syn keyword awkFunction patsplit split sprintf strtonum sub substr
syn keyword awkFunction tolower toupper
" Input Output Functions
@ -49,7 +54,7 @@ syn keyword awkFunction close fflush system
syn keyword awkFunction mktime strftime systime
" Bit Manipulation Functions
syn keyword awkFunction and compl lshift or rshift xor
" Getting Type Functions
" Getting Type Information Functions
syn keyword awkFunction isarray typeof
" String-Translation Functions
syn keyword awkFunction bindtextdomain dcgettext dcngetext

View File

@ -2014,7 +2014,10 @@ buflist_new(
apply_autocmds(EVENT_BUFWIPEOUT, NULL, NULL, FALSE, curbuf);
#ifdef FEAT_EVAL
if (aborting()) // autocmds may abort script processing
{
vim_free(ffname);
return NULL;
}
#endif
if (buf == curbuf)
{

View File

@ -4428,16 +4428,14 @@ channel_parse_messages(void)
int ret = FALSE;
int r;
ch_part_T part = PART_SOCK;
static int recursive = FALSE;
static int recursive = 0;
#ifdef ELAPSED_FUNC
elapsed_T start_tv;
#endif
// The code below may invoke callbacks, which might call us back.
// That doesn't work well, just return without doing anything.
if (recursive)
return FALSE;
recursive = TRUE;
// In a recursive call channels will not be closed.
++recursive;
++safe_to_invoke_callback;
#ifdef ELAPSED_FUNC
@ -4454,33 +4452,37 @@ channel_parse_messages(void)
}
while (channel != NULL)
{
if (channel_can_close(channel))
if (recursive == 1)
{
channel->ch_to_be_closed = (1U << PART_COUNT);
channel_close_now(channel);
// channel may have been freed, start over
channel = first_channel;
continue;
}
if (channel->ch_to_be_freed || channel->ch_killing)
{
channel_free_contents(channel);
if (channel->ch_job != NULL)
channel->ch_job->jv_channel = NULL;
if (channel_can_close(channel))
{
channel->ch_to_be_closed = (1U << PART_COUNT);
channel_close_now(channel);
// channel may have been freed, start over
channel = first_channel;
continue;
}
if (channel->ch_to_be_freed || channel->ch_killing)
{
channel_free_contents(channel);
if (channel->ch_job != NULL)
channel->ch_job->jv_channel = NULL;
// free the channel and then start over
channel_free_channel(channel);
channel = first_channel;
continue;
}
if (channel->ch_refcount == 0 && !channel_still_useful(channel))
{
// channel is no longer useful, free it
channel_free(channel);
channel = first_channel;
part = PART_SOCK;
continue;
// free the channel and then start over
channel_free_channel(channel);
channel = first_channel;
continue;
}
if (channel->ch_refcount == 0 && !channel_still_useful(channel))
{
// channel is no longer useful, free it
channel_free(channel);
channel = first_channel;
part = PART_SOCK;
continue;
}
}
if (channel->ch_part[part].ch_fd != INVALID_FD
|| channel_has_readahead(channel, part))
{
@ -4521,7 +4523,7 @@ channel_parse_messages(void)
}
--safe_to_invoke_callback;
recursive = FALSE;
--recursive;
return ret;
}

View File

@ -826,7 +826,8 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal)
if (**arg != ':')
{
semsg(_(e_missing_dict_colon), *arg);
if (evaluate)
semsg(_(e_missing_dict_colon), *arg);
clear_tv(&tvkey);
goto failret;
}
@ -853,7 +854,8 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal)
item = dict_find(d, key, -1);
if (item != NULL)
{
semsg(_(e_duplicate_key), key);
if (evaluate)
semsg(_(e_duplicate_key), key);
clear_tv(&tvkey);
clear_tv(&tv);
goto failret;
@ -873,7 +875,8 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal)
break;
if (**arg != ',')
{
semsg(_(e_missing_dict_comma), *arg);
if (evaluate)
semsg(_(e_missing_dict_comma), *arg);
goto failret;
}
*arg = skipwhite(*arg + 1);
@ -881,7 +884,8 @@ eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal)
if (**arg != '}')
{
semsg(_(e_missing_dict_end), *arg);
if (evaluate)
semsg(_(e_missing_dict_end), *arg);
failret:
if (d != NULL)
dict_free(d);

View File

@ -270,7 +270,6 @@ win_line(
int tocol = MAXCOL; // end of inverting
int fromcol_prev = -2; // start of inverting after cursor
int noinvcur = FALSE; // don't invert the cursor
pos_T *top, *bot;
int lnum_in_visual_area = FALSE;
pos_T pos;
long v;
@ -535,6 +534,8 @@ win_line(
// handle Visual active in this window
if (VIsual_active && wp->w_buffer == curwin->w_buffer)
{
pos_T *top, *bot;
if (LTOREQ_POS(curwin->w_cursor, VIsual))
{
// Visual is after curwin->w_cursor

View File

@ -280,13 +280,11 @@ ret_number(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_number;
}
#ifdef FEAT_FLOAT
static type_T *
ret_float(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_float;
}
#endif
static type_T *
ret_string(int argcount UNUSED, type_T **argtypes UNUSED)
{
@ -336,7 +334,6 @@ ret_partial_void(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_partial_void;
}
#ifdef FEAT_JOB_CHANNEL
static type_T *
ret_channel(int argcount UNUSED, type_T **argtypes UNUSED)
{
@ -347,7 +344,6 @@ ret_job(int argcount UNUSED, type_T **argtypes UNUSED)
{
return &t_job;
}
#endif
static type_T *ret_f_function(int argcount, type_T **argtypes);
@ -374,12 +370,51 @@ typedef struct
#define FEARG_4 4 // base is the fourth argument
#define FEARG_LAST 9 // base is the last argument
#ifdef FEAT_FLOAT
# define FLOAT_FUNC(name) name
#else
# define FLOAT_FUNC(name) NULL
#endif
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
# define MATH_FUNC(name) name
#else
# define MATH_FUNC(name) NULL
#endif
#ifdef FEAT_TIMERS
# define TIMER_FUNC(name) name
#else
# define TIMER_FUNC(name) NULL
#endif
#ifdef FEAT_JOB_CHANNEL
# define JOB_FUNC(name) name
#else
# define JOB_FUNC(name) NULL
#endif
#ifdef FEAT_PROP_POPUP
# define PROP_FUNC(name) name
#else
# define PROP_FUNC(name) NULL
#endif
#ifdef FEAT_SIGNS
# define SIGN_FUNC(name) name
#else
# define SIGN_FUNC(name) NULL
#endif
#ifdef FEAT_SOUND
# define SOUND_FUNC(name) name
#else
# define SOUND_FUNC(name) NULL
#endif
#ifdef FEAT_TERMINAL
# define TERM_FUNC(name) name
#else
# define TERM_FUNC(name) NULL
#endif
static funcentry_T global_functions[] =
{
#ifdef FEAT_FLOAT
{"abs", 1, 1, FEARG_1, ret_any, f_abs},
{"acos", 1, 1, FEARG_1, ret_float, f_acos}, // WJMc
#endif
{"abs", 1, 1, FEARG_1, ret_any, FLOAT_FUNC(f_abs)},
{"acos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_acos)},
{"add", 2, 2, FEARG_1, ret_any, f_add},
{"and", 2, 2, FEARG_1, ret_number, f_and},
{"append", 2, 2, FEARG_LAST, ret_number, f_append},
@ -388,9 +423,7 @@ static funcentry_T global_functions[] =
{"argidx", 0, 0, 0, ret_number, f_argidx},
{"arglistid", 0, 2, 0, ret_number, f_arglistid},
{"argv", 0, 2, 0, ret_any, f_argv},
#ifdef FEAT_FLOAT
{"asin", 1, 1, FEARG_1, ret_float, f_asin}, // WJMc
#endif
{"asin", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_asin)},
{"assert_beeps", 1, 2, FEARG_1, ret_number, f_assert_beeps},
{"assert_equal", 2, 3, FEARG_2, ret_number, f_assert_equal},
{"assert_equalfile", 2, 2, FEARG_1, ret_number, f_assert_equalfile},
@ -403,17 +436,29 @@ static funcentry_T global_functions[] =
{"assert_notmatch", 2, 3, FEARG_2, ret_number, f_assert_notmatch},
{"assert_report", 1, 1, FEARG_1, ret_number, f_assert_report},
{"assert_true", 1, 2, FEARG_1, ret_number, f_assert_true},
#ifdef FEAT_FLOAT
{"atan", 1, 1, FEARG_1, ret_float, f_atan},
{"atan2", 2, 2, FEARG_1, ret_float, f_atan2},
#endif
{"atan", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_atan)},
{"atan2", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_atan2)},
{"balloon_gettext", 0, 0, 0, ret_string,
#ifdef FEAT_BEVAL
{"balloon_gettext", 0, 0, 0, ret_string, f_balloon_gettext},
{"balloon_show", 1, 1, FEARG_1, ret_void, f_balloon_show},
# if defined(FEAT_BEVAL_TERM)
{"balloon_split", 1, 1, FEARG_1, ret_list_string, f_balloon_split},
# endif
f_balloon_gettext
#else
NULL
#endif
},
{"balloon_show", 1, 1, FEARG_1, ret_void,
#ifdef FEAT_BEVAL
f_balloon_show
#else
NULL
#endif
},
{"balloon_split", 1, 1, FEARG_1, ret_list_string,
#if defined(FEAT_BEVAL_TERM)
f_balloon_split
#else
NULL
#endif
},
{"browse", 4, 4, 0, ret_string, f_browse},
{"browsedir", 2, 2, 0, ret_string, f_browsedir},
{"bufadd", 1, 1, FEARG_1, ret_number, f_bufadd},
@ -432,29 +477,25 @@ static funcentry_T global_functions[] =
{"byteidx", 2, 2, FEARG_1, ret_number, f_byteidx},
{"byteidxcomp", 2, 2, FEARG_1, ret_number, f_byteidxcomp},
{"call", 2, 3, FEARG_1, ret_any, f_call},
#ifdef FEAT_FLOAT
{"ceil", 1, 1, FEARG_1, ret_float, f_ceil},
#endif
#ifdef FEAT_JOB_CHANNEL
{"ch_canread", 1, 1, FEARG_1, ret_number, f_ch_canread},
{"ch_close", 1, 1, FEARG_1, ret_void, f_ch_close},
{"ch_close_in", 1, 1, FEARG_1, ret_void, f_ch_close_in},
{"ch_evalexpr", 2, 3, FEARG_1, ret_any, f_ch_evalexpr},
{"ch_evalraw", 2, 3, FEARG_1, ret_any, f_ch_evalraw},
{"ch_getbufnr", 2, 2, FEARG_1, ret_number, f_ch_getbufnr},
{"ch_getjob", 1, 1, FEARG_1, ret_job, f_ch_getjob},
{"ch_info", 1, 1, FEARG_1, ret_dict_any, f_ch_info},
{"ch_log", 1, 2, FEARG_1, ret_void, f_ch_log},
{"ch_logfile", 1, 2, FEARG_1, ret_void, f_ch_logfile},
{"ch_open", 1, 2, FEARG_1, ret_channel, f_ch_open},
{"ch_read", 1, 2, FEARG_1, ret_string, f_ch_read},
{"ch_readblob", 1, 2, FEARG_1, ret_blob, f_ch_readblob},
{"ch_readraw", 1, 2, FEARG_1, ret_string, f_ch_readraw},
{"ch_sendexpr", 2, 3, FEARG_1, ret_void, f_ch_sendexpr},
{"ch_sendraw", 2, 3, FEARG_1, ret_void, f_ch_sendraw},
{"ch_setoptions", 2, 2, FEARG_1, ret_void, f_ch_setoptions},
{"ch_status", 1, 2, FEARG_1, ret_string, f_ch_status},
#endif
{"ceil", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_ceil)},
{"ch_canread", 1, 1, FEARG_1, ret_number, JOB_FUNC(f_ch_canread)},
{"ch_close", 1, 1, FEARG_1, ret_void, JOB_FUNC(f_ch_close)},
{"ch_close_in", 1, 1, FEARG_1, ret_void, JOB_FUNC(f_ch_close_in)},
{"ch_evalexpr", 2, 3, FEARG_1, ret_any, JOB_FUNC(f_ch_evalexpr)},
{"ch_evalraw", 2, 3, FEARG_1, ret_any, JOB_FUNC(f_ch_evalraw)},
{"ch_getbufnr", 2, 2, FEARG_1, ret_number, JOB_FUNC(f_ch_getbufnr)},
{"ch_getjob", 1, 1, FEARG_1, ret_job, JOB_FUNC(f_ch_getjob)},
{"ch_info", 1, 1, FEARG_1, ret_dict_any, JOB_FUNC(f_ch_info)},
{"ch_log", 1, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_log)},
{"ch_logfile", 1, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_logfile)},
{"ch_open", 1, 2, FEARG_1, ret_channel, JOB_FUNC(f_ch_open)},
{"ch_read", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_read)},
{"ch_readblob", 1, 2, FEARG_1, ret_blob, JOB_FUNC(f_ch_readblob)},
{"ch_readraw", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_readraw)},
{"ch_sendexpr", 2, 3, FEARG_1, ret_void, JOB_FUNC(f_ch_sendexpr)},
{"ch_sendraw", 2, 3, FEARG_1, ret_void, JOB_FUNC(f_ch_sendraw)},
{"ch_setoptions", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_ch_setoptions)},
{"ch_status", 1, 2, FEARG_1, ret_string, JOB_FUNC(f_ch_status)},
{"changenr", 0, 0, 0, ret_number, f_changenr},
{"char2nr", 1, 2, FEARG_1, ret_number, f_char2nr},
{"chdir", 1, 1, FEARG_1, ret_string, f_chdir},
@ -467,16 +508,18 @@ static funcentry_T global_functions[] =
{"complete_info", 0, 1, FEARG_1, ret_dict_any, f_complete_info},
{"confirm", 1, 4, FEARG_1, ret_number, f_confirm},
{"copy", 1, 1, FEARG_1, ret_any, f_copy},
#ifdef FEAT_FLOAT
{"cos", 1, 1, FEARG_1, ret_float, f_cos},
{"cosh", 1, 1, FEARG_1, ret_float, f_cosh},
#endif
{"cos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cos)},
{"cosh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cosh)},
{"count", 2, 4, FEARG_1, ret_number, f_count},
{"cscope_connection",0,3, 0, ret_number, f_cscope_connection},
{"cursor", 1, 3, FEARG_1, ret_number, f_cursor},
{"debugbreak", 1, 1, FEARG_1, ret_number,
#ifdef MSWIN
{"debugbreak", 1, 1, FEARG_1, ret_number, f_debugbreak},
f_debugbreak
#else
NULL
#endif
},
{"deepcopy", 1, 2, FEARG_1, ret_any, f_deepcopy},
{"delete", 1, 2, FEARG_1, ret_number, f_delete},
{"deletebufline", 2, 3, FEARG_1, ret_number, f_deletebufline},
@ -493,9 +536,7 @@ static funcentry_T global_functions[] =
{"execute", 1, 2, FEARG_1, ret_string, f_execute},
{"exepath", 1, 1, FEARG_1, ret_string, f_exepath},
{"exists", 1, 1, FEARG_1, ret_number, f_exists},
#ifdef FEAT_FLOAT
{"exp", 1, 1, FEARG_1, ret_float, f_exp},
#endif
{"exp", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_exp)},
{"expand", 1, 3, FEARG_1, ret_any, f_expand},
{"expandcmd", 1, 1, FEARG_1, ret_string, f_expandcmd},
{"extend", 2, 3, FEARG_1, ret_any, f_extend},
@ -506,11 +547,9 @@ static funcentry_T global_functions[] =
{"filter", 2, 2, FEARG_1, ret_any, f_filter},
{"finddir", 1, 3, FEARG_1, ret_string, f_finddir},
{"findfile", 1, 3, FEARG_1, ret_string, f_findfile},
#ifdef FEAT_FLOAT
{"float2nr", 1, 1, FEARG_1, ret_number, f_float2nr},
{"floor", 1, 1, FEARG_1, ret_float, f_floor},
{"fmod", 2, 2, FEARG_1, ret_float, f_fmod},
#endif
{"float2nr", 1, 1, FEARG_1, ret_number, FLOAT_FUNC(f_float2nr)},
{"floor", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_floor)},
{"fmod", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_fmod)},
{"fnameescape", 1, 1, FEARG_1, ret_string, f_fnameescape},
{"fnamemodify", 2, 2, FEARG_1, ret_string, f_fnamemodify},
{"foldclosed", 1, 1, FEARG_1, ret_number, f_foldclosed},
@ -592,22 +631,16 @@ static funcentry_T global_functions[] =
{"interrupt", 0, 0, 0, ret_void, f_interrupt},
{"invert", 1, 1, FEARG_1, ret_number, f_invert},
{"isdirectory", 1, 1, FEARG_1, ret_number, f_isdirectory},
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
{"isinf", 1, 1, FEARG_1, ret_number, f_isinf},
#endif
{"isinf", 1, 1, FEARG_1, ret_number, MATH_FUNC(f_isinf)},
{"islocked", 1, 1, FEARG_1, ret_number, f_islocked},
#if defined(FEAT_FLOAT) && defined(HAVE_MATH_H)
{"isnan", 1, 1, FEARG_1, ret_number, f_isnan},
#endif
{"isnan", 1, 1, FEARG_1, ret_number, MATH_FUNC(f_isnan)},
{"items", 1, 1, FEARG_1, ret_list_any, f_items},
#ifdef FEAT_JOB_CHANNEL
{"job_getchannel", 1, 1, FEARG_1, ret_channel, f_job_getchannel},
{"job_info", 0, 1, FEARG_1, ret_dict_any, f_job_info},
{"job_setoptions", 2, 2, FEARG_1, ret_void, f_job_setoptions},
{"job_start", 1, 2, FEARG_1, ret_job, f_job_start},
{"job_status", 1, 1, FEARG_1, ret_string, f_job_status},
{"job_stop", 1, 2, FEARG_1, ret_number, f_job_stop},
#endif
{"job_getchannel", 1, 1, FEARG_1, ret_channel, JOB_FUNC(f_job_getchannel)},
{"job_info", 0, 1, FEARG_1, ret_dict_any, JOB_FUNC(f_job_info)},
{"job_setoptions", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_job_setoptions)},
{"job_start", 1, 2, FEARG_1, ret_job, JOB_FUNC(f_job_start)},
{"job_status", 1, 1, FEARG_1, ret_string, JOB_FUNC(f_job_status)},
{"job_stop", 1, 2, FEARG_1, ret_number, JOB_FUNC(f_job_stop)},
{"join", 1, 2, FEARG_1, ret_string, f_join},
{"js_decode", 1, 1, FEARG_1, ret_any, f_js_decode},
{"js_encode", 1, 1, FEARG_1, ret_string, f_js_encode},
@ -626,13 +659,15 @@ static funcentry_T global_functions[] =
{"listener_flush", 0, 1, FEARG_1, ret_void, f_listener_flush},
{"listener_remove", 1, 1, FEARG_1, ret_number, f_listener_remove},
{"localtime", 0, 0, 0, ret_number, f_localtime},
#ifdef FEAT_FLOAT
{"log", 1, 1, FEARG_1, ret_float, f_log},
{"log10", 1, 1, FEARG_1, ret_float, f_log10},
#endif
{"log", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_log)},
{"log10", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_log10)},
{"luaeval", 1, 2, FEARG_1, ret_any,
#ifdef FEAT_LUA
{"luaeval", 1, 2, FEARG_1, ret_any, f_luaeval},
f_luaeval
#else
NULL
#endif
},
{"map", 2, 2, FEARG_1, ret_any, f_map},
{"maparg", 1, 4, FEARG_1, ret_string, f_maparg},
{"mapcheck", 1, 3, FEARG_1, ret_string, f_mapcheck},
@ -646,77 +681,93 @@ static funcentry_T global_functions[] =
{"matchstr", 2, 4, FEARG_1, ret_string, f_matchstr},
{"matchstrpos", 2, 4, FEARG_1, ret_list_any, f_matchstrpos},
{"max", 1, 1, FEARG_1, ret_any, f_max},
{"menu_info", 1, 2, FEARG_1, ret_dict_any,
#ifdef FEAT_MENU
{"menu_info", 1, 2, FEARG_1, ret_dict_any, f_menu_info},
f_menu_info
#else
NULL
#endif
},
{"min", 1, 1, FEARG_1, ret_any, f_min},
{"mkdir", 1, 3, FEARG_1, ret_number, f_mkdir},
{"mode", 0, 1, FEARG_1, ret_string, f_mode},
{"mzeval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_MZSCHEME
{"mzeval", 1, 1, FEARG_1, ret_any, f_mzeval},
f_mzeval
#else
NULL
#endif
},
{"nextnonblank", 1, 1, FEARG_1, ret_number, f_nextnonblank},
{"nr2char", 1, 2, FEARG_1, ret_string, f_nr2char},
{"or", 2, 2, FEARG_1, ret_number, f_or},
{"pathshorten", 1, 1, FEARG_1, ret_string, f_pathshorten},
{"perleval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_PERL
{"perleval", 1, 1, FEARG_1, ret_any, f_perleval},
#endif
#ifdef FEAT_PROP_POPUP
{"popup_atcursor", 2, 2, FEARG_1, ret_number, f_popup_atcursor},
{"popup_beval", 2, 2, FEARG_1, ret_number, f_popup_beval},
{"popup_clear", 0, 0, 0, ret_void, f_popup_clear},
{"popup_close", 1, 2, FEARG_1, ret_void, f_popup_close},
{"popup_create", 2, 2, FEARG_1, ret_number, f_popup_create},
{"popup_dialog", 2, 2, FEARG_1, ret_number, f_popup_dialog},
{"popup_filter_menu", 2, 2, 0, ret_number, f_popup_filter_menu},
{"popup_filter_yesno", 2, 2, 0, ret_number, f_popup_filter_yesno},
{"popup_findinfo", 0, 0, 0, ret_number, f_popup_findinfo},
{"popup_findpreview", 0, 0, 0, ret_number, f_popup_findpreview},
{"popup_getoptions", 1, 1, FEARG_1, ret_dict_any, f_popup_getoptions},
{"popup_getpos", 1, 1, FEARG_1, ret_dict_any, f_popup_getpos},
{"popup_hide", 1, 1, FEARG_1, ret_void, f_popup_hide},
{"popup_locate", 2, 2, 0, ret_number, f_popup_locate},
{"popup_menu", 2, 2, FEARG_1, ret_number, f_popup_menu},
{"popup_move", 2, 2, FEARG_1, ret_void, f_popup_move},
{"popup_notification", 2, 2, FEARG_1, ret_number, f_popup_notification},
{"popup_setoptions", 2, 2, FEARG_1, ret_void, f_popup_setoptions},
{"popup_settext", 2, 2, FEARG_1, ret_void, f_popup_settext},
{"popup_show", 1, 1, FEARG_1, ret_void, f_popup_show},
#endif
#ifdef FEAT_FLOAT
{"pow", 2, 2, FEARG_1, ret_float, f_pow},
f_perleval
#else
NULL
#endif
},
{"popup_atcursor", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_atcursor)},
{"popup_beval", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_beval)},
{"popup_clear", 0, 0, 0, ret_void, PROP_FUNC(f_popup_clear)},
{"popup_close", 1, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_close)},
{"popup_create", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_create)},
{"popup_dialog", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_dialog)},
{"popup_filter_menu", 2, 2, 0, ret_number, PROP_FUNC(f_popup_filter_menu)},
{"popup_filter_yesno", 2, 2, 0, ret_number, PROP_FUNC(f_popup_filter_yesno)},
{"popup_findinfo", 0, 0, 0, ret_number, PROP_FUNC(f_popup_findinfo)},
{"popup_findpreview", 0, 0, 0, ret_number, PROP_FUNC(f_popup_findpreview)},
{"popup_getoptions", 1, 1, FEARG_1, ret_dict_any, PROP_FUNC(f_popup_getoptions)},
{"popup_getpos", 1, 1, FEARG_1, ret_dict_any, PROP_FUNC(f_popup_getpos)},
{"popup_hide", 1, 1, FEARG_1, ret_void, PROP_FUNC(f_popup_hide)},
{"popup_locate", 2, 2, 0, ret_number, PROP_FUNC(f_popup_locate)},
{"popup_menu", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_menu)},
{"popup_move", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_move)},
{"popup_notification", 2, 2, FEARG_1, ret_number, PROP_FUNC(f_popup_notification)},
{"popup_setoptions", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_setoptions)},
{"popup_settext", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_popup_settext)},
{"popup_show", 1, 1, FEARG_1, ret_void, PROP_FUNC(f_popup_show)},
{"pow", 2, 2, FEARG_1, ret_float, FLOAT_FUNC(f_pow)},
{"prevnonblank", 1, 1, FEARG_1, ret_number, f_prevnonblank},
{"printf", 1, 19, FEARG_2, ret_string, f_printf},
#ifdef FEAT_JOB_CHANNEL
{"prompt_setcallback", 2, 2, FEARG_1, ret_void, f_prompt_setcallback},
{"prompt_setinterrupt", 2, 2, FEARG_1,ret_void, f_prompt_setinterrupt},
{"prompt_setprompt", 2, 2, FEARG_1, ret_void, f_prompt_setprompt},
#endif
#ifdef FEAT_PROP_POPUP
{"prop_add", 3, 3, FEARG_1, ret_void, f_prop_add},
{"prop_clear", 1, 3, FEARG_1, ret_void, f_prop_clear},
{"prop_find", 1, 2, FEARG_1, ret_dict_any, f_prop_find},
{"prop_list", 1, 2, FEARG_1, ret_list_dict_any, f_prop_list},
{"prop_remove", 1, 3, FEARG_1, ret_number, f_prop_remove},
{"prop_type_add", 2, 2, FEARG_1, ret_void, f_prop_type_add},
{"prop_type_change", 2, 2, FEARG_1, ret_void, f_prop_type_change},
{"prop_type_delete", 1, 2, FEARG_1, ret_void, f_prop_type_delete},
{"prop_type_get", 1, 2, FEARG_1, ret_dict_any, f_prop_type_get},
{"prop_type_list", 0, 1, FEARG_1, ret_list_string, f_prop_type_list},
#endif
{"prompt_setcallback", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_prompt_setcallback)},
{"prompt_setinterrupt", 2, 2, FEARG_1,ret_void, JOB_FUNC(f_prompt_setinterrupt)},
{"prompt_setprompt", 2, 2, FEARG_1, ret_void, JOB_FUNC(f_prompt_setprompt)},
{"prop_add", 3, 3, FEARG_1, ret_void, PROP_FUNC(f_prop_add)},
{"prop_clear", 1, 3, FEARG_1, ret_void, PROP_FUNC(f_prop_clear)},
{"prop_find", 1, 2, FEARG_1, ret_dict_any, PROP_FUNC(f_prop_find)},
{"prop_list", 1, 2, FEARG_1, ret_list_dict_any, PROP_FUNC(f_prop_list)},
{"prop_remove", 1, 3, FEARG_1, ret_number, PROP_FUNC(f_prop_remove)},
{"prop_type_add", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_add)},
{"prop_type_change", 2, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_change)},
{"prop_type_delete", 1, 2, FEARG_1, ret_void, PROP_FUNC(f_prop_type_delete)},
{"prop_type_get", 1, 2, FEARG_1, ret_dict_any, PROP_FUNC(f_prop_type_get)},
{"prop_type_list", 0, 1, FEARG_1, ret_list_string, PROP_FUNC(f_prop_type_list)},
{"pum_getpos", 0, 0, 0, ret_dict_number, f_pum_getpos},
{"pumvisible", 0, 0, 0, ret_number, f_pumvisible},
{"py3eval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_PYTHON3
{"py3eval", 1, 1, FEARG_1, ret_any, f_py3eval},
f_py3eval
#else
NULL
#endif
},
{"pyeval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_PYTHON
{"pyeval", 1, 1, FEARG_1, ret_any, f_pyeval},
f_pyeval
#else
NULL
#endif
},
{"pyxeval", 1, 1, FEARG_1, ret_any,
#if defined(FEAT_PYTHON) || defined(FEAT_PYTHON3)
{"pyxeval", 1, 1, FEARG_1, ret_any, f_pyxeval},
f_pyxeval
#else
NULL
#endif
},
{"rand", 0, 1, FEARG_1, ret_number, f_rand},
{"range", 1, 3, FEARG_1, ret_list_number, f_range},
{"readdir", 1, 2, FEARG_1, ret_list_string, f_readdir},
@ -724,9 +775,7 @@ static funcentry_T global_functions[] =
{"reg_executing", 0, 0, 0, ret_string, f_reg_executing},
{"reg_recording", 0, 0, 0, ret_string, f_reg_recording},
{"reltime", 0, 2, FEARG_1, ret_list_any, f_reltime},
#ifdef FEAT_FLOAT
{"reltimefloat", 1, 1, FEARG_1, ret_float, f_reltimefloat},
#endif
{"reltimefloat", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_reltimefloat)},
{"reltimestr", 1, 1, FEARG_1, ret_string, f_reltimestr},
{"remote_expr", 2, 4, FEARG_1, ret_string, f_remote_expr},
{"remote_foreground", 1, 1, FEARG_1, ret_string, f_remote_foreground},
@ -739,12 +788,14 @@ static funcentry_T global_functions[] =
{"repeat", 2, 2, FEARG_1, ret_any, f_repeat},
{"resolve", 1, 1, FEARG_1, ret_string, f_resolve},
{"reverse", 1, 1, FEARG_1, ret_any, f_reverse},
#ifdef FEAT_FLOAT
{"round", 1, 1, FEARG_1, ret_float, f_round},
#endif
{"round", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_round)},
{"rubyeval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_RUBY
{"rubyeval", 1, 1, FEARG_1, ret_any, f_rubyeval},
f_rubyeval
#else
NULL
#endif
},
{"screenattr", 2, 2, FEARG_1, ret_number, f_screenattr},
{"screenchar", 2, 2, FEARG_1, ret_number, f_screenchar},
{"screenchars", 2, 2, FEARG_1, ret_list_number, f_screenchars},
@ -775,62 +826,64 @@ static funcentry_T global_functions[] =
{"settabwinvar", 4, 4, FEARG_4, ret_void, f_settabwinvar},
{"settagstack", 2, 3, FEARG_2, ret_number, f_settagstack},
{"setwinvar", 3, 3, FEARG_3, ret_void, f_setwinvar},
{"sha256", 1, 1, FEARG_1, ret_string,
#ifdef FEAT_CRYPT
{"sha256", 1, 1, FEARG_1, ret_string, f_sha256},
f_sha256
#else
NULL
#endif
},
{"shellescape", 1, 2, FEARG_1, ret_string, f_shellescape},
{"shiftwidth", 0, 1, FEARG_1, ret_number, f_shiftwidth},
#ifdef FEAT_SIGNS
{"sign_define", 1, 2, FEARG_1, ret_any, f_sign_define},
{"sign_getdefined", 0, 1, FEARG_1, ret_list_dict_any, f_sign_getdefined},
{"sign_getplaced", 0, 2, FEARG_1, ret_list_dict_any, f_sign_getplaced},
{"sign_jump", 3, 3, FEARG_1, ret_number, f_sign_jump},
{"sign_place", 4, 5, FEARG_1, ret_number, f_sign_place},
{"sign_placelist", 1, 1, FEARG_1, ret_list_number, f_sign_placelist},
{"sign_undefine", 0, 1, FEARG_1, ret_number, f_sign_undefine},
{"sign_unplace", 1, 2, FEARG_1, ret_number, f_sign_unplace},
{"sign_unplacelist", 1, 2, FEARG_1, ret_list_number, f_sign_unplacelist},
#endif
{"sign_define", 1, 2, FEARG_1, ret_any, SIGN_FUNC(f_sign_define)},
{"sign_getdefined", 0, 1, FEARG_1, ret_list_dict_any, SIGN_FUNC(f_sign_getdefined)},
{"sign_getplaced", 0, 2, FEARG_1, ret_list_dict_any, SIGN_FUNC(f_sign_getplaced)},
{"sign_jump", 3, 3, FEARG_1, ret_number, SIGN_FUNC(f_sign_jump)},
{"sign_place", 4, 5, FEARG_1, ret_number, SIGN_FUNC(f_sign_place)},
{"sign_placelist", 1, 1, FEARG_1, ret_list_number, SIGN_FUNC(f_sign_placelist)},
{"sign_undefine", 0, 1, FEARG_1, ret_number, SIGN_FUNC(f_sign_undefine)},
{"sign_unplace", 1, 2, FEARG_1, ret_number, SIGN_FUNC(f_sign_unplace)},
{"sign_unplacelist", 1, 2, FEARG_1, ret_list_number, SIGN_FUNC(f_sign_unplacelist)},
{"simplify", 1, 1, 0, ret_string, f_simplify},
#ifdef FEAT_FLOAT
{"sin", 1, 1, FEARG_1, ret_float, f_sin},
{"sinh", 1, 1, FEARG_1, ret_float, f_sinh},
#endif
{"sin", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sin)},
{"sinh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sinh)},
{"sort", 1, 3, FEARG_1, ret_list_any, f_sort},
#ifdef FEAT_SOUND
{"sound_clear", 0, 0, 0, ret_void, f_sound_clear},
{"sound_playevent", 1, 2, FEARG_1, ret_number, f_sound_playevent},
{"sound_playfile", 1, 2, FEARG_1, ret_number, f_sound_playfile},
{"sound_stop", 1, 1, FEARG_1, ret_void, f_sound_stop},
#endif
{"sound_clear", 0, 0, 0, ret_void, SOUND_FUNC(f_sound_clear)},
{"sound_playevent", 1, 2, FEARG_1, ret_number, SOUND_FUNC(f_sound_playevent)},
{"sound_playfile", 1, 2, FEARG_1, ret_number, SOUND_FUNC(f_sound_playfile)},
{"sound_stop", 1, 1, FEARG_1, ret_void, SOUND_FUNC(f_sound_stop)},
{"soundfold", 1, 1, FEARG_1, ret_string, f_soundfold},
{"spellbadword", 0, 1, FEARG_1, ret_list_string, f_spellbadword},
{"spellsuggest", 1, 3, FEARG_1, ret_list_string, f_spellsuggest},
{"split", 1, 3, FEARG_1, ret_list_string, f_split},
#ifdef FEAT_FLOAT
{"sqrt", 1, 1, FEARG_1, ret_float, f_sqrt},
#endif
{"sqrt", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_sqrt)},
{"srand", 0, 1, FEARG_1, ret_list_number, f_srand},
{"state", 0, 1, FEARG_1, ret_string, f_state},
#ifdef FEAT_FLOAT
{"str2float", 1, 1, FEARG_1, ret_float, f_str2float},
#endif
{"str2float", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_str2float)},
{"str2list", 1, 2, FEARG_1, ret_list_number, f_str2list},
{"str2nr", 1, 3, FEARG_1, ret_number, f_str2nr},
{"strcharpart", 2, 3, FEARG_1, ret_string, f_strcharpart},
{"strchars", 1, 2, FEARG_1, ret_number, f_strchars},
{"strdisplaywidth", 1, 2, FEARG_1, ret_number, f_strdisplaywidth},
{"strftime", 1, 2, FEARG_1, ret_string,
#ifdef HAVE_STRFTIME
{"strftime", 1, 2, FEARG_1, ret_string, f_strftime},
f_strftime
#else
NULL
#endif
},
{"strgetchar", 2, 2, FEARG_1, ret_number, f_strgetchar},
{"stridx", 2, 3, FEARG_1, ret_number, f_stridx},
{"string", 1, 1, FEARG_1, ret_string, f_string},
{"strlen", 1, 1, FEARG_1, ret_number, f_strlen},
{"strpart", 2, 3, FEARG_1, ret_string, f_strpart},
{"strptime", 2, 2, FEARG_1, ret_number,
#ifdef HAVE_STRPTIME
{"strptime", 2, 2, FEARG_1, ret_number, f_strptime},
f_strptime
#else
NULL
#endif
},
{"strridx", 2, 3, FEARG_1, ret_number, f_strridx},
{"strtrans", 1, 1, FEARG_1, ret_string, f_strtrans},
{"strwidth", 1, 1, FEARG_1, ret_number, f_strwidth},
@ -850,41 +903,45 @@ static funcentry_T global_functions[] =
{"tabpagewinnr", 1, 2, FEARG_1, ret_number, f_tabpagewinnr},
{"tagfiles", 0, 0, 0, ret_list_string, f_tagfiles},
{"taglist", 1, 2, FEARG_1, ret_list_dict_any, f_taglist},
#ifdef FEAT_FLOAT
{"tan", 1, 1, FEARG_1, ret_float, f_tan},
{"tanh", 1, 1, FEARG_1, ret_float, f_tanh},
#endif
{"tan", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_tan)},
{"tanh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_tanh)},
{"tempname", 0, 0, 0, ret_string, f_tempname},
#ifdef FEAT_TERMINAL
{"term_dumpdiff", 2, 3, FEARG_1, ret_number, f_term_dumpdiff},
{"term_dumpload", 1, 2, FEARG_1, ret_number, f_term_dumpload},
{"term_dumpwrite", 2, 3, FEARG_2, ret_void, f_term_dumpwrite},
{"term_getaltscreen", 1, 1, FEARG_1, ret_number, f_term_getaltscreen},
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
{"term_getansicolors", 1, 1, FEARG_1, ret_list_string, f_term_getansicolors},
# endif
{"term_getattr", 2, 2, FEARG_1, ret_number, f_term_getattr},
{"term_getcursor", 1, 1, FEARG_1, ret_list_any, f_term_getcursor},
{"term_getjob", 1, 1, FEARG_1, ret_job, f_term_getjob},
{"term_getline", 2, 2, FEARG_1, ret_string, f_term_getline},
{"term_getscrolled", 1, 1, FEARG_1, ret_number, f_term_getscrolled},
{"term_getsize", 1, 1, FEARG_1, ret_list_number, f_term_getsize},
{"term_getstatus", 1, 1, FEARG_1, ret_string, f_term_getstatus},
{"term_gettitle", 1, 1, FEARG_1, ret_string, f_term_gettitle},
{"term_gettty", 1, 2, FEARG_1, ret_string, f_term_gettty},
{"term_list", 0, 0, 0, ret_list_number, f_term_list},
{"term_scrape", 2, 2, FEARG_1, ret_list_dict_any, f_term_scrape},
{"term_sendkeys", 2, 2, FEARG_1, ret_void, f_term_sendkeys},
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
{"term_setansicolors", 2, 2, FEARG_1, ret_void, f_term_setansicolors},
# endif
{"term_setapi", 2, 2, FEARG_1, ret_void, f_term_setapi},
{"term_setkill", 2, 2, FEARG_1, ret_void, f_term_setkill},
{"term_setrestore", 2, 2, FEARG_1, ret_void, f_term_setrestore},
{"term_setsize", 3, 3, FEARG_1, ret_void, f_term_setsize},
{"term_start", 1, 2, FEARG_1, ret_number, f_term_start},
{"term_wait", 1, 2, FEARG_1, ret_void, f_term_wait},
{"term_dumpdiff", 2, 3, FEARG_1, ret_number, TERM_FUNC(f_term_dumpdiff)},
{"term_dumpload", 1, 2, FEARG_1, ret_number, TERM_FUNC(f_term_dumpload)},
{"term_dumpwrite", 2, 3, FEARG_2, ret_void, TERM_FUNC(f_term_dumpwrite)},
{"term_getaltscreen", 1, 1, FEARG_1, ret_number, TERM_FUNC(f_term_getaltscreen)},
{"term_getansicolors", 1, 1, FEARG_1, ret_list_string,
#if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
f_term_getansicolors
#else
NULL
#endif
},
{"term_getattr", 2, 2, FEARG_1, ret_number, TERM_FUNC(f_term_getattr)},
{"term_getcursor", 1, 1, FEARG_1, ret_list_any, TERM_FUNC(f_term_getcursor)},
{"term_getjob", 1, 1, FEARG_1, ret_job, TERM_FUNC(f_term_getjob)},
{"term_getline", 2, 2, FEARG_1, ret_string, TERM_FUNC(f_term_getline)},
{"term_getscrolled", 1, 1, FEARG_1, ret_number, TERM_FUNC(f_term_getscrolled)},
{"term_getsize", 1, 1, FEARG_1, ret_list_number, TERM_FUNC(f_term_getsize)},
{"term_getstatus", 1, 1, FEARG_1, ret_string, TERM_FUNC(f_term_getstatus)},
{"term_gettitle", 1, 1, FEARG_1, ret_string, TERM_FUNC(f_term_gettitle)},
{"term_gettty", 1, 2, FEARG_1, ret_string, TERM_FUNC(f_term_gettty)},
{"term_list", 0, 0, 0, ret_list_number, TERM_FUNC(f_term_list)},
{"term_scrape", 2, 2, FEARG_1, ret_list_dict_any, TERM_FUNC(f_term_scrape)},
{"term_sendkeys", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_sendkeys)},
{"term_setansicolors", 2, 2, FEARG_1, ret_void,
#if defined(FEAT_TERMINAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
f_term_setansicolors
#else
NULL
#endif
},
{"term_setapi", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setapi)},
{"term_setkill", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setkill)},
{"term_setrestore", 2, 2, FEARG_1, ret_void, TERM_FUNC(f_term_setrestore)},
{"term_setsize", 3, 3, FEARG_1, ret_void, TERM_FUNC(f_term_setsize)},
{"term_start", 1, 2, FEARG_1, ret_number, TERM_FUNC(f_term_start)},
{"term_wait", 1, 2, FEARG_1, ret_void, TERM_FUNC(f_term_wait)},
{"test_alloc_fail", 3, 3, FEARG_1, ret_void, f_test_alloc_fail},
{"test_autochdir", 0, 0, 0, ret_void, f_test_autochdir},
{"test_feedinput", 1, 1, FEARG_1, ret_void, f_test_feedinput},
@ -893,41 +950,37 @@ static funcentry_T global_functions[] =
{"test_getvalue", 1, 1, FEARG_1, ret_number, f_test_getvalue},
{"test_ignore_error", 1, 1, FEARG_1, ret_void, f_test_ignore_error},
{"test_null_blob", 0, 0, 0, ret_blob, f_test_null_blob},
#ifdef FEAT_JOB_CHANNEL
{"test_null_channel", 0, 0, 0, ret_channel, f_test_null_channel},
#endif
{"test_null_channel", 0, 0, 0, ret_channel, JOB_FUNC(f_test_null_channel)},
{"test_null_dict", 0, 0, 0, ret_dict_any, f_test_null_dict},
#ifdef FEAT_JOB_CHANNEL
{"test_null_job", 0, 0, 0, ret_job, f_test_null_job},
#endif
{"test_null_job", 0, 0, 0, ret_job, JOB_FUNC(f_test_null_job)},
{"test_null_list", 0, 0, 0, ret_list_any, f_test_null_list},
{"test_null_partial", 0, 0, 0, ret_partial_void, f_test_null_partial},
{"test_null_string", 0, 0, 0, ret_string, f_test_null_string},
{"test_option_not_set", 1, 1, FEARG_1,ret_void, f_test_option_not_set},
{"test_override", 2, 2, FEARG_2, ret_void, f_test_override},
{"test_refcount", 1, 1, FEARG_1, ret_number, f_test_refcount},
{"test_scrollbar", 3, 3, FEARG_2, ret_void,
#ifdef FEAT_GUI
{"test_scrollbar", 3, 3, FEARG_2, ret_void, f_test_scrollbar},
f_test_scrollbar
#else
NULL
#endif
},
{"test_setmouse", 2, 2, 0, ret_void, f_test_setmouse},
{"test_settime", 1, 1, FEARG_1, ret_void, f_test_settime},
{"test_srand_seed", 0, 1, FEARG_1, ret_void, f_test_srand_seed},
{"test_unknown", 0, 0, 0, ret_any, f_test_unknown},
{"test_void", 0, 0, 0, ret_any, f_test_void},
#ifdef FEAT_TIMERS
{"timer_info", 0, 1, FEARG_1, ret_list_dict_any, f_timer_info},
{"timer_pause", 2, 2, FEARG_1, ret_void, f_timer_pause},
{"timer_start", 2, 3, FEARG_1, ret_number, f_timer_start},
{"timer_stop", 1, 1, FEARG_1, ret_void, f_timer_stop},
{"timer_stopall", 0, 0, 0, ret_void, f_timer_stopall},
#endif
{"timer_info", 0, 1, FEARG_1, ret_list_dict_any, TIMER_FUNC(f_timer_info)},
{"timer_pause", 2, 2, FEARG_1, ret_void, TIMER_FUNC(f_timer_pause)},
{"timer_start", 2, 3, FEARG_1, ret_number, TIMER_FUNC(f_timer_start)},
{"timer_stop", 1, 1, FEARG_1, ret_void, TIMER_FUNC(f_timer_stop)},
{"timer_stopall", 0, 0, 0, ret_void, TIMER_FUNC(f_timer_stopall)},
{"tolower", 1, 1, FEARG_1, ret_string, f_tolower},
{"toupper", 1, 1, FEARG_1, ret_string, f_toupper},
{"tr", 3, 3, FEARG_1, ret_string, f_tr},
{"trim", 1, 2, FEARG_1, ret_string, f_trim},
#ifdef FEAT_FLOAT
{"trunc", 1, 1, FEARG_1, ret_float, f_trunc},
#endif
{"trunc", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_trunc)},
{"type", 1, 1, FEARG_1, ret_number, f_type},
{"undofile", 1, 1, FEARG_1, ret_string, f_undofile},
{"undotree", 0, 0, 0, ret_dict_any, f_undotree},
@ -1014,10 +1067,11 @@ get_expr_name(expand_T *xp, int idx)
/*
* Find internal function "name" in table "global_functions".
* Return index, or -1 if not found
* Return index, or -1 if not found or "implemented" is TRUE and the function
* is not implemented.
*/
int
find_internal_func(char_u *name)
static int
find_internal_func_opt(char_u *name, int implemented)
{
int first = 0;
int last;
@ -1035,16 +1089,34 @@ find_internal_func(char_u *name)
last = x - 1;
else if (cmp > 0)
first = x + 1;
else if (implemented && global_functions[x].f_func == NULL)
break;
else
return x;
}
return -1;
}
/*
* Find internal function "name" in table "global_functions".
* Return index, or -1 if not found or the function is not implemented.
*/
int
find_internal_func(char_u *name)
{
return find_internal_func_opt(name, TRUE);
}
int
has_internal_func(char_u *name)
{
return find_internal_func(name) >= 0;
return find_internal_func_opt(name, TRUE) >= 0;
}
static int
has_internal_func_name(char_u *name)
{
return find_internal_func_opt(name, FALSE) >= 0;
}
char *
@ -2288,6 +2360,10 @@ f_exists(typval_T *argvars, typval_T *rettv)
{
n = function_exists(p + 1, FALSE);
}
else if (*p == '?') // internal function only
{
n = has_internal_func_name(p + 1);
}
else if (*p == ':')
{
n = cmd_exists(p + 1);

View File

@ -3461,7 +3461,6 @@ f_getwinvar(typval_T *argvars, typval_T *rettv)
f_getbufvar(typval_T *argvars, typval_T *rettv)
{
buf_T *buf;
buf_T *save_curbuf;
char_u *varname;
dictitem_T *v;
int done = FALSE;
@ -3476,12 +3475,13 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
if (buf != NULL && varname != NULL)
{
// set curbuf to be our buf, temporarily
save_curbuf = curbuf;
curbuf = buf;
if (*varname == '&')
{
buf_T *save_curbuf = curbuf;
// set curbuf to be our buf, temporarily
curbuf = buf;
if (varname[1] == NUL)
{
// get all buffer-local options in a dict
@ -3496,22 +3496,21 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
else if (get_option_tv(&varname, rettv, TRUE) == OK)
// buffer-local-option
done = TRUE;
// restore previous notion of curbuf
curbuf = save_curbuf;
}
else
{
// Look up the variable.
// Let getbufvar({nr}, "") return the "b:" dictionary.
v = find_var_in_ht(&curbuf->b_vars->dv_hashtab,
'b', varname, FALSE);
v = find_var_in_ht(&buf->b_vars->dv_hashtab, 'b', varname, FALSE);
if (v != NULL)
{
copy_tv(&v->di_tv, rettv);
done = TRUE;
}
}
// restore previous notion of curbuf
curbuf = save_curbuf;
}
if (!done && argvars[2].v_type != VAR_UNKNOWN)
@ -3618,11 +3617,11 @@ f_setbufvar(typval_T *argvars, typval_T *rettv UNUSED)
}
else
{
buf_T *save_curbuf = curbuf;
bufvarname = alloc(STRLEN(varname) + 3);
if (bufvarname != NULL)
{
buf_T *save_curbuf = curbuf;
curbuf = buf;
STRCPY(bufvarname, "b:");
STRCPY(bufvarname + 2, varname);

View File

@ -261,11 +261,21 @@ readfile(
{
if (apply_autocmds_exarg(EVENT_BUFREADCMD, NULL, sfname,
FALSE, curbuf, eap))
{
int status = OK;
#ifdef FEAT_EVAL
return aborting() ? FAIL : OK;
#else
return OK;
if (aborting())
status = FAIL;
#endif
// The BufReadCmd code usually uses ":read" to get the text and
// perhaps ":file" to change the buffer name. But we should
// consider this to work like ":edit", thus reset the
// BF_NOTEDITED flag. Then ":write" will work to overwrite the
// same file.
if (status == OK)
curbuf->b_flags &= ~BF_NOTEDITED;
return status;
}
}
else if (apply_autocmds_exarg(EVENT_FILEREADCMD, sfname, sfname,
FALSE, NULL, eap))

View File

@ -384,9 +384,7 @@ EXTERN type_T t_void INIT4(VAR_VOID, 0, NULL, NULL);
EXTERN type_T t_bool INIT4(VAR_BOOL, 0, NULL, NULL);
EXTERN type_T t_special INIT4(VAR_SPECIAL, 0, NULL, NULL);
EXTERN type_T t_number INIT4(VAR_NUMBER, 0, NULL, NULL);
# ifdef FEAT_FLOAT
EXTERN type_T t_float INIT4(VAR_FLOAT, 0, NULL, NULL);
# endif
EXTERN type_T t_string INIT4(VAR_STRING, 0, NULL, NULL);
EXTERN type_T t_blob INIT4(VAR_BLOB, 0, NULL, NULL);
EXTERN type_T t_job INIT4(VAR_JOB, 0, NULL, NULL);
@ -1646,6 +1644,7 @@ EXTERN char e_func_deleted[] INIT(= N_("E933: Function was deleted: %s"));
EXTERN char e_dictkey[] INIT(= N_("E716: Key not present in Dictionary: %s"));
EXTERN char e_listreq[] INIT(= N_("E714: List required"));
EXTERN char e_listblobreq[] INIT(= N_("E897: List or Blob required"));
EXTERN char e_list_end[] INIT(= N_("E697: Missing end of List ']': %s"));
EXTERN char e_listdictarg[] INIT(= N_("E712: Argument of %s must be a List or Dictionary"));
EXTERN char e_listdictblobarg[] INIT(= N_("E896: Argument of %s must be a List, Dictionary or Blob"));
EXTERN char e_modulus[] INIT(= N_("E804: Cannot use '%' with Float"));

View File

@ -2630,18 +2630,19 @@ gui_outstr_nowrap(
/*
* Un-draw the cursor. Actually this just redraws the character at the given
* position. The character just before it too, for when it was in bold.
* position.
*/
void
gui_undraw_cursor(void)
{
if (gui.cursor_is_valid)
{
if (gui_redraw_block(gui.cursor_row, gui.cursor_col,
gui.cursor_row, gui.cursor_col, GUI_MON_NOCLEAR)
&& gui.cursor_col > 0)
(void)gui_redraw_block(gui.cursor_row, gui.cursor_col - 1,
gui.cursor_row, gui.cursor_col - 1, GUI_MON_NOCLEAR);
// Redraw the character just before too, if there is one, because with
// some fonts and characters there can be a one pixel overlap.
gui_redraw_block(gui.cursor_row,
gui.cursor_col > 0 ? gui.cursor_col - 1 : gui.cursor_col,
gui.cursor_row, gui.cursor_col, GUI_MON_NOCLEAR);
// Cursor_is_valid is reset when the cursor is undrawn, also reset it
// here in case it wasn't needed to undraw it.
gui.cursor_is_valid = FALSE;
@ -2662,7 +2663,7 @@ gui_redraw(
row2 = Y_2_ROW(y + h - 1);
col2 = X_2_COL(x + w - 1);
(void)gui_redraw_block(row1, col1, row2, col2, GUI_MON_NOCLEAR);
gui_redraw_block(row1, col1, row2, col2, GUI_MON_NOCLEAR);
/*
* We may need to redraw the cursor, but don't take it upon us to change
@ -2678,10 +2679,8 @@ gui_redraw(
/*
* Draw a rectangular block of characters, from row1 to row2 (inclusive) and
* from col1 to col2 (inclusive).
* Return TRUE when the character before the first drawn character has
* different attributes (may have to be redrawn too).
*/
int
void
gui_redraw_block(
int row1,
int col1,
@ -2695,12 +2694,11 @@ gui_redraw_block(
sattr_T first_attr;
int idx, len;
int back, nback;
int retval = FALSE;
int orig_col1, orig_col2;
// Don't try to update when ScreenLines is not valid
if (!screen_cleared || ScreenLines == NULL)
return retval;
return;
// Don't try to draw outside the shell!
// Check everything, strange values may be caused by a big border width
@ -2762,8 +2760,6 @@ gui_redraw_block(
if (ScreenAttrs[off - 1 - back] != ScreenAttrs[off]
|| ScreenLines[off - 1 - back] == ' ')
break;
retval = (col1 > 0 && ScreenAttrs[off - 1] != 0 && back == 0
&& ScreenLines[off - 1] != ' ');
// Break it up in strings of characters with the same attributes.
// Print UTF-8 characters individually.
@ -2845,8 +2841,6 @@ gui_redraw_block(
gui.row = old_row;
gui.col = old_col;
gui.highlight_mask = (int)old_hl_mask;
return retval;
}
static void

View File

@ -4743,6 +4743,8 @@ is_cjk_font(PangoFontDescription *font_desc)
PangoCoverage *coverage;
gunichar uc;
// Valgrind reports a leak for pango_language_from_string(), but the
// documentation says "This is owned by Pango and should not be freed".
coverage = pango_font_get_coverage(
font, pango_language_from_string(cjk_langs[i]));

View File

@ -398,16 +398,6 @@ static const luaV_Reg luaV_dll[] = {
static HANDLE hinstLua = NULL;
static void
end_dynamic_lua(void)
{
if (hinstLua)
{
close_dll(hinstLua);
hinstLua = 0;
}
}
static int
lua_link_init(char *libname, int verbose)
{
@ -2121,9 +2111,6 @@ lua_end(void)
{
lua_close(L);
L = NULL;
#ifdef DYNAMIC_LUA
end_dynamic_lua();
#endif
}
}

View File

@ -762,7 +762,7 @@ perl_init(void)
}
/*
* perl_end(): clean up after ourselves
* Clean up after ourselves.
*/
void
perl_end(void)
@ -777,13 +777,6 @@ perl_end(void)
Perl_sys_term();
#endif
}
#ifdef DYNAMIC_PERL
if (hPerlLib)
{
close_dll(hPerlLib);
hPerlLib = NULL;
}
#endif
}
/*

View File

@ -654,19 +654,6 @@ static struct
{"", NULL},
};
/*
* Free python.dll
*/
static void
end_dynamic_python(void)
{
if (hinstPython)
{
close_dll(hinstPython);
hinstPython = 0;
}
}
/*
* Load library and get all pointers.
* Parameter 'libname' provides name of DLL.
@ -889,7 +876,6 @@ python_end(void)
# endif
Py_Finalize();
}
end_dynamic_python();
#else
if (Py_IsInitialized())
{

View File

@ -634,19 +634,6 @@ py3__Py_XDECREF(PyObject *op)
# define Py_XDECREF(op) py3__Py_XDECREF(_PyObject_CAST(op))
# endif
/*
* Free python.dll
*/
static void
end_dynamic_python3(void)
{
if (hinstPy3 != 0)
{
close_dll(hinstPy3);
hinstPy3 = 0;
}
}
/*
* Load library and get all pointers.
* Parameter 'libname' provides name of DLL.
@ -873,10 +860,6 @@ python3_end(void)
Py_Finalize();
}
#ifdef DYNAMIC_PYTHON3
end_dynamic_python3();
#endif
--recurse;
}

View File

@ -735,19 +735,6 @@ static struct
{"", NULL},
};
/*
* Free ruby.dll
*/
static void
end_dynamic_ruby(void)
{
if (hinstRuby)
{
close_dll(hinstRuby);
hinstRuby = NULL;
}
}
/*
* Load library and get all pointers.
* Parameter 'libname' provides name of DLL.
@ -797,9 +784,6 @@ ruby_enabled(int verbose)
void
ruby_end(void)
{
#ifdef DYNAMIC_RUBY
end_dynamic_ruby();
#endif
}
void

View File

@ -280,13 +280,6 @@ tcl_enabled(int verbose)
void
tcl_end(void)
{
#ifdef DYNAMIC_TCL
if (hTclLib)
{
close_dll(hTclLib);
hTclLib = NULL;
}
#endif
}
/////////////////////////////////////////////////////////////////////////////

View File

@ -1083,7 +1083,7 @@ get_list_tv(char_u **arg, typval_T *rettv, int evaluate, int do_error)
if (**arg != ']')
{
if (do_error)
semsg(_("E697: Missing end of List ']': %s"), *arg);
semsg(_(e_list_end), *arg);
failret:
if (evaluate)
list_free(l);

View File

@ -47,13 +47,13 @@
#endif // !USE_SYSTEM
#ifdef HAVE_STROPTS_H
#ifdef sinix
#define buf_T __system_buf_t__
#endif
# ifdef sinix
# define buf_T __system_buf_t__
# endif
# include <stropts.h>
#ifdef sinix
#undef buf_T
#endif
# ifdef sinix
# undef buf_T
# endif
#endif
#ifdef HAVE_STRING_H

File diff suppressed because it is too large Load Diff

View File

@ -27,7 +27,7 @@ void gui_enable_flush(void);
void gui_may_flush(void);
void gui_undraw_cursor(void);
void gui_redraw(int x, int y, int w, int h);
int gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
void gui_redraw_block(int row1, int col1, int row2, int col2, int flags);
int gui_wait_for_chars(long wtime, int tb_change_cnt);
int gui_inchar(char_u *buf, int maxlen, long wtime, int tb_change_cnt);
void gui_send_mouse_event(int button, int x, int y, int repeated_click, int_u modifiers);

View File

@ -33,6 +33,7 @@ void f_popup_hide(typval_T *argvars, typval_T *rettv);
void popup_show(win_T *wp);
void f_popup_show(typval_T *argvars, typval_T *rettv);
void f_popup_settext(typval_T *argvars, typval_T *rettv);
int error_if_popup_window(int also_with_term);
void popup_close(int id);
void popup_close_tabpage(tabpage_T *tp, int id);
void close_all_popups(void);
@ -41,7 +42,6 @@ void f_popup_setoptions(typval_T *argvars, typval_T *rettv);
void f_popup_getpos(typval_T *argvars, typval_T *rettv);
void f_popup_locate(typval_T *argvars, typval_T *rettv);
void f_popup_getoptions(typval_T *argvars, typval_T *rettv);
int error_if_popup_window(int also_with_term);
int error_if_term_popup_window(void);
void popup_reset_handled(int handled_flag);
win_T *find_next_popup(int lowest, int handled_flag);

View File

@ -2788,11 +2788,10 @@ give_up:
&& ScreenLines != NULL
&& old_Rows != Rows)
{
(void)gui_redraw_block(0, 0, (int)Rows - 1, (int)Columns - 1, 0);
/*
* Adjust the position of the cursor, for when executing an external
* command.
*/
gui_redraw_block(0, 0, (int)Rows - 1, (int)Columns - 1, 0);
// Adjust the position of the cursor, for when executing an external
// command.
if (msg_row >= Rows) // Rows got smaller
msg_row = Rows - 1; // put cursor at last row
else if (Rows > old_Rows) // Rows got bigger

View File

@ -1274,6 +1274,7 @@ do_source(
// loading the same script again
si->sn_had_command = FALSE;
si->sn_version = 1;
current_sctx.sc_sid = sid;
ht = &SCRIPT_VARS(sid);

View File

@ -6925,8 +6925,6 @@ term_and_job_init(
jobopt_T *orig_opt UNUSED)
{
term->tl_arg0_cmd = NULL;
if (opt->jo_set2 & JO2_TERM_HIGHLIGHT)
term->tl_highlight_name = vim_strsave(opt->jo_term_highlight);
if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
return FAIL;

View File

@ -25,9 +25,12 @@ func CheckOption(name)
endif
endfunc
" Command to check for the presence of a function.
" Command to check for the presence of a built-in function.
command -nargs=1 CheckFunction call CheckFunction(<f-args>)
func CheckFunction(name)
if !exists('?' .. a:name)
throw 'Checking for non-existent function ' .. a:name
endif
if !exists('*' .. a:name)
throw 'Skipped: ' .. a:name .. ' function missing'
endif

View File

@ -16,5 +16,5 @@
|a+0#0000001#ffd7ff255|b|6| @11| +0#0000000#a8a8a8255| +0&#ffffff0@58
|a|b|0> @71
|~+0#4040ff13&| @73
|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1|0|,|1| @10|B|o|t
|[+3#0000000&|N|o| |N|a|m|e|]| |[|+|]| @43|1@1|,|1| @10|B|o|t
|-+2&&@1| |K|e|y|w|o|r|d| |L|o|c|a|l| |c|o|m|p|l|e|t|i|o|n| |(|^|N|^|P|)| |m+0#00e0003&|a|t|c|h| |1| |o|f| |1|0| +0#0000000&@26

View File

@ -1536,6 +1536,40 @@ func Test_Cmd_Autocmds()
enew!
endfunc
func s:ReadFile()
setl noswapfile nomodified
let filename = resolve(expand("<afile>:p"))
execute 'read' fnameescape(filename)
1d_
exe 'file' fnameescape(filename)
setl buftype=acwrite
endfunc
func s:WriteFile()
let filename = resolve(expand("<afile>:p"))
setl buftype=
noautocmd execute 'write' fnameescape(filename)
setl buftype=acwrite
setl nomodified
endfunc
func Test_BufReadCmd()
autocmd BufReadCmd *.test call s:ReadFile()
autocmd BufWriteCmd *.test call s:WriteFile()
call writefile(['one', 'two', 'three'], 'Xcmd.test')
edit Xcmd.test
call assert_match('Xcmd.test" line 1 of 3', execute('file'))
normal! Gofour
write
call assert_equal(['one', 'two', 'three', 'four'], readfile('Xcmd.test'))
bwipe!
call delete('Xcmd.test')
au! BufReadCmd
au! BufWriteCmd
endfunc
func SetChangeMarks(start, end)
exe a:start. 'mark ['
exe a:end. 'mark ]'

View File

@ -1174,8 +1174,13 @@ func Test_out_cb()
" Receive a json object split in pieces
let g:Ch_outobj = ''
call ch_sendraw(job, "echosplit [0, {\"one\": 1,| \"tw|o\": 2, \"three\": 3|}]\n")
" For unknown reason this can be very slow on Mac.
call WaitForAssert({-> assert_equal({'one': 1, 'two': 2, 'three': 3}, g:Ch_outobj)}, 10000)
" For unknown reasons this can be very slow on Mac.
if has('mac')
let timeout = 20000
else
let timeout = 5000
endif
call WaitForAssert({-> assert_equal({'one': 1, 'two': 2, 'three': 3}, g:Ch_outobj)}, timeout)
finally
call job_stop(job)
endtry

View File

@ -259,11 +259,13 @@ func Test_confirm_cmd_cancel()
call WaitForAssert({-> assert_match('^\[Y\]es, (N)o, (C)ancel: *$',
\ term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, "C")
call term_wait(buf, 50)
call WaitForAssert({-> assert_equal('', term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, ":confirm close\n")
call WaitForAssert({-> assert_match('^\[Y\]es, (N)o, (C)ancel: *$',
\ term_getline(buf, 20))}, 1000)
call term_sendkeys(buf, "N")
call WaitForAssert({-> assert_match('^ *0,0-1 All$',
\ term_getline(buf, 20))}, 1000)
call StopVimInTerminal(buf)
endfunc

View File

@ -92,6 +92,11 @@ func Test_exists()
" Function that may be created by script autoloading
call assert_equal(0, exists('*footest#F'))
call assert_equal(has('float'), exists('*acos'))
call assert_equal(1, exists('?acos'))
call assert_equal(has('win32'), exists('*debugbreak'))
call assert_equal(1, exists('?debugbreak'))
" Valid internal command (full match)
call assert_equal(2, exists(':edit'))
" Valid internal command (full match) with garbage

View File

@ -62,7 +62,7 @@ endfunc
function Test_lambda_fails()
call assert_equal(3, {a, b -> a + b}(1, 2))
call assert_fails('echo {a, a -> a + a}(1, 2)', 'E853:')
call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E15:')
call assert_fails('echo {a, b -> a + b)}(1, 2)', 'E451:')
echo assert_fails('echo 10->{a -> a + 2}', 'E107:')
endfunc

View File

@ -33,10 +33,17 @@ func Test_buffer_menu_special_buffers()
let orig_buffer_menus = execute("nmenu Buffers")
" Test that regular new buffer results in a new buffer menu item.
new
let new_buffer_menus = execute('nmenu Buffers')
call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(new_buffer_menus, "\n")))
bwipe!
call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
" Make a new command-line window, test that it does not create a new buffer
" menu.
call feedkeys("q::let cmdline_buffer_menus=execute('nmenu Buffers')\<CR>:q\<CR>", 'ntx')
call assert_equal(len(split(orig_buffer_menus, "\n")), len(split(cmdline_buffer_menus, "\n")))
call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(cmdline_buffer_menus, "\n")))
call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
if has('terminal')
@ -44,7 +51,7 @@ func Test_buffer_menu_special_buffers()
" item.
terminal
let term_buffer_menus = execute('nmenu Buffers')
call assert_equal(len(split(orig_buffer_menus, "\n")), len(split(term_buffer_menus, "\n")))
call assert_equal(len(split(orig_buffer_menus, "\n")) + 2, len(split(term_buffer_menus, "\n")))
bwipe!
call assert_equal(orig_buffer_menus, execute("nmenu Buffers"))
endif
@ -155,6 +162,9 @@ endfunc
" Test for menu item completion in command line
func Test_menu_expand()
" Make sure we don't have stale menu items like Buffers menu.
source $VIMRUNTIME/delmenu.vim
" Create the menu itmes for test
menu Dummy.Nothing lll
for i in range(1, 4)

View File

@ -743,15 +743,19 @@ func Test_popup_and_previewwindow_dump()
let lines =<< trim END
set previewheight=9
silent! pedit
call setline(1, map(repeat(["ab"], 10), "v:val. v:key"))
call setline(1, map(repeat(["ab"], 10), "v:val .. v:key"))
exec "norm! G\<C-E>\<C-E>"
END
call writefile(lines, 'Xscript')
let buf = RunVimInTerminal('-S Xscript', {})
" wait for the script to finish
call term_wait(buf)
" Test that popup and previewwindow do not overlap.
call term_sendkeys(buf, "o\<C-X>\<C-N>")
sleep 100m
call term_sendkeys(buf, "o")
call term_wait(buf, 100)
call term_sendkeys(buf, "\<C-X>\<C-N>")
call VerifyScreenDump(buf, 'Test_popup_and_previewwindow_01', {})
call term_sendkeys(buf, "\<Esc>u")

View File

@ -2536,17 +2536,19 @@ func Test_term_nasty_callback()
let g:buf1 = term_start('sh', #{hidden: 1, term_finish: 'close'})
call popup_create(g:buf1, {})
let g:buf2 = term_start(['sh', '-c'], #{curwin: 1, exit_cb: function('TermExit')})
sleep 100m
call term_wait(g:buf2, 100)
call popup_close(win_getid())
endfunc
func TermExit(...)
call term_sendkeys(bufnr('#'), "exit\<CR>")
let altbuf = bufnr('#')
call term_sendkeys(altbuf, "exit\<CR>")
call term_wait(altbuf)
call popup_close(win_getid())
endfunc
call OpenTerms()
call term_sendkeys(g:buf0, "exit\<CR>")
sleep 100m
call term_wait(g:buf0, 100)
exe g:buf0 .. 'bwipe!'
set hidden&
endfunc

View File

@ -728,6 +728,13 @@ def Test_expr7_dict()
let val = 1
assert_equal(g:dict_one, {key: val})
call CheckDefFailure("let x = #{8: 8}", 'E1014:')
call CheckDefFailure("let x = #{xxx}", 'E720:')
call CheckDefFailure("let x = #{xxx: 1", 'E722:')
call CheckDefFailure("let x = #{xxx: 1,", 'E723:')
call CheckDefFailure("let x = {'a': xxx}", 'E1001:')
call CheckDefFailure("let x = {xxx: 8}", 'E1001:')
call CheckDefFailure("let x = #{a: 1, a: 2}", 'E721:')
call CheckDefExecFailure("let x = g:anint.member", 'E715:')
call CheckDefExecFailure("let x = g:dict_empty.member", 'E716:')
enddef
@ -750,6 +757,8 @@ def Test_expr7_environment()
" environment variable
assert_equal('testvar', $TESTVAR)
assert_equal('', $ASDF_ASD_XXX)
call CheckDefFailure("let x = $$$", 'E1002:')
enddef
def Test_expr7_register()
@ -802,22 +811,44 @@ func Test_expr7_fails()
call CheckDefFailure("let x = -'xx'", "E1030:")
call CheckDefFailure("let x = +'xx'", "E1030:")
call CheckDefFailure("let x = -0z12", "E974:")
call CheckDefExecFailure("let x = -[8]", "E39:")
call CheckDefExecFailure("let x = -{'a': 1}", "E39:")
call CheckDefFailure("let x = @", "E1002:")
call CheckDefFailure("let x = @<", "E354:")
call CheckDefFailure("let x = [1, 2", "E697:")
call CheckDefFailure("let x = [notfound]", "E1001:")
call CheckDefFailure("let x = { -> 123) }", "E451:")
call CheckDefFailure("let x = 123->{x -> x + 5) }", "E451:")
call CheckDefFailure("let x = &notexist", 'E113:')
call CheckDefExecFailure("&grepprg = [343]", 'E1051:')
call CheckDefExecFailure("echo s:doesnt_exist", 'E121:')
call CheckDefExecFailure("echo g:doesnt_exist", 'E121:')
call CheckDefFailure("echo a:somevar", 'E1075:')
call CheckDefFailure("echo l:somevar", 'E1075:')
call CheckDefFailure("echo x:somevar", 'E1075:')
" TODO
call CheckDefFailure("echo b:somevar", 'not supported yet')
call CheckDefFailure("echo w:somevar", 'not supported yet')
call CheckDefFailure("echo t:somevar", 'not supported yet')
call CheckDefExecFailure("let x = +g:astring", 'E1030:')
call CheckDefExecFailure("let x = +g:ablob", 'E974:')
call CheckDefExecFailure("let x = +g:alist", 'E745:')
call CheckDefExecFailure("let x = +g:adict", 'E728:')
call CheckDefFailureMult(["let x = ''", "let y = x.memb"], 'E715:')
call CheckDefExecFailure("[1, 2->len()", 'E492:')
call CheckDefExecFailure("#{a: 1->len()", 'E488:')
call CheckDefExecFailure("{'a': 1->len()", 'E492:')
endfunc
let g:Funcrefs = [function('add')]
@ -865,6 +896,7 @@ enddef
func Test_expr7_trailing_fails()
call CheckDefFailureList(['let l = [2]', 'l->{l -> add(l, 8)}'], 'E107')
call CheckDefFailureList(['let l = [2]', 'l->{l -> add(l, 8)} ()'], 'E274')
endfunc
func Test_expr_fails()
@ -878,4 +910,8 @@ func Test_expr_fails()
call CheckDefFailure("v:nosuch += 3", 'E1001:')
call CheckDefFailure("let v:version = 3", 'E1064:')
call CheckDefFailure("let asdf = v:nosuch", 'E1001:')
call CheckDefFailure("echo len('asdf'", 'E110:')
call CheckDefFailure("echo Func0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789()", 'E1011:')
call CheckDefFailure("echo doesnotexist()", 'E117:')
endfunc

View File

@ -101,6 +101,8 @@ func Test_assignment_failure()
call CheckDefFailure(['let true = 1'], 'E1034:')
call CheckDefFailure(['let false = 1'], 'E1034:')
call CheckScriptFailure(['vim9script', 'def Func()', 'let dummy = s:notfound', 'enddef'], 'E1050:')
call CheckDefFailure(['let var: list<string> = [123]'], 'expected list<string> but got list<number>')
call CheckDefFailure(['let var: list<number> = ["xx"]'], 'expected list<number> but got list<string>')
@ -112,6 +114,16 @@ func Test_assignment_failure()
call CheckDefFailure(['let var: dict <number>'], 'E1007:')
call CheckDefFailure(['let var: dict<number'], 'E1009:')
endfunc
func Test_wrong_type()
call CheckDefFailure(['let var: list<nothing>'], 'E1010:')
call CheckDefFailure(['let var: list<list<nothing>>'], 'E1010:')
call CheckDefFailure(['let var: dict<nothing>'], 'E1010:')
call CheckDefFailure(['let var: dict<dict<nothing>>'], 'E1010:')
call CheckDefFailure(['let var: dict<number'], 'E1009:')
call CheckDefFailure(['let var: dict<list<number>'], 'E1009:')
call CheckDefFailure(['let var: ally'], 'E1010:')
call CheckDefFailure(['let var: bram'], 'E1010:')
@ -436,6 +448,37 @@ def Test_vim9_import_export()
source Ximport.vim
assert_equal(9883, g:imported)
let import_star_as_lines_no_dot =<< trim END
vim9script
import * as Export from './Xexport.vim'
def Func()
let dummy = 1
let imported = Export + dummy
enddef
END
writefile(import_star_as_lines_no_dot, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1060:')
let import_star_as_lines_dot_space =<< trim END
vim9script
import * as Export from './Xexport.vim'
def Func()
let imported = Export . exported
enddef
END
writefile(import_star_as_lines_dot_space, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1074:')
let import_star_as_lines_missing_name =<< trim END
vim9script
import * as Export from './Xexport.vim'
def Func()
let imported = Export.
enddef
END
writefile(import_star_as_lines_missing_name, 'Ximport.vim')
assert_fails('source Ximport.vim', 'E1048:')
let import_star_lines =<< trim END
vim9script
import * from './Xexport.vim'
@ -577,6 +620,12 @@ def Test_vim9script_call()
enddef
{'a': 1, 'b': 2}->DictFunc()
assert_equal(#{a: 1, b: 2}, dictvar)
def CompiledDict()
{'a': 3, 'b': 4}->DictFunc()
enddef
CompiledDict()
assert_equal(#{a: 3, b: 4}, dictvar)
#{a: 3, b: 4}->DictFunc()
assert_equal(#{a: 3, b: 4}, dictvar)

View File

@ -350,7 +350,10 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
e = *arg;
*arg = skipwhite(*arg);
if (**arg != '}')
{
semsg(_("E451: Expected }: %s"), *arg);
goto errret;
}
++*arg;
if (evaluate)

View File

@ -738,6 +738,48 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
479,
/**/
478,
/**/
477,
/**/
476,
/**/
475,
/**/
474,
/**/
473,
/**/
472,
/**/
471,
/**/
470,
/**/
469,
/**/
468,
/**/
467,
/**/
466,
/**/
465,
/**/
464,
/**/
463,
/**/
462,
/**/
461,
/**/
460,
/**/
459,
/**/
458,
/**/

View File

@ -242,7 +242,7 @@ get_list_type(type_T *member_type, garray_T *type_list)
// Not a common type, create a new entry.
if (ga_grow(type_list, 1) == FAIL)
return FAIL;
return &t_any;
type = ((type_T *)type_list->ga_data) + type_list->ga_len;
++type_list->ga_len;
type->tt_type = VAR_LIST;
@ -269,7 +269,7 @@ get_dict_type(type_T *member_type, garray_T *type_list)
// Not a common type, create a new entry.
if (ga_grow(type_list, 1) == FAIL)
return FAIL;
return &t_any;
type = ((type_T *)type_list->ga_data) + type_list->ga_len;
++type_list->ga_len;
type->tt_type = VAR_DICT;
@ -1368,6 +1368,7 @@ skip_type(char_u *start)
parse_type_member(char_u **arg, type_T *type, garray_T *type_list)
{
type_T *member_type;
int prev_called_emsg = called_emsg;
if (**arg != '<')
{
@ -1380,11 +1381,9 @@ parse_type_member(char_u **arg, type_T *type, garray_T *type_list)
*arg = skipwhite(*arg + 1);
member_type = parse_type(arg, type_list);
if (member_type == NULL)
return type;
*arg = skipwhite(*arg);
if (**arg != '>')
if (**arg != '>' && called_emsg == prev_called_emsg)
{
emsg(_("E1009: Missing > after type"));
return type;
@ -1766,6 +1765,11 @@ compile_load_scriptvar(
return FAIL;
}
++p;
if (VIM_ISWHITE(*p))
{
emsg(_("E1074: no white space allowed after dot"));
return FAIL;
}
idx = find_exported(import->imp_sid, &p, &name_len, &ufunc, &type);
// TODO: what if it is a function?
@ -1806,11 +1810,15 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
char_u *name;
char_u *end = end_arg;
int res = FAIL;
int prev_called_emsg = called_emsg;
if (*(*arg + 1) == ':')
{
// load namespaced variable
name = vim_strnsave(*arg + 2, end - (*arg + 2));
if (end <= *arg + 2)
name = vim_strsave((char_u *)"[empty]");
else
name = vim_strnsave(*arg + 2, end - (*arg + 2));
if (name == NULL)
return FAIL;
@ -1828,9 +1836,24 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
{
res = compile_load_scriptvar(cctx, name, NULL, NULL, error);
}
else if (**arg == 'b')
{
semsg("Namespace b: not supported yet: %s", *arg);
goto theend;
}
else if (**arg == 'w')
{
semsg("Namespace w: not supported yet: %s", *arg);
goto theend;
}
else if (**arg == 't')
{
semsg("Namespace t: not supported yet: %s", *arg);
goto theend;
}
else
{
semsg("Namespace not supported yet: %s", *arg);
semsg("E1075: Namespace not supported: %s", *arg);
goto theend;
}
}
@ -1892,7 +1915,7 @@ compile_load(char_u **arg, char_u *end_arg, cctx_T *cctx, int error)
*arg = end;
theend:
if (res == FAIL && error)
if (res == FAIL && error && called_emsg == prev_called_emsg)
semsg(_(e_var_notfound), name);
vim_free(name);
return res;
@ -2055,6 +2078,7 @@ to_name_const_end(char_u *arg)
}
else if (p == arg && *arg == '#' && arg[1] == '{')
{
// Can be "#{a: 1}->Func()".
++p;
if (eval_dict(&p, &rettv, FALSE, TRUE) == FAIL)
p = arg;
@ -2063,6 +2087,8 @@ to_name_const_end(char_u *arg)
{
int ret = get_lambda_tv(&p, &rettv, FALSE);
// Can be "{x -> ret}()".
// Can be "{'a': 1}->Func()".
if (ret == NOTDONE)
ret = eval_dict(&p, &rettv, FALSE, FALSE);
if (ret != OK)
@ -2147,7 +2173,10 @@ compile_list(char_u **arg, cctx_T *cctx)
while (*p != ']')
{
if (*p == NUL)
{
semsg(_(e_list_end), *arg);
return FAIL;
}
if (compile_expr1(&p, cctx) == FAIL)
break;
++count;
@ -2173,7 +2202,7 @@ compile_lambda(char_u **arg, cctx_T *cctx)
ufunc_T *ufunc;
// Get the funcref in "rettv".
if (get_lambda_tv(arg, &rettv, TRUE) == FAIL)
if (get_lambda_tv(arg, &rettv, TRUE) != OK)
return FAIL;
ufunc = rettv.vval.v_partial->pt_func;
@ -5118,7 +5147,8 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
}
// "{" starts a block scope
if (*ea.cmd == '{')
// "{'a': 1}->func() is something else
if (*ea.cmd == '{' && ends_excmd(*skipwhite(ea.cmd + 1)))
{
line = compile_block(ea.cmd, &cctx);
continue;

View File

@ -1612,7 +1612,21 @@ call_def_function(
case ISN_NEGATENR:
tv = STACK_TV_BOT(-1);
tv->vval.v_number = -tv->vval.v_number;
if (tv->v_type != VAR_NUMBER
#ifdef FEAT_FLOAT
&& tv->v_type != VAR_FLOAT
#endif
)
{
emsg(_(e_number_exp));
goto failed;
}
#ifdef FEAT_FLOAT
if (tv->v_type == VAR_FLOAT)
tv->vval.v_float = -tv->vval.v_float;
else
#endif
tv->vval.v_number = -tv->vval.v_number;
break;
case ISN_CHECKNR: