mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-11 15:37:29 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
@@ -13,7 +13,8 @@ SRC_ALL = \
|
||||
.hgignore \
|
||||
.lgtm.yml \
|
||||
.travis.yml \
|
||||
appveyor.yml \
|
||||
.appveyor.yml \
|
||||
.codecov.yml \
|
||||
ci/appveyor.bat \
|
||||
ci/build-snd-dummy.sh \
|
||||
ci/config.mk*.sed \
|
||||
|
||||
+13
-5
@@ -1,4 +1,4 @@
|
||||
*change.txt* For Vim version 8.2. Last change: 2021 Jan 21
|
||||
*change.txt* For Vim version 8.2. Last change: 2021 Mar 01
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -649,6 +649,8 @@ For other systems the tmpnam() library function is used.
|
||||
The space between `:substitute` and the 'c', 'g',
|
||||
'i', 'I' and 'r' flags isn't required, but in scripts
|
||||
it's a good idea to keep it to avoid confusion.
|
||||
Also see the two and three letter commands to repeat
|
||||
:substitute below |:substitute-repeat|.
|
||||
|
||||
:[range]~[&][flags] [count] *:~*
|
||||
Repeat last substitute with same substitute string
|
||||
@@ -877,20 +879,26 @@ either the first or second pattern in parentheses did not match, so either
|
||||
*:sge* *:sgi* *:sgI* *:sgl* *:sgn* *:sgp* *:sgr* *:sI* *:si*
|
||||
*:sic* *:sIc* *:sie* *:sIe* *:sIg* *:sIl* *:sin* *:sIn* *:sIp*
|
||||
*:sip* *:sIr* *:sir* *:sr* *:src* *:srg* *:sri* *:srI* *:srl*
|
||||
*:srn* *:srp*
|
||||
*:srn* *:srp* *:substitute-repeat*
|
||||
2-letter and 3-letter :substitute commands ~
|
||||
|
||||
These commands repeat the previous `:substitute` command with the given flags.
|
||||
The first letter is always "s", followed by one or two of the possible flag
|
||||
characters. For example `:sce` works like `:s///ce`. The table lists the
|
||||
possible combinations, not all flags are possible, because the command is
|
||||
short for another command.
|
||||
|
||||
List of :substitute commands
|
||||
| c e g i I n p l r
|
||||
| c :sc :sce :scg :sci :scI :scn :scp :scl ---
|
||||
| c :sc :sce :scg :sci :scI :scn :scp :scl
|
||||
| e
|
||||
| g :sgc :sge :sg :sgi :sgI :sgn :sgp :sgl :sgr
|
||||
| i :sic :sie --- :si :siI :sin :sip --- :sir
|
||||
| i :sic :sie :si :siI :sin :sip :sir
|
||||
| I :sIc :sIe :sIg :sIi :sI :sIn :sIp :sIl :sIr
|
||||
| n
|
||||
| p
|
||||
| l
|
||||
| r :src --- :srg :sri :srI :srn :srp :srl :sr
|
||||
| r :src :srg :sri :srI :srn :srp :srl :sr
|
||||
|
||||
Exceptions:
|
||||
:scr is `:scriptnames`
|
||||
|
||||
+45
-16
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.2. Last change: 2021 Feb 10
|
||||
*eval.txt* For Vim version 8.2. Last change: 2021 Mar 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1187,7 +1187,8 @@ byte under the cursor: >
|
||||
|
||||
In Vim9 script:
|
||||
If expr8 is a String this results in a String that contains the expr1'th
|
||||
single character from expr8. To use byte indexes use |strpart()|.
|
||||
single character (including any composing characters) from expr8. To use byte
|
||||
indexes use |strpart()|.
|
||||
|
||||
Index zero gives the first byte or character. Careful: text column numbers
|
||||
start with one!
|
||||
@@ -1217,8 +1218,9 @@ In legacy Vim script the indexes are byte indexes. This doesn't recognize
|
||||
multibyte encodings, see |byteidx()| for computing the indexes. If expr8 is
|
||||
a Number it is first converted to a String.
|
||||
|
||||
In Vim9 script the indexes are character indexes. To use byte indexes use
|
||||
|strpart()|.
|
||||
In Vim9 script the indexes are character indexes and include composing
|
||||
characters. To use byte indexes use |strpart()|. To use character indexes
|
||||
without including composing characters use |strcharpart()|.
|
||||
|
||||
The item at index expr1b is included, it is inclusive. For an exclusive index
|
||||
use the |slice()| function.
|
||||
@@ -2935,10 +2937,11 @@ str2list({expr} [, {utf8}]) List convert each character of {expr} to
|
||||
ASCII/UTF8 value
|
||||
str2nr({expr} [, {base} [, {quoted}]])
|
||||
Number convert String to Number
|
||||
strcharpart({str}, {start} [, {len}])
|
||||
strcharlen({expr}) Number character length of the String {expr}
|
||||
strcharpart({str}, {start} [, {len} [, {skipcc}]])
|
||||
String {len} characters of {str} at
|
||||
character {start}
|
||||
strchars({expr} [, {skipcc}]) Number character length of the String {expr}
|
||||
strchars({expr} [, {skipcc}]) Number character count of the String {expr}
|
||||
strdisplaywidth({expr} [, {col}]) Number display length of the String {expr}
|
||||
strftime({format} [, {time}]) String format time with a specified format
|
||||
strgetchar({str}, {index}) Number get char {index} from {str}
|
||||
@@ -5312,6 +5315,9 @@ getcharpos({expr})
|
||||
Get the position for {expr}. Same as |getpos()| but the column
|
||||
number in the returned List is a character index instead of
|
||||
a byte index.
|
||||
If |getpos()| returns a very large column number, such as
|
||||
2147483647, then getcharpos() will return the character index
|
||||
of the last character.
|
||||
|
||||
Example:
|
||||
With the cursor on '세' in line 5 with text "여보세요": >
|
||||
@@ -5791,6 +5797,8 @@ getpos({expr}) Get the position for {expr}. For possible values of {expr}
|
||||
The column number in the returned List is the byte position
|
||||
within the line. To get the character position in the line,
|
||||
use |getcharpos()|
|
||||
The column number can be very large, e.g. 2147483647, in which
|
||||
case it means "after the end of the line".
|
||||
This can be used to save and restore the position of a mark: >
|
||||
let save_a_mark = getpos("'a")
|
||||
...
|
||||
@@ -7462,7 +7470,8 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
|
||||
to be used when fast match additions and deletions are
|
||||
required, for example to highlight matching parentheses.
|
||||
|
||||
The list {pos} can contain one of these items:
|
||||
{pos} is a list of positions. Each position can be one of
|
||||
these:
|
||||
- A number. This whole line will be highlighted. The first
|
||||
line has number 1.
|
||||
- A list with one number, e.g., [23]. The whole line with this
|
||||
@@ -7475,7 +7484,7 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
|
||||
- A list with three numbers, e.g., [23, 11, 3]. As above, but
|
||||
the third number gives the length of the highlight in bytes.
|
||||
|
||||
The maximum number of positions is 8.
|
||||
The maximum number of positions in {pos} is 8.
|
||||
|
||||
Example: >
|
||||
:highlight MyGroup ctermbg=green guibg=green
|
||||
@@ -7484,8 +7493,7 @@ matchaddpos({group}, {pos} [, {priority} [, {id} [, {dict}]]])
|
||||
:call matchdelete(m)
|
||||
|
||||
< Matches added by |matchaddpos()| are returned by
|
||||
|getmatches()| with an entry "pos1", "pos2", etc., with the
|
||||
value a list like the {pos} item.
|
||||
|getmatches()|.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetGroup()->matchaddpos([23, 11])
|
||||
@@ -9925,7 +9933,7 @@ slice({expr}, {start} [, {end}]) *slice()*
|
||||
Similar to using a |slice| "expr[start : end]", but "end" is
|
||||
used exclusive. And for a string the indexes are used as
|
||||
character indexes instead of byte indexes, like in
|
||||
|vim9script|.
|
||||
|vim9script|. Also, composing characters are not counted.
|
||||
When {end} is omitted the slice continues to the last item.
|
||||
When {end} is -1 the last item is omitted.
|
||||
|
||||
@@ -10283,23 +10291,44 @@ str2nr({expr} [, {base} [, {quoted}]]) *str2nr()*
|
||||
Can also be used as a |method|: >
|
||||
GetText()->str2nr()
|
||||
|
||||
strcharpart({src}, {start} [, {len}]) *strcharpart()*
|
||||
|
||||
strcharlen({expr}) *strcharlen()*
|
||||
The result is a Number, which is the number of characters
|
||||
in String {expr}. Composing characters are ignored.
|
||||
|strchars()| can count the number of characters, counting
|
||||
composing characters separately.
|
||||
|
||||
Also see |strlen()|, |strdisplaywidth()| and |strwidth()|.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetText()->strcharlen()
|
||||
|
||||
|
||||
strcharpart({src}, {start} [, {len} [, {skipcc}]]) *strcharpart()*
|
||||
Like |strpart()| but using character index and length instead
|
||||
of byte index and length.
|
||||
When {skipcc} is omitted or zero, composing characters are
|
||||
counted separately.
|
||||
When {skipcc} set to 1, Composing characters are ignored,
|
||||
similar to |slice()|.
|
||||
When a character index is used where a character does not
|
||||
exist it is assumed to be one character. For example: >
|
||||
exist it is omitted and counted as one character. For
|
||||
example: >
|
||||
strcharpart('abc', -1, 2)
|
||||
< results in 'a'.
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetText()->strcharpart(5)
|
||||
|
||||
|
||||
strchars({expr} [, {skipcc}]) *strchars()*
|
||||
The result is a Number, which is the number of characters
|
||||
in String {expr}.
|
||||
When {skipcc} is omitted or zero, composing characters are
|
||||
counted separately.
|
||||
When {skipcc} set to 1, Composing characters are ignored.
|
||||
|strcharlen()| always does this.
|
||||
|
||||
Also see |strlen()|, |strdisplaywidth()| and |strwidth()|.
|
||||
|
||||
{skipcc} is only available after 7.4.755. For backward
|
||||
@@ -13159,7 +13188,7 @@ text...
|
||||
Cannot be followed by a comment.
|
||||
Examples: >
|
||||
:execute "buffer" nextbuf
|
||||
:execute "normal" count . "w"
|
||||
:execute "normal" count .. "w"
|
||||
<
|
||||
":execute" can be used to append a command to commands
|
||||
that don't accept a '|'. Example: >
|
||||
@@ -13175,8 +13204,8 @@ text...
|
||||
file names. The |fnameescape()| function can be used
|
||||
for Vim commands, |shellescape()| for |:!| commands.
|
||||
Examples: >
|
||||
:execute "e " . fnameescape(filename)
|
||||
:execute "!ls " . shellescape(filename, 1)
|
||||
:execute "e " .. fnameescape(filename)
|
||||
:execute "!ls " .. shellescape(filename, 1)
|
||||
<
|
||||
Note: The executed string may be any command-line, but
|
||||
starting or ending "if", "while" and "for" does not
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*filetype.txt* For Vim version 8.2. Last change: 2021 Jan 21
|
||||
*filetype.txt* For Vim version 8.2. Last change: 2021 Mar 11
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -628,6 +628,13 @@ For fish, add to the config file
|
||||
|
||||
set -x MANPAGER "vim -M +MANPAGER -"
|
||||
|
||||
|
||||
MARKDOWN *ft-markdown-plugin*
|
||||
|
||||
To enable folding use this: >
|
||||
let g:markdown_folding = 1
|
||||
<
|
||||
|
||||
PDF *ft-pdf-plugin*
|
||||
|
||||
Two maps, <C-]> and <C-T>, are provided to simulate a tag stack for navigating
|
||||
|
||||
@@ -263,6 +263,20 @@ input. Example: >
|
||||
endfunc
|
||||
nnoremap <expr> <F3> <Sid>OpenPopup()
|
||||
|
||||
Also, keep in mind that the expression may be evaluated when looking for
|
||||
typeahead, before the previous command has been executed. For example: >
|
||||
func StoreColumn()
|
||||
let g:column = col('.')
|
||||
return 'x'
|
||||
endfunc
|
||||
nnoremap <expr> x StoreColumn()
|
||||
nmap ! f!x
|
||||
You will notice that g:column has the value from before executing "fx",
|
||||
because "z" is evaluated before "fx" is executed.
|
||||
This can be solved by inserting <Ignore> before the character that is
|
||||
expression-mapped: >
|
||||
nmap ! f!<Ignore>x
|
||||
|
||||
Be very careful about side effects! The expression is evaluated while
|
||||
obtaining characters, you may very well make the command dysfunctional.
|
||||
For this reason the following is blocked:
|
||||
|
||||
@@ -677,9 +677,9 @@ Your directory layout would be like this:
|
||||
opt/fooextra/doc/tags " help tags
|
||||
|
||||
This allows for the user to do: >
|
||||
mkdir ~/.vim/pack/myfoobar
|
||||
cd ~/.vim/pack/myfoobar
|
||||
git clone https://github.com/you/foobar.git
|
||||
mkdir ~/.vim/pack
|
||||
cd ~/.vim/pack
|
||||
git clone https://github.com/you/foobar.git myfoobar
|
||||
|
||||
Here "myfoobar" is a name that the user can choose, the only condition is that
|
||||
it differs from other packages.
|
||||
|
||||
+18
-2
@@ -1,4 +1,4 @@
|
||||
*sign.txt* For Vim version 8.2. Last change: 2020 Oct 28
|
||||
*sign.txt* For Vim version 8.2. Last change: 2021 Mar 07
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Gordon Prieur
|
||||
@@ -146,6 +146,9 @@ See |sign_define()| for the equivalent Vim script function.
|
||||
texthl={group}
|
||||
Highlighting group used for the text item.
|
||||
|
||||
Example: >
|
||||
:sign define MySign text=>> texthl=Search linehl=DiffText
|
||||
<
|
||||
|
||||
DELETING A SIGN *:sign-undefine* *E155*
|
||||
|
||||
@@ -155,7 +158,9 @@ See |sign_undefine()| for the equivalent Vim script function.
|
||||
Deletes a previously defined sign. If signs with this {name}
|
||||
are still placed this will cause trouble.
|
||||
|
||||
|
||||
Example: >
|
||||
:sign undefine MySign
|
||||
<
|
||||
|
||||
LISTING SIGNS *:sign-list* *E156*
|
||||
|
||||
@@ -209,6 +214,10 @@ See |sign_place()| for the equivalent Vim script function.
|
||||
Same, but use buffer {nr}. If the buffer argument is not
|
||||
given, place the sign in the current buffer.
|
||||
|
||||
Example: >
|
||||
:sign place 10 line=99 name=sign3
|
||||
:sign place 10 line=99 name=sign3 buffer=3
|
||||
<
|
||||
*E885*
|
||||
:sign place {id} name={name} file={fname}
|
||||
Change the placed sign {id} in file {fname} to use the defined
|
||||
@@ -221,10 +230,17 @@ See |sign_place()| for the equivalent Vim script function.
|
||||
"priority={prio}" attribute can be used to change the priority
|
||||
of an existing sign.
|
||||
|
||||
Example: >
|
||||
:sign place 23 name=sign1 file=/path/to/edit.py
|
||||
<
|
||||
:sign place {id} name={name} [buffer={nr}]
|
||||
Same, but use buffer {nr}. If the buffer argument is not
|
||||
given, use the current buffer.
|
||||
|
||||
Example: >
|
||||
:sign place 23 name=sign1
|
||||
:sign place 23 name=sign1 buffer=7
|
||||
<
|
||||
|
||||
REMOVING SIGNS *:sign-unplace* *E159*
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*syntax.txt* For Vim version 8.2. Last change: 2021 Jan 21
|
||||
*syntax.txt* For Vim version 8.2. Last change: 2021 Mar 06
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1741,8 +1741,8 @@ The coloring scheme for tags in the HTML file works as follows.
|
||||
|
||||
The <> of opening tags are colored differently than the </> of a closing tag.
|
||||
This is on purpose! For opening tags the 'Function' color is used, while for
|
||||
closing tags the 'Type' color is used (See syntax.vim to check how those are
|
||||
defined for you)
|
||||
closing tags the 'Identifier' color is used (See syntax.vim to check how those
|
||||
are defined for you)
|
||||
|
||||
Known tag names are colored the same way as statements in C. Unknown tag
|
||||
names are colored with the same color as the <> or </> respectively which
|
||||
@@ -4676,7 +4676,7 @@ matches, nextgroup, etc. But there are a few differences:
|
||||
- A line continuation pattern can be given. It is used to decide which group
|
||||
of lines need to be searched like they were one line. This means that the
|
||||
search for a match with the specified items starts in the first of the
|
||||
consecutive that contain the continuation pattern.
|
||||
consecutive lines that contain the continuation pattern.
|
||||
- When using "nextgroup" or "contains", this only works within one line (or
|
||||
group of continued lines).
|
||||
- When using a region, it must start and end in the same line (or group of
|
||||
|
||||
@@ -3218,6 +3218,7 @@ $VIM_POSIX vi_diff.txt /*$VIM_POSIX*
|
||||
:stselect tagsrch.txt /*:stselect*
|
||||
:su change.txt /*:su*
|
||||
:substitute change.txt /*:substitute*
|
||||
:substitute-repeat change.txt /*:substitute-repeat*
|
||||
:sun windows.txt /*:sun*
|
||||
:sunhide windows.txt /*:sunhide*
|
||||
:sunm map.txt /*:sunm*
|
||||
@@ -6667,6 +6668,7 @@ ft-mail.vim syntax.txt /*ft-mail.vim*
|
||||
ft-make-syntax syntax.txt /*ft-make-syntax*
|
||||
ft-man-plugin filetype.txt /*ft-man-plugin*
|
||||
ft-maple-syntax syntax.txt /*ft-maple-syntax*
|
||||
ft-markdown-plugin filetype.txt /*ft-markdown-plugin*
|
||||
ft-masm-syntax syntax.txt /*ft-masm-syntax*
|
||||
ft-mathematica-syntax syntax.txt /*ft-mathematica-syntax*
|
||||
ft-matlab-indent indent.txt /*ft-matlab-indent*
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*testing.txt* For Vim version 8.2. Last change: 2020 Dec 12
|
||||
*testing.txt* For Vim version 8.2. Last change: 2021 Mar 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -168,6 +168,7 @@ test_override({name}, {val}) *test_override()*
|
||||
wait time of up to 3 seconds for messages
|
||||
term_props reset all terminal properties when the version
|
||||
string is detected
|
||||
uptime overrules sysinfo.uptime
|
||||
ALL clear all overrides ({val} is not used)
|
||||
|
||||
"starting" is to be used when a test should behave like
|
||||
|
||||
+40
-15
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.2. Last change: 2021 Feb 20
|
||||
*todo.txt* For Vim version 8.2. Last change: 2021 Mar 11
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -39,13 +39,25 @@ browser use: https://github.com/vim/vim/issues/1234
|
||||
-------------------- Known bugs and current work -----------------------
|
||||
|
||||
Vim9 - Make everything work:
|
||||
- Implement "export {one, two three}".
|
||||
- Does this work now: Implement using imported items at script level from
|
||||
"import * as X" in
|
||||
- import of item that isn't exported: error should mention missing "export"?
|
||||
- no error for using :import in legacy script?
|
||||
- Disallow :open ?
|
||||
- Check: what if 'cpo' is intentionally changed in Vim9 script, does it get
|
||||
restored at the end?
|
||||
- ISN_CHECKTYPE could use check_argtype()
|
||||
- Using a script variable inside a :def function doesn't work if the variable
|
||||
is inside a block, see Test_nested_function(). Should it work?
|
||||
- give error for variable name:
|
||||
var p = function('NoSuchFunc')
|
||||
- When indexing a string, should we include composing characters? #6563
|
||||
string[0] - first character including its composing characters.
|
||||
string[0 : 0] - same
|
||||
If you don't want that use strcharpart().
|
||||
Also, add optional arg to strcharpart() to include composing chars, to
|
||||
make it consistent with strchars().
|
||||
Add strcharlen(), like strchars() but like skipcc is always set
|
||||
- Make closures work better:
|
||||
- Create closure in a loop. Need to make a list of them.
|
||||
- If a :def function is called with a function reference, compile it to get
|
||||
@@ -74,13 +86,11 @@ Vim9 - Make everything work:
|
||||
- make 0 == 'string' fail on the script level, like inside :def.
|
||||
- Check that when using a user function name without prefix, it does not find
|
||||
a global function. Prefixing g: is required.
|
||||
- Need the equivalent of get_lval() and set_var_lval() to implement assignment
|
||||
to nested list and dict members.
|
||||
- Assignment to dict doesn't work:
|
||||
var ret: dict<string> = #{}
|
||||
ret[i] = string(i)
|
||||
- Appending to dict item doesn't work:
|
||||
var d[i] ..= value
|
||||
- Appending to dict item doesn't work in a :def function:
|
||||
var d: dict<string> = {a: 'x'}
|
||||
d['a'] ..= 'y'
|
||||
d.a ..= 'y'
|
||||
Test to be extended: Test_assign_dict_with_op()
|
||||
- Using ".." at script level doesn't convert arguments to a string.
|
||||
- Compile replacement of :s command: s/pat/\=expr/
|
||||
- Compile redir to local variable: var_redir_start().
|
||||
@@ -89,8 +99,6 @@ Vim9 - Make everything work:
|
||||
islocked()
|
||||
- When evaluating constants for script variables, some functions could work:
|
||||
has('asdf'), len('string')
|
||||
- Implement "as Name" in "import Item as Name from ..."
|
||||
- Implement using imported items at script level from "import * as X" in
|
||||
eval_variable(). Should pass the ".xxx" that follows and return that.
|
||||
- Make "++nr" work. "++g:count" doesn't work, thinks it is a range.
|
||||
- Reload: How to make sure type of script function hasn't changed?
|
||||
@@ -102,6 +110,11 @@ Vim9 - Make everything work:
|
||||
- give an error for "echo Func()" if Func() does not return anything.
|
||||
- Using "windo echo expr" does not accept a line break inside "expr" (in a
|
||||
:def function and at script level in a not executed block). #7681
|
||||
- "assert_fails()" cannot access local variables. Perhaps add this:
|
||||
assertfails
|
||||
... cmd ...
|
||||
endassertfails /E99:.*cmd/
|
||||
Similar to try/catch/endtry but without the boilerplate.
|
||||
|
||||
Once Vim9 is stable:
|
||||
- Change the help to prefer Vim9 syntax where appropriate
|
||||
@@ -184,6 +197,7 @@ Text properties:
|
||||
- Popup attached to text property stays visible when text is deleted with
|
||||
"cc". (#7737) "C" works OK. "dd" also files in a buffer with a single
|
||||
line.
|
||||
- Auto-indenting may cause highlighting to shift. (#7719)
|
||||
- "cc" does not call inserted_bytes(). (Axel Forsman, #5763)
|
||||
- Combining text property with 'cursorline' does not always work (Billie
|
||||
Cleek, #5533)
|
||||
@@ -263,7 +277,9 @@ Terminal emulator window:
|
||||
- When 'encoding' is not utf-8, or the job is using another encoding, setup
|
||||
conversions.
|
||||
|
||||
Valgrind reports memory leaks in test_options
|
||||
Include patch #6290: recognize shell directory change.
|
||||
|
||||
Valgrind reports memory leaks in test_options.
|
||||
|
||||
test_arglist func Test_all_not_allowed_from_cmdwin() hangs on MS-Windows.
|
||||
|
||||
@@ -277,6 +293,8 @@ Was originally written by Felipe Morales.
|
||||
|
||||
Adding "10" to 'spellsuggest' causes spell suggestions to become very slow.
|
||||
(#4087) Did patch 8.2.2379 help?
|
||||
Also, z= in German on a long word can take a very long time, but CTRL-C to
|
||||
interrupt does not work. Where to add ui_breakcheck()?
|
||||
|
||||
Remove SPACE_IN_FILENAME ? It is only used for completion.
|
||||
|
||||
@@ -288,6 +306,8 @@ with 'termguicolors'. #1740
|
||||
|
||||
Patch for blockwise paste reporting changes: #6660.
|
||||
|
||||
Patch to make fillchars global-local. (#5206)
|
||||
|
||||
Missing filetype test for bashrc, PKGBUILD, etc.
|
||||
|
||||
Add an option to not fetch terminal codes in xterm, to avoid flicker when t_Co
|
||||
@@ -306,6 +326,10 @@ Try setting a color then request the current color, like using t_u7.
|
||||
Regexp to search for duplicate lines does not work correctly:
|
||||
/\(^.*\n\)\1 (Chris Morgan, #6239)
|
||||
|
||||
MS-Windows: when writing undo file the infostreams are copied in
|
||||
mch_copy_file_attribute(), that seems unnecessary. (#7925)
|
||||
Add a flag to only copy attributes?
|
||||
|
||||
Changing a capturing group to non-capturing changes the result: #7607
|
||||
:echo matchstr('aaa bbb', '\(.\{-1,}\>\)\|.*')
|
||||
aaa
|
||||
@@ -382,6 +406,10 @@ manager. Problem with Motif?
|
||||
|
||||
Patch to add :argdedupe. (Nir Lichtman, #6235)
|
||||
|
||||
When editing a file with ":edit" the output of :swapname is relative, while
|
||||
editing it with "vim file" it is absolute. (#355)
|
||||
Which one should it be?
|
||||
|
||||
:map output does not clear the reset of the command line.
|
||||
(#5623, also see #5962)
|
||||
|
||||
@@ -1156,9 +1184,6 @@ timer expires.
|
||||
Rule to use "^" for statusline does not work if a space is defined with
|
||||
highlighting for both stl and stlnc. Patch by Ken Hamada (itchyny, 2016 Dec 11)
|
||||
|
||||
8 "stl" and "stlnc" in 'fillchars' don't work for multibyte characters.
|
||||
Patch by Christian Wellenbrock, 2013 Jul 5.
|
||||
|
||||
Using CTRL-G_U in InsertCharPre causes trouble for redo. (Israel Chauca
|
||||
Fuentes, 2017 Feb 12, #1470)
|
||||
|
||||
|
||||
@@ -611,7 +611,8 @@ String manipulation: *string-functions*
|
||||
stridx() first index of a short string in a long string
|
||||
strridx() last index of a short string in a long string
|
||||
strlen() length of a string in bytes
|
||||
strchars() length of a string in characters
|
||||
strcharlen() length of a string in characters
|
||||
strchars() number of characters in a string
|
||||
strwidth() size of string when displayed
|
||||
strdisplaywidth() size of string when displayed, deals with tabs
|
||||
setcellwidths() set character cell width overrides
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*various.txt* For Vim version 8.2. Last change: 2021 Jan 26
|
||||
*various.txt* For Vim version 8.2. Last change: 2021 Mar 02
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -575,7 +575,7 @@ N *+X11* Unix only: can restore window title |X11|
|
||||
it in / any non-ID character (see |'isident'|) can be
|
||||
used, so long as it does not appear in {pat}. Without
|
||||
the enclosing character the pattern cannot include the
|
||||
bar character.
|
||||
bar character. 'ignorecase' is not used.
|
||||
|
||||
The pattern is matched against the relevant part of
|
||||
the output, not necessarily the whole line. Only some
|
||||
|
||||
+16
-8
@@ -1,4 +1,4 @@
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2021 Feb 23
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2021 Mar 03
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -96,8 +96,8 @@ script and `:def` functions; details are below:
|
||||
def CallMe(count: number, message: string): bool
|
||||
- Call functions without `:call`: >
|
||||
writefile(['done'], 'file.txt')
|
||||
- You cannot use `:xit`, `:t`, `:k`, `:append`, `:change`, `:insert` or
|
||||
curly-braces names.
|
||||
- You cannot use `:xit`, `:t`, `:k`, `:append`, `:change`, `:insert`, `:open`
|
||||
or curly-braces names.
|
||||
- A range before a command must be prefixed with a colon: >
|
||||
:%s/this/that
|
||||
- Unless mentioned specifically, the highest |scriptversion| is used.
|
||||
@@ -341,7 +341,8 @@ Functions can be called without `:call`: >
|
||||
Using `:call` is still possible, but this is discouraged.
|
||||
|
||||
A method call without `eval` is possible, so long as the start is an
|
||||
identifier or can't be an Ex command. Examples: >
|
||||
identifier or can't be an Ex command. For a function either "(" or "->" must
|
||||
be following, without a line break. Examples: >
|
||||
myList->add(123)
|
||||
g:myList->add(123)
|
||||
[1, 2, 3]->Process()
|
||||
@@ -696,8 +697,9 @@ for v:null. When converting a boolean to a string "false" and "true" are
|
||||
used, not "v:false" and "v:true" like in legacy script. "v:none" is not
|
||||
changed, it is only used in JSON and has no equivalent in other languages.
|
||||
|
||||
Indexing a string with [idx] or [idx : idx] uses character indexes instead of
|
||||
byte indexes. Example: >
|
||||
Indexing a string with [idx] or taking a slice with [idx : idx] uses character
|
||||
indexes instead of byte indexes. Composing characters are included.
|
||||
Example: >
|
||||
echo 'bár'[1]
|
||||
In legacy script this results in the character 0xc3 (an illegal byte), in Vim9
|
||||
script this results in the string 'á'.
|
||||
@@ -800,6 +802,8 @@ Patterns are used like 'magic' is set, unless explicitly overruled.
|
||||
The 'edcompatible' option value is not used.
|
||||
The 'gdefault' option value is not used.
|
||||
|
||||
You may also find this wiki useful. It was written by an early adoptor of
|
||||
Vim9 script: https://github.com/lacygoill/wiki/blob/master/vim/vim9.md
|
||||
|
||||
==============================================================================
|
||||
|
||||
@@ -843,6 +847,8 @@ THIS IS STILL UNDER DEVELOPMENT - ANYTHING CAN BREAK - ANYTHING CAN CHANGE
|
||||
:enddef End of a function defined with `:def`. It should be on
|
||||
a line by its own.
|
||||
|
||||
You may also find this wiki useful. It was written by an early adoptor of
|
||||
Vim9 script: https://github.com/lacygoill/wiki/blob/master/vim/vim9.md
|
||||
|
||||
If the script the function is defined in is Vim9 script, then script-local
|
||||
variables can be accessed without the "s:" prefix. They must be defined
|
||||
@@ -1076,7 +1082,9 @@ A side effect of `:vim9script` is that the 'cpoptions' option is set to the
|
||||
Vim default value, like with: >
|
||||
:set cpo&vim
|
||||
One of the effects is that |line-continuation| is always enabled.
|
||||
The original value of 'cpoptions' is restored at the end of the script.
|
||||
The original value of 'cpoptions' is restored at the end of the script, while
|
||||
flags added or removed in the script are also added to or removed from the
|
||||
original value to get the same effect. The order of flags may change.
|
||||
|
||||
*vim9-mix*
|
||||
There is one way to use both legacy and Vim9 syntax in one script file: >
|
||||
@@ -1111,7 +1119,7 @@ Exporting an item can be written as: >
|
||||
export class MyClass ...
|
||||
|
||||
As this suggests, only constants, variables, `:def` functions and classes can
|
||||
be exported. {classes are not implemented yet}
|
||||
be exported. {not implemented yet: export class}
|
||||
|
||||
*E1042*
|
||||
`:export` can only be used in Vim9 script, at the script level.
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2021 Jan 21
|
||||
" Last Change: 2021 Mar 12
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@@ -1334,6 +1334,9 @@ au BufNewFile,BufRead *.pml setf promela
|
||||
au BufNewFile,BufRead *.proto setf proto
|
||||
au BufNewFile,BufRead *.pbtxt setf pbtxt
|
||||
|
||||
" Poke
|
||||
au BufNewFile,BufRead *.pk setf poke
|
||||
|
||||
" Protocols
|
||||
au BufNewFile,BufRead */etc/protocols setf protocols
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
" Vim filetype plugin file
|
||||
" Language: GNU Poke
|
||||
" Maintainer: Doug Kearns <dougkearns@gmail.com>
|
||||
" Last Change: 2021 March 11
|
||||
|
||||
if exists("b:did_ftplugin")
|
||||
finish
|
||||
endif
|
||||
let b:did_ftplugin = 1
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
setlocal comments=sO:*\ -,mO:*\ \ ,exO:*/,s1:/*,mb:*,ex:*/,://
|
||||
setlocal commentstring=//\ %s
|
||||
setlocal formatoptions-=t formatoptions+=croql
|
||||
|
||||
setlocal include=load
|
||||
setlocal suffixesadd=.pk
|
||||
|
||||
if (has("gui_win32") || has("gui_gtk")) && !exists("b:browsefilter")
|
||||
let b:browsefilter = "Poke Files (*.pk)\t*.pk\n" .
|
||||
\ "All Files (*.*)\t*.*\n"
|
||||
endif
|
||||
|
||||
let b:undo_ftplugin = "setl fo< com< cms< inc< sua<" .
|
||||
\ " | unlet! b:browsefilter"
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
|
||||
" vim: nowrap sw=2 sts=2 ts=8
|
||||
+25
-44
@@ -3,8 +3,9 @@
|
||||
" Previous Maintainer: Jorge Maldonado Ventura <jorgesumle@freakspot.net>
|
||||
" Previous Maintainer: Claudio Fleiner <claudio@fleiner.com>
|
||||
" Repository: https://notabug.org/jorgesumle/vim-html-syntax
|
||||
" Last Change: 2021 Feb 25
|
||||
" Last Change: 2021 Mar 02
|
||||
" Included patch #7900 to fix comments
|
||||
" Included patch #7916 to fix a few more things
|
||||
"
|
||||
|
||||
" Please check :help html.vim for some comments and a description of the options
|
||||
@@ -79,26 +80,16 @@ syn keyword htmlArg contained usemap ismap valign value vlink vspace width wrap
|
||||
syn match htmlArg contained "\<\(http-equiv\|href\|title\)="me=e-1
|
||||
|
||||
" aria attributes
|
||||
syn match htmlArg contained "\<\(aria-activedescendant\|aria-atomic\)\>"
|
||||
syn match htmlArg contained "\<\(aria-autocomplete\|aria-busy\|aria-checked\)\>"
|
||||
syn match htmlArg contained "\<\(aria-colcount\|aria-colindex\|aria-colspan\)\>"
|
||||
syn match htmlArg contained "\<\(aria-controls\|aria-current\)\>"
|
||||
syn match htmlArg contained "\<\(aria-describedby\|aria-details\)\>"
|
||||
syn match htmlArg contained "\<\(aria-disabled\|aria-dropeffect\)\>"
|
||||
syn match htmlArg contained "\<\(aria-errormessage\|aria-expanded\)\>"
|
||||
syn match htmlArg contained "\<\(aria-flowto\|aria-grabbed\|aria-haspopup\)\>"
|
||||
syn match htmlArg contained "\<\(aria-hidden\|aria-invalid\)\>"
|
||||
syn match htmlArg contained "\<\(aria-keyshortcuts\|aria-label\)\>"
|
||||
syn match htmlArg contained "\<\(aria-labelledby\|aria-level\|aria-live\)\>"
|
||||
syn match htmlArg contained "\<\(aria-modal\|aria-multiline\)\>"
|
||||
syn match htmlArg contained "\<\(aria-multiselectable\|aria-orientation\)\>"
|
||||
syn match htmlArg contained "\<\(aria-owns\|aria-placeholder\|aria-posinset\)\>"
|
||||
syn match htmlArg contained "\<\(aria-pressed\|aria-readonly\|aria-relevant\)\>"
|
||||
syn match htmlArg contained "\<\(aria-required\|aria-roledescription\)\>"
|
||||
syn match htmlArg contained "\<\(aria-rowcount\|aria-rowindex\|aria-rowspan\)\>"
|
||||
syn match htmlArg contained "\<\(aria-selected\|aria-setsize\|aria-sort\)\>"
|
||||
syn match htmlArg contained "\<\(aria-valuemax\|aria-valuemin\)\>"
|
||||
syn match htmlArg contained "\<\(aria-valuenow\|aria-valuetext\)\>"
|
||||
exe 'syn match htmlArg contained "\<aria-\%(' . join([
|
||||
\ 'activedescendant', 'atomic', 'autocomplete', 'busy', 'checked', 'colcount',
|
||||
\ 'colindex', 'colspan', 'controls', 'current', 'describedby', 'details',
|
||||
\ 'disabled', 'dropeffect', 'errormessage', 'expanded', 'flowto', 'grabbed',
|
||||
\ 'haspopup', 'hidden', 'invalid', 'keyshortcuts', 'label', 'labelledby', 'level',
|
||||
\ 'live', 'modal', 'multiline', 'multiselectable', 'orientation', 'owns',
|
||||
\ 'placeholder', 'posinset', 'pressed', 'readonly', 'relevant', 'required',
|
||||
\ 'roledescription', 'rowcount', 'rowindex', 'rowspan', 'selected', 'setsize',
|
||||
\ 'sort', 'valuemax', 'valuemin', 'valuenow', 'valuetext'
|
||||
\ ], '\|') . '\)\>"'
|
||||
syn keyword htmlArg contained role
|
||||
|
||||
" Netscape extensions
|
||||
@@ -139,25 +130,19 @@ syn match htmlSpecialChar "&#\=[0-9A-Za-z]\{1,8};"
|
||||
|
||||
" Comments (the real ones or the old netscape ones)
|
||||
if exists("html_wrong_comments")
|
||||
syn region htmlComment start=+<!--+ end=+--\s*>+ contains=@Spell
|
||||
syn region htmlComment start=+<!--+ end=+--\s*>+ contains=@Spell
|
||||
else
|
||||
" The HTML 5.2 syntax 8.2.4.41-42: bogus comment is parser error; browser skips until next >
|
||||
" Note: must stand first to get lesser :syn-priority
|
||||
syn region htmlComment start=+<!+ end=+>+ contains=htmlCommentError
|
||||
" Normal comment opening <!-- ...>
|
||||
syn region htmlComment start=+<!--+ end=+>+ contains=htmlCommentPart,@Spell
|
||||
" Idem 8.2.4.43-44: <!--> and <!---> are parser errors; browser treats as comments
|
||||
syn match htmlComment "<!---\?>" contains=htmlCommentError
|
||||
" Idem 8.2.4.51: any number of consecutive dashes within comment is okay; --> closes comment
|
||||
" Idem 8.2.4.52: closing comment by dash-dash-bang (--!>) is error ignored by parser(!); closes comment
|
||||
syn region htmlCommentPart contained start=+--+ end=+--!\?>+me=e-1 contains=htmlCommentNested,@htmlPreProc,@Spell
|
||||
" Idem 8.2.4.49: opening nested comment <!-- is parser error, ignored by browser, except <!--> is all right
|
||||
syn match htmlCommentNested contained "<!--[^>]"me=e-1
|
||||
syn match htmlCommentNested contained "<!--->"me=e-3
|
||||
syn match htmlCommentNested contained "<!---\?!>"me=e-4
|
||||
syn match htmlCommentError contained "[^><!]"
|
||||
" The HTML 5.2 syntax 8.2.4.41: bogus comment is parser error; browser skips until next >
|
||||
syn region htmlComment start=+<!+ end=+>+ contains=htmlCommentError keepend
|
||||
" Idem 8.2.4.42,51: Comment starts with <!-- and ends with -->
|
||||
" Idem 8.2.4.43,44: Except <!--> and <!---> are parser errors
|
||||
" Idem 8.2.4.52: dash-dash-bang (--!>) is error ignored by parser, also closes comment
|
||||
syn region htmlComment matchgroup=htmlComment start=+<!--\%(-\?>\)\@!+ end=+--!\?>+ contains=htmlCommentNested,@htmlPreProc,@Spell keepend
|
||||
" Idem 8.2.4.49: nested comment is parser error, except <!--> is all right
|
||||
syn match htmlCommentNested contained "<!-->\@!"
|
||||
syn match htmlCommentError contained "[^><!]"
|
||||
endif
|
||||
syn region htmlComment start=+<!DOCTYPE+ keepend end=+>+
|
||||
syn region htmlComment start=+<!DOCTYPE+ end=+>+ keepend
|
||||
|
||||
" server-parsed commands
|
||||
syn region htmlPreProc start=+<!--#+ end=+-->+ contains=htmlPreStmt,htmlPreError,htmlPreAttr
|
||||
@@ -278,7 +263,7 @@ hi def link htmlEndTag Identifier
|
||||
hi def link htmlArg Type
|
||||
hi def link htmlTagName htmlStatement
|
||||
hi def link htmlSpecialTagName Exception
|
||||
hi def link htmlValue String
|
||||
hi def link htmlValue String
|
||||
hi def link htmlSpecialChar Special
|
||||
|
||||
if !exists("html_no_rendering")
|
||||
@@ -322,14 +307,10 @@ hi def link htmlPreProc PreProc
|
||||
hi def link htmlPreAttr String
|
||||
hi def link htmlPreProcAttrName PreProc
|
||||
hi def link htmlPreProcAttrError Error
|
||||
hi def link htmlSpecial Special
|
||||
hi def link htmlSpecialChar Special
|
||||
hi def link htmlString String
|
||||
hi def link htmlStatement Statement
|
||||
hi def link htmlComment Comment
|
||||
hi def link htmlCommentPart Comment
|
||||
hi def link htmlValue String
|
||||
hi def link htmlCommentNested htmlCommentError
|
||||
hi def link htmlCommentNested htmlError
|
||||
hi def link htmlCommentError htmlError
|
||||
hi def link htmlTagError htmlError
|
||||
hi def link htmlEvent javaScript
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
" Copyright (C) 2021 Matthew T. Ihlenfield.
|
||||
"
|
||||
" This program is free software: you can redistribute it and/or modify
|
||||
" it under the terms of the GNU General Public License as published by
|
||||
" the Free Software Foundation, either version 3 of the License, or
|
||||
" (at your option) any later version.
|
||||
"
|
||||
" This program is distributed in the hope that it will be useful,
|
||||
" but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
" GNU General Public License for more details.
|
||||
"
|
||||
" You should have received a copy of the GNU General Public License
|
||||
" along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
"
|
||||
" Vim syntax file
|
||||
" Language: Poke
|
||||
" Maintainer: Matt Ihlenfield <mtihlenfield@protonmail.com>
|
||||
" Filenames: *.pk
|
||||
" Latest Revision: 10 March 2021
|
||||
|
||||
if exists('b:current_syntax')
|
||||
finish
|
||||
endif
|
||||
|
||||
" Poke statement
|
||||
syn keyword pokeStatement assert break continue return
|
||||
syn keyword pokeStatement type unit fun method nextgroup=pokeFunction skipwhite
|
||||
syn keyword pokeStatement var nextgroup=pokeVar skipWhite
|
||||
|
||||
" Identifiers
|
||||
syn match pokeVar '\h\w*' display contained
|
||||
|
||||
" User defined functions
|
||||
syn match pokeFunction '\h\w*' display contained
|
||||
|
||||
" Poke operators
|
||||
syn keyword pokeOperator in sizeof as isa unmap
|
||||
|
||||
" Conditionals
|
||||
syn keyword pokeConditional if else where
|
||||
|
||||
" Structures, unions, etc...
|
||||
syn keyword pokeStructure struct union pinned
|
||||
|
||||
" Loops
|
||||
syn keyword pokeRepeat while for
|
||||
|
||||
" Imports
|
||||
syn keyword pokeLoad load
|
||||
|
||||
" Exceptions
|
||||
syn keyword pokeException try catch until raise
|
||||
|
||||
" Exception types
|
||||
syn keyword pokeExceptionType Exception E_generic E_out_of_bounds
|
||||
syn keyword pokeExceptionType E_eof E_elem E_constraint
|
||||
syn keyword pokeExceptionType E_conv E_map_bounds E_map
|
||||
syn keyword pokeExceptionType E_div_by_zero E_no_ios E_no_return
|
||||
syn keyword pokeExceptionType E_io E_io_flags E_assert E_overflow
|
||||
|
||||
" Exception codes
|
||||
syn keyword pokeExceptionCode EC_generic EC_out_of_bounds
|
||||
syn keyword pokeExceptionCode EC_eof EC_elem EC_constraint
|
||||
syn keyword pokeExceptionCode EC_conv EC_map_bounds EC_map
|
||||
syn keyword pokeExceptionCode EC_div_by_zero EC_no_ios EC_no_return
|
||||
syn keyword pokeExceptionCode EC_io EC_io_flags EC_assert EC_overflow
|
||||
|
||||
" Poke builtin types
|
||||
syn keyword pokeBuiltinType string void int uint bit nibble
|
||||
syn keyword pokeBuiltinType byte char ushort short ulong long
|
||||
syn keyword pokeBuiltinType uint8 uint16 uint32 uint64
|
||||
syn keyword pokeBuiltinType off64 uoff64 offset
|
||||
syn keyword pokeBuiltinType Comparator POSIX_Time32 POSIX_Time64
|
||||
syn keyword pokeBuiltinType big little any
|
||||
|
||||
" Poke constants
|
||||
syn keyword pokeConstant ENDIAN_LITTLE ENDIAN_BIG
|
||||
syn keyword pokeConstant IOS_F_READ IOS_F_WRITE IOS_F_TRUNCATE IOS_F_CREATE
|
||||
syn keyword pokeConstant IOS_M_RDONLY IOS_M_WRONLY IOS_M_RDWR
|
||||
syn keyword pokeConstant load_path NULL OFFSET
|
||||
|
||||
" Poke std lib
|
||||
syn keyword pokeBuiltinFunction print printf catos stoca atoi ltos reverse
|
||||
syn keyword pokeBuiltinFunction ltrim rtrim strchr qsort crc32 alignto
|
||||
syn keyword pokeBuiltinFunction open close flush get_ios set_ios iosize
|
||||
syn keyword pokeBuiltinFunction rand get_endian set_endian strace exit
|
||||
syn keyword pokeBuiltinFunction getenv
|
||||
|
||||
" Formats
|
||||
|
||||
" Special chars
|
||||
syn match pokeSpecial "\\\([nt\\]\|\o\{1,3}\)" display contained
|
||||
|
||||
" Chars
|
||||
syn match pokeChar "'[^']*'" contains=pokeSpecial
|
||||
|
||||
" Attributes
|
||||
syn match pokeAttribute "\h\w*'\h\w"
|
||||
|
||||
" Strings
|
||||
syn region pokeString skip=+\\\\\|\\"+ start=+"+ end=+"+ contains=pokeSpecial
|
||||
|
||||
" Integer literals
|
||||
syn match pokeInteger "\<\d\+_*\d*\([LlHhBbNn]\=[Uu]\=\|[Uu]\=[LlHhBbNn]\=\)\>"
|
||||
syn match pokeInteger "\<0[Xx]\x\+_*\x*\([LlHhBbNn]\=[Uu]\=\|[Uu]\=[LlHhBbNn]\=\)\>"
|
||||
syn match pokeInteger "\<0[Oo]\o\+_*\o*\([LlHhBbNn]\=[Uu]\=\|[Uu]\=[LlHhBbNn]\=\)\>"
|
||||
syn match pokeInteger "\<0[Bb][01]\+_*[01]*\([LlHhBbNn]\=[Uu]\=\|[Uu]\=[LlHhBbNn]\=\)\>"
|
||||
|
||||
" Units
|
||||
syn keyword pokeBuiltinUnit b M B
|
||||
syn keyword pokeBuiltinUnit Kb KB Mb MB Gb GB
|
||||
syn keyword pokeBuiltinUnit Kib KiB Mib MiB Gib GiB
|
||||
|
||||
" Offsets
|
||||
syn match pokeOffset "#\h\w*" contains=pokeBuiltinUnit
|
||||
|
||||
" Comments
|
||||
syn keyword pokeCommentTodo TODO FIXME XXX TBD contained
|
||||
syn match pokeLineComment "\/\/.*" contains=pokeCommentTodo,@Spell extend
|
||||
syn region pokeComment start="/\*" end="\*/" contains=pokeCommentTodo,@Spell fold extend
|
||||
|
||||
" Allow folding of blocks
|
||||
syn region pokeBlock start="{" end="}" transparent fold
|
||||
|
||||
" Highlight groups
|
||||
hi def link pokeBuiltinFunction Function
|
||||
hi def link pokeBuiltinType Type
|
||||
hi def link pokeBuiltinUnit Keyword
|
||||
hi def link pokeChar Character
|
||||
hi def link pokeComment Comment
|
||||
hi def link pokeCommentTodo Todo
|
||||
hi def link pokeConditional Conditional
|
||||
hi def link pokeConstant Constant
|
||||
hi def link pokeException Exception
|
||||
hi def link pokeExceptionCode Constant
|
||||
hi def link pokeExceptionType Type
|
||||
hi def link pokeFunction Function
|
||||
hi def link pokeInteger Number
|
||||
hi def link pokeLineComment Comment
|
||||
hi def link pokeLoad Include
|
||||
hi def link pokeOffset StorageClass
|
||||
hi def link pokeOperator Operator
|
||||
hi def link pokeSpecial SpecialChar
|
||||
hi def link pokeStatement Statement
|
||||
hi def link pokeString String
|
||||
hi def link pokeStructure Structure
|
||||
hi def link pokeRepeat Repeat
|
||||
hi def link pokeVar Identifier
|
||||
|
||||
let b:current_syntax = 'poke'
|
||||
+7
-3
@@ -60,8 +60,8 @@ To built Vim on Ubuntu from scratch on a clean system using git:
|
||||
% sudo apt install libxt-dev
|
||||
% make reconfig
|
||||
|
||||
Add GUI support (ignore compiler warnings):
|
||||
% sudo apt install libgtk2.0-dev
|
||||
Add GUI support:
|
||||
% sudo apt install libgtk-3-dev
|
||||
% make reconfig
|
||||
|
||||
Add Python 3 support:
|
||||
@@ -134,8 +134,12 @@ These configure arguments can be used to select which GUI to use:
|
||||
--disable-motif-check
|
||||
--disable-athena-check
|
||||
|
||||
This configure argument can be used to disable the GUI, even when the necessary
|
||||
files are found:
|
||||
--disable-gui
|
||||
|
||||
--enable-gui defaults to "auto", so it will automatically look for a GUI (in
|
||||
the order of GTK, Motif, then Athena). If one is found, then is uses it and
|
||||
the order of GTK, Motif, then Athena). If one is found, then it is used and
|
||||
does not proceed to check any of the remaining ones. Otherwise, it moves on
|
||||
to the next one.
|
||||
|
||||
|
||||
Vendored
+29
@@ -14148,6 +14148,35 @@ $as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysinfo.uptime" >&5
|
||||
$as_echo_n "checking for sysinfo.uptime... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
#include <sys/types.h>
|
||||
#include <sys/sysinfo.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
struct sysinfo sinfo;
|
||||
long ut;
|
||||
|
||||
(void)sysinfo(&sinfo);
|
||||
ut = sinfo.uptime;
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_compile "$LINENO"; then :
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
$as_echo "yes" >&6; }; $as_echo "#define HAVE_SYSINFO_UPTIME 1" >>confdefs.h
|
||||
|
||||
else
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
$as_echo "no" >&6; }
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for sysconf" >&5
|
||||
$as_echo_n "checking for sysconf... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
|
||||
+16
-4
@@ -1337,7 +1337,7 @@ do_doautocmd(
|
||||
void
|
||||
ex_doautoall(exarg_T *eap)
|
||||
{
|
||||
int retval;
|
||||
int retval = OK;
|
||||
aco_save_T aco;
|
||||
buf_T *buf;
|
||||
bufref_T bufref;
|
||||
@@ -1354,7 +1354,8 @@ ex_doautoall(exarg_T *eap)
|
||||
*/
|
||||
FOR_ALL_BUFFERS(buf)
|
||||
{
|
||||
if (buf->b_ml.ml_mfp != NULL)
|
||||
// Only do loaded buffers and skip the current buffer, it's done last.
|
||||
if (buf->b_ml.ml_mfp != NULL && buf != curbuf)
|
||||
{
|
||||
// find a window for this buffer and save some values
|
||||
aucmd_prepbuf(&aco, buf);
|
||||
@@ -1364,22 +1365,31 @@ ex_doautoall(exarg_T *eap)
|
||||
retval = do_doautocmd(arg, FALSE, &did_aucmd);
|
||||
|
||||
if (call_do_modelines && did_aucmd)
|
||||
{
|
||||
// Execute the modeline settings, but don't set window-local
|
||||
// options if we are using the current window for another
|
||||
// buffer.
|
||||
do_modelines(curwin == aucmd_win ? OPT_NOWIN : 0);
|
||||
}
|
||||
|
||||
// restore the current window
|
||||
aucmd_restbuf(&aco);
|
||||
|
||||
// stop if there is some error or buffer was deleted
|
||||
if (retval == FAIL || !bufref_valid(&bufref))
|
||||
{
|
||||
retval = FAIL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Execute autocommands for the current buffer last.
|
||||
if (retval == OK)
|
||||
{
|
||||
do_doautocmd(arg, FALSE, &did_aucmd);
|
||||
if (call_do_modelines && did_aucmd)
|
||||
do_modelines(0);
|
||||
}
|
||||
|
||||
check_cursor(); // just in case lines got deleted
|
||||
}
|
||||
|
||||
@@ -2167,12 +2177,14 @@ apply_autocmds_group(
|
||||
while (au_pending_free_buf != NULL)
|
||||
{
|
||||
buf_T *b = au_pending_free_buf->b_next;
|
||||
|
||||
vim_free(au_pending_free_buf);
|
||||
au_pending_free_buf = b;
|
||||
}
|
||||
while (au_pending_free_win != NULL)
|
||||
{
|
||||
win_T *w = au_pending_free_win->w_next;
|
||||
|
||||
vim_free(au_pending_free_win);
|
||||
au_pending_free_win = w;
|
||||
}
|
||||
|
||||
@@ -213,6 +213,7 @@
|
||||
#undef HAVE_SYSCTL
|
||||
#undef HAVE_SYSINFO
|
||||
#undef HAVE_SYSINFO_MEM_UNIT
|
||||
#undef HAVE_SYSINFO_UPTIME
|
||||
#undef HAVE_TGETENT
|
||||
#undef HAVE_TOWLOWER
|
||||
#undef HAVE_TOWUPPER
|
||||
|
||||
@@ -4280,6 +4280,20 @@ AC_TRY_COMPILE(
|
||||
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSINFO_MEM_UNIT),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
dnl struct sysinfo may have the uptime field or not
|
||||
AC_MSG_CHECKING(for sysinfo.uptime)
|
||||
AC_TRY_COMPILE(
|
||||
[#include <sys/types.h>
|
||||
#include <sys/sysinfo.h>],
|
||||
[ struct sysinfo sinfo;
|
||||
long ut;
|
||||
|
||||
(void)sysinfo(&sinfo);
|
||||
ut = sinfo.uptime;
|
||||
],
|
||||
AC_MSG_RESULT(yes); AC_DEFINE(HAVE_SYSINFO_UPTIME),
|
||||
AC_MSG_RESULT(no))
|
||||
|
||||
dnl sysconf() may exist but not support what we want to use
|
||||
AC_MSG_CHECKING(for sysconf)
|
||||
AC_TRY_COMPILE(
|
||||
|
||||
+1
-1
@@ -1034,7 +1034,7 @@ win_line(
|
||||
p_extra_free = alloc(MAX_MCO * fdc + 1);
|
||||
if (p_extra_free != NULL)
|
||||
{
|
||||
n_extra = fill_foldcolumn(p_extra_free, wp,
|
||||
n_extra = (int)fill_foldcolumn(p_extra_free, wp,
|
||||
FALSE, lnum);
|
||||
p_extra_free[n_extra] = NUL;
|
||||
p_extra = p_extra_free;
|
||||
|
||||
@@ -373,3 +373,5 @@ EXTERN char e_argument_name_shadows_existing_variable_str[]
|
||||
INIT(= N_("E1167: Argument name shadows existing variable: %s"));
|
||||
EXTERN char e_argument_already_declared_in_script_str[]
|
||||
INIT(= N_("E1168: Argument already declared in the script: %s"));
|
||||
EXTERN char e_import_as_name_not_supported_here[]
|
||||
INIT(= N_("E1169: 'import * as {name}' not supported here"));
|
||||
|
||||
+60
-2
@@ -1370,7 +1370,7 @@ set_var_lval(
|
||||
// handle +=, -=, *=, /=, %= and .=
|
||||
di = NULL;
|
||||
if (eval_variable(lp->ll_name, (int)STRLEN(lp->ll_name),
|
||||
&tv, &di, TRUE, FALSE) == OK)
|
||||
&tv, &di, EVAL_VAR_VERBOSE) == OK)
|
||||
{
|
||||
if ((di == NULL
|
||||
|| (!var_check_ro(di->di_flags, lp->ll_name, FALSE)
|
||||
@@ -3500,7 +3500,8 @@ eval7(
|
||||
ret = OK;
|
||||
}
|
||||
else
|
||||
ret = eval_variable(s, len, rettv, NULL, TRUE, FALSE);
|
||||
ret = eval_variable(s, len, rettv, NULL,
|
||||
EVAL_VAR_VERBOSE + EVAL_VAR_IMPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5760,6 +5761,63 @@ handle_subscript(
|
||||
check_white = FALSE;
|
||||
}
|
||||
|
||||
if (rettv->v_type == VAR_ANY)
|
||||
{
|
||||
char_u *exp_name;
|
||||
int cc;
|
||||
int idx;
|
||||
ufunc_T *ufunc;
|
||||
type_T *type;
|
||||
|
||||
// Found script from "import * as {name}", script item name must
|
||||
// follow.
|
||||
if (**arg != '.')
|
||||
{
|
||||
if (verbose)
|
||||
semsg(_(e_expected_str_but_got_str), "'.'", *arg);
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
++*arg;
|
||||
if (IS_WHITE_OR_NUL(**arg))
|
||||
{
|
||||
if (verbose)
|
||||
emsg(_(e_no_white_space_allowed_after_dot));
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
|
||||
// isolate the name
|
||||
exp_name = *arg;
|
||||
while (eval_isnamec(**arg))
|
||||
++*arg;
|
||||
cc = **arg;
|
||||
**arg = NUL;
|
||||
|
||||
idx = find_exported(rettv->vval.v_number, exp_name, &ufunc, &type,
|
||||
evalarg->eval_cctx, verbose);
|
||||
**arg = cc;
|
||||
*arg = skipwhite(*arg);
|
||||
|
||||
if (idx < 0 && ufunc == NULL)
|
||||
{
|
||||
ret = FAIL;
|
||||
break;
|
||||
}
|
||||
if (idx >= 0)
|
||||
{
|
||||
scriptitem_T *si = SCRIPT_ITEM(rettv->vval.v_number);
|
||||
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
|
||||
|
||||
copy_tv(sv->sv_tv, rettv);
|
||||
}
|
||||
else
|
||||
{
|
||||
rettv->v_type = VAR_FUNC;
|
||||
rettv->vval.v_string = vim_strsave(ufunc->uf_name);
|
||||
}
|
||||
}
|
||||
|
||||
if ((**arg == '(' && (!evaluate || rettv->v_type == VAR_FUNC
|
||||
|| rettv->v_type == VAR_PARTIAL))
|
||||
&& (!check_white || !VIM_ISWHITE(*(*arg - 1))))
|
||||
|
||||
+53
-16
@@ -223,6 +223,7 @@ static void f_str2float(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_str2list(typval_T *argvars, typval_T *rettv);
|
||||
static void f_str2nr(typval_T *argvars, typval_T *rettv);
|
||||
static void f_strcharlen(typval_T *argvars, typval_T *rettv);
|
||||
static void f_strchars(typval_T *argvars, typval_T *rettv);
|
||||
static void f_strgetchar(typval_T *argvars, typval_T *rettv);
|
||||
static void f_stridx(typval_T *argvars, typval_T *rettv);
|
||||
@@ -1021,7 +1022,7 @@ static funcentry_T global_functions[] =
|
||||
{"getcwd", 0, 2, FEARG_1, NULL,
|
||||
ret_string, f_getcwd},
|
||||
{"getenv", 1, 1, FEARG_1, NULL,
|
||||
ret_string, f_getenv},
|
||||
ret_any, f_getenv},
|
||||
{"getfontname", 0, 1, 0, NULL,
|
||||
ret_string, f_getfontname},
|
||||
{"getfperm", 1, 1, FEARG_1, NULL,
|
||||
@@ -1572,7 +1573,9 @@ static funcentry_T global_functions[] =
|
||||
ret_list_number, f_str2list},
|
||||
{"str2nr", 1, 3, FEARG_1, arg3_string_nr_bool,
|
||||
ret_number, f_str2nr},
|
||||
{"strcharpart", 2, 3, FEARG_1, NULL,
|
||||
{"strcharlen", 1, 1, FEARG_1, NULL,
|
||||
ret_number, f_strcharlen},
|
||||
{"strcharpart", 2, 4, FEARG_1, NULL,
|
||||
ret_string, f_strcharpart},
|
||||
{"strchars", 1, 2, FEARG_1, NULL,
|
||||
ret_number, f_strchars},
|
||||
@@ -9271,31 +9274,45 @@ f_strlen(typval_T *argvars, typval_T *rettv)
|
||||
tv_get_string(&argvars[0])));
|
||||
}
|
||||
|
||||
static void
|
||||
strchar_common(typval_T *argvars, typval_T *rettv, int skipcc)
|
||||
{
|
||||
char_u *s = tv_get_string(&argvars[0]);
|
||||
varnumber_T len = 0;
|
||||
int (*func_mb_ptr2char_adv)(char_u **pp);
|
||||
|
||||
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
|
||||
while (*s != NUL)
|
||||
{
|
||||
func_mb_ptr2char_adv(&s);
|
||||
++len;
|
||||
}
|
||||
rettv->vval.v_number = len;
|
||||
}
|
||||
|
||||
/*
|
||||
* "strcharlen()" function
|
||||
*/
|
||||
static void
|
||||
f_strcharlen(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
strchar_common(argvars, rettv, TRUE);
|
||||
}
|
||||
|
||||
/*
|
||||
* "strchars()" function
|
||||
*/
|
||||
static void
|
||||
f_strchars(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *s = tv_get_string(&argvars[0]);
|
||||
varnumber_T skipcc = FALSE;
|
||||
varnumber_T len = 0;
|
||||
int (*func_mb_ptr2char_adv)(char_u **pp);
|
||||
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
skipcc = tv_get_bool(&argvars[1]);
|
||||
if (skipcc < 0 || skipcc > 1)
|
||||
semsg(_(e_using_number_as_bool_nr), skipcc);
|
||||
else
|
||||
{
|
||||
func_mb_ptr2char_adv = skipcc ? mb_ptr2char_adv : mb_cptr2char_adv;
|
||||
while (*s != NUL)
|
||||
{
|
||||
func_mb_ptr2char_adv(&s);
|
||||
++len;
|
||||
}
|
||||
rettv->vval.v_number = len;
|
||||
}
|
||||
strchar_common(argvars, rettv, skipcc);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -9334,6 +9351,7 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
|
||||
int nchar;
|
||||
int nbyte = 0;
|
||||
int charlen;
|
||||
int skipcc = FALSE;
|
||||
int len = 0;
|
||||
int slen;
|
||||
int error = FALSE;
|
||||
@@ -9344,10 +9362,24 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
|
||||
nchar = (int)tv_get_number_chk(&argvars[1], &error);
|
||||
if (!error)
|
||||
{
|
||||
if (argvars[2].v_type != VAR_UNKNOWN
|
||||
&& argvars[3].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
skipcc = tv_get_bool(&argvars[3]);
|
||||
if (skipcc < 0 || skipcc > 1)
|
||||
{
|
||||
semsg(_(e_using_number_as_bool_nr), skipcc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (nchar > 0)
|
||||
while (nchar > 0 && nbyte < slen)
|
||||
{
|
||||
nbyte += MB_CPTR2LEN(p + nbyte);
|
||||
if (skipcc)
|
||||
nbyte += mb_ptr2len(p + nbyte);
|
||||
else
|
||||
nbyte += MB_CPTR2LEN(p + nbyte);
|
||||
--nchar;
|
||||
}
|
||||
else
|
||||
@@ -9362,7 +9394,12 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
|
||||
if (off < 0)
|
||||
len += 1;
|
||||
else
|
||||
len += MB_CPTR2LEN(p + off);
|
||||
{
|
||||
if (skipcc)
|
||||
len += mb_ptr2len(p + off);
|
||||
else
|
||||
len += MB_CPTR2LEN(p + off);
|
||||
}
|
||||
--charlen;
|
||||
}
|
||||
}
|
||||
|
||||
+50
-23
@@ -321,7 +321,8 @@ garbage_collect_scriptvars(int copyID)
|
||||
{
|
||||
svar_T *sv = ((svar_T *)si->sn_var_vals.ga_data) + idx;
|
||||
|
||||
abort = abort || set_ref_in_item(sv->sv_tv, copyID, NULL, NULL);
|
||||
if (sv->sv_name != NULL)
|
||||
abort = abort || set_ref_in_item(sv->sv_tv, copyID, NULL, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1220,7 +1221,8 @@ list_arg_vars(exarg_T *eap, char_u *arg, int *first)
|
||||
arg = skipwhite(arg);
|
||||
if (tofree != NULL)
|
||||
name = tofree;
|
||||
if (eval_variable(name, len, &tv, NULL, TRUE, FALSE) == FAIL)
|
||||
if (eval_variable(name, len, &tv, NULL,
|
||||
EVAL_VAR_VERBOSE) == FAIL)
|
||||
error = TRUE;
|
||||
else
|
||||
{
|
||||
@@ -2540,6 +2542,8 @@ set_cmdarg(exarg_T *eap, char_u *oldarg)
|
||||
|
||||
/*
|
||||
* Get the value of internal variable "name".
|
||||
* If "flags" has EVAL_VAR_IMPORT may return a VAR_ANY with v_number set to the
|
||||
* imported script ID.
|
||||
* Return OK or FAIL. If OK is returned "rettv" must be cleared.
|
||||
*/
|
||||
int
|
||||
@@ -2548,12 +2552,11 @@ eval_variable(
|
||||
int len, // length of "name"
|
||||
typval_T *rettv, // NULL when only checking existence
|
||||
dictitem_T **dip, // non-NULL when typval's dict item is needed
|
||||
int verbose, // may give error message
|
||||
int no_autoload) // do not use script autoloading
|
||||
int flags) // EVAL_VAR_ flags
|
||||
{
|
||||
int ret = OK;
|
||||
typval_T *tv = NULL;
|
||||
int foundFunc = FALSE;
|
||||
int found = FALSE;
|
||||
dictitem_T *v;
|
||||
int cc;
|
||||
|
||||
@@ -2562,7 +2565,7 @@ eval_variable(
|
||||
name[len] = NUL;
|
||||
|
||||
// Check for user-defined variables.
|
||||
v = find_var(name, NULL, no_autoload);
|
||||
v = find_var(name, NULL, flags & EVAL_VAR_NOAUTOLOAD);
|
||||
if (v != NULL)
|
||||
{
|
||||
tv = &v->di_tv;
|
||||
@@ -2582,7 +2585,7 @@ eval_variable(
|
||||
{
|
||||
if (import->imp_funcname != NULL)
|
||||
{
|
||||
foundFunc = TRUE;
|
||||
found = TRUE;
|
||||
if (rettv != NULL)
|
||||
{
|
||||
rettv->v_type = VAR_FUNC;
|
||||
@@ -2591,8 +2594,21 @@ eval_variable(
|
||||
}
|
||||
else if (import->imp_flags & IMP_FLAGS_STAR)
|
||||
{
|
||||
emsg("Sorry, 'import * as X' not implemented yet");
|
||||
ret = FAIL;
|
||||
if ((flags & EVAL_VAR_IMPORT) == 0)
|
||||
{
|
||||
if (flags & EVAL_VAR_VERBOSE)
|
||||
emsg(_(e_import_as_name_not_supported_here));
|
||||
ret = FAIL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rettv != NULL)
|
||||
{
|
||||
rettv->v_type = VAR_ANY;
|
||||
rettv->vval.v_number = import->imp_sid;
|
||||
}
|
||||
found = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2608,7 +2624,7 @@ eval_variable(
|
||||
|
||||
if (ufunc != NULL)
|
||||
{
|
||||
foundFunc = TRUE;
|
||||
found = TRUE;
|
||||
if (rettv != NULL)
|
||||
{
|
||||
rettv->v_type = VAR_FUNC;
|
||||
@@ -2618,11 +2634,11 @@ eval_variable(
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundFunc)
|
||||
if (!found)
|
||||
{
|
||||
if (tv == NULL)
|
||||
{
|
||||
if (rettv != NULL && verbose)
|
||||
if (rettv != NULL && (flags & EVAL_VAR_VERBOSE))
|
||||
semsg(_(e_undefined_variable_str), name);
|
||||
ret = FAIL;
|
||||
}
|
||||
@@ -2791,12 +2807,15 @@ get_script_local_ht(void)
|
||||
|
||||
/*
|
||||
* Look for "name[len]" in script-local variables and functions.
|
||||
* When "cmd" is TRUE it must look like a command, a function must be followed
|
||||
* by "(" or "->".
|
||||
* Return OK when found, FAIL when not found.
|
||||
*/
|
||||
int
|
||||
lookup_scriptitem(
|
||||
char_u *name,
|
||||
size_t len,
|
||||
int cmd,
|
||||
cctx_T *dummy UNUSED)
|
||||
{
|
||||
hashtab_T *ht = get_script_local_ht();
|
||||
@@ -2831,19 +2850,26 @@ lookup_scriptitem(
|
||||
if (p != buffer)
|
||||
vim_free(p);
|
||||
|
||||
// Find a function, so that a following "->" works.
|
||||
// When used as a command require "(" or "->" to follow, "Cmd" is a user
|
||||
// command while "Cmd()" is a function call.
|
||||
if (res != OK)
|
||||
{
|
||||
// Find a function, so that a following "->" works. Skip "g:" before a
|
||||
// function name.
|
||||
// Do not check for an internal function, since it might also be a
|
||||
// valid command, such as ":split" versuse "split()".
|
||||
if (name[0] == 'g' && name[1] == ':')
|
||||
p = skipwhite(name + len);
|
||||
|
||||
if (!cmd || name[len] == '(' || (p[0] == '-' && p[1] == '>'))
|
||||
{
|
||||
is_global = TRUE;
|
||||
fname = name + 2;
|
||||
// Do not check for an internal function, since it might also be a
|
||||
// valid command, such as ":split" versus "split()".
|
||||
// Skip "g:" before a function name.
|
||||
if (name[0] == 'g' && name[1] == ':')
|
||||
{
|
||||
is_global = TRUE;
|
||||
fname = name + 2;
|
||||
}
|
||||
if (find_func(fname, is_global, NULL) != NULL)
|
||||
res = OK;
|
||||
}
|
||||
if (find_func(fname, is_global, NULL) != NULL)
|
||||
res = OK;
|
||||
}
|
||||
|
||||
return res;
|
||||
@@ -3274,7 +3300,7 @@ set_var_const(
|
||||
{
|
||||
// Item not found, check if a function already exists.
|
||||
if (is_script_local && (flags & (ASSIGN_NO_DECL | ASSIGN_DECL)) == 0
|
||||
&& lookup_scriptitem(name, STRLEN(name), NULL) == OK)
|
||||
&& lookup_scriptitem(name, STRLEN(name), FALSE, NULL) == OK)
|
||||
{
|
||||
semsg(_(e_redefining_script_item_str), name);
|
||||
goto failed;
|
||||
@@ -3696,7 +3722,8 @@ var_exists(char_u *var)
|
||||
{
|
||||
if (tofree != NULL)
|
||||
name = tofree;
|
||||
n = (eval_variable(name, len, &tv, NULL, FALSE, TRUE) == OK);
|
||||
n = (eval_variable(name, len, &tv, NULL,
|
||||
EVAL_VAR_NOAUTOLOAD + EVAL_VAR_IMPORT) == OK);
|
||||
if (n)
|
||||
{
|
||||
// handle d.key, l[idx], f(expr)
|
||||
|
||||
+7
-3
@@ -3317,7 +3317,7 @@ skip_option_env_lead(char_u *start)
|
||||
find_ex_command(
|
||||
exarg_T *eap,
|
||||
int *full UNUSED,
|
||||
int (*lookup)(char_u *, size_t, cctx_T *) UNUSED,
|
||||
int (*lookup)(char_u *, size_t, int cmd, cctx_T *) UNUSED,
|
||||
cctx_T *cctx UNUSED)
|
||||
{
|
||||
int len;
|
||||
@@ -3436,7 +3436,7 @@ find_ex_command(
|
||||
|| *eap->cmd == '&'
|
||||
|| *eap->cmd == '$'
|
||||
|| *eap->cmd == '@'
|
||||
|| lookup(eap->cmd, p - eap->cmd, cctx) == OK)
|
||||
|| lookup(eap->cmd, p - eap->cmd, TRUE, cctx) == OK)
|
||||
{
|
||||
eap->cmdidx = CMD_var;
|
||||
return eap->cmd;
|
||||
@@ -3455,7 +3455,7 @@ find_ex_command(
|
||||
// If it is an ID it might be a variable with an operator on the next
|
||||
// line, if the variable exists it can't be an Ex command.
|
||||
if (p > eap->cmd && ends_excmd(*skipwhite(p))
|
||||
&& (lookup(eap->cmd, p - eap->cmd, cctx) == OK
|
||||
&& (lookup(eap->cmd, p - eap->cmd, TRUE, cctx) == OK
|
||||
|| (ASCII_ISALPHA(eap->cmd[0]) && eap->cmd[1] == ':')))
|
||||
{
|
||||
eap->cmdidx = CMD_eval;
|
||||
@@ -6615,6 +6615,10 @@ ex_open(exarg_T *eap)
|
||||
regmatch_T regmatch;
|
||||
char_u *p;
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (not_in_vim9(eap) == FAIL)
|
||||
return;
|
||||
#endif
|
||||
curwin->w_cursor.lnum = eap->line2;
|
||||
beginline(BL_SOL | BL_FIX);
|
||||
if (*eap->arg == '/')
|
||||
|
||||
@@ -1865,6 +1865,7 @@ EXTERN int nfa_fail_for_testing INIT(= FALSE);
|
||||
EXTERN int no_query_mouse_for_testing INIT(= FALSE);
|
||||
EXTERN int ui_delay_for_testing INIT(= 0);
|
||||
EXTERN int reset_term_props_on_termresponse INIT(= FALSE);
|
||||
EXTERN long override_sysinfo_uptime INIT(= -1);
|
||||
|
||||
EXTERN int in_free_unref_items INIT(= FALSE);
|
||||
#endif
|
||||
|
||||
@@ -568,6 +568,11 @@ luaV_pushtypval(lua_State *L, typval_T *tv)
|
||||
case VAR_FUNC:
|
||||
luaV_pushfuncref(L, tv->vval.v_string);
|
||||
break;
|
||||
case VAR_PARTIAL:
|
||||
// TODO: handle partial arguments
|
||||
luaV_pushfuncref(L, partial_name(tv->vval.v_partial));
|
||||
break;
|
||||
|
||||
case VAR_BLOB:
|
||||
luaV_pushblob(L, tv->vval.v_blob);
|
||||
break;
|
||||
|
||||
@@ -3627,8 +3627,11 @@ usage(void)
|
||||
#endif // FEAT_GUI_X11
|
||||
#ifdef FEAT_GUI_GTK
|
||||
mch_msg(_("\nArguments recognised by gvim (GTK+ version):\n"));
|
||||
main_msg(_("-background <color>\tUse <color> for the background (also: -bg)"));
|
||||
main_msg(_("-foreground <color>\tUse <color> for normal text (also: -fg)"));
|
||||
main_msg(_("-font <font>\t\tUse <font> for normal text (also: -fn)"));
|
||||
main_msg(_("-geometry <geom>\tUse <geom> for initial geometry (also: -geom)"));
|
||||
main_msg(_("-iconic\t\tStart Vim iconified"));
|
||||
main_msg(_("-reverse\t\tUse reverse video (also: -rv)"));
|
||||
main_msg(_("-display <display>\tRun Vim on <display> (also: --display)"));
|
||||
main_msg(_("--role <role>\tSet a unique role to identify the main window"));
|
||||
|
||||
+32
-7
@@ -1080,6 +1080,35 @@ add_b0_fenc(
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(HAVE_SYS_SYSINFO_H) && defined(HAVE_SYSINFO_UPTIME)
|
||||
# include <sys/sysinfo.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Return TRUE if the process with number "b0p->b0_pid" is still running.
|
||||
* "swap_fname" is the name of the swap file, if it's from before a reboot then
|
||||
* the result is FALSE;
|
||||
*/
|
||||
static int
|
||||
swapfile_process_running(ZERO_BL *b0p, char_u *swap_fname UNUSED)
|
||||
{
|
||||
#ifdef HAVE_SYSINFO_UPTIME
|
||||
stat_T st;
|
||||
struct sysinfo sinfo;
|
||||
|
||||
// If the system rebooted after when the swap file was written then the
|
||||
// process can't be running now.
|
||||
if (mch_stat((char *)swap_fname, &st) != -1
|
||||
&& sysinfo(&sinfo) == 0
|
||||
&& st.st_mtime < time(NULL) - (
|
||||
# ifdef FEAT_EVAL
|
||||
override_sysinfo_uptime >= 0 ? override_sysinfo_uptime :
|
||||
# endif
|
||||
sinfo.uptime))
|
||||
return FALSE;
|
||||
#endif
|
||||
return mch_process_running(char_to_long(b0p->b0_pid));
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to recover curbuf from the .swp file.
|
||||
@@ -1692,7 +1721,7 @@ ml_recover(int checkext)
|
||||
msg(_("Recovery completed. Buffer contents equals file contents."));
|
||||
msg_puts(_("\nYou may want to delete the .swp file now."));
|
||||
#if defined(UNIX) || defined(MSWIN)
|
||||
if (mch_process_running(char_to_long(b0p->b0_pid)))
|
||||
if (swapfile_process_running(b0p, fname_used))
|
||||
{
|
||||
// Warn there could be an active Vim on the same file, the user may
|
||||
// want to kill it.
|
||||
@@ -2170,7 +2199,7 @@ swapfile_info(char_u *fname)
|
||||
msg_puts(_("\n process ID: "));
|
||||
msg_outnum(char_to_long(b0.b0_pid));
|
||||
#if defined(UNIX) || defined(MSWIN)
|
||||
if (mch_process_running(char_to_long(b0.b0_pid)))
|
||||
if (swapfile_process_running(&b0, fname))
|
||||
{
|
||||
msg_puts(_(" (STILL RUNNING)"));
|
||||
# ifdef HAVE_PROCESS_STILL_RUNNING
|
||||
@@ -2213,9 +2242,6 @@ swapfile_unchanged(char_u *fname)
|
||||
int fd;
|
||||
struct block0 b0;
|
||||
int ret = TRUE;
|
||||
#if defined(UNIX) || defined(MSWIN)
|
||||
long pid;
|
||||
#endif
|
||||
|
||||
// must be able to stat the swap file
|
||||
if (mch_stat((char *)fname, &st) == -1)
|
||||
@@ -2258,8 +2284,7 @@ swapfile_unchanged(char_u *fname)
|
||||
}
|
||||
|
||||
// process must be known and not be running
|
||||
pid = char_to_long(b0.b0_pid);
|
||||
if (pid == 0L || mch_process_running(pid))
|
||||
if (char_to_long(b0.b0_pid) == 0L || swapfile_process_running(&b0, fname))
|
||||
ret = FALSE;
|
||||
#endif
|
||||
|
||||
|
||||
+7
-4
@@ -3247,7 +3247,9 @@ set_bool_option(
|
||||
if (curwin->w_curswant != MAXCOL
|
||||
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
check_redraw(options[opt_idx].flags);
|
||||
|
||||
if ((opt_flags & OPT_NO_REDRAW) == 0)
|
||||
check_redraw(options[opt_idx].flags);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -3263,8 +3265,8 @@ set_num_option(
|
||||
long value, // new value
|
||||
char *errbuf, // buffer for error messages
|
||||
size_t errbuflen, // length of "errbuf"
|
||||
int opt_flags) // OPT_LOCAL, OPT_GLOBAL and
|
||||
// OPT_MODELINE
|
||||
int opt_flags) // OPT_LOCAL, OPT_GLOBAL,
|
||||
// OPT_MODELINE, etc.
|
||||
{
|
||||
char *errmsg = NULL;
|
||||
long old_value = *(long *)varp;
|
||||
@@ -3842,7 +3844,8 @@ set_num_option(
|
||||
if (curwin->w_curswant != MAXCOL
|
||||
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
check_redraw(options[opt_idx].flags);
|
||||
if ((opt_flags & OPT_NO_REDRAW) == 0)
|
||||
check_redraw(options[opt_idx].flags);
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
+6
-3
@@ -2480,11 +2480,14 @@ ambw_end:
|
||||
&& (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0)
|
||||
curwin->w_set_curswant = TRUE;
|
||||
|
||||
if ((opt_flags & OPT_NO_REDRAW) == 0)
|
||||
{
|
||||
#ifdef FEAT_GUI
|
||||
// check redraw when it's not a GUI option or the GUI is active.
|
||||
if (!redraw_gui_only || gui.in_use)
|
||||
// check redraw when it's not a GUI option or the GUI is active.
|
||||
if (!redraw_gui_only || gui.in_use)
|
||||
#endif
|
||||
check_redraw(get_option_flags(opt_idx));
|
||||
check_redraw(get_option_flags(opt_idx));
|
||||
}
|
||||
|
||||
#if defined(FEAT_VTP) && defined(FEAT_TERMGUICOLORS)
|
||||
if (did_swaptcap)
|
||||
|
||||
@@ -56,12 +56,12 @@ 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 eval_variable(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 flags);
|
||||
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);
|
||||
hashtab_T *get_script_local_ht(void);
|
||||
int lookup_scriptitem(char_u *name, size_t len, cctx_T *dummy);
|
||||
int lookup_scriptitem(char_u *name, size_t len, int cmd, cctx_T *dummy);
|
||||
hashtab_T *find_var_ht(char_u *name, char_u **varname);
|
||||
char_u *get_var_value(char_u *name);
|
||||
void new_script_vars(scid_T id);
|
||||
|
||||
@@ -13,7 +13,7 @@ void undo_cmdmod(cmdmod_T *cmod);
|
||||
int parse_cmd_address(exarg_T *eap, char **errormsg, int silent);
|
||||
int checkforcmd(char_u **pp, char *cmd, int len);
|
||||
char_u *skip_option_env_lead(char_u *start);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, cctx_T *), cctx_T *cctx);
|
||||
char_u *find_ex_command(exarg_T *eap, int *full, int (*lookup)(char_u *, size_t, int cmd, cctx_T *), cctx_T *cctx);
|
||||
int modifier_len(char_u *cmd);
|
||||
int cmd_exists(char_u *name);
|
||||
void f_fullcommand(typval_T *argvars, typval_T *rettv);
|
||||
|
||||
@@ -7,7 +7,7 @@ void ex_export(exarg_T *eap);
|
||||
void free_imports_and_script_vars(int sid);
|
||||
void mark_imports_for_reload(int sid);
|
||||
void ex_import(exarg_T *eap);
|
||||
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T *cctx);
|
||||
int find_exported(int sid, char_u *name, ufunc_T **ufunc, type_T **type, cctx_T *cctx, int verbose);
|
||||
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);
|
||||
void update_vim9_script_var(int create, dictitem_T *di, int flags, typval_T *tv, type_T **type);
|
||||
|
||||
+28
-1
@@ -1459,7 +1459,34 @@ almosttheend:
|
||||
si = SCRIPT_ITEM(current_sctx.sc_sid);
|
||||
if (si->sn_save_cpo != NULL)
|
||||
{
|
||||
set_option_value((char_u *)"cpo", 0L, si->sn_save_cpo, 0);
|
||||
if (STRCMP(p_cpo, CPO_VIM) != 0)
|
||||
{
|
||||
char_u *f;
|
||||
char_u *t;
|
||||
|
||||
// 'cpo' was changed in the script. Apply the same change to the
|
||||
// saved value, if possible.
|
||||
for (f = (char_u *)CPO_VIM; *f != NUL; ++f)
|
||||
if (vim_strchr(p_cpo, *f) == NULL
|
||||
&& (t = vim_strchr(si->sn_save_cpo, *f)) != NULL)
|
||||
// flag was removed, also remove it from the saved 'cpo'
|
||||
mch_memmove(t, t + 1, STRLEN(t));
|
||||
for (f = p_cpo; *f != NUL; ++f)
|
||||
if (vim_strchr((char_u *)CPO_VIM, *f) == NULL
|
||||
&& vim_strchr(si->sn_save_cpo, *f) == NULL)
|
||||
{
|
||||
// flag was added, also add it to the saved 'cpo'
|
||||
t = alloc(STRLEN(si->sn_save_cpo) + 2);
|
||||
if (t != NULL)
|
||||
{
|
||||
*t = *f;
|
||||
STRCPY(t + 1, si->sn_save_cpo);
|
||||
vim_free(si->sn_save_cpo);
|
||||
si->sn_save_cpo = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
set_option_value((char_u *)"cpo", 0L, si->sn_save_cpo, OPT_NO_REDRAW);
|
||||
VIM_CLEAR(si->sn_save_cpo);
|
||||
}
|
||||
|
||||
|
||||
+2
-1
@@ -401,11 +401,12 @@ put_view(
|
||||
{
|
||||
buf_T *alt = buflist_findnr(wp->w_alt_fnum);
|
||||
|
||||
// Set the alternate file.
|
||||
// Set the alternate file if the buffer is listed.
|
||||
if ((flagp == &ssop_flags)
|
||||
&& alt != NULL
|
||||
&& alt->b_fname != NULL
|
||||
&& *alt->b_fname != NUL
|
||||
&& alt->b_p_bl
|
||||
&& (fputs("balt ", fd) < 0
|
||||
|| ses_fname(fd, alt, flagp, TRUE) == FAIL))
|
||||
return FAIL;
|
||||
|
||||
@@ -461,6 +461,7 @@ NEW_TESTS_RES = \
|
||||
test_quickfix.res \
|
||||
test_quotestar.res \
|
||||
test_random.res \
|
||||
test_recover.res \
|
||||
test_regex_char_classes.res \
|
||||
test_registers.res \
|
||||
test_rename.res \
|
||||
|
||||
+34
-1
@@ -84,8 +84,16 @@ func CheckUnix()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Command to check for running on Linix
|
||||
command CheckLinux call CheckLinux()
|
||||
func CheckLinux()
|
||||
if !has('linux')
|
||||
throw 'Skipped: only works on Linux'
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Command to check for not running on a BSD system.
|
||||
" TODO: using this checks should not be needed
|
||||
" TODO: using this check should not be needed
|
||||
command CheckNotBSD call CheckNotBSD()
|
||||
func CheckNotBSD()
|
||||
if has('bsd')
|
||||
@@ -191,4 +199,29 @@ func CheckNotAsan()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" Command to check for satisfying any of the conditions.
|
||||
" e.g. CheckAnyOf Feature:bsd Feature:sun Linux
|
||||
command -nargs=+ CheckAnyOf call CheckAnyOf(<f-args>)
|
||||
func CheckAnyOf(...)
|
||||
let excp = []
|
||||
for arg in a:000
|
||||
try
|
||||
exe 'Check' .. substitute(arg, ':', ' ', '')
|
||||
return
|
||||
catch /^Skipped:/
|
||||
let excp += [substitute(v:exception, '^Skipped:\s*', '', '')]
|
||||
endtry
|
||||
endfor
|
||||
throw 'Skipped: ' .. join(excp, '; ')
|
||||
endfunc
|
||||
|
||||
" Command to check for satisfying all of the conditions.
|
||||
" e.g. CheckAllOf Unix Gui Option:ballooneval
|
||||
command -nargs=+ CheckAllOf call CheckAllOf(<f-args>)
|
||||
func CheckAllOf(...)
|
||||
for arg in a:000
|
||||
exe 'Check' .. substitute(arg, ':', ' ', '')
|
||||
endfor
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|s+0&#ffffff0|o+0&#e0e0e08|m|e| |t|e|x|t| | +0&#ffffff0@64
|
||||
|~+0#4040ff13&| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|~| @73
|
||||
|:+0#0000000&|'|<|,|'|>> @68
|
||||
@@ -196,7 +196,12 @@ func RunTheTest(test)
|
||||
if a:test =~ 'Test_nocatch_'
|
||||
" Function handles errors itself. This avoids skipping commands after the
|
||||
" error.
|
||||
let g:skipped_reason = ''
|
||||
exe 'call ' . a:test
|
||||
if g:skipped_reason != ''
|
||||
call add(s:messages, ' Skipped')
|
||||
call add(s:skipped, 'SKIPPED ' . a:test . ': ' . g:skipped_reason)
|
||||
endif
|
||||
else
|
||||
try
|
||||
au VimLeavePre * call EarlyExit(g:testfunc)
|
||||
|
||||
@@ -21,7 +21,6 @@ source test_jumps.vim
|
||||
source test_lispwords.vim
|
||||
source test_move.vim
|
||||
source test_put.vim
|
||||
source test_recover.vim
|
||||
source test_reltime.vim
|
||||
source test_scroll_opt.vim
|
||||
source test_searchpos.vim
|
||||
|
||||
@@ -2670,6 +2670,9 @@ func Test_autocmd_window()
|
||||
%bw!
|
||||
edit one.txt
|
||||
tabnew two.txt
|
||||
vnew three.txt
|
||||
tabnew four.txt
|
||||
tabprevious
|
||||
let g:blist = []
|
||||
augroup aucmd_win_test1
|
||||
au!
|
||||
@@ -2678,7 +2681,12 @@ func Test_autocmd_window()
|
||||
augroup END
|
||||
|
||||
doautoall BufEnter
|
||||
call assert_equal([['one.txt', 'autocmd'], ['two.txt', '']], g:blist)
|
||||
call assert_equal([
|
||||
\ ['one.txt', 'autocmd'],
|
||||
\ ['two.txt', ''],
|
||||
\ ['four.txt', 'autocmd'],
|
||||
\ ['three.txt', ''],
|
||||
\ ], g:blist)
|
||||
|
||||
augroup aucmd_win_test1
|
||||
au!
|
||||
|
||||
@@ -31,6 +31,14 @@ func Test_strcharpart()
|
||||
call assert_equal('a', strcharpart('àxb', 0, 1))
|
||||
call assert_equal('̀', strcharpart('àxb', 1, 1))
|
||||
call assert_equal('x', strcharpart('àxb', 2, 1))
|
||||
|
||||
|
||||
call assert_equal('a', strcharpart('àxb', 0, 1, 0))
|
||||
call assert_equal('à', strcharpart('àxb', 0, 1, 1))
|
||||
call assert_equal('x', strcharpart('àxb', 1, 1, 1))
|
||||
|
||||
call assert_fails("let v = strcharpart('abc', 0, 0, [])", 'E745:')
|
||||
call assert_fails("let v = strcharpart('abc', 0, 0, 2)", 'E1023:')
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -33,6 +33,15 @@ func Test_fileformat_autocommand()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_fileformat_nomodifiable()
|
||||
new
|
||||
setlocal nomodifiable
|
||||
|
||||
call assert_fails('set fileformat=latin1', 'E21:')
|
||||
|
||||
bw
|
||||
endfunc
|
||||
|
||||
" Convert the contents of a file into a literal string
|
||||
func s:file2str(fname)
|
||||
let b = readfile(a:fname, 'B')
|
||||
|
||||
@@ -374,6 +374,7 @@ let s:filename_checks = {
|
||||
\ 'po': ['file.po', 'file.pot'],
|
||||
\ 'pod': ['file.pod'],
|
||||
\ 'pod6': ['file.pod6'],
|
||||
\ 'poke': ['file.pk'],
|
||||
\ 'postscr': ['file.ps', 'file.pfa', 'file.afm', 'file.eps', 'file.epsf', 'file.epsi', 'file.ai'],
|
||||
\ 'pov': ['file.pov'],
|
||||
\ 'povini': ['.povrayrc'],
|
||||
|
||||
@@ -1430,6 +1430,14 @@ func Test_input_func()
|
||||
delfunc Tcomplete
|
||||
call assert_equal('item1 item2 item3', c)
|
||||
|
||||
" Test for using special characters as default input
|
||||
call feedkeys(":let c = input('name? ', \"x\<BS>y\")\<CR>\<CR>", 'xt')
|
||||
call assert_equal('y', c)
|
||||
|
||||
" Test for using <CR> as default input
|
||||
call feedkeys(":let c = input('name? ', \"\\<CR>\")\<CR>x\<CR>", 'xt')
|
||||
call assert_equal(' x', c)
|
||||
|
||||
call assert_fails("call input('F:', '', 'invalid')", 'E180:')
|
||||
call assert_fails("call input('F:', '', [])", 'E730:')
|
||||
endfunc
|
||||
|
||||
@@ -121,6 +121,15 @@ func Test_lua_eval()
|
||||
lua v = nil
|
||||
endfunc
|
||||
|
||||
" Test luaeval() with lambda
|
||||
func Test_luaeval_with_lambda()
|
||||
lua function hello_luaeval_lambda(a, cb) return a .. cb() end
|
||||
call assert_equal('helloworld',
|
||||
\ luaeval('hello_luaeval_lambda(_A[1], _A[2])',
|
||||
\ ['hello', {->'world'}]))
|
||||
lua hello_luaeval_lambda = nil
|
||||
endfunc
|
||||
|
||||
" Test vim.window()
|
||||
func Test_lua_window()
|
||||
e Xfoo2
|
||||
|
||||
@@ -485,6 +485,30 @@ func Test_list_mappings()
|
||||
nmapclear
|
||||
endfunc
|
||||
|
||||
func Test_expr_map_gets_cursor()
|
||||
new
|
||||
call setline(1, ['one', 'some w!rd'])
|
||||
func StoreColumn()
|
||||
let g:exprLine = line('.')
|
||||
let g:exprCol = col('.')
|
||||
return 'x'
|
||||
endfunc
|
||||
nnoremap <expr> x StoreColumn()
|
||||
2
|
||||
nmap ! f!<Ignore>x
|
||||
call feedkeys("!", 'xt')
|
||||
call assert_equal('some wrd', getline(2))
|
||||
call assert_equal(2, g:exprLine)
|
||||
call assert_equal(7, g:exprCol)
|
||||
|
||||
bwipe!
|
||||
unlet g:exprLine
|
||||
unlet g:exprCol
|
||||
delfunc StoreColumn
|
||||
nunmap x
|
||||
nunmap !
|
||||
endfunc
|
||||
|
||||
func Test_expr_map_restore_cursor()
|
||||
CheckScreendump
|
||||
|
||||
|
||||
@@ -147,9 +147,9 @@ func Test_memory_func_capture_lvars()
|
||||
" The usage may be a bit less than the last value, use 80%.
|
||||
" Allow for 20% tolerance at the upper limit. That's very permissive, but
|
||||
" otherwise the test fails sometimes. On Cirrus CI with FreeBSD we need to
|
||||
" be even more permissive.
|
||||
" be even much more permissive.
|
||||
if has('bsd')
|
||||
let multiplier = 15
|
||||
let multiplier = 19
|
||||
else
|
||||
let multiplier = 12
|
||||
endif
|
||||
|
||||
@@ -259,6 +259,17 @@ func Test_message_more()
|
||||
call term_sendkeys(buf, 'q')
|
||||
call WaitForAssert({-> assert_equal('100', term_getline(buf, 5))})
|
||||
|
||||
" Execute a : command from the more prompt
|
||||
call term_sendkeys(buf, ":%p#\n")
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_equal('-- More --', term_getline(buf, 6))})
|
||||
call term_sendkeys(buf, ":")
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_equal(':', term_getline(buf, 6))})
|
||||
call term_sendkeys(buf, "echo 'Hello'\n")
|
||||
call term_wait(buf)
|
||||
call WaitForAssert({-> assert_equal('Hello ', term_getline(buf, 5))})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -544,6 +544,20 @@ func Test_mkview_no_balt()
|
||||
%bwipe
|
||||
endfunc
|
||||
|
||||
func Test_mksession_no_balt()
|
||||
edit Xtestfile1
|
||||
edit Xtestfile2
|
||||
|
||||
bdelete Xtestfile1
|
||||
mksession! Xtestview
|
||||
|
||||
source Xtestview
|
||||
call assert_equal(0, buflisted('Xtestfile1'))
|
||||
|
||||
call delete('Xtestview')
|
||||
%bwipe
|
||||
endfunc
|
||||
|
||||
" Test :mkview with a file argument.
|
||||
func Test_mkview_file()
|
||||
" Create a view with line number and a fold.
|
||||
|
||||
@@ -3207,6 +3207,13 @@ func Test_normal_delete_cmd()
|
||||
" delete to a readonly register
|
||||
call setline(1, ['abcd'])
|
||||
call assert_beeps('normal ":d2l')
|
||||
|
||||
" D and d with 'nomodifiable'
|
||||
call setline(1, ['abcd'])
|
||||
setlocal nomodifiable
|
||||
call assert_fails('normal D', 'E21:')
|
||||
call assert_fails('normal d$', 'E21:')
|
||||
|
||||
close!
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -1038,6 +1038,27 @@ func Test_opt_winminheight_term()
|
||||
call delete('Xwinminheight')
|
||||
endfunc
|
||||
|
||||
func Test_opt_winminheight_term_tabs()
|
||||
CheckRunVimInTerminal
|
||||
|
||||
" The tabline should be taken into account.
|
||||
let lines =<< trim END
|
||||
set wmh=0 stal=2
|
||||
split
|
||||
split
|
||||
split
|
||||
split
|
||||
tabnew
|
||||
END
|
||||
call writefile(lines, 'Xwinminheight')
|
||||
let buf = RunVimInTerminal('-S Xwinminheight', #{rows: 11})
|
||||
call term_sendkeys(buf, ":set wmh=1\n")
|
||||
call WaitForAssert({-> assert_match('E36: Not enough room', term_getline(buf, 11))})
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xwinminheight')
|
||||
endfunc
|
||||
|
||||
" Test for the 'winminwidth' option
|
||||
func Test_opt_winminwidth()
|
||||
only!
|
||||
|
||||
@@ -149,4 +149,18 @@ func Test_xrestore()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for 'pastetoggle'
|
||||
func Test_pastetoggle()
|
||||
new
|
||||
set pastetoggle=<F4>
|
||||
set nopaste
|
||||
call feedkeys("iHello\<F4>", 'xt')
|
||||
call assert_true(&paste)
|
||||
call feedkeys("i\<F4>", 'xt')
|
||||
call assert_false(&paste)
|
||||
call assert_equal('Hello', getline(1))
|
||||
set pastetoggle&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
" Test :recover
|
||||
|
||||
source check.vim
|
||||
|
||||
func Test_recover_root_dir()
|
||||
" This used to access invalid memory.
|
||||
split Xtest
|
||||
@@ -21,6 +23,21 @@ func Test_recover_root_dir()
|
||||
set dir&
|
||||
endfunc
|
||||
|
||||
" Make a copy of the current swap file to "Xswap".
|
||||
" Return the name of the swap file.
|
||||
func CopySwapfile()
|
||||
preserve
|
||||
" get the name of the swap file
|
||||
let swname = split(execute("swapname"))[0]
|
||||
let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
|
||||
" make a copy of the swap file in Xswap
|
||||
set binary
|
||||
exe 'sp ' . swname
|
||||
w! Xswap
|
||||
set nobinary
|
||||
return swname
|
||||
endfunc
|
||||
|
||||
" Inserts 10000 lines with text to fill the swap file with two levels of pointer
|
||||
" blocks. Then recovers from the swap file and checks all text is restored.
|
||||
"
|
||||
@@ -37,15 +54,9 @@ func Test_swap_file()
|
||||
let i += 1
|
||||
endwhile
|
||||
$delete
|
||||
preserve
|
||||
" get the name of the swap file
|
||||
let swname = split(execute("swapname"))[0]
|
||||
let swname = substitute(swname, '[[:blank:][:cntrl:]]*\(.\{-}\)[[:blank:][:cntrl:]]*$', '\1', '')
|
||||
" make a copy of the swap file in Xswap
|
||||
set binary
|
||||
exe 'sp ' . swname
|
||||
w! Xswap
|
||||
set nobinary
|
||||
|
||||
let swname = CopySwapfile()
|
||||
|
||||
new
|
||||
only!
|
||||
bwipe! Xtest
|
||||
@@ -67,4 +78,59 @@ func Test_swap_file()
|
||||
enew! | only
|
||||
endfunc
|
||||
|
||||
func Test_nocatch_process_still_running()
|
||||
" sysinfo.uptime probably only works on Linux
|
||||
if !has('linux')
|
||||
let g:skipped_reason = 'only works on Linux'
|
||||
return
|
||||
endif
|
||||
" the GUI dialog can't be handled
|
||||
if has('gui_running')
|
||||
let g:skipped_reason = 'only works in the terminal'
|
||||
return
|
||||
endif
|
||||
|
||||
" don't intercept existing swap file here
|
||||
au! SwapExists
|
||||
|
||||
" Edit a file and grab its swapfile.
|
||||
edit Xswaptest
|
||||
call setline(1, ['a', 'b', 'c'])
|
||||
let swname = CopySwapfile()
|
||||
|
||||
" Forget we edited this file
|
||||
new
|
||||
only!
|
||||
bwipe! Xswaptest
|
||||
|
||||
call rename('Xswap', swname)
|
||||
call feedkeys('e', 'tL')
|
||||
redir => editOutput
|
||||
edit Xswaptest
|
||||
redir END
|
||||
call assert_match('E325: ATTENTION', editOutput)
|
||||
call assert_match('file name: .*Xswaptest', editOutput)
|
||||
call assert_match('process ID: \d* (STILL RUNNING)', editOutput)
|
||||
|
||||
" Forget we edited this file
|
||||
new
|
||||
only!
|
||||
bwipe! Xswaptest
|
||||
|
||||
" pretend we rebooted
|
||||
call test_override("uptime", 0)
|
||||
sleep 1
|
||||
|
||||
call rename('Xswap', swname)
|
||||
call feedkeys('e', 'tL')
|
||||
redir => editOutput
|
||||
edit Xswaptest
|
||||
redir END
|
||||
call assert_match('E325: ATTENTION', editOutput)
|
||||
call assert_notmatch('(STILL RUNNING)', editOutput)
|
||||
|
||||
call test_override("ALL", 0)
|
||||
call delete(swname)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -709,4 +709,14 @@ func Test_insert_small_delete()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Record in insert mode using CTRL-O
|
||||
func Test_record_in_insert_mode()
|
||||
new
|
||||
let @r = ''
|
||||
call setline(1, ['foo'])
|
||||
call feedkeys("i\<C-O>qrbaz\<C-O>q", 'xt')
|
||||
call assert_equal('baz', @r)
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -165,7 +165,10 @@ func Test_term_mouse_multiple_clicks_to_select_mode()
|
||||
let save_term = &term
|
||||
let save_ttymouse = &ttymouse
|
||||
call test_override('no_query_mouse', 1)
|
||||
set mouse=a term=xterm mousetime=200
|
||||
|
||||
" 'mousetime' must be sufficiently large, or else the test is flaky when
|
||||
" using a ssh connection with X forwarding; i.e. ssh -X.
|
||||
set mouse=a term=xterm mousetime=1000
|
||||
set selectmode=mouse
|
||||
new
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ func! Test_sleep_bang()
|
||||
call s:assert_takes_longer('sl 50m', 50)
|
||||
call s:assert_takes_longer('sl! 50m', 50)
|
||||
call s:assert_takes_longer('1sleep', 1000)
|
||||
call s:assert_takes_longer('normal 1gs', 1000)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
+145
-14
@@ -109,9 +109,9 @@ func Test_pack_in_rtp_when_plugins_run()
|
||||
endfunc
|
||||
|
||||
func Test_help_arg()
|
||||
if !has('unix') && has('gui_running')
|
||||
throw 'Skipped: does not work with gvim on MS-Windows'
|
||||
endif
|
||||
" This does not work with a GUI-only binary, such as on MS-Windows.
|
||||
CheckAnyOf Unix NotGui
|
||||
|
||||
if RunVim([], [], '--help >Xtestout')
|
||||
let lines = readfile('Xtestout')
|
||||
call assert_true(len(lines) > 20)
|
||||
@@ -408,6 +408,134 @@ func Test_A_F_H_arg()
|
||||
call delete('Xtestout')
|
||||
endfunc
|
||||
|
||||
" Test the --echo-wid argument (for GTK GUI only).
|
||||
func Test_echo_wid()
|
||||
CheckCanRunGui
|
||||
CheckFeature gui_gtk
|
||||
|
||||
if RunVim([], [], '-g --echo-wid -cq >Xtest_echo_wid')
|
||||
let lines = readfile('Xtest_echo_wid')
|
||||
call assert_equal(1, len(lines))
|
||||
call assert_match('^WID: \d\+$', lines[0])
|
||||
endif
|
||||
|
||||
call delete('Xtest_echo_wid')
|
||||
endfunction
|
||||
|
||||
" Test the -reverse and +reverse arguments (for GUI only).
|
||||
func Test_reverse()
|
||||
CheckCanRunGui
|
||||
CheckAnyOf Feature:gui_gtk Feature:gui_motif Feature:gui_athena
|
||||
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&background], "Xtest_reverse")
|
||||
qall
|
||||
[CODE]
|
||||
if RunVim([], after, '-f -g -reverse')
|
||||
let lines = readfile('Xtest_reverse')
|
||||
call assert_equal(['dark'], lines)
|
||||
endif
|
||||
if RunVim([], after, '-f -g +reverse')
|
||||
let lines = readfile('Xtest_reverse')
|
||||
call assert_equal(['light'], lines)
|
||||
endif
|
||||
|
||||
call delete('Xtest_reverse')
|
||||
endfunc
|
||||
|
||||
" Test the -background and -foreground arguments (for GUI only).
|
||||
func Test_background_foreground()
|
||||
CheckCanRunGui
|
||||
CheckAnyOf Feature:gui_gtk Feature:gui_motif Feature:gui_athena
|
||||
|
||||
" Is there a better way to check the effect of -background & -foreground
|
||||
" other than merely looking at &background (dark or light)?
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&background], "Xtest_fg_bg")
|
||||
qall
|
||||
[CODE]
|
||||
if RunVim([], after, '-f -g -background darkred -foreground yellow')
|
||||
let lines = readfile('Xtest_fg_bg')
|
||||
call assert_equal(['dark'], lines)
|
||||
endif
|
||||
if RunVim([], after, '-f -g -background ivory -foreground darkgreen')
|
||||
let lines = readfile('Xtest_fg_bg')
|
||||
call assert_equal(['light'], lines)
|
||||
endif
|
||||
|
||||
call delete('Xtest_fg_bg')
|
||||
endfunc
|
||||
|
||||
" Test the -font argument (for GUI only).
|
||||
func Test_font()
|
||||
CheckCanRunGui
|
||||
CheckNotMSWindows
|
||||
|
||||
if has('gui_gtk')
|
||||
let font = 'Courier 14'
|
||||
elseif has('gui_motif') || has('gui_athena')
|
||||
let font = '-misc-fixed-bold-*'
|
||||
else
|
||||
throw 'Skipped: test does not set a valid font for this GUI'
|
||||
endif
|
||||
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&guifont], "Xtest_font")
|
||||
qall
|
||||
[CODE]
|
||||
|
||||
if RunVim([], after, '--nofork -g -font "' .. font .. '"')
|
||||
let lines = readfile('Xtest_font')
|
||||
call assert_equal([font], lines)
|
||||
endif
|
||||
|
||||
call delete('Xtest_font')
|
||||
endfunc
|
||||
|
||||
" Test the -geometry argument (for GUI only).
|
||||
func Test_geometry()
|
||||
CheckCanRunGui
|
||||
CheckAnyOf Feature:gui_gtk Feature:gui_motif Feature:gui_athena
|
||||
|
||||
if has('gui_motif') || has('gui_athena')
|
||||
" FIXME: With GUI Athena or Motif, the value of getwinposx(),
|
||||
" getwinposy() and getwinpos() do not match exactly the
|
||||
" value given in -geometry. Why?
|
||||
" So only check &columns and &lines for those GUIs.
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&columns, &lines], "Xtest_geometry")
|
||||
qall
|
||||
[CODE]
|
||||
if RunVim([], after, '-f -g -geometry 31x13+41+43')
|
||||
let lines = readfile('Xtest_geometry')
|
||||
call assert_equal(['31', '13'], lines)
|
||||
endif
|
||||
else
|
||||
let after =<< trim [CODE]
|
||||
call writefile([&columns, &lines, getwinposx(), getwinposy(), string(getwinpos())], "Xtest_geometry")
|
||||
qall
|
||||
[CODE]
|
||||
if RunVim([], after, '-f -g -geometry 31x13+41+43')
|
||||
let lines = readfile('Xtest_geometry')
|
||||
call assert_equal(['31', '13', '41', '43', '[41, 43]'], lines)
|
||||
endif
|
||||
endif
|
||||
|
||||
call delete('Xtest_geometry')
|
||||
endfunc
|
||||
|
||||
" Test the -iconic argument (for GUI only).
|
||||
func Test_iconic()
|
||||
CheckCanRunGui
|
||||
CheckAnyOf Feature:gui_gtk Feature:gui_motif Feature:gui_athena
|
||||
|
||||
call RunVim([], [], '-f -g -iconic -cq')
|
||||
|
||||
" TODO: currently only start vim iconified, but does not
|
||||
" check that vim is iconified. How could this be checked?
|
||||
endfunc
|
||||
|
||||
|
||||
func Test_invalid_args()
|
||||
" must be able to get the output of Vim.
|
||||
CheckUnix
|
||||
@@ -1044,16 +1172,11 @@ func Test_progname()
|
||||
\ 'vimdiff', 'gvimdiff']
|
||||
|
||||
for progname in prognames
|
||||
if empty($DISPLAY)
|
||||
if progname =~# 'g'
|
||||
" Can't run gvim, gview (etc.) if $DISPLAY is not setup.
|
||||
continue
|
||||
endif
|
||||
if has('gui') && (progname ==# 'evim' || progname ==# 'eview')
|
||||
" evim or eview will start the GUI if there is gui support.
|
||||
" So don't try to start them either if $DISPLAY is not setup.
|
||||
continue
|
||||
endif
|
||||
let run_with_gui = (progname =~# 'g') || (has('gui') && (progname ==# 'evim' || progname ==# 'eview'))
|
||||
|
||||
if empty($DISPLAY) && run_with_gui
|
||||
" Can't run gvim, gview (etc.) if $DISPLAY is not setup.
|
||||
continue
|
||||
endif
|
||||
|
||||
exe 'silent !ln -s -f ' ..exepath(GetVimProg()) .. ' Xprogname/' .. progname
|
||||
@@ -1068,7 +1191,15 @@ func Test_progname()
|
||||
if progname =~# 'g' && !has('gui')
|
||||
call assert_equal("E25: GUI cannot be used: Not enabled at compile time\n", stdout_stderr, progname)
|
||||
else
|
||||
call assert_equal('', stdout_stderr, progname)
|
||||
" GUI motif can output some warnings like this:
|
||||
" Warning:
|
||||
" Name: subMenu
|
||||
" Class: XmCascadeButton
|
||||
" Illegal mnemonic character; Could not convert X KEYSYM to a keycode
|
||||
" So don't check that stderr is empty with GUI Motif.
|
||||
if run_with_gui && !has('gui_motif')
|
||||
call assert_equal('', stdout_stderr, progname)
|
||||
endif
|
||||
call assert_equal(expectations[progname], readfile('Xprogname_out'), progname)
|
||||
endif
|
||||
|
||||
|
||||
@@ -858,6 +858,21 @@ func Test_mps_latin1()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
func Test_mps_error()
|
||||
let encoding_save = &encoding
|
||||
|
||||
for e in ['utf-8', 'latin1']
|
||||
exe 'set encoding=' .. e
|
||||
|
||||
call assert_fails('set mps=<:', 'E474:', e)
|
||||
call assert_fails('set mps=:>', 'E474:', e)
|
||||
call assert_fails('set mps=<>', 'E474:', e)
|
||||
call assert_fails('set mps=<:>_', 'E474:', e)
|
||||
endfor
|
||||
|
||||
let &encoding = encoding_save
|
||||
endfunc
|
||||
|
||||
" Test for ra on multi-byte characters
|
||||
func Test_ra_multibyte()
|
||||
new
|
||||
|
||||
@@ -733,4 +733,18 @@ func Test_undofile_cryptmethod_blowfish2()
|
||||
set undofile& undolevels& cryptmethod&
|
||||
endfunc
|
||||
|
||||
" Test for redoing with incrementing numbered registers
|
||||
func Test_redo_repeat_numbered_register()
|
||||
new
|
||||
for [i, v] in [[1, 'one'], [2, 'two'], [3, 'three'],
|
||||
\ [4, 'four'], [5, 'five'], [6, 'six'],
|
||||
\ [7, 'seven'], [8, 'eight'], [9, 'nine']]
|
||||
exe 'let @' .. i .. '="' .. v .. '\n"'
|
||||
endfor
|
||||
call feedkeys('"1p.........', 'xt')
|
||||
call assert_equal(['', 'one', 'two', 'three', 'four', 'five', 'six',
|
||||
\ 'seven', 'eight', 'nine', 'nine'], getline(1, '$'))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -11,7 +11,7 @@ func Test_visual_block_insert()
|
||||
bwipeout!
|
||||
endfunc
|
||||
|
||||
" Test for built-in function strchars()
|
||||
" Test for built-in functions strchars() and strcharlen()
|
||||
func Test_strchars()
|
||||
let inp = ["a", "あいa", "A\u20dd", "A\u20dd\u20dd", "\u20dd"]
|
||||
let exp = [[1, 1, 1], [3, 3, 3], [2, 2, 1], [3, 3, 1], [1, 1, 1]]
|
||||
@@ -20,6 +20,13 @@ func Test_strchars()
|
||||
call assert_equal(exp[i][1], inp[i]->strchars(0))
|
||||
call assert_equal(exp[i][2], strchars(inp[i], 1))
|
||||
endfor
|
||||
|
||||
let exp = [1, 3, 1, 1, 1]
|
||||
for i in range(len(inp))
|
||||
call assert_equal(exp[i], inp[i]->strcharlen())
|
||||
call assert_equal(exp[i], strcharlen(inp[i]))
|
||||
endfor
|
||||
|
||||
call assert_fails("let v=strchars('abc', [])", 'E745:')
|
||||
call assert_fails("let v=strchars('abc', 2)", 'E1023:')
|
||||
endfunc
|
||||
|
||||
@@ -72,6 +72,13 @@ def Test_assignment()
|
||||
CheckDefFailure(['var lambda = () => "lambda"'], 'E704:')
|
||||
CheckScriptFailure(['var x = "x"'], 'E1124:')
|
||||
|
||||
# lower case name is OK for a list
|
||||
var lambdaLines =<< trim END
|
||||
var lambdaList: list<func> = [Test_syntax]
|
||||
lambdaList[0] = () => "lambda"
|
||||
END
|
||||
CheckDefAndScriptSuccess(lambdaLines)
|
||||
|
||||
var nr: number = 1234
|
||||
CheckDefFailure(['var nr: number = "asdf"'], 'E1012:')
|
||||
|
||||
|
||||
@@ -340,6 +340,26 @@ def Test_extend_list_item_type()
|
||||
CheckScriptFailure(['vim9script'] + lines, 'E1012:', 1)
|
||||
enddef
|
||||
|
||||
def Test_extend_with_error_function()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def F()
|
||||
{
|
||||
var m = 10
|
||||
}
|
||||
echo m
|
||||
enddef
|
||||
|
||||
def Test()
|
||||
var d: dict<any> = {}
|
||||
d->extend({A: 10, Func: function('F', [])})
|
||||
enddef
|
||||
|
||||
Test()
|
||||
END
|
||||
CheckScriptFailure(lines, 'E1001: Variable not found: m')
|
||||
enddef
|
||||
|
||||
def Test_job_info_return_type()
|
||||
if has('job')
|
||||
job_start(&shell)
|
||||
@@ -472,6 +492,19 @@ def Test_getchar()
|
||||
getchar(true)->assert_equal(0)
|
||||
enddef
|
||||
|
||||
def Test_getenv()
|
||||
if getenv('does-not_exist') == ''
|
||||
assert_report('getenv() should return null')
|
||||
endif
|
||||
if getenv('does-not_exist') == null
|
||||
else
|
||||
assert_report('getenv() should return null')
|
||||
endif
|
||||
$SOMEENVVAR = 'some'
|
||||
assert_equal('some', getenv('SOMEENVVAR'))
|
||||
unlet $SOMEENVVAR
|
||||
enddef
|
||||
|
||||
def Test_getcompletion()
|
||||
set wildignore=*.vim,*~
|
||||
var l = getcompletion('run', 'file', true)
|
||||
|
||||
@@ -364,9 +364,8 @@ def Test_method_call_linebreak()
|
||||
return F()
|
||||
enddef
|
||||
def Test()
|
||||
Foo
|
||||
->Bar()
|
||||
->setline(1)
|
||||
Foo ->Bar()
|
||||
->setline(1)
|
||||
enddef
|
||||
Test()
|
||||
assert_equal('the text', getline(1))
|
||||
@@ -401,8 +400,7 @@ def Test_method_call_linebreak()
|
||||
return F()
|
||||
enddef
|
||||
|
||||
Foo
|
||||
->Bar()
|
||||
Foo->Bar()
|
||||
->setline(1)
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
@@ -424,6 +422,33 @@ def Test_method_call_whitespace()
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_method_and_user_command()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Cmd()
|
||||
g:didFunc = 1
|
||||
enddef
|
||||
command Cmd g:didCmd = 1
|
||||
Cmd
|
||||
assert_equal(1, g:didCmd)
|
||||
Cmd()
|
||||
assert_equal(1, g:didFunc)
|
||||
unlet g:didFunc
|
||||
unlet g:didCmd
|
||||
|
||||
def InDefFunc()
|
||||
Cmd
|
||||
assert_equal(1, g:didCmd)
|
||||
Cmd()
|
||||
assert_equal(1, g:didFunc)
|
||||
unlet g:didFunc
|
||||
unlet g:didCmd
|
||||
enddef
|
||||
InDefFunc()
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_skipped_expr_linebreak()
|
||||
if 0
|
||||
var x = []
|
||||
|
||||
@@ -947,7 +947,7 @@ def NestedOuter()
|
||||
enddef
|
||||
enddef
|
||||
|
||||
def Test_nested_func()
|
||||
def Test_disassemble_nested_func()
|
||||
var instr = execute('disassemble NestedOuter')
|
||||
assert_match('NestedOuter\_s*' ..
|
||||
'def g:Inner()\_s*' ..
|
||||
@@ -965,7 +965,7 @@ def NestedDefList()
|
||||
def /Info/
|
||||
enddef
|
||||
|
||||
def Test_nested_def_list()
|
||||
def Test_disassemble_nested_def_list()
|
||||
var instr = execute('disassemble NestedDefList')
|
||||
assert_match('NestedDefList\_s*' ..
|
||||
'def\_s*' ..
|
||||
|
||||
@@ -1370,6 +1370,9 @@ def Test_expr5_list_add()
|
||||
dany[i] = i
|
||||
endfor
|
||||
assert_equal({a: 'a', 12: 12}, dany)
|
||||
|
||||
# result of glob() is "any", runtime type check
|
||||
var sl: list<string> = glob('*.txt', false, true) + ['']
|
||||
enddef
|
||||
|
||||
" test multiply, divide, modulo
|
||||
@@ -2364,6 +2367,35 @@ def Test_expr7_any_index_slice()
|
||||
assert_equal('abcd', g:teststring[: -3])
|
||||
assert_equal('', g:teststring[: -9])
|
||||
|
||||
# composing characters are included
|
||||
g:teststring = 'àéû'
|
||||
assert_equal('à', g:teststring[0])
|
||||
assert_equal('é', g:teststring[1])
|
||||
assert_equal('û', g:teststring[2])
|
||||
assert_equal('', g:teststring[3])
|
||||
assert_equal('', g:teststring[4])
|
||||
|
||||
assert_equal('û', g:teststring[-1])
|
||||
assert_equal('é', g:teststring[-2])
|
||||
assert_equal('à', g:teststring[-3])
|
||||
assert_equal('', g:teststring[-4])
|
||||
assert_equal('', g:teststring[-5])
|
||||
|
||||
assert_equal('à', g:teststring[0 : 0])
|
||||
assert_equal('é', g:teststring[1 : 1])
|
||||
assert_equal('àé', g:teststring[0 : 1])
|
||||
assert_equal('àéû', g:teststring[0 : -1])
|
||||
assert_equal('àé', g:teststring[0 : -2])
|
||||
assert_equal('à', g:teststring[0 : -3])
|
||||
assert_equal('', g:teststring[0 : -4])
|
||||
assert_equal('', g:teststring[0 : -5])
|
||||
assert_equal('àéû', g:teststring[ : ])
|
||||
assert_equal('àéû', g:teststring[0 : ])
|
||||
assert_equal('éû', g:teststring[1 : ])
|
||||
assert_equal('û', g:teststring[2 : ])
|
||||
assert_equal('', g:teststring[3 : ])
|
||||
assert_equal('', g:teststring[4 : ])
|
||||
|
||||
# blob index cannot be out of range
|
||||
g:testblob = 0z01ab
|
||||
assert_equal(0x01, g:testblob[0])
|
||||
|
||||
@@ -311,6 +311,14 @@ def Test_call_default_args()
|
||||
delfunc g:Func
|
||||
CheckScriptFailure(['def Func(arg: number = "text")', 'enddef', 'defcompile'], 'E1013: Argument 1: type mismatch, expected number but got string')
|
||||
delfunc g:Func
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def Func(a = b == 0 ? 1 : 2, b = 0)
|
||||
enddef
|
||||
defcompile
|
||||
END
|
||||
CheckScriptFailure(lines, 'E1001: Variable not found: b')
|
||||
enddef
|
||||
|
||||
def FuncWithComment( # comment
|
||||
@@ -385,7 +393,6 @@ def Test_nested_function()
|
||||
CheckDefFailure(lines, 'E1117:')
|
||||
|
||||
# nested function inside conditional
|
||||
# TODO: should it work when "thecount" is inside the "if"?
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
var thecount = 0
|
||||
@@ -403,6 +410,25 @@ def Test_nested_function()
|
||||
assert_equal(2, Test())
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
|
||||
# also works when "thecount" is inside the "if" block
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
if true
|
||||
var thecount = 0
|
||||
def Test(): number
|
||||
def TheFunc(): number
|
||||
thecount += 1
|
||||
return thecount
|
||||
enddef
|
||||
return TheFunc()
|
||||
enddef
|
||||
endif
|
||||
defcompile
|
||||
assert_equal(1, Test())
|
||||
assert_equal(2, Test())
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_not_nested_function()
|
||||
@@ -726,11 +752,26 @@ def Test_call_lambda_args()
|
||||
CheckDefFailure(lines, 'E1167:')
|
||||
enddef
|
||||
|
||||
def FilterWithCond(x: string, Cond: func(string): bool): bool
|
||||
return Cond(x)
|
||||
enddef
|
||||
|
||||
def Test_lambda_return_type()
|
||||
var lines =<< trim END
|
||||
var Ref = (): => 123
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1157:', 1)
|
||||
|
||||
# this works
|
||||
for x in ['foo', 'boo']
|
||||
echo FilterWithCond(x, (v) => v =~ '^b')
|
||||
endfor
|
||||
|
||||
# this fails
|
||||
lines =<< trim END
|
||||
echo FilterWithCond('foo', (v) => v .. '^b')
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
|
||||
enddef
|
||||
|
||||
def Test_lambda_uses_assigned_var()
|
||||
|
||||
@@ -5,6 +5,7 @@ source term_util.vim
|
||||
source view_util.vim
|
||||
source vim9.vim
|
||||
source shared.vim
|
||||
source screendump.vim
|
||||
|
||||
def Test_range_only()
|
||||
new
|
||||
@@ -591,6 +592,31 @@ def Test_try_catch_throw()
|
||||
assert_equal(4, ReturnInFinally())
|
||||
enddef
|
||||
|
||||
" :while at the very start of a function that :continue jumps to
|
||||
def TryContinueFunc()
|
||||
while g:Count < 2
|
||||
g:sequence ..= 't'
|
||||
try
|
||||
echoerr 'Test'
|
||||
catch
|
||||
g:Count += 1
|
||||
g:sequence ..= 'c'
|
||||
continue
|
||||
endtry
|
||||
g:sequence ..= 'e'
|
||||
g:Count += 1
|
||||
endwhile
|
||||
enddef
|
||||
|
||||
def Test_continue_in_try_in_while()
|
||||
g:Count = 0
|
||||
g:sequence = ''
|
||||
TryContinueFunc()
|
||||
assert_equal('tctc', g:sequence)
|
||||
unlet g:Count
|
||||
unlet g:sequence
|
||||
enddef
|
||||
|
||||
def Test_nocatch_return_in_try()
|
||||
# return in try block returns normally
|
||||
def ReturnInTry(): string
|
||||
@@ -1030,13 +1056,17 @@ def Test_vim9_import_export()
|
||||
vim9script
|
||||
import * as Export from './Xexport.vim'
|
||||
def UseExport()
|
||||
g:imported = Export.exported
|
||||
g:imported_def = Export.exported
|
||||
enddef
|
||||
g:imported_script = Export.exported
|
||||
assert_equal(1, exists('Export.exported'))
|
||||
assert_equal(0, exists('Export.notexported'))
|
||||
UseExport()
|
||||
END
|
||||
writefile(import_star_as_lines, 'Ximport.vim')
|
||||
source Ximport.vim
|
||||
assert_equal(9883, g:imported)
|
||||
assert_equal(9883, g:imported_def)
|
||||
assert_equal(9883, g:imported_script)
|
||||
|
||||
var import_star_as_lines_no_dot =<< trim END
|
||||
vim9script
|
||||
@@ -1071,6 +1101,22 @@ def Test_vim9_import_export()
|
||||
writefile(import_star_as_duplicated, 'Ximport.vim')
|
||||
assert_fails('source Ximport.vim', 'E1073:', '', 4, 'Ximport.vim')
|
||||
|
||||
var import_star_as_lines_script_no_dot =<< trim END
|
||||
vim9script
|
||||
import * as Export from './Xexport.vim'
|
||||
g:imported_script = Export exported
|
||||
END
|
||||
writefile(import_star_as_lines_script_no_dot, 'Ximport.vim')
|
||||
assert_fails('source Ximport.vim', 'E1029:')
|
||||
|
||||
var import_star_as_lines_script_space_after_dot =<< trim END
|
||||
vim9script
|
||||
import * as Export from './Xexport.vim'
|
||||
g:imported_script = Export. exported
|
||||
END
|
||||
writefile(import_star_as_lines_script_space_after_dot, 'Ximport.vim')
|
||||
assert_fails('source Ximport.vim', 'E1074:')
|
||||
|
||||
var import_star_as_lines_missing_name =<< trim END
|
||||
vim9script
|
||||
import * as Export from './Xexport.vim'
|
||||
@@ -1204,17 +1250,23 @@ def Test_vim9_import_export()
|
||||
delete('Xexport.vim')
|
||||
|
||||
# Check that in a Vim9 script 'cpo' is set to the Vim default.
|
||||
set cpo&vi
|
||||
var cpo_before = &cpo
|
||||
# Flags added or removed are also applied to the restored value.
|
||||
set cpo=abcd
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
g:cpo_in_vim9script = &cpo
|
||||
set cpo+=f
|
||||
set cpo-=c
|
||||
g:cpo_after_vim9script = &cpo
|
||||
END
|
||||
writefile(lines, 'Xvim9_script')
|
||||
source Xvim9_script
|
||||
assert_equal(cpo_before, &cpo)
|
||||
assert_equal('fabd', &cpo)
|
||||
set cpo&vim
|
||||
assert_equal(&cpo, g:cpo_in_vim9script)
|
||||
var newcpo = substitute(&cpo, 'c', '', '') .. 'f'
|
||||
assert_equal(newcpo, g:cpo_after_vim9script)
|
||||
|
||||
delete('Xvim9_script')
|
||||
enddef
|
||||
|
||||
@@ -1515,6 +1567,35 @@ def Test_script_reload_change_type()
|
||||
delete('Xreload.vim')
|
||||
enddef
|
||||
|
||||
" Define CallFunc so that the test can be compiled
|
||||
command CallFunc echo 'nop'
|
||||
|
||||
def Test_script_reload_from_function()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
|
||||
if exists('g:loaded')
|
||||
finish
|
||||
endif
|
||||
g:loaded = 1
|
||||
delcommand CallFunc
|
||||
command CallFunc Func()
|
||||
def Func()
|
||||
so XreloadFunc.vim
|
||||
g:didTheFunc = 1
|
||||
enddef
|
||||
END
|
||||
writefile(lines, 'XreloadFunc.vim')
|
||||
source XreloadFunc.vim
|
||||
CallFunc
|
||||
assert_equal(1, g:didTheFunc)
|
||||
|
||||
delete('XreloadFunc.vim')
|
||||
delcommand CallFunc
|
||||
unlet g:loaded
|
||||
unlet g:didTheFunc
|
||||
enddef
|
||||
|
||||
def Test_script_var_shadows_function()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
@@ -1859,6 +1940,8 @@ def Test_no_insert_xit()
|
||||
CheckScriptFailure(['vim9script', 'c'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 'i = 1'], 'E488:')
|
||||
CheckScriptFailure(['vim9script', 'i'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 'o = 1'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 'o'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 't'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 't = 1'], 'E1100:')
|
||||
CheckScriptFailure(['vim9script', 'x = 1'], 'E1100:')
|
||||
@@ -3154,6 +3237,10 @@ def Test_vim9_autoload()
|
||||
return 'test'
|
||||
enddef
|
||||
g:some#name = 'name'
|
||||
|
||||
def some#varargs(a1: string, ...l: list<string>): string
|
||||
return a1 .. l[0] .. l[1]
|
||||
enddef
|
||||
END
|
||||
|
||||
mkdir('Xdir/autoload', 'p')
|
||||
@@ -3166,6 +3253,8 @@ def Test_vim9_autoload()
|
||||
g:some#other = 'other'
|
||||
assert_equal('other', g:some#other)
|
||||
|
||||
assert_equal('abc', some#varargs('a', 'b', 'c'))
|
||||
|
||||
# upper case script name works
|
||||
lines =<< trim END
|
||||
vim9script
|
||||
@@ -3332,6 +3421,38 @@ def Test_restoring_cpo()
|
||||
set cpo&vim
|
||||
enddef
|
||||
|
||||
" Use :function so we can use Check commands
|
||||
func Test_no_redraw_when_restoring_cpo()
|
||||
CheckScreendump
|
||||
CheckFeature timers
|
||||
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
def script#func()
|
||||
enddef
|
||||
END
|
||||
call mkdir('Xdir/autoload', 'p')
|
||||
call writefile(lines, 'Xdir/autoload/script.vim')
|
||||
|
||||
let lines =<< trim END
|
||||
vim9script
|
||||
set cpo+=M
|
||||
exe 'set rtp^=' .. getcwd() .. '/Xdir'
|
||||
au CmdlineEnter : ++once timer_start(0, () => script#func())
|
||||
setline(1, 'some text')
|
||||
END
|
||||
call writefile(lines, 'XTest_redraw_cpo')
|
||||
let buf = RunVimInTerminal('-S XTest_redraw_cpo', {'rows': 6})
|
||||
call term_sendkeys(buf, "V:")
|
||||
call VerifyScreenDump(buf, 'Test_vim9_no_redraw', {})
|
||||
|
||||
" clean up
|
||||
call term_sendkeys(buf, "\<Esc>u")
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('XTest_redraw_cpo')
|
||||
call delete('Xdir', 'rf')
|
||||
endfunc
|
||||
|
||||
|
||||
def Test_unset_any_variable()
|
||||
var lines =<< trim END
|
||||
|
||||
@@ -906,6 +906,10 @@ func Test_viminfo_oldfiles_newfile()
|
||||
call delete('Xviminfofile')
|
||||
call delete('Xviminfotest')
|
||||
call delete('Xnew-file.txt')
|
||||
|
||||
let v:oldfiles = test_null_list()
|
||||
call assert_equal("\nNo old files", execute('oldfiles'))
|
||||
|
||||
let &viminfo = save_viminfo
|
||||
let &viminfofile = save_viminfofile
|
||||
endfunc
|
||||
|
||||
@@ -970,6 +970,8 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
ui_delay_for_testing = val;
|
||||
else if (STRCMP(name, (char_u *)"term_props") == 0)
|
||||
reset_term_props_on_termresponse = val;
|
||||
else if (STRCMP(name, (char_u *)"uptime") == 0)
|
||||
override_sysinfo_uptime = val;
|
||||
else if (STRCMP(name, (char_u *)"ALL") == 0)
|
||||
{
|
||||
disable_char_avail_for_testing = FALSE;
|
||||
@@ -979,6 +981,7 @@ f_test_override(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
no_query_mouse_for_testing = FALSE;
|
||||
ui_delay_for_testing = 0;
|
||||
reset_term_props_on_termresponse = FALSE;
|
||||
override_sysinfo_uptime = -1;
|
||||
if (save_starting >= 0)
|
||||
{
|
||||
starting = save_starting;
|
||||
|
||||
+22
-8
@@ -1359,9 +1359,12 @@ func_remove(ufunc_T *fp)
|
||||
// function, so we can find the index when defining the function again.
|
||||
// Do remove it when it's a copy.
|
||||
if (fp->uf_def_status == UF_COMPILED && (fp->uf_flags & FC_COPY) == 0)
|
||||
{
|
||||
fp->uf_flags |= FC_DEAD;
|
||||
else
|
||||
hash_remove(&func_hashtab, hi);
|
||||
return FALSE;
|
||||
}
|
||||
hash_remove(&func_hashtab, hi);
|
||||
fp->uf_flags |= FC_DELETED;
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
@@ -2134,11 +2137,23 @@ delete_script_functions(int sid)
|
||||
int changed = func_hashtab.ht_changed;
|
||||
|
||||
fp->uf_flags |= FC_DEAD;
|
||||
func_clear(fp, TRUE);
|
||||
// When clearing a function another function can be cleared
|
||||
// as a side effect. When that happens start over.
|
||||
if (changed != func_hashtab.ht_changed)
|
||||
break;
|
||||
|
||||
if (fp->uf_calls > 0)
|
||||
{
|
||||
// Function is executing, don't free it but do remove
|
||||
// it from the hashtable.
|
||||
if (func_remove(fp))
|
||||
fp->uf_refcount--;
|
||||
}
|
||||
else
|
||||
{
|
||||
func_clear(fp, TRUE);
|
||||
// When clearing a function another function can be
|
||||
// cleared as a side effect. When that happens start
|
||||
// over.
|
||||
if (changed != func_hashtab.ht_changed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
--todo;
|
||||
}
|
||||
@@ -4251,7 +4266,6 @@ ex_delfunction(exarg_T *eap)
|
||||
// do remove it from the hashtable.
|
||||
if (func_remove(fp))
|
||||
fp->uf_refcount--;
|
||||
fp->uf_flags |= FC_DELETED;
|
||||
}
|
||||
else
|
||||
func_clear_free(fp, FALSE);
|
||||
|
||||
@@ -765,6 +765,92 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
2619,
|
||||
/**/
|
||||
2618,
|
||||
/**/
|
||||
2617,
|
||||
/**/
|
||||
2616,
|
||||
/**/
|
||||
2615,
|
||||
/**/
|
||||
2614,
|
||||
/**/
|
||||
2613,
|
||||
/**/
|
||||
2612,
|
||||
/**/
|
||||
2611,
|
||||
/**/
|
||||
2610,
|
||||
/**/
|
||||
2609,
|
||||
/**/
|
||||
2608,
|
||||
/**/
|
||||
2607,
|
||||
/**/
|
||||
2606,
|
||||
/**/
|
||||
2605,
|
||||
/**/
|
||||
2604,
|
||||
/**/
|
||||
2603,
|
||||
/**/
|
||||
2602,
|
||||
/**/
|
||||
2601,
|
||||
/**/
|
||||
2600,
|
||||
/**/
|
||||
2599,
|
||||
/**/
|
||||
2598,
|
||||
/**/
|
||||
2597,
|
||||
/**/
|
||||
2596,
|
||||
/**/
|
||||
2595,
|
||||
/**/
|
||||
2594,
|
||||
/**/
|
||||
2593,
|
||||
/**/
|
||||
2592,
|
||||
/**/
|
||||
2591,
|
||||
/**/
|
||||
2590,
|
||||
/**/
|
||||
2589,
|
||||
/**/
|
||||
2588,
|
||||
/**/
|
||||
2587,
|
||||
/**/
|
||||
2586,
|
||||
/**/
|
||||
2585,
|
||||
/**/
|
||||
2584,
|
||||
/**/
|
||||
2583,
|
||||
/**/
|
||||
2582,
|
||||
/**/
|
||||
2581,
|
||||
/**/
|
||||
2580,
|
||||
/**/
|
||||
2579,
|
||||
/**/
|
||||
2578,
|
||||
/**/
|
||||
2577,
|
||||
/**/
|
||||
2576,
|
||||
/**/
|
||||
|
||||
@@ -1208,6 +1208,7 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
||||
#define OPT_WINONLY 0x10 // only set window-local options
|
||||
#define OPT_NOWIN 0x20 // don't set window-local options
|
||||
#define OPT_ONECOLUMN 0x40 // list options one per line
|
||||
#define OPT_NO_REDRAW 0x80 // ignore redraw flags on option
|
||||
|
||||
// Magic chars used in confirm dialog strings
|
||||
#define DLG_BUTTON_SEP '\n'
|
||||
@@ -2712,4 +2713,9 @@ long elapsed(DWORD start_tick);
|
||||
#define MCH_DELAY_IGNOREINPUT 1
|
||||
#define MCH_DELAY_SETTMODE 2
|
||||
|
||||
// Flags for eval_variable().
|
||||
#define EVAL_VAR_VERBOSE 1 // may give error message
|
||||
#define EVAL_VAR_NOAUTOLOAD 2 // do not use script autoloading
|
||||
#define EVAL_VAR_IMPORT 4 // may return special variable for import
|
||||
|
||||
#endif // VIM__H
|
||||
|
||||
+54
-28
@@ -391,19 +391,29 @@ variable_exists(char_u *name, size_t len, cctx_T *cctx)
|
||||
* imported or function.
|
||||
*/
|
||||
static int
|
||||
item_exists(char_u *name, size_t len, cctx_T *cctx)
|
||||
item_exists(char_u *name, size_t len, int cmd UNUSED, cctx_T *cctx)
|
||||
{
|
||||
int is_global;
|
||||
char_u *p;
|
||||
|
||||
if (variable_exists(name, len, cctx))
|
||||
return TRUE;
|
||||
|
||||
// Find a function, so that a following "->" works. Skip "g:" before a
|
||||
// function name.
|
||||
// Do not check for an internal function, since it might also be a
|
||||
// valid command, such as ":split" versuse "split()".
|
||||
is_global = (name[0] == 'g' && name[1] == ':');
|
||||
return find_func(is_global ? name + 2 : name, is_global, cctx) != NULL;
|
||||
// This is similar to what is in lookup_scriptitem():
|
||||
// Find a function, so that a following "->" works.
|
||||
// Require "(" or "->" to follow, "Cmd" is a user command while "Cmd()" is
|
||||
// a function call.
|
||||
p = skipwhite(name + len);
|
||||
|
||||
if (name[len] == '(' || (p[0] == '-' && p[1] == '>'))
|
||||
{
|
||||
// Do not check for an internal function, since it might also be a
|
||||
// valid command, such as ":split" versuse "split()".
|
||||
// Skip "g:" before a function name.
|
||||
is_global = (name[0] == 'g' && name[1] == ':');
|
||||
return find_func(is_global ? name + 2 : name, is_global, cctx) != NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -2645,7 +2655,8 @@ compile_load_scriptvar(
|
||||
cc = *p;
|
||||
*p = NUL;
|
||||
|
||||
idx = find_exported(import->imp_sid, exp_name, &ufunc, &type, cctx);
|
||||
idx = find_exported(import->imp_sid, exp_name, &ufunc, &type,
|
||||
cctx, TRUE);
|
||||
*p = cc;
|
||||
p = skipwhite(p);
|
||||
|
||||
@@ -4184,7 +4195,7 @@ compile_expr7(
|
||||
* "null" constant
|
||||
*/
|
||||
case 'n': if (STRNCMP(*arg, "null", 4) == 0
|
||||
&& !eval_isnamec((*arg)[5]))
|
||||
&& !eval_isnamec((*arg)[4]))
|
||||
{
|
||||
*arg += 4;
|
||||
rettv->v_type = VAR_SPECIAL;
|
||||
@@ -4450,7 +4461,7 @@ compile_expr6(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
}
|
||||
|
||||
/*
|
||||
* + number addition
|
||||
* + number addition or list/blobl concatenation
|
||||
* - number subtraction
|
||||
* .. string concatenation
|
||||
*/
|
||||
@@ -4532,6 +4543,7 @@ compile_expr5(char_u **arg, cctx_T *cctx, ppconst_T *ppconst)
|
||||
else
|
||||
{
|
||||
generate_ppconst(cctx, ppconst);
|
||||
ppconst->pp_is_const = FALSE;
|
||||
if (*op == '.')
|
||||
{
|
||||
if (may_generate_2STRING(-2, cctx) == FAIL
|
||||
@@ -5171,6 +5183,21 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
||||
r = eap->skip ? OK : FAIL;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
// copy over the block scope IDs before compiling
|
||||
if (!is_global && cctx->ctx_ufunc->uf_block_depth > 0)
|
||||
{
|
||||
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
||||
|
||||
ufunc->uf_block_ids = ALLOC_MULT(int, block_depth);
|
||||
if (ufunc->uf_block_ids != NULL)
|
||||
{
|
||||
mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids,
|
||||
sizeof(int) * block_depth);
|
||||
ufunc->uf_block_depth = block_depth;
|
||||
}
|
||||
}
|
||||
|
||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
|
||||
== FAIL)
|
||||
@@ -5197,25 +5224,12 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
||||
// Define a local variable for the function reference.
|
||||
lvar_T *lvar = reserve_local(cctx, name_start, name_end - name_start,
|
||||
TRUE, ufunc->uf_func_type);
|
||||
int block_depth = cctx->ctx_ufunc->uf_block_depth;
|
||||
|
||||
if (lvar == NULL)
|
||||
goto theend;
|
||||
if (generate_FUNCREF(cctx, ufunc) == FAIL)
|
||||
goto theend;
|
||||
r = generate_STORE(cctx, ISN_STORE, lvar->lv_idx, NULL);
|
||||
|
||||
// copy over the block scope IDs
|
||||
if (block_depth > 0)
|
||||
{
|
||||
ufunc->uf_block_ids = ALLOC_MULT(int, block_depth);
|
||||
if (ufunc->uf_block_ids != NULL)
|
||||
{
|
||||
mch_memmove(ufunc->uf_block_ids, cctx->ctx_ufunc->uf_block_ids,
|
||||
sizeof(int) * block_depth);
|
||||
ufunc->uf_block_depth = block_depth;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: warning for trailing text?
|
||||
|
||||
@@ -5818,11 +5832,13 @@ compile_lhs(
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
// new local variable
|
||||
// Check the name is valid for a funcref.
|
||||
if ((lhs->lhs_type->tt_type == VAR_FUNC
|
||||
|| lhs->lhs_type->tt_type == VAR_PARTIAL)
|
||||
&& var_wrong_func_name(lhs->lhs_name, TRUE))
|
||||
&& var_wrong_func_name(lhs->lhs_name, TRUE))
|
||||
return FAIL;
|
||||
|
||||
// New local variable.
|
||||
lhs->lhs_lvar = reserve_local(cctx, var_start, lhs->lhs_varlen,
|
||||
cmdidx == CMD_final || cmdidx == CMD_const, lhs->lhs_type);
|
||||
if (lhs->lhs_lvar == NULL)
|
||||
@@ -6261,6 +6277,7 @@ compile_assignment(char_u *arg, exarg_T *eap, cmdidx_T cmdidx, cctx_T *cctx)
|
||||
{
|
||||
if ((rhs_type->tt_type == VAR_FUNC
|
||||
|| rhs_type->tt_type == VAR_PARTIAL)
|
||||
&& !lhs.lhs_has_index
|
||||
&& var_wrong_func_name(lhs.lhs_name, TRUE))
|
||||
goto theend;
|
||||
|
||||
@@ -8198,6 +8215,7 @@ compile_def_function(
|
||||
{
|
||||
int count = ufunc->uf_def_args.ga_len;
|
||||
int first_def_arg = ufunc->uf_args.ga_len - count;
|
||||
int uf_args_len = ufunc->uf_args.ga_len;
|
||||
int i;
|
||||
char_u *arg;
|
||||
int off = STACK_FRAME_SIZE + (ufunc->uf_va_name != NULL ? 1 : 0);
|
||||
@@ -8210,16 +8228,24 @@ compile_def_function(
|
||||
ufunc->uf_def_arg_idx = ALLOC_CLEAR_MULT(int, count + 1);
|
||||
if (ufunc->uf_def_arg_idx == NULL)
|
||||
goto erret;
|
||||
SOURCING_LNUM = 0; // line number unknown
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
garray_T *stack = &cctx.ctx_type_stack;
|
||||
type_T *val_type;
|
||||
int arg_idx = first_def_arg + i;
|
||||
where_T where;
|
||||
int r;
|
||||
|
||||
// Make sure later arguments are not found.
|
||||
ufunc->uf_args.ga_len = i;
|
||||
|
||||
ufunc->uf_def_arg_idx[i] = instr->ga_len;
|
||||
arg = ((char_u **)(ufunc->uf_def_args.ga_data))[i];
|
||||
if (compile_expr0(&arg, &cctx) == FAIL)
|
||||
r = compile_expr0(&arg, &cctx);
|
||||
|
||||
ufunc->uf_args.ga_len = uf_args_len;
|
||||
if (r == FAIL)
|
||||
goto erret;
|
||||
|
||||
// If no type specified use the type of the default value.
|
||||
@@ -8418,8 +8444,8 @@ compile_def_function(
|
||||
}
|
||||
}
|
||||
}
|
||||
p = find_ex_command(&ea, NULL, starts_with_colon ? NULL
|
||||
: (int (*)(char_u *, size_t, cctx_T *))item_exists, &cctx);
|
||||
p = find_ex_command(&ea, NULL, starts_with_colon
|
||||
? NULL : item_exists, &cctx);
|
||||
|
||||
if (p == NULL)
|
||||
{
|
||||
|
||||
+37
-18
@@ -30,7 +30,7 @@ typedef struct {
|
||||
int tcd_finally_idx; // instruction of the :finally block or zero
|
||||
int tcd_endtry_idx; // instruction of the :endtry
|
||||
int tcd_caught; // catch block entered
|
||||
int tcd_cont; // :continue encountered, jump here
|
||||
int tcd_cont; // :continue encountered, jump here (minus one)
|
||||
int tcd_return; // when TRUE return from end of :finally
|
||||
} trycmd_T;
|
||||
|
||||
@@ -323,6 +323,8 @@ call_dfunc(int cdf_idx, partial_T *pt, int argcount_arg, ectx_T *ectx)
|
||||
else
|
||||
ectx->ec_outer = NULL;
|
||||
|
||||
++ufunc->uf_calls;
|
||||
|
||||
// Set execution state to the start of the called function.
|
||||
ectx->ec_dfunc_idx = cdf_idx;
|
||||
ectx->ec_instr = INSTRUCTIONS(dfunc);
|
||||
@@ -556,6 +558,9 @@ func_return(ectx_T *ectx)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// TODO: when is it safe to delete the function when it is no longer used?
|
||||
--dfunc->df_ufunc->uf_calls;
|
||||
|
||||
// execution context goes one level up
|
||||
entry = estack_pop();
|
||||
if (entry != NULL)
|
||||
@@ -807,9 +812,12 @@ call_by_name(char_u *name, int argcount, ectx_T *ectx, isn_T *iptr)
|
||||
// types are correct.
|
||||
for (i = 0; i < argcount; ++i)
|
||||
{
|
||||
type_T *type = i < ufunc->uf_args.ga_len
|
||||
? ufunc->uf_arg_types[i] : ufunc->uf_va_type;
|
||||
type_T *type = NULL;
|
||||
|
||||
if (i < ufunc->uf_args.ga_len)
|
||||
type = ufunc->uf_arg_types[i];
|
||||
else if (ufunc->uf_va_type != NULL)
|
||||
type = ufunc->uf_va_type->tt_member;
|
||||
if (type != NULL && check_typval_arg_type(type,
|
||||
&argv[i], i + 1) == FAIL)
|
||||
return FAIL;
|
||||
@@ -982,8 +990,9 @@ allocate_if_null(typval_T *tv)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the character "str[index]" where "index" is the character index. If
|
||||
* "index" is out of range NULL is returned.
|
||||
* Return the character "str[index]" where "index" is the character index,
|
||||
* including composing characters.
|
||||
* If "index" is out of range NULL is returned.
|
||||
*/
|
||||
char_u *
|
||||
char_from_string(char_u *str, varnumber_T index)
|
||||
@@ -1002,7 +1011,7 @@ char_from_string(char_u *str, varnumber_T index)
|
||||
int clen = 0;
|
||||
|
||||
for (nbyte = 0; nbyte < slen; ++clen)
|
||||
nbyte += MB_CPTR2LEN(str + nbyte);
|
||||
nbyte += mb_ptr2len(str + nbyte);
|
||||
nchar = clen + index;
|
||||
if (nchar < 0)
|
||||
// unlike list: index out of range results in empty string
|
||||
@@ -1010,15 +1019,15 @@ char_from_string(char_u *str, varnumber_T index)
|
||||
}
|
||||
|
||||
for (nbyte = 0; nchar > 0 && nbyte < slen; --nchar)
|
||||
nbyte += MB_CPTR2LEN(str + nbyte);
|
||||
nbyte += mb_ptr2len(str + nbyte);
|
||||
if (nbyte >= slen)
|
||||
return NULL;
|
||||
return vim_strnsave(str + nbyte, MB_CPTR2LEN(str + nbyte));
|
||||
return vim_strnsave(str + nbyte, mb_ptr2len(str + nbyte));
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the byte index for character index "idx" in string "str" with length
|
||||
* "str_len".
|
||||
* "str_len". Composing characters are included.
|
||||
* If going over the end return "str_len".
|
||||
* If "idx" is negative count from the end, -1 is the last character.
|
||||
* When going over the start return -1.
|
||||
@@ -1033,7 +1042,7 @@ char_idx2byte(char_u *str, size_t str_len, varnumber_T idx)
|
||||
{
|
||||
while (nchar > 0 && nbyte < str_len)
|
||||
{
|
||||
nbyte += MB_CPTR2LEN(str + nbyte);
|
||||
nbyte += mb_ptr2len(str + nbyte);
|
||||
--nchar;
|
||||
}
|
||||
}
|
||||
@@ -1053,7 +1062,8 @@ char_idx2byte(char_u *str, size_t str_len, varnumber_T idx)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the slice "str[first:last]" using character indexes.
|
||||
* Return the slice "str[first : last]" using character indexes. Composing
|
||||
* characters are included.
|
||||
* "exclusive" is TRUE for slice().
|
||||
* Return NULL when the result is empty.
|
||||
*/
|
||||
@@ -1076,7 +1086,7 @@ string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive)
|
||||
end_byte = char_idx2byte(str, slen, last);
|
||||
if (!exclusive && end_byte >= 0 && end_byte < (long)slen)
|
||||
// end index is inclusive
|
||||
end_byte += MB_CPTR2LEN(str + end_byte);
|
||||
end_byte += mb_ptr2len(str + end_byte);
|
||||
}
|
||||
|
||||
if (start_byte >= (long)slen || end_byte <= start_byte)
|
||||
@@ -1329,7 +1339,7 @@ call_def_function(
|
||||
++ectx.ec_stack.ga_len;
|
||||
}
|
||||
if (ufunc->uf_va_name != NULL)
|
||||
++ectx.ec_stack.ga_len;
|
||||
++ectx.ec_stack.ga_len;
|
||||
|
||||
// Frame pointer points to just after arguments.
|
||||
ectx.ec_frame_idx = ectx.ec_stack.ga_len;
|
||||
@@ -1402,6 +1412,9 @@ call_def_function(
|
||||
// Do turn errors into exceptions.
|
||||
suppress_errthrow = FALSE;
|
||||
|
||||
// Do not delete the function while executing it.
|
||||
++ufunc->uf_calls;
|
||||
|
||||
// When ":silent!" was used before calling then we still abort the
|
||||
// function. If ":silent!" is used in the function then we don't.
|
||||
emsg_silent_def = emsg_silent;
|
||||
@@ -1762,7 +1775,7 @@ call_def_function(
|
||||
goto failed;
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
if (eval_variable(name, (int)STRLEN(name),
|
||||
STACK_TV_BOT(0), NULL, TRUE, FALSE) == FAIL)
|
||||
STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL)
|
||||
goto on_error;
|
||||
++ectx.ec_stack.ga_len;
|
||||
}
|
||||
@@ -2754,7 +2767,9 @@ call_def_function(
|
||||
{
|
||||
trycmd = ((trycmd_T *)trystack->ga_data)
|
||||
+ trystack->ga_len - i;
|
||||
trycmd->tcd_cont = iidx;
|
||||
// Add one to tcd_cont to be able to jump to
|
||||
// instruction with index zero.
|
||||
trycmd->tcd_cont = iidx + 1;
|
||||
iidx = trycmd->tcd_finally_idx == 0
|
||||
? trycmd->tcd_endtry_idx : trycmd->tcd_finally_idx;
|
||||
}
|
||||
@@ -2808,7 +2823,7 @@ call_def_function(
|
||||
if (trycmd->tcd_cont != 0)
|
||||
// handling :continue: jump to outer try block or
|
||||
// start of the loop
|
||||
ectx.ec_iidx = trycmd->tcd_cont;
|
||||
ectx.ec_iidx = trycmd->tcd_cont - 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -3244,8 +3259,9 @@ call_def_function(
|
||||
res = string_slice(tv->vval.v_string, n1, n2, FALSE);
|
||||
else
|
||||
// Index: The resulting variable is a string of a
|
||||
// single character. If the index is too big or
|
||||
// negative the result is empty.
|
||||
// single character (including composing characters).
|
||||
// If the index is too big or negative the result is
|
||||
// empty.
|
||||
res = char_from_string(tv->vval.v_string, n2);
|
||||
vim_free(tv->vval.v_string);
|
||||
tv->vval.v_string = res;
|
||||
@@ -3830,6 +3846,9 @@ failed:
|
||||
estack_pop();
|
||||
current_sctx = save_current_sctx;
|
||||
|
||||
// TODO: when is it safe to delete the function if it is no longer used?
|
||||
--ufunc->uf_calls;
|
||||
|
||||
if (*msg_list != NULL && saved_msg_list != NULL)
|
||||
{
|
||||
msglist_T **plist = saved_msg_list;
|
||||
|
||||
+9
-5
@@ -75,7 +75,7 @@ ex_vim9script(exarg_T *eap UNUSED)
|
||||
if (STRCMP(p_cpo, CPO_VIM) != 0)
|
||||
{
|
||||
si->sn_save_cpo = vim_strsave(p_cpo);
|
||||
set_option_value((char_u *)"cpo", 0L, (char_u *)CPO_VIM, 0);
|
||||
set_option_value((char_u *)"cpo", 0L, (char_u *)CPO_VIM, OPT_NO_REDRAW);
|
||||
}
|
||||
#else
|
||||
// No check for this being the first command, it doesn't matter.
|
||||
@@ -102,6 +102,7 @@ not_in_vim9(exarg_T *eap)
|
||||
case CMD_append:
|
||||
case CMD_change:
|
||||
case CMD_insert:
|
||||
case CMD_open:
|
||||
case CMD_t:
|
||||
case CMD_xit:
|
||||
semsg(_(e_command_not_supported_in_vim9_script_missing_var_str), eap->cmd);
|
||||
@@ -257,7 +258,8 @@ find_exported(
|
||||
char_u *name,
|
||||
ufunc_T **ufunc,
|
||||
type_T **type,
|
||||
cctx_T *cctx)
|
||||
cctx_T *cctx,
|
||||
int verbose)
|
||||
{
|
||||
int idx = -1;
|
||||
svar_T *sv;
|
||||
@@ -271,7 +273,8 @@ find_exported(
|
||||
sv = ((svar_T *)script->sn_var_vals.ga_data) + idx;
|
||||
if (!sv->sv_export)
|
||||
{
|
||||
semsg(_(e_item_not_exported_in_script_str), name);
|
||||
if (verbose)
|
||||
semsg(_(e_item_not_exported_in_script_str), name);
|
||||
return -1;
|
||||
}
|
||||
*type = sv->sv_type;
|
||||
@@ -301,7 +304,8 @@ find_exported(
|
||||
|
||||
if (*ufunc == NULL)
|
||||
{
|
||||
semsg(_(e_item_not_found_in_script_str), name);
|
||||
if (verbose)
|
||||
semsg(_(e_item_not_found_in_script_str), name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -532,7 +536,7 @@ handle_import(
|
||||
ufunc_T *ufunc = NULL;
|
||||
type_T *type;
|
||||
|
||||
idx = find_exported(sid, name, &ufunc, &type, cctx);
|
||||
idx = find_exported(sid, name, &ufunc, &type, cctx, TRUE);
|
||||
|
||||
if (idx < 0 && ufunc == NULL)
|
||||
goto erret;
|
||||
|
||||
+4
-2
@@ -919,6 +919,8 @@ equal_type(type_T *type1, type_T *type2)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (type1 == NULL || type2 == NULL)
|
||||
return FALSE;
|
||||
if (type1->tt_type != type2->tt_type)
|
||||
return FALSE;
|
||||
switch (type1->tt_type)
|
||||
@@ -969,12 +971,12 @@ common_type(type_T *type1, type_T *type2, type_T **dest, garray_T *type_gap)
|
||||
|
||||
// If either is VAR_UNKNOWN use the other type. An empty list/dict has no
|
||||
// specific type.
|
||||
if (type1->tt_type == VAR_UNKNOWN)
|
||||
if (type1 == NULL || type1->tt_type == VAR_UNKNOWN)
|
||||
{
|
||||
*dest = type2;
|
||||
return;
|
||||
}
|
||||
if (type2->tt_type == VAR_UNKNOWN)
|
||||
if (type2 == NULL || type2->tt_type == VAR_UNKNOWN)
|
||||
{
|
||||
*dest = type1;
|
||||
return;
|
||||
|
||||
+2
-2
@@ -5865,8 +5865,8 @@ win_setminheight(void)
|
||||
// loop until there is a 'winminheight' that is possible
|
||||
while (p_wmh > 0)
|
||||
{
|
||||
room = Rows - p_ch - tabline_height();
|
||||
needed = frame_minheight(topframe, NULL);
|
||||
room = Rows - p_ch;
|
||||
needed = min_rows() - 1; // 1 was added for the cmdline
|
||||
if (room >= needed)
|
||||
break;
|
||||
--p_wmh;
|
||||
|
||||
Reference in New Issue
Block a user