mirror of
https://github.com/vim/vim
synced 2025-07-28 01:11:40 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
373c65104e | |||
7633fe595e | |||
38041da1c2 | |||
73fef33014 | |||
8d9437968b | |||
7fe875583b | |||
f5433fbfe4 | |||
da58134eed | |||
23c5527373 | |||
e55b1c098d | |||
820ffa567c | |||
a3b7fdc1bb | |||
8c524f76eb | |||
6797966dfc | |||
0cb5bcf583 | |||
845e0ee594 | |||
a190548e91 | |||
b326edf5b3 | |||
ef6746f637 | |||
280b0dc815 | |||
1089374130 | |||
7e380030c1 | |||
20298ce679 |
@ -8,6 +8,7 @@ cd src
|
||||
echo "Building MinGW 32bit console version"
|
||||
set PATH=c:\msys64\mingw32\bin;%PATH%
|
||||
mingw32-make.exe -f Make_ming.mak GUI=no OPTIMIZE=speed IME=yes ICONV=yes DEBUG=no FEATURES=%FEATURE% || exit 1
|
||||
.\vim -u NONE -c "redir @a | ver |0put a | wq" ver_ming.txt
|
||||
:: Save vim.exe before Make clean, moved back below.
|
||||
copy vim.exe testdir
|
||||
mingw32-make.exe -f Make_ming.mak clean
|
||||
@ -20,13 +21,14 @@ if "%FEATURE%" == "HUGE" (
|
||||
) ELSE (
|
||||
mingw32-make.exe -f Make_ming.mak OPTIMIZE=speed GUI=yes IME=yes ICONV=yes DEBUG=no FEATURES=%FEATURE% || exit 1
|
||||
)
|
||||
.\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_ming.txt
|
||||
.\gvim -u NONE -c "redir @a | ver |0put a | wq" ver_ming_gui.txt
|
||||
|
||||
:: Filter out the progress bar from the build log
|
||||
sed -e "s/@<<$/@<< | sed -e 's#.*\\\\r.*##'/" Make_mvc.mak > Make_mvc2.mak
|
||||
|
||||
echo "Building MSVC 64bit console Version"
|
||||
nmake -f Make_mvc2.mak CPU=AMD64 OLE=no GUI=no IME=yes ICONV=yes DEBUG=no FEATURES=%FEATURE% || exit 1
|
||||
:: The executable is not used
|
||||
nmake -f Make_mvc2.mak clean
|
||||
|
||||
:: build MSVC huge version with python and channel support
|
||||
@ -43,6 +45,8 @@ if "%FEATURE%" == "HUGE" (
|
||||
move /Y testdir\vim.exe .
|
||||
echo "version output MinGW"
|
||||
type ver_ming.txt
|
||||
echo "version output MinGW GUI"
|
||||
type ver_ming_gui.txt
|
||||
echo "version output MVC"
|
||||
type ver_msvc.txt
|
||||
cd ..
|
||||
|
@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.2. Last change: 2020 Jun 14
|
||||
*eval.txt* For Vim version 8.2. Last change: 2020 Jun 17
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -3667,7 +3667,7 @@ complete_info([{what}])
|
||||
"function" User defined completion |i_CTRL-X_CTRL-U|
|
||||
"omni" Omni completion |i_CTRL-X_CTRL-O|
|
||||
"spell" Spelling suggestions |i_CTRL-X_s|
|
||||
"eval" |complete()| completion
|
||||
"eval" |complete()| completion
|
||||
"unknown" Other internal modes
|
||||
|
||||
If the optional {what} list argument is supplied, then only
|
||||
@ -4536,7 +4536,7 @@ flatten({list} [, {maxdepth}]) *flatten()*
|
||||
a very large number.
|
||||
The {list} is changed in place, make a copy first if you do
|
||||
not want that.
|
||||
*E900*
|
||||
*E900*
|
||||
{maxdepth} means how deep in nested lists changes are made.
|
||||
{list} is not modified when {maxdepth} is 0.
|
||||
{maxdepth} must be positive number.
|
||||
@ -5163,7 +5163,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
|
||||
highlight highlight groups
|
||||
history :history suboptions
|
||||
locale locale names (as output of locale -a)
|
||||
mapclear buffer argument
|
||||
mapclear buffer argument
|
||||
mapping mapping name
|
||||
menu menus
|
||||
messages |:messages| suboptions
|
||||
@ -5189,7 +5189,7 @@ getcompletion({pat}, {type} [, {filtered}]) *getcompletion()*
|
||||
If {type} is "cmdline", then the |cmdline-completion| result is
|
||||
returned. For example, to complete the possible values after
|
||||
a ":call" command: >
|
||||
echo getcompletion('call ', 'cmdline')
|
||||
echo getcompletion('call ', 'cmdline')
|
||||
<
|
||||
If there are no matches, an empty list is returned. An
|
||||
invalid value for {type} produces an error.
|
||||
@ -5770,8 +5770,8 @@ getwininfo([{winid}]) *getwininfo()*
|
||||
Returns information about windows as a List with Dictionaries.
|
||||
|
||||
If {winid} is given Information about the window with that ID
|
||||
is returned. If the window does not exist the result is an
|
||||
empty list.
|
||||
is returned, as a List with one item. If the window does not
|
||||
exist the result is an empty list.
|
||||
|
||||
Without {winid} information about all the windows in all the
|
||||
tab pages is returned.
|
||||
@ -8606,14 +8606,14 @@ searchcount([{options}]) *searchcount()*
|
||||
if result.total > result.maxcount &&
|
||||
\ result.current > result.maxcount
|
||||
return printf(' /%s [>%d/>%d]', @/,
|
||||
\ result.current, result.total)
|
||||
\ result.current, result.total)
|
||||
elseif result.total > result.maxcount
|
||||
return printf(' /%s [%d/>%d]', @/,
|
||||
\ result.current, result.total)
|
||||
\ result.current, result.total)
|
||||
endif
|
||||
endif
|
||||
return printf(' /%s [%d/%d]', @/,
|
||||
\ result.current, result.total)
|
||||
\ result.current, result.total)
|
||||
endfunction
|
||||
let &statusline .= '%{LastSearchCount()}'
|
||||
|
||||
@ -9386,7 +9386,9 @@ simplify({filename}) *simplify()*
|
||||
Unix) are not resolved. If the first path component in
|
||||
{filename} designates the current directory, this will be
|
||||
valid for the result as well. A trailing path separator is
|
||||
not removed either.
|
||||
not removed either. On Unix "//path" is unchanged, but
|
||||
"///path" is simplified to "/path" (this follows the Posix
|
||||
standard).
|
||||
Example: >
|
||||
simplify("./dir/.././/file/") == "./file/"
|
||||
< Note: The combination "dir/.." is only removed if "dir" is
|
||||
@ -9696,7 +9698,7 @@ state([{what}]) *state()*
|
||||
m halfway a mapping, :normal command, feedkeys() or
|
||||
stuffed command
|
||||
o operator pending or waiting for a command argument,
|
||||
e.g. after |f|
|
||||
e.g. after |f|
|
||||
a Insert mode autocomplete active
|
||||
x executing an autocommand
|
||||
w blocked on waiting, e.g. ch_evalexpr(), ch_read() and
|
||||
@ -10450,9 +10452,9 @@ terminalprops() *terminalprops()*
|
||||
If the |+termresponse| feature is missing then the result is
|
||||
an empty dictionary.
|
||||
|
||||
If "cursor_style" is 'y' then |t_RS| will be send to request the
|
||||
If "cursor_style" is 'y' then |t_RS| will be sent to request the
|
||||
current cursor style.
|
||||
If "cursor_blink_mode" is 'y' then |t_RC| will be send to
|
||||
If "cursor_blink_mode" is 'y' then |t_RC| will be sent to
|
||||
request the cursor blink status.
|
||||
"cursor_style" and "cursor_blink_mode" are also set if |t_u7|
|
||||
is not empty, Vim will detect the working of sending |t_RS|
|
||||
@ -10916,7 +10918,7 @@ win_screenpos({nr}) *win_screenpos()*
|
||||
GetWinid()->win_screenpos()
|
||||
<
|
||||
win_splitmove({nr}, {target} [, {options}]) *win_splitmove()*
|
||||
Move the window {nr} to a new split of the window {target}.
|
||||
Move the window {nr} to a new split of the window {target}.
|
||||
This is similar to moving to {target}, creating a new window
|
||||
using |:split| but having the same contents as window {nr}, and
|
||||
then closing {nr}.
|
||||
|
@ -1,4 +1,4 @@
|
||||
*mlang.txt* For Vim version 8.2. Last change: 2019 May 05
|
||||
*mlang.txt* For Vim version 8.2. Last change: 2020 Jun 16
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
@ -3897,6 +3897,7 @@ E105 mbyte.txt /*E105*
|
||||
E107 eval.txt /*E107*
|
||||
E108 eval.txt /*E108*
|
||||
E109 eval.txt /*E109*
|
||||
E1094 vim9.txt /*E1094*
|
||||
E11 cmdline.txt /*E11*
|
||||
E110 eval.txt /*E110*
|
||||
E111 eval.txt /*E111*
|
||||
@ -5798,6 +5799,7 @@ coding-style develop.txt /*coding-style*
|
||||
col() eval.txt /*col()*
|
||||
coldfusion.vim syntax.txt /*coldfusion.vim*
|
||||
collapse tips.txt /*collapse*
|
||||
collate-variable eval.txt /*collate-variable*
|
||||
color-xterm syntax.txt /*color-xterm*
|
||||
coloring syntax.txt /*coloring*
|
||||
colortest.vim syntax.txt /*colortest.vim*
|
||||
@ -9723,6 +9725,7 @@ v:charconvert_from eval.txt /*v:charconvert_from*
|
||||
v:charconvert_to eval.txt /*v:charconvert_to*
|
||||
v:cmdarg eval.txt /*v:cmdarg*
|
||||
v:cmdbang eval.txt /*v:cmdbang*
|
||||
v:collate eval.txt /*v:collate*
|
||||
v:completed_item eval.txt /*v:completed_item*
|
||||
v:count eval.txt /*v:count*
|
||||
v:count1 eval.txt /*v:count1*
|
||||
|
@ -1,4 +1,4 @@
|
||||
*testing.txt* For Vim version 8.2. Last change: 2020 Jun 13
|
||||
*testing.txt* For Vim version 8.2. Last change: 2020 Jun 15
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.2. Last change: 2020 Jun 14
|
||||
*todo.txt* For Vim version 8.2. Last change: 2020 Jun 21
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -40,16 +40,16 @@ browser use: https://github.com/vim/vim/issues/1234
|
||||
|
||||
Include src/po/vim.pot ?
|
||||
|
||||
See if resizing a terminal can be fixed.
|
||||
|
||||
Vim9 script:
|
||||
Making everything work:
|
||||
- assignment to script var should check type
|
||||
- Compile: let [var, var] = expr
|
||||
share code for :let between compiled and uncompiled?
|
||||
- do not allow "let g:var = value", must drop "let"
|
||||
- Error for "g:var: string = 'value'"
|
||||
- Make func()->append('$') work - value is last argument, not first. #6305
|
||||
- possible memory leak in test_vim9_func through compile_nested_function.
|
||||
- memory leaks in test_vim9_expr
|
||||
- memory leaks in test_vim9_script
|
||||
- Test that a script-local function in Vim9 script cannot be deleted.
|
||||
- more return types depending on the first argument, like sort().
|
||||
- Check that when sourcing a Vim9 script, only the global items can be used.
|
||||
- Make "true" and "false" work in vim9script
|
||||
- Test that a function defined inside a :def function is local to that
|
||||
@ -240,10 +240,12 @@ Terminal emulator window:
|
||||
conversions.
|
||||
|
||||
Error numbers available:
|
||||
E489, E610, E611, E653, E856, E857, E861
|
||||
E489, E610, E611, E653, E856
|
||||
|
||||
Remove SPACE_IN_FILENAME ? It is only used for completion.
|
||||
|
||||
Patch to use collaction based sorting. (Christian Brabandt, #6229)
|
||||
|
||||
Can we detect true color support? https://gist.github.com/XVilka/8346728
|
||||
Try setting a color then request the current color, like using t_u7.
|
||||
|
||||
@ -272,6 +274,8 @@ The buffer list and windows are locked, no changes possible
|
||||
How about removing Atari MiNT support?
|
||||
src/Make_mint.mak, src/os_mint.h, matches with __MINT__
|
||||
|
||||
Patch to make :q work with local arglist. (Christian Brabandt, #6286)
|
||||
|
||||
Patch to fix drawing error with DirectX. (James Grant, #5688)
|
||||
Causes flicker on resizing. Workaround from Ken Takata.
|
||||
How about only setting the attribute when part of the Vim window is offscreen?
|
||||
@ -285,6 +289,8 @@ Motif: Build on Ubuntu can't enter any text in dialog text fields.
|
||||
Running test_gui and test_gui_init with Motif sometimes kills the window
|
||||
manager. Problem with Motif?
|
||||
|
||||
Patch to add :argdedupe. (Nir Lichtman, #6235)
|
||||
|
||||
:map output does not clear the reset of the command line.
|
||||
(#5623, also see #5962)
|
||||
|
||||
@ -1402,9 +1408,6 @@ the system encoding (usually utf-8).
|
||||
MS-Windows: use WS_HIDE instead of SW_SHOWMINNOACTIVE in os_win32.c?
|
||||
Otherwise task flickers in taskbar.
|
||||
|
||||
Should make ":@r" handle line continuation. (Cesar Romani, 2016 Jun 26)
|
||||
Also for ":@.".
|
||||
|
||||
Repeating 'opfunc' in a function only works once. (Tarmean, 2016 Jul 15, #925)
|
||||
|
||||
Have a way to get the call stack, in a function and from an exception.
|
||||
|
@ -211,7 +211,7 @@ will automatically delete it:
|
||||
- The flag that the file was modified is not set.
|
||||
- The process is not running.
|
||||
|
||||
You can programatically deal with this situation with the |FileChangedShell|
|
||||
You can programmatically deal with this situation with the |FileChangedShell|
|
||||
autocommand event.
|
||||
|
||||
|
||||
|
@ -112,7 +112,7 @@ Although it's shorter to do: >
|
||||
|
||||
Legacy Vim script does have type checking, but this happens at runtime, when
|
||||
the code is executed. And it's permissive, often a computation gives an
|
||||
unexpected value instead of reporting an error . Thus you can define a
|
||||
unexpected value instead of reporting an error. Thus you can define a
|
||||
function and think it's fine, but see a problem only later when it is called: >
|
||||
let s:collected = ''
|
||||
func ExtendAndReturn(add)
|
||||
@ -142,7 +142,7 @@ you did wrong: >
|
||||
|
||||
Vim9 script is strict, it uses the "+" operator only for numbers and floats.
|
||||
For string concatenation ".." must be used. This avoids mistakes and avoids
|
||||
the automatic conversion that gave a suprising result above. So you change
|
||||
the automatic conversion that gave a surprising result above. So you change
|
||||
the first line of the function to: >
|
||||
s:collected ..= add
|
||||
And now it works.
|
||||
|
@ -1,4 +1,4 @@
|
||||
*usr_toc.txt* For Vim version 8.2. Last change: 2020 Jun 11
|
||||
*usr_toc.txt* For Vim version 8.2. Last change: 2020 Jun 15
|
||||
|
||||
VIM USER MANUAL - by Bram Moolenaar
|
||||
|
||||
@ -340,6 +340,12 @@ Make Vim work as you like it.
|
||||
|45.4| Editing files with a different encoding
|
||||
|45.5| Entering language text
|
||||
|
||||
|usr_46.txt| Write plugins using Vim9 script
|
||||
|46.1| Introduction
|
||||
|46.2| Variable declarations
|
||||
|46.3| Functions and types
|
||||
|46.?| Using a Vim9 script from legacy script
|
||||
|
||||
==============================================================================
|
||||
Making Vim Run ~
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 14
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 21
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@ -30,7 +30,7 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
|
||||
|
||||
Vim script has been growing over time, while preserving backwards
|
||||
compatibility. That means bad choices from the past often can't be changed
|
||||
and compability with Vi restricts possible solutions. Execution is quite
|
||||
and compatibility with Vi restricts possible solutions. Execution is quite
|
||||
slow, each line is parsed every time it is executed.
|
||||
|
||||
The main goal of Vim9 script is to drastically improve performance. This is
|
||||
@ -68,7 +68,7 @@ In Vim script comments normally start with double quote. That can also be the
|
||||
start of a string, thus in many places it cannot be used. In Vim9 script a
|
||||
comment can also start with #. In Vi this is a command to list text with
|
||||
numbers, but you can also use `:number` for that. >
|
||||
let count = 0 # number of occurences
|
||||
let count = 0 # number of occurrences
|
||||
|
||||
To improve readability there must be a space between the command and the #
|
||||
that starts a comment. Note that #{ is the start of a dictionary, therefore
|
||||
@ -269,6 +269,13 @@ possible AFTER the operators. For example: >
|
||||
PosFunc(arg) :
|
||||
NegFunc(arg)
|
||||
|
||||
A special case is "->" for function call chains, it can appear in the next
|
||||
line: >
|
||||
let result = GetBuilder()
|
||||
->BuilderSetWidth(333)
|
||||
->BuilderSetHeight(777)
|
||||
->BuilderBuild()
|
||||
|
||||
Note that "enddef" cannot be used at the start of a continuation line, it ends
|
||||
the current function.
|
||||
|
||||
@ -566,7 +573,7 @@ defined (otherwise script-local) items: >
|
||||
|
||||
|
||||
Import ~
|
||||
*:import* *:imp*
|
||||
*:import* *:imp* *E1094*
|
||||
The exported items can be imported individually in another Vim9 script: >
|
||||
import EXPORTED_CONST from "thatscript.vim"
|
||||
import MyClass from "myclass.vim"
|
||||
@ -692,7 +699,7 @@ A, B and C, where A calls B, B calls C, and C calls A again. It's impossible
|
||||
to reorder the functions to avoid forward references.
|
||||
|
||||
An alternative would be to first scan through the file to locate items and
|
||||
figure out their type, so that forward refeferences are found, and only then
|
||||
figure out their type, so that forward references are found, and only then
|
||||
execute the script and compile the functions. This means the script has to be
|
||||
parsed twice, which is slower, and some conditions at the script level, such
|
||||
as checking if a feature is supported, are hard to use. An attempt was made
|
||||
|
@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2020 Jun 07
|
||||
" Last Change: 2020 Jun 15
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@ -237,7 +237,7 @@ au BufNewFile,BufRead */etc/blkid.tab,*/etc/blkid.tab.old setf xml
|
||||
au BufNewFile,BufRead *bsd,*.bsdl setf bsdl
|
||||
|
||||
" Bazel (http://bazel.io)
|
||||
autocmd BufRead,BufNewFile *.bzl,WORKSPACE,BUILD.bazel setf bzl
|
||||
autocmd BufRead,BufNewFile *.bzl,WORKSPACE,BUILD.bazel setf bzl
|
||||
if has("fname_case")
|
||||
" There is another check for BUILD further below.
|
||||
autocmd BufRead,BufNewFile BUILD setf bzl
|
||||
@ -625,8 +625,8 @@ au BufNewFile,BufRead *.mo,*.gdmo setf gdmo
|
||||
au BufNewFile,BufRead *.ged,lltxxxxx.txt setf gedcom
|
||||
|
||||
" Git
|
||||
au BufNewFile,BufRead COMMIT_EDITMSG,MERGE_MSG,TAG_EDITMSG setf gitcommit
|
||||
au BufNewFile,BufRead *.git/config,.gitconfig,/etc/gitconfig setf gitconfig
|
||||
au BufNewFile,BufRead COMMIT_EDITMSG,MERGE_MSG,TAG_EDITMSG setf gitcommit
|
||||
au BufNewFile,BufRead *.git/config,.gitconfig,/etc/gitconfig setf gitconfig
|
||||
au BufNewFile,BufRead */.config/git/config setf gitconfig
|
||||
au BufNewFile,BufRead .gitmodules,*.git/modules/*/config setf gitconfig
|
||||
if !empty($XDG_CONFIG_HOME)
|
||||
@ -770,11 +770,11 @@ au BufNewFile,BufRead *.inf,*.INF setf inform
|
||||
au BufNewFile,BufRead */etc/initng/*/*.i,*.ii setf initng
|
||||
|
||||
" Innovation Data Processing
|
||||
au BufRead,BufNewFile upstream.dat\c,upstream.*.dat\c,*.upstream.dat\c setf upstreamdat
|
||||
au BufRead,BufNewFile fdrupstream.log,upstream.log\c,upstream.*.log\c,*.upstream.log\c,UPSTREAM-*.log\c setf upstreamlog
|
||||
au BufRead,BufNewFile upstream.dat\c,upstream.*.dat\c,*.upstream.dat\c setf upstreamdat
|
||||
au BufRead,BufNewFile fdrupstream.log,upstream.log\c,upstream.*.log\c,*.upstream.log\c,UPSTREAM-*.log\c setf upstreamlog
|
||||
au BufRead,BufNewFile upstreaminstall.log\c,upstreaminstall.*.log\c,*.upstreaminstall.log\c setf upstreaminstalllog
|
||||
au BufRead,BufNewFile usserver.log\c,usserver.*.log\c,*.usserver.log\c setf usserverlog
|
||||
au BufRead,BufNewFile usw2kagt.log\c,usw2kagt.*.log\c,*.usw2kagt.log\c setf usw2kagtlog
|
||||
au BufRead,BufNewFile usserver.log\c,usserver.*.log\c,*.usserver.log\c setf usserverlog
|
||||
au BufRead,BufNewFile usw2kagt.log\c,usw2kagt.*.log\c,*.usw2kagt.log\c setf usw2kagtlog
|
||||
|
||||
" Ipfilter
|
||||
au BufNewFile,BufRead ipf.conf,ipf6.conf,ipf.rules setf ipfilter
|
||||
@ -1073,7 +1073,7 @@ au BufNewFile,BufRead Mutt{ng,}rc setf muttrc
|
||||
au BufRead,BufNewfile *.n1ql,*.nql setf n1ql
|
||||
|
||||
" Nano
|
||||
au BufNewFile,BufRead */etc/nanorc,*.nanorc setf nanorc
|
||||
au BufNewFile,BufRead */etc/nanorc,*.nanorc setf nanorc
|
||||
|
||||
" Nastran input/DMAP
|
||||
"au BufNewFile,BufRead *.dat setf nastran
|
||||
@ -1156,7 +1156,7 @@ au BufNewFile,BufRead *.dpr setf pascal
|
||||
au BufNewFile,BufRead *.pdf setf pdf
|
||||
|
||||
" PCMK - HAE - crm configure edit
|
||||
au BufNewFile,BufRead *.pcmk setf pcmk
|
||||
au BufNewFile,BufRead *.pcmk setf pcmk
|
||||
|
||||
" Perl
|
||||
if has("fname_case")
|
||||
@ -1646,10 +1646,10 @@ au BufNewFile,BufRead *.cm setf voscm
|
||||
|
||||
" Swift
|
||||
au BufNewFile,BufRead *.swift setf swift
|
||||
au BufNewFile,BufRead *.swift.gyb setf swiftgyb
|
||||
au BufNewFile,BufRead *.swift.gyb setf swiftgyb
|
||||
|
||||
" Swift Intermediate Language
|
||||
au BufNewFile,BufRead *.sil setf sil
|
||||
au BufNewFile,BufRead *.sil setf sil
|
||||
|
||||
" Sysctl
|
||||
au BufNewFile,BufRead */etc/sysctl.conf,*/etc/sysctl.d/*.conf setf sysctl
|
||||
@ -2066,7 +2066,7 @@ au BufNewFile,BufRead *fvwm2rc*
|
||||
au BufNewFile,BufRead */tmp/lltmp* call s:StarSetf('gedcom')
|
||||
|
||||
" Git
|
||||
au BufNewFile,BufRead */.gitconfig.d/*,/etc/gitconfig.d/* call s:StarSetf('gitconfig')
|
||||
au BufNewFile,BufRead */.gitconfig.d/*,/etc/gitconfig.d/* call s:StarSetf('gitconfig')
|
||||
|
||||
" Gitolite
|
||||
au BufNewFile,BufRead */gitolite-admin/conf/* call s:StarSetf('gitolite')
|
||||
|
@ -1,7 +1,7 @@
|
||||
" Vim filetype plugin
|
||||
" Language: Vim
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2020 May 17
|
||||
" Last Change: 2020 Jun 16
|
||||
|
||||
" Only do this when not done yet for this buffer
|
||||
if exists("b:did_ftplugin")
|
||||
@ -83,8 +83,7 @@ endif
|
||||
if exists("loaded_matchit")
|
||||
let b:match_ignorecase = 0
|
||||
let b:match_words =
|
||||
\ '\<fu\%[nction]\>:\<retu\%[rn]\>:\<endf\%[unction]\>,' .
|
||||
\ '\<def\>:\<retu\%[rn]\>:\<enddef\>,' .
|
||||
\ '\<\%(fu\%[nction]\|def\)\>:\<retu\%[rn]\>:\<\%(endf\%[unction]\|enddef\)\>,' .
|
||||
\ '\<\(wh\%[ile]\|for\)\>:\<brea\%[k]\>:\<con\%[tinue]\>:\<end\(w\%[hile]\|fo\%[r]\)\>,' .
|
||||
\ '\<if\>:\<el\%[seif]\>:\<en\%[dif]\>,' .
|
||||
\ '{:},' .
|
||||
|
@ -2,7 +2,7 @@
|
||||
" Header: "{{{
|
||||
" Maintainer: Bram Moolenaar
|
||||
" Original Author: Andy Wokula <anwoku@yahoo.de>
|
||||
" Last Change: 2019 Mar 20
|
||||
" Last Change: 2020 Jun 18
|
||||
" Version: 1.0
|
||||
" Description: HTML indent script with cached state for faster indenting on a
|
||||
" range of lines.
|
||||
@ -223,7 +223,7 @@ endfunc "}}}
|
||||
call s:AddITags(s:indent_tags, [
|
||||
\ 'a', 'abbr', 'acronym', 'address', 'b', 'bdo', 'big',
|
||||
\ 'blockquote', 'body', 'button', 'caption', 'center', 'cite', 'code',
|
||||
\ 'colgroup', 'del', 'dfn', 'dir', 'div', 'dl', 'em', 'fieldset', 'font',
|
||||
\ 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl', 'dt', 'em', 'fieldset', 'font',
|
||||
\ 'form', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'html',
|
||||
\ 'i', 'iframe', 'ins', 'kbd', 'label', 'legend', 'li',
|
||||
\ 'map', 'menu', 'noframes', 'noscript', 'object', 'ol',
|
||||
|
@ -23,4 +23,14 @@ bar">
|
||||
text
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dd>
|
||||
dd text
|
||||
</dd>
|
||||
<dt>
|
||||
dt text
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
|
||||
" END_INDENT
|
||||
|
@ -23,4 +23,14 @@
|
||||
text
|
||||
</div>
|
||||
|
||||
<dl>
|
||||
<dd>
|
||||
dd text
|
||||
</dd>
|
||||
<dt>
|
||||
dt text
|
||||
</dt>
|
||||
</dl>
|
||||
|
||||
|
||||
" END_INDENT
|
||||
|
@ -1,6 +1,6 @@
|
||||
" Vim plugin for showing matching parens
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2019 Oct 28
|
||||
" Last Change: 2020 Jun 18
|
||||
|
||||
" Exit quickly when:
|
||||
" - this plugin was already loaded (or disabled)
|
||||
@ -21,6 +21,7 @@ endif
|
||||
augroup matchparen
|
||||
" Replace all matchparen autocommands
|
||||
autocmd! CursorMoved,CursorMovedI,WinEnter * call s:Highlight_Matching_Pair()
|
||||
autocmd! WinLeave * call s:Remove_Matches()
|
||||
if exists('##TextChanged')
|
||||
autocmd! TextChanged,TextChangedI * call s:Highlight_Matching_Pair()
|
||||
endif
|
||||
@ -38,10 +39,7 @@ set cpo-=C
|
||||
" for any matching paren.
|
||||
func s:Highlight_Matching_Pair()
|
||||
" Remove any previous match.
|
||||
if exists('w:paren_hl_on') && w:paren_hl_on
|
||||
silent! call matchdelete(3)
|
||||
let w:paren_hl_on = 0
|
||||
endif
|
||||
call s:Remove_Matches()
|
||||
|
||||
" Avoid that we remove the popup menu.
|
||||
" Return when there are no colors (looks like the cursor jumps).
|
||||
@ -195,6 +193,14 @@ func s:Highlight_Matching_Pair()
|
||||
endif
|
||||
endfunction
|
||||
|
||||
func s:Remove_Matches()
|
||||
if exists('w:paren_hl_on') && w:paren_hl_on
|
||||
silent! call matchdelete(3)
|
||||
let w:paren_hl_on = 0
|
||||
endif
|
||||
endfunc
|
||||
|
||||
|
||||
" Define commands that will disable and enable the plugin.
|
||||
command DoMatchParen call s:DoMatchParen()
|
||||
command NoMatchParen call s:NoMatchParen()
|
||||
|
@ -253,7 +253,7 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
|
||||
return FAIL;
|
||||
|
||||
if (partial->pt_func != NULL
|
||||
&& partial->pt_func->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
&& partial->pt_func->uf_def_status != UF_NOT_COMPILED)
|
||||
{
|
||||
if (call_def_function(partial->pt_func, argc, argv,
|
||||
partial, rettv) == FAIL)
|
||||
|
@ -6002,11 +6002,11 @@ static int srand_seed_for_testing_is_used = FALSE;
|
||||
f_test_srand_seed(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
if (argvars[0].v_type == VAR_UNKNOWN)
|
||||
srand_seed_for_testing_is_used = FALSE;
|
||||
srand_seed_for_testing_is_used = FALSE;
|
||||
else
|
||||
{
|
||||
srand_seed_for_testing = (UINT32_T)tv_get_number(&argvars[0]);
|
||||
srand_seed_for_testing_is_used = TRUE;
|
||||
srand_seed_for_testing = (UINT32_T)tv_get_number(&argvars[0]);
|
||||
srand_seed_for_testing_is_used = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -6019,7 +6019,7 @@ init_srand(UINT32_T *x)
|
||||
|
||||
if (srand_seed_for_testing_is_used)
|
||||
{
|
||||
*x = srand_seed_for_testing;
|
||||
*x = srand_seed_for_testing;
|
||||
return;
|
||||
}
|
||||
#ifndef MSWIN
|
||||
@ -7268,6 +7268,37 @@ f_setpos(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Translate a register type string to the yank type and block length
|
||||
*/
|
||||
static int
|
||||
get_yank_type(char_u **pp, char_u *yank_type, long *block_len)
|
||||
{
|
||||
char_u *stropt = *pp;
|
||||
switch (*stropt)
|
||||
{
|
||||
case 'v': case 'c': // character-wise selection
|
||||
*yank_type = MCHAR;
|
||||
break;
|
||||
case 'V': case 'l': // line-wise selection
|
||||
*yank_type = MLINE;
|
||||
break;
|
||||
case 'b': case Ctrl_V: // block-wise selection
|
||||
*yank_type = MBLOCK;
|
||||
if (VIM_ISDIGIT(stropt[1]))
|
||||
{
|
||||
++stropt;
|
||||
*block_len = getdigits(&stropt) - 1;
|
||||
--stropt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FAIL;
|
||||
}
|
||||
*pp = stropt;
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* "setreg()" function
|
||||
*/
|
||||
@ -7302,30 +7333,31 @@ f_setreg(typval_T *argvars, typval_T *rettv)
|
||||
if (argvars[1].v_type == VAR_DICT)
|
||||
{
|
||||
dict_T *d = argvars[1].vval.v_dict;
|
||||
dictitem_T *di = dict_find(d, (char_u *)"regcontents", -1);
|
||||
dictitem_T *di;
|
||||
|
||||
if (d == NULL || d->dv_hashtab.ht_used == 0)
|
||||
{
|
||||
// Empty dict, clear the register (like setreg(0, []))
|
||||
char_u *lstval[2] = {NULL, NULL};
|
||||
write_reg_contents_lst(regname, lstval, 0, FALSE, MAUTO, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
di = dict_find(d, (char_u *)"regcontents", -1);
|
||||
if (di != NULL)
|
||||
regcontents = &di->di_tv;
|
||||
|
||||
stropt = dict_get_string(d, (char_u *)"regtype", FALSE);
|
||||
if (stropt != NULL)
|
||||
switch (*stropt)
|
||||
{
|
||||
int ret = get_yank_type(&stropt, &yank_type, &block_len);
|
||||
|
||||
if (ret == FAIL || *++stropt != NUL)
|
||||
{
|
||||
case 'v': // character-wise selection
|
||||
yank_type = MCHAR;
|
||||
break;
|
||||
case 'V': // line-wise selection
|
||||
yank_type = MLINE;
|
||||
break;
|
||||
case Ctrl_V: // block-wise selection
|
||||
yank_type = MBLOCK;
|
||||
if (VIM_ISDIGIT(stropt[1]))
|
||||
{
|
||||
++stropt;
|
||||
block_len = getdigits(&stropt) - 1;
|
||||
--stropt;
|
||||
}
|
||||
break;
|
||||
semsg(_(e_invargval), "value");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (regname == '"')
|
||||
{
|
||||
@ -7344,6 +7376,12 @@ f_setreg(typval_T *argvars, typval_T *rettv)
|
||||
|
||||
if (argvars[2].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
if (yank_type != MAUTO)
|
||||
{
|
||||
semsg(_(e_toomanyarg), "setreg");
|
||||
return;
|
||||
}
|
||||
|
||||
stropt = tv_get_string_chk(&argvars[2]);
|
||||
if (stropt == NULL)
|
||||
return; // type error
|
||||
@ -7353,21 +7391,8 @@ f_setreg(typval_T *argvars, typval_T *rettv)
|
||||
case 'a': case 'A': // append
|
||||
append = TRUE;
|
||||
break;
|
||||
case 'v': case 'c': // character-wise selection
|
||||
yank_type = MCHAR;
|
||||
break;
|
||||
case 'V': case 'l': // line-wise selection
|
||||
yank_type = MLINE;
|
||||
break;
|
||||
case 'b': case Ctrl_V: // block-wise selection
|
||||
yank_type = MBLOCK;
|
||||
if (VIM_ISDIGIT(stropt[1]))
|
||||
{
|
||||
++stropt;
|
||||
block_len = getdigits(&stropt) - 1;
|
||||
--stropt;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
get_yank_type(&stropt, &yank_type, &block_len);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1204,6 +1204,13 @@ ex_let_one(
|
||||
emsg(_("E996: Cannot lock an environment variable"));
|
||||
return NULL;
|
||||
}
|
||||
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
|
||||
&& (flags & LET_NO_COMMAND) == 0)
|
||||
{
|
||||
vim9_declare_error(arg);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Find the end of the name.
|
||||
++arg;
|
||||
name = arg;
|
||||
@ -2628,7 +2635,7 @@ find_var_ht(char_u *name, char_u **varname)
|
||||
if (*name == 'v') // v: variable
|
||||
return &vimvarht;
|
||||
if (get_current_funccal() != NULL
|
||||
&& get_current_funccal()->func->uf_dfunc_idx == UF_NOT_COMPILED)
|
||||
&& get_current_funccal()->func->uf_def_status == UF_NOT_COMPILED)
|
||||
{
|
||||
// a: and l: are only used in functions defined with ":function"
|
||||
if (*name == 'a') // a: function argument
|
||||
@ -2866,6 +2873,15 @@ set_var_const(
|
||||
}
|
||||
is_script_local = ht == get_script_local_ht();
|
||||
|
||||
if (current_sctx.sc_version == SCRIPT_VERSION_VIM9
|
||||
&& !is_script_local
|
||||
&& (flags & LET_NO_COMMAND) == 0
|
||||
&& name[1] == ':')
|
||||
{
|
||||
vim9_declare_error(name);
|
||||
return;
|
||||
}
|
||||
|
||||
di = find_var_in_ht(ht, 0, varname, TRUE);
|
||||
|
||||
// Search in parent scope which is possible to reference from lambda
|
||||
|
@ -1788,6 +1788,8 @@ EXTERN char e_no_white_before[] INIT(= N_("E1068: No white space allowed before
|
||||
EXTERN char e_lock_unlock[] INIT(= N_("E940: Cannot lock or unlock variable %s"));
|
||||
EXTERN char e_const_req_value[] INIT(= N_("E1021: const requires a value"));
|
||||
EXTERN char e_type_req[] INIT(= N_("E1022: type or initialization required"));
|
||||
EXTERN char e_declare_var[] INIT(= N_("E1016: Cannot declare a %s variable: %s"));
|
||||
EXTERN char e_declare_env_var[] INIT(= N_("E1016: Cannot declare an environment variable: %s"));
|
||||
#endif
|
||||
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
|
||||
EXTERN char e_alloc_color[] INIT(= N_("E254: Cannot allocate color %s"));
|
||||
|
@ -1211,15 +1211,19 @@ key_press_event(GtkWidget *widget UNUSED,
|
||||
if (len == 0) // Unrecognized key
|
||||
return TRUE;
|
||||
|
||||
// Handle modifiers.
|
||||
modifiers = modifiers_gdk2vim(state);
|
||||
|
||||
// For some keys a shift modifier is translated into another key code.
|
||||
if (len == -3)
|
||||
key = TO_SPECIAL(string[1], string[2]);
|
||||
else
|
||||
key = string[0];
|
||||
{
|
||||
string[len] = NUL;
|
||||
key = mb_ptr2char(string);
|
||||
}
|
||||
|
||||
// Handle modifiers.
|
||||
modifiers = modifiers_gdk2vim(state);
|
||||
|
||||
// Recognize special keys.
|
||||
key = simplify_key(key, &modifiers);
|
||||
if (key == CSI)
|
||||
key = K_CSI;
|
||||
@ -1235,8 +1239,11 @@ key_press_event(GtkWidget *widget UNUSED,
|
||||
// <C-H> and <C-h> mean the same thing, always use "H"
|
||||
if ((modifiers & MOD_MASK_CTRL) && ASCII_ISALPHA(key))
|
||||
key = TOUPPER_ASC(key);
|
||||
string[0] = key;
|
||||
len = 1;
|
||||
|
||||
// May remove the shift modifier if it's included in the key.
|
||||
modifiers = may_remove_shift_modifier(modifiers, key);
|
||||
|
||||
len = mb_char2bytes(key, string);
|
||||
}
|
||||
|
||||
if (modifiers != 0)
|
||||
|
@ -938,7 +938,10 @@ gui_x11_key_hit_cb(
|
||||
if (len == -3)
|
||||
key = TO_SPECIAL(string[1], string[2]);
|
||||
else
|
||||
key = string[0];
|
||||
{
|
||||
string[len] = NUL;
|
||||
key = mb_ptr2char(string);
|
||||
}
|
||||
key = simplify_key(key, &modifiers);
|
||||
if (key == CSI)
|
||||
key = K_CSI;
|
||||
@ -951,8 +954,7 @@ gui_x11_key_hit_cb(
|
||||
}
|
||||
else
|
||||
{
|
||||
string[0] = key;
|
||||
len = 1;
|
||||
len = mb_char2bytes(key, string);
|
||||
|
||||
// Remove the SHIFT modifier for keys where it's already included,
|
||||
// e.g., '(', '!' and '*'.
|
||||
|
@ -658,6 +658,11 @@ S_SvREFCNT_dec(pTHX_ SV *sv)
|
||||
}
|
||||
# endif
|
||||
|
||||
/* perl-5.32 needs Perl_SvREFCNT_dec */
|
||||
# if (PERL_REVISION == 5) && (PERL_VERSION >= 32)
|
||||
# define Perl_SvREFCNT_dec S_SvREFCNT_dec
|
||||
# endif
|
||||
|
||||
/* perl-5.26 also needs S_TOPMARK and S_POPMARK. */
|
||||
# if (PERL_REVISION == 5) && (PERL_VERSION >= 26)
|
||||
PERL_STATIC_INLINE I32
|
||||
@ -682,6 +687,20 @@ S_POPMARK(pTHX)
|
||||
}
|
||||
# endif
|
||||
|
||||
/* perl-5.32 needs Perl_POPMARK */
|
||||
# if (PERL_REVISION == 5) && (PERL_VERSION >= 32)
|
||||
# define Perl_POPMARK S_POPMARK
|
||||
|
||||
/* perl-5.32 needs Perl_SvTRUE */
|
||||
PERL_STATIC_INLINE bool
|
||||
Perl_SvTRUE(pTHX_ SV *sv) {
|
||||
if (!LIKELY(sv))
|
||||
return FALSE;
|
||||
SvGETMAGIC(sv);
|
||||
return SvTRUE_nomg_NN(sv);
|
||||
}
|
||||
# endif
|
||||
|
||||
/*
|
||||
* Make all runtime-links of perl.
|
||||
*
|
||||
|
@ -646,6 +646,12 @@ static int setlineinfo(int row, const VTermLineInfo *newinfo, const VTermLineInf
|
||||
newinfo->doubleheight != oldinfo->doubleheight) {
|
||||
for(col = 0; col < screen->cols; col++) {
|
||||
ScreenCell *cell = getcell(screen, row, col);
|
||||
if (cell == NULL)
|
||||
{
|
||||
DEBUG_LOG2("libvterm: setlineinfo() position invalid: %d / %d",
|
||||
row, col);
|
||||
return 1;
|
||||
}
|
||||
cell->pen.dwl = newinfo->doublewidth;
|
||||
cell->pen.dhl = newinfo->doubleheight;
|
||||
}
|
||||
@ -773,6 +779,12 @@ static size_t _get_chars(const VTermScreen *screen, const int utf8, void *buffer
|
||||
ScreenCell *cell = getcell(screen, row, col);
|
||||
int i;
|
||||
|
||||
if (cell == NULL)
|
||||
{
|
||||
DEBUG_LOG2("libvterm: _get_chars() position invalid: %d / %d",
|
||||
row, col);
|
||||
return 1;
|
||||
}
|
||||
if(cell->chars[0] == 0)
|
||||
// Erased cell, might need a space
|
||||
padding++;
|
||||
|
@ -17,11 +17,6 @@ static void putglyph(VTermState *state, const uint32_t chars[], int width, VTerm
|
||||
{
|
||||
VTermGlyphInfo info;
|
||||
|
||||
if (pos.row >= state->rows)
|
||||
{
|
||||
DEBUG_LOG2("libvterm: putglyph() pos.row %d out of range (rows = %d)\n", pos.row, state.rows);
|
||||
return;
|
||||
}
|
||||
info.chars = chars;
|
||||
info.width = width;
|
||||
info.protected_cell = state->protected_cell;
|
||||
@ -289,11 +284,6 @@ static int on_text(const char bytes[], size_t len, void *user)
|
||||
|
||||
VTermPos oldpos = state->pos;
|
||||
|
||||
if (state->pos.row >= state->rows)
|
||||
{
|
||||
DEBUG_LOG2("libvterm: on_text() pos.row %d out of range (rows = %d)\n", state->pos.row, state->rows);
|
||||
return 0;
|
||||
}
|
||||
// We'll have at most len codepoints, plus one from a previous incomplete
|
||||
// sequence.
|
||||
codepoints = vterm_allocator_malloc(state->vt, (len + 1) * sizeof(uint32_t));
|
||||
@ -1856,8 +1846,12 @@ static int on_resize(int rows, int cols, void *user)
|
||||
|
||||
if(state->pos.row >= rows)
|
||||
state->pos.row = rows - 1;
|
||||
if(state->pos.row < 0)
|
||||
state->pos.row = 0;
|
||||
if(state->pos.col >= cols)
|
||||
state->pos.col = cols - 1;
|
||||
if(state->pos.col < 0)
|
||||
state->pos.col = 0;
|
||||
|
||||
updatecursor(state, &oldpos, 1);
|
||||
|
||||
|
27
src/misc2.c
27
src/misc2.c
@ -2910,6 +2910,25 @@ find_special_key(
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Some keys already have Shift included, pass them as normal keys.
|
||||
* Not when Ctrl is also used, because <C-H> and <C-S-H> are different.
|
||||
* Also for <A-S-a> and <M-S-a>.
|
||||
*/
|
||||
int
|
||||
may_remove_shift_modifier(int modifiers, int key)
|
||||
{
|
||||
if ((modifiers == MOD_MASK_SHIFT
|
||||
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
|
||||
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
|
||||
&& ((key >= '@' && key <= 'Z')
|
||||
|| key == '^' || key == '_'
|
||||
|| (key >= '{' && key <= '~')))
|
||||
return modifiers & ~MOD_MASK_SHIFT;
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to include modifiers in the key.
|
||||
* Changes "Shift-a" to 'A', "Alt-A" to 0xc0, etc.
|
||||
@ -2929,9 +2948,11 @@ extract_modifiers(int key, int *modp, int simplify, int *did_simplify)
|
||||
if ((modifiers & MOD_MASK_SHIFT) && ASCII_ISALPHA(key))
|
||||
{
|
||||
key = TOUPPER_ASC(key);
|
||||
// With <C-S-a> and <A-S-a> we keep the shift modifier.
|
||||
// With <S-a> and <S-A> we don't keep the shift modifier.
|
||||
if (simplify || modifiers == MOD_MASK_SHIFT)
|
||||
// With <C-S-a> we keep the shift modifier.
|
||||
// With <S-a>, <A-S-a> and <S-A> we don't keep the shift modifier.
|
||||
if (simplify || modifiers == MOD_MASK_SHIFT
|
||||
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_ALT)
|
||||
|| modifiers == (MOD_MASK_SHIFT | MOD_MASK_META))
|
||||
modifiers &= ~MOD_MASK_SHIFT;
|
||||
}
|
||||
|
||||
|
@ -71,6 +71,7 @@ char_u *get_special_key_name(int c, int modifiers);
|
||||
int trans_special(char_u **srcp, char_u *dst, int flags, int *did_simplify);
|
||||
int special_to_buf(int key, int modifiers, int keycode, char_u *dst);
|
||||
int find_special_key(char_u **srcp, int *modp, int flags, int *did_simplify);
|
||||
int may_remove_shift_modifier(int modifiers, int key);
|
||||
int extract_modifiers(int key, int *modp, int simplify, int *did_simplify);
|
||||
int find_special_key_in_table(int c);
|
||||
int get_special_key_code(char_u *name);
|
||||
|
@ -10,10 +10,11 @@ int get_script_item_idx(int sid, char_u *name, int check_writable);
|
||||
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
|
||||
char_u *to_name_const_end(char_u *arg);
|
||||
int assignment_len(char_u *p, int *heredoc);
|
||||
void vim9_declare_error(char_u *name);
|
||||
int check_vim9_unlet(char_u *name);
|
||||
int compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx);
|
||||
void set_function_type(ufunc_T *ufunc);
|
||||
void delete_instr(isn_T *isn);
|
||||
void delete_def_function(ufunc_T *ufunc);
|
||||
void clear_def_function(ufunc_T *ufunc);
|
||||
void free_def_functions(void);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -1873,7 +1873,7 @@ ex_scriptversion(exarg_T *eap UNUSED)
|
||||
nr = getdigits(&eap->arg);
|
||||
if (nr == 0 || *eap->arg != NUL)
|
||||
emsg(_(e_invarg));
|
||||
else if (nr > 4)
|
||||
else if (nr > SCRIPT_VERSION_MAX)
|
||||
semsg(_("E999: scriptversion not supported: %d"), nr);
|
||||
else
|
||||
{
|
||||
|
@ -67,6 +67,8 @@ typedef struct terminal_S term_T;
|
||||
typedef struct VimMenu vimmenu_T;
|
||||
#endif
|
||||
|
||||
// maximum value for sc_version
|
||||
#define SCRIPT_VERSION_MAX 4
|
||||
// value for sc_version in a Vim9 script file
|
||||
#define SCRIPT_VERSION_VIM9 999999
|
||||
|
||||
@ -1531,8 +1533,11 @@ struct blobvar_S
|
||||
typedef struct funccall_S funccall_T;
|
||||
|
||||
// values used for "uf_dfunc_idx"
|
||||
# define UF_NOT_COMPILED -2
|
||||
# define UF_TO_BE_COMPILED -1
|
||||
typedef enum {
|
||||
UF_NOT_COMPILED,
|
||||
UF_TO_BE_COMPILED,
|
||||
UF_COMPILED
|
||||
} def_status_T;
|
||||
|
||||
/*
|
||||
* Structure to hold info for a user function.
|
||||
@ -1543,7 +1548,8 @@ typedef struct
|
||||
int uf_flags; // FC_ flags
|
||||
int uf_calls; // nr of active calls
|
||||
int uf_cleared; // func_clear() was already called
|
||||
int uf_dfunc_idx; // UF_NOT_COMPILED, UF_TO_BE_COMPILED or >= 0
|
||||
def_status_T uf_def_status; // UF_NOT_COMPILED, UF_TO_BE_COMPILED, etc.
|
||||
int uf_dfunc_idx; // only valid if uf_def_status is UF_COMPILED
|
||||
garray_T uf_args; // arguments, including optional arguments
|
||||
garray_T uf_def_args; // default argument expressions
|
||||
|
||||
|
10
src/term.c
10
src/term.c
@ -4769,14 +4769,8 @@ handle_key_with_modifier(
|
||||
|
||||
modifiers = decode_modifiers(arg[1]);
|
||||
|
||||
// Some keys already have Shift included, pass them as
|
||||
// normal keys. Not when Ctrl is also used, because <C-H>
|
||||
// and <C-S-H> are different.
|
||||
if (modifiers == MOD_MASK_SHIFT
|
||||
&& ((key >= '@' && key <= 'Z')
|
||||
|| key == '^' || key == '_'
|
||||
|| (key >= '{' && key <= '~')))
|
||||
modifiers = 0;
|
||||
// May remove the shift modifier if it's already included in the key.
|
||||
modifiers = may_remove_shift_modifier(modifiers, key);
|
||||
|
||||
// When used with Ctrl we always make a letter upper case,
|
||||
// so that mapping <C-H> and <C-h> are the same. Typing
|
||||
|
@ -216,7 +216,15 @@ func RunTheTest(test)
|
||||
|
||||
let message = 'Executed ' . a:test
|
||||
if has('reltime')
|
||||
let message ..= ' in ' .. reltimestr(reltime(func_start)) .. ' seconds'
|
||||
let message ..= repeat(' ', 50 - len(message))
|
||||
let time = reltime(func_start)
|
||||
if has('float') && reltimefloat(time) > 0.1
|
||||
let message = &t_md .. message
|
||||
endif
|
||||
let message ..= ' in ' .. reltimestr(time) .. ' seconds'
|
||||
if has('float') && reltimefloat(time) > 0.1
|
||||
let message ..= &t_me
|
||||
endif
|
||||
endif
|
||||
call add(s:messages, message)
|
||||
let s:done += 1
|
||||
@ -284,7 +292,9 @@ func FinishTesting()
|
||||
let message = 'Executed ' . s:done . (s:done > 1 ? ' tests' : ' test')
|
||||
endif
|
||||
if s:done > 0 && has('reltime')
|
||||
let message = &t_md .. message .. repeat(' ', 40 - len(message))
|
||||
let message ..= ' in ' .. reltimestr(reltime(s:start_time)) .. ' seconds'
|
||||
let message ..= &t_me
|
||||
endif
|
||||
echo message
|
||||
call add(s:messages, message)
|
||||
|
@ -254,6 +254,7 @@ func Test_blob_func_remove()
|
||||
call assert_fails("call remove(b, 3, 2)", 'E979:')
|
||||
call assert_fails("call remove(1, 0)", 'E896:')
|
||||
call assert_fails("call remove(b, b)", 'E974:')
|
||||
call assert_fails("call remove(b, 1, [])", 'E745:')
|
||||
call assert_fails("call remove(test_null_blob(), 1, 2)", 'E979:')
|
||||
endfunc
|
||||
|
||||
|
@ -246,6 +246,7 @@ func Test_cpo_H()
|
||||
endfunc
|
||||
|
||||
" TODO: Add a test for the 'i' flag in 'cpo'
|
||||
" Interrupting the reading of a file will leave it modified.
|
||||
|
||||
" Test for the 'I' flag in 'cpo' (deleting autoindent when using arrow keys)
|
||||
func Test_cpo_I()
|
||||
@ -294,9 +295,12 @@ func Test_cpo_J()
|
||||
let &cpo = save_cpo
|
||||
endfunc
|
||||
|
||||
" TODO: Add a test for the 'k' flag in 'cpo'
|
||||
" TODO: Add a test for the 'k' flag in 'cpo'.
|
||||
" Disable the recognition of raw key codes in mappings, abbreviations, and the
|
||||
" "to" part of menu commands.
|
||||
|
||||
" TODO: Add a test for the 'K' flag in 'cpo'
|
||||
" TODO: Add a test for the 'K' flag in 'cpo'.
|
||||
" Don't wait for a key code to complete when it is halfway a mapping.
|
||||
|
||||
" Test for the 'l' flag in 'cpo' (backslash in a [] range)
|
||||
func Test_cpo_l()
|
||||
@ -334,7 +338,9 @@ func Test_cpo_L()
|
||||
let &cpo = save_cpo
|
||||
endfunc
|
||||
|
||||
" TODO: Add a test for the 'm' flag in 'cpo'
|
||||
" TODO: Add a test for the 'm' flag in 'cpo'.
|
||||
" When included, a showmatch will always wait half a second. When not
|
||||
" included, a showmatch will wait half a second or until a character is typed.
|
||||
|
||||
" Test for the 'M' flag in 'cpo' (% with escape parenthesis)
|
||||
func Test_cpo_M()
|
||||
@ -498,7 +504,9 @@ func Test_cpo_R()
|
||||
let &cpo = save_cpo
|
||||
endfunc
|
||||
|
||||
" TODO: Add a test for the 's' flag in 'cpo'
|
||||
" TODO: Add a test for the 's' flag in 'cpo'.
|
||||
" Set buffer options when entering the buffer for the first time. If not
|
||||
" present the options are set when the buffer is created.
|
||||
|
||||
" Test for the 'S' flag in 'cpo' (copying buffer options)
|
||||
func Test_cpo_S()
|
||||
@ -543,8 +551,8 @@ func Test_cpo_u()
|
||||
let &cpo = save_cpo
|
||||
endfunc
|
||||
|
||||
" TODO: Add a test for the 'v' flag in 'cpo' (backspace doesn't remove
|
||||
" characters from the screen)
|
||||
" TODO: Add a test for the 'v' flag in 'cpo'.
|
||||
" Backspaced characters remain visible on the screen in Insert mode.
|
||||
|
||||
" Test for the 'w' flag in 'cpo' ('cw' on a blank character changes only one
|
||||
" character)
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
source check.vim
|
||||
CheckFeature digraphs
|
||||
source term_util.vim
|
||||
|
||||
func Put_Dig(chars)
|
||||
exe "norm! o\<c-k>".a:chars
|
||||
@ -502,4 +503,20 @@ func Test_loadkeymap_error()
|
||||
call delete('Xkeymap')
|
||||
endfunc
|
||||
|
||||
" Test for the characters displayed on the screen when entering a digraph
|
||||
func Test_entering_digraph()
|
||||
CheckRunVimInTerminal
|
||||
let buf = RunVimInTerminal('', {'rows': 6})
|
||||
call term_sendkeys(buf, "i\<C-K>")
|
||||
call term_wait(buf)
|
||||
call assert_equal('?', term_getline(buf, 1))
|
||||
call term_sendkeys(buf, "1")
|
||||
call term_wait(buf)
|
||||
call assert_equal('1', term_getline(buf, 1))
|
||||
call term_sendkeys(buf, "2")
|
||||
call term_wait(buf)
|
||||
call assert_equal('½', term_getline(buf, 1))
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -401,6 +401,14 @@ func Test_edit_13()
|
||||
call assert_equal("", getline(2))
|
||||
call assert_equal(" baz", getline(3))
|
||||
set autoindent&
|
||||
|
||||
" pressing <C-U> to erase line should keep the indent with 'autoindent'
|
||||
set backspace=2 autoindent
|
||||
%d
|
||||
exe "normal i\tone\<CR>three\<C-U>two"
|
||||
call assert_equal(["\tone", "\ttwo"], getline(1, '$'))
|
||||
set backspace& autoindent&
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
@ -1301,9 +1309,7 @@ endfunc
|
||||
|
||||
func Test_edit_rightleft()
|
||||
" Cursor in rightleft mode moves differently
|
||||
if !exists("+rightleft")
|
||||
return
|
||||
endif
|
||||
CheckFeature rightleft
|
||||
call NewWindow(10, 20)
|
||||
call setline(1, ['abc', 'def', 'ghi'])
|
||||
call cursor(1, 2)
|
||||
@ -1348,6 +1354,13 @@ func Test_edit_rightleft()
|
||||
\" ihg",
|
||||
\" ~"]
|
||||
call assert_equal(join(expect, "\n"), join(lines, "\n"))
|
||||
%d _
|
||||
call test_override('redraw_flag', 1)
|
||||
call test_override('char_avail', 1)
|
||||
call feedkeys("a\<C-V>x41", "xt")
|
||||
redraw!
|
||||
call assert_equal(repeat(' ', 19) .. 'A', Screenline(1))
|
||||
call test_override('ALL', 0)
|
||||
set norightleft
|
||||
bw!
|
||||
endfunc
|
||||
@ -1683,4 +1696,103 @@ func Test_edit_file_no_read_perm()
|
||||
call delete('Xfile')
|
||||
endfunc
|
||||
|
||||
" Pressing escape in 'insertmode' should beep
|
||||
func Test_edit_insertmode_esc_beeps()
|
||||
new
|
||||
set insertmode
|
||||
call assert_beeps("call feedkeys(\"one\<Esc>\", 'xt')")
|
||||
set insertmode&
|
||||
" unsupported CTRL-G command should beep in insert mode.
|
||||
call assert_beeps("normal i\<C-G>l")
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for 'hkmap' and 'hkmapp'
|
||||
func Test_edit_hkmap()
|
||||
CheckFeature rightleft
|
||||
if has('win32') && !has('gui')
|
||||
" Test fails on the MS-Windows terminal version
|
||||
return
|
||||
endif
|
||||
new
|
||||
|
||||
set revins hkmap
|
||||
let str = 'abcdefghijklmnopqrstuvwxyz'
|
||||
let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
let str ..= '`/'',.;'
|
||||
call feedkeys('i' .. str, 'xt')
|
||||
let expected = "óõú,.;"
|
||||
let expected ..= "ZYXWVUTSRQPONMLKJIHGFEDCBA"
|
||||
let expected ..= "æèñ'äåàãø/ôíîöêìçïéòë÷âáðù"
|
||||
call assert_equal(expected, getline(1))
|
||||
|
||||
%d
|
||||
set revins hkmap hkmapp
|
||||
let str = 'abcdefghijklmnopqrstuvwxyz'
|
||||
let str ..= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
call feedkeys('i' .. str, 'xt')
|
||||
let expected = "õYXWVUTSRQóOïíLKJIHGFEDêBA"
|
||||
let expected ..= "öòXùåèúæø'ôñðîì÷çéäâóǟãëáà"
|
||||
call assert_equal(expected, getline(1))
|
||||
|
||||
set revins& hkmap& hkmapp&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for 'allowrevins' and using CTRL-_ in insert mode
|
||||
func Test_edit_allowrevins()
|
||||
CheckFeature rightleft
|
||||
new
|
||||
set allowrevins
|
||||
call feedkeys("iABC\<C-_>DEF\<C-_>GHI", 'xt')
|
||||
call assert_equal('ABCFEDGHI', getline(1))
|
||||
set allowrevins&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for inserting a register in insert mode using CTRL-R
|
||||
func Test_edit_insert_reg()
|
||||
new
|
||||
let g:Line = ''
|
||||
func SaveFirstLine()
|
||||
let g:Line = Screenline(1)
|
||||
return 'r'
|
||||
endfunc
|
||||
inoremap <expr> <buffer> <F2> SaveFirstLine()
|
||||
call test_override('redraw_flag', 1)
|
||||
call test_override('char_avail', 1)
|
||||
let @r = 'sample'
|
||||
call feedkeys("a\<C-R>=SaveFirstLine()\<CR>", "xt")
|
||||
call assert_equal('"', g:Line)
|
||||
call test_override('ALL', 0)
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" When a character is inserted at the last position of the last line in a
|
||||
" window, the window contents should be scrolled one line up. If the top line
|
||||
" is part of a fold, then the entire fold should be scrolled up.
|
||||
func Test_edit_lastline_scroll()
|
||||
new
|
||||
let h = winheight(0)
|
||||
let lines = ['one', 'two', 'three']
|
||||
let lines += repeat(['vim'], h - 4)
|
||||
call setline(1, lines)
|
||||
call setline(h, repeat('x', winwidth(0) - 1))
|
||||
call feedkeys("GAx", 'xt')
|
||||
redraw!
|
||||
call assert_equal(h - 1, winline())
|
||||
call assert_equal(2, line('w0'))
|
||||
|
||||
" scroll with a fold
|
||||
1,2fold
|
||||
normal gg
|
||||
call setline(h + 1, repeat('x', winwidth(0) - 1))
|
||||
call feedkeys("GAx", 'xt')
|
||||
redraw!
|
||||
call assert_equal(h - 1, winline())
|
||||
call assert_equal(3, line('w0'))
|
||||
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -7,7 +7,7 @@ let s:imstatus_active = 0
|
||||
|
||||
func IM_activatefunc(active)
|
||||
let s:imactivatefunc_called = 1
|
||||
let s:imstatus_active = a:active
|
||||
let s:imstatus_active = a:active
|
||||
endfunc
|
||||
|
||||
func IM_statusfunc()
|
||||
@ -83,4 +83,30 @@ func Test_lmap_in_insert_mode()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for using CTRL-^ to toggle iminsert in insert mode
|
||||
func Test_iminsert_toggle()
|
||||
CheckGui
|
||||
if has('win32')
|
||||
CheckFeature multi_byte_ime
|
||||
elseif !has('gui_mac')
|
||||
CheckFeature xim
|
||||
endif
|
||||
if has('gui_running') && !has('win32')
|
||||
" this works only in Win32 GUI version (for some reason)
|
||||
return
|
||||
endif
|
||||
new
|
||||
let save_imdisable = &imdisable
|
||||
let save_iminsert = &iminsert
|
||||
set noimdisable
|
||||
set iminsert=0
|
||||
exe "normal i\<C-^>"
|
||||
call assert_equal(2, &iminsert)
|
||||
exe "normal i\<C-^>"
|
||||
call assert_equal(0, &iminsert)
|
||||
let &iminsert = save_iminsert
|
||||
let &imdisable = save_imdisable
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -79,11 +79,27 @@ func Test_paste_clipboard()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" bracketed paste in command line
|
||||
func Test_paste_cmdline()
|
||||
call feedkeys(":a\<Esc>[200~foo\<CR>bar\<Esc>[201~b\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal("\"afoo\<CR>barb", getreg(':'))
|
||||
endfunc
|
||||
|
||||
" bracketed paste in Ex-mode
|
||||
func Test_paste_ex_mode()
|
||||
unlet! foo
|
||||
call feedkeys("Qlet foo=\"\<Esc>[200~foo\<CR>bar\<Esc>[201~\"\<CR>vi\<CR>", 'xt')
|
||||
call assert_equal("foo\rbar", foo)
|
||||
endfunc
|
||||
|
||||
func Test_paste_onechar()
|
||||
new
|
||||
let @f='abc'
|
||||
call feedkeys("i\<C-R>\<Esc>[200~foo\<CR>bar\<Esc>[201~", 'xt')
|
||||
call assert_equal("abc", getline(1))
|
||||
close!
|
||||
endfunc
|
||||
|
||||
func Test_paste_visual_mode()
|
||||
new
|
||||
call setline(1, 'here are some words')
|
||||
@ -134,3 +150,5 @@ func Test_xrestore()
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -2079,9 +2079,9 @@ func Test_popup_scrollbar()
|
||||
" check size with wrapping lines
|
||||
call term_sendkeys(buf, "j")
|
||||
call VerifyScreenDump(buf, 'Test_popupwin_scroll_12', {})
|
||||
call term_sendkeys(buf, "x")
|
||||
|
||||
" clean up
|
||||
call term_sendkeys(buf, "x")
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XtestPopupScroll')
|
||||
endfunc
|
||||
@ -2454,9 +2454,11 @@ func Test_popupwin_terminal_buffer()
|
||||
call term_sendkeys(termbuf2, "exit\<CR>")
|
||||
|
||||
" Exiting shell closes popup window
|
||||
let pupwin = win_getid()
|
||||
call feedkeys("exit\<CR>", 'xt')
|
||||
" Wait for shell to exit
|
||||
sleep 100m
|
||||
call WaitForAssert({-> assert_notequal(pupwin, win_getid())})
|
||||
|
||||
call feedkeys(":quit\<CR>", 'xt')
|
||||
call assert_equal(origwin, win_getid())
|
||||
endfunc
|
||||
@ -3347,6 +3349,16 @@ func Test_popupwin_filter_input_multibyte()
|
||||
call feedkeys("\u301b", 'xt')
|
||||
call assert_equal([0xe3, 0x80, 0x9b], g:bytes)
|
||||
|
||||
if has('unix')
|
||||
" with modifyOtherKeys <M-S-a> does not include a modifier sequence
|
||||
if has('gui_running')
|
||||
call feedkeys("\x9b\xfc\x08A", 'Lx!')
|
||||
else
|
||||
call feedkeys("\<Esc>[27;4;65~", 'Lx!')
|
||||
endif
|
||||
call assert_equal([0xc3, 0x81], g:bytes)
|
||||
endif
|
||||
|
||||
call popup_clear()
|
||||
delfunc MyPopupFilter
|
||||
unlet g:bytes
|
||||
|
@ -147,6 +147,11 @@ func Test_prompt_buffer_edit()
|
||||
call assert_beeps('normal! S')
|
||||
call assert_beeps("normal! \<C-A>")
|
||||
call assert_beeps("normal! \<C-X>")
|
||||
" pressing CTRL-W in the prompt buffer should trigger the window commands
|
||||
call assert_equal(1, winnr())
|
||||
exe "normal A\<C-W>\<C-W>"
|
||||
call assert_equal(2, winnr())
|
||||
wincmd w
|
||||
close!
|
||||
call assert_equal(0, prompt_setprompt([], ''))
|
||||
endfunc
|
||||
|
@ -485,6 +485,14 @@ func Test_set_register_dict()
|
||||
call assert_equal(['six'], getreginfo('0').regcontents)
|
||||
call assert_equal(['six'], getreginfo('"').regcontents)
|
||||
|
||||
let @x = 'one'
|
||||
call setreg('x', {})
|
||||
call assert_equal(1, len(split(execute('reg x'), '\n')))
|
||||
|
||||
call assert_fails("call setreg('0', #{regtype: 'V'}, 'v')", 'E118:')
|
||||
call assert_fails("call setreg('0', #{regtype: 'X'})", 'E475:')
|
||||
call assert_fails("call setreg('0', #{regtype: 'vy'})", 'E475:')
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
|
@ -26,6 +26,18 @@ func Test_rubydo()
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_rubydo_dollar_underscore()
|
||||
new
|
||||
call setline(1, ['one', 'two', 'three', 'four'])
|
||||
2,3rubydo $_ = '[' + $_ + ']'
|
||||
call assert_equal(['one', '[two]', '[three]', 'four'], getline(1, '$'))
|
||||
bwipe!
|
||||
|
||||
call assert_fails('rubydo $_ = 0', 'E265:')
|
||||
call assert_fails('rubydo (')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_rubyfile()
|
||||
" Check :rubyfile does not SEGV with Ruby level exception but just fails
|
||||
let tempfile = tempname() . '.rb'
|
||||
@ -395,6 +407,15 @@ func Test_ruby_p()
|
||||
call assert_equal(0, len(messages))
|
||||
endfunc
|
||||
|
||||
func Test_rubyeval_error()
|
||||
" On Linux or Windows the error matches:
|
||||
" "syntax error, unexpected end-of-input"
|
||||
" whereas on macOS in CI, the error message makes less sense:
|
||||
" "SyntaxError: array length must be 2"
|
||||
" Unclear why. The test does not check the error message.
|
||||
call assert_fails('call rubyeval("(")')
|
||||
endfunc
|
||||
|
||||
" Test for various heredoc syntax
|
||||
func Test_ruby_heredoc()
|
||||
ruby << END
|
||||
|
@ -38,6 +38,9 @@ func Test_selectmode_start()
|
||||
set selectmode=cmd
|
||||
call feedkeys('gvabc', 'xt')
|
||||
call assert_equal('abctdef', getline(1))
|
||||
" arrow keys without shift should not start selection
|
||||
call feedkeys("A\<Home>\<Right>\<Left>ro", 'xt')
|
||||
call assert_equal('roabctdef', getline(1))
|
||||
set selectmode= keymodel=
|
||||
bw!
|
||||
endfunc
|
||||
|
@ -623,4 +623,93 @@ func Test_tabpage_close_cmdwin()
|
||||
tabonly
|
||||
endfunc
|
||||
|
||||
" Pressing <C-PageUp> in insert mode should go to the previous tab page
|
||||
" and <C-PageDown> should go to the next tab page
|
||||
func Test_tabpage_Ctrl_Pageup()
|
||||
tabnew
|
||||
call feedkeys("i\<C-PageUp>", 'xt')
|
||||
call assert_equal(1, tabpagenr())
|
||||
call feedkeys("i\<C-PageDown>", 'xt')
|
||||
call assert_equal(2, tabpagenr())
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Return the terminal key code for selecting a tab page from the tabline. This
|
||||
" sequence contains the following codes: a CSI (0x9b), KS_TABLINE (0xf0),
|
||||
" KS_FILLER (0x58) and then the tab page number.
|
||||
func TabLineSelectPageCode(tabnr)
|
||||
return "\x9b\xf0\x58" .. nr2char(a:tabnr)
|
||||
endfunc
|
||||
|
||||
" Return the terminal key code for opening a new tabpage from the tabpage
|
||||
" menu. This sequence consists of the following codes: a CSI (0x9b),
|
||||
" KS_TABMENU (0xef), KS_FILLER (0x58), the tab page number and
|
||||
" TABLINE_MENU_NEW (2).
|
||||
func TabMenuNewItemCode(tabnr)
|
||||
return "\x9b\xef\x58" .. nr2char(a:tabnr) .. nr2char(2)
|
||||
endfunc
|
||||
|
||||
" Return the terminal key code for closing a tabpage from the tabpage menu.
|
||||
" This sequence consists of the following codes: a CSI (0x9b), KS_TABMENU
|
||||
" (0xef), KS_FILLER (0x58), the tab page number and TABLINE_MENU_CLOSE (1).
|
||||
func TabMenuCloseItemCode(tabnr)
|
||||
return "\x9b\xef\x58" .. nr2char(a:tabnr) .. nr2char(1)
|
||||
endfunc
|
||||
|
||||
" Test for using the tabpage menu from the insert and normal modes
|
||||
func Test_tabline_tabmenu()
|
||||
" only works in GUI
|
||||
CheckGui
|
||||
|
||||
%bw!
|
||||
tabnew
|
||||
tabnew
|
||||
call assert_equal(3, tabpagenr())
|
||||
|
||||
" go to tab page 2 in normal mode
|
||||
call feedkeys(TabLineSelectPageCode(2), "Lx!")
|
||||
call assert_equal(2, tabpagenr())
|
||||
|
||||
" close tab page 3 in normal mode
|
||||
call feedkeys(TabMenuCloseItemCode(3), "Lx!")
|
||||
call assert_equal(2, tabpagenr('$'))
|
||||
call assert_equal(2, tabpagenr())
|
||||
|
||||
" open new tab page before tab page 1 in normal mode
|
||||
call feedkeys(TabMenuNewItemCode(1), "Lx!")
|
||||
call assert_equal(1, tabpagenr())
|
||||
call assert_equal(3, tabpagenr('$'))
|
||||
|
||||
" go to tab page 2 in operator-pending mode (should beep)
|
||||
call assert_beeps('call feedkeys("f" .. TabLineSelectPageCode(2), "Lx!")')
|
||||
|
||||
" open new tab page before tab page 1 in operator-pending mode (should beep)
|
||||
call assert_beeps('call feedkeys("f" .. TabMenuNewItemCode(1), "Lx!")')
|
||||
|
||||
" open new tab page after tab page 3 in normal mode
|
||||
call feedkeys(TabMenuNewItemCode(4), "Lx!")
|
||||
call assert_equal(4, tabpagenr())
|
||||
call assert_equal(4, tabpagenr('$'))
|
||||
|
||||
" go to tab page 2 in insert mode
|
||||
call feedkeys("i" .. TabLineSelectPageCode(2) .. "\<C-C>", "Lx!")
|
||||
call assert_equal(2, tabpagenr())
|
||||
|
||||
" close tab page 2 in insert mode
|
||||
call feedkeys("i" .. TabMenuCloseItemCode(2) .. "\<C-C>", "Lx!")
|
||||
call assert_equal(3, tabpagenr('$'))
|
||||
|
||||
" open new tab page before tab page 3 in insert mode
|
||||
call feedkeys("i" .. TabMenuNewItemCode(3) .. "\<C-C>", "Lx!")
|
||||
call assert_equal(3, tabpagenr())
|
||||
call assert_equal(4, tabpagenr('$'))
|
||||
|
||||
" open new tab page after tab page 4 in insert mode
|
||||
call feedkeys("i" .. TabMenuNewItemCode(5) .. "\<C-C>", "Lx!")
|
||||
call assert_equal(5, tabpagenr())
|
||||
call assert_equal(5, tabpagenr('$'))
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -240,6 +240,7 @@ func Test_tag_file_encoding()
|
||||
call delete('Xtags1')
|
||||
endfunc
|
||||
|
||||
" Test for emacs-style tags file (TAGS)
|
||||
func Test_tagjump_etags()
|
||||
if !has('emacs_tags')
|
||||
return
|
||||
@ -1055,7 +1056,7 @@ func Test_tselect_listing()
|
||||
call writefile([
|
||||
\ "!_TAG_FILE_ENCODING\tutf-8\t//",
|
||||
\ "first\tXfoo\t1" .. ';"' .. "\tv\ttyperef:typename:int\tfile:",
|
||||
\ "first\tXfoo\t2" .. ';"' .. "\tv\ttyperef:typename:char\tfile:"],
|
||||
\ "first\tXfoo\t2" .. ';"' .. "\tkind:v\ttyperef:typename:char\tfile:"],
|
||||
\ 'Xtags')
|
||||
set tags=Xtags
|
||||
|
||||
@ -1337,4 +1338,56 @@ func Test_tag_length()
|
||||
set tags& taglength&
|
||||
endfunc
|
||||
|
||||
" Tests for errors in a tags file
|
||||
func Test_tagfile_errors()
|
||||
set tags=Xtags
|
||||
|
||||
" missing search pattern or line number for a tag
|
||||
call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
|
||||
\ "foo\tXfile\t"], 'Xtags', 'b')
|
||||
call writefile(['foo'], 'Xfile')
|
||||
|
||||
enew
|
||||
tag foo
|
||||
call assert_equal('', @%)
|
||||
let caught_431 = v:false
|
||||
try
|
||||
eval taglist('.*')
|
||||
catch /:E431:/
|
||||
let caught_431 = v:true
|
||||
endtry
|
||||
call assert_equal(v:true, caught_431)
|
||||
|
||||
call delete('Xtags')
|
||||
call delete('Xfile')
|
||||
set tags&
|
||||
endfunc
|
||||
|
||||
" When :stag fails to open the file, should close the new window
|
||||
func Test_stag_close_window_on_error()
|
||||
new | only
|
||||
set tags=Xtags
|
||||
call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
|
||||
\ "foo\tXfile\t1"], 'Xtags')
|
||||
call writefile(['foo'], 'Xfile')
|
||||
call writefile([], '.Xfile.swp')
|
||||
" Remove the catch-all that runtest.vim adds
|
||||
au! SwapExists
|
||||
augroup StagTest
|
||||
au!
|
||||
autocmd SwapExists Xfile let v:swapchoice='q'
|
||||
augroup END
|
||||
|
||||
stag foo
|
||||
call assert_equal(1, winnr('$'))
|
||||
call assert_equal('', @%)
|
||||
|
||||
augroup StagTest
|
||||
au!
|
||||
augroup END
|
||||
call delete('Xfile')
|
||||
call delete('.Xfile.swp')
|
||||
set tags&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -1116,6 +1116,20 @@ func Test_fo_a_w()
|
||||
call feedkeys("iabc abc a abc\<Esc>k0weade", 'xt')
|
||||
call assert_equal(['abc abcde ', 'a abc'], getline(1, '$'))
|
||||
|
||||
" when a line ends with space, it is not broken up.
|
||||
%d
|
||||
call feedkeys("ione two to ", 'xt')
|
||||
call assert_equal('one two to ', getline(1))
|
||||
|
||||
" when a line ends with spaces and backspace is used in the next line, the
|
||||
" last space in the previous line should be removed.
|
||||
%d
|
||||
set backspace=indent,eol,start
|
||||
call setline(1, ['one ', 'two'])
|
||||
exe "normal 2Gi\<BS>"
|
||||
call assert_equal(['one two'], getline(1, '$'))
|
||||
set backspace&
|
||||
|
||||
" Test for 'a', 'w' and '1' options.
|
||||
setlocal textwidth=0
|
||||
setlocal fo=1aw
|
||||
|
@ -1190,7 +1190,7 @@ def Test_vim9script_forward_func()
|
||||
def FuncTwo(): string
|
||||
return 'two'
|
||||
enddef
|
||||
let g:res_FuncOne: string = execute('disass FuncOne')
|
||||
g:res_FuncOne = execute('disass FuncOne')
|
||||
END
|
||||
writefile(lines, 'Xdisassemble')
|
||||
source Xdisassemble
|
||||
|
@ -1029,6 +1029,39 @@ def Test_expr7_trailing()
|
||||
assert_equal(123, d.key)
|
||||
enddef
|
||||
|
||||
def Test_expr7_subscript_linebreak()
|
||||
let range = range(
|
||||
3)
|
||||
let l = range->
|
||||
map('string(v:key)')
|
||||
assert_equal(['0', '1', '2'], l)
|
||||
|
||||
l = range
|
||||
->map('string(v:key)')
|
||||
assert_equal(['0', '1', '2'], l)
|
||||
|
||||
l = range # comment
|
||||
->map('string(v:key)')
|
||||
assert_equal(['0', '1', '2'], l)
|
||||
|
||||
l = range
|
||||
|
||||
->map('string(v:key)')
|
||||
assert_equal(['0', '1', '2'], l)
|
||||
|
||||
l = range
|
||||
# comment
|
||||
->map('string(v:key)')
|
||||
assert_equal(['0', '1', '2'], l)
|
||||
|
||||
assert_equal('1', l[
|
||||
1])
|
||||
|
||||
let d = #{one: 33}
|
||||
assert_equal(33, d.
|
||||
one)
|
||||
enddef
|
||||
|
||||
|
||||
func Test_expr7_trailing_fails()
|
||||
call CheckDefFailure(['let l = [2]', 'l->{l -> add(l, 8)}'], 'E107')
|
||||
@ -1044,7 +1077,7 @@ func Test_expr_fails()
|
||||
call CheckDefFailure(["CallMe2('yes' , 'no')"], 'E1068:')
|
||||
|
||||
call CheckDefFailure(["v:nosuch += 3"], 'E1001:')
|
||||
call CheckDefFailure(["let v:statusmsg = ''"], 'E1064:')
|
||||
call CheckDefFailure(["let v:statusmsg = ''"], 'E1016: Cannot declare a v: variable:')
|
||||
call CheckDefFailure(["let asdf = v:nosuch"], 'E1001:')
|
||||
|
||||
call CheckDefFailure(["echo len('asdf'"], 'E110:')
|
||||
|
@ -323,7 +323,7 @@ def Test_vim9script_call()
|
||||
str->MyFunc()
|
||||
assert_equal('barfoo', var)
|
||||
|
||||
let g:value = 'value'
|
||||
g:value = 'value'
|
||||
g:value->MyFunc()
|
||||
assert_equal('value', var)
|
||||
|
||||
|
@ -322,15 +322,15 @@ def Test_assignment_failure()
|
||||
call CheckDefFailure(['let &option'], 'E1052:')
|
||||
call CheckDefFailure(['&g:option = 5'], 'E113:')
|
||||
|
||||
call CheckDefFailure(['let $VAR = 5'], 'E1065:')
|
||||
call CheckDefFailure(['let $VAR = 5'], 'E1016: Cannot declare an environment variable:')
|
||||
|
||||
call CheckDefFailure(['let @~ = 5'], 'E354:')
|
||||
call CheckDefFailure(['let @a = 5'], 'E1066:')
|
||||
|
||||
call CheckDefFailure(['let g:var = 5'], 'E1016:')
|
||||
call CheckDefFailure(['let w:var = 5'], 'E1079:')
|
||||
call CheckDefFailure(['let b:var = 5'], 'E1078:')
|
||||
call CheckDefFailure(['let t:var = 5'], 'E1080:')
|
||||
call CheckDefFailure(['let g:var = 5'], 'E1016: Cannot declare a global variable:')
|
||||
call CheckDefFailure(['let w:var = 5'], 'E1016: Cannot declare a window variable:')
|
||||
call CheckDefFailure(['let b:var = 5'], 'E1016: Cannot declare a buffer variable:')
|
||||
call CheckDefFailure(['let t:var = 5'], 'E1016: Cannot declare a tab variable:')
|
||||
|
||||
call CheckDefFailure(['let anr = 4', 'anr ..= "text"'], 'E1019:')
|
||||
call CheckDefFailure(['let xnr += 4'], 'E1020:')
|
||||
@ -1099,11 +1099,11 @@ def Test_if_const_expr()
|
||||
|
||||
g:glob = 2
|
||||
if false
|
||||
execute('let g:glob = 3')
|
||||
execute('g:glob = 3')
|
||||
endif
|
||||
assert_equal(2, g:glob)
|
||||
if true
|
||||
execute('let g:glob = 3')
|
||||
execute('g:glob = 3')
|
||||
endif
|
||||
assert_equal(3, g:glob)
|
||||
|
||||
@ -1790,8 +1790,8 @@ def Test_vim9_comment_gui()
|
||||
enddef
|
||||
|
||||
def Test_vim9_comment_not_compiled()
|
||||
au TabEnter *.vim let g:entered = 1
|
||||
au TabEnter *.x let g:entered = 2
|
||||
au TabEnter *.vim g:entered = 1
|
||||
au TabEnter *.x g:entered = 2
|
||||
|
||||
edit test.vim
|
||||
doautocmd TabEnter #comment
|
||||
@ -1811,14 +1811,46 @@ def Test_vim9_comment_not_compiled()
|
||||
|
||||
CheckScriptSuccess([
|
||||
'vim9script',
|
||||
'let g:var = 123',
|
||||
'let w:var = 777',
|
||||
'g:var = 123',
|
||||
'b:var = 456',
|
||||
'w:var = 777',
|
||||
't:var = 888',
|
||||
'unlet g:var w:var # something',
|
||||
])
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let g:var = 123',
|
||||
], 'E1016: Cannot declare a global variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let b:var = 123',
|
||||
], 'E1016: Cannot declare a buffer variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let w:var = 123',
|
||||
], 'E1016: Cannot declare a window variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let t:var = 123',
|
||||
], 'E1016: Cannot declare a tab variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let v:version = 123',
|
||||
], 'E1016: Cannot declare a v: variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'let $VARIABLE = "text"',
|
||||
], 'E1016: Cannot declare an environment variable:')
|
||||
|
||||
CheckScriptFailure([
|
||||
'vim9script',
|
||||
'g:var = 123',
|
||||
'unlet g:var# comment1',
|
||||
], 'E108:')
|
||||
|
||||
@ -1889,11 +1921,11 @@ enddef
|
||||
def Test_finish()
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
let g:res = 'one'
|
||||
g:res = 'one'
|
||||
if v:false | finish | endif
|
||||
let g:res = 'two'
|
||||
g:res = 'two'
|
||||
finish
|
||||
let g:res = 'three'
|
||||
g:res = 'three'
|
||||
END
|
||||
writefile(lines, 'Xfinished')
|
||||
source Xfinished
|
||||
|
@ -87,6 +87,28 @@ func Test_global_vars()
|
||||
call assert_equal(test_null, g:MY_GLOBAL_NULL)
|
||||
call assert_equal(test_none, g:MY_GLOBAL_NONE)
|
||||
|
||||
" Test for invalid values for a blob, list, dict in a viminfo file
|
||||
call writefile([
|
||||
\ "!GLOB_BLOB_1\tBLO\t123",
|
||||
\ "!GLOB_BLOB_2\tBLO\t012",
|
||||
\ "!GLOB_BLOB_3\tBLO\t0z1x",
|
||||
\ "!GLOB_BLOB_4\tBLO\t0z12 ab",
|
||||
\ "!GLOB_LIST_1\tLIS\t1 2",
|
||||
\ "!GLOB_DICT_1\tDIC\t1 2"], 'Xviminfo')
|
||||
call assert_fails('rv! Xviminfo', 'E15:')
|
||||
call assert_equal('123', g:GLOB_BLOB_1)
|
||||
call assert_equal(1, type(g:GLOB_BLOB_1))
|
||||
call assert_equal('012', g:GLOB_BLOB_2)
|
||||
call assert_equal(1, type(g:GLOB_BLOB_2))
|
||||
call assert_equal('0z1x', g:GLOB_BLOB_3)
|
||||
call assert_equal(1, type(g:GLOB_BLOB_3))
|
||||
call assert_equal('0z12 ab', g:GLOB_BLOB_4)
|
||||
call assert_equal(1, type(g:GLOB_BLOB_4))
|
||||
call assert_equal('1 2', g:GLOB_LIST_1)
|
||||
call assert_equal(1, type(g:GLOB_LIST_1))
|
||||
call assert_equal('1 2', g:GLOB_DICT_1)
|
||||
call assert_equal(1, type(g:GLOB_DICT_1))
|
||||
|
||||
call delete('Xviminfo')
|
||||
set viminfo-=!
|
||||
endfunc
|
||||
|
@ -357,4 +357,22 @@ func Test_delete_break_tab()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Test for using <BS>, <C-W> and <C-U> in virtual edit mode
|
||||
" to erase character, word and line.
|
||||
func Test_ve_backspace()
|
||||
new
|
||||
call setline(1, 'sample')
|
||||
set virtualedit=all
|
||||
set backspace=indent,eol,start
|
||||
exe "normal 15|i\<BS>\<BS>"
|
||||
call assert_equal([0, 1, 7, 5], getpos('.'))
|
||||
exe "normal 15|i\<C-W>"
|
||||
call assert_equal([0, 1, 6, 0], getpos('.'))
|
||||
exe "normal 15|i\<C-U>"
|
||||
call assert_equal([0, 1, 1, 0], getpos('.'))
|
||||
set backspace&
|
||||
set virtualedit&
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
@ -208,6 +208,15 @@ func Test_virtual_replace()
|
||||
exe "normal iabcdefghijklmnopqrst\<Esc>0gRAB\tIJKLMNO\tQR"
|
||||
call assert_equal(['AB......CDEFGHI.Jkl',
|
||||
\ 'AB IJKLMNO QRst'], getline(12, 13))
|
||||
|
||||
" Test inserting Tab with 'noexpandtab' and 'softabstop' set to 4
|
||||
%d
|
||||
call setline(1, 'aaaaaaaaaaaaa')
|
||||
set softtabstop=4
|
||||
exe "normal gggR\<Tab>\<Tab>x"
|
||||
call assert_equal("\txaaaa", getline(1))
|
||||
set softtabstop&
|
||||
|
||||
enew!
|
||||
set noai bs&vim
|
||||
if exists('save_t_kD')
|
||||
|
@ -409,7 +409,7 @@ get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate)
|
||||
fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
|
||||
if (fp == NULL)
|
||||
goto errret;
|
||||
fp->uf_dfunc_idx = UF_NOT_COMPILED;
|
||||
fp->uf_def_status = UF_NOT_COMPILED;
|
||||
pt = ALLOC_CLEAR_ONE(partial_T);
|
||||
if (pt == NULL)
|
||||
goto errret;
|
||||
@ -1001,7 +1001,7 @@ func_remove(ufunc_T *fp)
|
||||
{
|
||||
// When there is a def-function index do not actually remove the
|
||||
// function, so we can find the index when defining the function again.
|
||||
if (fp->uf_dfunc_idx >= 0)
|
||||
if (fp->uf_def_status == UF_COMPILED)
|
||||
fp->uf_flags |= FC_DEAD;
|
||||
else
|
||||
hash_remove(&func_hashtab, hi);
|
||||
@ -1046,7 +1046,7 @@ func_clear(ufunc_T *fp, int force)
|
||||
// clear this function
|
||||
func_clear_items(fp);
|
||||
funccal_unref(fp->uf_scoped, fp, force);
|
||||
delete_def_function(fp);
|
||||
clear_def_function(fp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1074,7 +1074,8 @@ func_free(ufunc_T *fp, int force)
|
||||
func_clear_free(ufunc_T *fp, int force)
|
||||
{
|
||||
func_clear(fp, force);
|
||||
func_free(fp, force);
|
||||
if (force || fp->uf_dfunc_idx == 0)
|
||||
func_free(fp, force);
|
||||
}
|
||||
|
||||
|
||||
@ -1137,7 +1138,7 @@ call_user_func(
|
||||
ga_init2(&fc->fc_funcs, sizeof(ufunc_T *), 1);
|
||||
func_ptr_ref(fp);
|
||||
|
||||
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (fp->uf_def_status != UF_NOT_COMPILED)
|
||||
{
|
||||
estack_push_ufunc(fp, 1);
|
||||
save_current_sctx = current_sctx;
|
||||
@ -1662,7 +1663,7 @@ free_all_functions(void)
|
||||
// clear the def function index now
|
||||
fp = HI2UF(hi);
|
||||
fp->uf_flags &= ~FC_DEAD;
|
||||
fp->uf_dfunc_idx = UF_NOT_COMPILED;
|
||||
fp->uf_def_status = UF_NOT_COMPILED;
|
||||
|
||||
// Only free functions that are not refcounted, those are
|
||||
// supposed to be freed when no longer referenced.
|
||||
@ -2058,7 +2059,7 @@ list_func_head(ufunc_T *fp, int indent)
|
||||
msg_start();
|
||||
if (indent)
|
||||
msg_puts(" ");
|
||||
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (fp->uf_def_status != UF_NOT_COMPILED)
|
||||
msg_puts("def ");
|
||||
else
|
||||
msg_puts("function ");
|
||||
@ -2107,7 +2108,7 @@ list_func_head(ufunc_T *fp, int indent)
|
||||
}
|
||||
msg_putchar(')');
|
||||
|
||||
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (fp->uf_def_status != UF_NOT_COMPILED)
|
||||
{
|
||||
if (fp->uf_ret_type != &t_void)
|
||||
{
|
||||
@ -2624,7 +2625,7 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
if (!got_int)
|
||||
{
|
||||
msg_putchar('\n');
|
||||
if (fp->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (fp->uf_def_status != UF_NOT_COMPILED)
|
||||
msg_puts(" enddef");
|
||||
else
|
||||
msg_puts(" endfunction");
|
||||
@ -3097,6 +3098,7 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
fp->uf_profiling = FALSE;
|
||||
fp->uf_prof_initialized = FALSE;
|
||||
#endif
|
||||
clear_def_function(fp);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3162,7 +3164,7 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
fp = alloc_clear(offsetof(ufunc_T, uf_name) + STRLEN(name) + 1);
|
||||
if (fp == NULL)
|
||||
goto erret;
|
||||
fp->uf_dfunc_idx = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED
|
||||
fp->uf_def_status = eap->cmdidx == CMD_def ? UF_TO_BE_COMPILED
|
||||
: UF_NOT_COMPILED;
|
||||
|
||||
if (fudi.fd_dict != NULL)
|
||||
@ -3219,7 +3221,7 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
{
|
||||
int lnum_save = SOURCING_LNUM;
|
||||
|
||||
fp->uf_dfunc_idx = UF_TO_BE_COMPILED;
|
||||
fp->uf_def_status = UF_TO_BE_COMPILED;
|
||||
|
||||
// error messages are for the first function line
|
||||
SOURCING_LNUM = sourcing_lnum_top;
|
||||
@ -3289,7 +3291,7 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
SOURCING_LNUM = lnum_save;
|
||||
}
|
||||
else
|
||||
fp->uf_dfunc_idx = UF_NOT_COMPILED;
|
||||
fp->uf_def_status = UF_NOT_COMPILED;
|
||||
|
||||
fp->uf_lines = newlines;
|
||||
if ((flags & FC_CLOSURE) != 0)
|
||||
@ -3323,6 +3325,9 @@ def_function(exarg_T *eap, char_u *name_arg)
|
||||
|
||||
if (eap->cmdidx == CMD_def)
|
||||
set_function_type(fp);
|
||||
else if (fp->uf_script_ctx.sc_version == SCRIPT_VERSION_VIM9)
|
||||
// :func does not use Vim9 script syntax, even in a Vim9 script file
|
||||
fp->uf_script_ctx.sc_version = SCRIPT_VERSION_MAX;
|
||||
|
||||
goto ret_free;
|
||||
|
||||
@ -3372,7 +3377,7 @@ ex_defcompile(exarg_T *eap UNUSED)
|
||||
--todo;
|
||||
ufunc = HI2UF(hi);
|
||||
if (ufunc->uf_script_ctx.sc_sid == current_sctx.sc_sid
|
||||
&& ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED)
|
||||
&& ufunc->uf_def_status == UF_TO_BE_COMPILED)
|
||||
{
|
||||
compile_def_function(ufunc, FALSE, NULL);
|
||||
|
||||
|
@ -754,6 +754,50 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1036,
|
||||
/**/
|
||||
1035,
|
||||
/**/
|
||||
1034,
|
||||
/**/
|
||||
1033,
|
||||
/**/
|
||||
1032,
|
||||
/**/
|
||||
1031,
|
||||
/**/
|
||||
1030,
|
||||
/**/
|
||||
1029,
|
||||
/**/
|
||||
1028,
|
||||
/**/
|
||||
1027,
|
||||
/**/
|
||||
1026,
|
||||
/**/
|
||||
1025,
|
||||
/**/
|
||||
1024,
|
||||
/**/
|
||||
1023,
|
||||
/**/
|
||||
1022,
|
||||
/**/
|
||||
1021,
|
||||
/**/
|
||||
1020,
|
||||
/**/
|
||||
1019,
|
||||
/**/
|
||||
1018,
|
||||
/**/
|
||||
1017,
|
||||
/**/
|
||||
1016,
|
||||
/**/
|
||||
1015,
|
||||
/**/
|
||||
1014,
|
||||
/**/
|
||||
|
@ -27,7 +27,7 @@
|
||||
typedef enum {
|
||||
SKIP_NOT, // condition is a constant, produce code
|
||||
SKIP_YES, // condition is a constant, do NOT produce code
|
||||
SKIP_UNKNONW // condition is not a constant, produce code
|
||||
SKIP_UNKNOWN // condition is not a constant, produce code
|
||||
} skip_T;
|
||||
|
||||
/*
|
||||
@ -1493,7 +1493,7 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (ufunc->uf_def_status != UF_NOT_COMPILED)
|
||||
{
|
||||
int i;
|
||||
|
||||
@ -1517,16 +1517,16 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED)
|
||||
if (ufunc->uf_def_status == UF_TO_BE_COMPILED)
|
||||
if (compile_def_function(ufunc, TRUE, NULL) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if ((isn = generate_instr(cctx,
|
||||
ufunc->uf_dfunc_idx != UF_NOT_COMPILED ? ISN_DCALL
|
||||
ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
|
||||
: ISN_UCALL)) == NULL)
|
||||
return FAIL;
|
||||
if (ufunc->uf_dfunc_idx != UF_NOT_COMPILED)
|
||||
if (ufunc->uf_def_status != UF_NOT_COMPILED)
|
||||
{
|
||||
isn->isn_arg.dfunc.cdf_idx = ufunc->uf_dfunc_idx;
|
||||
isn->isn_arg.dfunc.cdf_argcount = argcount;
|
||||
@ -2380,12 +2380,43 @@ free_imported(cctx_T *cctx)
|
||||
ga_clear(&cctx->ctx_imports);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "p" points at a "#" but not at "#{".
|
||||
*/
|
||||
static int
|
||||
comment_start(char_u *p)
|
||||
{
|
||||
return p[0] == '#' && p[1] != '{';
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a pointer to the next line that isn't empty or only contains a
|
||||
* comment. Skips over white space.
|
||||
* Returns NULL if there is none.
|
||||
*/
|
||||
static char_u *
|
||||
peek_next_line(cctx_T *cctx)
|
||||
{
|
||||
int lnum = cctx->ctx_lnum;
|
||||
|
||||
while (++lnum < cctx->ctx_ufunc->uf_lines.ga_len)
|
||||
{
|
||||
char_u *line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[lnum];
|
||||
char_u *p = skipwhite(line);
|
||||
|
||||
if (*p != NUL && !comment_start(p))
|
||||
return p;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the next line of the function from "cctx".
|
||||
* Skips over empty lines. Skips over comment lines if "skip_comment" is TRUE.
|
||||
* Returns NULL when at the end.
|
||||
*/
|
||||
static char_u *
|
||||
next_line_from_context(cctx_T *cctx)
|
||||
next_line_from_context(cctx_T *cctx, int skip_comment)
|
||||
{
|
||||
char_u *line;
|
||||
|
||||
@ -2400,19 +2431,11 @@ next_line_from_context(cctx_T *cctx)
|
||||
line = ((char_u **)cctx->ctx_ufunc->uf_lines.ga_data)[cctx->ctx_lnum];
|
||||
cctx->ctx_line_start = line;
|
||||
SOURCING_LNUM = cctx->ctx_lnum + 1;
|
||||
} while (line == NULL || *skipwhite(line) == NUL);
|
||||
} while (line == NULL || *skipwhite(line) == NUL
|
||||
|| (skip_comment && comment_start(skipwhite(line))));
|
||||
return line;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if "p" points at a "#" but not at "#{".
|
||||
*/
|
||||
static int
|
||||
comment_start(char_u *p)
|
||||
{
|
||||
return p[0] == '#' && p[1] != '{';
|
||||
}
|
||||
|
||||
/*
|
||||
* If "*arg" is at the end of the line, advance to the next line.
|
||||
* Also when "whitep" points to white space and "*arg" is on a "#".
|
||||
@ -2423,7 +2446,7 @@ may_get_next_line(char_u *whitep, char_u **arg, cctx_T *cctx)
|
||||
{
|
||||
if (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
|
||||
{
|
||||
char_u *next = next_line_from_context(cctx);
|
||||
char_u *next = next_line_from_context(cctx, TRUE);
|
||||
|
||||
if (next == NULL)
|
||||
return FAIL;
|
||||
@ -2752,14 +2775,8 @@ compile_arguments(char_u **arg, cctx_T *cctx, int *argcount)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
|
||||
{
|
||||
p = next_line_from_context(cctx);
|
||||
if (p == NULL)
|
||||
goto failret;
|
||||
whitep = (char_u *)" ";
|
||||
p = skipwhite(p);
|
||||
}
|
||||
if (may_get_next_line(whitep, &p, cctx) == FAIL)
|
||||
goto failret;
|
||||
if (*p == ')')
|
||||
{
|
||||
*arg = p + 1;
|
||||
@ -2986,16 +3003,10 @@ compile_list(char_u **arg, cctx_T *cctx)
|
||||
|
||||
for (;;)
|
||||
{
|
||||
while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
|
||||
if (may_get_next_line(whitep, &p, cctx) == FAIL)
|
||||
{
|
||||
p = next_line_from_context(cctx);
|
||||
if (p == NULL)
|
||||
{
|
||||
semsg(_(e_list_end), *arg);
|
||||
return FAIL;
|
||||
}
|
||||
whitep = (char_u *)" ";
|
||||
p = skipwhite(p);
|
||||
semsg(_(e_list_end), *arg);
|
||||
return FAIL;
|
||||
}
|
||||
if (*p == ']')
|
||||
{
|
||||
@ -3042,7 +3053,7 @@ compile_lambda(char_u **arg, cctx_T *cctx)
|
||||
// Compile it into instructions.
|
||||
compile_def_function(ufunc, TRUE, cctx);
|
||||
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
if (ufunc->uf_def_status == UF_COMPILED)
|
||||
return generate_FUNCREF(cctx, ufunc->uf_dfunc_idx);
|
||||
return FAIL;
|
||||
}
|
||||
@ -3112,14 +3123,10 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
|
||||
{
|
||||
char_u *key = NULL;
|
||||
|
||||
while (**arg == NUL || (literal && **arg == '"')
|
||||
|| (VIM_ISWHITE(*whitep) && comment_start(*arg)))
|
||||
if (may_get_next_line(whitep, arg, cctx) == FAIL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx);
|
||||
if (*arg == NULL)
|
||||
goto failret;
|
||||
whitep = (char_u *)" ";
|
||||
*arg = skipwhite(*arg);
|
||||
*arg = NULL;
|
||||
goto failret;
|
||||
}
|
||||
|
||||
if (**arg == '}')
|
||||
@ -3179,13 +3186,10 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
|
||||
|
||||
whitep = *arg + 1;
|
||||
*arg = skipwhite(*arg + 1);
|
||||
while (**arg == NUL || (VIM_ISWHITE(*whitep) && comment_start(*arg)))
|
||||
if (may_get_next_line(whitep, arg, cctx) == FAIL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx);
|
||||
if (*arg == NULL)
|
||||
goto failret;
|
||||
whitep = (char_u *)" ";
|
||||
*arg = skipwhite(*arg);
|
||||
*arg = NULL;
|
||||
goto failret;
|
||||
}
|
||||
|
||||
if (compile_expr0(arg, cctx) == FAIL)
|
||||
@ -3193,15 +3197,11 @@ compile_dict(char_u **arg, cctx_T *cctx, int literal)
|
||||
++count;
|
||||
|
||||
whitep = *arg;
|
||||
p = skipwhite(*arg);
|
||||
while (*p == NUL || (VIM_ISWHITE(*whitep) && comment_start(p)))
|
||||
*arg = skipwhite(*arg);
|
||||
if (may_get_next_line(whitep, arg, cctx) == FAIL)
|
||||
{
|
||||
*arg = next_line_from_context(cctx);
|
||||
if (*arg == NULL)
|
||||
goto failret;
|
||||
whitep = (char_u *)" ";
|
||||
*arg = skipwhite(*arg);
|
||||
p = *arg;
|
||||
*arg = NULL;
|
||||
goto failret;
|
||||
}
|
||||
if (**arg == '}')
|
||||
break;
|
||||
@ -3506,6 +3506,24 @@ compile_subscript(
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
char_u *p = skipwhite(*arg);
|
||||
|
||||
if (*p == NUL || (VIM_ISWHITE(**arg) && comment_start(p)))
|
||||
{
|
||||
char_u *next = peek_next_line(cctx);
|
||||
|
||||
// If a following line starts with "->{" or "->X" advance to that
|
||||
// line, so that a line break before "->" is allowed.
|
||||
if (next != NULL && next[0] == '-' && next[1] == '>'
|
||||
&& (next[2] == '{' || ASCII_ISALPHA(next[2])))
|
||||
{
|
||||
next = next_line_from_context(cctx, TRUE);
|
||||
if (next == NULL)
|
||||
return FAIL;
|
||||
*arg = skipwhite(next);
|
||||
}
|
||||
}
|
||||
|
||||
if (**arg == '(')
|
||||
{
|
||||
garray_T *stack = &cctx->ctx_type_stack;
|
||||
@ -3526,8 +3544,6 @@ compile_subscript(
|
||||
}
|
||||
else if (**arg == '-' && (*arg)[1] == '>')
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (generate_ppconst(cctx, ppconst) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
@ -3538,7 +3554,10 @@ compile_subscript(
|
||||
return FAIL;
|
||||
*start_leader = end_leader; // don't apply again later
|
||||
|
||||
*arg = skipwhite(*arg + 2);
|
||||
p = *arg + 2;
|
||||
*arg = skipwhite(p);
|
||||
if (may_get_next_line(p, arg, cctx) == FAIL)
|
||||
return FAIL;
|
||||
if (**arg == '{')
|
||||
{
|
||||
// lambda call: list->{lambda}
|
||||
@ -3576,7 +3595,10 @@ compile_subscript(
|
||||
if (generate_ppconst(cctx, ppconst) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
*arg = skipwhite(*arg + 1);
|
||||
p = *arg + 1;
|
||||
*arg = skipwhite(p);
|
||||
if (may_get_next_line(p, arg, cctx) == FAIL)
|
||||
return FAIL;
|
||||
if (compile_expr0(arg, cctx) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
@ -3611,14 +3633,14 @@ compile_subscript(
|
||||
}
|
||||
else if (**arg == '.' && (*arg)[1] != '.')
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
if (generate_ppconst(cctx, ppconst) == FAIL)
|
||||
return FAIL;
|
||||
|
||||
++*arg;
|
||||
p = *arg;
|
||||
if (may_get_next_line(*arg, arg, cctx) == FAIL)
|
||||
return FAIL;
|
||||
// dictionary member: dict.name
|
||||
p = *arg;
|
||||
if (eval_isnamec1(*p))
|
||||
while (eval_isnamec(*p))
|
||||
MB_PTR_ADV(p);
|
||||
@ -4335,9 +4357,9 @@ compile_expr1(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
garray_T *instr = &cctx->ctx_instr;
|
||||
garray_T *stack = &cctx->ctx_type_stack;
|
||||
int alt_idx = instr->ga_len;
|
||||
int end_idx;
|
||||
int end_idx = 0;
|
||||
isn_T *isn;
|
||||
type_T *type1;
|
||||
type_T *type1 = NULL;
|
||||
type_T *type2;
|
||||
int has_const_expr = FALSE;
|
||||
int const_value = FALSE;
|
||||
@ -4539,7 +4561,7 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
||||
|
||||
if (ufunc == NULL)
|
||||
return NULL;
|
||||
if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
||||
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||
&& compile_def_function(ufunc, TRUE, cctx) == FAIL)
|
||||
return NULL;
|
||||
|
||||
@ -4650,6 +4672,24 @@ generate_loadvar(
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
vim9_declare_error(char_u *name)
|
||||
{
|
||||
char *scope = "";
|
||||
|
||||
switch (*name)
|
||||
{
|
||||
case 'g': scope = _("global"); break;
|
||||
case 'b': scope = _("buffer"); break;
|
||||
case 'w': scope = _("window"); break;
|
||||
case 't': scope = _("tab"); break;
|
||||
case 'v': scope = "v:"; break;
|
||||
case '$': semsg(_(e_declare_env_var), name); return;
|
||||
default: return;
|
||||
}
|
||||
semsg(_(e_declare_var), scope, name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compile declaration and assignment:
|
||||
* "let var", "let var = expr", "const var = expr" and "var = expr"
|
||||
@ -4846,8 +4886,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
type = &t_string;
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1065: Cannot declare an environment variable: %s"),
|
||||
name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -4871,8 +4910,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
dest = dest_global;
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1016: Cannot declare a global variable: %s"),
|
||||
name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -4881,8 +4919,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
dest = dest_buffer;
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1078: Cannot declare a buffer variable: %s"),
|
||||
name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -4891,8 +4928,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
dest = dest_window;
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1079: Cannot declare a window variable: %s"),
|
||||
name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -4901,7 +4937,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
dest = dest_tab;
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1080: Cannot declare a tab variable: %s"), name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -4924,7 +4960,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
type = typval2type(vtv);
|
||||
if (is_decl)
|
||||
{
|
||||
semsg(_("E1064: Cannot declare a v: variable: %s"), name);
|
||||
vim9_declare_error(name);
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
@ -5688,7 +5724,7 @@ compile_if(char_u *arg, cctx_T *cctx)
|
||||
else
|
||||
{
|
||||
// Not a constant, generate instructions for the expression.
|
||||
cctx->ctx_skip = SKIP_UNKNONW;
|
||||
cctx->ctx_skip = SKIP_UNKNOWN;
|
||||
if (generate_ppconst(cctx, &ppconst) == FAIL)
|
||||
return NULL;
|
||||
}
|
||||
@ -5700,7 +5736,7 @@ compile_if(char_u *arg, cctx_T *cctx)
|
||||
// "is_had_return" will be reset if any block does not end in :return
|
||||
scope->se_u.se_if.is_had_return = TRUE;
|
||||
|
||||
if (cctx->ctx_skip == SKIP_UNKNONW)
|
||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
||||
{
|
||||
// "where" is set when ":elseif", "else" or ":endif" is found
|
||||
scope->se_u.se_if.is_if_label = instr->ga_len;
|
||||
@ -5731,7 +5767,7 @@ compile_elseif(char_u *arg, cctx_T *cctx)
|
||||
if (!cctx->ctx_had_return)
|
||||
scope->se_u.se_if.is_had_return = FALSE;
|
||||
|
||||
if (cctx->ctx_skip == SKIP_UNKNONW)
|
||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
||||
{
|
||||
if (compile_jump_to_end(&scope->se_u.se_if.is_end_label,
|
||||
JUMP_ALWAYS, cctx) == FAIL)
|
||||
@ -5761,7 +5797,7 @@ compile_elseif(char_u *arg, cctx_T *cctx)
|
||||
else
|
||||
{
|
||||
// Not a constant, generate instructions for the expression.
|
||||
cctx->ctx_skip = SKIP_UNKNONW;
|
||||
cctx->ctx_skip = SKIP_UNKNOWN;
|
||||
if (generate_ppconst(cctx, &ppconst) == FAIL)
|
||||
return NULL;
|
||||
|
||||
@ -5794,7 +5830,7 @@ compile_else(char_u *arg, cctx_T *cctx)
|
||||
if (scope->se_skip_save != SKIP_YES)
|
||||
{
|
||||
// jump from previous block to the end, unless the else block is empty
|
||||
if (cctx->ctx_skip == SKIP_UNKNONW)
|
||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
||||
{
|
||||
if (!cctx->ctx_had_return
|
||||
&& compile_jump_to_end(&scope->se_u.se_if.is_end_label,
|
||||
@ -5802,7 +5838,7 @@ compile_else(char_u *arg, cctx_T *cctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cctx->ctx_skip == SKIP_UNKNONW)
|
||||
if (cctx->ctx_skip == SKIP_UNKNOWN)
|
||||
{
|
||||
if (scope->se_u.se_if.is_if_label >= 0)
|
||||
{
|
||||
@ -5813,7 +5849,7 @@ compile_else(char_u *arg, cctx_T *cctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (cctx->ctx_skip != SKIP_UNKNONW)
|
||||
if (cctx->ctx_skip != SKIP_UNKNOWN)
|
||||
cctx->ctx_skip = cctx->ctx_skip == SKIP_YES ? SKIP_NOT : SKIP_YES;
|
||||
}
|
||||
|
||||
@ -6517,13 +6553,22 @@ theend:
|
||||
|
||||
/*
|
||||
* Add a function to the list of :def functions.
|
||||
* This "sets ufunc->uf_dfunc_idx" but the function isn't compiled yet.
|
||||
* This sets "ufunc->uf_dfunc_idx" but the function isn't compiled yet.
|
||||
*/
|
||||
static int
|
||||
add_def_function(ufunc_T *ufunc)
|
||||
{
|
||||
dfunc_T *dfunc;
|
||||
|
||||
if (def_functions.ga_len == 0)
|
||||
{
|
||||
// The first position is not used, so that a zero uf_dfunc_idx means it
|
||||
// wasn't set.
|
||||
if (ga_grow(&def_functions, 1) == FAIL)
|
||||
return FAIL;
|
||||
++def_functions.ga_len;
|
||||
}
|
||||
|
||||
// Add the function to "def_functions".
|
||||
if (ga_grow(&def_functions, 1) == FAIL)
|
||||
return FAIL;
|
||||
@ -6563,7 +6608,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
|
||||
// When using a function that was compiled before: Free old instructions.
|
||||
// Otherwise add a new entry in "def_functions".
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
if (ufunc->uf_dfunc_idx > 0)
|
||||
{
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
@ -6656,7 +6701,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
if (line != NULL && *line == '|')
|
||||
// the line continues after a '|'
|
||||
++line;
|
||||
else if (line != NULL && *line != NUL
|
||||
else if (line != NULL && *skipwhite(line) != NUL
|
||||
&& !(*line == '#' && (line == cctx.ctx_line_start
|
||||
|| VIM_ISWHITE(line[-1]))))
|
||||
{
|
||||
@ -6665,7 +6710,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
}
|
||||
else
|
||||
{
|
||||
line = next_line_from_context(&cctx);
|
||||
line = next_line_from_context(&cctx, FALSE);
|
||||
if (cctx.ctx_lnum >= ufunc->uf_lines.ga_len)
|
||||
// beyond the last line
|
||||
break;
|
||||
@ -6838,6 +6883,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
p = skipwhite(p);
|
||||
|
||||
if (cctx.ctx_skip == SKIP_YES
|
||||
&& ea.cmdidx != CMD_if
|
||||
&& ea.cmdidx != CMD_elseif
|
||||
&& ea.cmdidx != CMD_else
|
||||
&& ea.cmdidx != CMD_endif)
|
||||
@ -7013,6 +7059,7 @@ compile_def_function(ufunc_T *ufunc, int set_return_type, cctx_T *outer_cctx)
|
||||
dfunc->df_closure_count = cctx.ctx_closure_count;
|
||||
if (cctx.ctx_outer_used)
|
||||
ufunc->uf_flags |= FC_CLOSURE;
|
||||
ufunc->uf_def_status = UF_COMPILED;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
@ -7032,7 +7079,7 @@ erret:
|
||||
if (!dfunc->df_deleted
|
||||
&& ufunc->uf_dfunc_idx == def_functions.ga_len - 1)
|
||||
--def_functions.ga_len;
|
||||
ufunc->uf_dfunc_idx = UF_NOT_COMPILED;
|
||||
ufunc->uf_def_status = UF_NOT_COMPILED;
|
||||
|
||||
while (cctx.ctx_scope != NULL)
|
||||
drop_scope(&cctx);
|
||||
@ -7260,17 +7307,19 @@ delete_def_function_contents(dfunc_T *dfunc)
|
||||
}
|
||||
|
||||
/*
|
||||
* When a user function is deleted, delete any associated def function.
|
||||
* When a user function is deleted, clear the contents of any associated def
|
||||
* function. The position in def_functions can be re-used.
|
||||
*/
|
||||
void
|
||||
delete_def_function(ufunc_T *ufunc)
|
||||
clear_def_function(ufunc_T *ufunc)
|
||||
{
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
if (ufunc->uf_dfunc_idx > 0)
|
||||
{
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
|
||||
delete_def_function_contents(dfunc);
|
||||
ufunc->uf_def_status = UF_NOT_COMPILED;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -487,10 +487,10 @@ call_ufunc(ufunc_T *ufunc, int argcount, ectx_T *ectx, isn_T *iptr)
|
||||
int error;
|
||||
int idx;
|
||||
|
||||
if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
||||
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||
&& compile_def_function(ufunc, FALSE, NULL) == FAIL)
|
||||
return FAIL;
|
||||
if (ufunc->uf_dfunc_idx >= 0)
|
||||
if (ufunc->uf_def_status == UF_COMPILED)
|
||||
{
|
||||
// The function has been compiled, can call it quickly. For a function
|
||||
// that was defined later: we can call it directly next time.
|
||||
@ -671,8 +671,8 @@ call_def_function(
|
||||
// Like STACK_TV_VAR but use the outer scope
|
||||
#define STACK_OUT_TV_VAR(idx) (((typval_T *)ectx.ec_outer_stack->ga_data) + ectx.ec_outer_frame + STACK_FRAME_SIZE + idx)
|
||||
|
||||
if (ufunc->uf_dfunc_idx == UF_NOT_COMPILED
|
||||
|| (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
||||
if (ufunc->uf_def_status == UF_NOT_COMPILED
|
||||
|| (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||
&& compile_def_function(ufunc, FALSE, NULL) == FAIL))
|
||||
{
|
||||
if (called_emsg == called_emsg_before)
|
||||
@ -2379,10 +2379,10 @@ ex_disassemble(exarg_T *eap)
|
||||
semsg(_("E1061: Cannot find function %s"), eap->arg);
|
||||
return;
|
||||
}
|
||||
if (ufunc->uf_dfunc_idx == UF_TO_BE_COMPILED
|
||||
if (ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||
&& compile_def_function(ufunc, FALSE, NULL) == FAIL)
|
||||
return;
|
||||
if (ufunc->uf_dfunc_idx < 0)
|
||||
if (ufunc->uf_def_status != UF_COMPILED)
|
||||
{
|
||||
semsg(_("E1062: Function %s is not compiled"), eap->arg);
|
||||
return;
|
||||
|
Reference in New Issue
Block a user