Merge remote-tracking branch 'vim/master'

This commit is contained in:
ichizok
2020-07-07 18:22:52 +09:00
144 changed files with 15103 additions and 11158 deletions
+2
View File
@@ -80,6 +80,7 @@ SRC_ALL = \
src/main.c \
src/map.c \
src/mark.c \
src/match.c \
src/mbyte.c \
src/memfile.c \
src/memfile_test.c \
@@ -247,6 +248,7 @@ SRC_ALL = \
src/proto/main.pro \
src/proto/map.pro \
src/proto/mark.pro \
src/proto/match.pro \
src/proto/mbyte.pro \
src/proto/memfile.pro \
src/proto/memline.pro \
+57 -41
View File
@@ -1,4 +1,4 @@
*eval.txt* For Vim version 8.2. Last change: 2020 Jun 17
*eval.txt* For Vim version 8.2. Last change: 2020 Jun 30
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -157,7 +157,7 @@ You will not get an error if you try to change the type of a variable.
1.2 Function references ~
*Funcref* *E695* *E718*
*Funcref* *E695* *E718*
A Funcref variable is obtained with the |function()| function, the |funcref()|
function or created with the lambda expression |expr-lambda|. It can be used
in an expression in the place of a function name, before the parenthesis
@@ -2523,13 +2523,15 @@ getjumplist([{winnr} [, {tabnr}]])
List list of jump list items
getline({lnum}) String line {lnum} of current buffer
getline({lnum}, {end}) List lines {lnum} to {end} of current buffer
getloclist({nr} [, {what}]) List list of location list items
getloclist({nr}) List list of location list items
getloclist({nr}, {what}) Dict get specific location list properties
getmarklist([{expr}]) List list of global/local marks
getmatches([{win}]) List list of current matches
getmousepos() Dict last known mouse position
getpid() Number process ID of Vim
getpos({expr}) List position of cursor, mark, etc.
getqflist([{what}]) List list of quickfix items
getqflist() List list of quickfix items
getqflist({what}) Dict get specific quickfix list properties
getreg([{regname} [, 1 [, {list}]]])
String or List contents of a register
getreginfo([{regname}]) Dict information about a register
@@ -2768,12 +2770,15 @@ setcmdpos({pos}) Number set cursor position in command-line
setenv({name}, {val}) none set environment variable
setfperm({fname}, {mode}) Number set {fname} file permissions to {mode}
setline({lnum}, {line}) Number set line {lnum} to {line}
setloclist({nr}, {list} [, {action} [, {what}]])
Number modify location list using {list}
setloclist({nr}, {list} [, {action}])
Number modify location list using {list}
setloclist({nr}, {list}, {action}, {what})
Number modify specific location list props
setmatches({list} [, {win}]) Number restore a list of matches
setpos({expr}, {list}) Number set the {expr} position to {list}
setqflist({list} [, {action} [, {what}]])
Number modify quickfix list using {list}
setqflist({list} [, {action}]) Number modify quickfix list using {list}
setqflist({list}, {action}, {what})
Number modify specific quickfix list props
setreg({n}, {v} [, {opt}]) Number set register to value and type
settabvar({nr}, {varname}, {val}) none set {varname} in tab page {nr} to {val}
settabwinvar({tabnr}, {winnr}, {varname}, {val})
@@ -3647,7 +3652,7 @@ complete_check() *complete_check()*
*complete_info()*
complete_info([{what}])
Returns a Dictionary with information about Insert mode
Returns a |Dictionary| with information about Insert mode
completion. See |ins-completion|.
The items are:
mode Current completion mode name string.
@@ -4874,7 +4879,7 @@ getbufinfo([{dict}])
Without an argument information about all the buffers is
returned.
When the argument is a Dictionary only the buffers matching
When the argument is a |Dictionary| only the buffers matching
the specified criteria are returned. The following keys can
be specified in {dict}:
buflisted include only listed buffers.
@@ -5405,7 +5410,7 @@ getline({lnum} [, {end}])
< To get lines from another buffer see |getbufline()|
getloclist({nr} [, {what}]) *getloclist()*
Returns a list with all the entries in the location list for
Returns a |List| with all the entries in the location list for
window {nr}. {nr} can be the window number or the |window-ID|.
When {nr} is zero the current window is used.
@@ -5427,6 +5432,14 @@ getloclist({nr} [, {what}]) *getloclist()*
|location-list-file-window| for more
details.
Returns an empty Dictionary if there is no location list for
the window {nr} or the window is not present.
Examples (See also |getqflist-examples|): >
:echo getloclist(3, {'all': 0})
:echo getloclist(5, {'filewinid': 0})
getmarklist([{expr}] *getmarklist()*
Without the {expr} argument returns a |List| with information
about all the global marks. |mark|
@@ -5471,7 +5484,7 @@ getmatches([{win}]) *getmatches()*
:unlet m
<
getmousepos() *getmousepos()*
Returns a Dictionary with the last known position of the
Returns a |Dictionary| with the last known position of the
mouse. This can be used in a mapping for a mouse click or in
a filter of a popup window. The items are:
screenrow screen row
@@ -5691,12 +5704,12 @@ getregtype([{regname}]) *getregtype()*
gettabinfo([{arg}]) *gettabinfo()*
If {arg} is not specified, then information about all the tab
pages is returned as a List. Each List item is a Dictionary.
pages is returned as a |List|. Each List item is a |Dictionary|.
Otherwise, {arg} specifies the tab page number and information
about that one is returned. If the tab page does not exist an
empty List is returned.
Each List item is a Dictionary with the following entries:
Each List item is a |Dictionary| with the following entries:
tabnr tab page number.
variables a reference to the dictionary with
tabpage-local variables
@@ -5724,7 +5737,7 @@ gettabwinvar({tabnr}, {winnr}, {varname} [, {def}]) *gettabwinvar()*
When {varname} is empty a dictionary with all window-local
variables is returned.
When {varname} is equal to "&" get the values of all
window-local options in a Dictionary.
window-local options in a |Dictionary|.
Otherwise, when {varname} starts with "&" get the value of a
window-local option.
Note that {varname} must be the name without "w:".
@@ -5779,16 +5792,16 @@ gettagstack([{nr}]) *gettagstack()*
GetWinnr()->gettagstack()
getwininfo([{winid}]) *getwininfo()*
Returns information about windows as a List with Dictionaries.
Returns information about windows as a |List| with Dictionaries.
If {winid} is given Information about the window with that ID
is returned, as a List with one item. If the window does not
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.
Each List item is a Dictionary with the following entries:
Each List item is a |Dictionary| with the following entries:
botline last displayed buffer line
bufnr number of buffer in the window
height window height (excluding winbar)
@@ -5816,7 +5829,7 @@ getwininfo([{winid}]) *getwininfo()*
GetWinnr()->getwininfo()
getwinpos([{timeout}]) *getwinpos()*
The result is a List with two numbers, the result of
The result is a |List| with two numbers, the result of
|getwinposx()| and |getwinposy()| combined:
[x-pos, y-pos]
{timeout} can be used to specify how long to wait in msec for
@@ -5871,7 +5884,7 @@ glob({expr} [, {nosuf} [, {list} [, {alllinks}]]]) *glob()*
'suffixes' affect the ordering of matches.
'wildignorecase' always applies.
When {list} is present and it is |TRUE| the result is a List
When {list} is present and it is |TRUE| the result is a |List|
with all matching files. The advantage of using a List is,
you also get filenames containing newlines correctly.
Otherwise the result is a String and when there are several
@@ -5934,7 +5947,7 @@ globpath({path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
one of the patterns in 'wildignore' will be skipped and
'suffixes' affect the ordering of matches.
When {list} is present and it is |TRUE| the result is a List
When {list} is present and it is |TRUE| the result is a |List|
with all matching files. The advantage of using a List is, you
also get filenames containing newlines correctly. Otherwise
the result is a String and when there are several matches,
@@ -7293,7 +7306,7 @@ matchstrpos({expr}, {pat} [, {start} [, {count}]]) *matchstrpos()*
*max()*
max({expr}) Return the maximum value of all items in {expr}.
{expr} can be a List or a Dictionary. For a Dictionary,
{expr} can be a |List| or a |Dictionary|. For a Dictionary,
it returns the maximum of all values in the Dictionary.
If {expr} is neither a List nor a Dictionary, or one of the
items in {expr} cannot be used as a Number this results in
@@ -7364,7 +7377,7 @@ menu_info({name} [, {mode}]) *menu_info()*
< *min()*
min({expr}) Return the minimum value of all items in {expr}.
{expr} can be a List or a Dictionary. For a Dictionary,
{expr} can be a |List| or a |Dictionary|. For a Dictionary,
it returns the minimum of all values in the Dictionary.
If {expr} is neither a List nor a Dictionary, or one of the
items in {expr} cannot be used as a Number this results in
@@ -8026,7 +8039,7 @@ readdirex({directory} [, {expr} [, {dict}]]) *readdirex()*
If {expr} results in 1 then this entry will be added
to the list.
The entries "." and ".." are always excluded.
Each time {expr} is evaluated |v:val| is set to a Dictionary
Each time {expr} is evaluated |v:val| is set to a |Dictionary|
of the entry.
When {expr} is a function the entry is passed as the argument.
For example, to get a list of files ending in ".txt": >
@@ -8275,7 +8288,7 @@ remove({list}, {idx} [, {end}]) *remove()*
Without {end}: Remove the item at {idx} from |List| {list} and
return the item.
With {end}: Remove items from {idx} to {end} (inclusive) and
return a List with these items. When {idx} points to the same
return a |List| with these items. When {idx} points to the same
item as {end} a list with one item is returned. When {end}
points to an item before {idx} this is an error.
See |list-index| for possible values of {idx} and {end}.
@@ -8412,7 +8425,7 @@ screenchar({row}, {col}) *screenchar()*
GetRow()->screenchar(col)
screenchars({row}, {col}) *screenchars()*
The result is a List of Numbers. The first number is the same
The result is a |List| of Numbers. The first number is the same
as what |screenchar()| returns. Further numbers are
composing characters on top of the base character.
This is mainly to be used for testing.
@@ -8577,7 +8590,7 @@ searchcount([{options}]) *searchcount()*
without the "S" flag in 'shortmess'. This works even if
'shortmess' does contain the "S" flag.
This returns a Dictionary. The dictionary is empty if the
This returns a |Dictionary|. The dictionary is empty if the
previous pattern was not set and "pattern" was not specified.
key type meaning ~
@@ -8659,7 +8672,7 @@ searchcount([{options}]) *searchcount()*
" search again
call searchcount()
<
{options} must be a Dictionary. It can contain:
{options} must be a |Dictionary|. It can contain:
key type meaning ~
recompute |Boolean| if |TRUE|, recompute the count
like |n| or |N| was executed.
@@ -9198,10 +9211,12 @@ setqflist({list} [, {action} [, {what}]]) *setqflist()*
setreg({regname}, {value} [, {options}])
Set the register {regname} to {value}.
If {regname} is "" or "@", the unnamed register '"' is used.
{value} may be any value returned by |getreg()| or
|getreginfo()|, including a |List| or |Dict|.
If {options} contains "a" or {regname} is upper case,
then the value is appended.
{options} can also contain a register type specification:
"c" or "v" |characterwise| mode
"l" or "V" |linewise| mode
@@ -9232,7 +9247,7 @@ setreg({regname}, {value} [, {options}])
register: >
:let var_a = getreginfo()
:call setreg('a', var_a)
< or:
< or: >
:let var_a = getreg('a', 1, 1)
:let var_amode = getregtype('a')
....
@@ -9709,13 +9724,13 @@ state([{what}]) *state()*
something is busy:
m halfway a mapping, :normal command, feedkeys() or
stuffed command
o operator pending or waiting for a command argument,
e.g. after |f|
o operator pending, e.g. after |d|
a Insert mode autocomplete active
x executing an autocommand
w blocked on waiting, e.g. ch_evalexpr(), ch_read() and
ch_readraw() when reading json.
S not triggering SafeState or SafeStateAgain
ch_readraw() when reading json
S not triggering SafeState or SafeStateAgain, e.g. after
|f| or a count
c callback invoked, including timer (repeats for
recursiveness up to "ccc")
s screen has scrolled for messages
@@ -9896,7 +9911,7 @@ string({expr}) Return {expr} converted to a String. If {expr} is a Number,
List [item, item]
Dictionary {key: value, key: value}
When a List or Dictionary has a recursive reference it is
When a |List| or |Dictionary| has a recursive reference it is
replaced by "[...]" or "{...}". Using eval() on the result
will then fail.
@@ -10187,7 +10202,7 @@ synIDtrans({synID}) *synIDtrans()*
:echo synID(line("."), col("."), 1)->synIDtrans()->synIDattr("fg")
synconcealed({lnum}, {col}) *synconcealed()*
The result is a List with currently three items:
The result is a |List| with currently three items:
1. The first item in the list is 0 if the character at the
position {lnum} and {col} is not part of a concealable
region, 1 if it is.
@@ -10232,7 +10247,7 @@ synstack({lnum}, {col}) *synstack()*
system({expr} [, {input}]) *system()* *E677*
Get the output of the shell command {expr} as a string. See
|systemlist()| to get the output as a List.
|systemlist()| to get the output as a |List|.
When {input} is given and is a string this string is written
to a file and passed as stdin to the command. The string is
@@ -10494,7 +10509,7 @@ timer_info([{id}])
returned.
When {id} is omitted information about all timers is returned.
For each timer the information is stored in a Dictionary with
For each timer the information is stored in a |Dictionary| with
these items:
"id" the timer ID
"time" time the timer was started with
@@ -10728,7 +10743,7 @@ undotree() *undotree()*
undo blocks.
The first item in the "entries" list is the oldest undo item.
Each List item is a Dictionary with these items:
Each List item is a |Dictionary| with these items:
"seq" Undo sequence number. Same as what appears in
|:undolist|.
"time" Timestamp when the change happened. Use
@@ -10940,7 +10955,7 @@ win_splitmove({nr}, {target} [, {options}]) *win_splitmove()*
Returns zero for success, non-zero for failure.
{options} is a Dictionary with the following optional entries:
{options} is a |Dictionary| with the following optional entries:
"vertical" When TRUE, the split is created vertically,
like with |:vsplit|.
"rightbelow" When TRUE, the split is made below or to the
@@ -12110,8 +12125,9 @@ An assignment leaves out the `:let` command. |vim9-declaration|
text...
text...
{endmarker}
Set internal variable {var-name} to a List containing
the lines of text bounded by the string {endmarker}.
Set internal variable {var-name} to a |List|
containing the lines of text bounded by the string
{endmarker}.
{endmarker} must not contain white space.
{endmarker} cannot start with a lower case character.
The last line should end only with the {endmarker}
+31 -7
View File
@@ -1,4 +1,4 @@
*if_lua.txt* For Vim version 8.2. Last change: 2020 May 17
*if_lua.txt* For Vim version 8.2. Last change: 2020 Jun 28
VIM REFERENCE MANUAL by Luis Carvalho
@@ -217,14 +217,27 @@ Vim's syntax for lists. Since lists are objects, changes in list references in
Lua are reflected in Vim and vice-versa. A list "l" has the following
properties and methods:
NOTE: In patch 8.2.1066 array indexes were changed from zero-based to
one-based. You can check with: >
if has("patch-8.2.1066")
Properties
----------
o "#l" is the number of items in list "l", equivalent to "len(l)"
in Vim.
o "l[k]" returns the k-th item in "l"; "l" is zero-indexed, as in Vim.
o "l[k]" returns the k-th item in "l"; "l" is one-indexed, as in Lua.
To modify the k-th item, simply do "l[k] = newitem"; in
particular, "l[k] = nil" removes the k-th item from "l".
particular, "l[k] = nil" removes the k-th item from "l". Item can
be added to the end of the list by "l[#l + 1] = newitem"
o "l()" returns an iterator for "l".
o "table.insert(l, newitem)" inserts an item at the end of the list.
(only Lua 5.3 and later)
o "table.insert(l, position, newitem)" inserts an item at the
specified position. "position" is one-indexed. (only Lua 5.3 and
later)
o "table.remove(l, position)" removes an item at the specified
position. "position" is one-indexed.
Methods
-------
@@ -237,13 +250,16 @@ Examples:
:let l = [1, 'item']
:lua l = vim.eval('l') -- same 'l'
:lua l:add(vim.list())
:lua l[0] = math.pi
:lua l[1] = math.pi
:echo l[0] " 3.141593
:lua l[0] = nil -- remove first item
:lua l[1] = nil -- remove first item
:lua l:insert(true, 1)
:lua print(l, #l, l[0], l[1], l[-1])
:lua print(l, #l, l[1], l[2])
:lua l[#l + 1] = 'value'
:lua table.insert(l, 100)
:lua table.insert(l, 2, 200)
:lua table.remove(l, 1)
:lua for item in l() do print(item) end
<
==============================================================================
4. Dict userdata *lua-dict*
@@ -333,6 +349,14 @@ Examples:
:lua l = d.len -- assign d as 'self'
:lua print(l())
<
Lua functions and closures are automatically converted to a Vim |Funcref| and
can be accessed in Vim scripts. Example:
>
lua <<EOF
vim.fn.timer_start(1000, function(timer)
print('timer callback')
end)
EOF
==============================================================================
7. Buffer userdata *lua-buffer*
+3 -3
View File
@@ -4244,7 +4244,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global
This option specifies a function that will be called to
activate or deactivate the Input Method.
It is not used in the GUI.
It is not used in the MS-Windows GUI version.
The expression will be evaluated in the |sandbox| when set from a
modeline, see |sandbox-option|.
@@ -4353,7 +4353,7 @@ A jump table for the options with a short description can be found at |Q_op|.
global
This option specifies a function that is called to obtain the status
of Input Method. It must return a positive number when IME is active.
It is not used in the GUI.
It is not used in the MS-Windows GUI version.
Example: >
function ImStatusFunc()
@@ -6879,7 +6879,7 @@ A jump table for the options with a short description can be found at |Q_op|.
flag meaning when present ~
f use "(3 of 5)" instead of "(file 3 of 5)"
i use "[noeol]" instead of "[Incomplete last line]"
l use "999L, 888C" instead of "999 lines, 888 characters"
l use "999L, 888B" instead of "999 lines, 888 bytes"
m use "[+]" instead of "[Modified]"
n use "[New]" instead of "[New File]"
r use "[RO]" instead of "[readonly]"
+1 -1
View File
@@ -5018,7 +5018,7 @@ ctermul={color-nr} *highlight-ctermul*
console. Example, for reverse video: >
:highlight Visual ctermfg=bg ctermbg=fg
< Note that the colors are used that are valid at the moment this
command are given. If the Normal group colors are changed later, the
command is given. If the Normal group colors are changed later, the
"fg" and "bg" colors will not be adjusted.
+2
View File
@@ -3948,6 +3948,7 @@ E103 diff.txt /*E103*
E104 digraph.txt /*E104*
E1042 vim9.txt /*E1042*
E105 mbyte.txt /*E105*
E1050 vim9.txt /*E1050*
E107 eval.txt /*E107*
E108 eval.txt /*E108*
E109 eval.txt /*E109*
@@ -10136,6 +10137,7 @@ vim9-declaration vim9.txt /*vim9-declaration*
vim9-declarations usr_46.txt /*vim9-declarations*
vim9-differences vim9.txt /*vim9-differences*
vim9-export vim9.txt /*vim9-export*
vim9-gotchas vim9.txt /*vim9-gotchas*
vim9-import vim9.txt /*vim9-import*
vim9-rationale vim9.txt /*vim9-rationale*
vim9-scopes vim9.txt /*vim9-scopes*
+46 -78
View File
@@ -1,4 +1,4 @@
*todo.txt* For Vim version 8.2. Last change: 2020 Jun 21
*todo.txt* For Vim version 8.2. Last change: 2020 Jun 28
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -40,12 +40,31 @@ browser use: https://github.com/vim/vim/issues/1234
Include src/po/vim.pot ?
See if resizing a terminal can be fixed.
Vim9 script:
- line continuation at script level:
eval_to_string_skip(), test with :throw
eval1_emsg(), pass "eap", test with :execute, :echomsg, :echoerr
handle_subscript() - call_func_rettv() - get_func_tv()
func(
args arg)
callers of get_func_tv():
eval_func()
ex_call()
function arguments, test assert_equal() with lambda, test :function
:import:
others
eval_index()
- test:
[1,
2,
3]->Func()
Making everything work:
- "nr += 4" gives "already defined" error.
- Error for "g:var: string = 'value'"
- Make func()->append('$') work - value is last argument, not first. #6305
- in Vim9 script expressions are evaluated differently, not using a type.
e.g. "'' == 0" does not give an error and evaluates to true.
- possible memory leak in test_vim9_func through compile_nested_function.
- memory leaks in test_vim9_expr
- memory leaks in test_vim9_script
@@ -134,12 +153,6 @@ Further improvements:
- compile "expr" and "call" expression of a channel in channel_exe_cmd()?
Popup windows:
- With some sequence get get hidden finished terminal buffer. (#5768)
Cannot close popup terminal (#5744)
Buffer can't be wiped, gets status "aF". (#5764)
Is buf->nwindows incorrect?
- popup_clear() and popup_close() should close the terminal popup, and
make the buffer hidden. #5745
- Cursor not updated before a redraw, making it jump. (#5943)
- With terminal in popup, allow for popup_hide() to temporarily hide it.?
- Fire some autocommand event after a new popup window was created and
@@ -274,6 +287,13 @@ 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__
Add the <=> (spaceship) operator and "cond ?< expr ?= expr ?> expr"
replace this:
let left = GetLeftFunc()
let right = GetRightFunc()
let res = left < right ? lower : left == right ? equal : upper
by:
let res = GetLeftFunc() <=> GetRightFunc() ?< lower ?= equal ?> upper
Patch to make :q work with local arglist. (Christian Brabandt, #6286)
Patch to fix drawing error with DirectX. (James Grant, #5688)
@@ -495,9 +515,6 @@ window 2. User expects 10 to be added to size of window 2. (Daniel Steinberg,
Would be nice to set tab-local values for 'diffexpr' and 'diffopt'. Use
t:diffexpr_option t:diffopt_option? (#4782)
v:register isn't reset early enough, may be used by next command.
(Andy Massimino, #5294, possible fix in #5305)
Internal diff doesn't handle binary file like external diff does. (Mike
Williams, 2018 Oct 30)
@@ -580,9 +597,6 @@ buffer didn't change at all.
Line numbers in profile are off when function was defined with ":execute".
(Daniel Hahler, #4511)
Add a way to create an empty, hidden buffer. Like doing ":new|hide".
":let buf = bufcreate('name')
Session file contains absolute paths when "curdir" is removed form
'sessionoptions', making it impossible to have a session with a relative path.
(#4450)
@@ -1199,8 +1213,8 @@ Make a function to check for function-like type?
Screen updated delayed when using CTRL-O u in Insert mode.
(Barlik, #1191) Perhaps because status message?
Implement named arguments for functions:
func Foo(start, count = 1 all = 1)
Implement named arguments for functions with optional arguments:
func Foo(start, count = 1, all = 1)
call Foo(12, all = 0)
Add a command to take a range of lines, filter them and put the output
@@ -1393,8 +1407,6 @@ Did maintainer reply?
ml_get errors when reloading file. (Chris Desjardins, 2016 Apr 19)
Also with latest version.
Cannot delete a file with square brackets with delete(). (#696)
Completion for input() does not expand environment variables. (chdiza, 2016
Jul 25, #948)
@@ -1403,8 +1415,6 @@ names, shell commands and the like. (Kikuchan, 2010 Oct 14)
Assume the system converts between the actual encoding of the filesystem to
the system encoding (usually utf-8).
'hlsearch' interferes with a Conceal match. (Rom Grk, 2016 Aug 9)
MS-Windows: use WS_HIDE instead of SW_SHOWMINNOACTIVE in os_win32.c?
Otherwise task flickers in taskbar.
@@ -1416,8 +1426,6 @@ Have a way to get the call stack, in a function and from an exception.
Second problem in #966: ins_compl_add_tv() uses get_dict_string() multiple
times, overwrites the one buffer. (Nikolay Pavlov, 2016 Aug 5)
Possibly wrong value for seq_cur. (Florent Fayolle, 2016 May 15, #806)
Filetype plugin for awk. (Doug Kearns, 2016 Sep 5)
Patch to improve map documentation. Issue #799.
@@ -1436,8 +1444,6 @@ Reject the value? #710.
When doing "vi buf.md" a BufNew autocommand for *.md is not triggered.
Because of using the initial buffer? (Dun Peal, 2016 May 12)
Add redrawtabline command. (Naruhiko Nishino, 2016 Jun 11)
Neovim patch for utfc_ptr2char_len() https://github.com/neovim/neovim/pull/4574
No test, needs some work to include.
@@ -1507,20 +1513,10 @@ If ":bd" also closes a Tab page then the " mark is not set. (Harm te Hennepe,
Patch to avoid redrawing tabline when the popup menu is visible.
(Christian Brabandt, 2016 Jan 28)
Patch to show search statistics. (Christian Brabandt, 2016 Jul 22)
When the CursorMovedI event triggers, and CTRL-X was typed, a script cannot
restore the mode properly. (Andrew Stewart, 2016 Apr 20)
Do not trigger the event?
Using ":windo" to set options in all windows has the side effect that it
changes the window layout and the current window. Make a variant that saves
and restores. Use in the matchparen plugin.
Perhaps we can use ":windo <restore> {cmd}"?
Patch to add <restore> to :windo, :bufdo, etc. (Christian Brabandt, 2015 Jan
6, 2nd message)
Alternative: ":keeppos" command modifier: ":keeppos windo {cmd}".
Patch to fix display of listchars on the cursorline. (Nayuri Aohime, 2013)
Update suggested by Yasuhiro Matsumoto, 2014 Nov 25:
https://gist.github.com/presuku/d3d6b230b9b6dcfc0477
@@ -1549,10 +1545,6 @@ Python: ":py raw_input('prompt')" doesn't work. (Manu Hack)
Comparing nested structures with "==" uses a different comparator than when
comparing individual items.
Also, "'' == 0" evaluates to true, which isn't nice.
Add "===" to have a strict comparison (type and value match).
Add "==*" (?) to have a value match, but no automatic conversion, and v:true
equals 1 and 1.0, v:false equals 0 and 0.0.?
Using uninitialized memory. (Dominique Pelle, 2015 Nov 4)
@@ -1723,8 +1715,6 @@ arguments.
Problem with transparent and matchgroup. Issue #475
Patch to add :arglocal and :arglists. (Marcin Szamotulski, 2014 Aug 6)
Spell files use a latin single quote. Unicode also has another single quote:
0x2019. (Ron Aaron, 2014 Apr 4)
New OpenOffice spell files support this with ICONV. But they are not
@@ -1751,8 +1741,11 @@ from?
Problem with upwards search on Windows (works OK on Linux). (Brett Stahlman,
2014 Jun 8)
Include a plugin manager with Vim? Neobundle seems to be the best currently.
Include a plugin manager with Vim? vim-plug seems to be the best currently:
https://github.com/junegunn/vim-plug.
Also Vundle: https://github.com/gmarik/vundle
Or minpac: https://github.com/k-takata/minpac, since it leverages the builtin
package feature.
Long message about this from ZyX, 2014 Mar 23. And following replies.
Also see http://vim-wiki.mawercer.de/wiki/topic/vim%20plugin%20managment.html
User view:
@@ -1807,6 +1800,7 @@ instead. (Samuel Ferencik, 2013 Sep 28)
Patch for XDG base directory support. (Jean François Bignolles, 2014 Mar 4)
Remark on the docs. Should not be a compile time feature. But then what?
Also see #2034.
Completion of ":e" is ":earlier", should be ":edit". Complete to the matching
command instead of doing this alphabetically. (Mikel Jorgensen)
@@ -1868,6 +1862,10 @@ Patch to add {lhs} to :mapclear: clear all maps starting with {lhs}.
Exception caused by argument of return is not caught by try/catch.
(David Barnett, 2013 Nov 19)
Bug in try/catch: return with invalid compare throws error that isn't caught.
(ZyX, 2011 Jan 26)
try/catch not working for argument of return. (Matt Wozniski, 2008 Sep 15)
try/catch not working when inside a for loop. (ZyX, 2011 Jan 25)
Patch to fix that 'cedit' is recognized after :normal. (Christian Brabandt,
2013 Mar 19, later message)
@@ -1903,6 +1901,8 @@ process that is running. It might actually be some other program, e.g. after
a reboot.
patch to add "combine" flag to syntax commands. (so8res, 2012 Dec 6)
Patch to add "combine" to :syntax, combines highlight attributes. (Nate
Soares, 2012 Dec 3)
Syntax update problem in one buffer opened in two windows, bottom window is
not correctly updated. (Paul Harris, 2012 Feb 27)
@@ -2090,9 +2090,6 @@ doesn't jump to the correct line with :cfirst. (ZyX, 2011 Sep 18)
Behavior of i" and a" text objects isn't logical. (Ben Fritz, 2013 Nov 19)
Bug in try/catch: return with invalid compare throws error that isn't caught.
(ZyX, 2011 Jan 26)
When setting a local option value from the global value, add a script ID that
indicates this, so that ":verbose set" can give a hint. Check with options in
the help file.
@@ -2281,9 +2278,6 @@ Add local time at start of --startuptime output.
Requires configure check for localtime().
Use format year-month-day hr:min:sec.
Patch to add "combine" to :syntax, combines highlight attributes. (Nate
Soares, 2012 Dec 3)
Patch to make ":hi link" also take arguments. (Nate Soares, 2012 Dec 4)
Shell not recognized properly if it ends in "csh -f". (James Vega, 2009 Nov 3)
@@ -2478,6 +2472,9 @@ Sergey Khorev)
Consider making YankRing or something else that keeps a list of yanked text
part of standard Vim. The "1 to "9 registers are not sufficient.
6 When yanking into the unnamed registers several times, somehow make the
previous contents also available (like it's done for deleting). What
register names to use? g"1, g"2, etc.?
After doing "su" $HOME can be the old user's home, thus ~root/file is not
correct. Don't use it in the swap file.
@@ -2684,10 +2681,6 @@ Problem with 'ts' set to 9 and 'showbreak' to ">>>". (Matthew Winn, 2007 Oct
In the swapfile dialog, add a H(elp) option that gives more info about what
each choice does. Similar to ":help swap-exists-choices"
try/catch not working for argument of return. (Matt Wozniski, 2008 Sep 15)
try/catch not working when inside a for loop. (ZyX, 2011 Jan 25)
":tab help" always opens a new tab, while ":help" re-uses an existing window.
Would be more consistent when an existing tab is re-used. (Tony Mechelynck)
@@ -3257,7 +3250,7 @@ Quickfix/Location List:
":grep" and ":helpgrep".
More generic solution: support a filter (e.g., by calling a function).
7 Add a command that goes back to the position from before jumping to the
first quickfix location. ":cbefore"?
first quickfix location.
Vi incompatibility:
- Try new POSIX tests, made after my comments. (Geoff Clare, 2005 April 7)
@@ -3294,7 +3287,6 @@ Vi incompatibility:
7 The ":map" command output overwrites the command. Perhaps it should keep
the ":map" when it's used without arguments?
7 CTRL-L is not the end of a section? It is for Posix! Make it an option.
7 Implement 'prompt' option. Init to off when stdin is not a tty.
7 Add a way to send an email for a crashed edit session. Create a file when
making changes (containing name of the swap file), delete it when writing
the file. Supply a program that can check for crashed sessions (either
@@ -3472,8 +3464,6 @@ GUI:
Solaris 2.6. (Marley)
9 On Solaris: Using a "-geometry" argument, bigger than the window where Vim
is started from, causes empty lines below the cmdline. (raf)
8 X11 GUI: When menu is disabled by excluding 'm' from 'guioptions', ALT key
should not be used to trigger a menu (like the Win32 version).
8 When setting 'langmenu', it should be effective immediately. Store both
the English and the translated text in the menu structure. Re-generate
the translation when 'langmenu' has changed.
@@ -3512,10 +3502,6 @@ GUI:
When the "+0+0" is omitted it works.
8 When starting an external command, and 'guipty' set, BS and DEL are mixed
up. Set erase character somehow?
8 A dead circumflex followed by a space should give the '^' character
(Rommel). Look how xterm does this.
Also: Bednar has some code for dead key handling.
Also: Nedit 5.0.2 with USE_XMIM does it right. (Gaya)
8 The compose key doesn't work properly (Cepas). Both for Win32 and X11.
7 The cursor in an inactive window should be hollow. Currently it's not
visible.
@@ -3612,17 +3598,8 @@ Macintosh:
"Small" problems:
- Can't disable terminal flow control, to enable the use of CTRL-S and
CTRL-Q. Add an option for it?
- When using e_secure in do_one_cmd() mention the command being executed,
otherwise it's not clear where it comes from.
- When the quickfix window is open and executing ":echo 'hello'" using the
Command-line window, the text is immediately removed by the redrawing.
(Michael Henry, 2008 Nov 1)
Generic solution: When redrawing while there is a message on the
cmdline, don't erase the display but draw over the existing text.
Other solution, redraw after closing the cmdline window, before executing
the command.
9 For Turkish vim_tolower() and vim_toupper() also need to use utf_
functions for characters below 0x80. (Sertacyildiz)
9 When the last edited file is a help file, using '0 in a new Vim doesn't
@@ -4082,8 +4059,6 @@ Spell checking:
- Considering Hunspell 1.1.4:
What does MAXNGRAMSUGS do?
Is COMPLEXPREFIXES necessary when we have flags for affixes?
- Support spelling words in CamelCase as if they were two separate words.
Requires some option to enable it. (Timothy Knox)
- There is no Finnish spell checking file. For openoffice Voikko is now
used, which is based on Malaga: http://home.arcor.de/bjoern-beutel/malaga/
(Teemu Likonen)
@@ -4458,8 +4433,6 @@ Vim script language:
7 Execute a function with standard option values. No need to save and
restore option values. Especially useful for new options. Problem: how
to avoid a performance penalty (esp. for string options)?
8 Add referring to key options with "&t_xx". Both for "echo &t_xx" and
":let &t_xx =". Useful for making portable mappings.
- range for ":exec", pass it on to the executed command. (Webb)
8 ":{range}source": source the lines from the current file.
You can already yank lines and use :@" to execute them.
@@ -4690,8 +4663,6 @@ Messages:
- Delete message after new command has been entered and have waited for key.
Perhaps after ten seconds?
- Make message history available in "msg" variables: msg1, msg2, .. msg9.
8 When reading from stdin allow suppressing the "reading from stdin"
message.
9 Check handling of overwriting of messages and delays:
Very wrong: errors while redrawing cause endless loop.
When switching to another file and screen scrolls because of the long
@@ -5979,9 +5950,6 @@ Registers:
8 Add put command that overwrites existing text. Should also work for
blocks. Useful to move text around in a table. Works like using "R ^R r"
for every line.
6 When yanking into the unnamed registers several times, somehow make the
previous contents also available (like it's done for deleting). What
register names to use? g"1, g"2, etc.?
- When appending to a register, also report the total resulting number of
lines. Or just say "99 more lines yanked", add the "more".
- When inserting a register in Insert mode with CTRL-R, don't insert comment
+44 -1
View File
@@ -1,4 +1,4 @@
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 22
*vim9.txt* For Vim version 8.2. Last change: 2020 Jun 24
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -378,6 +378,49 @@ string. >
In Vim9 script one can use "true" for v:true and "false" for v:false.
What to watch out for ~
*vim9-gotchas*
Vim9 was designed to be closer to often used programming languages, but at the
same time tries to support the legacy Vim commands. Some compromises had to
be made. Here is a summary of what might be unexpected.
Ex command ranges need to be prefixed with a colon. >
-> " legacy Vim: shifts the previous line to the right
->func() " Vim9: method call
:-> " Vim9: shifts the previous line to the right
%s/a/b " legacy Vim: substitute on all lines
x = alongname
% another " Vim9: line continuation without a backslash
:%s/a/b " Vim9: substitute on all lines
Functions defined with `:def` compile the whole function. Legacy functions
can bail out, and the following lines are not parsed: >
func Maybe()
if !has('feature')
return
endif
use-feature
endfunc
Vim9 functions are compiled as a whole: >
def Maybe()
if !has('feature')
return
endif
use-feature " May give compilation error
enddef
For a workaround, split it in two functions: >
func Maybe()
if has('feature')
call MaybyInner()
endif
endfunc
if has('feature')
def MaybeInner()
use-feature
enddef
endif
==============================================================================
3. New style functions *fast-functions*
+12 -3
View File
@@ -1,7 +1,7 @@
" Vim support file to detect file types
"
" Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2020 Jun 15
" Last Change: 2020 Jun 25
" Listen very carefully, I will say this only once
if exists("did_load_filetypes")
@@ -542,7 +542,7 @@ au BufNewFile,BufRead *.ecd setf ecd
au BufNewFile,BufRead *.e,*.E call dist#ft#FTe()
" Elinks configuration
au BufNewFile,BufRead */etc/elinks.conf,*/.elinks/elinks.conf setf elinks
au BufNewFile,BufRead elinks.conf setf elinks
" ERicsson LANGuage; Yaws is erlang too
au BufNewFile,BufRead *.erl,*.hrl,*.yaws setf erlang
@@ -1134,8 +1134,17 @@ au BufNewFile,BufRead *.ora setf ora
" Packet filter conf
au BufNewFile,BufRead pf.conf setf pf
" Pacman Config (close enough to dosini)
au BufNewFile,BufRead */etc/pacman.conf setf dosini
" Pacman hooks
au BufNewFile,BufRead *.hook
\ if getline(1) == '[Trigger]' |
\ setf dosini |
\ endif
" Pam conf
au BufNewFile,BufRead */etc/pam.conf setf pamconf
au BufNewFile,BufRead */etc/pam.conf setf pamconf
" Pam environment
au BufNewFile,BufRead pam_env.conf,.pam_environment setf pamenv
File diff suppressed because it is too large Load Diff
+1
View File
@@ -753,6 +753,7 @@ OBJ = \
$(OUTDIR)/main.o \
$(OUTDIR)/map.o \
$(OUTDIR)/mark.o \
$(OUTDIR)/match.o \
$(OUTDIR)/memfile.o \
$(OUTDIR)/memline.o \
$(OUTDIR)/menu.o \
+1
View File
@@ -72,6 +72,7 @@ SRC = arabic.c \
main.c \
map.c \
mark.c \
match.c \
mbyte.c \
memfile.c \
memline.c \
+4
View File
@@ -775,6 +775,7 @@ OBJ = \
$(OUTDIR)\main.obj \
$(OUTDIR)\map.obj \
$(OUTDIR)\mark.obj \
$(OUTDIR)\match.obj \
$(OUTDIR)\mbyte.obj \
$(OUTDIR)\memfile.obj \
$(OUTDIR)\memline.obj \
@@ -1671,6 +1672,8 @@ $(OUTDIR)/map.obj: $(OUTDIR) map.c $(INCL)
$(OUTDIR)/mark.obj: $(OUTDIR) mark.c $(INCL)
$(OUTDIR)/match.obj: $(OUTDIR) match.c $(INCL)
$(OUTDIR)/memfile.obj: $(OUTDIR) memfile.c $(INCL)
$(OUTDIR)/memline.obj: $(OUTDIR) memline.c $(INCL)
@@ -1935,6 +1938,7 @@ proto.h: \
proto/main.pro \
proto/map.pro \
proto/mark.pro \
proto/match.pro \
proto/memfile.pro \
proto/memline.pro \
proto/menu.pro \
+5
View File
@@ -347,6 +347,7 @@ SRC = \
main.c \
map.c \
mark.c \
match.c \
mbyte.c \
memfile.c \
memline.c \
@@ -460,6 +461,7 @@ OBJ = \
main.obj \
map.obj \
mark.obj \
match.obj \
mbyte.obj \
memfile.obj \
memline.obj \
@@ -867,6 +869,9 @@ map.obj : map.c vim.h [.auto]config.h feature.h os_unix.h \
mark.obj : mark.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h
match.obj : match.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h gui.h beval.h \
[.proto]gui_beval.pro option.h ex_cmds.h proto.h globals.h
memfile.obj : memfile.c vim.h [.auto]config.h feature.h os_unix.h \
ascii.h keymap.h term.h macros.h structs.h regexp.h \
gui.h beval.h [.proto]gui_beval.pro option.h ex_cmds.h proto.h \
+10 -1
View File
@@ -1666,6 +1666,7 @@ BASIC_SRC = \
main.c \
map.c \
mark.c \
match.c \
mbyte.c \
memfile.c \
memline.c \
@@ -1814,6 +1815,7 @@ OBJ_COMMON = \
objects/list.o \
objects/map.o \
objects/mark.o \
objects/match.o \
objects/mbyte.o \
objects/memline.o \
objects/menu.o \
@@ -1988,6 +1990,7 @@ PRO_AUTO = \
main.pro \
map.pro \
mark.pro \
match.pro \
mbyte.pro \
memfile.pro \
memline.pro \
@@ -2322,7 +2325,6 @@ test1 \
test42 test44 test49 \
test52 test59 \
test70 \
test86 test87 \
test99:
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTESTTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
@@ -3405,6 +3407,9 @@ objects/map.o: map.c
objects/mark.o: mark.c
$(CCC) -o $@ mark.c
objects/match.o: match.c
$(CCC) -o $@ match.c
objects/memfile.o: memfile.c
$(CCC) -o $@ memfile.c
@@ -4034,6 +4039,10 @@ objects/mark.o: mark.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
objects/match.o: match.c vim.h protodef.h auto/config.h feature.h \
os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
proto.h globals.h
objects/mbyte.o: mbyte.c vim.h protodef.h auto/config.h feature.h os_unix.h \
auto/osdef.h ascii.h keymap.h term.h macros.h option.h beval.h \
proto/gui_beval.pro structs.h regexp.h gui.h alloc.h ex_cmds.h spell.h \
+2 -1
View File
@@ -51,8 +51,9 @@ getchar.c | getting characters and key mapping
highlight.c | syntax highlighting
indent.c | text indentation
insexpand.c | Insert mode completion
mark.c | marks
map.c | mapping and abbreviations
mark.c | marks
match.c | highlight matching
mbyte.c | multi-byte character handling
memfile.c | storing lines for buffers in a swapfile
memline.c | storing lines for buffers in memory
+2 -2
View File
@@ -14276,8 +14276,8 @@ else
main() {
uint32_t nr1 = (uint32_t)-1;
uint32_t nr2 = (uint32_t)0xffffffffUL;
if (sizeof(uint32_t) != 4 || nr1 != 0xffffffffUL || nr2 + 1 != 0) exit(1);
exit(0);
if (sizeof(uint32_t) != 4 || nr1 != 0xffffffffUL || nr2 + 1 != 0) return 1;
return 0;
}
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
+1 -1
View File
@@ -285,7 +285,7 @@ general_beval_cb(BalloonEval *beval, int state UNUSED)
++textwinlock;
vim_free(result);
result = eval_to_string(bexpr, NULL, TRUE);
result = eval_to_string(bexpr, TRUE);
// Remove one trailing newline, it is added when the result was a
// list and it's hardly ever useful. If the user really wants a
+2 -2
View File
@@ -4104,7 +4104,7 @@ build_stl_str_hl(
tv.vval.v_number = wp->w_id;
set_var((char_u *)"g:statusline_winid", &tv, FALSE);
usefmt = eval_to_string_safe(fmt + 2, NULL, use_sandbox);
usefmt = eval_to_string_safe(fmt + 2, use_sandbox);
if (usefmt == NULL)
usefmt = fmt;
@@ -4444,7 +4444,7 @@ build_stl_str_hl(
if (curwin != save_curwin)
VIsual_active = FALSE;
str = eval_to_string_safe(p, &t, use_sandbox);
str = eval_to_string_safe(p, use_sandbox);
curwin = save_curwin;
curbuf = save_curbuf;
+1 -1
View File
@@ -86,7 +86,7 @@ eval_client_expr_to_string(char_u *expr)
// to be typed. Do generate errors so that try/catch works.
++emsg_silent;
res = eval_to_string(expr, NULL, TRUE);
res = eval_to_string(expr, TRUE);
debug_break_level = save_dbl;
redir_off = save_ro;
+9 -8
View File
@@ -1099,6 +1099,15 @@ set_one_cmd_context(
arg = skipwhite(p);
// Skip over ++argopt argument
if ((ea.argt & EX_ARGOPT) && *arg != NUL && STRNCMP(arg, "++", 2) == 0)
{
p = arg;
while (*p && !vim_isspace(*p))
MB_PTR_ADV(p);
arg = skipwhite(p);
}
if (ea.cmdidx == CMD_write || ea.cmdidx == CMD_update)
{
if (*arg == '>') // append
@@ -1146,14 +1155,6 @@ set_one_cmd_context(
arg = skipwhite(arg);
}
// Skip over ++argopt argument
if ((ea.argt & EX_ARGOPT) && *arg != NUL && STRNCMP(arg, "++", 2) == 0)
{
p = arg;
while (*p && !vim_isspace(*p))
MB_PTR_ADV(p);
arg = skipwhite(p);
}
// Check for '|' to separate commands and '"' to start comments.
// Don't do this for ":read !cmd" and ":write !cmd".
+2 -2
View File
@@ -4249,8 +4249,8 @@ AC_TRY_RUN([
main() {
uint32_t nr1 = (uint32_t)-1;
uint32_t nr2 = (uint32_t)0xffffffffUL;
if (sizeof(uint32_t) != 4 || nr1 != 0xffffffffUL || nr2 + 1 != 0) exit(1);
exit(0);
if (sizeof(uint32_t) != 4 || nr1 != 0xffffffffUL || nr2 + 1 != 0) return 1;
return 0;
}],
AC_MSG_RESULT(ok),
AC_MSG_ERROR([WRONG! uint32_t not defined correctly.]),
+31 -9
View File
@@ -787,13 +787,15 @@ get_literal_key(char_u **arg, typval_T *tv)
/*
* Allocate a variable for a Dictionary and fill it from "*arg".
* "*arg" points to the "{".
* "literal" is TRUE for #{key: val}
* Return OK or FAIL. Returns NOTDONE for {expr}.
*/
int
eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal)
{
int evaluate = flags & EVAL_EVALUATE;
int evaluate = evalarg == NULL ? FALSE
: evalarg->eval_flags & EVAL_EVALUATE;
dict_T *d = NULL;
typval_T tvkey;
typval_T tv;
@@ -802,6 +804,7 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
char_u *start = skipwhite(*arg + 1);
char_u buf[NUMBUFLEN];
int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9;
int had_comma;
/*
* First check if it's not a curly-braces thing: {expr}.
@@ -812,7 +815,7 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
*/
if (!vim9script && *start != '}')
{
if (eval1(&start, &tv, 0) == FAIL) // recursive!
if (eval1(&start, &tv, NULL) == FAIL) // recursive!
return FAIL;
if (*start == '}')
return NOTDONE;
@@ -827,12 +830,12 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
tvkey.v_type = VAR_UNKNOWN;
tv.v_type = VAR_UNKNOWN;
*arg = skipwhite(*arg + 1);
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
while (**arg != '}' && **arg != NUL)
{
if ((literal
? get_literal_key(arg, &tvkey)
: eval1(arg, &tvkey, flags)) == FAIL) // recursive!
: eval1(arg, &tvkey, evalarg)) == FAIL) // recursive!
goto failret;
if (**arg != ':')
@@ -852,9 +855,15 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
goto failret;
}
}
if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1]))
{
semsg(_(e_white_after), ":");
clear_tv(&tvkey);
goto failret;
}
*arg = skipwhite(*arg + 1);
if (eval1(arg, &tv, flags) == FAIL) // recursive!
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
if (eval1(arg, &tv, evalarg) == FAIL) // recursive!
{
if (evaluate)
clear_tv(&tvkey);
@@ -882,15 +891,28 @@ eval_dict(char_u **arg, typval_T *rettv, int flags, int literal)
}
clear_tv(&tvkey);
// the comma must come after the value
had_comma = **arg == ',';
if (had_comma)
{
if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1]))
{
semsg(_(e_white_after), ",");
goto failret;
}
*arg = skipwhite(*arg + 1);
}
// the "}" can be on the next line
*arg = skipwhite_and_linebreak(*arg, evalarg);
if (**arg == '}')
break;
if (**arg != ',')
if (!had_comma)
{
if (evaluate)
semsg(_(e_missing_dict_comma), *arg);
goto failret;
}
*arg = skipwhite(*arg + 1);
}
if (**arg != '}')
+10 -4
View File
@@ -967,7 +967,7 @@ win_line(
for (;;)
{
#if defined(FEAT_CONCEAL) || defined(FEAT_SEARCH_EXTRA)
int has_match_conc = 0; // match wants to conceal
int has_match_conc = 0; // match wants to conceal
#endif
#ifdef FEAT_CONCEAL
int did_decrement_ptr = FALSE;
@@ -1334,6 +1334,11 @@ win_line(
&screen_search_hl, &has_match_conc,
&match_conc, did_line_attr, lcs_eol_one);
ptr = line + v; // "line" may have been changed
// Do not allow a conceal over EOL otherwise EOL will be missed
// and bad things happen.
if (*ptr == NUL)
has_match_conc = 0;
}
#endif
@@ -2353,13 +2358,14 @@ win_line(
{
char_attr = conceal_attr;
if ((prev_syntax_id != syntax_seqnr || has_match_conc > 1)
&& (syn_get_sub_char() != NUL || match_conc
|| wp->w_p_cole == 1)
&& (syn_get_sub_char() != NUL
|| (has_match_conc && match_conc)
|| wp->w_p_cole == 1)
&& wp->w_p_cole != 3)
{
// First time at this concealed item: display one
// character.
if (match_conc)
if (has_match_conc && match_conc)
c = match_conc;
else if (syn_get_sub_char() != NUL)
c = syn_get_sub_char();
+489 -158
View File
File diff suppressed because it is too large Load Diff
+65 -19
View File
@@ -347,6 +347,52 @@ ret_first_arg(int argcount, type_T **argtypes)
return &t_void;
}
/*
* Used for getqflist(): returns list if there is no argument, dict if there is
* one.
*/
static type_T *
ret_list_or_dict_0(int argcount, type_T **argtypes UNUSED)
{
if (argcount > 0)
return &t_dict_any;
return &t_list_dict_any;
}
/*
* Used for getloclist(): returns list if there is one argument, dict if there
* are two.
*/
static type_T *
ret_list_or_dict_1(int argcount, type_T **argtypes UNUSED)
{
if (argcount > 1)
return &t_dict_any;
return &t_list_dict_any;
}
static type_T *
ret_argv(int argcount, type_T **argtypes UNUSED)
{
// argv() returns list of strings
if (argcount == 0)
return &t_list_string;
// argv(0) returns a string, but argv(-1] returns a list
return &t_any;
}
static type_T *
ret_remove(int argcount UNUSED, type_T **argtypes)
{
if (argtypes[0]->tt_type == VAR_LIST
|| argtypes[0]->tt_type == VAR_DICT)
return argtypes[0]->tt_member;
if (argtypes[0]->tt_type == VAR_BLOB)
return &t_number;
return &t_any;
}
static type_T *ret_f_function(int argcount, type_T **argtypes);
/*
@@ -417,14 +463,14 @@ static funcentry_T global_functions[] =
{
{"abs", 1, 1, FEARG_1, ret_any, FLOAT_FUNC(f_abs)},
{"acos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_acos)},
{"add", 2, 2, FEARG_1, ret_any, f_add},
{"add", 2, 2, FEARG_1, ret_first_arg, f_add},
{"and", 2, 2, FEARG_1, ret_number, f_and},
{"append", 2, 2, FEARG_LAST, ret_number, f_append},
{"appendbufline", 3, 3, FEARG_LAST, ret_number, f_appendbufline},
{"argc", 0, 1, 0, ret_number, f_argc},
{"argidx", 0, 0, 0, ret_number, f_argidx},
{"arglistid", 0, 2, 0, ret_number, f_arglistid},
{"argv", 0, 2, 0, ret_any, f_argv},
{"argv", 0, 2, 0, ret_argv, f_argv},
{"asin", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_asin)},
{"assert_beeps", 1, 2, FEARG_1, ret_number, f_assert_beeps},
{"assert_equal", 2, 3, FEARG_2, ret_number, f_assert_equal},
@@ -509,7 +555,7 @@ static funcentry_T global_functions[] =
{"complete_check", 0, 0, 0, ret_number, f_complete_check},
{"complete_info", 0, 1, FEARG_1, ret_dict_any, f_complete_info},
{"confirm", 1, 4, FEARG_1, ret_number, f_confirm},
{"copy", 1, 1, FEARG_1, ret_any, f_copy},
{"copy", 1, 1, FEARG_1, ret_first_arg, f_copy},
{"cos", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cos)},
{"cosh", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_cosh)},
{"count", 2, 4, FEARG_1, ret_number, f_count},
@@ -522,7 +568,7 @@ static funcentry_T global_functions[] =
NULL
#endif
},
{"deepcopy", 1, 2, FEARG_1, ret_any, f_deepcopy},
{"deepcopy", 1, 2, FEARG_1, ret_first_arg, f_deepcopy},
{"delete", 1, 2, FEARG_1, ret_number, f_delete},
{"deletebufline", 2, 3, FEARG_1, ret_number, f_deletebufline},
{"did_filetype", 0, 0, 0, ret_number, f_did_filetype},
@@ -541,12 +587,12 @@ static funcentry_T global_functions[] =
{"exp", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_exp)},
{"expand", 1, 3, FEARG_1, ret_any, f_expand},
{"expandcmd", 1, 1, FEARG_1, ret_string, f_expandcmd},
{"extend", 2, 3, FEARG_1, ret_any, f_extend},
{"extend", 2, 3, FEARG_1, ret_first_arg, f_extend},
{"feedkeys", 1, 2, FEARG_1, ret_void, f_feedkeys},
{"file_readable", 1, 1, FEARG_1, ret_number, f_filereadable}, // obsolete
{"filereadable", 1, 1, FEARG_1, ret_number, f_filereadable},
{"filewritable", 1, 1, FEARG_1, ret_number, f_filewritable},
{"filter", 2, 2, FEARG_1, ret_any, f_filter},
{"filter", 2, 2, FEARG_1, ret_first_arg, f_filter},
{"finddir", 1, 3, FEARG_1, ret_string, f_finddir},
{"findfile", 1, 3, FEARG_1, ret_string, f_findfile},
{"flatten", 1, 2, FEARG_1, ret_list_any, f_flatten},
@@ -588,13 +634,13 @@ static funcentry_T global_functions[] =
{"getimstatus", 0, 0, 0, ret_number, f_getimstatus},
{"getjumplist", 0, 2, FEARG_1, ret_list_any, f_getjumplist},
{"getline", 1, 2, FEARG_1, ret_f_getline, f_getline},
{"getloclist", 1, 2, 0, ret_list_dict_any, f_getloclist},
{"getloclist", 1, 2, 0, ret_list_or_dict_1, f_getloclist},
{"getmarklist", 0, 1, FEARG_1, ret_list_dict_any, f_getmarklist},
{"getmatches", 0, 1, 0, ret_list_dict_any, f_getmatches},
{"getmousepos", 0, 0, 0, ret_dict_number, f_getmousepos},
{"getpid", 0, 0, 0, ret_number, f_getpid},
{"getpos", 1, 1, FEARG_1, ret_list_number, f_getpos},
{"getqflist", 0, 1, 0, ret_list_dict_any, f_getqflist},
{"getqflist", 0, 1, 0, ret_list_or_dict_0, f_getqflist},
{"getreg", 0, 3, FEARG_1, ret_string, f_getreg},
{"getreginfo", 0, 1, FEARG_1, ret_dict_any, f_getreginfo},
{"getregtype", 0, 1, FEARG_1, ret_string, f_getregtype},
@@ -632,7 +678,7 @@ static funcentry_T global_functions[] =
{"inputrestore", 0, 0, 0, ret_number, f_inputrestore},
{"inputsave", 0, 0, 0, ret_number, f_inputsave},
{"inputsecret", 1, 2, FEARG_1, ret_string, f_inputsecret},
{"insert", 2, 3, FEARG_1, ret_any, f_insert},
{"insert", 2, 3, FEARG_1, ret_first_arg, f_insert},
{"interrupt", 0, 0, 0, ret_void, f_interrupt},
{"invert", 1, 1, FEARG_1, ret_number, f_invert},
{"isdirectory", 1, 1, FEARG_1, ret_number, f_isdirectory},
@@ -791,12 +837,12 @@ static funcentry_T global_functions[] =
{"remote_peek", 1, 2, FEARG_1, ret_number, f_remote_peek},
{"remote_read", 1, 2, FEARG_1, ret_string, f_remote_read},
{"remote_send", 2, 3, FEARG_1, ret_string, f_remote_send},
{"remote_startserver", 1, 1, FEARG_1, ret_void, f_remote_startserver},
{"remove", 2, 3, FEARG_1, ret_any, f_remove},
{"remote_startserver", 1, 1, FEARG_1, ret_void, f_remote_startserver},
{"remove", 2, 3, FEARG_1, ret_remove, f_remove},
{"rename", 2, 2, FEARG_1, ret_number, f_rename},
{"repeat", 2, 2, FEARG_1, ret_any, f_repeat},
{"repeat", 2, 2, FEARG_1, ret_first_arg, f_repeat},
{"resolve", 1, 1, FEARG_1, ret_string, f_resolve},
{"reverse", 1, 1, FEARG_1, ret_any, f_reverse},
{"reverse", 1, 1, FEARG_1, ret_first_arg, f_reverse},
{"round", 1, 1, FEARG_1, ret_float, FLOAT_FUNC(f_round)},
{"rubyeval", 1, 1, FEARG_1, ret_any,
#ifdef FEAT_RUBY
@@ -2084,7 +2130,7 @@ f_eval(typval_T *argvars, typval_T *rettv)
s = skipwhite(s);
p = s;
if (s == NULL || eval1(&s, rettv, EVAL_EVALUATE) == FAIL)
if (s == NULL || eval1(&s, rettv, &EVALARG_EVALUATE) == FAIL)
{
if (p != NULL && !aborting())
semsg(_(e_invexpr2), p);
@@ -2300,7 +2346,7 @@ f_exists(typval_T *argvars, typval_T *rettv)
}
else if (*p == '&' || *p == '+') // option
{
n = (get_option_tv(&p, NULL, TRUE) == OK);
n = (eval_option(&p, NULL, TRUE) == OK);
if (*skipwhite(p) != NUL)
n = FALSE; // trailing garbage
}
@@ -6307,7 +6353,7 @@ f_getreginfo(typval_T *argvars, typval_T *rettv)
list = (list_T *)get_reg_contents(regname, GREG_EXPR_SRC | GREG_LIST);
if (list == NULL)
return;
dict_add_list(dict, "regcontents", list);
(void)dict_add_list(dict, "regcontents", list);
buf[0] = NUL;
buf[1] = NUL;
@@ -6320,12 +6366,12 @@ f_getreginfo(typval_T *argvars, typval_T *rettv)
reglen + 1);
break;
}
dict_add_string(dict, (char *)"regtype", buf);
(void)dict_add_string(dict, (char *)"regtype", buf);
buf[0] = get_register_name(get_unname_register());
buf[1] = NUL;
if (regname == '"')
dict_add_string(dict, (char *)"points_to", buf);
(void)dict_add_string(dict, (char *)"points_to", buf);
else
{
dictitem_T *item = dictitem_alloc((char_u *)"isunnamed");
@@ -6335,7 +6381,7 @@ f_getreginfo(typval_T *argvars, typval_T *rettv)
item->di_tv.v_type = VAR_SPECIAL;
item->di_tv.vval.v_number = regname == buf[0]
? VVAL_TRUE : VVAL_FALSE;
dict_add(dict, item);
(void)dict_add(dict, item);
}
}
}
+22 -15
View File
@@ -437,7 +437,7 @@ eval_spell_expr(char_u *badword, char_u *expr)
if (p_verbose == 0)
++emsg_off;
if (eval1(&p, &rettv, EVAL_EVALUATE) == OK)
if (eval1(&p, &rettv, &EVALARG_EVALUATE) == OK)
{
if (rettv.v_type != VAR_LIST)
clear_tv(&rettv);
@@ -776,7 +776,7 @@ ex_let(exarg_T *eap)
}
else
{
int eval_flags;
evalarg_T evalarg;
rettv.v_type = VAR_UNKNOWN;
i = FAIL;
@@ -799,14 +799,22 @@ ex_let(exarg_T *eap)
if (eap->skip)
++emsg_skip;
eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
i = eval0(expr, &rettv, &eap->nextcmd, eval_flags);
CLEAR_FIELD(evalarg);
evalarg.eval_flags = eap->skip ? 0 : EVAL_EVALUATE;
if (getline_equal(eap->getline, eap->cookie, getsourceline))
{
evalarg.eval_getline = eap->getline;
evalarg.eval_cookie = eap->cookie;
}
i = eval0(expr, &rettv, eap, &evalarg);
if (eap->skip)
--emsg_skip;
clear_evalarg(&evalarg, eap);
}
if (eap->skip)
{
if (i != FAIL)
clear_tv(&rettv);
--emsg_skip;
}
else if (i != FAIL)
{
@@ -1118,14 +1126,14 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
{
if (tofree != NULL)
name = tofree;
if (get_var_tv(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
if (eval_variable(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
error = TRUE;
else
{
// handle d.key, l[idx], f(expr)
arg_subsc = arg;
if (handle_subscript(&arg, &tv, EVAL_EVALUATE, TRUE,
name, &name) == FAIL)
if (handle_subscript(&arg, &tv, &EVALARG_EVALUATE, TRUE)
== FAIL)
error = TRUE;
else
{
@@ -2359,7 +2367,7 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
* Return OK or FAIL. If OK is returned "rettv" must be cleared.
*/
int
get_var_tv(
eval_variable(
char_u *name,
int len, // length of "name"
typval_T *rettv, // NULL when only checking existence
@@ -2846,7 +2854,7 @@ set_var(
typval_T *tv,
int copy) // make copy of value in "tv"
{
set_var_const(name, NULL, tv, copy, 0);
set_var_const(name, NULL, tv, copy, LET_NO_COMMAND);
}
/*
@@ -3200,7 +3208,7 @@ getwinvar(
done = TRUE;
}
}
else if (get_option_tv(&varname, rettv, 1) == OK)
else if (eval_option(&varname, rettv, 1) == OK)
// window-local-option
done = TRUE;
}
@@ -3336,12 +3344,11 @@ var_exists(char_u *var)
{
if (tofree != NULL)
name = tofree;
n = (get_var_tv(name, len, &tv, NULL, FALSE, TRUE) == OK);
n = (eval_variable(name, len, &tv, NULL, FALSE, TRUE) == OK);
if (n)
{
// handle d.key, l[idx], f(expr)
n = (handle_subscript(&var, &tv, EVAL_EVALUATE,
FALSE, name, &name) == OK);
n = (handle_subscript(&var, &tv, &EVALARG_EVALUATE, FALSE) == OK);
if (n)
clear_tv(&tv);
}
@@ -3604,7 +3611,7 @@ f_getbufvar(typval_T *argvars, typval_T *rettv)
done = TRUE;
}
}
else if (get_option_tv(&varname, rettv, TRUE) == OK)
else if (eval_option(&varname, rettv, TRUE) == OK)
// buffer-local-option
done = TRUE;
+3
View File
@@ -1847,6 +1847,9 @@ struct exarg
char_u *nextcmd; // next command (NULL if none)
char_u *cmd; // the name of the command (except for :make)
char_u **cmdlinep; // pointer to pointer of allocated cmdline
#ifdef FEAT_EVAL
char_u *cmdline_tofree; // free later
#endif
cmdidx_T cmdidx; // the index for the command
long argt; // flags for the command
int skip; // don't execute the command, only parse it
+124 -64
View File
@@ -25,7 +25,6 @@ static char_u *do_one_cmd(char_u **, int, cstack_T *, char_u *(*fgetline)(int, v
static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int, int), void *cookie);
static int if_level = 0; // depth in :if
#endif
static void free_cmdmod(void);
static void append_command(char_u *cmd);
#ifndef FEAT_MENU
@@ -635,6 +634,7 @@ do_cmdline(
cstack_T cstack; // conditional stack
garray_T lines_ga; // keep lines for ":while"/":for"
int current_line = 0; // active line in lines_ga
int current_line_before = 0;
char_u *fname = NULL; // function or script name
linenr_T *breakpoint = NULL; // ptr to breakpoint field in cookie
int *dbg_tick = NULL; // ptr to dbg_tick field in cookie
@@ -857,27 +857,6 @@ do_cmdline(
}
# endif
}
if (cstack.cs_looplevel > 0)
{
// Inside a while/for loop we need to store the lines and use them
// again. Pass a different "fgetline" function to do_one_cmd()
// below, so that it stores lines in or reads them from
// "lines_ga". Makes it possible to define a function inside a
// while/for loop.
cmd_getline = get_loop_line;
cmd_cookie = (void *)&cmd_loop_cookie;
cmd_loop_cookie.lines_gap = &lines_ga;
cmd_loop_cookie.current_line = current_line;
cmd_loop_cookie.getline = fgetline;
cmd_loop_cookie.cookie = cookie;
cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
}
else
{
cmd_getline = fgetline;
cmd_cookie = cookie;
}
#endif
// 2. If no line given, get an allocated line with fgetline().
@@ -935,21 +914,44 @@ do_cmdline(
#ifdef FEAT_EVAL
/*
* Save the current line when inside a ":while" or ":for", and when
* the command looks like a ":while" or ":for", because we may need it
* later. When there is a '|' and another command, it is stored
* separately, because we need to be able to jump back to it from an
* Inside a while/for loop, and when the command looks like a ":while"
* or ":for", the line is stored, because we may need it later when
* looping.
*
* When there is a '|' and another command, it is stored separately,
* because we need to be able to jump back to it from an
* :endwhile/:endfor.
*
* Pass a different "fgetline" function to do_one_cmd() below,
* that it stores lines in or reads them from "lines_ga". Makes it
* possible to define a function inside a while/for loop and handles
* line continuation.
*/
if (current_line == lines_ga.ga_len
&& (cstack.cs_looplevel || has_loop_cmd(next_cmdline)))
if ((cstack.cs_looplevel > 0 || has_loop_cmd(next_cmdline)))
{
if (store_loop_line(&lines_ga, next_cmdline) == FAIL)
cmd_getline = get_loop_line;
cmd_cookie = (void *)&cmd_loop_cookie;
cmd_loop_cookie.lines_gap = &lines_ga;
cmd_loop_cookie.current_line = current_line;
cmd_loop_cookie.getline = fgetline;
cmd_loop_cookie.cookie = cookie;
cmd_loop_cookie.repeating = (current_line < lines_ga.ga_len);
// Save the current line when encountering it the first time.
if (current_line == lines_ga.ga_len
&& store_loop_line(&lines_ga, next_cmdline) == FAIL)
{
retval = FAIL;
break;
}
current_line_before = current_line;
}
else
{
cmd_getline = fgetline;
cmd_cookie = cookie;
}
did_endif = FALSE;
#endif
@@ -1084,7 +1086,7 @@ do_cmdline(
else if (cstack.cs_lflags & CSL_HAD_LOOP)
{
cstack.cs_lflags &= ~CSL_HAD_LOOP;
cstack.cs_line[cstack.cs_idx] = current_line - 1;
cstack.cs_line[cstack.cs_idx] = current_line_before;
}
}
@@ -1521,7 +1523,7 @@ getline_cookie(
{
#ifdef FEAT_EVAL
char_u *(*gp)(int, void *, int, int);
struct loop_cookie *cp;
struct loop_cookie *cp;
// When "fgetline" is "get_loop_line()" use the "cookie" to find the
// cookie that's originally used to obtain the lines. This may be nested
@@ -1539,6 +1541,41 @@ getline_cookie(
#endif
}
#if defined(FEAT_EVAL) || defined(PROT)
/*
* Get the next line source line without advancing.
*/
char_u *
getline_peek(
char_u *(*fgetline)(int, void *, int, int) UNUSED,
void *cookie) // argument for fgetline()
{
char_u *(*gp)(int, void *, int, int);
struct loop_cookie *cp;
wcmd_T *wp;
// When "fgetline" is "get_loop_line()" use the "cookie" to find the
// cookie that's originally used to obtain the lines. This may be nested
// several levels.
gp = fgetline;
cp = (struct loop_cookie *)cookie;
while (gp == get_loop_line)
{
if (cp->current_line + 1 < cp->lines_gap->ga_len)
{
// executing lines a second time, use the stored copy
wp = (wcmd_T *)(cp->lines_gap->ga_data) + cp->current_line + 1;
return wp->line;
}
gp = cp->getline;
cp = cp->cookie;
}
if (gp == getsourceline)
return source_nextline(cp);
return NULL;
}
#endif
/*
* Helper function to apply an offset for buffer commands, i.e. ":bdelete",
@@ -2579,32 +2616,10 @@ doend:
? cmdnames[(int)ea.cmdidx].cmd_name : (char_u *)NULL);
#endif
if (ea.verbose_save >= 0)
p_verbose = ea.verbose_save;
free_cmdmod();
undo_cmdmod(&ea, save_msg_scroll);
cmdmod = save_cmdmod;
reg_executing = save_reg_executing;
if (ea.save_msg_silent != -1)
{
// messages could be enabled for a serious error, need to check if the
// counters don't become negative
if (!did_emsg || msg_silent > ea.save_msg_silent)
msg_silent = ea.save_msg_silent;
emsg_silent -= ea.did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
// Restore msg_scroll, it's set by file I/O commands, even when no
// message is actually displayed.
msg_scroll = save_msg_scroll;
// "silent reg" or "silent echo x" inside "redir" leaves msg_col
// somewhere in the line. Put it back in the first column.
if (redirecting())
msg_col = 0;
}
#ifdef HAVE_SANDBOX
if (ea.did_sandbox)
--sandbox;
@@ -2615,6 +2630,7 @@ doend:
#ifdef FEAT_EVAL
--ex_nesting_level;
vim_free(ea.cmdline_tofree);
#endif
return ea.nextcmd;
@@ -2894,11 +2910,14 @@ parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only)
}
/*
* Free contents of "cmdmod".
* Unod and free contents of "cmdmod".
*/
static void
free_cmdmod(void)
void
undo_cmdmod(exarg_T *eap, int save_msg_scroll)
{
if (eap->verbose_save >= 0)
p_verbose = eap->verbose_save;
if (cmdmod.save_ei != NULL)
{
// Restore 'eventignore' to the value before ":noautocmd".
@@ -2909,6 +2928,25 @@ free_cmdmod(void)
if (cmdmod.filter_regmatch.regprog != NULL)
vim_regfree(cmdmod.filter_regmatch.regprog);
if (eap->save_msg_silent != -1)
{
// messages could be enabled for a serious error, need to check if the
// counters don't become negative
if (!did_emsg || msg_silent > eap->save_msg_silent)
msg_silent = eap->save_msg_silent;
emsg_silent -= eap->did_esilent;
if (emsg_silent < 0)
emsg_silent = 0;
// Restore msg_scroll, it's set by file I/O commands, even when no
// message is actually displayed.
msg_scroll = save_msg_scroll;
// "silent reg" or "silent echo x" inside "redir" leaves msg_col
// somewhere in the line. Put it back in the first column.
if (redirecting())
msg_col = 0;
}
}
/*
@@ -3186,8 +3224,9 @@ find_ex_command(
* "lvar = value", "lvar(arg)", "[1, 2 3]->Func()"
*/
p = eap->cmd;
if (lookup != NULL && (*p == '('
|| ((p = to_name_const_end(eap->cmd)) > eap->cmd && *p != NUL)))
if (lookup != NULL && (*p == '(' || *p == '{'
|| ((p = to_name_const_end(eap->cmd)) > eap->cmd && *p != NUL)
|| *p == '['))
{
int oplen;
int heredoc;
@@ -3197,8 +3236,10 @@ find_ex_command(
// "g:varname" is an expression.
// "varname->expr" is an expression.
// "(..." is an expression.
// "{..." is an dict expression.
if (*p == '('
|| *p == '['
|| *p == '{'
|| (*p == '[' && p > eap->cmd)
|| p[1] == ':'
|| (*p == '-' && p[1] == '>'))
{
@@ -3206,12 +3247,24 @@ find_ex_command(
return eap->cmd;
}
// "[...]->Method()" is a list expression, but "[a, b] = Func()" is
// an assignment.
// If there is no line break inside the "[...]" then "p" is advanced to
// after the "]" by to_name_const_end(): check if a "=" follows.
// If "[...]" has a line break "p" still points at the "[" and it can't
// be an assignment.
if (*eap->cmd == '[' && (p == eap->cmd || *skipwhite(p) != '='))
{
eap->cmdidx = CMD_eval;
return eap->cmd;
}
// Recognize an assignment if we recognize the variable name:
// "g:var = expr"
// "var = expr" where "var" is a local var name.
oplen = assignment_len(skipwhite(p), &heredoc);
if (oplen > 0)
{
// Recognize an assignment if we recognize the variable name:
// "g:var = expr"
// "var = expr" where "var" is a local var name.
if (((p - eap->cmd) > 2 && eap->cmd[1] == ':')
|| lookup(eap->cmd, p - eap->cmd, cctx) != NULL)
{
@@ -4918,7 +4971,7 @@ ex_colorscheme(exarg_T *eap)
if (expr != NULL)
{
++emsg_off;
p = eval_to_string(expr, NULL, FALSE);
p = eval_to_string(expr, FALSE);
--emsg_off;
vim_free(expr);
}
@@ -5183,6 +5236,13 @@ ex_win_close(
int need_hide;
buf_T *buf = win->w_buffer;
// Never close the autocommand window.
if (win == aucmd_win)
{
emsg(_(e_autocmd_close));
return;
}
need_hide = (bufIsChanged(buf) && buf->b_nwindows <= 1);
if (need_hide && !buf_hide(buf) && !forceit)
{
+25 -8
View File
@@ -895,10 +895,14 @@ report_discard_pending(int pending, void *value)
ex_eval(exarg_T *eap)
{
typval_T tv;
evalarg_T evalarg;
if (eval0(eap->arg, &tv, &eap->nextcmd, eap->skip ? 0 : EVAL_EVALUATE)
== OK)
fill_evalarg_from_eap(&evalarg, eap, eap->skip);
if (eval0(eap->arg, &tv, eap, &evalarg) == OK)
clear_tv(&tv);
clear_evalarg(&evalarg, eap);
}
/*
@@ -926,7 +930,7 @@ ex_if(exarg_T *eap)
skip = did_emsg || got_int || did_throw || (cstack->cs_idx > 0
&& !(cstack->cs_flags[cstack->cs_idx - 1] & CSF_ACTIVE));
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
result = eval_to_bool(eap->arg, &error, eap, skip);
if (!skip && !error)
{
@@ -1038,7 +1042,7 @@ ex_else(exarg_T *eap)
if (eap->cmdidx == CMD_elseif)
{
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
result = eval_to_bool(eap->arg, &error, eap, skip);
// When throwing error exceptions, we want to throw always the first
// of several errors in a row. This is what actually happens when
@@ -1100,11 +1104,20 @@ ex_while(exarg_T *eap)
/*
* ":while bool-expr"
*/
result = eval_to_bool(eap->arg, &error, &eap->nextcmd, skip);
result = eval_to_bool(eap->arg, &error, eap, skip);
}
else
{
void *fi;
void *fi;
evalarg_T evalarg;
CLEAR_FIELD(evalarg);
evalarg.eval_flags = skip ? 0 : EVAL_EVALUATE;
if (getline_equal(eap->getline, eap->cookie, getsourceline))
{
evalarg.eval_getline = eap->getline;
evalarg.eval_cookie = eap->cookie;
}
/*
* ":for var in list-expr"
@@ -1115,11 +1128,14 @@ ex_while(exarg_T *eap)
// previously evaluated list.
fi = cstack->cs_forinfo[cstack->cs_idx];
error = FALSE;
// the "in expr" is not used, skip over it
skip_for_lines(fi, &evalarg);
}
else
{
// Evaluate the argument and get the info in a structure.
fi = eval_for_line(eap->arg, &error, &eap->nextcmd, skip);
fi = eval_for_line(eap->arg, &error, eap, &evalarg);
cstack->cs_forinfo[cstack->cs_idx] = fi;
}
@@ -1134,6 +1150,7 @@ ex_while(exarg_T *eap)
free_for_info(fi);
cstack->cs_forinfo[cstack->cs_idx] = NULL;
}
clear_evalarg(&evalarg, eap);
}
/*
@@ -1319,7 +1336,7 @@ ex_throw(exarg_T *eap)
char_u *value;
if (*arg != NUL && *arg != '|' && *arg != '\n')
value = eval_to_string_skip(arg, &eap->nextcmd, eap->skip);
value = eval_to_string_skip(arg, eap, eap->skip);
else
{
emsg(_(e_argreq));
+9 -5
View File
@@ -52,10 +52,14 @@ filemess(
if (msg_silent != 0)
return;
msg_add_fname(buf, name); // put file name in IObuff with quotes
// If it's extremely long, truncate it.
if (STRLEN(IObuff) > IOSIZE - 80)
IObuff[IOSIZE - 80] = NUL;
STRCAT(IObuff, s);
if (STRLEN(IObuff) > IOSIZE - 100)
IObuff[IOSIZE - 100] = NUL;
// Avoid an over-long translation to cause trouble.
STRNCAT(IObuff, s, 99);
/*
* For the first message may have to start a new line.
* For further ones overwrite the previous one, reset msg_scroll before
@@ -3035,13 +3039,13 @@ msg_add_lines(
*p++ = ' ';
if (shortmess(SHM_LINES))
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
"%ldL, %lldC", lnum, (varnumber_T)nchars);
"%ldL, %lldB", lnum, (varnumber_T)nchars);
else
{
sprintf((char *)p, NGETTEXT("%ld line, ", "%ld lines, ", lnum), lnum);
p += STRLEN(p);
vim_snprintf((char *)p, IOSIZE - (p - IObuff),
NGETTEXT("%lld character", "%lld characters", nchars),
NGETTEXT("%lld byte", "%lld bytes", nchars),
(varnumber_T)nchars);
}
}
+7 -2
View File
@@ -3083,7 +3083,7 @@ expand_backtick(
#ifdef FEAT_EVAL
if (*cmd == '=') // `={expr}`: Expand expression
buffer = eval_to_string(cmd + 1, &p, TRUE);
buffer = eval_to_string(cmd + 1, TRUE);
else
#endif
buffer = get_cmd_output(cmd, NULL,
@@ -3813,8 +3813,13 @@ gen_expand_wildcards(
vim_free(p);
}
// When returning FAIL the array must be freed here.
if (retval == FAIL)
ga_clear(&ga);
*num_file = ga.ga_len;
*file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data : (char_u **)"";
*file = (ga.ga_data != NULL) ? (char_u **)ga.ga_data
: (char_u **)_("no matches");
recursive = FALSE;
+1 -1
View File
@@ -2079,7 +2079,7 @@ eval_includeexpr(char_u *ptr, int len)
char_u *res;
set_vim_var_string(VV_FNAME, ptr, len);
res = eval_to_string_safe(curbuf->b_p_inex, NULL,
res = eval_to_string_safe(curbuf->b_p_inex,
was_set_insecurely((char_u *)"includeexpr", OPT_LOCAL));
set_vim_var_string(VV_FNAME, NULL, 0);
return res;
+1 -1
View File
@@ -1928,7 +1928,7 @@ get_foldtext(
curbuf = wp->w_buffer;
++emsg_silent; // handle exceptions, but don't display errors
text = eval_to_string_safe(wp->w_p_fdt, NULL,
text = eval_to_string_safe(wp->w_p_fdt,
was_set_insecurely((char_u *)"foldtext", OPT_LOCAL));
--emsg_silent;
+8
View File
@@ -1770,6 +1770,7 @@ EXTERN char e_float_as_string[] INIT(= N_("E806: using Float as a String"));
#endif
EXTERN char e_dirnotf[] INIT(= N_("E919: Directory not found in '%s': \"%s\""));
EXTERN char e_au_recursive[] INIT(= N_("E952: Autocommand caused recursive behavior"));
EXTERN char e_autocmd_close[] INIT(= N_("E813: Cannot close autocmd or popup window"));
#ifdef FEAT_MENU
EXTERN char e_menuothermode[] INIT(= N_("E328: Menu only exists in another mode"));
#endif
@@ -1885,6 +1886,13 @@ EXTERN char windowsVersion[20] INIT(= {0});
// Used for lv_first in a non-materialized range() list.
EXTERN listitem_T range_list_item;
// Passed to an eval() function to enable evaluation.
EXTERN evalarg_T EVALARG_EVALUATE
# ifdef DO_INIT
= {EVAL_EVALUATE, 0, NULL, NULL, {0, 0, 0, 0, NULL}, NULL}
# endif
;
#endif
#ifdef MSWIN
+1 -1
View File
@@ -57,7 +57,7 @@ xim_log(char *s, ...)
}
#endif
#ifdef FEAT_GUI
#if defined(FEAT_GUI_MSWIN)
# define USE_IMACTIVATEFUNC (!gui.in_use && *p_imaf != NUL)
# define USE_IMSTATUSFUNC (!gui.in_use && *p_imsf != NUL)
#else
-1345
View File
File diff suppressed because it is too large Load Diff
+159 -22
View File
@@ -35,6 +35,13 @@ typedef struct {
} luaV_Funcref;
typedef void (*msgfunc_T)(char_u *);
typedef struct {
int lua_funcref; // ref to a lua func
int lua_tableref; // ref to a lua table if metatable else LUA_NOREF. used
// for __call
lua_State *L;
} luaV_CFuncState;
static const char LUAVIM_DICT[] = "dict";
static const char LUAVIM_LIST[] = "list";
static const char LUAVIM_BLOB[] = "blob";
@@ -45,6 +52,8 @@ static const char LUAVIM_FREE[] = "luaV_free";
static const char LUAVIM_LUAEVAL[] = "luaV_luaeval";
static const char LUAVIM_SETREF[] = "luaV_setref";
static const char LUA___CALL[] = "__call";
// most functions are closures with a cache table as first upvalue;
// get/setudata manage references to vim userdata in cache table through
// object pointers (light userdata)
@@ -64,7 +73,7 @@ static const char LUAVIM_SETREF[] = "luaV_setref";
#define luaV_emsg(L) luaV_msgfunc((L), (msgfunc_T) emsg)
#define luaV_checktypval(L, a, v, msg) \
do { \
if (luaV_totypval(L, a, v) == FAIL) \
if (luaV_totypval(L, a, v) == FAIL) \
luaL_error(L, msg ": cannot convert value"); \
} while (0)
@@ -72,6 +81,8 @@ static luaV_List *luaV_pushlist(lua_State *L, list_T *lis);
static luaV_Dict *luaV_pushdict(lua_State *L, dict_T *dic);
static luaV_Blob *luaV_pushblob(lua_State *L, blob_T *blo);
static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
static int luaV_call_lua_func(int argcount, typval_T *argvars, typval_T *rettv, void *state);
static void luaV_call_lua_func_free(void *state);
#if LUA_VERSION_NUM <= 501
#define luaV_openlib(L, l, n) luaL_openlib(L, NULL, l, n)
@@ -120,6 +131,8 @@ static luaV_Funcref *luaV_pushfuncref(lua_State *L, char_u *name);
#define luaL_addlstring dll_luaL_addlstring
#define luaL_pushresult dll_luaL_pushresult
#define luaL_loadstring dll_luaL_loadstring
#define luaL_ref dll_luaL_ref
#define luaL_unref dll_luaL_unref
// lua
#if LUA_VERSION_NUM <= 501
#define lua_tonumber dll_lua_tonumber
@@ -215,6 +228,12 @@ void (*dll_luaL_buffinit) (lua_State *L, luaL_Buffer *B);
void (*dll_luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l);
void (*dll_luaL_pushresult) (luaL_Buffer *B);
int (*dll_luaL_loadstring) (lua_State *L, const char *s);
int (*dll_luaL_ref) (lua_State *L, int idx);
#if LUA_VERSION_NUM <= 502
void (*dll_luaL_unref) (lua_State *L, int idx, int n);
#else
void (*dll_luaL_unref) (lua_State *L, int idx, lua_Integer n);
#endif
// lua
#if LUA_VERSION_NUM <= 501
lua_Number (*dll_lua_tonumber) (lua_State *L, int idx);
@@ -328,6 +347,8 @@ static const luaV_Reg luaV_dll[] = {
{"luaL_addlstring", (luaV_function) &dll_luaL_addlstring},
{"luaL_pushresult", (luaV_function) &dll_luaL_pushresult},
{"luaL_loadstring", (luaV_function) &dll_luaL_loadstring},
{"luaL_ref", (luaV_function) &dll_luaL_ref},
{"luaL_unref", (luaV_function) &dll_luaL_unref},
// lua
#if LUA_VERSION_NUM <= 501
{"lua_tonumber", (luaV_function) &dll_lua_tonumber},
@@ -555,6 +576,8 @@ luaV_totypval(lua_State *L, int pos, typval_T *tv)
{
int status = OK;
tv->v_lock = 0;
switch (lua_type(L, pos))
{
case LUA_TBOOLEAN:
@@ -591,6 +614,45 @@ luaV_totypval(lua_State *L, int pos, typval_T *tv)
tv->vval.v_number = (varnumber_T) lua_tointeger(L, pos);
#endif
break;
case LUA_TFUNCTION:
{
char_u *name;
lua_pushvalue(L, pos);
luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
state->lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
state->L = L;
state->lua_tableref = LUA_NOREF;
name = register_cfunc(&luaV_call_lua_func,
&luaV_call_lua_func_free, state);
tv->v_type = VAR_FUNC;
tv->vval.v_string = vim_strsave(name);
break;
}
case LUA_TTABLE:
{
lua_pushvalue(L, pos);
int lua_tableref = luaL_ref(L, LUA_REGISTRYINDEX);
if (lua_getmetatable(L, pos)) {
lua_getfield(L, -1, LUA___CALL);
if (lua_isfunction(L, -1)) {
char_u *name;
int lua_funcref = luaL_ref(L, LUA_REGISTRYINDEX);
luaV_CFuncState *state = ALLOC_CLEAR_ONE(luaV_CFuncState);
state->lua_funcref = lua_funcref;
state->L = L;
state->lua_tableref = lua_tableref;
name = register_cfunc(&luaV_call_lua_func,
&luaV_call_lua_func_free, state);
tv->v_type = VAR_FUNC;
tv->vval.v_string = vim_strsave(name);
break;
}
}
tv->v_type = VAR_NUMBER;
tv->vval.v_number = 0;
status = FAIL;
break;
}
case LUA_TUSERDATA:
{
void *p = lua_touserdata(L, pos);
@@ -811,7 +873,13 @@ luaV_list_index(lua_State *L)
list_T *l = luaV_unbox(L, luaV_List, 1);
if (lua_isnumber(L, 2)) // list item?
{
listitem_T *li = list_find(l, (long) luaL_checkinteger(L, 2));
long n = (long) luaL_checkinteger(L, 2);
listitem_T *li;
// Lua array index starts with 1 while Vim uses 0, subtract 1 to
// normalize.
n -= 1;
li = list_find(l, n);
if (li == NULL)
lua_pushnil(L);
else
@@ -840,22 +908,38 @@ luaV_list_newindex(lua_State *L)
list_T *l = luaV_unbox(L, luaV_List, 1);
long n = (long) luaL_checkinteger(L, 2);
listitem_T *li;
// Lua array index starts with 1 while Vim uses 0, subtract 1 to normalize.
n -= 1;
if (l->lv_lock)
luaL_error(L, "list is locked");
li = list_find(l, n);
if (li == NULL) return 0;
if (lua_isnil(L, 3)) // remove?
if (li == NULL)
{
vimlist_remove(l, li, li);
listitem_free(l, li);
if (!lua_isnil(L, 3))
{
typval_T v;
luaV_checktypval(L, 3, &v, "inserting list item");
if (list_insert_tv(l, &v, li) == FAIL)
luaL_error(L, "failed to add item to list");
clear_tv(&v);
}
}
else
{
typval_T v;
luaV_checktypval(L, 3, &v, "setting list item");
clear_tv(&li->li_tv);
copy_tv(&v, &li->li_tv);
clear_tv(&v);
if (lua_isnil(L, 3)) // remove?
{
vimlist_remove(l, li, li);
listitem_free(l, li);
}
else
{
typval_T v;
luaV_checktypval(L, 3, &v, "setting list item");
clear_tv(&li->li_tv);
li->li_tv = v;
}
}
return 0;
}
@@ -1001,7 +1085,7 @@ luaV_dict_newindex(lua_State *L)
dict_T *d = luaV_unbox(L, luaV_Dict, 1);
char_u *key = (char_u *) luaL_checkstring(L, 2);
dictitem_T *di;
typval_T v;
typval_T tv;
if (d->dv_lock)
luaL_error(L, "dict is locked");
@@ -1011,9 +1095,12 @@ luaV_dict_newindex(lua_State *L)
luaL_error(L, "empty key");
if (!lua_isnil(L, 3)) // read value?
{
luaV_checktypval(L, 3, &v, "setting dict item");
if (d->dv_scope == VAR_DEF_SCOPE && v.v_type == VAR_FUNC)
luaV_checktypval(L, 3, &tv, "setting dict item");
if (d->dv_scope == VAR_DEF_SCOPE && tv.v_type == VAR_FUNC)
{
clear_tv(&tv);
luaL_error(L, "cannot assign funcref to builtin scope");
}
}
di = dict_find(d, key, -1);
if (di == NULL) // non-existing key?
@@ -1022,10 +1109,14 @@ luaV_dict_newindex(lua_State *L)
return 0;
di = dictitem_alloc(key);
if (di == NULL)
{
clear_tv(&tv);
return 0;
}
if (dict_add(d, di) == FAIL)
{
vim_free(di);
clear_tv(&tv);
return 0;
}
}
@@ -1038,10 +1129,7 @@ luaV_dict_newindex(lua_State *L)
dictitem_free(di);
}
else
{
copy_tv(&v, &di->di_tv);
clear_tv(&v);
}
di->di_tv = tv;
return 0;
}
@@ -1358,7 +1446,8 @@ luaV_buffer_newindex(lua_State *L)
curwin->w_cursor.lnum -= 1;
check_cursor_col();
}
else check_cursor();
else
check_cursor();
changed_cline_bef_curs();
}
invalidate_botline();
@@ -1759,8 +1848,7 @@ luaV_dict(lua_State *L)
lua_pushnil(L);
return 1;
}
copy_tv(&v, &di->di_tv);
clear_tv(&v);
di->di_tv = v;
lua_pop(L, 2); // key copy and value
}
}
@@ -2315,7 +2403,7 @@ ex_luado(exarg_T *eap)
lua_replace(L, -2); // function -> body
for (l = eap->line1; l <= eap->line2; l++)
{
// Check the line number, the command my have deleted lines.
// Check the line number, the command may have deleted lines.
if (l > curbuf->b_ml.ml_line_count)
break;
@@ -2415,4 +2503,53 @@ update_package_paths_in_lua()
}
}
/*
* Native C function callback
*/
static int
luaV_call_lua_func(
int argcount,
typval_T *argvars,
typval_T *rettv,
void *state)
{
int i;
int luaargcount = argcount;
luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
if (funcstate->lua_tableref != LUA_NOREF)
{
// First arg for metatable __call method is a table
luaargcount += 1;
lua_rawgeti(funcstate->L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
}
for (i = 0; i < argcount; ++i)
luaV_pushtypval(funcstate->L, &argvars[i]);
if (lua_pcall(funcstate->L, luaargcount, 1, 0))
{
luaV_emsg(funcstate->L);
return FCERR_OTHER;
}
luaV_checktypval(funcstate->L, -1, rettv, "get return value");
return FCERR_NONE;
}
/*
* Free up any lua references held by the func state.
*/
static void
luaV_call_lua_func_free(void *state)
{
luaV_CFuncState *funcstate = (luaV_CFuncState*)state;
luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_funcref);
funcstate->L = NULL;
if (funcstate->lua_tableref != LUA_NOREF)
luaL_unref(L, LUA_REGISTRYINDEX, funcstate->lua_tableref);
VIM_CLEAR(funcstate);
}
#endif
+1 -1
View File
@@ -388,7 +388,7 @@ CVim::Eval(BSTR expr, BSTR *result)
/* Evaluate the expression */
++emsg_skip;
str = (char *)eval_to_string((char_u *)buffer, NULL, TRUE);
str = (char *)eval_to_string((char_u *)buffer, TRUE);
--emsg_skip;
vim_free(buffer);
if (str == NULL)
+1 -2
View File
@@ -832,7 +832,6 @@ msg_split(
char_u *
eval_to_string(
char_u *arg UNUSED,
char_u **nextcmd UNUSED,
int dolist UNUSED)
{
return NULL;
@@ -1562,7 +1561,7 @@ Eval(str)
PREINIT:
char_u *value;
PPCODE:
value = eval_to_string((char_u *)str, (char_u **)0, TRUE);
value = eval_to_string((char_u *)str, TRUE);
if (value == NULL)
{
XPUSHs(sv_2mortal(newSViv(0)));
+16 -2
View File
@@ -1913,7 +1913,6 @@ DictionaryAssItem(
if (dict_add(dict, di) == FAIL)
{
vim_free(di);
dictitem_free(di);
RAISE_KEY_ADD_FAIL(key);
Py_XDECREF(todecref);
@@ -2251,6 +2250,9 @@ ListNew(PyTypeObject *subtype, list_T *list)
{
ListObject *self;
if (list == NULL)
return NULL;
self = (ListObject *) subtype->tp_alloc(subtype, 0);
if (self == NULL)
return NULL;
@@ -2696,6 +2698,12 @@ ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
if (obj == NULL)
{
li = list_find(l, (long) index);
if (li == NULL)
{
PyErr_VIM_FORMAT(N_("internal error: failed to get Vim "
"list item %d"), (int) index);
return -1;
}
vimlist_remove(l, li, li);
clear_tv(&li->li_tv);
vim_free(li);
@@ -2717,6 +2725,12 @@ ListAssIndex(ListObject *self, Py_ssize_t index, PyObject *obj)
else
{
li = list_find(l, (long) index);
if (li == NULL)
{
PyErr_VIM_FORMAT(N_("internal error: failed to get Vim "
"list item %d"), (int) index);
return -1;
}
clear_tv(&li->li_tv);
copy_tv(&tv, &li->li_tv);
clear_tv(&tv);
@@ -3898,7 +3912,7 @@ WindowDestructor(WindowObject *self)
PyObject_GC_UnTrack((void *)(self));
if (self->win && self->win != INVALID_WINDOW_VALUE)
WIN_PYTHON_REF(self->win) = NULL;
Py_XDECREF(((PyObject *)(self->tabObject)));
Py_XDECREF(((PyObject *)(self->tabObject)));
PyObject_GC_Del((void *)(self));
}
+4
View File
@@ -1256,6 +1256,10 @@ BufferAsSubscript(PyObject *self, PyObject* idx, PyObject* val)
if (PyLong_Check(idx))
{
long n = PyLong_AsLong(idx);
if (CheckBuffer((BufferObject *) self))
return -1;
return RBAsItem((BufferObject *)(self), n, val, 1,
(Py_ssize_t)((BufferObject *)(self))->buf->b_ml.ml_line_count,
NULL);
+1 -1
View File
@@ -1373,7 +1373,7 @@ tclvimexpr(
#ifdef FEAT_EVAL
expr = Tcl_GetStringFromObj(objv[objn], NULL);
str = (char *)eval_to_string((char_u *)expr, NULL, TRUE);
str = (char *)eval_to_string((char_u *)expr, TRUE);
if (str == NULL)
Tcl_SetResult(interp, _("invalid expression"), TCL_STATIC);
else
+10 -6
View File
@@ -757,6 +757,10 @@ set_indent(
// Replace the line (unless undo fails).
if (!(flags & SIN_UNDO) || u_savesub(curwin->w_cursor.lnum) == OK)
{
colnr_T old_offset = (colnr_T)(p - oldline);
colnr_T new_offset = (colnr_T)(s - newline);
// this may free "newline"
ml_replace(curwin->w_cursor.lnum, newline, FALSE);
if (flags & SIN_CHANGED)
changed_bytes(curwin->w_cursor.lnum, 0);
@@ -764,24 +768,24 @@ set_indent(
// Correct saved cursor position if it is in this line.
if (saved_cursor.lnum == curwin->w_cursor.lnum)
{
if (saved_cursor.col >= (colnr_T)(p - oldline))
if (saved_cursor.col >= old_offset)
// cursor was after the indent, adjust for the number of
// bytes added/removed
saved_cursor.col += ind_len - (colnr_T)(p - oldline);
else if (saved_cursor.col >= (colnr_T)(s - newline))
saved_cursor.col += ind_len - old_offset;
else if (saved_cursor.col >= new_offset)
// cursor was in the indent, and is now after it, put it back
// at the start of the indent (replacing spaces with TAB)
saved_cursor.col = (colnr_T)(s - newline);
saved_cursor.col = new_offset;
}
#ifdef FEAT_PROP_POPUP
{
int added = ind_len - (colnr_T)(p - oldline);
int added = ind_len - old_offset;
// When increasing indent this behaves like spaces were inserted at
// the old indent, when decreasing indent it behaves like spaces
// were deleted at the new indent.
adjust_prop_columns(curwin->w_cursor.lnum,
(colnr_T)(added > 0 ? (p - oldline) : ind_len), added, 0);
added > 0 ? old_offset : (colnr_T)ind_len, added, 0);
}
#endif
retval = TRUE;
+2 -2
View File
@@ -83,7 +83,7 @@ void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod)
state->mouse_buttons &= ~(1 << (button-1));
}
/* Most of the time we don't get button releases from 4/5 */
/* Most of the time we don't get button releases from 4/5/6/7 */
if(state->mouse_buttons == old_buttons && button < 4)
return;
if (!(state->mouse_flags & MOUSE_WANT_CLICK))
@@ -92,7 +92,7 @@ void vterm_mouse_button(VTerm *vt, int button, int pressed, VTermModifier mod)
if(button < 4) {
output_mouse(state, button-1, pressed, mod, state->mouse_col, state->mouse_row);
}
else if(button < 6) {
else if(button < 8) {
output_mouse(state, button-4 + 0x40, pressed, mod, state->mouse_col, state->mouse_row);
}
}
+1 -2
View File
@@ -106,8 +106,7 @@ static int lookup_colour(const VTermState *state, int palette, const long args[]
}
lookup_colour_palette(state, args[0], col);
return argcount ? 1 : 0;
return 1;
default:
DEBUG_LOG1("Unrecognised colour palette %d\n", palette);
+4 -4
View File
@@ -1844,14 +1844,14 @@ static int on_resize(int rows, int cols, void *user)
state->pos.col++;
}
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.row >= rows)
state->pos.row = rows - 1;
if(state->pos.col < 0)
state->pos.col = 0;
if(state->pos.col >= cols)
state->pos.col = cols - 1;
updatecursor(state, &oldpos, 1);
+16
View File
@@ -69,6 +69,22 @@ RESIZE 24,80
?screen_chars 22,0,23,10 = "Line 25"
?cursor = 23,0
!Resize shorter does not send the cursor to a negative row
# See also https://github.com/vim/vim/pull/6141
RESET
WANTSCREEN -b
RESIZE 25,80
WANTSCREEN b
PUSH "\e[24HLine 24\r\nLine 25\e[H"
?cursor = 0,0
RESIZE 20,80
sb_pushline 80 =
sb_pushline 80 =
sb_pushline 80 =
sb_pushline 80 =
sb_pushline 80 =
?cursor = 0,0
!Resize taller attempts to pop scrollback
RESET
WANTSCREEN -b
+45 -17
View File
@@ -1156,15 +1156,19 @@ f_join(typval_T *argvars, typval_T *rettv)
/*
* Allocate a variable for a List and fill it from "*arg".
* "*arg" points to the "[".
* Return OK or FAIL.
*/
int
get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
eval_list(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error)
{
int evaluate = flags & EVAL_EVALUATE;
int evaluate = evalarg == NULL ? FALSE
: evalarg->eval_flags & EVAL_EVALUATE;
list_T *l = NULL;
typval_T tv;
listitem_T *item;
int vim9script = current_sctx.sc_version == SCRIPT_VERSION_VIM9;
int had_comma;
if (evaluate)
{
@@ -1173,10 +1177,10 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
return FAIL;
}
*arg = skipwhite(*arg + 1);
*arg = skipwhite_and_linebreak(*arg + 1, evalarg);
while (**arg != ']' && **arg != NUL)
{
if (eval1(arg, &tv, flags) == FAIL) // recursive!
if (eval1(arg, &tv, evalarg) == FAIL) // recursive!
goto failret;
if (evaluate)
{
@@ -1191,15 +1195,30 @@ get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error)
clear_tv(&tv);
}
// the comma must come after the value
had_comma = **arg == ',';
if (had_comma)
{
if (vim9script && (*arg)[1] != NUL && !VIM_ISWHITE((*arg)[1]))
{
semsg(_(e_white_after), ",");
goto failret;
}
*arg = skipwhite(*arg + 1);
}
// The "]" can be on the next line. But a double quoted string may
// follow, not a comment.
*arg = skipwhite_and_linebreak(*arg, evalarg);
if (**arg == ']')
break;
if (**arg != ',')
if (!had_comma)
{
if (do_error)
semsg(_("E696: Missing comma in List: %s"), *arg);
goto failret;
}
*arg = skipwhite(*arg + 1);
}
if (**arg != ']')
@@ -2338,7 +2357,7 @@ f_insert(typval_T *argvars, typval_T *rettv)
}
if (l != NULL)
{
list_insert_tv(l, &argvars[1], item);
(void)list_insert_tv(l, &argvars[1], item);
copy_tv(&argvars[0], rettv);
}
}
@@ -2457,8 +2476,10 @@ f_reduce(typval_T *argvars, typval_T *rettv)
list_T *l = argvars[0].vval.v_list;
listitem_T *li = NULL;
int r;
int called_emsg_start = called_emsg;
CHECK_LIST_MATERIALIZE(l);
if (l != NULL)
CHECK_LIST_MATERIALIZE(l);
if (argvars[2].v_type == VAR_UNKNOWN)
{
if (l == NULL || l->lv_first == NULL)
@@ -2475,17 +2496,24 @@ f_reduce(typval_T *argvars, typval_T *rettv)
if (l != NULL)
li = l->lv_first;
}
copy_tv(&initial, rettv);
for ( ; li != NULL; li = li->li_next)
if (l != NULL)
{
argv[0] = *rettv;
argv[1] = li->li_tv;
rettv->v_type = VAR_UNKNOWN;
r = call_func(func_name, -1, rettv, 2, argv, &funcexe);
clear_tv(&argv[0]);
if (r == FAIL)
return;
int prev_locked = l->lv_lock;
l->lv_lock = VAR_FIXED; // disallow the list changing here
for ( ; li != NULL; li = li->li_next)
{
argv[0] = *rettv;
argv[1] = li->li_tv;
rettv->v_type = VAR_UNKNOWN;
r = call_func(func_name, -1, rettv, 2, argv, &funcexe);
clear_tv(&argv[0]);
if (r == FAIL || called_emsg != called_emsg_start)
break;
}
l->lv_lock = prev_locked;
}
}
else
+1 -1
View File
@@ -1614,7 +1614,7 @@ eval_map_expr(
save_cursor = curwin->w_cursor;
save_msg_col = msg_col;
save_msg_row = msg_row;
p = eval_to_string(expr, NULL, FALSE);
p = eval_to_string(expr, FALSE);
--textwinlock;
--ex_normal_lock;
curwin->w_cursor = save_cursor;
+1351
View File
File diff suppressed because it is too large Load Diff
+6
View File
@@ -3657,6 +3657,7 @@ do_dialog(
char_u *hotkeys;
int c;
int i;
tmode_T save_tmode;
#ifndef NO_CONSOLE
// Don't output anything in silent mode ("ex -s")
@@ -3688,6 +3689,10 @@ do_dialog(
State = CONFIRM;
setmouse();
// Ensure raw mode here.
save_tmode = cur_tmode;
settmode(TMODE_RAW);
/*
* Since we wait for a keypress, don't make the
* user press RETURN as well afterwards.
@@ -3748,6 +3753,7 @@ do_dialog(
vim_free(hotkeys);
}
settmode(save_tmode);
State = oldState;
setmouse();
--no_wait_return;
+41 -16
View File
@@ -2160,6 +2160,7 @@ check_termcode_mouse(
# endif
int mouse_code = 0; // init for GCC
int is_click, is_drag;
int is_release, release_is_ambiguous;
int wheel_code = 0;
int current_button;
static int held_button = MOUSE_RELEASE;
@@ -2174,7 +2175,7 @@ check_termcode_mouse(
long timediff; // elapsed time in msec
# endif
is_click = is_drag = FALSE;
is_click = is_drag = is_release = release_is_ambiguous = FALSE;
# if !defined(UNIX) || defined(FEAT_MOUSE_XTERM) || defined(FEAT_GUI) \
|| defined(FEAT_MOUSE_GPM) || defined(FEAT_SYSMOUSE)
@@ -2297,9 +2298,6 @@ check_termcode_mouse(
|| key_name[0] == KS_SGR_MOUSE_RELEASE)
mouse_code += 32;
if (key_name[0] == KS_SGR_MOUSE_RELEASE)
mouse_code |= MOUSE_RELEASE;
mouse_col = getdigits(&p) - 1;
if (*p++ != ';')
return -1;
@@ -2311,6 +2309,19 @@ check_termcode_mouse(
*modifiers = 0;
}
if (key_name[0] == KS_SGR_MOUSE
|| key_name[0] == KS_SGR_MOUSE_RELEASE)
{
if (key_name[0] == KS_SGR_MOUSE_RELEASE)
is_release = TRUE;
}
else
{
release_is_ambiguous = TRUE;
if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
is_release = TRUE;
}
if (key_name[0] == KS_MOUSE
# ifdef FEAT_MOUSE_GPM
|| key_name[0] == KS_GPM_MOUSE
@@ -2372,7 +2383,7 @@ check_termcode_mouse(
# ifdef FEAT_XCLIPBOARD
else if (!(mouse_code & MOUSE_DRAG & ~MOUSE_CLICK_MASK))
{
if ((mouse_code & MOUSE_RELEASE) == MOUSE_RELEASE)
if (is_release)
stop_xterm_trace();
else
start_xterm_trace(mouse_code);
@@ -2510,12 +2521,13 @@ check_termcode_mouse(
if (button & 16) mouse_code |= MOUSE_CTRL;
break;
case 'u': // Button Up
is_release = TRUE;
if (button & 1)
mouse_code |= MOUSE_LEFT | MOUSE_RELEASE;
mouse_code |= MOUSE_LEFT;
if (button & 2)
mouse_code |= MOUSE_MIDDLE | MOUSE_RELEASE;
mouse_code |= MOUSE_MIDDLE;
if (button & 4)
mouse_code |= MOUSE_RIGHT | MOUSE_RELEASE;
mouse_code |= MOUSE_RIGHT;
if (button & 8)
mouse_code |= MOUSE_SHIFT;
if (button & 16)
@@ -2639,17 +2651,20 @@ check_termcode_mouse(
case 2: mouse_code = MOUSE_LEFT;
WantQueryMouse = TRUE;
break;
case 3: mouse_code = MOUSE_RELEASE | MOUSE_LEFT;
case 3: mouse_code = MOUSE_LEFT;
is_release = TRUE;
break;
case 4: mouse_code = MOUSE_MIDDLE;
WantQueryMouse = TRUE;
break;
case 5: mouse_code = MOUSE_RELEASE | MOUSE_MIDDLE;
case 5: mouse_code = MOUSE_MIDDLE;
is_release = TRUE;
break;
case 6: mouse_code = MOUSE_RIGHT;
WantQueryMouse = TRUE;
break;
case 7: mouse_code = MOUSE_RELEASE | MOUSE_RIGHT;
case 7: mouse_code = MOUSE_RIGHT;
is_release = TRUE;
break;
case 8: return -1; // fourth button down
case 9: return -1; // fourth button up
@@ -2702,7 +2717,7 @@ check_termcode_mouse(
break;
case 32: // Release
mouse_code |= MOUSE_RELEASE;
is_release = TRUE;
break;
case 33: // Drag
@@ -2723,6 +2738,9 @@ check_termcode_mouse(
// Interpret the mouse code
current_button = (mouse_code & MOUSE_CLICK_MASK);
if (is_release)
current_button |= MOUSE_RELEASE;
if (current_button == MOUSE_RELEASE
# ifdef FEAT_MOUSE_XTERM
&& wheel_code == 0
@@ -2827,15 +2845,22 @@ check_termcode_mouse(
// Work out our pseudo mouse event. Note that MOUSE_RELEASE gets
// added, then it's not mouse up/down.
key_name[0] = KS_EXTRA;
if (wheel_code != 0
&& (wheel_code & MOUSE_RELEASE) != MOUSE_RELEASE)
if (wheel_code != 0 && (!is_release || release_is_ambiguous))
{
if (wheel_code & MOUSE_CTRL)
*modifiers |= MOD_MASK_CTRL;
if (wheel_code & MOUSE_ALT)
*modifiers |= MOD_MASK_ALT;
key_name[1] = (wheel_code & 1)
? (int)KE_MOUSEUP : (int)KE_MOUSEDOWN;
if (wheel_code & 1 && wheel_code & 2)
key_name[1] = (int)KE_MOUSELEFT;
else if (wheel_code & 2)
key_name[1] = (int)KE_MOUSERIGHT;
else if (wheel_code & 1)
key_name[1] = (int)KE_MOUSEUP;
else
key_name[1] = (int)KE_MOUSEDOWN;
held_button = MOUSE_RELEASE;
}
else
-2
View File
@@ -2710,8 +2710,6 @@ halfpage(int flag, linenr_T Prenum)
if (curwin->w_topfill > 0)
{
i = 1;
if (--n < 0 && scrolled > 0)
break;
--curwin->w_topfill;
}
else
+2
View File
@@ -5944,6 +5944,8 @@ mch_create_pty_channel(job_T *job, jobopt_T *options)
channel_T *channel;
open_pty(&pty_master_fd, &pty_slave_fd, &job->jv_tty_out, &job->jv_tty_in);
if (pty_master_fd < 0 || pty_slave_fd < 0)
return FAIL;
close(pty_slave_fd);
channel = add_channel();
+1 -1
View File
@@ -384,7 +384,7 @@ popup_add_timeout(win_T *wp, int time)
vim_snprintf((char *)cbbuf, sizeof(cbbuf),
"{_ -> popup_close(%d)}", wp->w_id);
if (get_lambda_tv(&ptr, &tv, TRUE) == OK)
if (get_lambda_tv(&ptr, &tv, &EVALARG_EVALUATE) == OK)
{
wp->w_popup_timer = create_timer(time, 0);
wp->w_popup_timer->tr_callback = get_callback(&tv);
+1
View File
@@ -104,6 +104,7 @@ extern int _stricoll(char *a, char *b);
# include "main.pro"
# include "map.pro"
# include "mark.pro"
# include "match.pro"
# include "memfile.pro"
# include "memline.pro"
# ifdef FEAT_MENU
+1 -1
View File
@@ -32,7 +32,7 @@ varnumber_T dict_get_number(dict_T *d, char_u *key);
varnumber_T dict_get_number_def(dict_T *d, char_u *key, int def);
varnumber_T dict_get_number_check(dict_T *d, char_u *key);
char_u *dict2string(typval_T *tv, int copyID, int restore_copyID);
int eval_dict(char_u **arg, typval_T *rettv, int evaluate, int literal);
int eval_dict(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int literal);
void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
dictitem_T *dict_lookup(hashitem_T *hi);
int dict_equal(dict_T *d1, dict_T *d2, int ic, int recursive);
+16 -9
View File
@@ -3,16 +3,18 @@ varnumber_T num_divide(varnumber_T n1, varnumber_T n2);
varnumber_T num_modulus(varnumber_T n1, varnumber_T n2);
void eval_init(void);
void eval_clear(void);
int eval_to_bool(char_u *arg, int *error, char_u **nextcmd, int skip);
void fill_evalarg_from_eap(evalarg_T *evalarg, exarg_T *eap, int skip);
int eval_to_bool(char_u *arg, int *error, exarg_T *eap, int skip);
int eval_expr_valid_arg(typval_T *tv);
int eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv);
int eval_expr_to_bool(typval_T *expr, int *error);
char_u *eval_to_string_skip(char_u *arg, char_u **nextcmd, int skip);
char_u *eval_to_string_skip(char_u *arg, exarg_T *eap, int skip);
int skip_expr(char_u **pp);
char_u *eval_to_string(char_u *arg, char_u **nextcmd, int convert);
char_u *eval_to_string_safe(char_u *arg, char_u **nextcmd, int use_sandbox);
int skip_expr_concatenate(char_u **start, char_u **end, evalarg_T *evalarg);
char_u *eval_to_string(char_u *arg, int convert);
char_u *eval_to_string_safe(char_u *arg, int use_sandbox);
varnumber_T eval_to_number(char_u *expr);
typval_T *eval_expr(char_u *arg, char_u **nextcmd);
typval_T *eval_expr(char_u *arg, exarg_T *eap);
int call_vim_function(char_u *func, int argc, typval_T *argv, typval_T *rettv);
varnumber_T call_func_retnr(char_u *func, int argc, typval_T *argv);
void *call_func_retstr(char_u *func, int argc, typval_T *argv);
@@ -21,13 +23,18 @@ int eval_foldexpr(char_u *arg, int *cp);
char_u *get_lval(char_u *name, typval_T *rettv, lval_T *lp, int unlet, int skip, int flags, int fne_flags);
void clear_lval(lval_T *lp);
void set_var_lval(lval_T *lp, char_u *endp, typval_T *rettv, int copy, int flags, char_u *op);
void *eval_for_line(char_u *arg, int *errp, char_u **nextcmdp, int skip);
void *eval_for_line(char_u *arg, int *errp, exarg_T *eap, evalarg_T *evalarg);
void skip_for_lines(void *fi_void, evalarg_T *evalarg);
int next_for_item(void *fi_void, char_u *arg);
void free_for_info(void *fi_void);
void set_context_for_expression(expand_T *xp, char_u *arg, cmdidx_T cmdidx);
int pattern_match(char_u *pat, char_u *text, int ic);
int eval0(char_u *arg, typval_T *rettv, char_u **nextcmd, int flags);
int eval1(char_u **arg, typval_T *rettv, int flags);
char_u *eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext);
char_u *eval_next_line(evalarg_T *evalarg);
char_u *skipwhite_and_linebreak(char_u *arg, evalarg_T *evalarg);
void clear_evalarg(evalarg_T *evalarg, exarg_T *eap);
int eval0(char_u *arg, typval_T *rettv, exarg_T *eap, evalarg_T *evalarg);
int eval1(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
void eval_addblob(typval_T *tv1, typval_T *tv2);
int eval_addlist(typval_T *tv1, typval_T *tv2);
char_u *partial_name(partial_T *pt);
@@ -51,7 +58,7 @@ int get_name_len(char_u **arg, char_u **alias, int evaluate, int verbose);
char_u *find_name_end(char_u *arg, char_u **expr_start, char_u **expr_end, int flags);
int eval_isnamec(int c);
int eval_isnamec1(int c);
int handle_subscript(char_u **arg, typval_T *rettv, int flags, int verbose, char_u *start_leader, char_u **end_leaderp);
int handle_subscript(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int verbose);
int item_copy(typval_T *from, typval_T *to, int deep, int copyID);
void echo_one(typval_T *rettv, int with_space, int *atstart, int *needclr);
void ex_echo(exarg_T *eap);
+1 -1
View File
@@ -52,7 +52,7 @@ void set_reg_var(int c);
char_u *v_exception(char_u *oldval);
char_u *v_throwpoint(char_u *oldval);
char_u *set_cmdarg(exarg_T *eap, char_u *oldarg);
int get_var_tv(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload);
int eval_variable(char_u *name, int len, typval_T *rettv, dictitem_T **dip, int verbose, int no_autoload);
void check_vars(char_u *name, int len);
dictitem_T *find_var(char_u *name, hashtab_T **htp, int no_autoload);
dictitem_T *find_var_in_ht(hashtab_T *ht, int htname, char_u *varname, int no_autoload);
+3 -1
View File
@@ -4,10 +4,12 @@ int do_cmdline_cmd(char_u *cmd);
int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int, int), void *cookie, int flags);
int getline_equal(char_u *(*fgetline)(int, void *, int, int), void *cookie, char_u *(*func)(int, void *, int, int));
void *getline_cookie(char_u *(*fgetline)(int, void *, int, int), void *cookie);
char_u *getline_peek(char_u *(*fgetline)(int, void *, int, int), void *cookie);
int parse_command_modifiers(exarg_T *eap, char **errormsg, int skip_only);
void undo_cmdmod(exarg_T *eap, int save_msg_scroll);
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
int checkforcmd(char_u **pp, char *cmd, int len);
char_u *find_ex_command(exarg_T *eap, int *full, void *((*lookup)(char_u *, size_t, cctx_T *)), cctx_T *cctx);
char_u *find_ex_command(exarg_T *eap, int *full, void *(*lookup)(char_u *, size_t, cctx_T *), cctx_T *cctx);
int modifier_len(char_u *cmd);
int cmd_exists(char_u *name);
cmdidx_T excmd_get_cmdidx(char_u *cmd, int len);
-15
View File
@@ -43,19 +43,4 @@ void set_context_in_highlight_cmd(expand_T *xp, char_u *arg);
char_u *get_highlight_name(expand_T *xp, int idx);
char_u *get_highlight_name_ext(expand_T *xp, int idx, int skip_cleared);
void free_highlight_fonts(void);
void clear_matches(win_T *wp);
void init_search_hl(win_T *wp, match_T *search_hl);
void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum);
int prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **line, match_T *search_hl, int *search_attr);
int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl, int *has_match_conc, int *match_conc, int did_line_attr, int lcs_eol_one);
int get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol);
void get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr);
void f_clearmatches(typval_T *argvars, typval_T *rettv);
void f_getmatches(typval_T *argvars, typval_T *rettv);
void f_setmatches(typval_T *argvars, typval_T *rettv);
void f_matchadd(typval_T *argvars, typval_T *rettv);
void f_matchaddpos(typval_T *argvars, typval_T *rettv);
void f_matcharg(typval_T *argvars, typval_T *rettv);
void f_matchdelete(typval_T *argvars, typval_T *rettv);
void ex_match(exarg_T *eap);
/* vim: set ft=c : */
+1 -1
View File
@@ -39,7 +39,7 @@ void vimlist_remove(list_T *l, listitem_T *item, listitem_T *item2);
char_u *list2string(typval_T *tv, int copyID, int restore_copyID);
int list_join(garray_T *gap, list_T *l, char_u *sep, int echo_style, int restore_copyID, int copyID);
void f_join(typval_T *argvars, typval_T *rettv);
int get_list_tv(char_u **arg, typval_T *rettv, int flags, int do_error);
int eval_list(char_u **arg, typval_T *rettv, evalarg_T *evalarg, int do_error);
int write_list(FILE *fd, list_T *list, int binary);
void init_static_list(staticList10_T *sl);
void f_list2str(typval_T *argvars, typval_T *rettv);
+17
View File
@@ -0,0 +1,17 @@
/* match.c */
void clear_matches(win_T *wp);
void init_search_hl(win_T *wp, match_T *search_hl);
void prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum);
int prepare_search_hl_line(win_T *wp, linenr_T lnum, colnr_T mincol, char_u **line, match_T *search_hl, int *search_attr);
int update_search_hl(win_T *wp, linenr_T lnum, colnr_T col, char_u **line, match_T *search_hl, int *has_match_conc, int *match_conc, int did_line_attr, int lcs_eol_one);
int get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol);
void get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr);
void f_clearmatches(typval_T *argvars, typval_T *rettv);
void f_getmatches(typval_T *argvars, typval_T *rettv);
void f_setmatches(typval_T *argvars, typval_T *rettv);
void f_matchadd(typval_T *argvars, typval_T *rettv);
void f_matchaddpos(typval_T *argvars, typval_T *rettv);
void f_matcharg(typval_T *argvars, typval_T *rettv);
void f_matchdelete(typval_T *argvars, typval_T *rettv);
void ex_match(exarg_T *eap);
/* vim: set ft=c : */
+1
View File
@@ -22,6 +22,7 @@ void ex_options(exarg_T *eap);
linenr_T *source_breakpoint(void *cookie);
int *source_dbg_tick(void *cookie);
int source_level(void *cookie);
char_u *source_nextline(void *cookie);
int do_source(char_u *fname, int check_other, int is_vimrc, int *ret_sid);
void ex_scriptnames(exarg_T *eap);
void scriptnames_slash_adjust(void);
+13 -13
View File
@@ -4,18 +4,6 @@ typval_T *alloc_string_tv(char_u *s);
void free_tv(typval_T *varp);
void clear_tv(typval_T *varp);
void init_tv(typval_T *varp);
int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
void copy_tv(typval_T *from, typval_T *to);
int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int ic);
char_u *typval_tostring(typval_T *arg);
int tv_islocked(typval_T *tv);
int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
int get_option_tv(char_u **arg, typval_T *rettv, int evaluate);
int get_number_tv(char_u **arg, typval_T *rettv, int evaluate, int want_string);
int get_string_tv(char_u **arg, typval_T *rettv, int evaluate);
int get_lit_string_tv(char_u **arg, typval_T *rettv, int evaluate);
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
int get_env_tv(char_u **arg, typval_T *rettv, int evaluate);
varnumber_T tv_get_number(typval_T *varp);
varnumber_T tv_get_number_chk(typval_T *varp, int *denote);
float_T tv_get_float(typval_T *varp);
@@ -23,8 +11,20 @@ char_u *tv_get_string(typval_T *varp);
char_u *tv_get_string_buf(typval_T *varp, char_u *buf);
char_u *tv_get_string_chk(typval_T *varp);
char_u *tv_get_string_buf_chk(typval_T *varp, char_u *buf);
char_u *tv_stringify(typval_T *varp, char_u *buf);
int tv_check_lock(typval_T *tv, char_u *name, int use_gettext);
void copy_tv(typval_T *from, typval_T *to);
int typval_compare(typval_T *typ1, typval_T *typ2, exptype_T type, int ic);
char_u *typval_tostring(typval_T *arg);
int tv_islocked(typval_T *tv);
int tv_equal(typval_T *tv1, typval_T *tv2, int ic, int recursive);
int eval_option(char_u **arg, typval_T *rettv, int evaluate);
int eval_number(char_u **arg, typval_T *rettv, int evaluate, int want_string);
int eval_string(char_u **arg, typval_T *rettv, int evaluate);
int eval_lit_string(char_u **arg, typval_T *rettv, int evaluate);
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
int eval_env_var(char_u **arg, typval_T *rettv, int evaluate);
linenr_T tv_get_lnum(typval_T *argvars);
linenr_T tv_get_lnum_buf(typval_T *argvars, buf_T *buf);
buf_T *tv_get_buf(typval_T *tv, int curtab_only);
char_u *tv_stringify(typval_T *varp, char_u *buf);
/* vim: set ft=c : */
+3 -2
View File
@@ -3,10 +3,11 @@ void func_init(void);
hashtab_T *func_tbl_get(void);
int get_function_args(char_u **argp, char_u endchar, garray_T *newargs, garray_T *argtypes, int *varargs, garray_T *default_args, int skip, exarg_T *eap, char_u **line_to_free);
char_u *get_lambda_name(void);
int get_lambda_tv(char_u **arg, typval_T *rettv, int evaluate);
char_u *register_cfunc(cfunc_T cb, cfunc_free_T cb_free, void *state);
int get_lambda_tv(char_u **arg, typval_T *rettv, evalarg_T *evalarg);
char_u *deref_func_name(char_u *name, int *lenp, partial_T **partialp, int no_autoload);
void emsg_funcname(char *ermsg, char_u *name);
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, funcexe_T *funcexe);
int get_func_tv(char_u *name, int len, typval_T *rettv, char_u **arg, evalarg_T *evalarg, funcexe_T *funcexe);
char_u *fname_trans_sid(char_u *name, char_u *fname_buf, char_u **tofree, int *error);
ufunc_T *find_func(char_u *name, int is_global, cctx_T *cctx);
int call_user_func_check(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rettv, funcexe_T *funcexe, dict_T *selfdict);
+1 -1
View File
@@ -1,5 +1,5 @@
/* vim9compile.c */
int check_defined(char_u *p, int len, cctx_T *cctx);
int check_defined(char_u *p, size_t len, cctx_T *cctx);
type_T *typval2type(typval_T *tv);
int check_type(type_T *expected, type_T *actual, int give_msg);
char_u *skip_type(char_u *start);
+2 -2
View File
@@ -4,8 +4,8 @@ void ex_vim9script(exarg_T *eap);
void ex_export(exarg_T *eap);
void free_imports(int sid);
void ex_import(exarg_T *eap);
int find_exported(int sid, char_u **argp, int *name_len, ufunc_T **ufunc, type_T **type);
char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, void *cctx);
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type);
char_u *handle_import(char_u *arg_start, garray_T *gap, int import_sid, evalarg_T *evalarg, void *cctx);
char_u *vim9_declare_scriptvar(exarg_T *eap, char_u *arg);
int check_script_var_type(typval_T *dest, typval_T *value, char_u *name);
/* vim: set ft=c : */
+16 -6
View File
@@ -7374,6 +7374,7 @@ qf_free_stack(win_T *wp, qf_info_T *qi)
* Populate the quickfix list with the items supplied in the list
* of dictionaries. "title" will be copied to w:quickfix_title.
* "action" is 'a' for add, 'r' for replace. Otherwise create a new list.
* When "what" is not NULL then only set some properties.
*/
int
set_errorlist(
@@ -7400,6 +7401,14 @@ set_errorlist(
return OK;
}
// A dict argument cannot be specified with a non-empty list argument
if (list->lv_len != 0 && what != NULL)
{
semsg(_(e_invarg2),
_("cannot have both a list and a \"what\" argument"));
return FAIL;
}
incr_quickfix_busy();
if (what != NULL)
@@ -7680,7 +7689,7 @@ ex_cexpr(exarg_T *eap)
// Evaluate the expression. When the result is a string or a list we can
// use it to fill the errorlist.
tv = eval_expr(eap->arg, &eap->nextcmd);
tv = eval_expr(eap->arg, eap);
if (tv != NULL)
{
if ((tv->v_type == VAR_STRING && tv->vval.v_string != NULL)
@@ -8098,7 +8107,7 @@ set_qf_ll_list(
else
{
list_T *l = list_arg->vval.v_list;
dict_T *d = NULL;
dict_T *what = NULL;
int valid_dict = TRUE;
if (action_arg->v_type == VAR_STRING)
@@ -8120,8 +8129,8 @@ set_qf_ll_list(
if (action_arg->v_type != VAR_UNKNOWN
&& what_arg->v_type != VAR_UNKNOWN)
{
if (what_arg->v_type == VAR_DICT)
d = what_arg->vval.v_dict;
if (what_arg->v_type == VAR_DICT && what_arg->vval.v_dict != NULL)
what = what_arg->vval.v_dict;
else
{
emsg(_(e_dictreq));
@@ -8130,9 +8139,10 @@ set_qf_ll_list(
}
++recursive;
if (l != NULL && action && valid_dict && set_errorlist(wp, l, action,
if (l != NULL && action && valid_dict
&& set_errorlist(wp, l, action,
(char_u *)(wp == NULL ? ":setqflist()" : ":setloclist()"),
d) == OK)
what) == OK)
rettv->vval.v_number = 0;
--recursive;
}
+1 -1
View File
@@ -2066,7 +2066,7 @@ vim_regsub_both(
clear_tv(&rettv);
}
else
eval_result = eval_to_string(source + 2, NULL, TRUE);
eval_result = eval_to_string(source + 2, TRUE);
if (eval_result != NULL)
{
+6 -6
View File
@@ -136,7 +136,7 @@ get_expr_line(void)
return expr_copy;
++nested;
rv = eval_to_string(expr_copy, NULL, TRUE);
rv = eval_to_string(expr_copy, TRUE);
--nested;
vim_free(expr_copy);
return rv;
@@ -989,16 +989,16 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
for (n = 0; n < reg->y_size; n++)
list_append_string(list, reg->y_array[n], -1);
list->lv_lock = VAR_FIXED;
dict_add_list(v_event, "regcontents", list);
(void)dict_add_list(v_event, "regcontents", list);
buf[0] = (char_u)oap->regname;
buf[1] = NUL;
dict_add_string(v_event, "regname", buf);
(void)dict_add_string(v_event, "regname", buf);
buf[0] = get_op_char(oap->op_type);
buf[1] = get_extra_op_char(oap->op_type);
buf[2] = NUL;
dict_add_string(v_event, "operator", buf);
(void)dict_add_string(v_event, "operator", buf);
buf[0] = NUL;
buf[1] = NUL;
@@ -1011,9 +1011,9 @@ yank_do_autocmd(oparg_T *oap, yankreg_T *reg)
reglen + 1);
break;
}
dict_add_string(v_event, "regtype", buf);
(void)dict_add_string(v_event, "regtype", buf);
dict_add_bool(v_event, "visual", oap->is_VIsual);
(void)dict_add_bool(v_event, "visual", oap->is_VIsual);
// Lock the dictionary and its keys
dict_set_items_ro(v_event);
+1 -1
View File
@@ -1160,7 +1160,7 @@ get_keymap_str(
curwin = wp;
STRCPY(buf, "b:keymap_name"); // must be writable
++emsg_skip;
s = p = eval_to_string(buf, NULL, FALSE);
s = p = eval_to_string(buf, FALSE);
--emsg_skip;
curbuf = old_curbuf;
curwin = old_curwin;
+9
View File
@@ -1050,6 +1050,15 @@ source_level(void *cookie)
{
return ((struct source_cookie *)cookie)->level;
}
/*
* Return the readahead line.
*/
char_u *
source_nextline(void *cookie)
{
return ((struct source_cookie *)cookie)->nextline;
}
#endif
#if (defined(MSWIN) && defined(FEAT_CSCOPE)) || defined(HAVE_FD_CLOEXEC)
+2 -3
View File
@@ -5908,7 +5908,8 @@ mkspell(
spin.si_newcompID = 127; // start compound ID at first maximum
// default: fnames[0] is output file, following are input files
innames = &fnames[1];
// When "fcount" is 1 there is only one file.
innames = &fnames[fcount == 1 ? 0 : 1];
incount = fcount - 1;
wfname = alloc(MAXPATHL);
@@ -5922,14 +5923,12 @@ mkspell(
{
// For ":mkspell path/en.latin1.add" output file is
// "path/en.latin1.add.spl".
innames = &fnames[0];
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, "%s.spl", fnames[0]);
}
else if (fcount == 1)
{
// For ":mkspell path/vim" output file is "path/vim.latin1.spl".
innames = &fnames[0];
incount = 1;
vim_snprintf((char *)wfname, MAXPATHL, SPL_FNAME_TMPL,
fnames[0], spin.si_ascii ? (char_u *)"ascii" : spell_enc());
+6 -4
View File
@@ -676,8 +676,6 @@ spell_suggest(int count)
mch_memmove(p, line, c);
STRCPY(p + c, stp->st_word);
STRCAT(p, sug.su_badptr + stp->st_orglen);
ml_replace(curwin->w_cursor.lnum, p, FALSE);
curwin->w_cursor.col = c;
// For redo we use a change-word command.
ResetRedobuff();
@@ -686,7 +684,10 @@ spell_suggest(int count)
stp->st_wordlen + sug.su_badlen - stp->st_orglen);
AppendCharToRedobuff(ESC);
// After this "p" may be invalid.
// "p" may be freed here
ml_replace(curwin->w_cursor.lnum, p, FALSE);
curwin->w_cursor.col = c;
changed_bytes(curwin->w_cursor.lnum, c);
}
}
@@ -1405,7 +1406,8 @@ suggest_trie_walk(
tword[sp->ts_twordlen] = NUL;
if (sp->ts_prefixdepth <= PFD_NOTSPECIAL
&& (sp->ts_flags & TSF_PREFIXOK) == 0)
&& (sp->ts_flags & TSF_PREFIXOK) == 0
&& pbyts != NULL)
{
// There was a prefix before the word. Check that the prefix
// can be used with this word.
+36
View File
@@ -1529,6 +1529,9 @@ struct blobvar_S
char bv_lock; // zero, VAR_LOCKED, VAR_FIXED
};
typedef int (*cfunc_T)(int argcount, typval_T *argvars, typval_T *rettv, void *state);
typedef void (*cfunc_free_T)(void *state);
#if defined(FEAT_EVAL) || defined(PROTO)
typedef struct funccall_S funccall_T;
@@ -1562,6 +1565,11 @@ typedef struct
char_u *uf_va_name; // name from "...name" or NULL
type_T *uf_va_type; // type from "...name: type" or NULL
type_T *uf_func_type; // type of the function, &t_func_any if unknown
# if defined(FEAT_LUA)
cfunc_T uf_cb; // callback function for cfunc
cfunc_free_T uf_cb_free; // callback function to free cfunc
void *uf_cb_state; // state of uf_cb
# endif
garray_T uf_lines; // function lines
# ifdef FEAT_PROFILE
@@ -1607,6 +1615,7 @@ typedef struct
#define FC_EXPORT 0x100 // "export def Func()"
#define FC_NOARGS 0x200 // no a: variables in lambda
#define FC_VIM9 0x400 // defined in vim9 script file
#define FC_CFUNC 0x800 // defined as Lua C func
#define MAX_FUNC_ARGS 20 // maximum number of function arguments
#define VAR_SHORT_LEN 20 // short variable name length
@@ -1746,6 +1755,29 @@ typedef struct
# endif
} scriptitem_T;
// Struct passed through eval() functions.
// See EVALARG_EVALUATE for a fixed value with eval_flags set to EVAL_EVALUATE.
typedef struct {
int eval_flags; // EVAL_ flag values below
int eval_break_count; // nr of line breaks consumed
// copied from exarg_T when "getline" is "getsourceline". Can be NULL.
char_u *(*eval_getline)(int, void *, int, int);
void *eval_cookie; // argument for eval_getline()
// Used to collect lines while parsing them, so that they can be
// concatenated later. Used when "eval_ga.ga_itemsize" is not zero.
// "eval_ga.ga_data" is a list of pointers to lines.
garray_T eval_ga;
// pointer to the line obtained with getsourceline()
char_u *eval_tofree;
} evalarg_T;
// Flags for expression evaluation.
#define EVAL_EVALUATE 1 // when missing don't actually evaluate
#define EVAL_CONSTANT 2 // when not a constant return FAIL
# ifdef FEAT_PROFILE
/*
* Struct used in sn_prl_ga for every line of a script.
@@ -1781,6 +1813,10 @@ typedef struct
{
int dummy;
} scriptitem_T;
typedef struct
{
int dummy;
} evalarg_T;
#endif
// Struct passed between functions dealing with function call execution.
+4 -2
View File
@@ -1394,8 +1394,8 @@ term_convert_key(term_T *term, int c, int modmask, char *buf)
case K_MOUSEUP: other = term_send_mouse(vterm, 5, 1); break;
case K_MOUSEDOWN: other = term_send_mouse(vterm, 4, 1); break;
case K_MOUSELEFT: /* TODO */ return 0;
case K_MOUSERIGHT: /* TODO */ return 0;
case K_MOUSELEFT: other = term_send_mouse(vterm, 7, 1); break;
case K_MOUSERIGHT: other = term_send_mouse(vterm, 6, 1); break;
case K_LEFTMOUSE:
case K_LEFTMOUSE_NM:
@@ -2479,6 +2479,8 @@ terminal_loop(int blocking)
restore_cursor = TRUE;
raw_c = term_vgetc();
if (raw_c > 0)
ch_log(NULL, "terminal_loop() got %d", raw_c);
if (!term_use_loop_check(TRUE) || in_terminal_loop != curbuf->b_term)
{
// Job finished while waiting for a character. Push back the
+5 -7
View File
@@ -20,16 +20,12 @@ SCRIPTS_ALL = \
# Tests that run on most systems, but not on Amiga.
SCRIPTS_MORE1 = \
test52.out \
test86.out \
test87.out
test52.out
# Tests that run on most systems, but not on Amiga and DOS/Windows.
SCRIPTS_MORE2 = \
test49.out
# Tests that run on most systems, but not on VMS
SCRIPTS_MORE4 = \
test59.out
@@ -37,7 +33,6 @@ SCRIPTS_MORE4 = \
# Tests specifically for MS-Windows.
SCRIPTS_WIN32 =
# Tests for the GUI.
SCRIPTS_GUI =
@@ -90,6 +85,7 @@ NEW_TESTS = \
test_close_count \
test_cmdline \
test_command_count \
test_comments \
test_comparators \
test_compiler \
test_conceal \
@@ -276,6 +272,7 @@ NEW_TESTS = \
test_termcodes \
test_termencoding \
test_terminal \
test_terminal2 \
test_terminal_fail \
test_textformat \
test_textobjects \
@@ -309,7 +306,6 @@ NEW_TESTS = \
test_alot_utf8 \
test_alot
# Test targets that use runtest.vim.
# Keep test_alot*.res as the last one, sort the others.
# test_largefile.res is omitted, it uses too much resources to run on CI.
@@ -342,6 +338,7 @@ NEW_TESTS_RES = \
test_close_count.res \
test_cmdline.res \
test_command_count.res \
test_comments.res \
test_comparators.res \
test_conceal.res \
test_const.res \
@@ -492,6 +489,7 @@ NEW_TESTS_RES = \
test_termcodes.res \
test_termencoding.res \
test_terminal.res \
test_terminal2.res \
test_terminal_fail.res \
test_textformat.res \
test_textobjects.res \
+2 -6
View File
@@ -4,7 +4,7 @@
# Authors: Zoltan Arpadffy, <arpadffy@polarhome.com>
# Sandor Kopanyi, <sandor.kopanyi@mailbox.hu>
#
# Last change: 2019 May 31
# Last change: 2020 Jul 03
#
# This has been tested on VMS 6.2 to 8.3 on DEC Alpha, VAX and IA64.
# Edit the lines in the Configuration section below to select.
@@ -115,10 +115,6 @@ SCRIPT_ODS5 = test102.out
SCRIPT_GDIFF = test47.out
.ENDIF
.IFDEF HAVE_PYTHON
SCRIPT_PYTHON = test86.out test87.out
.ENDIF
.in.out :
-@ !clean up before doing the test
-@ if "''F$SEARCH("test.out.*")'" .NES. "" then delete/noconfirm/nolog test.out.*
@@ -140,7 +136,7 @@ SCRIPT_PYTHON = test86.out test87.out
-@ if "''F$SEARCH("Xtest.*")'" .NES. "" then delete/noconfirm/nolog Xtest.*.*
all : clean nolog $(START_WITH) $(SCRIPT) $(SCRIPT_GUI) $(SCRIPT_UNIX) $(SCRIPT_WIN) $(SCRIPT_SPELL) $(SCRIPT_ODS5) \
$(SCRIPT_GDIFF) $(SCRIPT_MZSCH) $(SCRIPT_LUA) $(SCRIPT_PYTHON) nolog
$(SCRIPT_GDIFF) $(SCRIPT_MZSCH) $(SCRIPT_LUA) nolog
-@ write sys$output " "
-@ write sys$output "-----------------------------------------------"
-@ write sys$output " All done"
-8
View File
@@ -168,14 +168,6 @@ newtestssilent: $(NEW_TESTS_RES)
$(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim $(REDIR_TEST_TO_NULL)
@rm vimcmd
# Temporary: Do not use $REDIR_TEST_TO_NULL for test_terminal to be able to see
# where it sometimes hanges on CI.
test_terminal.res: test_terminal.vim
@echo "$(VIMPROG)" > vimcmd
@echo "$(RUN_VIMTEST)" >> vimcmd
$(RUN_VIMTEST) $(NO_INITS) -S runtest.vim $*.vim
@rm vimcmd
test_gui.res: test_gui.vim
@echo "$(VIMPROG)" > vimcmd
@echo "$(RUN_GVIMTEST)" >> vimcmd
+1 -1
View File
@@ -17,4 +17,4 @@
|~| @73
|~| @73
|X+1#0000000&|p|r|o|g|r|a|m|1|.|c| @45|1|,|1| @11|A|l@1
|"+0&&|X|p|r|o|g|r|a|m|2|.|c|"| |5|L|,| |7|6|C| @53
|"+0&&|X|p|r|o|g|r|a|m|2|.|c|"| |5|L|,| |7|6|B| @53
@@ -6,4 +6,4 @@
|t|w|o| @46
|~+0#4040ff13&| @48
|X+1#0000000&|u|n|i|x|.|t|x|t| @22|1|,|1| @11|A|l@1
|"+0&&|X|m|a|c|.|t|x|t|"| |[|n|o|e|o|l|]|[|m|a|c|]| |2|L|,| |9|C| @19
|"+0&&|X|m|a|c|.|t|x|t|"| |[|n|o|e|o|l|]|[|m|a|c|]| |2|L|,| |9|B| @19
+1 -1
View File
@@ -5,4 +5,4 @@
|~| @73
|~| @73
|~| @73
|<+0#0000000&|x@64|"| |0|L|,| |0|C|
|<+0#0000000&|x@64|"| |0|L|,| |0|B|
+1 -1
View File
@@ -7,4 +7,4 @@
|~| @48
|~| @48
|~| @48
|"+0#0000000&|X|t|e|s|t|.|c|"| |2|L|,| |2|3|C| @14|1|,|1| @10|A|l@1|
|"+0#0000000&|X|t|e|s|t|.|c|"| |2|L|,| |2|3|B| @14|1|,|1| @10|A|l@1|
@@ -0,0 +1,6 @@
| +0&#ffffff0@74
|~+0#4040ff13&| @73
|~| @73
|~| @73
|~| @73
|:+0#0000000&|a|b|c> @70
+16
View File
@@ -169,4 +169,20 @@ func MouseWheelDown(row, col)
call feedkeys(MouseWheelDownCode(a:row, a:col), 'Lx!')
endfunc
func MouseWheelLeftCode(row, col)
return TerminalEscapeCode(0x42, a:row, a:col, 'M')
endfunc
func MouseWheelLeft(row, col)
call feedkeys(MouseWheelLeftCode(a:row, a:col), 'Lx!')
endfunc
func MouseWheelRightCode(row, col)
return TerminalEscapeCode(0x43, a:row, a:col, 'M')
endfunc
func MouseWheelRight(row, col)
call feedkeys(MouseWheelRightCode(a:row, a:col), 'Lx!')
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+15
View File
@@ -353,4 +353,19 @@ func GetMessages()
return msg_list
endfunc
" Run the list of commands in 'cmds' and look for 'errstr' in exception.
" Note that assert_fails() cannot be used in some places and this function
" can be used.
func AssertException(cmds, errstr)
let save_exception = ''
try
for cmd in a:cmds
exe cmd
endfor
catch
let save_exception = v:exception
endtry
call assert_match(a:errstr, save_exception)
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+24
View File
@@ -146,4 +146,28 @@ func StopVimInTerminal(buf)
only!
endfunc
" Open a terminal with a shell, assign the job to g:job and return the buffer
" number.
func Run_shell_in_terminal(options)
if has('win32')
let buf = term_start([&shell,'/k'], a:options)
else
let buf = term_start(&shell, a:options)
endif
let g:test_is_flaky = 1
let termlist = term_list()
call assert_equal(1, len(termlist))
call assert_equal(buf, termlist[0])
let g:job = term_getjob(buf)
call assert_equal(v:t_job, type(g:job))
let string = string({'job': buf->term_getjob()})
call assert_match("{'job': 'process \\d\\+ run'}", string)
return buf
endfunc
" vim: shiftwidth=2 sts=2 expandtab
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+18 -15
View File
@@ -175,22 +175,25 @@ func Test_argument()
let save_columns = &columns
let &columns = 79
exe 'args ' .. join(range(1, 81))
call assert_equal(join([
\ '',
\ '[1] 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 ',
\ '2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 ',
\ '3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 ',
\ '4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 ',
\ '5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ',
\ ], "\n"),
\ execute('args'))
try
exe 'args ' .. join(range(1, 81))
call assert_equal(join([
\ '',
\ '[1] 6 11 16 21 26 31 36 41 46 51 56 61 66 71 76 81 ',
\ '2 7 12 17 22 27 32 37 42 47 52 57 62 67 72 77 ',
\ '3 8 13 18 23 28 33 38 43 48 53 58 63 68 73 78 ',
\ '4 9 14 19 24 29 34 39 44 49 54 59 64 69 74 79 ',
\ '5 10 15 20 25 30 35 40 45 50 55 60 65 70 75 80 ',
\ ], "\n"),
\ execute('args'))
" No trailing newline with one item per row.
let long_arg = repeat('X', 81)
exe 'args ' .. long_arg
call assert_equal("\n[".long_arg.']', execute('args'))
let &columns = save_columns
" No trailing newline with one item per row.
let long_arg = repeat('X', 81)
exe 'args ' .. long_arg
call assert_equal("\n[".long_arg.']', execute('args'))
finally
let &columns = save_columns
endtry
" Setting argument list should fail when the current buffer has unsaved
" changes
+41 -2
View File
@@ -2585,7 +2585,7 @@ func Test_autocmd_window()
edit one.txt
tabnew two.txt
let g:blist = []
augroup aucmd_win_test
augroup aucmd_win_test1
au!
au BufEnter * call add(g:blist, [expand('<afile>'),
\ win_gettype(bufwinnr(expand('<afile>')))])
@@ -2594,11 +2594,50 @@ func Test_autocmd_window()
doautoall BufEnter
call assert_equal([['one.txt', 'autocmd'], ['two.txt', '']], g:blist)
augroup aucmd_win_test1
au!
augroup END
augroup! aucmd_win_test1
%bw!
endfunc
" Test for trying to close the temporary window used for executing an autocmd
func Test_close_autocmd_window()
%bw!
edit one.txt
tabnew two.txt
augroup aucmd_win_test2
au!
au BufEnter * if expand('<afile>') == 'one.txt' | 1close | endif
augroup END
call assert_fails('doautoall BufEnter', 'E813:')
augroup aucmd_win_test2
au!
augroup END
augroup! aucmd_win_test2
%bwipe!
endfunc
" Test for trying to close the tab that has the temporary window for exeucing
" an autocmd.
func Test_close_autocmd_tab()
edit one.txt
tabnew two.txt
augroup aucmd_win_test
au!
au BufEnter * if expand('<afile>') == 'one.txt' | tabfirst | tabonly | endif
augroup END
call assert_fails('doautoall BufEnter', 'E813:')
tabonly
augroup aucmd_win_test
au!
augroup END
augroup! aucmd_win_test
%bw!
%bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+204
View File
@@ -1,5 +1,7 @@
" Tests for Vim buffer
source check.vim
" Test for the :bunload command with an offset
func Test_bunload_with_offset()
%bwipe!
@@ -152,6 +154,24 @@ func Test_bdelete_cmd()
set nobuflisted
enew
call assert_fails('bdelete ' .. bnr, 'E516:')
" Deleting more than one buffer
new Xbuf1
new Xbuf2
exe 'bdel ' .. bufnr('Xbuf2') .. ' ' .. bufnr('Xbuf1')
call assert_equal(1, winnr('$'))
call assert_equal(0, getbufinfo('Xbuf1')[0].loaded)
call assert_equal(0, getbufinfo('Xbuf2')[0].loaded)
" Deleting more than one buffer and an invalid buffer
new Xbuf1
new Xbuf2
let cmd = "exe 'bdel ' .. bufnr('Xbuf2') .. ' xxx ' .. bufnr('Xbuf1')"
call assert_fails(cmd, 'E94:')
call assert_equal(2, winnr('$'))
call assert_equal(1, getbufinfo('Xbuf1')[0].loaded)
call assert_equal(0, getbufinfo('Xbuf2')[0].loaded)
%bwipe!
endfunc
@@ -166,4 +186,188 @@ func Test_buffer_error()
%bwipe
endfunc
" Test for the status messages displayed when unloading, deleting or wiping
" out buffers
func Test_buffer_statusmsg()
CheckEnglish
set report=1
new Xbuf1
new Xbuf2
let bnr = bufnr()
exe "normal 2\<C-G>"
call assert_match('buf ' .. bnr .. ':', v:statusmsg)
bunload Xbuf1 Xbuf2
call assert_equal('2 buffers unloaded', v:statusmsg)
bdel Xbuf1 Xbuf2
call assert_equal('2 buffers deleted', v:statusmsg)
bwipe Xbuf1 Xbuf2
call assert_equal('2 buffers wiped out', v:statusmsg)
set report&
endfunc
" Test for quitting the 'swapfile exists' dialog with the split buffer
" command.
func Test_buffer_sbuf_cleanup()
call writefile([], 'Xfile')
" first open the file in a buffer
new Xfile
let bnr = bufnr()
close
" create the swap file
call writefile([], '.Xfile.swp')
" Remove the catch-all that runtest.vim adds
au! SwapExists
augroup BufTest
au!
autocmd SwapExists Xfile let v:swapchoice='q'
augroup END
exe 'sbuf ' . bnr
call assert_equal(1, winnr('$'))
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
" test for :sball
sball
call assert_equal(1, winnr('$'))
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
%bw!
set shortmess+=F
let v:statusmsg = ''
edit Xfile
call assert_equal('', v:statusmsg)
call assert_equal(1, winnr('$'))
call assert_equal(0, getbufinfo('Xfile')[0].loaded)
set shortmess&
call delete('Xfile')
call delete('.Xfile.swp')
augroup BufTest
au!
augroup END
augroup! BufTest
endfunc
" Test for deleting a modified buffer with :confirm
func Test_bdel_with_confirm()
CheckUnix
CheckNotGui
CheckFeature dialog_con
new
call setline(1, 'test')
call assert_fails('bdel', 'E89:')
call feedkeys('c', 'L')
confirm bdel
call assert_equal(2, winnr('$'))
call assert_equal(1, &modified)
call feedkeys('n', 'L')
confirm bdel
call assert_equal(1, winnr('$'))
endfunc
" Test for editing another buffer from a modified buffer with :confirm
func Test_goto_buf_with_confirm()
CheckUnix
CheckNotGui
CheckFeature dialog_con
new Xfile
enew
call setline(1, 'test')
call assert_fails('b Xfile', 'E37:')
call feedkeys('c', 'L')
call assert_fails('confirm b Xfile', 'E37:')
call assert_equal(1, &modified)
call assert_equal('', @%)
call feedkeys('y', 'L')
call assert_fails('confirm b Xfile', 'E37:')
call assert_equal(1, &modified)
call assert_equal('', @%)
call feedkeys('n', 'L')
confirm b Xfile
call assert_equal('Xfile', @%)
close!
endfunc
" Test for splitting buffer with 'switchbuf'
func Test_buffer_switchbuf()
new Xfile
wincmd w
set switchbuf=useopen
sbuf Xfile
call assert_equal(1, winnr())
call assert_equal(2, winnr('$'))
set switchbuf=usetab
tabnew
sbuf Xfile
call assert_equal(1, tabpagenr())
call assert_equal(2, tabpagenr('$'))
set switchbuf&
%bw
endfunc
" Test for BufAdd autocommand wiping out the buffer
func Test_bufadd_autocmd_bwipe()
%bw!
augroup BufAdd_Wipe
au!
autocmd BufAdd Xfile %bw!
augroup END
edit Xfile
call assert_equal('', @%)
call assert_equal(0, bufexists('Xfile'))
augroup BufAdd_Wipe
au!
augroup END
augroup! BufAdd_Wipe
endfunc
" Test for trying to load a buffer with text locked
" <C-\>e in the command line is used to lock the text
func Test_load_buf_with_text_locked()
new Xfile1
edit Xfile2
let cmd = ":\<C-\>eexecute(\"normal \<C-O>\")\<CR>\<C-C>"
call assert_fails("call feedkeys(cmd, 'xt')", 'E565:')
%bw!
endfunc
" Test for using CTRL-^ to edit the alternative file keeping the cursor
" position with 'nostartofline'. Also test using the 'buf' command.
func Test_buffer_edit_altfile()
call writefile(repeat(['one two'], 50), 'Xfile1')
call writefile(repeat(['five six'], 50), 'Xfile2')
set nosol
edit Xfile1
call cursor(25, 5)
edit Xfile2
call cursor(30, 4)
exe "normal \<C-^>"
call assert_equal([0, 25, 5, 0], getpos('.'))
exe "normal \<C-^>"
call assert_equal([0, 30, 4, 0], getpos('.'))
buf Xfile1
call assert_equal([0, 25, 5, 0], getpos('.'))
buf Xfile2
call assert_equal([0, 30, 4, 0], getpos('.'))
set sol&
call delete('Xfile1')
call delete('Xfile2')
endfunc
" Test for running the :sball command with a maximum window count and a
" modified buffer
func Test_sball_with_count()
%bw!
edit Xfile1
call setline(1, ['abc'])
new Xfile2
new Xfile3
new Xfile4
2sball
call assert_equal(bufnr('Xfile4'), winbufnr(1))
call assert_equal(bufnr('Xfile1'), winbufnr(2))
call assert_equal(0, getbufinfo('Xfile2')[0].loaded)
call assert_equal(0, getbufinfo('Xfile3')[0].loaded)
%bw!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+17 -1
View File
@@ -191,6 +191,10 @@ func Test_highlight_completion()
call assert_equal('"hi default', getreg(':'))
call feedkeys(":hi c\<S-Tab>\<Home>\"\<CR>", 'xt')
call assert_equal('"hi clear', getreg(':'))
call feedkeys(":hi clear Aardig Aard\<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal('"hi clear Aardig Aardig', getreg(':'))
call feedkeys(":hi Aardig \<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"hi Aardig \t", getreg(':'))
" A cleared group does not show up in completions.
hi Anders ctermfg=green
@@ -201,6 +205,14 @@ func Test_highlight_completion()
call assert_equal([], getcompletion('A', 'highlight'))
endfunc
" Test for command-line expansion of "hi Ni " (easter egg)
func Test_highlight_easter_egg()
call test_override('ui_delay', 1)
call feedkeys(":hi Ni \<Tab>\<C-B>\"\<CR>", 'xt')
call assert_equal("\"hi Ni \<Tab>", @:)
call test_override('ALL', 0)
endfunc
func Test_getcompletion()
if !has('cmdline_compl')
return
@@ -392,6 +404,7 @@ func Test_getcompletion()
call delete('Xtags')
set tags&
call assert_fails("call getcompletion('\\\\@!\\\\@=', 'buffer')", 'E871:')
call assert_fails('call getcompletion("", "burp")', 'E475:')
call assert_fails('call getcompletion("abc", [])', 'E475:')
endfunc
@@ -1580,8 +1593,11 @@ func Test_read_shellcmd()
call feedkeys(":r! ++enc=utf-8 r\<c-a>\<c-b>\"\<cr>", 'tx')
call assert_notmatch('^"r!.*\<runtest.vim\>', @:)
call assert_match('^"r!.*\<rm\>', @:)
call feedkeys(":r ++enc=utf-8 !rm\<c-a>\<c-b>\"\<cr>", 'tx')
call assert_notmatch('^"r.*\<runtest.vim\>', @:)
call assert_match('^"r ++enc\S\+ !.*\<rm\>', @:)
endif
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+277
View File
@@ -0,0 +1,277 @@
" Tests for the various flags in the 'comments' option
" Test for the 'n' flag in 'comments'
func Test_comment_nested()
new
setlocal comments=n:> fo+=ro
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC\<C-C>Go\<BS>>>> F\nH"
exe "normal 5GOE\<C-C>6GoG"
let expected =<< trim END
> A
> B
> C
> D
>>>> E
>>>> F
>>>> G
>>>> H
END
call assert_equal(expected, getline(1, '$'))
close!
endfunc
" Test for the 'b' flag in 'comments'
func Test_comment_blank()
new
setlocal comments=b:* fo+=ro
exe "normal i* E\nF\n\<BS>G\nH\<C-C>ggOC\<C-C>O\<BS>B\<C-C>OA\<C-C>2joD"
let expected =<< trim END
A
*B
* C
* D
* E
* F
*G
H
END
call assert_equal(expected, getline(1, '$'))
close!
endfunc
" Test for the 'f' flag in 'comments' (only the first line has a comment
" string)
func Test_comment_firstline()
new
setlocal comments=f:- fo+=ro
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
call assert_equal(['A', '- B', ' C', ' D'], getline(1, '$'))
%d
setlocal comments=:-
exe "normal i- B\nD\<C-C>ggoC\<C-C>ggOA\<C-C>"
call assert_equal(['- A', '- B', '- C', '- D'], getline(1, '$'))
close!
endfunc
" Test for the 's', 'm' and 'e' flags in 'comments'
" Test for automatically adding comment leaders in insert mode
func Test_comment_threepiece()
new
setlocal expandtab
call setline(1, ["\t/*"])
setlocal formatoptions=croql
call cursor(1, 3)
call feedkeys("A\<cr>\<cr>/", 'tnix')
call assert_equal(["\t/*", " *", " */"], getline(1, '$'))
" If a comment ends in a single line, then don't add it in the next line
%d
call setline(1, '/* line1 */')
call feedkeys("A\<CR>next line", 'xt')
call assert_equal(['/* line1 */', 'next line'], getline(1, '$'))
%d
" Copy the trailing indentation from the leader comment to a new line
setlocal autoindent noexpandtab
call feedkeys("a\t/*\tone\ntwo\n/", 'xt')
call assert_equal(["\t/*\tone", "\t *\ttwo", "\t */"], getline(1, '$'))
close!
endfunc
" Test for the 'r' flag in 'comments' (right align comment)
func Test_comment_rightalign()
new
setlocal comments=sr:/***,m:**,ex-2:******/ fo+=ro
exe "normal i=\<C-C>o\t /***\nD\n/"
exe "normal 2GOA\<C-C>joB\<C-C>jOC\<C-C>joE\<C-C>GOF\<C-C>joG"
let expected =<< trim END
=
A
/***
** B
** C
** D
** E
** F
******/
G
END
call assert_equal(expected, getline(1, '$'))
close!
endfunc
" Test for the 'O' flag in 'comments'
func Test_comment_O()
new
setlocal comments=Ob:* fo+=ro
exe "normal i* B\nD\<C-C>kOA\<C-C>joC"
let expected =<< trim END
A
* B
* C
* D
END
call assert_equal(expected, getline(1, '$'))
close!
endfunc
" Test for using a multibyte character as a comment leader
func Test_comment_multibyte_leader()
new
let t =<< trim END
{
a
a
XY
XYZ
YZ
XX
XXa
XXY
}
END
call setline(1, t)
call cursor(2, 1)
set tw=2 fo=cqm comments=n:
exe "normal gqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgqjgqgq"
let t =<< trim END
a
a
XY
XYZ
YZ
XX
XXa
XXY
END
exe "normal o\n" . join(t, "\n")
let expected =<< trim END
{
a
a
XY
XY
XY
XZ
XX
XXa
XXY
a
a
XY
XY
XY
XZ
XX
XXa
XXY
}
END
call assert_equal(expected, getline(1, '$'))
set tw& fo& comments&
close!
endfunc
" Test for a space character in 'comments' setting
func Test_comment_space()
new
setlocal comments=b:\ > fo+=ro
exe "normal i> B\nD\<C-C>ggOA\<C-C>joC"
exe "normal Go > F\nH\<C-C>kOE\<C-C>joG"
let expected =<< trim END
A
> B
C
D
> E
> F
> G
> H
END
call assert_equal(expected, getline(1, '$'))
close!
endfunc
" Test for formatting lines with and without comments
func Test_comment_format_lines()
new
call setline(1, ['one', '/* two */', 'three'])
normal gggqG
call assert_equal(['one', '/* two */', 'three'], getline(1, '$'))
close!
endfunc
" Test for using 'a' in 'formatoptions' with comments
func Test_comment_autoformat()
new
setlocal formatoptions+=a
call feedkeys("a- one\n- two\n", 'xt')
call assert_equal(['- one', '- two', ''], getline(1, '$'))
%d
call feedkeys("a\none\n", 'xt')
call assert_equal(['', 'one', ''], getline(1, '$'))
setlocal formatoptions+=aw
%d
call feedkeys("aone \ntwo\n", 'xt')
call assert_equal(['one two', ''], getline(1, '$'))
%d
call feedkeys("aone\ntwo\n", 'xt')
call assert_equal(['one', 'two', ''], getline(1, '$'))
close!
endfunc
" Test for joining lines with comments ('j' flag in 'formatoptions')
func Test_comment_join_lines_fo_j()
new
setlocal fo+=j comments=://
call setline(1, ['i++; // comment1', ' // comment2'])
normal J
call assert_equal('i++; // comment1 comment2', getline(1))
setlocal fo-=j
call setline(1, ['i++; // comment1', ' // comment2'])
normal J
call assert_equal('i++; // comment1 // comment2', getline(1))
" Test with nested comments
setlocal fo+=j comments=n:>,n:)
call setline(1, ['i++; > ) > ) comment1', ' > ) comment2'])
normal J
call assert_equal('i++; > ) > ) comment1 comment2', getline(1))
close!
endfunc
" Test for formatting lines where only the first line has a comment.
func Test_comment_format_firstline_comment()
new
setlocal formatoptions=tcq
call setline(1, ['- one two', 'three'])
normal gggqG
call assert_equal(['- one two three'], getline(1, '$'))
%d
call setline(1, ['- one', '- two'])
normal gggqG
call assert_equal(['- one', '- two'], getline(1, '$'))
close!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+22
View File
@@ -254,4 +254,26 @@ func Test_conceal_cursor_pos()
call delete('XTest_conceal_curpos')
endfunc
func Test_conceal_eol()
new!
setlocal concealcursor=n conceallevel=1
call setline(1, ["x", ""])
call matchaddpos('Conceal', [[2, 1, 1]], 2, -1, {'conceal': 1})
redraw!
call assert_notequal(screenchar(1, 1), screenchar(2, 2))
call assert_equal(screenattr(1, 1), screenattr(1, 2))
call assert_equal(screenattr(1, 2), screenattr(2, 2))
call assert_equal(screenattr(2, 1), screenattr(2, 2))
set list
redraw!
call assert_equal(screenattr(1, 1), screenattr(2, 2))
call assert_notequal(screenattr(1, 1), screenattr(1, 2))
call assert_notequal(screenattr(1, 2), screenattr(2, 1))
set nolist
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+2 -2
View File
@@ -103,7 +103,7 @@ func Test_cscopeWithCscopeConnections()
for cmd in ['cs find f Xmemfile_test.c', 'cs find 7 Xmemfile_test.c']
enew
let a = execute(cmd)
call assert_true(a =~ '"Xmemfile_test.c" \d\+L, \d\+C')
call assert_true(a =~ '"Xmemfile_test.c" \d\+L, \d\+B')
call assert_equal('Xmemfile_test.c', @%)
endfor
@@ -113,7 +113,7 @@ func Test_cscopeWithCscopeConnections()
let a = execute(cmd)
let alines = split(a, '\n', 1)
call assert_equal('', alines[0])
call assert_true(alines[1] =~ '"Xmemfile_test.c" \d\+L, \d\+C')
call assert_true(alines[1] =~ '"Xmemfile_test.c" \d\+L, \d\+B')
call assert_equal('(1 of 1): <<global>> #include <assert.h>', alines[2])
call assert_equal('#include <assert.h>', getline('.'))
endfor

Some files were not shown because too many files have changed in this diff Show More