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:
@@ -4,6 +4,12 @@
|
||||
|
||||
<sub>For translations of this README see the end.</sub>
|
||||
|
||||
If you find a bug or want to discuss the best way to add a new feature, please
|
||||
open an [issue](https://github.com/vim/vim/issues).
|
||||
If you have a question or want to discuss the best way to do something with
|
||||
Vim, you can use [StackExchange](https://vi.stackexchange.com/)
|
||||
or one of the [Maillists](https://www.vim.org/community.php).
|
||||
|
||||
|
||||
## What is Vim? ##
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ effects. Be careful not to destroy your text.
|
||||
:au[tocmd] [group] {event} {pat} [++once] [++nested] {cmd}
|
||||
Add {cmd} to the list of commands that Vim will
|
||||
execute automatically on {event} for a file matching
|
||||
{pat} |autocmd-patterns|.
|
||||
{pat} |autocmd-patterns|.
|
||||
Here {event} cannot be "*". *E1155*
|
||||
Note: A quote character is seen as argument to the
|
||||
:autocmd and won't start a comment.
|
||||
|
||||
+13
-2
@@ -1,4 +1,4 @@
|
||||
*change.txt* For Vim version 8.2. Last change: 2021 Mar 01
|
||||
*change.txt* For Vim version 8.2. Last change: 2021 Jun 10
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -1042,6 +1042,10 @@ inside of strings can change! Also see 'softtabstop' option. >
|
||||
cursor to the end of line (which is more logical,
|
||||
but not Vi-compatible) use ":map Y y$".
|
||||
|
||||
*zy*
|
||||
["x]zy{motion} Yank {motion} text [into register x]. Only differs
|
||||
from `y` when selecting a block of text, see |v_zy|.
|
||||
|
||||
*v_y*
|
||||
{Visual}["x]y Yank the highlighted text [into register x] (for
|
||||
{Visual} see |Visual-mode|).
|
||||
@@ -1050,6 +1054,12 @@ inside of strings can change! Also see 'softtabstop' option. >
|
||||
{Visual}["x]Y Yank the highlighted lines [into register x] (for
|
||||
{Visual} see |Visual-mode|).
|
||||
|
||||
*v_zy*
|
||||
{Visual}["x]zy Yank the highlighted text [into register x]. Trailing
|
||||
whitespace at the end of each line of a selected block
|
||||
won't be yanked. Especially useful in combination
|
||||
with `zp`. (for {Visual} see |Visual-mode|)
|
||||
|
||||
*:y* *:yank* *E850*
|
||||
:[range]y[ank] [x] Yank [range] lines [into register x]. Yanking to the
|
||||
"* or "+ registers is possible only when the
|
||||
@@ -1129,7 +1139,8 @@ inside of strings can change! Also see 'softtabstop' option. >
|
||||
["x]zp or *zp* *zP*
|
||||
["x]zP Like "p" and "P", except without adding trailing spaces
|
||||
when pasting a block. Thus the inserted text will not
|
||||
always be a rectangle.
|
||||
always be a rectangle. Especially useful in
|
||||
combination with |v_zy|.
|
||||
|
||||
You can use these commands to copy text from one place to another. Do this
|
||||
by first getting the text into a register with a yank, delete or change
|
||||
|
||||
+16
-16
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 8.2. Last change: 2021 May 07
|
||||
*eval.txt* For Vim version 8.2. Last change: 2021 Jun 07
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -2102,7 +2102,7 @@ v:null An empty String. Used to put "null" in JSON. See
|
||||
v:numbermax Maximum value of a number.
|
||||
|
||||
*v:numbermin* *numbermin-variable*
|
||||
v:numbermin Minimum value of a number (negative)
|
||||
v:numbermin Minimum value of a number (negative).
|
||||
|
||||
*v:numbersize* *numbersize-variable*
|
||||
v:numbersize Number of bits in a Number. This is normally 64, but on some
|
||||
@@ -2520,7 +2520,7 @@ char2nr({expr} [, {utf8}]) Number ASCII/UTF8 value of first char in {expr}
|
||||
charclass({string}) Number character class of {string}
|
||||
charcol({expr}) Number column number of cursor or mark
|
||||
charidx({string}, {idx} [, {countcc}])
|
||||
Number char index of byte {idx} in {string}
|
||||
Number char index of byte {idx} in {string}
|
||||
chdir({dir}) String change current working directory
|
||||
cindent({lnum}) Number C indent for line {lnum}
|
||||
clearmatches([{win}]) none clear all matches
|
||||
@@ -2541,7 +2541,7 @@ cscope_connection([{num}, {dbpath} [, {prepend}]])
|
||||
cursor({lnum}, {col} [, {off}])
|
||||
Number move cursor to {lnum}, {col}, {off}
|
||||
cursor({list}) Number move cursor to position in {list}
|
||||
debugbreak({pid}) Number interrupt process being debugged
|
||||
debugbreak({pid}) Number interrupt process being debugged
|
||||
deepcopy({expr} [, {noref}]) any make a full copy of {expr}
|
||||
delete({fname} [, {flags}]) Number delete the file or directory {fname}
|
||||
deletebufline({expr}, {first} [, {last}])
|
||||
@@ -4963,7 +4963,7 @@ funcref({name} [, {arglist}] [, {dict}])
|
||||
Can also be used as a |method|: >
|
||||
GetFuncname()->funcref([arg])
|
||||
<
|
||||
*function()* *E700* *E922* *E923*
|
||||
*function()* *partial* *E700* *E922* *E923*
|
||||
function({name} [, {arglist}] [, {dict}])
|
||||
Return a |Funcref| variable that refers to function {name}.
|
||||
{name} can be the name of a user defined function or an
|
||||
@@ -5512,8 +5512,8 @@ getcurpos([{winid}])
|
||||
|
||||
Can also be used as a |method|: >
|
||||
GetWinid()->getcurpos()
|
||||
|
||||
< *getcursorcharpos()*
|
||||
<
|
||||
*getcursorcharpos()*
|
||||
getcursorcharpos([{winid}])
|
||||
Same as |getcurpos()| but the column number in the returned
|
||||
List is a character index instead of a byte index.
|
||||
@@ -5522,8 +5522,8 @@ getcursorcharpos([{winid}])
|
||||
With the cursor on '보' in line 3 with text "여보세요": >
|
||||
getcursorcharpos() returns [0, 3, 2, 0, 3]
|
||||
getcurpos() returns [0, 3, 4, 0, 3]
|
||||
|
||||
< Can also be used as a |method|: >
|
||||
<
|
||||
Can also be used as a |method|: >
|
||||
GetWinid()->getcursorcharpos()
|
||||
|
||||
< *getcwd()*
|
||||
@@ -5748,11 +5748,11 @@ getmarklist([{expr}]) *getmarklist()*
|
||||
see |bufname()|.
|
||||
|
||||
Each item in the returned List is a |Dict| with the following:
|
||||
name - name of the mark prefixed by "'"
|
||||
pos - a |List| with the position of the mark:
|
||||
mark name of the mark prefixed by "'"
|
||||
pos a |List| with the position of the mark:
|
||||
[bufnum, lnum, col, off]
|
||||
Refer to |getpos()| for more information.
|
||||
file - file name
|
||||
Refer to |getpos()| for more information.
|
||||
file file name
|
||||
|
||||
Refer to |getpos()| for getting information about a specific
|
||||
mark.
|
||||
@@ -5834,7 +5834,7 @@ getpos({expr}) Get the position for {expr}. For possible values of {expr}
|
||||
'> is a large number.
|
||||
The column number in the returned List is the byte position
|
||||
within the line. To get the character position in the line,
|
||||
use |getcharpos()|
|
||||
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: >
|
||||
@@ -7649,7 +7649,7 @@ matchfuzzypos({list}, {str} [, {dict}]) *matchfuzzypos()*
|
||||
Same as |matchfuzzy()|, but returns the list of matched
|
||||
strings, the list of character positions where characters
|
||||
in {str} matches and a list of matching scores. You can
|
||||
use |byteidx()|to convert a character position to a byte
|
||||
use |byteidx()| to convert a character position to a byte
|
||||
position.
|
||||
|
||||
If {str} matches multiple times in a string, then only the
|
||||
@@ -9973,7 +9973,7 @@ sinh({expr}) *sinh()*
|
||||
{only available when compiled with the |+float| feature}
|
||||
|
||||
|
||||
slice({expr}, {start} [, {end}]) *slice()*
|
||||
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
|
||||
|
||||
@@ -632,7 +632,7 @@ For fish, add to the config file
|
||||
MARKDOWN *ft-markdown-plugin*
|
||||
|
||||
To enable folding use this: >
|
||||
let g:markdown_folding = 1
|
||||
let g:markdown_folding = 1
|
||||
<
|
||||
|
||||
PDF *ft-pdf-plugin*
|
||||
|
||||
@@ -45,7 +45,7 @@ Numbers, subscripts and superscripts are available with 's' and 'S':
|
||||
1s ₁ 1S ¹ ~
|
||||
2s ₂ 9S ⁹ ~
|
||||
|
||||
But some don´t come defined by default. Those are digraph definitions you can
|
||||
But some don't come defined by default. Those are digraph definitions you can
|
||||
add in your ~/.vimrc file. >
|
||||
exec 'digraph \\ '.char2nr('∖')
|
||||
exec 'digraph \< '.char2nr('≼')
|
||||
|
||||
@@ -132,7 +132,7 @@ Advanced editing ~
|
||||
|windows.txt| commands for using multiple windows and buffers
|
||||
|tabpage.txt| commands for using multiple tab pages
|
||||
|spell.txt| spell checking
|
||||
|diff.txt| working with two to four versions of the same file
|
||||
|diff.txt| working with two to eight versions of the same file
|
||||
|autocmd.txt| automatically executing commands on an event
|
||||
|eval.txt| expression evaluation, conditional commands
|
||||
|channel.txt| Jobs, Channels, inter-process communication
|
||||
@@ -145,6 +145,7 @@ Special issues ~
|
||||
|term.txt| using different terminals and mice
|
||||
|terminal.txt| Terminal window support
|
||||
|popup.txt| popup window support
|
||||
|vim9.txt| using Vim9 script
|
||||
|
||||
Programming language support ~
|
||||
|indent.txt| automatic indenting for C and other languages
|
||||
@@ -153,6 +154,8 @@ Programming language support ~
|
||||
|filetype.txt| settings done specifically for a type of file
|
||||
|quickfix.txt| commands for a quick edit-compile-fix cycle
|
||||
|ft_ada.txt| Ada (the programming language) support
|
||||
|ft_ps1.txt| Filetype plugin for Windows PowerShell
|
||||
|ft_raku.txt| Filetype plugin for Raku
|
||||
|ft_rust.txt| Filetype plugin for Rust
|
||||
|ft_sql.txt| about the SQL filetype plugin
|
||||
|
||||
|
||||
@@ -878,6 +878,7 @@ tag char note action in Normal mode ~
|
||||
|zv| zv open enough folds to view the cursor line
|
||||
|zw| zw permanently mark word as incorrectly spelled
|
||||
|zx| zx re-apply 'foldlevel' and do "zv"
|
||||
|zy| zy yank without trailing spaces
|
||||
|zz| zz redraw, cursor line at center of window
|
||||
|z<Left>| z<Left> same as "zh"
|
||||
|z<Right>| z<Right> same as "zl"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*motion.txt* For Vim version 8.2. Last change: 2021 Mar 28
|
||||
*motion.txt* For Vim version 8.2. Last change: 2021 Jun 13
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -59,9 +59,14 @@ or change text. The following operators are available:
|
||||
|<| < shift left
|
||||
|zf| zf define a fold
|
||||
|g@| g@ call function set with the 'operatorfunc' option
|
||||
|
||||
*motion-count-multiplied*
|
||||
If the motion includes a count and the operator also had a count before it,
|
||||
the two counts are multiplied. For example: "2d3w" deletes six words.
|
||||
*operator-doubled*
|
||||
When doubling the operator it operates on a line. When using a count, before
|
||||
or after the first character, that many lines are operated upon. Thus `3dd`
|
||||
deletes three lines. A count before and after the first character is
|
||||
multiplied, thus `2y3y` yanks six lines.
|
||||
|
||||
After applying the operator the cursor is mostly left at the start of the text
|
||||
that was operated upon. For example, "yfe" doesn't move the cursor, but "yFe"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*options.txt* For Vim version 8.2. Last change: 2021 May 16
|
||||
*options.txt* For Vim version 8.2. Last change: 2021 May 31
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
|
||||
@@ -767,12 +767,12 @@ GNU_TOOLS.ZIP package downloadable from http://www.polarhome.com/vim/
|
||||
|
||||
Version 8.2
|
||||
- make all changes needed for clean compile build of v8.2 on VMS on all platforms
|
||||
- fix the call mkdir bug (vicente_polo@yahoo.es)
|
||||
- fix the call mkdir bug (vicente_polo@yahoo.es)
|
||||
- test on VSI OpenVMS Alpha and Itanium platforms
|
||||
- added LUA support
|
||||
- added XPM support - Motif GUI with toolbar on all platforms
|
||||
- XPM v3.4.11 libraries for IA64, AXP and VAX are added
|
||||
- start integrating the new test scripts
|
||||
- XPM v3.4.11 libraries for IA64, AXP and VAX are added
|
||||
- start integrating the new test scripts
|
||||
|
||||
Version 8.1
|
||||
- make necessary changes to build v8.1 on VMS
|
||||
|
||||
@@ -1217,7 +1217,7 @@ x A single character, with no special meaning, matches itself
|
||||
|
||||
\%d123 Matches the character specified with a decimal number. Must be
|
||||
followed by a non-digit.
|
||||
\%o40 Matches the character specified with an octal number up to 0377.
|
||||
\%o40 Matches the character specified with an octal number up to 0o377.
|
||||
Numbers below 0o40 must be followed by a non-octal digit or a
|
||||
non-digit.
|
||||
\%x2a Matches the character specified with up to two hexadecimal characters.
|
||||
|
||||
@@ -3809,7 +3809,7 @@ netrw:
|
||||
Decho.vim is provided as a "vimball"; see |vimball-intro|. You
|
||||
should edit the Decho.vba.gz file and source it in: >
|
||||
|
||||
vim Decho.vba.gz
|
||||
vim Decho.vba.gz
|
||||
:so %
|
||||
:q
|
||||
<
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*repeat.txt* For Vim version 8.2. Last change: 2021 May 08
|
||||
*repeat.txt* For Vim version 8.2. Last change: 2021 Jun 11
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -279,7 +279,9 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
ftdetect scripts are loaded, only the matching
|
||||
directories are added to 'runtimepath'. This is
|
||||
useful in your .vimrc. The plugins will then be
|
||||
loaded during initialization, see |load-plugins|.
|
||||
loaded during initialization, see |load-plugins| (note
|
||||
that the loading order will be reversed, because each
|
||||
directory is inserted before others).
|
||||
Note that for ftdetect scripts to be loaded
|
||||
you will need to write `filetype plugin indent on`
|
||||
AFTER all `packadd!` commands.
|
||||
@@ -372,7 +374,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|.
|
||||
for some commands.
|
||||
See |:vim9cmd| for executing one command with Vim9
|
||||
syntax and semantics.
|
||||
|
||||
|
||||
*:scr* *:scriptnames*
|
||||
:scr[iptnames] List all sourced script names, in the order they were
|
||||
first sourced. The number is used for the script ID
|
||||
|
||||
@@ -3430,8 +3430,8 @@ syntax highlighting script handles this with the following logic:
|
||||
Tex: Match Check Control~
|
||||
|
||||
Sometimes one actually wants mismatched parentheses, square braces,
|
||||
and or curly braces; for example, \text{(1,10] is a range from but
|
||||
not including 1 to and including 10}. This wish, of course, conflicts
|
||||
and or curly braces; for example, \text{(1,10]} is a range from but
|
||||
not including 1 to and including 10. This wish, of course, conflicts
|
||||
with the desire to provide delimiter mismatch detection. To
|
||||
accommodate these conflicting goals, syntax/tex.vim provides >
|
||||
g:tex_matchcheck = '[({[]'
|
||||
@@ -4084,7 +4084,7 @@ match in the same position overrules an earlier one). The "transparent"
|
||||
argument makes the "myVim" match use the same highlighting as "myString". But
|
||||
it does not contain anything. If the "contains=NONE" argument would be left
|
||||
out, then "myVim" would use the contains argument from myString and allow
|
||||
"myWord" to be contained, which will be highlighted as a Constant. This
|
||||
"myWord" to be contained, which will be highlighted as a Comment. This
|
||||
happens because a contained match doesn't match inside itself in the same
|
||||
position, thus the "myVim" match doesn't overrule the "myWord" match here.
|
||||
|
||||
@@ -4970,8 +4970,8 @@ ctermul={color-nr} *highlight-ctermul*
|
||||
*tmux*
|
||||
When using tmux you may want to use this in the tmux config: >
|
||||
# tmux colors
|
||||
set -g default-terminal "xterm-256color"
|
||||
set -ag terminal-overrides ",xterm-256color:Tc"
|
||||
set -s default-terminal "tmux-256color"
|
||||
set -as terminal-overrides ",*-256color:Tc"
|
||||
< More info at:
|
||||
https://github.com/tmux/tmux/wiki/FAQ#how-do-i-use-a-256-colour-terminal
|
||||
https://github.com/tmux/tmux/wiki/FAQ#how-do-i-use-rgb-colour
|
||||
|
||||
@@ -7091,6 +7091,7 @@ getchar() eval.txt /*getchar()*
|
||||
getcharmod() eval.txt /*getcharmod()*
|
||||
getcharpos() eval.txt /*getcharpos()*
|
||||
getcharsearch() eval.txt /*getcharsearch()*
|
||||
getcharstr() eval.txt /*getcharstr()*
|
||||
getcmdline() eval.txt /*getcmdline()*
|
||||
getcmdpos() eval.txt /*getcmdpos()*
|
||||
getcmdtype() eval.txt /*getcmdtype()*
|
||||
@@ -8044,6 +8045,7 @@ moo.vim syntax.txt /*moo.vim*
|
||||
more-compatible version5.txt /*more-compatible*
|
||||
more-prompt message.txt /*more-prompt*
|
||||
more-variables eval.txt /*more-variables*
|
||||
motion-count-multiplied motion.txt /*motion-count-multiplied*
|
||||
motion.txt motion.txt /*motion.txt*
|
||||
mouse-mode-table term.txt /*mouse-mode-table*
|
||||
mouse-overview term.txt /*mouse-overview*
|
||||
@@ -8494,6 +8496,7 @@ omni-sql-completion ft_sql.txt /*omni-sql-completion*
|
||||
online-help helphelp.txt /*online-help*
|
||||
opening-window windows.txt /*opening-window*
|
||||
operator motion.txt /*operator*
|
||||
operator-doubled motion.txt /*operator-doubled*
|
||||
operator-pending-index index.txt /*operator-pending-index*
|
||||
operator-variable eval.txt /*operator-variable*
|
||||
option-backslash options.txt /*option-backslash*
|
||||
@@ -8548,6 +8551,7 @@ page_up intro.txt /*page_up*
|
||||
pager message.txt /*pager*
|
||||
papp.vim syntax.txt /*papp.vim*
|
||||
paragraph motion.txt /*paragraph*
|
||||
partial eval.txt /*partial*
|
||||
pascal.vim syntax.txt /*pascal.vim*
|
||||
patches-8 version8.txt /*patches-8*
|
||||
patches-8.1 version8.txt /*patches-8.1*
|
||||
@@ -10214,6 +10218,7 @@ v_u change.txt /*v_u*
|
||||
v_v visual.txt /*v_v*
|
||||
v_x change.txt /*v_x*
|
||||
v_y change.txt /*v_y*
|
||||
v_zy change.txt /*v_zy*
|
||||
v_~ change.txt /*v_~*
|
||||
vab motion.txt /*vab*
|
||||
val-variable eval.txt /*val-variable*
|
||||
@@ -10584,6 +10589,7 @@ zOS-PuTTY os_390.txt /*zOS-PuTTY*
|
||||
zOS-has-ebcdic os_390.txt /*zOS-has-ebcdic*
|
||||
zOS-limitations os_390.txt /*zOS-limitations*
|
||||
zOS-open-source os_390.txt /*zOS-open-source*
|
||||
zP change.txt /*zP*
|
||||
zR fold.txt /*zR*
|
||||
zW spell.txt /*zW*
|
||||
zX fold.txt /*zX*
|
||||
@@ -10611,6 +10617,7 @@ zl scroll.txt /*zl*
|
||||
zm fold.txt /*zm*
|
||||
zn fold.txt /*zn*
|
||||
zo fold.txt /*zo*
|
||||
zp change.txt /*zp*
|
||||
zr fold.txt /*zr*
|
||||
zs scroll.txt /*zs*
|
||||
zsh.vim syntax.txt /*zsh.vim*
|
||||
@@ -10622,6 +10629,7 @@ zuw spell.txt /*zuw*
|
||||
zv fold.txt /*zv*
|
||||
zw spell.txt /*zw*
|
||||
zx fold.txt /*zx*
|
||||
zy change.txt /*zy*
|
||||
zz scroll.txt /*zz*
|
||||
{ motion.txt /*{*
|
||||
{Visual} intro.txt /*{Visual}*
|
||||
|
||||
@@ -373,10 +373,10 @@ Added by Vim (there are no standard codes for these):
|
||||
t_Ri restore icon text from stack *t_Ri* *'t_Ri'*
|
||||
t_TE end of "raw" mode *t_TE* *'t_TE'*
|
||||
t_TI put terminal into "raw" mode *t_TI* *'t_TI'*
|
||||
t_fd disable focus-event tracking *t_fd* *'t_fd'*
|
||||
|xterm-focus-event|
|
||||
t_fe enable focus-event tracking *t_fe* *'t_fe'*
|
||||
|xterm-focus-event|
|
||||
t_fd disable focus-event tracking *t_fd* *'t_fd'*
|
||||
|xterm-focus-event|
|
||||
|
||||
Some codes have a start, middle and end part. The start and end are defined
|
||||
by the termcap option, the middle part is text.
|
||||
|
||||
+22
-43
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 8.2. Last change: 2021 May 28
|
||||
*todo.txt* For Vim version 8.2. Last change: 2021 Jun 13
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -38,57 +38,30 @@ browser use: https://github.com/vim/vim/issues/1234
|
||||
*known-bugs*
|
||||
-------------------- Known bugs and current work -----------------------
|
||||
|
||||
Geen memory leak?
|
||||
|
||||
Crash using outer var from nested lambda:
|
||||
vim9script
|
||||
def F(text: string): func(string): func(string): string
|
||||
return (arg: string): func(string): string => ((sep: string): string => {
|
||||
return text .. ' ' .. arg
|
||||
})
|
||||
enddef
|
||||
|
||||
echo F('hello')(' ')('there')
|
||||
|
||||
|
||||
|
||||
Vim9 - Make everything work:
|
||||
- function returning nothing should return void instead of zero
|
||||
- compile "expr" and "call" expression of a channel in channel_exe_cmd()?
|
||||
- Need some solution for dict function. Can we implement part of classes?
|
||||
- A lambda without {} does not require a return type, using { return x } does.
|
||||
That's unexpected, since the arguments are not required to have a type.
|
||||
alt 1: not require a return type, figure it out from the common type of all
|
||||
the return statements found
|
||||
alt 2: also require argument types
|
||||
- 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
|
||||
- use CheckLegacyAndVim9Success(lines) in many more places
|
||||
- Make debugging work - at least per function.
|
||||
- How to evaluate the stack and variables on the stack?
|
||||
- FIXME in test_debugger.vim
|
||||
- For builtin functions using tv_get_string*() use check_for_string() to be
|
||||
more strict about the argument type (not a bool).
|
||||
done: balloon_()
|
||||
- Check many more builtin function arguments at compile time.
|
||||
map() could check that the return type of the function argument matches
|
||||
the type of the list or dict member. (#8092)
|
||||
- Allow for using an autoload function name without quotes. It is then loaded
|
||||
(and compiled) right away. #8124
|
||||
- Test more expressions in legacy and Vim9 script, using
|
||||
CheckLegacyAndVim9Success()
|
||||
Same for other functions, such as searchpair().
|
||||
- use CheckLegacyAndVim9Success(lines) in many more places
|
||||
- Test try/catch and throw better, also nested.
|
||||
Test that return inside try/finally jumps to finally and then returns.
|
||||
- Test that a function defined inside a :def function is local to that
|
||||
function, g: functions can be defined and script-local functions cannot be
|
||||
defined.
|
||||
- Make debugging work - at least per function. Need to recompile a function
|
||||
to step through it line-by-line? Evaluate the stack and variables on the
|
||||
stack?
|
||||
- Reserve command for future use: :type, :class, :enum
|
||||
- compile get_lambda_tv() in popup_add_timeout()
|
||||
|
||||
Once Vim9 is stable:
|
||||
- Add the "vim9script" feature, can use has('vim9script')
|
||||
- Change the help to prefer Vim9 syntax where appropriate
|
||||
- Add all the error numbers in a good place in documentation.
|
||||
- In the generic eval docs, point out the Vim9 syntax where it differs.
|
||||
- Add the "vim9script" feature, can use has('vim9script')
|
||||
- Use Vim9 for runtime files.
|
||||
PR #7497 for autoload/ccomplete.vim
|
||||
|
||||
@@ -100,13 +73,12 @@ Further Vim9 improvements, possibly after launch:
|
||||
Give an error if compilation fails. (#7625)
|
||||
Use the location where the option was set for deciding whether it's to be
|
||||
evaluated in Vim9 script context.
|
||||
- implement :type, import type declaration.
|
||||
- implement enum, import enum.
|
||||
- Future work: See |vim9-classes|
|
||||
- implement :type, "import type"
|
||||
- implement enum, "import enum".
|
||||
- implement class and interface: See |vim9-classes|
|
||||
- For range: make table of first ASCII character with flag to quickly check if
|
||||
it can be a Vim9 command. E.g. "+" can, but "." can't.
|
||||
- compile get_lambda_tv() in popup_add_timeout()
|
||||
- inline call to map() and filter()
|
||||
- Inline call to map() and filter(), better type checking.
|
||||
- Make accessing varargs faster: arg[expr]
|
||||
EVAL expr
|
||||
LOADVARARG (varargs idx)
|
||||
@@ -300,6 +272,9 @@ inconsistent with the documentation.
|
||||
Making breakat support multibyte characters (Yasuhiro Matsumoto, #6598)
|
||||
Scroll doesn't work correctly, why?
|
||||
|
||||
glob() and globfile() do not always honor 'wildignorecase'. #8350
|
||||
globpath() does not use 'wildignorecase' at all?
|
||||
|
||||
Add 'termguiattr' option, use "gui=" attributes in the terminal? Would work
|
||||
with 'termguicolors'. #1740
|
||||
|
||||
@@ -344,6 +319,9 @@ Should also work without any group:
|
||||
:echo matchstr('aaa bbb', '.\{-1,}\>\|.*')
|
||||
aaa bbb (should be aaa)
|
||||
|
||||
Should add a match/str/list/pos method that also returns the test and position
|
||||
of submatches. #8355
|
||||
|
||||
Check out PR #543 (Roland Puntaier).
|
||||
Patch for multibyte characters in langmap and applying a mapping on them.
|
||||
(Christian Brabandt, 2015 Jun 12, update July 25)
|
||||
@@ -380,6 +358,10 @@ work.
|
||||
Using "au!" after "filetype on" is a bit slow. Can the matching of
|
||||
autocommands be made faster? (#7056)
|
||||
|
||||
Append in Visual block mode inserts the wrong character.
|
||||
Test_visual_block_mode() already has the proper check, which is commented out.
|
||||
(#8288)
|
||||
|
||||
Add the <=> (spaceship) operator and "cond ?< expr ?= expr ?> expr"
|
||||
replace this:
|
||||
let left = GetLeftFunc()
|
||||
@@ -2263,9 +2245,6 @@ Win32: Improved Makefile for MSVC. (Leonardo Valeri Manera, 2010 Aug 18)
|
||||
|
||||
Win32: Expanding 'path' runs into a maximum size limit. (bgold12, 2009 Nov 15)
|
||||
|
||||
Win32: Patch for enabling quick edit mode in console. (Craig Barkhouse, 2010
|
||||
Sep 1)
|
||||
|
||||
Win32: Patch for using .png files for icons. (Charles Peacech, 2012 Feb 5)
|
||||
|
||||
Putting a Visual block while 'visualedit' is "all" does not leave the cursor
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*usr_41.txt* For Vim version 8.2. Last change: 2021 Apr 19
|
||||
*usr_41.txt* For Vim version 8.2. Last change: 2021 Jun 07
|
||||
|
||||
VIM USER MANUAL - by Bram Moolenaar
|
||||
|
||||
|
||||
@@ -727,7 +727,7 @@ K Run a program to lookup the keyword under the
|
||||
feature}
|
||||
|
||||
*:sl!* *:sleep!*
|
||||
:[N]sl[eep]! [N] [m] Same as above, but hide the cursor.
|
||||
:[N]sl[eep]! [N][m] Same as above, but hide the cursor.
|
||||
|
||||
*:xrestore* *:xr*
|
||||
:xr[estore] [display] Reinitializes the connection to the X11 server. Useful
|
||||
|
||||
+1
-1
@@ -186,7 +186,7 @@ behave mostly like Vi, even though a .vimrc file exists.
|
||||
.TP
|
||||
\-d
|
||||
Start in diff mode.
|
||||
There should be two, three or four file name arguments.
|
||||
There should between two to eight file name arguments.
|
||||
.B Vim
|
||||
will open all the files and show differences between them.
|
||||
Works like vimdiff(1).
|
||||
|
||||
+3
-3
@@ -135,9 +135,9 @@ OPTIONS
|
||||
Vim behave mostly like Vi, even though a .vimrc file ex‐
|
||||
ists.
|
||||
|
||||
-d Start in diff mode. There should be two, three or four
|
||||
file name arguments. Vim will open all the files and show
|
||||
differences between them. Works like vimdiff(1).
|
||||
-d Start in diff mode. There should between two to eight file
|
||||
name arguments. Vim will open all the files and show dif‐
|
||||
ferences between them. Works like vimdiff(1).
|
||||
|
||||
-d {device} Open {device} for use as a terminal. Only on the Amiga.
|
||||
Example: "-d con:20/30/600/150".
|
||||
|
||||
+72
-14
@@ -1,4 +1,4 @@
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2021 May 26
|
||||
*vim9.txt* For Vim version 8.2. Last change: 2021 Jun 12
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -169,6 +169,14 @@ created yet. In this case you can call `execute()` to invoke it at runtime. >
|
||||
used for the command or inside a `:try` block), does not get a range passed
|
||||
cannot be a "dict" function, and can always be a closure.
|
||||
|
||||
Later classes will be added, which replaces the "dict function" mechanism.
|
||||
For now you will need to pass the dictionary explicitly: >
|
||||
def DictFunc(d: dict<any>, arg: string)
|
||||
echo d[arg]
|
||||
enddef
|
||||
var d = {item: 'value', func: DictFunc}
|
||||
d.func(d, 'item')
|
||||
|
||||
The argument types and return type need to be specified. The "any" type can
|
||||
be used, type checking will then be done at runtime, like with legacy
|
||||
functions.
|
||||
@@ -445,11 +453,12 @@ it is the start of a lambda or a dictionary, which is now more complicated
|
||||
because of the use of argument types.
|
||||
|
||||
To avoid these problems Vim9 script uses a different syntax for a lambda,
|
||||
which is similar to Javascript: >
|
||||
which is similar to JavaScript: >
|
||||
var Lambda = (arg) => expression
|
||||
|
||||
No line break is allowed in the arguments of a lambda up to and including the
|
||||
"=>". This is OK: >
|
||||
"=>" (so that Vim can tell the difference between an expression in parenthesis
|
||||
and lambda arguments). This is OK: >
|
||||
filter(list, (k, v) =>
|
||||
v > 0)
|
||||
This does not work: >
|
||||
@@ -522,7 +531,7 @@ And when a dict spans multiple lines: >
|
||||
one: 1,
|
||||
two: 2,
|
||||
}
|
||||
Function call: >
|
||||
With a function call: >
|
||||
var result = Func(
|
||||
arg1,
|
||||
arg2
|
||||
@@ -555,10 +564,31 @@ at the start of the line indicates line continuation: >
|
||||
| echo 'match'
|
||||
| endif
|
||||
|
||||
Note that this means that in heredoc the first line cannot be a bar: >
|
||||
var lines =<< trim END
|
||||
| this doesn't work
|
||||
END
|
||||
Either use an empty line at the start or do not use heredoc. Or temporarily
|
||||
add the "C" flag to 'cpoptions': >
|
||||
set cpo+=C
|
||||
var lines =<< trim END
|
||||
| this doesn't work
|
||||
END
|
||||
set cpo-=C
|
||||
If the heredoc is inside a function 'cpoptions' must be set before :def and
|
||||
restored after the :enddef.
|
||||
|
||||
In places where line continuation with a backslash is still needed, such as
|
||||
splitting up a long Ex command, comments can start with #\ instead of "\: >
|
||||
syn region Text
|
||||
\ start='foo'
|
||||
#\ comment
|
||||
\ end='bar'
|
||||
|
||||
< *E1050*
|
||||
To make it possible for the operator at the start of the line to be
|
||||
recognized, it is required to put a colon before a range. This will add
|
||||
"start" and print: >
|
||||
recognized, it is required to put a colon before a range. This example will
|
||||
add "start" and print: >
|
||||
var result = start
|
||||
+ print
|
||||
Like this: >
|
||||
@@ -610,6 +640,9 @@ Notes:
|
||||
< This does not work: >
|
||||
echo [1, 2]
|
||||
[3, 4]
|
||||
- In some cases it is difficult for Vim to parse a command, especially when
|
||||
commands are used as an argument to another command, such as `windo`. In
|
||||
those cases the line continuation with a backslash has to be used.
|
||||
|
||||
|
||||
White space ~
|
||||
@@ -966,9 +999,14 @@ prefix if they do not exist at the time of compiling.
|
||||
Note that for command line completion of {func} you
|
||||
can prepend "s:" to find script-local functions.
|
||||
|
||||
:disa[ssemble]! {func} Like `:disassemble` but with the instructions used for
|
||||
:disa[ssemble] profile {func}
|
||||
Like `:disassemble` but with the instructions used for
|
||||
profiling.
|
||||
|
||||
:disa[ssemble] debug {func}
|
||||
Like `:disassemble` but with the instructions used for
|
||||
debugging.
|
||||
|
||||
Limitations ~
|
||||
|
||||
Local variables will not be visible to string evaluation. For example: >
|
||||
@@ -1240,9 +1278,10 @@ Exporting an item can be written as: >
|
||||
export const someValue = ...
|
||||
export def MyFunc() ...
|
||||
export class MyClass ...
|
||||
export interface MyClass ...
|
||||
|
||||
As this suggests, only constants, variables, `:def` functions and classes can
|
||||
be exported. {not implemented yet: export class}
|
||||
be exported. {not implemented yet: class, interface}
|
||||
|
||||
*E1042*
|
||||
`:export` can only be used in Vim9 script, at the script level.
|
||||
@@ -1342,27 +1381,46 @@ implementing classes is going to be a lot of work, it is left for the future.
|
||||
For now we'll just make sure classes can be added later.
|
||||
|
||||
Thoughts:
|
||||
- `class` / `endclass`, everything in one file
|
||||
- Class names are always CamelCase
|
||||
- Single constructor
|
||||
- `class` / `endclass`, the whole class must be in one file
|
||||
- Class names are always CamelCase (to avoid a name clash with builtin types)
|
||||
- A single constructor called "constructor"
|
||||
- Single inheritance with `class ThisClass extends BaseClass`
|
||||
- `abstract class`
|
||||
- `interface` (Abstract class without any implementation)
|
||||
- `abstract class` (class with incomplete implementation)
|
||||
- `interface` / `endinterface` (abstract class without any implementation)
|
||||
- `class SomeClass implements SomeInterface`
|
||||
- Generics for class: `class <Tkey, Tentry>`
|
||||
- Generics for function: `def <Tkey> GetLast(key: Tkey)`
|
||||
|
||||
Again, much of this is from TypeScript.
|
||||
Again, much of this is from TypeScript with a slightly different syntax.
|
||||
|
||||
Some things that look like good additions:
|
||||
- Use a class as an interface (like Dart)
|
||||
- Extend a class with methods, using an import (like Dart)
|
||||
- Mixins
|
||||
- For testing: Mock mechanism
|
||||
|
||||
An important class that will be provided is "Promise". Since Vim is single
|
||||
threaded, connecting asynchronous operations is a natural way of allowing
|
||||
plugins to do their work without blocking the user. It's a uniform way to
|
||||
invoke callbacks and handle timeouts and errors.
|
||||
|
||||
Some examples: >
|
||||
|
||||
abstract class Person
|
||||
static const prefix = 'xxx'
|
||||
var name: string
|
||||
|
||||
def constructor(name: string)
|
||||
this.name = name;
|
||||
enddef
|
||||
|
||||
def display(): void
|
||||
echo name
|
||||
enddef
|
||||
|
||||
abstract def find(string): Person
|
||||
endclass
|
||||
|
||||
==============================================================================
|
||||
|
||||
9. Rationale *vim9-rationale*
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
.TH VIMDIFF 1 "2001 March 30"
|
||||
.SH NAME
|
||||
vimdiff \- edit two, three or four versions of a file with Vim and show differences
|
||||
vimdiff \- edit between two and eight versions of a file with Vim and show differences
|
||||
.SH SYNOPSIS
|
||||
.br
|
||||
.B vimdiff
|
||||
[options] file1 file2 [file3 [file4]]
|
||||
[options] file1 file2 [file3 [file4 [file5 [file6 [file7 [file8]]]]]]
|
||||
.PP
|
||||
.B gvimdiff
|
||||
.SH DESCRIPTION
|
||||
.B Vimdiff
|
||||
starts
|
||||
.B Vim
|
||||
on two (or three or four) files.
|
||||
on two up to eight files.
|
||||
Each file gets its own window.
|
||||
The differences between the files are highlighted.
|
||||
This is a nice way to inspect changes and to move changes from one version
|
||||
|
||||
+10
-9
@@ -1,27 +1,28 @@
|
||||
VIMDIFF(1) VIMDIFF(1)
|
||||
VIMDIFF(1) General Commands Manual VIMDIFF(1)
|
||||
|
||||
|
||||
|
||||
NAME
|
||||
vimdiff - edit two, three or four versions of a file with Vim and show
|
||||
differences
|
||||
vimdiff - edit between two and eight versions of a file with Vim and
|
||||
show differences
|
||||
|
||||
SYNOPSIS
|
||||
vimdiff [options] file1 file2 [file3 [file4]]
|
||||
vimdiff [options] file1 file2 [file3 [file4 [file5 [file6 [file7
|
||||
[file8]]]]]]
|
||||
|
||||
gvimdiff
|
||||
|
||||
DESCRIPTION
|
||||
Vimdiff starts Vim on two (or three or four) files. Each file gets its
|
||||
own window. The differences between the files are highlighted. This
|
||||
is a nice way to inspect changes and to move changes from one version
|
||||
to another version of the same file.
|
||||
Vimdiff starts Vim on two up to eight files. Each file gets its own
|
||||
window. The differences between the files are highlighted. This is a
|
||||
nice way to inspect changes and to move changes from one version to an‐
|
||||
other version of the same file.
|
||||
|
||||
See vim(1) for details about Vim itself.
|
||||
|
||||
When started as gvimdiff the GUI will be started, if available.
|
||||
|
||||
In each window the 'diff' option will be set, which causes the differ-
|
||||
In each window the 'diff' option will be set, which causes the differ‐
|
||||
ences to be highlighted.
|
||||
The 'wrap' and 'scrollbind' options are set to make the text look good.
|
||||
The 'foldmethod' option is set to "diff", which puts ranges of lines
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
" Vim support file to detect file types
|
||||
"
|
||||
" Maintainer: Bram Moolenaar <Bram@vim.org>
|
||||
" Last Change: 2021 Apr 17
|
||||
" Last Change: 2021 Jun 13
|
||||
|
||||
" Listen very carefully, I will say this only once
|
||||
if exists("did_load_filetypes")
|
||||
@@ -855,6 +855,9 @@ au BufNewFile,BufRead *.jov,*.j73,*.jovial setf jovial
|
||||
" JSON
|
||||
au BufNewFile,BufRead *.json,*.jsonp,*.webmanifest setf json
|
||||
|
||||
" Jupyter Notebook is also json
|
||||
au BufNewFile,BufRead *.ipynb setf json
|
||||
|
||||
" Kixtart
|
||||
au BufNewFile,BufRead *.kix setf kix
|
||||
|
||||
|
||||
@@ -112,6 +112,7 @@ Icon[de]=gvim
|
||||
Icon[eo]=gvim
|
||||
Icon[fr]=gvim
|
||||
Icon[ru]=gvim
|
||||
Icon[sr]=gvim
|
||||
Icon=gvim
|
||||
Categories=Utility;TextEditor;
|
||||
StartupNotify=true
|
||||
|
||||
+34
-29
@@ -1,7 +1,7 @@
|
||||
" Vim indent script for HTML
|
||||
" Maintainer: Bram Moolenaar
|
||||
" Original Author: Andy Wokula <anwoku@yahoo.de>
|
||||
" Last Change: 2021 Jan 26
|
||||
" Last Change: 2021 Jun 13
|
||||
" Version: 1.0 "{{{
|
||||
" Description: HTML indent script with cached state for faster indenting on a
|
||||
" range of lines.
|
||||
@@ -62,7 +62,7 @@ let s:tagname = '\w\+\(-\w\+\)*'
|
||||
" Prefer using buffer-local settings over global settings, so that there can
|
||||
" be defaults for all HTML files and exceptions for specific types of HTML
|
||||
" files.
|
||||
func! HtmlIndent_CheckUserSettings()
|
||||
func HtmlIndent_CheckUserSettings()
|
||||
"{{{
|
||||
let inctags = ''
|
||||
if exists("b:html_indent_inctags")
|
||||
@@ -178,7 +178,7 @@ let s:endtags = [0,0,0,0,0,0,0] " long enough for the highest index
|
||||
"}}}
|
||||
|
||||
" Add a list of tag names for a pair of <tag> </tag> to "tags".
|
||||
func! s:AddITags(tags, taglist)
|
||||
func s:AddITags(tags, taglist)
|
||||
"{{{
|
||||
for itag in a:taglist
|
||||
let a:tags[itag] = 1
|
||||
@@ -187,7 +187,7 @@ func! s:AddITags(tags, taglist)
|
||||
endfunc "}}}
|
||||
|
||||
" Take a list of tag name pairs that are not to be used as tag pairs.
|
||||
func! s:RemoveITags(tags, taglist)
|
||||
func s:RemoveITags(tags, taglist)
|
||||
"{{{
|
||||
for itag in a:taglist
|
||||
let a:tags[itag] = 1
|
||||
@@ -196,7 +196,7 @@ func! s:RemoveITags(tags, taglist)
|
||||
endfunc "}}}
|
||||
|
||||
" Add a block tag, that is a tag with a different kind of indenting.
|
||||
func! s:AddBlockTag(tag, id, ...)
|
||||
func s:AddBlockTag(tag, id, ...)
|
||||
"{{{
|
||||
if !(a:id >= 2 && a:id < len(s:endtags))
|
||||
echoerr 'AddBlockTag ' . a:id
|
||||
@@ -255,7 +255,7 @@ call s:AddBlockTag('<!--[', 6, '![endif]-->')
|
||||
" Return non-zero when "tagname" is an opening tag, not being a block tag, for
|
||||
" which there should be a closing tag. Can be used by scripts that include
|
||||
" HTML indenting.
|
||||
func! HtmlIndent_IsOpenTag(tagname)
|
||||
func HtmlIndent_IsOpenTag(tagname)
|
||||
"{{{
|
||||
if get(s:indent_tags, a:tagname) == 1
|
||||
return 1
|
||||
@@ -264,7 +264,7 @@ func! HtmlIndent_IsOpenTag(tagname)
|
||||
endfunc "}}}
|
||||
|
||||
" Get the value for "tagname", taking care of buffer-local tags.
|
||||
func! s:get_tag(tagname)
|
||||
func s:get_tag(tagname)
|
||||
"{{{
|
||||
let i = get(s:indent_tags, a:tagname)
|
||||
if (i == 1 || i == -1) && get(b:hi_removed_tags, a:tagname) != 0
|
||||
@@ -277,7 +277,7 @@ func! s:get_tag(tagname)
|
||||
endfunc "}}}
|
||||
|
||||
" Count the number of start and end tags in "text".
|
||||
func! s:CountITags(text)
|
||||
func s:CountITags(text)
|
||||
"{{{
|
||||
" Store the result in s:curind and s:nextrel.
|
||||
let s:curind = 0 " relative indent steps for current line [unit &sw]:
|
||||
@@ -289,7 +289,7 @@ func! s:CountITags(text)
|
||||
endfunc "}}}
|
||||
|
||||
" Count the number of start and end tags in text.
|
||||
func! s:CountTagsAndState(text)
|
||||
func s:CountTagsAndState(text)
|
||||
"{{{
|
||||
" Store the result in s:curind and s:nextrel. Update b:hi_newstate.block.
|
||||
let s:curind = 0 " relative indent steps for current line [unit &sw]:
|
||||
@@ -304,7 +304,7 @@ func! s:CountTagsAndState(text)
|
||||
endfunc "}}}
|
||||
|
||||
" Used by s:CountITags() and s:CountTagsAndState().
|
||||
func! s:CheckTag(itag)
|
||||
func s:CheckTag(itag)
|
||||
"{{{
|
||||
" Returns an empty string or "SCRIPT".
|
||||
" a:itag can be "tag" or "/tag" or "<!--" or "-->"
|
||||
@@ -338,7 +338,7 @@ func! s:CheckTag(itag)
|
||||
endfunc "}}}
|
||||
|
||||
" Used by s:CheckTag(). Returns an empty string or "SCRIPT".
|
||||
func! s:CheckBlockTag(blocktag, ind)
|
||||
func s:CheckBlockTag(blocktag, ind)
|
||||
"{{{
|
||||
if a:ind > 0
|
||||
" a block starts here
|
||||
@@ -366,7 +366,7 @@ func! s:CheckBlockTag(blocktag, ind)
|
||||
endfunc "}}}
|
||||
|
||||
" Used by s:CheckTag().
|
||||
func! s:CheckCustomTag(ctag)
|
||||
func s:CheckCustomTag(ctag)
|
||||
"{{{
|
||||
" Returns 1 if ctag is the tag for a custom element, 0 otherwise.
|
||||
" a:ctag can be "tag" or "/tag" or "<!--" or "-->"
|
||||
@@ -396,7 +396,7 @@ func! s:CheckCustomTag(ctag)
|
||||
endfunc "}}}
|
||||
|
||||
" Return the <script> type: either "javascript" or ""
|
||||
func! s:GetScriptType(str)
|
||||
func s:GetScriptType(str)
|
||||
"{{{
|
||||
if a:str == "" || a:str =~ "java"
|
||||
return "javascript"
|
||||
@@ -407,7 +407,7 @@ endfunc "}}}
|
||||
|
||||
" Look back in the file, starting at a:lnum - 1, to compute a state for the
|
||||
" start of line a:lnum. Return the new state.
|
||||
func! s:FreshState(lnum)
|
||||
func s:FreshState(lnum)
|
||||
"{{{
|
||||
" A state is to know ALL relevant details about the
|
||||
" lines 1..a:lnum-1, initial calculating (here!) can be slow, but updating is
|
||||
@@ -568,24 +568,29 @@ func! s:FreshState(lnum)
|
||||
endfunc "}}}
|
||||
|
||||
" Indent inside a <pre> block: Keep indent as-is.
|
||||
func! s:Alien2()
|
||||
func s:Alien2()
|
||||
"{{{
|
||||
return -1
|
||||
endfunc "}}}
|
||||
|
||||
" Return the indent inside a <script> block for javascript.
|
||||
func! s:Alien3()
|
||||
func s:Alien3()
|
||||
"{{{
|
||||
let lnum = prevnonblank(v:lnum - 1)
|
||||
while lnum > 1 && getline(lnum) =~ '^\s*/[/*]'
|
||||
" Skip over comments to avoid that cindent() aligns with the <script> tag
|
||||
let lnum = prevnonblank(lnum - 1)
|
||||
endwhile
|
||||
if lnum < b:hi_indent.blocklnr
|
||||
" indent for <script> itself
|
||||
return b:hi_indent.blocktagind
|
||||
endif
|
||||
if lnum == b:hi_indent.blocklnr
|
||||
" indent for the first line after <script>
|
||||
return eval(b:hi_js1indent)
|
||||
endif
|
||||
if b:hi_indent.scripttype == "javascript"
|
||||
" indent for further lines
|
||||
return eval(b:hi_js1indent) + GetJavascriptIndent()
|
||||
else
|
||||
return -1
|
||||
@@ -593,7 +598,7 @@ func! s:Alien3()
|
||||
endfunc "}}}
|
||||
|
||||
" Return the indent inside a <style> block.
|
||||
func! s:Alien4()
|
||||
func s:Alien4()
|
||||
"{{{
|
||||
if prevnonblank(v:lnum-1) == b:hi_indent.blocklnr
|
||||
" indent for first content line
|
||||
@@ -603,7 +608,7 @@ func! s:Alien4()
|
||||
endfunc "}}}
|
||||
|
||||
" Indending inside a <style> block. Returns the indent.
|
||||
func! s:CSSIndent()
|
||||
func s:CSSIndent()
|
||||
"{{{
|
||||
" This handles standard CSS and also Closure stylesheets where special lines
|
||||
" start with @.
|
||||
@@ -720,13 +725,13 @@ endfunc "}}}
|
||||
" tag: blah
|
||||
" tag: blah &&
|
||||
" tag: blah ||
|
||||
func! s:CssUnfinished(text)
|
||||
func s:CssUnfinished(text)
|
||||
"{{{
|
||||
return a:text =~ '\(||\|&&\|:\|\k\)\s*$'
|
||||
endfunc "}}}
|
||||
|
||||
" Search back for the first unfinished line above "lnum".
|
||||
func! s:CssFirstUnfinished(lnum, min_lnum)
|
||||
func s:CssFirstUnfinished(lnum, min_lnum)
|
||||
"{{{
|
||||
let align_lnum = a:lnum
|
||||
while align_lnum > a:min_lnum && s:CssUnfinished(getline(align_lnum - 1))
|
||||
@@ -736,7 +741,7 @@ func! s:CssFirstUnfinished(lnum, min_lnum)
|
||||
endfunc "}}}
|
||||
|
||||
" Find the non-empty line at or before "lnum" that is not a comment.
|
||||
func! s:CssPrevNonComment(lnum, stopline)
|
||||
func s:CssPrevNonComment(lnum, stopline)
|
||||
"{{{
|
||||
" caller starts from a line a:lnum + 1 that is not a comment
|
||||
let lnum = prevnonblank(a:lnum)
|
||||
@@ -761,7 +766,7 @@ func! s:CssPrevNonComment(lnum, stopline)
|
||||
endfunc "}}}
|
||||
|
||||
" Check the number of {} and () in line "lnum". Return a dict with the counts.
|
||||
func! HtmlIndent_CountBraces(lnum)
|
||||
func HtmlIndent_CountBraces(lnum)
|
||||
"{{{
|
||||
let brs = substitute(getline(a:lnum), '[''"].\{-}[''"]\|/\*.\{-}\*/\|/\*.*$\|[^{}()]', '', 'g')
|
||||
let c_open = 0
|
||||
@@ -794,7 +799,7 @@ func! HtmlIndent_CountBraces(lnum)
|
||||
endfunc "}}}
|
||||
|
||||
" Return the indent for a comment: <!-- -->
|
||||
func! s:Alien5()
|
||||
func s:Alien5()
|
||||
"{{{
|
||||
let curtext = getline(v:lnum)
|
||||
if curtext =~ '^\s*\zs-->'
|
||||
@@ -826,7 +831,7 @@ func! s:Alien5()
|
||||
endfunc "}}}
|
||||
|
||||
" Return the indent for conditional comment: <!--[ ![endif]-->
|
||||
func! s:Alien6()
|
||||
func s:Alien6()
|
||||
"{{{
|
||||
let curtext = getline(v:lnum)
|
||||
if curtext =~ '\s*\zs<!\[endif\]-->'
|
||||
@@ -840,7 +845,7 @@ func! s:Alien6()
|
||||
endfunc "}}}
|
||||
|
||||
" When the "lnum" line ends in ">" find the line containing the matching "<".
|
||||
func! HtmlIndent_FindTagStart(lnum)
|
||||
func HtmlIndent_FindTagStart(lnum)
|
||||
"{{{
|
||||
" Avoids using the indent of a continuation line.
|
||||
" Moves the cursor.
|
||||
@@ -863,7 +868,7 @@ func! HtmlIndent_FindTagStart(lnum)
|
||||
endfunc "}}}
|
||||
|
||||
" Find the unclosed start tag from the current cursor position.
|
||||
func! HtmlIndent_FindStartTag()
|
||||
func HtmlIndent_FindStartTag()
|
||||
"{{{
|
||||
" The cursor must be on or before a closing tag.
|
||||
" If found, positions the cursor at the match and returns the line number.
|
||||
@@ -877,7 +882,7 @@ func! HtmlIndent_FindStartTag()
|
||||
endfunc "}}}
|
||||
|
||||
" Moves the cursor from a "<" to the matching ">".
|
||||
func! HtmlIndent_FindTagEnd()
|
||||
func HtmlIndent_FindTagEnd()
|
||||
"{{{
|
||||
" Call this with the cursor on the "<" of a start tag.
|
||||
" This will move the cursor to the ">" of the matching end tag or, when it's
|
||||
@@ -897,7 +902,7 @@ func! HtmlIndent_FindTagEnd()
|
||||
endfunc "}}}
|
||||
|
||||
" Indenting inside a start tag. Return the correct indent or -1 if unknown.
|
||||
func! s:InsideTag(foundHtmlString)
|
||||
func s:InsideTag(foundHtmlString)
|
||||
"{{{
|
||||
if a:foundHtmlString
|
||||
" Inside an attribute string.
|
||||
@@ -958,7 +963,7 @@ func! s:InsideTag(foundHtmlString)
|
||||
endfunc "}}}
|
||||
|
||||
" THE MAIN INDENT FUNCTION. Return the amount of indent for v:lnum.
|
||||
func! HtmlIndent()
|
||||
func HtmlIndent()
|
||||
"{{{
|
||||
if prevnonblank(v:lnum - 1) < 1
|
||||
" First non-blank line has no indent.
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
" Vim syntax file
|
||||
" Language: Graphviz program
|
||||
" Maintainer: Matthew Fernandez <matthew.fernandez@gmail.com>
|
||||
" Last Change: Tue, 28 Jul 2020 17:20:44 -0700
|
||||
|
||||
if exists("b:current_syntax")
|
||||
finish
|
||||
endif
|
||||
|
||||
let s:cpo_save = &cpo
|
||||
set cpo&vim
|
||||
|
||||
syn keyword gvArg ARGC ARGV
|
||||
syn keyword gvBeg BEGIN BEG_G N E END END_G
|
||||
syn keyword gvFunc
|
||||
\ graph fstsubg isDirect isStrict isSubg nEdges nNodes nxtsubg subg
|
||||
\ degreeOf fstnode indegreeOf isNode isSubnode node nxtnode nxtnode_sg
|
||||
\ outDegreeOf subnode
|
||||
\ edge edge_sg fstedge fstedge_sg fstin fstin_sg fstout fstout_sg isEdge
|
||||
\ isEdge_sg isSubedge nxtedge nxtedge_sg nxtin nxtin_sg nxtout nxtout_sg opp
|
||||
\ subedge
|
||||
\ freadG fwriteG readG write[] writeG
|
||||
\ aget aset clone cloneG compOf copy[] copyA delete[] fstAttr getDflt hasAttr
|
||||
\ induce isAttr isIn kindOf lock[] nxtAttr setDflt
|
||||
\ canon gsub html index ishtml length llOf match[] rindex split[] sprintf
|
||||
\ sscanf strcmp sub substr tokens tolower toupper urOf xOf yOf
|
||||
\ closeF openF print[] printf scanf readL
|
||||
\ atan2 cos exp log MAX MIN pow sin[] sqrt
|
||||
\ in[] unset
|
||||
\ colorx exit[] rand srand system
|
||||
syn keyword gvCons
|
||||
\ NULL TV_bfs TV_dfs TV_en TV_flat TV_fwd TV_ne TV_prepostdfs TV_prepostfwd
|
||||
\ TV_prepostrev TV_postdfs TV_postfwd tv_postrev TV_rev
|
||||
syn keyword gvType char double float int long unsigned void
|
||||
\ string
|
||||
\ edge_t graph_t node_t obj_t
|
||||
syn match gvVar
|
||||
\ "\$\(\(F\|G\|NG\|O\|T\|tgtname\|tvedge\|tvnext\|tvroot\|tvtype\)\>\)\?\(\<\)\@!"
|
||||
syn keyword gvWord break continue else for forr if return switch while
|
||||
|
||||
" numbers adapted from c.vim's cNumbers and friends
|
||||
syn match gvNums transparent "\<\d\|\.\d" contains=gvNumber,gvFloat,gvOctal
|
||||
syn match gvNumber contained "\d\+\(u\=l\{0,2}\|ll\=u\)\>"
|
||||
syn match gvNumber contained "0x\x\+\(u\=l\{0,2}\|ll\=u\)\>"
|
||||
syn match gvOctal contained "0\o\+\(u\=l\{0,2}\|ll\=u\)\>" contains=gvOctalZero
|
||||
syn match gvOctalZero contained "\<0"
|
||||
syn match gvFloat contained "\d\+f"
|
||||
syn match gvFloat contained "\d\+\.\d*\(e[-+]\=\d\+\)\=[fl]\="
|
||||
syn match gvFloat contained "\.\d\+\(e[-+]\=\d\+\)\=[fl]\=\>"
|
||||
syn match gvFloat contained "\d\+e[-+]\=\d\+[fl]\=\>"
|
||||
|
||||
syn region gvString start=+"+ skip=+\\\\\|\\"+ end=+"+ contains=gvFormat,gvSpecial extend
|
||||
syn region gvString start="'" skip="\\\\\|\\'" end="'" contains=gvFormat,gvSpecial extend
|
||||
|
||||
" adapted from c.vim's cFormat for c_no_c99
|
||||
syn match gvFormat "%\(\d\+\$\)\=[-+' #0*]*\(\d*\|\*\|\*\d\+\$\)\(\.\(\d*\|\*\|\*\d\+\$\)\)\=\([hlL]\|ll\)\=\([bdiuoxXDOUfeEgGcCsSpn]\|\[\^\=.[^]]*\]\)" contained
|
||||
|
||||
syn match gvSpecial "\\." contained
|
||||
|
||||
syn region gvCComment start="//" skip="\\$" end="$" keepend
|
||||
syn region gvCPPComment start="#" skip="\\$" end="$" keepend
|
||||
syn region gvCXXComment start="/\*" end="\*/" fold
|
||||
|
||||
hi def link gvArg Identifier
|
||||
hi def link gvBeg Keyword
|
||||
hi def link gvFloat Number
|
||||
hi def link gvFunc Identifier
|
||||
hi def link gvCons Number
|
||||
hi def link gvNumber Number
|
||||
hi def link gvType Type
|
||||
hi def link gvVar Statement
|
||||
hi def link gvWord Keyword
|
||||
|
||||
hi def link gvString String
|
||||
hi def link gvFormat Special
|
||||
hi def link gvSpecial Special
|
||||
|
||||
hi def link gvCComment Comment
|
||||
hi def link gvCPPComment Comment
|
||||
hi def link gvCXXComment Comment
|
||||
|
||||
let b:current_syntax = "gvpr"
|
||||
|
||||
let &cpo = s:cpo_save
|
||||
unlet s:cpo_save
|
||||
@@ -112,6 +112,7 @@ Icon[de]=gvim
|
||||
Icon[eo]=gvim
|
||||
Icon[fr]=gvim
|
||||
Icon[ru]=gvim
|
||||
Icon[sr]=gvim
|
||||
Icon=gvim
|
||||
Categories=Utility;TextEditor;
|
||||
StartupNotify=false
|
||||
|
||||
+2
-1
@@ -284,7 +284,8 @@ open the window from the start menu, MSYS2 64 bit / MSYS2 MSYS.
|
||||
Execute:
|
||||
$ pacman -Syu
|
||||
|
||||
And restart MSYS2 console (select "MSYS2 MSYS" icon from the Start Menu).
|
||||
And restart MSYS2 console (select "MSYS2 MSYS 32-Bit" icon from the Start
|
||||
Menu for building 32 bit Vim, otherwise select "MSYS2 MinGW 64-Bit").
|
||||
Then execute:
|
||||
$ pacman -Su
|
||||
|
||||
|
||||
Vendored
+4
-1
@@ -6854,7 +6854,10 @@ else
|
||||
|
||||
vi_cv_path_python3_conf=
|
||||
config_dir="config-${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags}"
|
||||
d=`${vi_cv_path_python3} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBPL'))"`
|
||||
d=`${vi_cv_path_python3} -c "import sysconfig; print(sysconfig.get_config_var('LIBPL'))" 2> /dev/null`
|
||||
if test "x$d" = "x"; then
|
||||
d=`${vi_cv_path_python3} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBPL'))"`
|
||||
fi
|
||||
if test -d "$d" && test -f "$d/config.c"; then
|
||||
vi_cv_path_python3_conf="$d"
|
||||
else
|
||||
|
||||
+143
-123
@@ -1184,122 +1184,6 @@ handle_swap_exists(bufref_T *old_curbuf)
|
||||
swap_exists_action = SEA_NONE;
|
||||
}
|
||||
|
||||
/*
|
||||
* do_bufdel() - delete or unload buffer(s)
|
||||
*
|
||||
* addr_count == 0: ":bdel" - delete current buffer
|
||||
* addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
|
||||
* buffer "end_bnr", then any other arguments.
|
||||
* addr_count == 2: ":N,N bdel" - delete buffers in range
|
||||
*
|
||||
* command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
|
||||
* DOBUF_DEL (":bdel")
|
||||
*
|
||||
* Returns error message or NULL
|
||||
*/
|
||||
char *
|
||||
do_bufdel(
|
||||
int command,
|
||||
char_u *arg, // pointer to extra arguments
|
||||
int addr_count,
|
||||
int start_bnr, // first buffer number in a range
|
||||
int end_bnr, // buffer nr or last buffer nr in a range
|
||||
int forceit)
|
||||
{
|
||||
int do_current = 0; // delete current buffer?
|
||||
int deleted = 0; // number of buffers deleted
|
||||
char *errormsg = NULL; // return value
|
||||
int bnr; // buffer number
|
||||
char_u *p;
|
||||
|
||||
if (addr_count == 0)
|
||||
{
|
||||
(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr_count == 2)
|
||||
{
|
||||
if (*arg) // both range and argument is not allowed
|
||||
return ex_errmsg(e_trailing_arg, arg);
|
||||
bnr = start_bnr;
|
||||
}
|
||||
else // addr_count == 1
|
||||
bnr = end_bnr;
|
||||
|
||||
for ( ;!got_int; ui_breakcheck())
|
||||
{
|
||||
/*
|
||||
* delete the current buffer last, otherwise when the
|
||||
* current buffer is deleted, the next buffer becomes
|
||||
* the current one and will be loaded, which may then
|
||||
* also be deleted, etc.
|
||||
*/
|
||||
if (bnr == curbuf->b_fnum)
|
||||
do_current = bnr;
|
||||
else if (do_buffer(command, DOBUF_FIRST, FORWARD, (int)bnr,
|
||||
forceit) == OK)
|
||||
++deleted;
|
||||
|
||||
/*
|
||||
* find next buffer number to delete/unload
|
||||
*/
|
||||
if (addr_count == 2)
|
||||
{
|
||||
if (++bnr > end_bnr)
|
||||
break;
|
||||
}
|
||||
else // addr_count == 1
|
||||
{
|
||||
arg = skipwhite(arg);
|
||||
if (*arg == NUL)
|
||||
break;
|
||||
if (!VIM_ISDIGIT(*arg))
|
||||
{
|
||||
p = skiptowhite_esc(arg);
|
||||
bnr = buflist_findpat(arg, p,
|
||||
command == DOBUF_WIPE || command == DOBUF_WIPE_REUSE,
|
||||
FALSE, FALSE);
|
||||
if (bnr < 0) // failed
|
||||
break;
|
||||
arg = p;
|
||||
}
|
||||
else
|
||||
bnr = getdigits(&arg);
|
||||
}
|
||||
}
|
||||
if (!got_int && do_current && do_buffer(command, DOBUF_FIRST,
|
||||
FORWARD, do_current, forceit) == OK)
|
||||
++deleted;
|
||||
|
||||
if (deleted == 0)
|
||||
{
|
||||
if (command == DOBUF_UNLOAD)
|
||||
STRCPY(IObuff, _("E515: No buffers were unloaded"));
|
||||
else if (command == DOBUF_DEL)
|
||||
STRCPY(IObuff, _("E516: No buffers were deleted"));
|
||||
else
|
||||
STRCPY(IObuff, _("E517: No buffers were wiped out"));
|
||||
errormsg = (char *)IObuff;
|
||||
}
|
||||
else if (deleted >= p_report)
|
||||
{
|
||||
if (command == DOBUF_UNLOAD)
|
||||
smsg(NGETTEXT("%d buffer unloaded",
|
||||
"%d buffers unloaded", deleted), deleted);
|
||||
else if (command == DOBUF_DEL)
|
||||
smsg(NGETTEXT("%d buffer deleted",
|
||||
"%d buffers deleted", deleted), deleted);
|
||||
else
|
||||
smsg(NGETTEXT("%d buffer wiped out",
|
||||
"%d buffers wiped out", deleted), deleted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return errormsg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make the current buffer empty.
|
||||
* Used when it is wiped out and it's the last buffer.
|
||||
@@ -1358,13 +1242,13 @@ empty_curbuf(
|
||||
*
|
||||
* Return FAIL or OK.
|
||||
*/
|
||||
int
|
||||
do_buffer(
|
||||
static int
|
||||
do_buffer_ext(
|
||||
int action,
|
||||
int start,
|
||||
int dir, // FORWARD or BACKWARD
|
||||
int count, // buffer number or number of buffers
|
||||
int forceit) // TRUE for :...!
|
||||
int flags) // DOBUF_FORCEIT etc.
|
||||
{
|
||||
buf_T *buf;
|
||||
buf_T *bp;
|
||||
@@ -1450,6 +1334,14 @@ do_buffer(
|
||||
emsg(_("E88: Cannot go before first buffer"));
|
||||
return FAIL;
|
||||
}
|
||||
#ifdef FEAT_PROP_POPUP
|
||||
if ((flags & DOBUF_NOPOPUP) && bt_popup(buf)
|
||||
# ifdef FEAT_TERMINAL
|
||||
&& !bt_terminal(buf)
|
||||
#endif
|
||||
)
|
||||
return OK;
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_GUI
|
||||
need_mouse_correct = TRUE;
|
||||
@@ -1474,7 +1366,7 @@ do_buffer(
|
||||
&& buf->b_ml.ml_mfp == NULL && !buf->b_p_bl)
|
||||
return FAIL;
|
||||
|
||||
if (!forceit && bufIsChanged(buf))
|
||||
if ((flags & DOBUF_FORCEIT) == 0 && bufIsChanged(buf))
|
||||
{
|
||||
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
|
||||
if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write)
|
||||
@@ -1510,7 +1402,7 @@ do_buffer(
|
||||
if (bp->b_p_bl && bp != buf)
|
||||
break;
|
||||
if (bp == NULL && buf == curbuf)
|
||||
return empty_curbuf(TRUE, forceit, action);
|
||||
return empty_curbuf(TRUE, (flags & DOBUF_FORCEIT), action);
|
||||
|
||||
/*
|
||||
* If the deleted buffer is the current one, close the current window
|
||||
@@ -1637,7 +1529,7 @@ do_buffer(
|
||||
{
|
||||
// Autocommands must have wiped out all other buffers. Only option
|
||||
// now is to make the current buffer empty.
|
||||
return empty_curbuf(FALSE, forceit, action);
|
||||
return empty_curbuf(FALSE, (flags & DOBUF_FORCEIT), action);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1664,7 +1556,7 @@ do_buffer(
|
||||
/*
|
||||
* Check if the current buffer may be abandoned.
|
||||
*/
|
||||
if (action == DOBUF_GOTO && !can_abandon(curbuf, forceit))
|
||||
if (action == DOBUF_GOTO && !can_abandon(curbuf, (flags & DOBUF_FORCEIT)))
|
||||
{
|
||||
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG)
|
||||
if ((p_confirm || (cmdmod.cmod_flags & CMOD_CONFIRM)) && p_write)
|
||||
@@ -1699,6 +1591,134 @@ do_buffer(
|
||||
return OK;
|
||||
}
|
||||
|
||||
int
|
||||
do_buffer(
|
||||
int action,
|
||||
int start,
|
||||
int dir, // FORWARD or BACKWARD
|
||||
int count, // buffer number or number of buffers
|
||||
int forceit) // TRUE when using !
|
||||
{
|
||||
return do_buffer_ext(action, start, dir, count,
|
||||
forceit ? DOBUF_FORCEIT : 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* do_bufdel() - delete or unload buffer(s)
|
||||
*
|
||||
* addr_count == 0: ":bdel" - delete current buffer
|
||||
* addr_count == 1: ":N bdel" or ":bdel N [N ..]" - first delete
|
||||
* buffer "end_bnr", then any other arguments.
|
||||
* addr_count == 2: ":N,N bdel" - delete buffers in range
|
||||
*
|
||||
* command can be DOBUF_UNLOAD (":bunload"), DOBUF_WIPE (":bwipeout") or
|
||||
* DOBUF_DEL (":bdel")
|
||||
*
|
||||
* Returns error message or NULL
|
||||
*/
|
||||
char *
|
||||
do_bufdel(
|
||||
int command,
|
||||
char_u *arg, // pointer to extra arguments
|
||||
int addr_count,
|
||||
int start_bnr, // first buffer number in a range
|
||||
int end_bnr, // buffer nr or last buffer nr in a range
|
||||
int forceit)
|
||||
{
|
||||
int do_current = 0; // delete current buffer?
|
||||
int deleted = 0; // number of buffers deleted
|
||||
char *errormsg = NULL; // return value
|
||||
int bnr; // buffer number
|
||||
char_u *p;
|
||||
|
||||
if (addr_count == 0)
|
||||
{
|
||||
(void)do_buffer(command, DOBUF_CURRENT, FORWARD, 0, forceit);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addr_count == 2)
|
||||
{
|
||||
if (*arg) // both range and argument is not allowed
|
||||
return ex_errmsg(e_trailing_arg, arg);
|
||||
bnr = start_bnr;
|
||||
}
|
||||
else // addr_count == 1
|
||||
bnr = end_bnr;
|
||||
|
||||
for ( ;!got_int; ui_breakcheck())
|
||||
{
|
||||
/*
|
||||
* Delete the current buffer last, otherwise when the
|
||||
* current buffer is deleted, the next buffer becomes
|
||||
* the current one and will be loaded, which may then
|
||||
* also be deleted, etc.
|
||||
*/
|
||||
if (bnr == curbuf->b_fnum)
|
||||
do_current = bnr;
|
||||
else if (do_buffer_ext(command, DOBUF_FIRST, FORWARD, (int)bnr,
|
||||
DOBUF_NOPOPUP | (forceit ? DOBUF_FORCEIT : 0)) == OK)
|
||||
++deleted;
|
||||
|
||||
/*
|
||||
* find next buffer number to delete/unload
|
||||
*/
|
||||
if (addr_count == 2)
|
||||
{
|
||||
if (++bnr > end_bnr)
|
||||
break;
|
||||
}
|
||||
else // addr_count == 1
|
||||
{
|
||||
arg = skipwhite(arg);
|
||||
if (*arg == NUL)
|
||||
break;
|
||||
if (!VIM_ISDIGIT(*arg))
|
||||
{
|
||||
p = skiptowhite_esc(arg);
|
||||
bnr = buflist_findpat(arg, p,
|
||||
command == DOBUF_WIPE || command == DOBUF_WIPE_REUSE,
|
||||
FALSE, FALSE);
|
||||
if (bnr < 0) // failed
|
||||
break;
|
||||
arg = p;
|
||||
}
|
||||
else
|
||||
bnr = getdigits(&arg);
|
||||
}
|
||||
}
|
||||
if (!got_int && do_current && do_buffer(command, DOBUF_FIRST,
|
||||
FORWARD, do_current, forceit) == OK)
|
||||
++deleted;
|
||||
|
||||
if (deleted == 0)
|
||||
{
|
||||
if (command == DOBUF_UNLOAD)
|
||||
STRCPY(IObuff, _("E515: No buffers were unloaded"));
|
||||
else if (command == DOBUF_DEL)
|
||||
STRCPY(IObuff, _("E516: No buffers were deleted"));
|
||||
else
|
||||
STRCPY(IObuff, _("E517: No buffers were wiped out"));
|
||||
errormsg = (char *)IObuff;
|
||||
}
|
||||
else if (deleted >= p_report)
|
||||
{
|
||||
if (command == DOBUF_UNLOAD)
|
||||
smsg(NGETTEXT("%d buffer unloaded",
|
||||
"%d buffers unloaded", deleted), deleted);
|
||||
else if (command == DOBUF_DEL)
|
||||
smsg(NGETTEXT("%d buffer deleted",
|
||||
"%d buffers deleted", deleted), deleted);
|
||||
else
|
||||
smsg(NGETTEXT("%d buffer wiped out",
|
||||
"%d buffers wiped out", deleted), deleted);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return errormsg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set current buffer to "buf". Executes autocommands and closes current
|
||||
* buffer. "action" tells how to close the current buffer:
|
||||
|
||||
+6
-1
@@ -1370,6 +1370,8 @@ set_one_cmd_context(
|
||||
case CMD_verbose:
|
||||
case CMD_vertical:
|
||||
case CMD_windo:
|
||||
case CMD_vim9cmd:
|
||||
case CMD_legacy:
|
||||
return arg;
|
||||
|
||||
case CMD_filter:
|
||||
@@ -1555,10 +1557,12 @@ set_one_cmd_context(
|
||||
|
||||
case CMD_function:
|
||||
case CMD_delfunction:
|
||||
case CMD_disassemble:
|
||||
xp->xp_context = EXPAND_USER_FUNC;
|
||||
xp->xp_pattern = arg;
|
||||
break;
|
||||
case CMD_disassemble:
|
||||
set_context_in_disassemble_cmd(xp, arg);
|
||||
break;
|
||||
|
||||
case CMD_echohl:
|
||||
set_context_in_echohl_cmd(xp, arg);
|
||||
@@ -2127,6 +2131,7 @@ ExpandFromContext(
|
||||
{EXPAND_USER_VARS, get_user_var_name, FALSE, TRUE},
|
||||
{EXPAND_FUNCTIONS, get_function_name, FALSE, TRUE},
|
||||
{EXPAND_USER_FUNC, get_user_func_name, FALSE, TRUE},
|
||||
{EXPAND_DISASSEMBLE, get_disassemble_argument, FALSE, TRUE},
|
||||
{EXPAND_EXPRESSION, get_expr_name, FALSE, TRUE},
|
||||
# endif
|
||||
# ifdef FEAT_MENU
|
||||
|
||||
+4
-1
@@ -1558,7 +1558,10 @@ if test "$enable_python3interp" = "yes" -o "$enable_python3interp" = "dynamic";
|
||||
[
|
||||
vi_cv_path_python3_conf=
|
||||
config_dir="config-${vi_cv_var_python3_version}${vi_cv_var_python3_abiflags}"
|
||||
d=`${vi_cv_path_python3} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBPL'))"`
|
||||
d=`${vi_cv_path_python3} -c "import sysconfig; print(sysconfig.get_config_var('LIBPL'))" 2> /dev/null`
|
||||
if test "x$d" = "x"; then
|
||||
d=`${vi_cv_path_python3} -c "import distutils.sysconfig; print(distutils.sysconfig.get_config_var('LIBPL'))"`
|
||||
fi
|
||||
if test -d "$d" && test -f "$d/config.c"; then
|
||||
vi_cv_path_python3_conf="$d"
|
||||
else
|
||||
|
||||
+1
-1
@@ -218,7 +218,7 @@ do_debug(char_u *cmd)
|
||||
|
||||
if (last_cmd != 0)
|
||||
{
|
||||
// Execute debug command: decided where to break next and
|
||||
// Execute debug command: decide where to break next and
|
||||
// return.
|
||||
switch (last_cmd)
|
||||
{
|
||||
|
||||
@@ -423,3 +423,7 @@ EXTERN char e_one_argument_too_few[]
|
||||
INIT(= N_("E1190: One argument too few"));
|
||||
EXTERN char e_nr_arguments_too_few[]
|
||||
INIT(= N_("E1190: %d arguments too few"));
|
||||
EXTERN char e_call_to_function_that_failed_to_compile_str[]
|
||||
INIT(= N_("E1191: Call to function that failed to compile: %s"));
|
||||
EXTERN char e_empty_function_name[]
|
||||
INIT(= N_("E1192: Empty function name"));
|
||||
|
||||
+21
-4
@@ -3530,9 +3530,13 @@ eval7(
|
||||
{
|
||||
ufunc_T *ufunc = rettv->vval.v_partial->pt_func;
|
||||
|
||||
// compile it here to get the return type
|
||||
// Compile it here to get the return type. The return
|
||||
// type is optional, when it's missing use t_unknown.
|
||||
// This is recognized in compile_return().
|
||||
if (ufunc->uf_ret_type->tt_type == VAR_VOID)
|
||||
ufunc->uf_ret_type = &t_unknown;
|
||||
if (compile_def_function(ufunc,
|
||||
TRUE, PROFILING(ufunc), NULL) == FAIL)
|
||||
FALSE, COMPILE_TYPE(ufunc), NULL) == FAIL)
|
||||
{
|
||||
clear_tv(rettv);
|
||||
ret = FAIL;
|
||||
@@ -3772,7 +3776,15 @@ call_func_rettv(
|
||||
s = partial_name(pt);
|
||||
}
|
||||
else
|
||||
{
|
||||
s = functv.vval.v_string;
|
||||
if (s == NULL || *s == NUL)
|
||||
{
|
||||
emsg(_(e_empty_function_name));
|
||||
ret = FAIL;
|
||||
goto theend;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
s = (char_u *)"";
|
||||
@@ -3786,6 +3798,7 @@ call_func_rettv(
|
||||
funcexe.basetv = basetv;
|
||||
ret = get_func_tv(s, -1, rettv, arg, evalarg, &funcexe);
|
||||
|
||||
theend:
|
||||
// Clear the funcref afterwards, so that deleting it while
|
||||
// evaluating the arguments is possible (see test55).
|
||||
if (evaluate)
|
||||
@@ -4301,6 +4314,9 @@ partial_free(partial_T *pt)
|
||||
else
|
||||
func_ptr_unref(pt->pt_func);
|
||||
|
||||
// "out_up" is no longer used, decrement refcount on partial that owns it.
|
||||
partial_unref(pt->pt_outer.out_up_partial);
|
||||
|
||||
// Decrease the reference count for the context of a closure. If down
|
||||
// to the minimum it may be time to free it.
|
||||
if (pt->pt_funcstack != NULL)
|
||||
@@ -5786,8 +5802,9 @@ handle_subscript(
|
||||
p = eval_next_non_blank(*arg, evalarg, &getnext);
|
||||
if (getnext
|
||||
&& ((rettv->v_type == VAR_DICT && *p == '.' && eval_isdictc(p[1]))
|
||||
|| (p[0] == '-' && p[1] == '>'
|
||||
&& (p[2] == '{' || ASCII_ISALPHA(p[2])))))
|
||||
|| (p[0] == '-' && p[1] == '>' && (p[2] == '{'
|
||||
|| ASCII_ISALPHA(in_vim9script() ? *skipwhite(p + 2)
|
||||
: p[2])))))
|
||||
{
|
||||
*arg = eval_next_line(evalarg);
|
||||
p = *arg;
|
||||
|
||||
+14
-8
@@ -1441,6 +1441,7 @@ ex_let_one(
|
||||
case '%': n = (long)num_modulus(numval, n,
|
||||
&failed); break;
|
||||
}
|
||||
s = NULL;
|
||||
}
|
||||
else if (opt_type == gov_string
|
||||
&& stringval != NULL && s != NULL)
|
||||
@@ -2572,13 +2573,17 @@ eval_variable(
|
||||
cc = name[len];
|
||||
name[len] = NUL;
|
||||
|
||||
// Check for user-defined variables.
|
||||
v = find_var(name, NULL, flags & EVAL_VAR_NOAUTOLOAD);
|
||||
if (v != NULL)
|
||||
// Check for local variable when debugging.
|
||||
if ((tv = lookup_debug_var(name)) == NULL)
|
||||
{
|
||||
tv = &v->di_tv;
|
||||
if (dip != NULL)
|
||||
*dip = v;
|
||||
// Check for user-defined variables.
|
||||
v = find_var(name, NULL, flags & EVAL_VAR_NOAUTOLOAD);
|
||||
if (v != NULL)
|
||||
{
|
||||
tv = &v->di_tv;
|
||||
if (dip != NULL)
|
||||
*dip = v;
|
||||
}
|
||||
}
|
||||
|
||||
if (tv == NULL && (in_vim9script() || STRNCMP(name, "s:", 2) == 0))
|
||||
@@ -2922,8 +2927,9 @@ find_var_ht(char_u *name, char_u **varname)
|
||||
if (ht != NULL)
|
||||
return ht; // local variable
|
||||
|
||||
// in Vim9 script items at the script level are script-local
|
||||
if (in_vim9script())
|
||||
// In Vim9 script items at the script level are script-local, except
|
||||
// for autoload names.
|
||||
if (in_vim9script() && vim_strchr(name, AUTOLOAD_CHAR) == NULL)
|
||||
{
|
||||
ht = get_script_local_ht();
|
||||
if (ht != NULL)
|
||||
|
||||
+30
-30
@@ -6,31 +6,31 @@
|
||||
static const unsigned short cmdidxs1[26] =
|
||||
{
|
||||
/* a */ 0,
|
||||
/* b */ 19,
|
||||
/* c */ 43,
|
||||
/* d */ 110,
|
||||
/* e */ 135,
|
||||
/* f */ 162,
|
||||
/* g */ 179,
|
||||
/* h */ 185,
|
||||
/* i */ 194,
|
||||
/* j */ 213,
|
||||
/* k */ 215,
|
||||
/* l */ 220,
|
||||
/* m */ 283,
|
||||
/* n */ 303,
|
||||
/* o */ 323,
|
||||
/* p */ 335,
|
||||
/* q */ 374,
|
||||
/* r */ 377,
|
||||
/* s */ 397,
|
||||
/* t */ 466,
|
||||
/* u */ 512,
|
||||
/* v */ 523,
|
||||
/* w */ 544,
|
||||
/* x */ 558,
|
||||
/* y */ 568,
|
||||
/* z */ 569
|
||||
/* b */ 20,
|
||||
/* c */ 44,
|
||||
/* d */ 111,
|
||||
/* e */ 136,
|
||||
/* f */ 164,
|
||||
/* g */ 181,
|
||||
/* h */ 187,
|
||||
/* i */ 196,
|
||||
/* j */ 216,
|
||||
/* k */ 218,
|
||||
/* l */ 223,
|
||||
/* m */ 286,
|
||||
/* n */ 306,
|
||||
/* o */ 326,
|
||||
/* p */ 338,
|
||||
/* q */ 377,
|
||||
/* r */ 380,
|
||||
/* s */ 400,
|
||||
/* t */ 470,
|
||||
/* u */ 516,
|
||||
/* v */ 527,
|
||||
/* w */ 548,
|
||||
/* x */ 562,
|
||||
/* y */ 572,
|
||||
/* z */ 573
|
||||
};
|
||||
|
||||
/*
|
||||
@@ -41,15 +41,15 @@ static const unsigned short cmdidxs1[26] =
|
||||
*/
|
||||
static const unsigned char cmdidxs2[26][26] =
|
||||
{ /* a b c d e f g h i j k l m n o p q r s t u v w x y z */
|
||||
/* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 5, 6, 0, 0, 0, 7, 15, 0, 16, 0, 0, 0, 0, 0 },
|
||||
/* a */ { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 6, 7, 0, 0, 0, 8, 16, 0, 17, 0, 0, 0, 0, 0 },
|
||||
/* b */ { 2, 0, 0, 5, 6, 8, 0, 0, 0, 0, 0, 9, 10, 11, 12, 13, 0, 14, 0, 0, 0, 0, 23, 0, 0, 0 },
|
||||
/* c */ { 3, 12, 16, 18, 20, 22, 25, 0, 0, 0, 0, 33, 38, 41, 47, 57, 59, 60, 61, 0, 63, 0, 66, 0, 0, 0 },
|
||||
/* d */ { 0, 0, 0, 0, 0, 0, 0, 0, 8, 18, 0, 19, 0, 0, 20, 0, 0, 22, 23, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 11, 0, 0, 0, 0, 0, 0, 0, 21, 0, 22, 0, 0 },
|
||||
/* e */ { 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 11, 0, 0, 0, 0, 0, 0, 0, 22, 0, 23, 0, 0 },
|
||||
/* f */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0 },
|
||||
/* g */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 2, 0, 0, 4, 5, 0, 0, 0, 0 },
|
||||
/* h */ { 5, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 14, 0, 16, 0, 0, 0, 0, 0 },
|
||||
/* i */ { 1, 0, 0, 0, 0, 3, 0, 0, 0, 4, 0, 5, 6, 0, 0, 0, 0, 0, 15, 0, 17, 0, 0, 0, 0, 0 },
|
||||
/* j */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 },
|
||||
/* k */ { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* l */ { 3, 11, 15, 19, 20, 25, 28, 33, 0, 0, 0, 35, 38, 41, 45, 51, 0, 53, 62, 54, 55, 59, 61, 0, 0, 0 },
|
||||
@@ -59,7 +59,7 @@ static const unsigned char cmdidxs2[26][26] =
|
||||
/* p */ { 1, 0, 3, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 9, 0, 0, 16, 17, 26, 0, 27, 0, 28, 0 },
|
||||
/* q */ { 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* r */ { 0, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 19, 0, 0, 0, 0 },
|
||||
/* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 63, 64, 0, 65, 0 },
|
||||
/* s */ { 2, 6, 15, 0, 19, 23, 0, 25, 26, 0, 0, 29, 31, 35, 39, 41, 0, 50, 0, 51, 0, 64, 65, 0, 66, 0 },
|
||||
/* t */ { 2, 0, 19, 0, 24, 26, 0, 27, 0, 28, 0, 29, 33, 36, 38, 39, 0, 40, 42, 0, 43, 0, 0, 0, 45, 0 },
|
||||
/* u */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
|
||||
/* v */ { 1, 0, 0, 0, 2, 0, 0, 0, 5, 0, 0, 0, 12, 15, 0, 0, 0, 0, 18, 0, 19, 0, 0, 0, 0, 0 },
|
||||
@@ -69,4 +69,4 @@ static const unsigned char cmdidxs2[26][26] =
|
||||
/* z */ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static const int command_count = 586;
|
||||
static const int command_count = 590;
|
||||
|
||||
@@ -122,6 +122,9 @@ EXCMD(CMD_abclear, "abclear", ex_abclear,
|
||||
EXCMD(CMD_aboveleft, "aboveleft", ex_wrongmodifier,
|
||||
EX_NEEDARG|EX_EXTRA|EX_NOTRLCOM,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_abstract, "abstract", ex_ni,
|
||||
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_all, "all", ex_all,
|
||||
EX_BANG|EX_RANGE|EX_COUNT|EX_TRLBAR,
|
||||
ADDR_OTHER),
|
||||
@@ -551,6 +554,9 @@ EXCMD(CMD_emenu, "emenu", ex_emenu,
|
||||
EXCMD(CMD_endif, "endif", ex_endif,
|
||||
EX_TRLBAR|EX_SBOXOK|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_endinterface, "endinterface", ex_ni,
|
||||
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_endclass, "endclass", ex_ni,
|
||||
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
@@ -734,6 +740,9 @@ EXCMD(CMD_inoremenu, "inoremenu", ex_menu,
|
||||
EXCMD(CMD_intro, "intro", ex_intro,
|
||||
EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_interface, "interface", ex_ni,
|
||||
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_isearch, "isearch", ex_findpat,
|
||||
EX_BANG|EX_RANGE|EX_DFLALL|EX_WHOLEFOLD|EX_EXTRA|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_LINES),
|
||||
@@ -1469,6 +1478,9 @@ EXCMD(CMD_startgreplace, "startgreplace", ex_startinsert,
|
||||
EXCMD(CMD_startreplace, "startreplace", ex_startinsert,
|
||||
EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_static, "static", ex_ni,
|
||||
EX_EXTRA|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
EXCMD(CMD_stopinsert, "stopinsert", ex_stopinsert,
|
||||
EX_BANG|EX_TRLBAR|EX_CMDWIN|EX_LOCK_OK,
|
||||
ADDR_NONE),
|
||||
|
||||
+1
-1
@@ -1850,7 +1850,7 @@ do_one_cmd(
|
||||
|
||||
// If a ':' before the range is missing, give a clearer error
|
||||
// message.
|
||||
if (ar > ea.cmd)
|
||||
if (ar > ea.cmd && !ea.skip)
|
||||
{
|
||||
semsg(_(e_colon_required_before_range_str), ea.cmd);
|
||||
goto doend;
|
||||
|
||||
@@ -3105,6 +3105,9 @@ gui_send_mouse_event(
|
||||
*/
|
||||
switch (button)
|
||||
{
|
||||
case MOUSE_MOVE:
|
||||
button_char = KE_MOUSEMOVE_XY;
|
||||
goto button_set;
|
||||
case MOUSE_X1:
|
||||
button_char = KE_X1MOUSE;
|
||||
goto button_set;
|
||||
@@ -4965,7 +4968,7 @@ gui_mouse_moved(int x, int y)
|
||||
if (popup_visible)
|
||||
// Generate a mouse-moved event, so that the popup can perhaps be
|
||||
// closed, just like in the terminal.
|
||||
gui_send_mouse_event(MOUSE_DRAG, x, y, FALSE, 0);
|
||||
gui_send_mouse_event(MOUSE_MOVE, x, y, FALSE, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +253,9 @@ addEventHandler(GtkWidget *target, BalloonEval *beval)
|
||||
if (gtk_socket_id == 0 && gui.mainwin != NULL
|
||||
&& gtk_widget_is_ancestor(target, gui.mainwin))
|
||||
{
|
||||
gtk_widget_add_events(gui.mainwin,
|
||||
GDK_LEAVE_NOTIFY_MASK);
|
||||
|
||||
g_signal_connect(G_OBJECT(gui.mainwin), "event",
|
||||
G_CALLBACK(mainwin_event_cb),
|
||||
beval);
|
||||
@@ -360,6 +363,12 @@ mainwin_event_cb(GtkWidget *widget UNUSED, GdkEvent *event, gpointer data)
|
||||
case GDK_KEY_RELEASE:
|
||||
key_event(beval, event->key.keyval, FALSE);
|
||||
break;
|
||||
case GDK_LEAVE_NOTIFY:
|
||||
// Ignore LeaveNotify events that are not "normal".
|
||||
// Apparently we also get it when somebody else grabs focus.
|
||||
if (event->crossing.mode == GDK_CROSSING_NORMAL)
|
||||
cancelBalloon(beval);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -184,6 +184,9 @@ typedef PySliceObject PySliceObject_T;
|
||||
# ifndef PyMapping_Keys
|
||||
# define PyMapping_Keys py3_PyMapping_Keys
|
||||
# endif
|
||||
# if PY_VERSION_HEX >= 0x030a00b2
|
||||
# define PyIter_Check py3_PyIter_Check
|
||||
# endif
|
||||
# define PyIter_Next py3_PyIter_Next
|
||||
# define PyObject_GetIter py3_PyObject_GetIter
|
||||
# define PyObject_Repr py3_PyObject_Repr
|
||||
@@ -358,6 +361,9 @@ static PyObject* (*py3_PyDict_GetItemString)(PyObject *, const char *);
|
||||
static int (*py3_PyDict_Next)(PyObject *, Py_ssize_t *, PyObject **, PyObject **);
|
||||
static PyObject* (*py3_PyLong_FromLong)(long);
|
||||
static PyObject* (*py3_PyDict_New)(void);
|
||||
# if PY_VERSION_HEX >= 0x030a00b2
|
||||
static int (*py3_PyIter_Check)(PyObject *o);
|
||||
# endif
|
||||
static PyObject* (*py3_PyIter_Next)(PyObject *);
|
||||
static PyObject* (*py3_PyObject_GetIter)(PyObject *);
|
||||
static PyObject* (*py3_PyObject_Repr)(PyObject *);
|
||||
@@ -538,6 +544,9 @@ static struct
|
||||
{"PyDict_Next", (PYTHON_PROC*)&py3_PyDict_Next},
|
||||
{"PyMapping_Check", (PYTHON_PROC*)&py3_PyMapping_Check},
|
||||
{"PyMapping_Keys", (PYTHON_PROC*)&py3_PyMapping_Keys},
|
||||
# if PY_VERSION_HEX >= 0x030a00b2
|
||||
{"PyIter_Check", (PYTHON_PROC*)&py3_PyIter_Check},
|
||||
# endif
|
||||
{"PyIter_Next", (PYTHON_PROC*)&py3_PyIter_Next},
|
||||
{"PyObject_GetIter", (PYTHON_PROC*)&py3_PyObject_GetIter},
|
||||
{"PyObject_Repr", (PYTHON_PROC*)&py3_PyObject_Repr},
|
||||
@@ -671,6 +680,15 @@ py3_PyType_HasFeature(PyTypeObject *type, unsigned long feature)
|
||||
# define PyType_HasFeature(t,f) py3_PyType_HasFeature(t,f)
|
||||
# endif
|
||||
|
||||
# if PY_VERSION_HEX >= 0x030a00b2
|
||||
static inline int
|
||||
py3__PyObject_TypeCheck(PyObject *ob, PyTypeObject *type)
|
||||
{
|
||||
return Py_IS_TYPE(ob, type) || PyType_IsSubtype(Py_TYPE(ob), type);
|
||||
}
|
||||
# define _PyObject_TypeCheck(o,t) py3__PyObject_TypeCheck(o,t)
|
||||
# endif
|
||||
|
||||
# ifdef MSWIN
|
||||
/*
|
||||
* Look up the library "libname" using the InstallPath registry key.
|
||||
|
||||
+1
-1
@@ -1531,7 +1531,7 @@ tclsetdelcmd(
|
||||
reflist = reflist->next;
|
||||
}
|
||||
// This should never happen. Famous last word?
|
||||
emsg(_("E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"));
|
||||
iemsg(_("E280: TCL FATAL ERROR: reflist corrupt!? Please report this to vim-dev@vim.org"));
|
||||
Tcl_SetResult(interp, _("cannot register callback command: buffer/window reference not found"), TCL_STATIC);
|
||||
return TCL_ERROR;
|
||||
}
|
||||
|
||||
+8
-7
@@ -273,15 +273,16 @@ enum key_extra
|
||||
, KE_FOCUSGAINED = 98 // focus gained
|
||||
, KE_FOCUSLOST = 99 // focus lost
|
||||
, KE_MOUSEMOVE = 100 // mouse moved with no button down
|
||||
, KE_CANCEL = 101 // return from vgetc()
|
||||
, KE_COMMAND = 102 // <Cmd> special key
|
||||
, KE_MOUSEMOVE_XY = 101 // KE_MOUSEMOVE with coordinates
|
||||
, KE_CANCEL = 102 // return from vgetc()
|
||||
, KE_COMMAND = 103 // <Cmd> special key
|
||||
|
||||
#ifdef FEAT_GUI_MACVIM
|
||||
, KE_SWIPELEFT = 103 // Swipe trackpad left
|
||||
, KE_SWIPERIGHT = 104 // Swipe trackpad right
|
||||
, KE_SWIPEUP = 105 // Swipe trackpad up
|
||||
, KE_SWIPEDOWN = 106 // Swipe trackpad down
|
||||
, KE_FORCECLICK = 107 // Force click on trackpad
|
||||
, KE_SWIPELEFT = 104 // Swipe trackpad left
|
||||
, KE_SWIPERIGHT = 105 // Swipe trackpad right
|
||||
, KE_SWIPEUP = 106 // Swipe trackpad up
|
||||
, KE_SWIPEDOWN = 107 // Swipe trackpad down
|
||||
, KE_FORCECLICK = 108 // Force click on trackpad
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
+1
-2
@@ -733,8 +733,7 @@ codepage_invalid:
|
||||
|
||||
// When using Unicode, set default for 'fileencodings'.
|
||||
if (enc_utf8 && !option_was_set((char_u *)"fencs"))
|
||||
set_string_option_direct((char_u *)"fencs", -1,
|
||||
(char_u *)"ucs-bom,utf-8,default,latin1", OPT_FREE, 0);
|
||||
set_fencs_unicode();
|
||||
|
||||
#if defined(HAVE_BIND_TEXTDOMAIN_CODESET) && defined(FEAT_GETTEXT)
|
||||
// GNU gettext 0.10.37 supports this feature: set the codeset used for
|
||||
|
||||
@@ -1696,6 +1696,7 @@ ml_recover(int checkext)
|
||||
&& !(curbuf->b_ml.ml_flags & ML_EMPTY))
|
||||
ml_delete(curbuf->b_ml.ml_line_count);
|
||||
curbuf->b_flags |= BF_RECOVERED;
|
||||
check_cursor();
|
||||
|
||||
recoverymode = FALSE;
|
||||
if (got_int)
|
||||
|
||||
+11
-9
@@ -2756,19 +2756,21 @@ msg_puts_printf(char_u *str, int maxlen)
|
||||
|
||||
if (*p != NUL && !(silent_mode && p_verbose == 0))
|
||||
{
|
||||
int c = -1;
|
||||
char_u *tofree = NULL;
|
||||
|
||||
if (maxlen > 0 && STRLEN(p) > (size_t)maxlen)
|
||||
{
|
||||
c = p[maxlen];
|
||||
p[maxlen] = 0;
|
||||
tofree = vim_strnsave(p, (size_t)maxlen);
|
||||
p = tofree;
|
||||
}
|
||||
if (p != NULL)
|
||||
{
|
||||
if (info_message)
|
||||
mch_msg((char *)p);
|
||||
else
|
||||
mch_errmsg((char *)p);
|
||||
vim_free(tofree);
|
||||
}
|
||||
if (info_message)
|
||||
mch_msg((char *)p);
|
||||
else
|
||||
mch_errmsg((char *)p);
|
||||
if (c != -1)
|
||||
p[maxlen] = c;
|
||||
}
|
||||
|
||||
msg_didout = TRUE; // assume that line is not empty
|
||||
|
||||
@@ -2988,6 +2988,9 @@ dozet:
|
||||
case 'P':
|
||||
case 'p': nv_put(cap);
|
||||
break;
|
||||
// "zy" Yank without trailing spaces
|
||||
case 'y': nv_operator(cap);
|
||||
break;
|
||||
#ifdef FEAT_FOLDING
|
||||
// "zF": create fold command
|
||||
// "zf": create fold operator
|
||||
|
||||
@@ -78,6 +78,8 @@ get_op_type(int char1, int char2)
|
||||
return OP_NR_ADD;
|
||||
if (char1 == 'g' && char2 == Ctrl_X) // subtract
|
||||
return OP_NR_SUB;
|
||||
if (char1 == 'z' && char2 == 'y') // OP_YANK
|
||||
return OP_YANK;
|
||||
for (i = 0; ; ++i)
|
||||
{
|
||||
if (opchars[i][0] == char1 && opchars[i][1] == char2)
|
||||
@@ -3894,6 +3896,7 @@ do_pending_operator(cmdarg_T *cap, int old_col, int gui_yank)
|
||||
#ifdef FEAT_LINEBREAK
|
||||
curwin->w_p_lbr = lbr_saved;
|
||||
#endif
|
||||
oap->excl_tr_ws = cap->cmdchar == 'z';
|
||||
(void)op_yank(oap, FALSE, !gui_yank);
|
||||
}
|
||||
check_cursor_col();
|
||||
|
||||
+19
-1
@@ -553,6 +553,19 @@ set_init_1(int clean_arg)
|
||||
#endif
|
||||
}
|
||||
|
||||
static char_u *fencs_utf8_default = (char_u *)"ucs-bom,utf-8,default,latin1";
|
||||
|
||||
/*
|
||||
* Set the "fileencodings" option to the default value for when 'encoding' is
|
||||
* utf-8.
|
||||
*/
|
||||
void
|
||||
set_fencs_unicode()
|
||||
{
|
||||
set_string_option_direct((char_u *)"fencs", -1, fencs_utf8_default,
|
||||
OPT_FREE, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set an option to its default value.
|
||||
* This does not take care of side effects!
|
||||
@@ -576,9 +589,12 @@ set_option_default(
|
||||
dvi = ((flags & P_VI_DEF) || compatible) ? VI_DEFAULT : VIM_DEFAULT;
|
||||
if (flags & P_STRING)
|
||||
{
|
||||
// 'fencs' default value depends on 'encoding'
|
||||
if (options[opt_idx].var == (char_u *)&p_fencs && enc_utf8)
|
||||
set_fencs_unicode();
|
||||
// Use set_string_option_direct() for local options to handle
|
||||
// freeing and allocating the value.
|
||||
if (options[opt_idx].indir != PV_NONE)
|
||||
else if (options[opt_idx].indir != PV_NONE)
|
||||
set_string_option_direct(NULL, opt_idx,
|
||||
options[opt_idx].def_val[dvi], opt_flags, 0);
|
||||
else
|
||||
@@ -1702,6 +1718,8 @@ do_set(
|
||||
#endif
|
||||
newval = term_bg_default();
|
||||
}
|
||||
else if ((char_u **)varp == &p_fencs && enc_utf8)
|
||||
newval = fencs_utf8_default;
|
||||
|
||||
// expand environment variables and ~ (since the
|
||||
// default value was already expanded, only
|
||||
|
||||
+4
-4
@@ -7558,7 +7558,7 @@ myresetstkoflw(void)
|
||||
|
||||
|
||||
/*
|
||||
* The command line arguments in UCS2
|
||||
* The command line arguments in UTF-16
|
||||
*/
|
||||
static int nArgsW = 0;
|
||||
static LPWSTR *ArglistW = NULL;
|
||||
@@ -7601,8 +7601,8 @@ get_cmd_argsW(char ***argvp)
|
||||
{
|
||||
int len;
|
||||
|
||||
// Convert each Unicode argument to the current codepage.
|
||||
WideCharToMultiByte_alloc(GetACP(), 0,
|
||||
// Convert each Unicode argument to UTF-8.
|
||||
WideCharToMultiByte_alloc(CP_UTF8, 0,
|
||||
ArglistW[i], (int)wcslen(ArglistW[i]) + 1,
|
||||
(LPSTR *)&argv[i], &len, 0, 0);
|
||||
if (argv[i] == NULL)
|
||||
@@ -7678,7 +7678,7 @@ set_alist_count(void)
|
||||
|
||||
/*
|
||||
* Fix the encoding of the command line arguments. Invoked when 'encoding'
|
||||
* has been changed while starting up. Use the UCS-2 command line arguments
|
||||
* has been changed while starting up. Use the UTF-16 command line arguments
|
||||
* and convert them to 'encoding'.
|
||||
*/
|
||||
void
|
||||
|
||||
+169
-52
@@ -2,7 +2,7 @@
|
||||
#
|
||||
# Do ":help uganda" in Vim to read copying and usage conditions.
|
||||
# Do ":help credits" in Vim to see a list of people who contributed.
|
||||
# Copyright (C) 2017
|
||||
# Copyright (C) 2021
|
||||
# This file is distributed under the same license as the Vim package.
|
||||
# FIRST AUTHOR Ivan Pešić <ivan.pesic@gmail.com>, 2017.
|
||||
#
|
||||
@@ -10,8 +10,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Vim(Serbian)\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-14 01:49+0400\n"
|
||||
"PO-Revision-Date: 2021-02-14 01:54+0400\n"
|
||||
"POT-Creation-Date: 2021-06-13 13:16+0400\n"
|
||||
"PO-Revision-Date: 2021-06-13 13:50+0400\n"
|
||||
"Last-Translator: Ivan Pešić <ivan.pesic@gmail.com>\n"
|
||||
"Language-Team: Serbian\n"
|
||||
"Language: sr\n"
|
||||
@@ -97,6 +97,9 @@ msgstr "Извршавање %s"
|
||||
msgid "autocommand %s"
|
||||
msgstr "аутокоманда %s"
|
||||
|
||||
msgid "E972: Blob value does not have the right number of bytes"
|
||||
msgstr "E972: Блоб вредност нема одговарајући број бајтова"
|
||||
|
||||
msgid "E831: bf_key_init() called with empty password"
|
||||
msgstr "E831: bf_key_init() је позвана са празном лозинком"
|
||||
|
||||
@@ -731,9 +734,6 @@ msgstr "E708: [:] мора да буде последња"
|
||||
msgid "E709: [:] requires a List or Blob value"
|
||||
msgstr "E709: [:] захтева вредност типа Листа или Блоб"
|
||||
|
||||
msgid "E972: Blob value does not have the right number of bytes"
|
||||
msgstr "E972: Блоб вредност нема одговарајући број бајтова"
|
||||
|
||||
msgid "E996: Cannot lock a range"
|
||||
msgstr "E996: Опсег не може да се закључа"
|
||||
|
||||
@@ -763,9 +763,6 @@ msgstr ""
|
||||
"\n"
|
||||
"\tПоследње постављено из "
|
||||
|
||||
msgid "E808: Number or Float required"
|
||||
msgstr "E808: Захтева се Број или Покретни"
|
||||
|
||||
#, c-format
|
||||
msgid "E158: Invalid buffer name: %s"
|
||||
msgstr "E158: Неисправно име бафера: %s"
|
||||
@@ -932,6 +929,10 @@ msgstr "E135: *Филтер* Аутокоманде не смеју да мењ
|
||||
msgid "[No write since last change]\n"
|
||||
msgstr "[Нема уписа од последње промене]\n"
|
||||
|
||||
#, c-format
|
||||
msgid "E503: \"%s\" is not a file or writable device"
|
||||
msgstr "E503: „%s” није фајл или уређај на који може да се уписује"
|
||||
|
||||
msgid "Save As"
|
||||
msgstr "Сачувај као"
|
||||
|
||||
@@ -1594,6 +1595,9 @@ msgstr "E446: Под курсором се не налази име фајла"
|
||||
msgid "E447: Can't find file \"%s\" in path"
|
||||
msgstr "E447: Фајл \"%s\" не може да се пронађе у путањи"
|
||||
|
||||
msgid "E808: Number or Float required"
|
||||
msgstr "E808: Захтева се Број или Покретни"
|
||||
|
||||
msgid "E490: No fold found"
|
||||
msgstr "E490: Није пронађен ниједан свијутак"
|
||||
|
||||
@@ -4069,12 +4073,12 @@ msgstr "E531: Користите \":gui\" да покренете ГКИ"
|
||||
msgid "E589: 'backupext' and 'patchmode' are equal"
|
||||
msgstr "E589: 'backupext' и 'patchmode' су истоветни"
|
||||
|
||||
msgid "E834: Conflicts with value of 'listchars'"
|
||||
msgstr "E834: У конфликту са вредношћу 'listchars'"
|
||||
|
||||
msgid "E835: Conflicts with value of 'fillchars'"
|
||||
msgstr "E835: У конфликту са вредношћу 'fillchars'"
|
||||
|
||||
msgid "E834: Conflicts with value of 'listchars'"
|
||||
msgstr "E834: У конфликту са вредношћу 'listchars'"
|
||||
|
||||
msgid "E617: Cannot be changed in the GTK+ 2 GUI"
|
||||
msgstr "E617: Не може да се промени у GTK+ 2 ГКИ"
|
||||
|
||||
@@ -4513,7 +4517,7 @@ msgstr "E554: Синтаксна грешка у %s{...}"
|
||||
|
||||
#, c-format
|
||||
msgid "E888: (NFA regexp) cannot repeat %s"
|
||||
msgstr "E888: (НКА регизраз) не може да се понови %s"
|
||||
msgstr "E888: (НКА регуларни израз) не може да се понови %s"
|
||||
|
||||
msgid ""
|
||||
"E864: \\%#= can only be followed by 0, 1, or 2. The automatic engine will be "
|
||||
@@ -4579,15 +4583,15 @@ msgid "External submatches:\n"
|
||||
msgstr "Спољна подподударања:\n"
|
||||
|
||||
msgid "E865: (NFA) Regexp end encountered prematurely"
|
||||
msgstr "E865: (НКА) прерано је достигнут крај регизраза"
|
||||
msgstr "E865: (НКА) прерано је достигнут крај регуларног израза"
|
||||
|
||||
#, c-format
|
||||
msgid "E866: (NFA regexp) Misplaced %c"
|
||||
msgstr "E866: (НКА регизраз) %c је на погрешном месту"
|
||||
msgstr "E866: (НКА регуларни израз) %c је на погрешном месту"
|
||||
|
||||
#, c-format
|
||||
msgid "E877: (NFA regexp) Invalid character class: %d"
|
||||
msgstr "E877: (НКА регизраз) Неважећа карактер класа: %d"
|
||||
msgstr "E877: (НКА регуларни израз) Неважећа карактер класа: %d"
|
||||
|
||||
msgid "E951: \\% value too large"
|
||||
msgstr "E951: Вредност \\% је предугачка"
|
||||
@@ -4608,19 +4612,19 @@ msgid "E869: (NFA) Unknown operator '\\@%c'"
|
||||
msgstr "E869: (НКА) Непознати оператор '\\@%c'"
|
||||
|
||||
msgid "E870: (NFA regexp) Error reading repetition limits"
|
||||
msgstr "E870: (НКА регизраз) Грешка при читању граница понављања"
|
||||
msgstr "E870: (НКА регуларни израз) Грешка при читању граница понављања"
|
||||
|
||||
msgid "E871: (NFA regexp) Can't have a multi follow a multi"
|
||||
msgstr "E871: (НКА регизраз) Мулти не може следи иза мулти"
|
||||
msgstr "E871: (НКА регуларни израз) Мулти не може следи иза мулти"
|
||||
|
||||
msgid "E872: (NFA regexp) Too many '('"
|
||||
msgstr "E872: (НКА регизраз) Превише '('"
|
||||
msgstr "E872: (НКА регуларни израз) Превише '('"
|
||||
|
||||
msgid "E879: (NFA regexp) Too many \\z("
|
||||
msgstr "E879: (НКА регизраз) Превише \\z("
|
||||
msgstr "E879: (НКА регуларни израз) Превише \\z("
|
||||
|
||||
msgid "E873: (NFA regexp) proper termination error"
|
||||
msgstr "E873: (НКА регизраз) грешка правилне терминације"
|
||||
msgstr "E873: (НКА регуларни израз) грешка правилне терминације"
|
||||
|
||||
msgid "Could not open temporary log file for writing, displaying on stderr... "
|
||||
msgstr ""
|
||||
@@ -4634,12 +4638,12 @@ msgid ""
|
||||
"E875: (NFA regexp) (While converting from postfix to NFA), too many states "
|
||||
"left on stack"
|
||||
msgstr ""
|
||||
"E875: (НКА регизраз) (Док је вршена конверзија из постфикног облика у НКА), "
|
||||
"E875: (НКА регуларни израз) (Док је вршена конверзија из постфикног облика у НКА), "
|
||||
"превише стања је остало на стеку"
|
||||
|
||||
msgid "E876: (NFA regexp) Not enough space to store the whole NFA "
|
||||
msgstr ""
|
||||
"E876: (НКА регизраз) Нема довољно простора да се ускладишти комплетан НКА "
|
||||
"E876: (НКА регуларни израз) Нема довољно простора да се ускладишти комплетан НКА "
|
||||
|
||||
msgid "E878: (NFA) Could not allocate memory for branch traversal!"
|
||||
msgstr "E878: (НКА) Није могла да се алоцира меморија за обилазак грана!"
|
||||
@@ -6027,6 +6031,13 @@ msgstr "E853: Име аргумента је дуплирано: %s"
|
||||
msgid "E989: Non-default argument follows default argument"
|
||||
msgstr "E989: Неподразумевани аргумент следи иза подразумеваног аргумента"
|
||||
|
||||
msgid "E126: Missing :endfunction"
|
||||
msgstr "E126: Недостаје :endfunction"
|
||||
|
||||
#, c-format
|
||||
msgid "W22: Text found after :endfunction: %s"
|
||||
msgstr "W22: Пронађен текст након :endfunction: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E451: Expected }: %s"
|
||||
msgstr "E451: Очекује се }: %s"
|
||||
@@ -6102,17 +6113,6 @@ msgstr "E862: Овде не може да се користи g:"
|
||||
msgid "E932: Closure function should not be at top level: %s"
|
||||
msgstr "E932: Затварајућа функција не би требало да буде на највишем нивоу: %s"
|
||||
|
||||
msgid "E126: Missing :endfunction"
|
||||
msgstr "E126: Недостаје :endfunction"
|
||||
|
||||
#, c-format
|
||||
msgid "W1001: Text found after :enddef: %s"
|
||||
msgstr "W1001: Пронађен је текст након :enddef: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "W22: Text found after :endfunction: %s"
|
||||
msgstr "W22: Пронађен текст након :endfunction: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E707: Function name conflicts with variable: %s"
|
||||
msgstr "E707: Име функције је у конфликту са променљивом: %s"
|
||||
@@ -6635,25 +6635,25 @@ msgid "E366: Not allowed to enter a popup window"
|
||||
msgstr "E366: Није дозвољено да се уђе у искачући прозор"
|
||||
|
||||
msgid "Edit with &multiple Vims"
|
||||
msgstr "Уређуј са &више Vim-ова"
|
||||
msgstr "Уређуј са &више Vim програма"
|
||||
|
||||
msgid "Edit with single &Vim"
|
||||
msgstr "Уређуј са једним &Vim-ом"
|
||||
msgstr "Уређуј са једним програмом &Vim"
|
||||
|
||||
msgid "Diff with Vim"
|
||||
msgstr "Diff са Vim"
|
||||
msgstr "Diff са програмом Vim"
|
||||
|
||||
msgid "Edit with &Vim"
|
||||
msgstr "Уређуј са &Vim-ом"
|
||||
msgstr "Уређуј са програмом &Vim"
|
||||
|
||||
msgid "Edit with existing Vim"
|
||||
msgstr "Уређуј са постојећим Vim-ом"
|
||||
msgstr "Уређуј са постојећим програмом Vim"
|
||||
|
||||
msgid "Edit with existing Vim - "
|
||||
msgstr "Уређуј са постојећим Vim - "
|
||||
msgstr "Уређуј са постојећим програмом Vim - "
|
||||
|
||||
msgid "Edits the selected file(s) with Vim"
|
||||
msgstr "Уређује селектован(е) фајл(ове) са Vim-ом"
|
||||
msgstr "Уређује селектован(е) фајл(ове) програмом Vim"
|
||||
|
||||
msgid "Error creating process: Check if gvim is in your path!"
|
||||
msgstr ""
|
||||
@@ -6699,6 +6699,10 @@ msgstr ""
|
||||
"E856: \"assert_fails()\" други аргумент мора бити стринг или листа са једним "
|
||||
"или два стринга"
|
||||
|
||||
#, c-format
|
||||
msgid "E908: using an invalid value as a String: %s"
|
||||
msgstr "E908: Користи се неважећа вредност као Стринг: %s"
|
||||
|
||||
msgid "E909: Cannot index a special variable"
|
||||
msgstr "E909: Специјална променљива не може да се индексира"
|
||||
|
||||
@@ -7188,8 +7192,8 @@ msgid "E1143: Empty expression: \"%s\""
|
||||
msgstr "E1143: Празан израз: \"%s\""
|
||||
|
||||
#, c-format
|
||||
msgid "E1144: Command is not followed by white space: %s"
|
||||
msgstr "E1144: Иза команде се не налази празан простор: %s"
|
||||
msgid "E1144: Command \"%s\" is not followed by white space: %s"
|
||||
msgstr "E1144: Иза команде „%s” се не налази празан простор: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E1145: Missing heredoc end marker: %s"
|
||||
@@ -7242,7 +7246,8 @@ msgid "E1159: Cannot split a window when closing the buffer"
|
||||
msgstr "E1159: Прозор не може да се подели када се затвара бафер"
|
||||
|
||||
msgid "E1160: Cannot use a default for variable arguments"
|
||||
msgstr "E1160: За аргументе променљиве не може да се користи подразумевана вредност"
|
||||
msgstr ""
|
||||
"E1160: За аргументе променљиве не може да се користи подразумевана вредност"
|
||||
|
||||
#, c-format
|
||||
msgid "E1161: Cannot json encode a %s"
|
||||
@@ -7254,7 +7259,116 @@ msgstr "E1162: Име регистра мора бити један каракт
|
||||
|
||||
#, c-format
|
||||
msgid "E1163: Variable %d: type mismatch, expected %s but got %s"
|
||||
msgstr "E1163: Променљива %d: неодговарајући тип, очекује се %s али је наведено %s"
|
||||
msgstr ""
|
||||
"E1163: Променљива %d: неодговарајући тип, очекује се %s али је наведено %s"
|
||||
|
||||
msgid "E1164: vim9cmd must be followed by a command"
|
||||
msgstr "E1164: Иза vim9cmd мора да следи команда"
|
||||
|
||||
#, c-format
|
||||
msgid "E1165: Cannot use a range with an assignment: %s"
|
||||
msgstr "E1165: Опсег не може да се користи са доделом: %s"
|
||||
|
||||
msgid "E1166: Cannot use a range with a dictionary"
|
||||
msgstr "E1166: Опсег не може да се користи са речником"
|
||||
|
||||
#, c-format
|
||||
msgid "E1167: Argument name shadows existing variable: %s"
|
||||
msgstr "E1167: Име аргумента заклања постојећу променљиву: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E1168: Argument already declared in the script: %s"
|
||||
msgstr "E1168: Аргумент је већ декларисан у скрипти: %s"
|
||||
|
||||
msgid "E1169: 'import * as {name}' not supported here"
|
||||
msgstr "E1169: Овде се не подржава 'import * as {име}'"
|
||||
|
||||
msgid "E1170: Cannot use #{ to start a comment"
|
||||
msgstr "E1170: #{ не може да се користи за почетак коментара"
|
||||
|
||||
msgid "E1171: Missing } after inline function"
|
||||
msgstr "E1171: Након inline функције недостаје }"
|
||||
|
||||
msgid "E1172: Cannot use default values in a lambda"
|
||||
msgstr "E1172: Није могућа употреба подразумеваних вредности у ламбди"
|
||||
|
||||
#, c-format
|
||||
msgid "E1173: Text found after enddef: %s"
|
||||
msgstr "E1173: Пронађен је текст након enddef: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E1174: String required for argument %d"
|
||||
msgstr "E1174: Неопходан је стринг за аргумент %d"
|
||||
|
||||
#, c-format
|
||||
msgid "E1175: Non-empty string required for argument %d"
|
||||
msgstr "E1175: Неопходан је непразни стринг за аргумент %d"
|
||||
|
||||
msgid "E1176: Misplaced command modifier"
|
||||
msgstr "E1176: Модификатор команде није на одговарајућем месту"
|
||||
|
||||
#, c-format
|
||||
msgid "E1177: For loop on %s not supported"
|
||||
msgstr "E1177: Не подржава се for петља над %s"
|
||||
|
||||
msgid "E1178: Cannot lock or unlock a local variable"
|
||||
msgstr "E1178: Локална променљива не може да се закључа или откључа"
|
||||
|
||||
#, c-format
|
||||
msgid ""
|
||||
"E1179: Failed to extract PWD from %s, check your shell's config related to "
|
||||
"OSC 7"
|
||||
msgstr ""
|
||||
"E1179: Није успело издвајање PWD из %s, проверите подешавање командног окружења "
|
||||
"које се тиче OSC 7"
|
||||
|
||||
#, c-format
|
||||
msgid "E1180: Variable arguments type must be a list: %s"
|
||||
msgstr "E1180: Тип променљивих аргумената мора бити листа: %s"
|
||||
|
||||
msgid "E1181: Cannot use an underscore here"
|
||||
msgstr "E1181: Овде не може да се користи доња црта"
|
||||
|
||||
msgid "E1182: Blob required"
|
||||
msgstr "E1182: Потребан је Блоб"
|
||||
|
||||
#, c-format
|
||||
msgid "E1183: Cannot use a range with an assignment operator: %s"
|
||||
msgstr "E1183: Опсег не може да се користи са оператором доделе: %s"
|
||||
|
||||
msgid "E1184: Blob not set"
|
||||
msgstr "E1184: Blob није постављен"
|
||||
|
||||
msgid "E1185: Cannot nest :redir"
|
||||
msgstr "E1185: :redir не може да се угњеждава"
|
||||
|
||||
msgid "E1185: Missing :redir END"
|
||||
msgstr "E1185: Недостаје :redir END"
|
||||
|
||||
#, c-format
|
||||
msgid "E1186: Expression does not result in a value: %s"
|
||||
msgstr "E1186: Резултат израза није вредност: %s"
|
||||
|
||||
msgid "E1187: Failed to source defaults.vim"
|
||||
msgstr "E1187: Није успело учитавање defaults.vim"
|
||||
|
||||
msgid "E1188: Cannot open a terminal from the command line window"
|
||||
msgstr "E1188: Из прозора командне линије не може да се отвори терминал"
|
||||
|
||||
#, c-format
|
||||
msgid "E1189: Cannot use :legacy with this command: %s"
|
||||
msgstr "E1189: :legacy не може да се користи са овом командом: %s"
|
||||
|
||||
msgid "E1190: One argument too few"
|
||||
msgstr "E1190: Фали један аргумент"
|
||||
|
||||
#, c-format
|
||||
msgid "E1190: %d arguments too few"
|
||||
msgstr "E1190: фали %d аргумената"
|
||||
|
||||
#, c-format
|
||||
msgid "E1191: Call to function that failed to compile: %s"
|
||||
msgstr "E1191: Позив функције која није успела да се компајлира: %s"
|
||||
|
||||
msgid "--No lines in buffer--"
|
||||
msgstr "--У баферу нема линија--"
|
||||
@@ -7355,8 +7469,8 @@ msgid "E475: Invalid value for argument %s: %s"
|
||||
msgstr "E475: Неважећа вредност за аргумент %s: %s"
|
||||
|
||||
#, c-format
|
||||
msgid "E15: Invalid expression: %s"
|
||||
msgstr "E15: Неважећи израз: %s"
|
||||
msgid "E15: Invalid expression: \"%s\""
|
||||
msgstr "E15: Неважећи израз: „%s”"
|
||||
|
||||
msgid "E16: Invalid range"
|
||||
msgstr "E16: Неважећи опсег"
|
||||
@@ -7591,9 +7705,6 @@ msgstr "E896: Аргумент за %s мора бити Листа, Речни
|
||||
msgid "E804: Cannot use '%' with Float"
|
||||
msgstr "E804: '%' не може да се користи са Покретни"
|
||||
|
||||
msgid "E908: using an invalid value as a String"
|
||||
msgstr "E908: Користи се недозвољена вредност као Стринг"
|
||||
|
||||
msgid "E996: Cannot lock an option"
|
||||
msgstr "E996: Опција не може да се закључа"
|
||||
|
||||
@@ -8133,6 +8244,9 @@ msgstr "Уређујте текст фајлове"
|
||||
msgid "Text;editor;"
|
||||
msgstr "Текст;едитор;"
|
||||
|
||||
msgid "gvim"
|
||||
msgstr "gvim"
|
||||
|
||||
msgid "Vim"
|
||||
msgstr "Vim"
|
||||
|
||||
@@ -8233,6 +8347,9 @@ msgstr "листа имена директоријума који се кори
|
||||
msgid "change to directory of file in buffer"
|
||||
msgstr "мења на директоријум фајла у баферу"
|
||||
|
||||
msgid "change to pwd of shell in terminal buffer"
|
||||
msgstr "мења на pwd командног окружења терминал баферу"
|
||||
|
||||
msgid "search commands wrap around the end of the buffer"
|
||||
msgstr "команде претраге се обавијају око краја бафера"
|
||||
|
||||
@@ -8245,7 +8362,7 @@ msgstr ""
|
||||
"претраге"
|
||||
|
||||
msgid "select the default regexp engine used"
|
||||
msgstr "бира подразумевани регизраз механизам"
|
||||
msgstr "бира подразумевани механизам регуларних израза"
|
||||
|
||||
msgid "ignore case when using a search pattern"
|
||||
msgstr "не прави разлику у величини слова када се користи шаблон претраге"
|
||||
@@ -8837,7 +8954,7 @@ msgid ""
|
||||
"\"autoselect\" to always put selected text on the clipboard"
|
||||
msgstr ""
|
||||
"„unnamed” да се користи * регистар као неименовани регистар\n"
|
||||
"„autoselect” да се изабрани текст увек ставља у клипборд"
|
||||
"„autoselect” да се изабрани текст увек ставља у системску оставу"
|
||||
|
||||
msgid "\"startsel\" and/or \"stopsel\"; what special keys can do"
|
||||
msgstr "„startsel” и/или „stopsel”; шта могу да ураде специјални тастери"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* option.c */
|
||||
void set_init_1(int clean_arg);
|
||||
void set_fencs_unicode(void);
|
||||
void set_string_default(char *name, char_u *val);
|
||||
void set_number_default(char *name, long val);
|
||||
void set_local_options_default(win_T *wp, int do_buffer);
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ void clear_spell_chartab(spelltab_T *sp);
|
||||
void init_spell_chartab(void);
|
||||
int spell_iswordp(char_u *p, win_T *wp);
|
||||
int spell_iswordp_nmw(char_u *p, win_T *wp);
|
||||
int spell_casefold(char_u *str, int len, char_u *buf, int buflen);
|
||||
int spell_casefold(win_T *wp, char_u *str, int len, char_u *buf, int buflen);
|
||||
int check_need_cap(linenr_T lnum, colnr_T col);
|
||||
void ex_spellrepall(exarg_T *eap);
|
||||
void onecap_copy(char_u *word, char_u *wcopy, int upper);
|
||||
|
||||
@@ -3,7 +3,7 @@ int check_defined(char_u *p, size_t len, cctx_T *cctx, int is_arg);
|
||||
int check_compare_types(exprtype_T type, typval_T *tv1, typval_T *tv2);
|
||||
int use_typecheck(type_T *actual, type_T *expected);
|
||||
int need_type(type_T *actual, type_T *expected, int offset, int arg_idx, cctx_T *cctx, int silent, int actual_is_const);
|
||||
int func_needs_compiling(ufunc_T *ufunc, int profile);
|
||||
int func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type);
|
||||
int get_script_item_idx(int sid, char_u *name, int check_writable, cctx_T *cctx);
|
||||
imported_T *find_imported(char_u *name, size_t len, cctx_T *cctx);
|
||||
imported_T *find_imported_in_script(char_u *name, size_t len, int sid);
|
||||
@@ -17,7 +17,7 @@ void fill_exarg_from_cctx(exarg_T *eap, cctx_T *cctx);
|
||||
int assignment_len(char_u *p, int *heredoc);
|
||||
void vim9_declare_error(char_u *name);
|
||||
int check_vim9_unlet(char_u *name);
|
||||
int compile_def_function(ufunc_T *ufunc, int check_return_type, int profiling, cctx_T *outer_cctx);
|
||||
int compile_def_function(ufunc_T *ufunc, int check_return_type, compiletype_T compile_type, cctx_T *outer_cctx);
|
||||
void set_function_type(ufunc_T *ufunc);
|
||||
void delete_instr(isn_T *isn);
|
||||
void unlink_def_function(ufunc_T *ufunc);
|
||||
|
||||
@@ -4,9 +4,12 @@ void funcstack_check_refcount(funcstack_T *funcstack);
|
||||
char_u *char_from_string(char_u *str, varnumber_T index);
|
||||
char_u *string_slice(char_u *str, varnumber_T first, varnumber_T last, int exclusive);
|
||||
int fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx);
|
||||
typval_T *lookup_debug_var(char_u *name);
|
||||
int exe_typval_instr(typval_T *tv, typval_T *rettv);
|
||||
char_u *exe_substitute_instr(void);
|
||||
int call_def_function(ufunc_T *ufunc, int argc_arg, typval_T *argv, partial_T *partial, typval_T *rettv);
|
||||
void set_context_in_disassemble_cmd(expand_T *xp, char_u *arg);
|
||||
char_u *get_disassemble_argument(expand_T *xp, int idx);
|
||||
void ex_disassemble(exarg_T *eap);
|
||||
int tv2bool(typval_T *tv);
|
||||
void emsg_using_string_as(typval_T *tv, int as_number);
|
||||
|
||||
+20
-6
@@ -32,7 +32,7 @@ static int stuff_yank(int, char_u *);
|
||||
static void put_reedit_in_typebuf(int silent);
|
||||
static int put_in_typebuf(char_u *s, int esc, int colon,
|
||||
int silent);
|
||||
static int yank_copy_line(struct block_def *bd, long y_idx);
|
||||
static int yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space);
|
||||
#ifdef FEAT_CLIPBOARD
|
||||
static void copy_yank_reg(yankreg_T *reg);
|
||||
#endif
|
||||
@@ -1208,20 +1208,20 @@ op_yank(oparg_T *oap, int deleting, int mess)
|
||||
{
|
||||
case MBLOCK:
|
||||
block_prep(oap, &bd, lnum, FALSE);
|
||||
if (yank_copy_line(&bd, y_idx) == FAIL)
|
||||
if (yank_copy_line(&bd, y_idx, oap->excl_tr_ws) == FAIL)
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case MLINE:
|
||||
if ((y_current->y_array[y_idx] =
|
||||
vim_strsave(ml_get(lnum))) == NULL)
|
||||
vim_strsave(ml_get(lnum))) == NULL)
|
||||
goto fail;
|
||||
break;
|
||||
|
||||
case MCHAR:
|
||||
{
|
||||
colnr_T startcol = 0, endcol = MAXCOL;
|
||||
int is_oneChar = FALSE;
|
||||
int is_oneChar = FALSE;
|
||||
colnr_T cs, ce;
|
||||
|
||||
p = ml_get(lnum);
|
||||
@@ -1282,7 +1282,7 @@ op_yank(oparg_T *oap, int deleting, int mess)
|
||||
else
|
||||
bd.textlen = endcol - startcol + oap->inclusive;
|
||||
bd.textstart = p + startcol;
|
||||
if (yank_copy_line(&bd, y_idx) == FAIL)
|
||||
if (yank_copy_line(&bd, y_idx, FALSE) == FAIL)
|
||||
goto fail;
|
||||
break;
|
||||
}
|
||||
@@ -1443,8 +1443,12 @@ fail: // free the allocated lines
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a block range into a register.
|
||||
* If "exclude_trailing_space" is set, do not copy trailing whitespaces.
|
||||
*/
|
||||
static int
|
||||
yank_copy_line(struct block_def *bd, long y_idx)
|
||||
yank_copy_line(struct block_def *bd, long y_idx, int exclude_trailing_space)
|
||||
{
|
||||
char_u *pnew;
|
||||
|
||||
@@ -1458,6 +1462,16 @@ yank_copy_line(struct block_def *bd, long y_idx)
|
||||
pnew += bd->textlen;
|
||||
vim_memset(pnew, ' ', (size_t)bd->endspaces);
|
||||
pnew += bd->endspaces;
|
||||
if (exclude_trailing_space)
|
||||
{
|
||||
int s = bd->textlen + bd->endspaces;
|
||||
|
||||
while (VIM_ISWHITE(*(bd->textstart + s - 1)) && s > 0)
|
||||
{
|
||||
s = s - (*mb_head_off)(bd->textstart, bd->textstart + s - 1) - 1;
|
||||
pnew--;
|
||||
}
|
||||
}
|
||||
*pnew = NUL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
+6
-1
@@ -1119,6 +1119,7 @@ do_source(
|
||||
int save_debug_break_level = debug_break_level;
|
||||
int sid;
|
||||
scriptitem_T *si = NULL;
|
||||
int save_estack_compiling = estack_compiling;
|
||||
#endif
|
||||
#ifdef STARTUPTIME
|
||||
struct timeval tv_rel;
|
||||
@@ -1142,8 +1143,9 @@ do_source(
|
||||
smsg(_("Cannot source a directory: \"%s\""), fname);
|
||||
goto theend;
|
||||
}
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
estack_compiling = FALSE;
|
||||
|
||||
// See if we loaded this script before.
|
||||
for (sid = script_items.ga_len; sid > 0; --sid)
|
||||
{
|
||||
@@ -1508,6 +1510,9 @@ almosttheend:
|
||||
|
||||
theend:
|
||||
vim_free(fname_exp);
|
||||
#ifdef FEAT_EVAL
|
||||
estack_compiling = save_estack_compiling;
|
||||
#endif
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
+22
-5
@@ -249,7 +249,7 @@ spell_check(
|
||||
if (*mi.mi_fend != NUL)
|
||||
MB_PTR_ADV(mi.mi_fend);
|
||||
|
||||
(void)spell_casefold(ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
|
||||
(void)spell_casefold(wp, ptr, (int)(mi.mi_fend - ptr), mi.mi_fword,
|
||||
MAXWLEN + 1);
|
||||
mi.mi_fwordlen = (int)STRLEN(mi.mi_fword);
|
||||
|
||||
@@ -736,7 +736,8 @@ find_word(matchinf_T *mip, int mode)
|
||||
{
|
||||
// "fword" is only needed for checking syllables.
|
||||
if (ptr == mip->mi_word)
|
||||
(void)spell_casefold(ptr, wlen, fword, MAXWLEN);
|
||||
(void)spell_casefold(mip->mi_win,
|
||||
ptr, wlen, fword, MAXWLEN);
|
||||
else
|
||||
vim_strncpy(fword, ptr, endlen[endidxcnt]);
|
||||
}
|
||||
@@ -1213,7 +1214,7 @@ fold_more(matchinf_T *mip)
|
||||
if (*mip->mi_fend != NUL)
|
||||
MB_PTR_ADV(mip->mi_fend);
|
||||
|
||||
(void)spell_casefold(p, (int)(mip->mi_fend - p),
|
||||
(void)spell_casefold(mip->mi_win, p, (int)(mip->mi_fend - p),
|
||||
mip->mi_fword + mip->mi_fwordlen,
|
||||
MAXWLEN - mip->mi_fwordlen);
|
||||
flen = (int)STRLEN(mip->mi_fword + mip->mi_fwordlen);
|
||||
@@ -2737,6 +2738,7 @@ spell_iswordp_w(int *p, win_T *wp)
|
||||
*/
|
||||
int
|
||||
spell_casefold(
|
||||
win_T *wp,
|
||||
char_u *str,
|
||||
int len,
|
||||
char_u *buf,
|
||||
@@ -2765,7 +2767,21 @@ spell_casefold(
|
||||
return FAIL;
|
||||
}
|
||||
c = mb_cptr2char_adv(&p);
|
||||
outi += mb_char2bytes(SPELL_TOFOLD(c), buf + outi);
|
||||
|
||||
// Exception: greek capital sigma 0x03A3 folds to 0x03C3, except
|
||||
// when it is the last character in a word, then it folds to
|
||||
// 0x03C2.
|
||||
if (c == 0x03a3 || c == 0x03c2)
|
||||
{
|
||||
if (p == str + len || !spell_iswordp(p, wp))
|
||||
c = 0x03c2;
|
||||
else
|
||||
c = 0x03c3;
|
||||
}
|
||||
else
|
||||
c = SPELL_TOFOLD(c);
|
||||
|
||||
outi += mb_char2bytes(c, buf + outi);
|
||||
}
|
||||
buf[outi] = NUL;
|
||||
}
|
||||
@@ -3097,7 +3113,8 @@ spell_soundfold(
|
||||
word = inword;
|
||||
else
|
||||
{
|
||||
(void)spell_casefold(inword, (int)STRLEN(inword), fword, MAXWLEN);
|
||||
(void)spell_casefold(curwin,
|
||||
inword, (int)STRLEN(inword), fword, MAXWLEN);
|
||||
word = fword;
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -3429,9 +3429,9 @@ add_fromto(
|
||||
if (ga_grow(gap, 1) == OK)
|
||||
{
|
||||
ftp = ((fromto_T *)gap->ga_data) + gap->ga_len;
|
||||
(void)spell_casefold(from, (int)STRLEN(from), word, MAXWLEN);
|
||||
(void)spell_casefold(curwin, from, (int)STRLEN(from), word, MAXWLEN);
|
||||
ftp->ft_from = getroom_save(spin, word);
|
||||
(void)spell_casefold(to, (int)STRLEN(to), word, MAXWLEN);
|
||||
(void)spell_casefold(curwin, to, (int)STRLEN(to), word, MAXWLEN);
|
||||
ftp->ft_to = getroom_save(spin, word);
|
||||
++gap->ga_len;
|
||||
}
|
||||
@@ -4391,7 +4391,7 @@ store_word(
|
||||
int res = OK;
|
||||
char_u *p;
|
||||
|
||||
(void)spell_casefold(word, len, foldword, MAXWLEN);
|
||||
(void)spell_casefold(curwin, word, len, foldword, MAXWLEN);
|
||||
for (p = pfxlist; res == OK; ++p)
|
||||
{
|
||||
if (!need_affix || (p != NULL && *p != NUL))
|
||||
|
||||
+4
-3
@@ -791,7 +791,7 @@ spell_find_suggest(
|
||||
if (su->su_badlen >= MAXWLEN)
|
||||
su->su_badlen = MAXWLEN - 1; // just in case
|
||||
vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
|
||||
(void)spell_casefold(su->su_badptr, su->su_badlen,
|
||||
(void)spell_casefold(curwin, su->su_badptr, su->su_badlen,
|
||||
su->su_fbadword, MAXWLEN);
|
||||
// TODO: make this work if the case-folded text is longer than the original
|
||||
// text. Currently an illegal byte causes wrong pointer computations.
|
||||
@@ -1176,7 +1176,7 @@ suggest_try_change(suginfo_T *su)
|
||||
STRCPY(fword, su->su_fbadword);
|
||||
n = (int)STRLEN(fword);
|
||||
p = su->su_badptr + su->su_badlen;
|
||||
(void)spell_casefold(p, (int)STRLEN(p), fword + n, MAXWLEN - n);
|
||||
(void)spell_casefold(curwin, p, (int)STRLEN(p), fword + n, MAXWLEN - n);
|
||||
|
||||
for (lpi = 0; lpi < curwin->w_s->b_langp.ga_len; ++lpi)
|
||||
{
|
||||
@@ -3005,7 +3005,8 @@ stp_sal_score(
|
||||
else
|
||||
{
|
||||
// soundfold the bad word with more characters following
|
||||
(void)spell_casefold(su->su_badptr, stp->st_orglen, fword, MAXWLEN);
|
||||
(void)spell_casefold(curwin,
|
||||
su->su_badptr, stp->st_orglen, fword, MAXWLEN);
|
||||
|
||||
// When joining two words the sound often changes a lot. E.g., "t he"
|
||||
// sounds like "t h" while "the" sounds like "@". Avoid that by
|
||||
|
||||
+4
-2
@@ -1995,7 +1995,7 @@ struct outer_S {
|
||||
garray_T *out_stack; // stack from outer scope
|
||||
int out_frame_idx; // index of stack frame in out_stack
|
||||
outer_T *out_up; // outer scope of outer scope or NULL
|
||||
int out_up_is_copy; // don't free out_up
|
||||
partial_T *out_up_partial; // partial owning out_up or NULL
|
||||
};
|
||||
|
||||
struct partial_S
|
||||
@@ -3784,7 +3784,7 @@ typedef struct oparg_S
|
||||
int use_reg_one; // TRUE if delete uses reg 1 even when not
|
||||
// linewise
|
||||
int inclusive; // TRUE if char motion is inclusive (only
|
||||
// valid when motion_type is MCHAR
|
||||
// valid when motion_type is MCHAR)
|
||||
int end_adjusted; // backuped b_op_end one char (only used by
|
||||
// do_format())
|
||||
pos_T start; // start of the operator
|
||||
@@ -3801,6 +3801,8 @@ typedef struct oparg_S
|
||||
colnr_T end_vcol; // end col for block mode operator
|
||||
long prev_opcount; // ca.opcount saved for K_CURSORHOLD
|
||||
long prev_count0; // ca.count0 saved for K_CURSORHOLD
|
||||
int excl_tr_ws; // exclude trailing whitespace for yank of a
|
||||
// block
|
||||
} oparg_T;
|
||||
|
||||
/*
|
||||
|
||||
@@ -5594,6 +5594,7 @@ check_termcode(
|
||||
&& key_name[0] == (int)KS_EXTRA
|
||||
&& (key_name[1] == (int)KE_X1MOUSE
|
||||
|| key_name[1] == (int)KE_X2MOUSE
|
||||
|| key_name[1] == (int)KE_MOUSEMOVE_XY
|
||||
|| key_name[1] == (int)KE_MOUSELEFT
|
||||
|| key_name[1] == (int)KE_MOUSERIGHT
|
||||
|| key_name[1] == (int)KE_MOUSEDOWN
|
||||
@@ -5607,6 +5608,9 @@ check_termcode(
|
||||
mouse_col = 128 * (bytes[0] - ' ' - 1) + bytes[1] - ' ' - 1;
|
||||
mouse_row = 128 * (bytes[2] - ' ' - 1) + bytes[3] - ' ' - 1;
|
||||
slen += num_bytes;
|
||||
// equal to K_MOUSEMOVE
|
||||
if (key_name[1] == (int)KE_MOUSEMOVE_XY)
|
||||
key_name[1] = (int)KE_MOUSEMOVE;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
|
||||
@@ -804,6 +804,22 @@ func Test_cmdline_complete_various()
|
||||
call feedkeys(":topleft new\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"topleft new", @:)
|
||||
|
||||
" completion for vim9 and legacy commands
|
||||
call feedkeys(":vim9 call strle\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"vim9 call strlen(", @:)
|
||||
call feedkeys(":legac call strle\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"legac call strlen(", @:)
|
||||
|
||||
" completion for the :disassemble command
|
||||
call feedkeys(":disas deb\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"disas debug", @:)
|
||||
call feedkeys(":disas pro\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"disas profile", @:)
|
||||
call feedkeys(":disas debug Test_cmdline_complete_var\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"disas debug Test_cmdline_complete_various", @:)
|
||||
call feedkeys(":disas profile Test_cmdline_complete_var\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"disas profile Test_cmdline_complete_various", @:)
|
||||
|
||||
" completion for the :match command
|
||||
call feedkeys(":match Search /pat/\<C-A>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal("\"match Search /pat/\<C-A>", @:)
|
||||
|
||||
@@ -853,6 +853,7 @@ func Test_Backtrace_DefFunction()
|
||||
enddef
|
||||
|
||||
def g:GlobalFunction()
|
||||
var some = "some var"
|
||||
CallAFunction()
|
||||
enddef
|
||||
|
||||
@@ -884,19 +885,22 @@ func Test_Backtrace_DefFunction()
|
||||
\ ':debug call GlobalFunction()',
|
||||
\ ['cmd: call GlobalFunction()'])
|
||||
|
||||
" FIXME: Vim9 lines are not debugged!
|
||||
call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
|
||||
call RunDbgCmd(buf, 'step', ['line 1: var some = "some var"'])
|
||||
call RunDbgCmd(buf, 'step', ['line 2: CallAFunction()'])
|
||||
call RunDbgCmd(buf, 'echo some', ['some var'])
|
||||
|
||||
" But they do appear in the backtrace
|
||||
call RunDbgCmd(buf, 'backtrace', [
|
||||
\ '\V>backtrace',
|
||||
\ '\V 2 function GlobalFunction[1]',
|
||||
\ '\V 1 <SNR>\.\*_CallAFunction[1]',
|
||||
\ '\V->0 <SNR>\.\*_SourceAnotherFile',
|
||||
\ '\Vline 1: source Xtest2.vim'],
|
||||
\ '\V->0 function GlobalFunction',
|
||||
\ '\Vline 2: CallAFunction()',
|
||||
\ ],
|
||||
\ #{match: 'pattern'})
|
||||
|
||||
|
||||
call RunDbgCmd(buf, 'step', ['line 1: SourceAnotherFile()'])
|
||||
call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
|
||||
" Repeated line, because we fist are in the compiled function before the
|
||||
" EXEC and then in do_cmdline() before the :source command.
|
||||
call RunDbgCmd(buf, 'step', ['line 1: source Xtest2.vim'])
|
||||
call RunDbgCmd(buf, 'step', ['line 1: vim9script'])
|
||||
call RunDbgCmd(buf, 'step', ['line 3: def DoAThing(): number'])
|
||||
call RunDbgCmd(buf, 'step', ['line 9: export def File2Function()'])
|
||||
@@ -905,7 +909,7 @@ func Test_Backtrace_DefFunction()
|
||||
call RunDbgCmd(buf, 'step', ['line 14: File2Function()'])
|
||||
call RunDbgCmd(buf, 'backtrace', [
|
||||
\ '\V>backtrace',
|
||||
\ '\V 3 function GlobalFunction[1]',
|
||||
\ '\V 3 function GlobalFunction[2]',
|
||||
\ '\V 2 <SNR>\.\*_CallAFunction[1]',
|
||||
\ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
|
||||
\ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
|
||||
@@ -913,22 +917,48 @@ func Test_Backtrace_DefFunction()
|
||||
\ #{match: 'pattern'})
|
||||
|
||||
" Don't step into compiled functions...
|
||||
call RunDbgCmd(buf, 'step', ['line 15: End of sourced file'])
|
||||
call RunDbgCmd(buf, 'next', ['line 15: End of sourced file'])
|
||||
call RunDbgCmd(buf, 'backtrace', [
|
||||
\ '\V>backtrace',
|
||||
\ '\V 3 function GlobalFunction[1]',
|
||||
\ '\V 3 function GlobalFunction[2]',
|
||||
\ '\V 2 <SNR>\.\*_CallAFunction[1]',
|
||||
\ '\V 1 <SNR>\.\*_SourceAnotherFile[1]',
|
||||
\ '\V->0 script ' .. getcwd() .. '/Xtest2.vim',
|
||||
\ '\Vline 15: End of sourced file'],
|
||||
\ #{match: 'pattern'})
|
||||
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xtest1.vim')
|
||||
call delete('Xtest2.vim')
|
||||
endfunc
|
||||
|
||||
func Test_debug_def_function()
|
||||
CheckCWD
|
||||
let file =<< trim END
|
||||
vim9script
|
||||
def g:Func()
|
||||
var n: number
|
||||
def Closure(): number
|
||||
return n + 3
|
||||
enddef
|
||||
n += Closure()
|
||||
echo 'result: ' .. n
|
||||
enddef
|
||||
END
|
||||
call writefile(file, 'Xtest.vim')
|
||||
|
||||
let buf = RunVimInTerminal('-S Xtest.vim', {})
|
||||
|
||||
call RunDbgCmd(buf,
|
||||
\ ':debug call Func()',
|
||||
\ ['cmd: call Func()'])
|
||||
call RunDbgCmd(buf, 'next', ['result: 3'])
|
||||
call term_sendkeys(buf, "\r")
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xtest.vim')
|
||||
endfunc
|
||||
|
||||
func Test_debug_backtrace_level()
|
||||
CheckCWD
|
||||
let lines =<< trim END
|
||||
@@ -1116,6 +1146,7 @@ func Test_debug_backtrace_level()
|
||||
\ [ 'E121: Undefined variable: s:file1_var' ] )
|
||||
call RunDbgCmd(buf, 'echo s:file2_var', [ 'file2' ] )
|
||||
|
||||
call RunDbgCmd(buf, 'cont')
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xtest1.vim')
|
||||
call delete('Xtest2.vim')
|
||||
|
||||
@@ -243,6 +243,36 @@ func Test_diffput_two()
|
||||
bwipe! b
|
||||
endfunc
|
||||
|
||||
" Test for :diffget/:diffput with a range that is inside a diff chunk
|
||||
func Test_diffget_diffput_range()
|
||||
call setline(1, range(1, 10))
|
||||
new
|
||||
call setline(1, range(11, 20))
|
||||
windo diffthis
|
||||
3,5diffget
|
||||
call assert_equal(['13', '14', '15'], getline(3, 5))
|
||||
call setline(1, range(1, 10))
|
||||
4,8diffput
|
||||
wincmd p
|
||||
call assert_equal(['13', '4', '5', '6', '7', '8', '19'], getline(3, 9))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" Test for :diffget/:diffput with an empty buffer and a non-empty buffer
|
||||
func Test_diffget_diffput_empty_buffer()
|
||||
%d _
|
||||
new
|
||||
call setline(1, 'one')
|
||||
windo diffthis
|
||||
diffget
|
||||
call assert_equal(['one'], getline(1, '$'))
|
||||
%d _
|
||||
diffput
|
||||
wincmd p
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" :diffput and :diffget completes names of buffers which
|
||||
" are in diff mode and which are different then current buffer.
|
||||
" No completion when the current window is not in diff mode.
|
||||
@@ -329,7 +359,7 @@ func Test_dp_do_buffer()
|
||||
call assert_equal('10', getline('.'))
|
||||
21
|
||||
call assert_equal('two', getline('.'))
|
||||
diffget one
|
||||
diffget one
|
||||
call assert_equal('20', getline('.'))
|
||||
|
||||
31
|
||||
@@ -645,7 +675,11 @@ func Test_diffexpr()
|
||||
call assert_equal(normattr, screenattr(1, 1))
|
||||
call assert_equal(normattr, screenattr(2, 1))
|
||||
call assert_notequal(normattr, screenattr(3, 1))
|
||||
diffoff!
|
||||
|
||||
" Try using an non-existing function for 'diffexpr'.
|
||||
set diffexpr=NewDiffFunc()
|
||||
call assert_fails('windo diffthis', ['E117:', 'E97:'])
|
||||
diffoff!
|
||||
%bwipe!
|
||||
set diffexpr& diffopt&
|
||||
@@ -1220,5 +1254,88 @@ func Test_diff_filler_cursorcolumn()
|
||||
call delete('Xtest_diff_cuc')
|
||||
endfunc
|
||||
|
||||
" Test for adding/removing lines inside diff chunks, between diff chunks
|
||||
" and before diff chunks
|
||||
func Test_diff_modify_chunks()
|
||||
enew!
|
||||
let w2_id = win_getid()
|
||||
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
||||
new
|
||||
let w1_id = win_getid()
|
||||
call setline(1, ['a', '2', '3', 'd', 'e', 'f', '7', '8', 'i'])
|
||||
windo diffthis
|
||||
|
||||
" remove a line between two diff chunks and create a new diff chunk
|
||||
call win_gotoid(w2_id)
|
||||
5d
|
||||
call win_gotoid(w1_id)
|
||||
call diff_hlID(5, 1)->synIDattr('name')->assert_equal('DiffAdd')
|
||||
|
||||
" add a line between two diff chunks
|
||||
call win_gotoid(w2_id)
|
||||
normal! 4Goe
|
||||
call win_gotoid(w1_id)
|
||||
call diff_hlID(4, 1)->synIDattr('name')->assert_equal('')
|
||||
call diff_hlID(5, 1)->synIDattr('name')->assert_equal('')
|
||||
|
||||
" remove all the lines in a diff chunk.
|
||||
call win_gotoid(w2_id)
|
||||
7,8d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', 'DiffText', 'DiffText', '', '', '', 'DiffAdd',
|
||||
\ 'DiffAdd', ''], hl)
|
||||
|
||||
" remove lines from one diff chunk to just before the next diff chunk
|
||||
call win_gotoid(w2_id)
|
||||
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
||||
2,6d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', 'DiffAdd',
|
||||
\ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
|
||||
|
||||
" remove lines just before the top of a diff chunk
|
||||
call win_gotoid(w2_id)
|
||||
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
||||
5,6d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', 'DiffText', 'DiffText', '', 'DiffText', 'DiffText',
|
||||
\ 'DiffAdd', 'DiffAdd', ''], hl)
|
||||
|
||||
" remove line after the end of a diff chunk
|
||||
call win_gotoid(w2_id)
|
||||
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
||||
4d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', 'DiffText', 'DiffText', 'DiffAdd', '', '', 'DiffText',
|
||||
\ 'DiffText', ''], hl)
|
||||
|
||||
" remove lines starting from the end of one diff chunk and ending inside
|
||||
" another diff chunk
|
||||
call win_gotoid(w2_id)
|
||||
call setline(1, ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i'])
|
||||
4,7d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', 'DiffText', 'DiffText', 'DiffText', 'DiffAdd',
|
||||
\ 'DiffAdd', 'DiffAdd', 'DiffAdd', ''], hl)
|
||||
|
||||
" removing the only remaining diff chunk should make the files equal
|
||||
call win_gotoid(w2_id)
|
||||
call setline(1, ['a', '2', '3', 'x', 'd', 'e', 'f', 'x', '7', '8', 'i'])
|
||||
8d
|
||||
let hl = range(1, 10)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', '', '', 'DiffAdd', '', '', '', '', '', ''], hl)
|
||||
call win_gotoid(w2_id)
|
||||
4d
|
||||
call win_gotoid(w1_id)
|
||||
let hl = range(1, 9)->map({_, lnum -> diff_hlID(lnum, 1)->synIDattr('name')})
|
||||
call assert_equal(['', '', '', '', '', '', '', '', ''], hl)
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1874,4 +1874,28 @@ func Test_read_invalid()
|
||||
set encoding=utf-8
|
||||
endfunc
|
||||
|
||||
" Test for the 'revins' option
|
||||
func Test_edit_revins()
|
||||
CheckFeature rightleft
|
||||
new
|
||||
set revins
|
||||
exe "normal! ione\ttwo three"
|
||||
call assert_equal("eerht owt\teno", getline(1))
|
||||
call setline(1, "one\ttwo three")
|
||||
normal! gg$bi a
|
||||
call assert_equal("one\ttwo a three", getline(1))
|
||||
exe "normal! $bi\<BS>\<BS>"
|
||||
call assert_equal("one\ttwo a ree", getline(1))
|
||||
exe "normal! 0wi\<C-W>"
|
||||
call assert_equal("one\t a ree", getline(1))
|
||||
exe "normal! 0wi\<C-U>"
|
||||
call assert_equal("one\t ", getline(1))
|
||||
" newline in insert mode starts at the end of the line
|
||||
call setline(1, 'one two three')
|
||||
exe "normal! wi\nfour"
|
||||
call assert_equal(['one two three', 'ruof'], getline(1, '$'))
|
||||
set revins&
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -593,6 +593,12 @@ func Sandbox_tests()
|
||||
if has('unix')
|
||||
call assert_fails('cd `pwd`', 'E48:')
|
||||
endif
|
||||
" some options cannot be changed in a sandbox
|
||||
call assert_fails('set exrc', 'E48:')
|
||||
call assert_fails('set cdpath', 'E48:')
|
||||
if has('xim') && has('gui_gtk')
|
||||
call assert_fails('set imstyle', 'E48:')
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_sandbox()
|
||||
|
||||
@@ -257,7 +257,7 @@ let s:filename_checks = {
|
||||
\ 'jgraph': ['file.jgr'],
|
||||
\ 'jovial': ['file.jov', 'file.j73', 'file.jovial'],
|
||||
\ 'jproperties': ['file.properties', 'file.properties_xx', 'file.properties_xx_xx', 'some.properties_xx_xx_file'],
|
||||
\ 'json': ['file.json', 'file.jsonp', 'file.webmanifest', 'Pipfile.lock'],
|
||||
\ 'json': ['file.json', 'file.jsonp', 'file.webmanifest', 'Pipfile.lock', 'file.ipynb'],
|
||||
\ 'jsp': ['file.jsp'],
|
||||
\ 'kconfig': ['Kconfig', 'Kconfig.debug', 'Kconfig.file'],
|
||||
\ 'kivy': ['file.kv'],
|
||||
|
||||
@@ -86,13 +86,13 @@ func Test_empty()
|
||||
endfunc
|
||||
|
||||
func Test_test_void()
|
||||
call assert_fails('echo 1 == test_void()', 'E685:')
|
||||
call assert_fails('echo 1 == test_void()', 'E1031:')
|
||||
if has('float')
|
||||
call assert_fails('echo 1.0 == test_void()', 'E685:')
|
||||
call assert_fails('echo 1.0 == test_void()', 'E1031:')
|
||||
endif
|
||||
call assert_fails('let x = json_encode(test_void())', 'E685:')
|
||||
call assert_fails('let x = copy(test_void())', 'E685:')
|
||||
call assert_fails('let x = copy([test_void()])', 'E685:')
|
||||
call assert_fails('let x = copy([test_void()])', 'E1031:')
|
||||
endfunc
|
||||
|
||||
func Test_len()
|
||||
@@ -2174,9 +2174,11 @@ func Test_call()
|
||||
call assert_fails("call call('Mylen', [], 0)", 'E715:')
|
||||
call assert_fails('call foo', 'E107:')
|
||||
|
||||
" This once caused a crash.
|
||||
" These once caused a crash.
|
||||
call call(test_null_function(), [])
|
||||
call call(test_null_partial(), [])
|
||||
call assert_fails('call test_null_function()()', 'E1192:')
|
||||
call assert_fails('call test_null_partial()()', 'E117:')
|
||||
endfunc
|
||||
|
||||
func Test_char2nr()
|
||||
|
||||
@@ -123,5 +123,15 @@ func Test_helptag_cmd_readonly()
|
||||
call delete('Xdir', 'rf')
|
||||
endfunc
|
||||
|
||||
" Test for setting the 'helpheight' option in the help window
|
||||
func Test_help_window_height()
|
||||
let &cmdheight = &lines - 24
|
||||
set helpheight=10
|
||||
help
|
||||
set helpheight=14
|
||||
call assert_equal(14, winheight(0))
|
||||
set helpheight& cmdheight=1
|
||||
close
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -485,6 +485,11 @@ func Test_list_mappings()
|
||||
call assert_equal(['n ,k <Nop>'],
|
||||
\ execute('nmap ,k')->trim()->split("\n"))
|
||||
|
||||
" map with space at the beginning
|
||||
exe "nmap \<C-V> w <Nop>"
|
||||
call assert_equal(['n <Space>w <Nop>'],
|
||||
\ execute("nmap \<C-V> w")->trim()->split("\n"))
|
||||
|
||||
nmapclear
|
||||
endfunc
|
||||
|
||||
@@ -1411,4 +1416,19 @@ func Test_abbreviate_multi_byte()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for abbreviations with 'latin1' encoding
|
||||
func Test_abbreviate_latin1_encoding()
|
||||
set encoding=latin1
|
||||
call assert_fails('abbr ab#$c ABC', 'E474:')
|
||||
new
|
||||
iabbr <buffer> #i #include
|
||||
iabbr <buffer> ## #enddef
|
||||
exe "normal i#i\<C-]>"
|
||||
call assert_equal('#include', getline(1))
|
||||
exe "normal 0Di##\<C-]>"
|
||||
call assert_equal('#enddef', getline(1))
|
||||
%bw!
|
||||
set encoding=utf-8
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1019,6 +1019,19 @@ func Test_mkvimrc()
|
||||
endfor
|
||||
|
||||
call s:ClearMappings()
|
||||
|
||||
" the 'pastetoggle', 'wildchar' and 'wildcharm' option values should be
|
||||
" stored as key names in the vimrc file
|
||||
set pastetoggle=<F5>
|
||||
set wildchar=<F6>
|
||||
set wildcharm=<F7>
|
||||
call assert_fails('mkvimrc Xtestvimrc')
|
||||
mkvimrc! Xtestvimrc
|
||||
call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set pastetoggle=<F5>'))
|
||||
call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set wildchar=<F6>'))
|
||||
call assert_notequal(-1, index(readfile('Xtestvimrc'), 'set wildcharm=<F7>'))
|
||||
set pastetoggle& wildchar& wildcharm&
|
||||
|
||||
call delete('Xtestvimrc')
|
||||
endfunc
|
||||
|
||||
|
||||
@@ -334,4 +334,30 @@ func Test_modeline_setoption_verbose()
|
||||
call delete('Xmodeline')
|
||||
endfunc
|
||||
|
||||
" Test for the 'modeline' default value in compatible and non-compatible modes
|
||||
" for root and non-root accounts
|
||||
func Test_modeline_default()
|
||||
set compatible
|
||||
call assert_false(&modeline)
|
||||
set nocompatible
|
||||
call assert_equal(IsRoot() ? 0 : 1, &modeline)
|
||||
set compatible&vi
|
||||
call assert_false(&modeline)
|
||||
set compatible&vim
|
||||
call assert_equal(IsRoot() ? 0 : 1, &modeline)
|
||||
set compatible& modeline&
|
||||
endfunc
|
||||
|
||||
" Some options cannot be set from the modeline when 'diff' option is set
|
||||
func Test_modeline_diff_buffer()
|
||||
call writefile(['vim: diff foldmethod=marker wrap'], 'Xfile')
|
||||
set foldmethod& nowrap
|
||||
new Xfile
|
||||
call assert_equal('manual', &foldmethod)
|
||||
call assert_false(&wrap)
|
||||
set wrap&
|
||||
call delete('Xfile')
|
||||
bw
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -434,6 +434,7 @@ func Test_set_errors()
|
||||
set nomodifiable
|
||||
call assert_fails('set fileencoding=latin1', 'E21:')
|
||||
set modifiable&
|
||||
call assert_fails('set t_#-&', 'E522:')
|
||||
endfunc
|
||||
|
||||
func CheckWasSet(name)
|
||||
@@ -954,6 +955,18 @@ func Test_opt_local_to_global()
|
||||
call assert_equal('gnewprg', &l:equalprg)
|
||||
call assert_equal('gnewprg', &equalprg)
|
||||
set equalprg&
|
||||
|
||||
" Test for setting the global/local value of a boolean option
|
||||
setglobal autoread
|
||||
setlocal noautoread
|
||||
call assert_false(&autoread)
|
||||
set autoread<
|
||||
call assert_true(&autoread)
|
||||
setglobal noautoread
|
||||
setlocal autoread
|
||||
setlocal autoread<
|
||||
call assert_false(&autoread)
|
||||
set autoread&
|
||||
endfunc
|
||||
|
||||
" Test for incrementing, decrementing and multiplying a number option value
|
||||
@@ -1129,4 +1142,47 @@ func Test_VIM_POSIX()
|
||||
call setenv('VIM_POSIX', saved_VIM_POSIX)
|
||||
endfunc
|
||||
|
||||
" Test for setting an option to a Vi or Vim default
|
||||
func Test_opt_default()
|
||||
set formatoptions&vi
|
||||
call assert_equal('vt', &formatoptions)
|
||||
set formatoptions&vim
|
||||
call assert_equal('tcq', &formatoptions)
|
||||
|
||||
call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
|
||||
set fencs=latin1
|
||||
set fencs&
|
||||
call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
|
||||
set fencs=latin1
|
||||
set all&
|
||||
call assert_equal('ucs-bom,utf-8,default,latin1', &fencs)
|
||||
endfunc
|
||||
|
||||
" Test for the 'cmdheight' option
|
||||
func Test_cmdheight()
|
||||
%bw!
|
||||
let ht = &lines
|
||||
set cmdheight=9999
|
||||
call assert_equal(1, winheight(0))
|
||||
call assert_equal(ht - 1, &cmdheight)
|
||||
set cmdheight&
|
||||
endfunc
|
||||
|
||||
" To specify a control character as a option value, '^' can be used
|
||||
func Test_opt_control_char()
|
||||
set wildchar=^v
|
||||
call assert_equal("\<C-V>", nr2char(&wildchar))
|
||||
set wildcharm=^r
|
||||
call assert_equal("\<C-R>", nr2char(&wildcharm))
|
||||
" Bug: This doesn't work for the 'cedit' and 'termwinkey' options
|
||||
set wildchar& wildcharm&
|
||||
endfunc
|
||||
|
||||
" Test for the 'errorbells' option
|
||||
func Test_opt_errorbells()
|
||||
set errorbells
|
||||
call assert_beeps('s/a1b2/x1y2/')
|
||||
set noerrorbells
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -159,8 +159,68 @@ func Test_pastetoggle()
|
||||
call feedkeys("i\<F4>", 'xt')
|
||||
call assert_false(&paste)
|
||||
call assert_equal('Hello', getline(1))
|
||||
" command-line completion for 'pastetoggle' value
|
||||
call feedkeys(":set pastetoggle=\<Tab>\<C-B>\"\<CR>", 'xt')
|
||||
call assert_equal('"set pastetoggle=<F4>', @:)
|
||||
set pastetoggle&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
" Test for restoring option values when 'paste' is disabled
|
||||
func Test_paste_opt_restore()
|
||||
set autoindent expandtab ruler showmatch
|
||||
if has('rightleft')
|
||||
set revins hkmap
|
||||
endif
|
||||
set smarttab softtabstop=3 textwidth=27 wrapmargin=12
|
||||
if has('vartabs')
|
||||
set varsofttabstop=10,20
|
||||
endif
|
||||
|
||||
" enabling 'paste' should reset the above options
|
||||
set paste
|
||||
call assert_false(&autoindent)
|
||||
call assert_false(&expandtab)
|
||||
if has('rightleft')
|
||||
call assert_false(&revins)
|
||||
call assert_false(&hkmap)
|
||||
endif
|
||||
call assert_false(&ruler)
|
||||
call assert_false(&showmatch)
|
||||
call assert_false(&smarttab)
|
||||
call assert_equal(0, &softtabstop)
|
||||
call assert_equal(0, &textwidth)
|
||||
call assert_equal(0, &wrapmargin)
|
||||
if has('vartabs')
|
||||
call assert_equal('', &varsofttabstop)
|
||||
endif
|
||||
|
||||
" disabling 'paste' should restore the option values
|
||||
set nopaste
|
||||
call assert_true(&autoindent)
|
||||
call assert_true(&expandtab)
|
||||
if has('rightleft')
|
||||
call assert_true(&revins)
|
||||
call assert_true(&hkmap)
|
||||
endif
|
||||
call assert_true(&ruler)
|
||||
call assert_true(&showmatch)
|
||||
call assert_true(&smarttab)
|
||||
call assert_equal(3, &softtabstop)
|
||||
call assert_equal(27, &textwidth)
|
||||
call assert_equal(12, &wrapmargin)
|
||||
if has('vartabs')
|
||||
call assert_equal('10,20', &varsofttabstop)
|
||||
endif
|
||||
|
||||
set autoindent& expandtab& ruler& showmatch&
|
||||
if has('rightleft')
|
||||
set revins& hkmap&
|
||||
endif
|
||||
set smarttab& softtabstop& textwidth& wrapmargin&
|
||||
if has('vartabs')
|
||||
set varsofttabstop&
|
||||
endif
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1552,6 +1552,7 @@ func Test_popup_filter()
|
||||
call assert_equal(9, getcurpos()[2])
|
||||
call feedkeys('0', 'xt')
|
||||
call assert_equal('0', g:ignored)
|
||||
redraw
|
||||
call assert_equal(1, getcurpos()[2])
|
||||
|
||||
" x closes the popup
|
||||
@@ -3918,5 +3919,11 @@ func Test_popup_prop_not_visible()
|
||||
call delete('XtestPropNotVisble')
|
||||
endfunction
|
||||
|
||||
func Test_bufdel_skips_popupwin_buffer()
|
||||
let id = popup_create("Some text", {})
|
||||
%bd
|
||||
call popup_close(id)
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2
|
||||
|
||||
@@ -150,6 +150,8 @@ func Test_prompt_buffer_edit()
|
||||
call assert_beeps('normal! S')
|
||||
call assert_beeps("normal! \<C-A>")
|
||||
call assert_beeps("normal! \<C-X>")
|
||||
call assert_beeps("normal! dp")
|
||||
call assert_beeps("normal! do")
|
||||
" pressing CTRL-W in the prompt buffer should trigger the window commands
|
||||
call assert_equal(1, winnr())
|
||||
exe "normal A\<C-W>\<C-W>"
|
||||
|
||||
+130
-87
@@ -198,103 +198,102 @@ func Test_recover_corrupted_swap_file()
|
||||
let b = readblob(sn)
|
||||
let save_b = copy(b)
|
||||
bw!
|
||||
" Run these tests only on little-endian systems. These tests fail on a
|
||||
" big-endian system (IBM S390x system).
|
||||
if b[1008:1011] == 0z33323130
|
||||
\ && b[4096:4097] == 0z7470
|
||||
\ && b[8192:8193] == 0z6164
|
||||
|
||||
" clear the B0_MAGIC_LONG field
|
||||
let b[1008:1011] = 0z00000000
|
||||
call writefile(b, sn)
|
||||
let msg = execute('recover Xfile1')
|
||||
call assert_match('the file has been damaged', msg)
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
" Not all fields are written in a system-independent manner. Detect whether
|
||||
" the test is running on a little or big-endian system, so the correct
|
||||
" corruption values can be set.
|
||||
let little_endian = b[1008:1015] == 0z33323130.00000000
|
||||
|
||||
" reduce the page size
|
||||
let b = copy(save_b)
|
||||
let b[12:15] = 0z00010000
|
||||
call writefile(b, sn)
|
||||
let msg = execute('recover Xfile1')
|
||||
call assert_match('page size is smaller than minimum value', msg)
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
" clear the B0_MAGIC_LONG field
|
||||
let b[1008:1015] = 0z0000000000000000
|
||||
call writefile(b, sn)
|
||||
let msg = execute('recover Xfile1')
|
||||
call assert_match('the file has been damaged', msg)
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" clear the pointer ID
|
||||
let b = copy(save_b)
|
||||
let b[4096:4097] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E310:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
" reduce the page size
|
||||
let b = copy(save_b)
|
||||
let b[12:15] = 0z00010000
|
||||
call writefile(b, sn)
|
||||
let msg = execute('recover Xfile1')
|
||||
call assert_match('page size is smaller than minimum value', msg)
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" set the number of pointers in a pointer block to zero
|
||||
let b = copy(save_b)
|
||||
let b[4098:4099] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???EMPTY BLOCK'], getline(1, '$'))
|
||||
bw!
|
||||
" clear the pointer ID
|
||||
let b = copy(save_b)
|
||||
let b[4096:4097] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E310:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal([''], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" set the block number in a pointer entry to a negative number
|
||||
let b = copy(save_b)
|
||||
let b[4104:4111] = 0z00000000.00000080
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???LINES MISSING'], getline(1, '$'))
|
||||
bw!
|
||||
" set the number of pointers in a pointer block to zero
|
||||
let b = copy(save_b)
|
||||
let b[4098:4099] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???EMPTY BLOCK'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" clear the data block ID
|
||||
let b = copy(save_b)
|
||||
let b[8192:8193] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???BLOCK MISSING'], getline(1, '$'))
|
||||
bw!
|
||||
" set the block number in a pointer entry to a negative number
|
||||
let b = copy(save_b)
|
||||
let b[4104:4111] = little_endian ? 0z00000000.00000080 : 0z80000000.00000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???LINES MISSING'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" set the number of lines in the data block to zero
|
||||
let b = copy(save_b)
|
||||
let b[8208:8211] = 0z00000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['??? from here until ???END lines may have been inserted/deleted',
|
||||
\ '???END'], getline(1, '$'))
|
||||
bw!
|
||||
" clear the data block ID
|
||||
let b = copy(save_b)
|
||||
let b[8192:8193] = 0z0000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???BLOCK MISSING'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" use an invalid text start for the lines in a data block
|
||||
let b = copy(save_b)
|
||||
let b[8216:8219] = 0z00000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???'], getline(1, '$'))
|
||||
bw!
|
||||
" set the number of lines in the data block to zero
|
||||
let b = copy(save_b)
|
||||
let b[8208:8215] = 0z00000000.00000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['??? from here until ???END lines may have been inserted/deleted',
|
||||
\ '???END'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" use an incorrect text end (db_txt_end) for the data block
|
||||
let b = copy(save_b)
|
||||
let b[8204:8207] = 0z80000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['??? from here until ???END lines may be messed up', '',
|
||||
\ '???END'], getline(1, '$'))
|
||||
bw!
|
||||
" use an invalid text start for the lines in a data block
|
||||
let b = copy(save_b)
|
||||
let b[8216:8219] = 0z00000000
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" remove the data block
|
||||
let b = copy(save_b)
|
||||
call writefile(b[:8191], sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???MANY LINES MISSING'], getline(1, '$'))
|
||||
endif
|
||||
" use an incorrect text end (db_txt_end) for the data block
|
||||
let b = copy(save_b)
|
||||
let b[8204:8207] = little_endian ? 0z80000000 : 0z00000080
|
||||
call writefile(b, sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['??? from here until ???END lines may be messed up', '',
|
||||
\ '???END'], getline(1, '$'))
|
||||
bw!
|
||||
|
||||
" remove the data block
|
||||
let b = copy(save_b)
|
||||
call writefile(b[:8191], sn)
|
||||
call assert_fails('recover Xfile1', 'E312:')
|
||||
call assert_equal('Xfile1', @%)
|
||||
call assert_equal(['???MANY LINES MISSING'], getline(1, '$'))
|
||||
|
||||
bw!
|
||||
call delete(sn)
|
||||
@@ -390,4 +389,48 @@ func Test_recover_symbolic_link()
|
||||
call delete('.Xfile1.swp')
|
||||
endfunc
|
||||
|
||||
" Test for recovering a file when an autocmd moves the cursor to an invalid
|
||||
" line. This used to result in an internal error (E315) which is fixed
|
||||
" by 8.2.2966.
|
||||
func Test_recover_invalid_cursor_pos()
|
||||
call writefile([], 'Xfile1')
|
||||
edit Xfile1
|
||||
preserve
|
||||
let b = readblob('.Xfile1.swp')
|
||||
bw!
|
||||
augroup Test
|
||||
au!
|
||||
au BufReadPost Xfile1 normal! 3G
|
||||
augroup END
|
||||
call writefile(range(1, 3), 'Xfile1')
|
||||
call writefile(b, '.Xfile1.swp')
|
||||
try
|
||||
recover Xfile1
|
||||
catch /E308:/
|
||||
" this test is for the :E315 internal error.
|
||||
" ignore the 'E308: Original file may have been changed' error
|
||||
endtry
|
||||
redraw!
|
||||
augroup Test
|
||||
au!
|
||||
augroup END
|
||||
augroup! Test
|
||||
call delete('Xfile1')
|
||||
call delete('.Xfile1.swp')
|
||||
endfunc
|
||||
|
||||
" Test for recovering a buffer without a name
|
||||
func Test_noname_buffer()
|
||||
new
|
||||
call setline(1, ['one', 'two'])
|
||||
preserve
|
||||
let sn = swapname('')
|
||||
let b = readblob(sn)
|
||||
bw!
|
||||
call writefile(b, sn)
|
||||
exe "recover " .. sn
|
||||
call assert_equal(['one', 'two'], getline(1, '$'))
|
||||
call delete(sn)
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -1303,4 +1303,19 @@ func Test_write_in_vimrc()
|
||||
call delete('Xvimrc')
|
||||
endfunc
|
||||
|
||||
func Test_echo_true_in_cmd()
|
||||
let lines =<< trim END
|
||||
echo v:true
|
||||
call writefile(['done'], 'Xresult')
|
||||
quit
|
||||
END
|
||||
call writefile(lines, 'Xscript')
|
||||
if RunVim([], [], '--cmd "source Xscript"')
|
||||
call assert_equal(['done'], readfile('Xresult'))
|
||||
endif
|
||||
call delete('Xscript')
|
||||
call delete('Xresult')
|
||||
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -419,4 +419,17 @@ func Test_varsofttabstop()
|
||||
close!
|
||||
endfunc
|
||||
|
||||
" Setting 'shiftwidth' to a negative value, should set it to either the value
|
||||
" of 'tabstop' (if 'vartabstop' is not set) or to the first value in
|
||||
" 'vartabstop'
|
||||
func Test_shiftwidth_vartabstop()
|
||||
setlocal tabstop=7 vartabstop=
|
||||
call assert_fails('set shiftwidth=-1', 'E487:')
|
||||
call assert_equal(7, &shiftwidth)
|
||||
setlocal tabstop=7 vartabstop=5,7,10
|
||||
call assert_fails('set shiftwidth=-1', 'E487:')
|
||||
call assert_equal(5, &shiftwidth)
|
||||
setlocal shiftwidth& vartabstop& tabstop&
|
||||
endfunc
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -982,6 +982,8 @@ def Test_assignment_failure()
|
||||
|
||||
CheckDefFailure(['var true = 1'], 'E1034:')
|
||||
CheckDefFailure(['var false = 1'], 'E1034:')
|
||||
CheckDefFailure(['var null = 1'], 'E1034:')
|
||||
CheckDefFailure(['var this = 1'], 'E1034:')
|
||||
|
||||
CheckDefFailure(['[a; b; c] = g:list'], 'E452:')
|
||||
CheckDefExecFailure(['var a: number',
|
||||
|
||||
@@ -117,7 +117,7 @@ def Test_disassemble_exec_expr()
|
||||
'\d 2STRING stack\[-1\]\_s*' ..
|
||||
'\d\+ PUSHS ".txt"\_s*' ..
|
||||
'\d\+ EXECCONCAT 4\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -133,7 +133,7 @@ EOF
|
||||
assert_match('<SNR>\d*_PyHeredoc.*' ..
|
||||
" python3 << EOF^@ print('hello')^@EOF\\_s*" ..
|
||||
'\d EXEC_SPLIT python3 << EOF^@ print(''hello'')^@EOF\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
endif
|
||||
@@ -153,7 +153,7 @@ def Test_disassemble_substitute()
|
||||
'\d SUBSTITUTE :%s/a/\\=expr/&g#c\_s*' ..
|
||||
' 0 LOAD $0\_s*' ..
|
||||
' -------------\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -181,7 +181,7 @@ def Test_disassemble_seachpair()
|
||||
' -------------\_s*' ..
|
||||
'\d BCALL searchpair(argc 5)\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -209,7 +209,7 @@ def Test_disassemble_redir_var()
|
||||
'\d REDIR END\_s*' ..
|
||||
'\d CONCAT\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -228,7 +228,7 @@ def Test_disassemble_cexpr()
|
||||
'\d CEXPR pre cexpr\_s*' ..
|
||||
'\d LOAD $0\_s*' ..
|
||||
'\d CEXPR core cexpr "cexpr errors"\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -244,7 +244,7 @@ def Test_disassemble_yank_range()
|
||||
'\d EXEC norm! m\[jjm\]\_s*' ..
|
||||
' :''\[,''\]yank\_s*' ..
|
||||
'\d EXEC :''\[,''\]yank\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -258,7 +258,7 @@ def Test_disassemble_put_expr()
|
||||
' :3put ="text"\_s*' ..
|
||||
'\d PUSHS "text"\_s*' ..
|
||||
'\d PUT = 3\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -272,7 +272,7 @@ def Test_disassemble_put_range()
|
||||
' :$-2put a\_s*' ..
|
||||
'\d RANGE $-2\_s*' ..
|
||||
'\d PUT a range\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -390,7 +390,7 @@ def Test_disassemble_store_member()
|
||||
'\d\+ PUSHNR 1\_s*' ..
|
||||
'\d\+ LOAD $2\_s*' ..
|
||||
'\d\+ STOREINDEX blob\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -413,7 +413,7 @@ def Test_disassemble_store_index()
|
||||
'\d LOAD $0\_s*' ..
|
||||
'\d MEMBER dd\_s*' ..
|
||||
'\d STOREINDEX any\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -448,7 +448,7 @@ def Test_disassemble_list_assign()
|
||||
'\d\+ STORE $1\_s*' ..
|
||||
'\d\+ SLICE 2\_s*' ..
|
||||
'\d\+ STORE $2\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -476,7 +476,7 @@ def Test_disassemble_list_add()
|
||||
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
|
||||
'\d\+ LISTAPPEND\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -503,7 +503,7 @@ def Test_disassemble_blob_add()
|
||||
'\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
|
||||
'\d\+ BLOBAPPEND\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -530,7 +530,7 @@ def Test_disassemble_blob_index_slice()
|
||||
'\d\+ PUSHNR 2\_s*' ..
|
||||
'\d\+ BLOBSLICE\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -720,7 +720,7 @@ def Test_disassemble_closure()
|
||||
'\d LOAD arg\[-1\]\_s*' ..
|
||||
'\d CONCAT\_s*' ..
|
||||
'\d STOREOUTER level 1 $0\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
|
||||
res = execute('disass g:Get')
|
||||
@@ -754,7 +754,7 @@ def Test_disassemble_pcall()
|
||||
'\d PCALL top (argc 1)\_s*' ..
|
||||
'\d PCALL end\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1012,7 +1012,7 @@ def Test_disassemble_function()
|
||||
'\d PUSHS "UserFunc"\_s*' ..
|
||||
'\d BCALL funcref(argc 1)\_s*' ..
|
||||
'\d STORE $2\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1039,7 +1039,7 @@ def Test_disassemble_channel()
|
||||
'var chan1: channel\_s*' ..
|
||||
'\d PUSHCHANNEL 0\_s*' ..
|
||||
'\d STORE $2\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1111,7 +1111,7 @@ def Test_disassemble_nested_func()
|
||||
'echomsg "inner"\_s*' ..
|
||||
'enddef\_s*' ..
|
||||
'\d NEWFUNC <lambda>\d\+ Inner\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1133,7 +1133,7 @@ def Test_disassemble_nested_def_list()
|
||||
'\d DEF /Info\_s*' ..
|
||||
'def /Info/\_s*' ..
|
||||
'\d DEF /Info/\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1264,7 +1264,7 @@ def Test_disassemble_for_loop_unpack()
|
||||
'endfor\_s*' ..
|
||||
'\d\+ JUMP -> 8\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1321,7 +1321,7 @@ def Test_disassemble_for_loop_continue()
|
||||
'endfor\_s*' ..
|
||||
'21 JUMP -> 4\_s*' ..
|
||||
'\d\+ DROP\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1341,7 +1341,7 @@ def Test_disassemble_typecast()
|
||||
'\d NEWLIST size 2\_s*' ..
|
||||
'\d SETTYPE list<number>\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'\d RETURN 0\_s*',
|
||||
'\d RETURN void\_s*',
|
||||
instr)
|
||||
enddef
|
||||
|
||||
@@ -1828,7 +1828,7 @@ def Test_dsassemble_falsy_op()
|
||||
'echo "" ?? "empty string"\_s*' ..
|
||||
'\d\+ PUSHS "empty string"\_s*' ..
|
||||
'\d\+ ECHO 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1855,7 +1855,7 @@ def Test_disassemble_compare_const()
|
||||
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '.*' ..
|
||||
'\d PUSHNR 42.*' ..
|
||||
'\d ECHO 1.*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
else
|
||||
# condition false, function just returns
|
||||
@@ -1863,7 +1863,7 @@ def Test_disassemble_compare_const()
|
||||
'if ' .. substitute(case[0], '[[~]', '\\\0', 'g') .. '[ \n]*' ..
|
||||
'echo 42[ \n]*' ..
|
||||
'endif[ \n]*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
instr)
|
||||
endif
|
||||
|
||||
@@ -1901,7 +1901,7 @@ def Test_disassemble_execute()
|
||||
'\d\+ LOAD $1\_s*' ..
|
||||
'\d\+ CONCAT\_s*' ..
|
||||
'\d\+ EXECUTE 1\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -1920,7 +1920,7 @@ def Test_disassemble_echomsg()
|
||||
"echoerr 'went' .. 'wrong'\\_s*" ..
|
||||
'\d PUSHS "wentwrong"\_s*' ..
|
||||
'\d ECHOERR 1\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2029,7 +2029,7 @@ def Test_shuffle()
|
||||
'\d SHUFFLE 2 up 1\_s*' ..
|
||||
'\d BCALL append(argc 2)\_s*' ..
|
||||
'\d DROP\_s*' ..
|
||||
'\d RETURN 0',
|
||||
'\d RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2052,7 +2052,7 @@ def Test_silent()
|
||||
'\d PUSHS "error"\_s*' ..
|
||||
'\d ECHOERR 1\_s*' ..
|
||||
'\d CMDMOD_REV\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2081,7 +2081,7 @@ def Test_silent_if()
|
||||
'\d\+ CMDMOD_REV\_s*' ..
|
||||
'\d\+ JUMP_IF_FALSE -> \d\+\_s*' ..
|
||||
'endif\_s*' ..
|
||||
'\d\+ RETURN 0',
|
||||
'\d\+ RETURN void',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2104,7 +2104,7 @@ def Test_silent_for()
|
||||
'endfor\_s*' ..
|
||||
'\d JUMP -> 5\_s*' ..
|
||||
'8 DROP\_s*' ..
|
||||
'\d RETURN 0\_s*',
|
||||
'\d RETURN void\_s*',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2125,7 +2125,7 @@ def Test_silent_while()
|
||||
|
||||
'endwhile\_s*' ..
|
||||
'\d JUMP -> 0\_s*' ..
|
||||
'6 RETURN 0\_s*',
|
||||
'6 RETURN void\_s*',
|
||||
res)
|
||||
enddef
|
||||
|
||||
@@ -2146,6 +2146,7 @@ enddef
|
||||
|
||||
def s:Profiled(): string
|
||||
echo "profiled"
|
||||
var some = "some text"
|
||||
return "done"
|
||||
enddef
|
||||
|
||||
@@ -2153,18 +2154,41 @@ def Test_profiled()
|
||||
if !has('profile')
|
||||
MissingFeature 'profile'
|
||||
endif
|
||||
var res = execute('disass! s:Profiled')
|
||||
var res = execute('disass profile s:Profiled')
|
||||
assert_match('<SNR>\d*_Profiled\_s*' ..
|
||||
'echo "profiled"\_s*' ..
|
||||
'\d PROFILE START line 1\_s*' ..
|
||||
'\d PUSHS "profiled"\_s*' ..
|
||||
'\d ECHO 1\_s*' ..
|
||||
'return "done"\_s*' ..
|
||||
'var some = "some text"\_s*' ..
|
||||
'\d PROFILE END\_s*' ..
|
||||
'\d PROFILE START line 2\_s*' ..
|
||||
'\d PUSHS "some text"\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'return "done"\_s*' ..
|
||||
'\d PROFILE END\_s*' ..
|
||||
'\d PROFILE START line 3\_s*' ..
|
||||
'\d PUSHS "done"\_s*' ..
|
||||
'\d RETURN\_s*' ..
|
||||
'\d PROFILE END',
|
||||
'\d\+ RETURN\_s*' ..
|
||||
'\d\+ PROFILE END',
|
||||
res)
|
||||
enddef
|
||||
|
||||
def Test_debugged()
|
||||
var res = execute('disass debug s:Profiled')
|
||||
assert_match('<SNR>\d*_Profiled\_s*' ..
|
||||
'echo "profiled"\_s*' ..
|
||||
'\d DEBUG line 1 varcount 0\_s*' ..
|
||||
'\d PUSHS "profiled"\_s*' ..
|
||||
'\d ECHO 1\_s*' ..
|
||||
'var some = "some text"\_s*' ..
|
||||
'\d DEBUG line 2 varcount 0\_s*' ..
|
||||
'\d PUSHS "some text"\_s*' ..
|
||||
'\d STORE $0\_s*' ..
|
||||
'return "done"\_s*' ..
|
||||
'\d DEBUG line 3 varcount 1\_s*' ..
|
||||
'\d PUSHS "done"\_s*' ..
|
||||
'\d RETURN\_s*',
|
||||
res)
|
||||
enddef
|
||||
|
||||
|
||||
@@ -2961,8 +2961,26 @@ def Test_expr7_method_call()
|
||||
|
||||
var Join = (l) => join(l, 'x')
|
||||
assert_equal('axb', ['a', 'b']->(Join)())
|
||||
|
||||
var sorted = [3, 1, 2]
|
||||
-> sort()
|
||||
assert_equal([1, 2, 3], sorted)
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
def RetVoid()
|
||||
enddef
|
||||
RetVoid()->byte2line()
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E1031:')
|
||||
|
||||
lines =<< trim END
|
||||
def RetVoid()
|
||||
enddef
|
||||
RetVoid()->byteidx(3)
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E1031:')
|
||||
enddef
|
||||
|
||||
|
||||
|
||||
@@ -74,6 +74,22 @@ def TestCompilingErrorInTry()
|
||||
delete('Xdir', 'rf')
|
||||
enddef
|
||||
|
||||
def Test_compile_error_in_called_function()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
var n: number
|
||||
def Foo()
|
||||
&hls = n
|
||||
enddef
|
||||
def Bar()
|
||||
Foo()
|
||||
enddef
|
||||
silent! Foo()
|
||||
Bar()
|
||||
END
|
||||
CheckScriptFailureList(lines, ['E1012:', 'E1191:'])
|
||||
enddef
|
||||
|
||||
def Test_autoload_name_mismatch()
|
||||
var dir = 'Xdir/autoload'
|
||||
mkdir(dir, 'p')
|
||||
@@ -98,6 +114,34 @@ def Test_autoload_name_mismatch()
|
||||
delete(dir, 'rf')
|
||||
enddef
|
||||
|
||||
def Test_autoload_names()
|
||||
var dir = 'Xdir/autoload'
|
||||
mkdir(dir, 'p')
|
||||
|
||||
var lines =<< trim END
|
||||
func foobar#function()
|
||||
return 'yes'
|
||||
endfunc
|
||||
let foobar#var = 'no'
|
||||
END
|
||||
writefile(lines, dir .. '/foobar.vim')
|
||||
|
||||
var save_rtp = &rtp
|
||||
exe 'set rtp=' .. getcwd() .. '/Xdir'
|
||||
|
||||
lines =<< trim END
|
||||
assert_equal('yes', foobar#function())
|
||||
var Function = foobar#function
|
||||
assert_equal('yes', Function())
|
||||
|
||||
assert_equal('no', foobar#var)
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
&rtp = save_rtp
|
||||
delete(dir, 'rf')
|
||||
enddef
|
||||
|
||||
def CallRecursive(n: number): number
|
||||
return CallRecursive(n + 1)
|
||||
enddef
|
||||
@@ -904,6 +948,26 @@ def Test_lambda_return_type()
|
||||
echo FilterWithCond('foo', (v) => v .. '^b')
|
||||
END
|
||||
CheckDefAndScriptFailure(lines, 'E1013: Argument 2: type mismatch, expected func(string): bool but got func(any): string', 1)
|
||||
|
||||
lines =<< trim END
|
||||
var Lambda1 = (x) => {
|
||||
return x
|
||||
}
|
||||
assert_equal('asdf', Lambda1('asdf'))
|
||||
var Lambda2 = (x): string => {
|
||||
return x
|
||||
}
|
||||
assert_equal('foo', Lambda2('foo'))
|
||||
END
|
||||
CheckDefAndScriptSuccess(lines)
|
||||
|
||||
lines =<< trim END
|
||||
var Lambda = (x): string => {
|
||||
return x
|
||||
}
|
||||
echo Lambda(['foo'])
|
||||
END
|
||||
CheckDefExecAndScriptFailure(lines, 'E1012:')
|
||||
enddef
|
||||
|
||||
def Test_lambda_uses_assigned_var()
|
||||
@@ -2112,6 +2176,19 @@ def Test_nested_lambda()
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_double_nested_lambda()
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
def F(head: string): func(string): func(string): string
|
||||
return (sep: string): func(string): string => ((tail: string): string => {
|
||||
return head .. sep .. tail
|
||||
})
|
||||
enddef
|
||||
assert_equal('hello-there', F('hello')('-')('there'))
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
enddef
|
||||
|
||||
def Test_nested_inline_lambda()
|
||||
# TODO: use the "text" argument
|
||||
var lines =<< trim END
|
||||
|
||||
@@ -590,6 +590,19 @@ def Test_try_catch_throw()
|
||||
return 2
|
||||
enddef
|
||||
assert_equal(4, ReturnInFinally())
|
||||
|
||||
var lines =<< trim END
|
||||
vim9script
|
||||
try
|
||||
acos('0.5')
|
||||
->setline(1)
|
||||
catch
|
||||
g:caught = v:exception
|
||||
endtry
|
||||
END
|
||||
CheckScriptSuccess(lines)
|
||||
assert_match('E808: Number or Float required', g:caught)
|
||||
unlet g:caught
|
||||
enddef
|
||||
|
||||
" :while at the very start of a function that :continue jumps to
|
||||
|
||||
@@ -7083,6 +7083,15 @@ func Test_compound_assignment_operators()
|
||||
call assert_fails('let &scrolljump .= "j"', 'E734:')
|
||||
set scrolljump&vim
|
||||
|
||||
let &foldlevelstart = 2
|
||||
let &foldlevelstart -= 1
|
||||
call assert_equal(1, &foldlevelstart)
|
||||
let &foldlevelstart -= 1
|
||||
call assert_equal(0, &foldlevelstart)
|
||||
let &foldlevelstart = 2
|
||||
let &foldlevelstart -= 2
|
||||
call assert_equal(0, &foldlevelstart)
|
||||
|
||||
" Test for register
|
||||
let @/ = 1
|
||||
call assert_fails('let @/ += 1', 'E734:')
|
||||
|
||||
@@ -1171,4 +1171,59 @@ func Test_visual_put_in_block_using_zp()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_visual_put_in_block_using_zy_and_zp()
|
||||
new
|
||||
|
||||
" Test 1) Paste using zp - after the cursor without trailing spaces
|
||||
call setline(1, ['/path;text', '/path;text', '/path;text', '',
|
||||
\ 'texttext /subdir columntext',
|
||||
\ 'texttext /longsubdir columntext',
|
||||
\ 'texttext /longlongsubdir columntext'])
|
||||
exe "normal! 5G0f/\<c-v>2jezy"
|
||||
norm! 1G0f;hzp
|
||||
call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
|
||||
|
||||
" Test 2) Paste using zP - in front of the cursor without trailing spaces
|
||||
%d
|
||||
call setline(1, ['/path;text', '/path;text', '/path;text', '',
|
||||
\ 'texttext /subdir columntext',
|
||||
\ 'texttext /longsubdir columntext',
|
||||
\ 'texttext /longlongsubdir columntext'])
|
||||
exe "normal! 5G0f/\<c-v>2jezy"
|
||||
norm! 1G0f;zP
|
||||
call assert_equal(['/path/subdir;text', '/path/longsubdir;text', '/path/longlongsubdir;text'], getline(1, 3))
|
||||
|
||||
" Test 3) Paste using p - with trailing spaces
|
||||
%d
|
||||
call setline(1, ['/path;text', '/path;text', '/path;text', '',
|
||||
\ 'texttext /subdir columntext',
|
||||
\ 'texttext /longsubdir columntext',
|
||||
\ 'texttext /longlongsubdir columntext'])
|
||||
exe "normal! 5G0f/\<c-v>2jezy"
|
||||
norm! 1G0f;hp
|
||||
call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
|
||||
|
||||
" Test 4) Paste using P - with trailing spaces
|
||||
%d
|
||||
call setline(1, ['/path;text', '/path;text', '/path;text', '',
|
||||
\ 'texttext /subdir columntext',
|
||||
\ 'texttext /longsubdir columntext',
|
||||
\ 'texttext /longlongsubdir columntext'])
|
||||
exe "normal! 5G0f/\<c-v>2jezy"
|
||||
norm! 1G0f;P
|
||||
call assert_equal(['/path/subdir ;text', '/path/longsubdir ;text', '/path/longlongsubdir;text'], getline(1, 3))
|
||||
|
||||
" Test 5) Yank with spaces inside the block
|
||||
%d
|
||||
call setline(1, ['/path;text', '/path;text', '/path;text', '',
|
||||
\ 'texttext /sub dir/ columntext',
|
||||
\ 'texttext /lon gsubdir/ columntext',
|
||||
\ 'texttext /lon glongsubdir/ columntext'])
|
||||
exe "normal! 5G0f/\<c-v>2jf/zy"
|
||||
norm! 1G0f;zP
|
||||
call assert_equal(['/path/sub dir/;text', '/path/lon gsubdir/;text', '/path/lon glongsubdir/;text'], getline(1, 3))
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
|
||||
" vim: shiftwidth=2 sts=2 expandtab
|
||||
|
||||
@@ -397,7 +397,15 @@ func Test_window_width()
|
||||
call assert_inrange(ww1, ww1 + 1, ww2)
|
||||
call assert_inrange(ww3, ww3 + 1, ww2)
|
||||
|
||||
bw Xa Xb Xc
|
||||
" when the current window width is less than the new 'winwidth', the current
|
||||
" window width should be increased.
|
||||
enew | only
|
||||
split
|
||||
10vnew
|
||||
set winwidth=15
|
||||
call assert_equal(15, winwidth(0))
|
||||
|
||||
%bw!
|
||||
endfunc
|
||||
|
||||
func Test_equalalways_on_close()
|
||||
|
||||
+13
-5
@@ -238,9 +238,11 @@ tv_get_bool_or_number_chk(typval_T *varp, int *denote, int want_bool)
|
||||
case VAR_BLOB:
|
||||
emsg(_("E974: Using a Blob as a Number"));
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
internal_error_no_abort("tv_get_number(UNKNOWN)");
|
||||
break;
|
||||
@@ -294,7 +296,7 @@ tv_get_bool_chk(typval_T *varp, int *denote)
|
||||
return tv_get_bool_or_number_chk(varp, denote, TRUE);
|
||||
}
|
||||
|
||||
#ifdef FEAT_FLOAT
|
||||
#if defined(FEAT_FLOAT) || defined(PROTO)
|
||||
float_T
|
||||
tv_get_float(typval_T *varp)
|
||||
{
|
||||
@@ -336,9 +338,11 @@ tv_get_float(typval_T *varp)
|
||||
case VAR_BLOB:
|
||||
emsg(_("E975: Using a Blob as a Float"));
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
internal_error_no_abort("tv_get_float(UNKNOWN)");
|
||||
break;
|
||||
@@ -501,9 +505,11 @@ tv_get_string_buf_chk_strict(typval_T *varp, char_u *buf, int strict)
|
||||
return channel_to_string_buf(varp, buf);
|
||||
#endif
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
case VAR_INSTR:
|
||||
semsg(_(e_using_invalid_value_as_string_str),
|
||||
vartype_name(varp->v_type));
|
||||
@@ -657,9 +663,11 @@ copy_tv(typval_T *from, typval_T *to)
|
||||
++to->vval.v_dict->dv_refcount;
|
||||
}
|
||||
break;
|
||||
case VAR_VOID:
|
||||
emsg(_(e_cannot_use_void_value));
|
||||
break;
|
||||
case VAR_UNKNOWN:
|
||||
case VAR_ANY:
|
||||
case VAR_VOID:
|
||||
internal_error_no_abort("copy_tv(UNKNOWN)");
|
||||
break;
|
||||
}
|
||||
|
||||
+2
-2
@@ -1377,7 +1377,7 @@ get_lambda_tv(
|
||||
goto errret;
|
||||
}
|
||||
else
|
||||
fp->uf_ret_type = &t_any;
|
||||
fp->uf_ret_type = &t_unknown;
|
||||
}
|
||||
|
||||
fp->uf_lines = newlines;
|
||||
@@ -4395,7 +4395,7 @@ ex_defcompile(exarg_T *eap UNUSED)
|
||||
&& ufunc->uf_def_status == UF_TO_BE_COMPILED
|
||||
&& (ufunc->uf_flags & FC_DEAD) == 0)
|
||||
{
|
||||
(void)compile_def_function(ufunc, FALSE, FALSE, NULL);
|
||||
(void)compile_def_function(ufunc, FALSE, CT_NONE, NULL);
|
||||
|
||||
if (func_hashtab.ht_changed != changed)
|
||||
{
|
||||
|
||||
@@ -765,6 +765,100 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
3008,
|
||||
/**/
|
||||
3007,
|
||||
/**/
|
||||
3006,
|
||||
/**/
|
||||
3005,
|
||||
/**/
|
||||
3004,
|
||||
/**/
|
||||
3003,
|
||||
/**/
|
||||
3002,
|
||||
/**/
|
||||
3001,
|
||||
/**/
|
||||
3000,
|
||||
/**/
|
||||
2999,
|
||||
/**/
|
||||
2998,
|
||||
/**/
|
||||
2997,
|
||||
/**/
|
||||
2996,
|
||||
/**/
|
||||
2995,
|
||||
/**/
|
||||
2994,
|
||||
/**/
|
||||
2993,
|
||||
/**/
|
||||
2992,
|
||||
/**/
|
||||
2991,
|
||||
/**/
|
||||
2990,
|
||||
/**/
|
||||
2989,
|
||||
/**/
|
||||
2988,
|
||||
/**/
|
||||
2987,
|
||||
/**/
|
||||
2986,
|
||||
/**/
|
||||
2985,
|
||||
/**/
|
||||
2984,
|
||||
/**/
|
||||
2983,
|
||||
/**/
|
||||
2982,
|
||||
/**/
|
||||
2981,
|
||||
/**/
|
||||
2980,
|
||||
/**/
|
||||
2979,
|
||||
/**/
|
||||
2978,
|
||||
/**/
|
||||
2977,
|
||||
/**/
|
||||
2976,
|
||||
/**/
|
||||
2975,
|
||||
/**/
|
||||
2974,
|
||||
/**/
|
||||
2973,
|
||||
/**/
|
||||
2972,
|
||||
/**/
|
||||
2971,
|
||||
/**/
|
||||
2970,
|
||||
/**/
|
||||
2969,
|
||||
/**/
|
||||
2968,
|
||||
/**/
|
||||
2967,
|
||||
/**/
|
||||
2966,
|
||||
/**/
|
||||
2965,
|
||||
/**/
|
||||
2964,
|
||||
/**/
|
||||
2963,
|
||||
/**/
|
||||
2962,
|
||||
/**/
|
||||
2961,
|
||||
/**/
|
||||
|
||||
@@ -784,7 +784,8 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
||||
#define EXPAND_MAPCLEAR 47
|
||||
#define EXPAND_ARGLIST 48
|
||||
#define EXPAND_DIFF_BUFFERS 49
|
||||
#define EXPAND_MACACTION 50
|
||||
#define EXPAND_DISASSEMBLE 50
|
||||
#define EXPAND_MACACTION 51
|
||||
|
||||
// Values for exmode_active (0 is no exmode)
|
||||
#define EXMODE_NORMAL 1
|
||||
@@ -1002,6 +1003,10 @@ extern int (*dyn_libintl_wputenv)(const wchar_t *envstring);
|
||||
#define DOBUF_LAST 2 // "count" buffer from last buffer
|
||||
#define DOBUF_MOD 3 // "count" mod. buffer from current buffer
|
||||
|
||||
// Values for flags argument of do_buffer()
|
||||
#define DOBUF_FORCEIT 1 // :cmd!
|
||||
#define DOBUF_NOPOPUP 2 // skip popup window buffers
|
||||
|
||||
// Values for sub_cmd and which_pat argument for search_regcomp()
|
||||
// Also used for which_pat argument for searchit()
|
||||
#define RE_SEARCH 0 // save/use pat in/from search_pattern
|
||||
@@ -1799,10 +1804,18 @@ typedef struct timeval proftime_T;
|
||||
typedef int proftime_T; // dummy for function prototypes
|
||||
#endif
|
||||
|
||||
// Type of compilation passed to compile_def_function()
|
||||
typedef enum {
|
||||
CT_NONE, // use df_instr
|
||||
CT_PROFILE, // use df_instr_prof
|
||||
CT_DEBUG // use df_instr_debug, overrules CT_PROFILE
|
||||
} compiletype_T;
|
||||
|
||||
// Keep in sync with INSTRUCTIONS().
|
||||
#ifdef FEAT_PROFILE
|
||||
# define PROFILING(ufunc) (do_profiling == PROF_YES && (ufunc)->uf_profiling)
|
||||
# define COMPILE_TYPE(ufunc) (debug_break_level > 0 ? CT_DEBUG : do_profiling == PROF_YES && (ufunc)->uf_profiling ? CT_PROFILE : CT_NONE)
|
||||
#else
|
||||
# define PROFILING(ufunc) FALSE
|
||||
# define COMPILE_TYPE(ufunc) debug_break_level > 0 ? CT_DEBUG : CT_NONE
|
||||
#endif
|
||||
|
||||
/*
|
||||
@@ -1868,6 +1881,8 @@ typedef int sock_T;
|
||||
#define MOUSE_6 0x500 // scroll wheel left
|
||||
#define MOUSE_7 0x600 // scroll wheel right
|
||||
|
||||
#define MOUSE_MOVE 0x700 // report mouse moved
|
||||
|
||||
// 0x20 is reserved by xterm
|
||||
#define MOUSE_DRAG_XTERM 0x40
|
||||
|
||||
|
||||
+17
-4
@@ -91,7 +91,7 @@ typedef enum {
|
||||
ISN_PCALL, // call partial, use isn_arg.pfunc
|
||||
ISN_PCALL_END, // cleanup after ISN_PCALL with cpf_top set
|
||||
ISN_RETURN, // return, result is on top of stack
|
||||
ISN_RETURN_ZERO, // Push zero, then return
|
||||
ISN_RETURN_VOID, // Push void, then return
|
||||
ISN_FUNCREF, // push a function ref to dfunc isn_arg.funcref
|
||||
ISN_NEWFUNC, // create a global function from a lambda function
|
||||
ISN_DEF, // list functions
|
||||
@@ -168,6 +168,9 @@ typedef enum {
|
||||
ISN_PROF_START, // start a line for profiling
|
||||
ISN_PROF_END, // end a line for profiling
|
||||
|
||||
ISN_DEBUG, // check for debug breakpoint, isn_arg.number is current
|
||||
// number of local variables
|
||||
|
||||
ISN_UNPACK, // unpack list into items, uses isn_arg.unpack
|
||||
ISN_SHUFFLE, // move item on stack up or down
|
||||
ISN_DROP, // pop stack and discard value
|
||||
@@ -445,6 +448,7 @@ struct dfunc_S {
|
||||
// was compiled.
|
||||
|
||||
garray_T df_def_args_isn; // default argument instructions
|
||||
garray_T df_var_names; // names of local vars
|
||||
|
||||
// After compiling "df_instr" and/or "df_instr_prof" is not NULL.
|
||||
isn_T *df_instr; // function body to be executed
|
||||
@@ -453,6 +457,8 @@ struct dfunc_S {
|
||||
isn_T *df_instr_prof; // like "df_instr" with profiling
|
||||
int df_instr_prof_count; // size of "df_instr_prof"
|
||||
#endif
|
||||
isn_T *df_instr_debug; // like "df_instr" with debugging
|
||||
int df_instr_debug_count; // size of "df_instr_debug"
|
||||
|
||||
int df_varcount; // number of local variables
|
||||
int df_has_closure; // one if a closure was created
|
||||
@@ -489,10 +495,17 @@ extern garray_T def_functions;
|
||||
// Used for "lnum" when a range is to be taken from the stack and "!" is used.
|
||||
#define LNUM_VARIABLE_RANGE_ABOVE -888
|
||||
|
||||
// Keep in sync with COMPILE_TYPE()
|
||||
#ifdef FEAT_PROFILE
|
||||
# define INSTRUCTIONS(dfunc) \
|
||||
((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
|
||||
? (dfunc)->df_instr_prof : (dfunc)->df_instr)
|
||||
(debug_break_level > 0 \
|
||||
? (dfunc)->df_instr_debug \
|
||||
: ((do_profiling == PROF_YES && (dfunc->df_ufunc)->uf_profiling) \
|
||||
? (dfunc)->df_instr_prof \
|
||||
: (dfunc)->df_instr))
|
||||
#else
|
||||
# define INSTRUCTIONS(dfunc) ((dfunc)->df_instr)
|
||||
# define INSTRUCTIONS(dfunc) \
|
||||
(debug_break_level > 0 \
|
||||
? (dfunc)->df_instr_debug \
|
||||
: (dfunc)->df_instr)
|
||||
#endif
|
||||
|
||||
+170
-54
@@ -174,10 +174,9 @@ struct cctx_S {
|
||||
char_u *ctx_line_start; // start of current line or NULL
|
||||
garray_T ctx_instr; // generated instructions
|
||||
|
||||
int ctx_profiling; // when TRUE generate ISN_PROF_START
|
||||
compiletype_T ctx_compile_type;
|
||||
|
||||
garray_T ctx_locals; // currently visible local variables
|
||||
int ctx_locals_count; // total number of local variables
|
||||
|
||||
int ctx_has_closure; // set to one if a closures was created in
|
||||
// the function
|
||||
@@ -454,7 +453,7 @@ item_exists(char_u *name, size_t len, int cmd UNUSED, cctx_T *cctx)
|
||||
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()".
|
||||
// valid command, such as ":split" versus "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;
|
||||
@@ -574,6 +573,22 @@ generate_instr_type(cctx_T *cctx, isntype_T isn_type, type_T *type)
|
||||
return isn;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an ISN_DEBUG instruction.
|
||||
*/
|
||||
static isn_T *
|
||||
generate_instr_debug(cctx_T *cctx)
|
||||
{
|
||||
isn_T *isn;
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ cctx->ctx_ufunc->uf_dfunc_idx;
|
||||
|
||||
if ((isn = generate_instr(cctx, ISN_DEBUG)) == NULL)
|
||||
return NULL;
|
||||
isn->isn_arg.number = dfunc->df_var_names.ga_len;
|
||||
return isn;
|
||||
}
|
||||
|
||||
/*
|
||||
* If type at "offset" isn't already VAR_STRING then generate ISN_2STRING.
|
||||
* But only for simple types.
|
||||
@@ -1857,7 +1872,7 @@ generate_BLOBAPPEND(cctx_T *cctx)
|
||||
* "profile" indicates profiling is to be done.
|
||||
*/
|
||||
int
|
||||
func_needs_compiling(ufunc_T *ufunc, int profile UNUSED)
|
||||
func_needs_compiling(ufunc_T *ufunc, compiletype_T compile_type)
|
||||
{
|
||||
switch (ufunc->uf_def_status)
|
||||
{
|
||||
@@ -1866,15 +1881,20 @@ func_needs_compiling(ufunc_T *ufunc, int profile UNUSED)
|
||||
|
||||
case UF_COMPILED:
|
||||
{
|
||||
#ifdef FEAT_PROFILE
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
|
||||
return profile ? dfunc->df_instr_prof == NULL
|
||||
: dfunc->df_instr == NULL;
|
||||
#else
|
||||
break;
|
||||
switch (compile_type)
|
||||
{
|
||||
case CT_PROFILE:
|
||||
#ifdef FEAT_PROFILE
|
||||
return dfunc->df_instr_prof == NULL;
|
||||
#endif
|
||||
case CT_NONE:
|
||||
return dfunc->df_instr == NULL;
|
||||
case CT_DEBUG:
|
||||
return dfunc->df_instr_debug == NULL;
|
||||
}
|
||||
}
|
||||
|
||||
case UF_NOT_COMPILED:
|
||||
@@ -1945,11 +1965,17 @@ generate_CALL(cctx_T *cctx, ufunc_T *ufunc, int pushed_argcount)
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, ufunc->uf_ret_type == NULL,
|
||||
PROFILING(ufunc), NULL) == FAIL)
|
||||
COMPILE_TYPE(ufunc), NULL) == FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
if (ufunc->uf_def_status == UF_COMPILE_ERROR)
|
||||
{
|
||||
emsg_funcname(_(e_call_to_function_that_failed_to_compile_str),
|
||||
ufunc->uf_name);
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if ((isn = generate_instr(cctx,
|
||||
ufunc->uf_def_status != UF_NOT_COMPILED ? ISN_DCALL
|
||||
@@ -2307,14 +2333,28 @@ current_instr_idx(cctx_T *cctx)
|
||||
garray_T *instr = &cctx->ctx_instr;
|
||||
int idx = instr->ga_len;
|
||||
|
||||
if (cctx->ctx_has_cmdmod && ((isn_T *)instr->ga_data)[idx - 1]
|
||||
while (idx > 0)
|
||||
{
|
||||
if (cctx->ctx_has_cmdmod && ((isn_T *)instr->ga_data)[idx - 1]
|
||||
.isn_type == ISN_CMDMOD)
|
||||
--idx;
|
||||
{
|
||||
--idx;
|
||||
continue;
|
||||
}
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[idx - 1]
|
||||
.isn_type == ISN_PROF_START)
|
||||
--idx;
|
||||
if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_PROF_START)
|
||||
{
|
||||
--idx;
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (((isn_T *)instr->ga_data)[idx - 1].isn_type == ISN_DEBUG)
|
||||
{
|
||||
--idx;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
@@ -2322,7 +2362,7 @@ current_instr_idx(cctx_T *cctx)
|
||||
static void
|
||||
may_generate_prof_end(cctx_T *cctx, int prof_lnum)
|
||||
{
|
||||
if (cctx->ctx_profiling && prof_lnum >= 0)
|
||||
if (cctx->ctx_compile_type == CT_PROFILE && prof_lnum >= 0)
|
||||
generate_instr(cctx, ISN_PROF_END);
|
||||
}
|
||||
#endif
|
||||
@@ -2340,6 +2380,7 @@ reserve_local(
|
||||
type_T *type)
|
||||
{
|
||||
lvar_T *lvar;
|
||||
dfunc_T *dfunc;
|
||||
|
||||
if (arg_exists(name, len, NULL, NULL, NULL, cctx) == OK)
|
||||
{
|
||||
@@ -2356,12 +2397,20 @@ reserve_local(
|
||||
// the last ones when leaving a scope, but then variables used in a closure
|
||||
// might get overwritten. To keep things simple do not re-use stack
|
||||
// entries. This is less efficient, but memory is cheap these days.
|
||||
lvar->lv_idx = cctx->ctx_locals_count++;
|
||||
dfunc = ((dfunc_T *)def_functions.ga_data) + cctx->ctx_ufunc->uf_dfunc_idx;
|
||||
lvar->lv_idx = dfunc->df_var_names.ga_len;
|
||||
|
||||
lvar->lv_name = vim_strnsave(name, len == 0 ? STRLEN(name) : len);
|
||||
lvar->lv_const = isConst;
|
||||
lvar->lv_type = type;
|
||||
|
||||
// Remember the name for debugging.
|
||||
if (ga_grow(&dfunc->df_var_names, 1) == FAIL)
|
||||
return NULL;
|
||||
((char_u **)dfunc->df_var_names.ga_data)[lvar->lv_idx] =
|
||||
vim_strsave(lvar->lv_name);
|
||||
++dfunc->df_var_names.ga_len;
|
||||
|
||||
return lvar;
|
||||
}
|
||||
|
||||
@@ -2966,8 +3015,8 @@ generate_funcref(cctx_T *cctx, char_u *name)
|
||||
return FAIL;
|
||||
|
||||
// Need to compile any default values to get the argument types.
|
||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), NULL)
|
||||
if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, TRUE, COMPILE_TYPE(ufunc), NULL)
|
||||
== FAIL)
|
||||
return FAIL;
|
||||
return generate_PUSHFUNC(cctx, ufunc->uf_name, ufunc->uf_func_type);
|
||||
@@ -3078,7 +3127,13 @@ compile_load(
|
||||
if (name == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (arg_exists(*arg, len, &idx, &type, &gen_load_outer, cctx) == OK)
|
||||
if (vim_strchr(name, AUTOLOAD_CHAR) != NULL)
|
||||
{
|
||||
script_autoload(name, FALSE);
|
||||
res = generate_LOAD(cctx, ISN_LOADAUTO, 0, name, &t_any);
|
||||
}
|
||||
else if (arg_exists(*arg, len, &idx, &type, &gen_load_outer, cctx)
|
||||
== OK)
|
||||
{
|
||||
if (gen_load_outer == 0)
|
||||
gen_load = TRUE;
|
||||
@@ -3553,8 +3608,12 @@ compile_lambda(char_u **arg, cctx_T *cctx)
|
||||
++ufunc->uf_refcount;
|
||||
clear_tv(&rettv);
|
||||
|
||||
// Compile the function into instructions.
|
||||
compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx);
|
||||
// Compile it here to get the return type. The return type is optional,
|
||||
// when it's missing use t_unknown. This is recognized in
|
||||
// compile_return().
|
||||
if (ufunc->uf_ret_type->tt_type == VAR_VOID)
|
||||
ufunc->uf_ret_type = &t_unknown;
|
||||
compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), cctx);
|
||||
|
||||
// evalarg.eval_tofree_cmdline may have a copy of the last line and "*arg"
|
||||
// points into it. Point to the original line to avoid a dangling pointer.
|
||||
@@ -4108,7 +4167,8 @@ compile_subscript(
|
||||
// Also if a following line starts with ".x".
|
||||
if (next != NULL &&
|
||||
((next[0] == '-' && next[1] == '>'
|
||||
&& (next[2] == '{' || ASCII_ISALPHA(next[2])))
|
||||
&& (next[2] == '{'
|
||||
|| ASCII_ISALPHA(*skipwhite(next + 2))))
|
||||
|| (next[0] == '.' && eval_isdictc(next[1]))))
|
||||
{
|
||||
next = next_line_from_context(cctx, TRUE);
|
||||
@@ -5385,10 +5445,15 @@ compile_return(char_u *arg, int check_return_type, int legacy, cctx_T *cctx)
|
||||
|
||||
if (cctx->ctx_skip != SKIP_YES)
|
||||
{
|
||||
// "check_return_type" with uf_ret_type set to &t_unknown is used
|
||||
// for an inline function without a specified return type. Set the
|
||||
// return type here.
|
||||
stack_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
|
||||
if (check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL
|
||||
if ((check_return_type && (cctx->ctx_ufunc->uf_ret_type == NULL
|
||||
|| cctx->ctx_ufunc->uf_ret_type == &t_unknown
|
||||
|| cctx->ctx_ufunc->uf_ret_type == &t_any))
|
||||
|| (!check_return_type
|
||||
&& cctx->ctx_ufunc->uf_ret_type == &t_unknown))
|
||||
{
|
||||
cctx->ctx_ufunc->uf_ret_type = stack_type;
|
||||
}
|
||||
@@ -5544,8 +5609,8 @@ compile_nested_function(exarg_T *eap, cctx_T *cctx)
|
||||
}
|
||||
}
|
||||
|
||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
&& compile_def_function(ufunc, TRUE, PROFILING(ufunc), cctx)
|
||||
if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, TRUE, COMPILE_TYPE(ufunc), cctx)
|
||||
== FAIL)
|
||||
{
|
||||
func_ptr_unref(ufunc);
|
||||
@@ -7354,7 +7419,7 @@ compile_if(char_u *arg, cctx_T *cctx)
|
||||
scope->se_u.se_if.is_if_label = -1;
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling && cctx->ctx_skip == SKIP_YES
|
||||
if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
|
||||
&& skip_save != SKIP_YES)
|
||||
{
|
||||
// generated a profile start, need to generate a profile end, since it
|
||||
@@ -7435,13 +7500,19 @@ compile_elseif(char_u *arg, cctx_T *cctx)
|
||||
{
|
||||
cctx->ctx_skip = SKIP_UNKNOWN;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling)
|
||||
if (cctx->ctx_compile_type == CT_PROFILE)
|
||||
{
|
||||
// the previous block was skipped, need to profile this line
|
||||
generate_instr(cctx, ISN_PROF_START);
|
||||
instr_count = instr->ga_len;
|
||||
}
|
||||
#endif
|
||||
if (cctx->ctx_compile_type == CT_DEBUG)
|
||||
{
|
||||
// the previous block was skipped, may want to debug this line
|
||||
generate_instr_debug(cctx);
|
||||
instr_count = instr->ga_len;
|
||||
}
|
||||
}
|
||||
if (compile_expr1(&p, cctx, &ppconst) == FAIL)
|
||||
{
|
||||
@@ -7509,12 +7580,13 @@ compile_else(char_u *arg, cctx_T *cctx)
|
||||
scope->se_u.se_if.is_seen_else = TRUE;
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling)
|
||||
if (cctx->ctx_compile_type == CT_PROFILE)
|
||||
{
|
||||
if (cctx->ctx_skip == SKIP_NOT
|
||||
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
.isn_type == ISN_PROF_START)
|
||||
// the previous block was executed, do not count "else" for profiling
|
||||
// the previous block was executed, do not count "else" for
|
||||
// profiling
|
||||
--instr->ga_len;
|
||||
if (cctx->ctx_skip == SKIP_YES && !scope->se_u.se_if.is_seen_skip_not)
|
||||
{
|
||||
@@ -7590,7 +7662,7 @@ compile_endif(char_u *arg, cctx_T *cctx)
|
||||
#ifdef FEAT_PROFILE
|
||||
// even when skipping we count the endif as executed, unless the block it's
|
||||
// in is skipped
|
||||
if (cctx->ctx_profiling && cctx->ctx_skip == SKIP_YES
|
||||
if (cctx->ctx_compile_type == CT_PROFILE && cctx->ctx_skip == SKIP_YES
|
||||
&& scope->se_skip_save != SKIP_YES)
|
||||
{
|
||||
cctx->ctx_skip = SKIP_NOT;
|
||||
@@ -8161,7 +8233,8 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
|
||||
{
|
||||
#ifdef FEAT_PROFILE
|
||||
// the profile-start should be after the jump
|
||||
if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
if (cctx->ctx_compile_type == CT_PROFILE
|
||||
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
.isn_type == ISN_PROF_START)
|
||||
--instr->ga_len;
|
||||
#endif
|
||||
@@ -8181,7 +8254,7 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
|
||||
isn->isn_arg.jump.jump_where = instr->ga_len;
|
||||
}
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling)
|
||||
if (cctx->ctx_compile_type == CT_PROFILE)
|
||||
{
|
||||
// a "throw" that jumps here needs to be counted
|
||||
generate_instr(cctx, ISN_PROF_END);
|
||||
@@ -8189,6 +8262,8 @@ compile_catch(char_u *arg, cctx_T *cctx UNUSED)
|
||||
generate_instr(cctx, ISN_PROF_START);
|
||||
}
|
||||
#endif
|
||||
if (cctx->ctx_compile_type == CT_DEBUG)
|
||||
generate_instr_debug(cctx);
|
||||
}
|
||||
|
||||
p = skipwhite(arg);
|
||||
@@ -8276,7 +8351,8 @@ compile_finally(char_u *arg, cctx_T *cctx)
|
||||
|
||||
this_instr = instr->ga_len;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
if (cctx->ctx_compile_type == CT_PROFILE
|
||||
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
.isn_type == ISN_PROF_START)
|
||||
// jump to the profile start of the "finally"
|
||||
--this_instr;
|
||||
@@ -8345,7 +8421,8 @@ compile_endtry(char_u *arg, cctx_T *cctx)
|
||||
}
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling && ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
if (cctx->ctx_compile_type == CT_PROFILE
|
||||
&& ((isn_T *)instr->ga_data)[instr->ga_len - 1]
|
||||
.isn_type == ISN_PROF_START)
|
||||
// move the profile start after "endtry" so that it's not counted when
|
||||
// the exception is rethrown.
|
||||
@@ -8377,7 +8454,7 @@ compile_endtry(char_u *arg, cctx_T *cctx)
|
||||
&& generate_instr(cctx, ISN_ENDTRY) == NULL)
|
||||
return NULL;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx->ctx_profiling)
|
||||
if (cctx->ctx_compile_type == CT_PROFILE)
|
||||
generate_instr(cctx, ISN_PROF_START);
|
||||
#endif
|
||||
}
|
||||
@@ -8923,6 +9000,7 @@ add_def_function(ufunc_T *ufunc)
|
||||
ufunc->uf_dfunc_idx = dfunc->df_idx;
|
||||
dfunc->df_ufunc = ufunc;
|
||||
dfunc->df_name = vim_strsave(ufunc->uf_name);
|
||||
ga_init2(&dfunc->df_var_names, sizeof(char_u *), 10);
|
||||
++dfunc->df_refcount;
|
||||
++def_functions.ga_len;
|
||||
return OK;
|
||||
@@ -8943,10 +9021,10 @@ add_def_function(ufunc_T *ufunc)
|
||||
*/
|
||||
int
|
||||
compile_def_function(
|
||||
ufunc_T *ufunc,
|
||||
int check_return_type,
|
||||
int profiling UNUSED,
|
||||
cctx_T *outer_cctx)
|
||||
ufunc_T *ufunc,
|
||||
int check_return_type,
|
||||
compiletype_T compile_type,
|
||||
cctx_T *outer_cctx)
|
||||
{
|
||||
char_u *line = NULL;
|
||||
char_u *line_to_free = NULL;
|
||||
@@ -8965,6 +9043,7 @@ compile_def_function(
|
||||
#ifdef FEAT_PROFILE
|
||||
int prof_lnum = -1;
|
||||
#endif
|
||||
int debug_lnum = -1;
|
||||
|
||||
// When using a function that was compiled before: Free old instructions.
|
||||
// The index is reused. Otherwise add a new entry in "def_functions".
|
||||
@@ -8972,7 +9051,21 @@ compile_def_function(
|
||||
{
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
delete_def_function_contents(dfunc, FALSE);
|
||||
isn_T *instr_dest = NULL;
|
||||
|
||||
switch (compile_type)
|
||||
{
|
||||
case CT_PROFILE:
|
||||
#ifdef FEAT_PROFILE
|
||||
instr_dest = dfunc->df_instr_prof; break;
|
||||
#endif
|
||||
case CT_NONE: instr_dest = dfunc->df_instr; break;
|
||||
case CT_DEBUG: instr_dest = dfunc->df_instr_debug; break;
|
||||
}
|
||||
if (instr_dest != NULL)
|
||||
// Was compiled in this mode before: Free old instructions.
|
||||
delete_def_function_contents(dfunc, FALSE);
|
||||
ga_clear_strings(&dfunc->df_var_names);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -8985,9 +9078,7 @@ compile_def_function(
|
||||
|
||||
CLEAR_FIELD(cctx);
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
cctx.ctx_profiling = profiling;
|
||||
#endif
|
||||
cctx.ctx_compile_type = compile_type;
|
||||
cctx.ctx_ufunc = ufunc;
|
||||
cctx.ctx_lnum = -1;
|
||||
cctx.ctx_outer = outer_cctx;
|
||||
@@ -9137,8 +9228,8 @@ compile_def_function(
|
||||
}
|
||||
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx.ctx_profiling && cctx.ctx_lnum != prof_lnum &&
|
||||
cctx.ctx_skip != SKIP_YES)
|
||||
if (cctx.ctx_compile_type == CT_PROFILE && cctx.ctx_lnum != prof_lnum
|
||||
&& cctx.ctx_skip != SKIP_YES)
|
||||
{
|
||||
may_generate_prof_end(&cctx, prof_lnum);
|
||||
|
||||
@@ -9146,6 +9237,12 @@ compile_def_function(
|
||||
generate_instr(&cctx, ISN_PROF_START);
|
||||
}
|
||||
#endif
|
||||
if (cctx.ctx_compile_type == CT_DEBUG && cctx.ctx_lnum != debug_lnum
|
||||
&& cctx.ctx_skip != SKIP_YES)
|
||||
{
|
||||
debug_lnum = cctx.ctx_lnum;
|
||||
generate_instr_debug(&cctx);
|
||||
}
|
||||
|
||||
// Some things can be recognized by the first character.
|
||||
switch (*ea.cmd)
|
||||
@@ -9574,14 +9671,16 @@ nextline:
|
||||
|
||||
if (!cctx.ctx_had_return)
|
||||
{
|
||||
if (ufunc->uf_ret_type->tt_type != VAR_VOID)
|
||||
if (ufunc->uf_ret_type->tt_type == VAR_UNKNOWN)
|
||||
ufunc->uf_ret_type = &t_void;
|
||||
else if (ufunc->uf_ret_type->tt_type != VAR_VOID)
|
||||
{
|
||||
emsg(_(e_missing_return_statement));
|
||||
goto erret;
|
||||
}
|
||||
|
||||
// Return zero if there is no return at the end.
|
||||
generate_instr(&cctx, ISN_RETURN_ZERO);
|
||||
// Return void if there is no return at the end.
|
||||
generate_instr(&cctx, ISN_RETURN_VOID);
|
||||
}
|
||||
|
||||
// When compiled with ":silent!" and there was an error don't consider the
|
||||
@@ -9593,18 +9692,24 @@ nextline:
|
||||
dfunc->df_deleted = FALSE;
|
||||
dfunc->df_script_seq = current_sctx.sc_seq;
|
||||
#ifdef FEAT_PROFILE
|
||||
if (cctx.ctx_profiling)
|
||||
if (cctx.ctx_compile_type == CT_PROFILE)
|
||||
{
|
||||
dfunc->df_instr_prof = instr->ga_data;
|
||||
dfunc->df_instr_prof_count = instr->ga_len;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (cctx.ctx_compile_type == CT_DEBUG)
|
||||
{
|
||||
dfunc->df_instr_debug = instr->ga_data;
|
||||
dfunc->df_instr_debug_count = instr->ga_len;
|
||||
}
|
||||
else
|
||||
{
|
||||
dfunc->df_instr = instr->ga_data;
|
||||
dfunc->df_instr_count = instr->ga_len;
|
||||
}
|
||||
dfunc->df_varcount = cctx.ctx_locals_count;
|
||||
dfunc->df_varcount = dfunc->df_var_names.ga_len;
|
||||
dfunc->df_has_closure = cctx.ctx_has_closure;
|
||||
if (cctx.ctx_outer_used)
|
||||
ufunc->uf_flags |= FC_CLOSURE;
|
||||
@@ -9619,8 +9724,10 @@ erret:
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ufunc->uf_dfunc_idx;
|
||||
|
||||
// Compiling aborted, free the generated instructions.
|
||||
clear_instr_ga(instr);
|
||||
VIM_CLEAR(dfunc->df_name);
|
||||
ga_clear_strings(&dfunc->df_var_names);
|
||||
|
||||
// If using the last entry in the table and it was added above, we
|
||||
// might as well remove it.
|
||||
@@ -9895,6 +10002,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_COMPARESTRING:
|
||||
case ISN_CONCAT:
|
||||
case ISN_COND2BOOL:
|
||||
case ISN_DEBUG:
|
||||
case ISN_DROP:
|
||||
case ISN_ECHO:
|
||||
case ISN_ECHOERR:
|
||||
@@ -9903,6 +10011,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_EXECCONCAT:
|
||||
case ISN_EXECUTE:
|
||||
case ISN_FINALLY:
|
||||
case ISN_FINISH:
|
||||
case ISN_FOR:
|
||||
case ISN_GETITEM:
|
||||
case ISN_JUMP:
|
||||
@@ -9925,7 +10034,6 @@ delete_instr(isn_T *isn)
|
||||
case ISN_NEWLIST:
|
||||
case ISN_OPANY:
|
||||
case ISN_OPFLOAT:
|
||||
case ISN_FINISH:
|
||||
case ISN_OPNR:
|
||||
case ISN_PCALL:
|
||||
case ISN_PCALL_END:
|
||||
@@ -9939,7 +10047,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_REDIREND:
|
||||
case ISN_REDIRSTART:
|
||||
case ISN_RETURN:
|
||||
case ISN_RETURN_ZERO:
|
||||
case ISN_RETURN_VOID:
|
||||
case ISN_SHUFFLE:
|
||||
case ISN_SLICE:
|
||||
case ISN_STORE:
|
||||
@@ -9970,6 +10078,7 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
|
||||
int idx;
|
||||
|
||||
ga_clear(&dfunc->df_def_args_isn);
|
||||
ga_clear_strings(&dfunc->df_var_names);
|
||||
|
||||
if (dfunc->df_instr != NULL)
|
||||
{
|
||||
@@ -9978,6 +10087,13 @@ delete_def_function_contents(dfunc_T *dfunc, int mark_deleted)
|
||||
VIM_CLEAR(dfunc->df_instr);
|
||||
dfunc->df_instr = NULL;
|
||||
}
|
||||
if (dfunc->df_instr_debug != NULL)
|
||||
{
|
||||
for (idx = 0; idx < dfunc->df_instr_debug_count; ++idx)
|
||||
delete_instr(dfunc->df_instr_debug + idx);
|
||||
VIM_CLEAR(dfunc->df_instr_debug);
|
||||
dfunc->df_instr_debug = NULL;
|
||||
}
|
||||
#ifdef FEAT_PROFILE
|
||||
if (dfunc->df_instr_prof != NULL)
|
||||
{
|
||||
|
||||
+237
-71
@@ -43,6 +43,14 @@ typedef struct {
|
||||
int floc_restore_cmdmod_stacklen;
|
||||
} funclocal_T;
|
||||
|
||||
// Structure to hold a reference to an outer_T, with information of whether it
|
||||
// was allocated.
|
||||
typedef struct {
|
||||
outer_T *or_outer;
|
||||
partial_T *or_partial; // decrement "or_partial->pt_refcount" later
|
||||
int or_outer_allocated; // free "or_outer" later
|
||||
} outer_ref_T;
|
||||
|
||||
// A stack is used to store:
|
||||
// - arguments passed to a :def function
|
||||
// - info about the calling function, to use when returning
|
||||
@@ -70,7 +78,7 @@ struct ectx_S {
|
||||
int ec_frame_idx; // index in ec_stack: context of ec_dfunc_idx
|
||||
int ec_initial_frame_idx; // frame index when called
|
||||
|
||||
outer_T *ec_outer; // outer scope used for closures, allocated
|
||||
outer_ref_T *ec_outer_ref; // outer scope used for closures, allocated
|
||||
funclocal_T ec_funclocal;
|
||||
|
||||
garray_T ec_trystack; // stack of trycmd_T values
|
||||
@@ -143,7 +151,7 @@ exe_newlist(int count, ectx_T *ectx)
|
||||
* Call compiled function "cdf_idx" from compiled code.
|
||||
* This adds a stack frame and sets the instruction pointer to the start of the
|
||||
* called function.
|
||||
* If "pt" is not null use "pt->pt_outer" for ec_outer.
|
||||
* If "pt" is not null use "pt->pt_outer" for ec_outer_ref->or_outer.
|
||||
*
|
||||
* Stack has:
|
||||
* - current arguments (already there)
|
||||
@@ -164,6 +172,7 @@ call_dfunc(
|
||||
int argcount = argcount_arg;
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) + cdf_idx;
|
||||
ufunc_T *ufunc = dfunc->df_ufunc;
|
||||
int did_emsg_before = did_emsg_cumul + did_emsg;
|
||||
int arg_to_add;
|
||||
int vararg_count = 0;
|
||||
int varcount;
|
||||
@@ -196,13 +205,26 @@ call_dfunc(
|
||||
// Profiling might be enabled/disabled along the way. This should not
|
||||
// fail, since the function was compiled before and toggling profiling
|
||||
// doesn't change any errors.
|
||||
if (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
|
||||
if (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
|
||||
== FAIL)
|
||||
return FAIL;
|
||||
}
|
||||
#endif
|
||||
|
||||
// When debugging and using "cont" switches to the not-debugged
|
||||
// instructions, may need to still compile them.
|
||||
if ((func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
|
||||
== FAIL)
|
||||
|| INSTRUCTIONS(dfunc) == NULL)
|
||||
{
|
||||
if (did_emsg_cumul + did_emsg == did_emsg_before)
|
||||
semsg(_(e_function_is_not_compiled_str),
|
||||
printable_func_name(ufunc));
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (ufunc->uf_va_name != NULL)
|
||||
{
|
||||
// Need to make a list out of the vararg arguments.
|
||||
@@ -256,6 +278,7 @@ call_dfunc(
|
||||
// If depth of calling is getting too high, don't execute the function.
|
||||
if (funcdepth_increment() == FAIL)
|
||||
return FAIL;
|
||||
++ex_nesting_level;
|
||||
|
||||
// Only make a copy of funclocal if it contains something to restore.
|
||||
if (ectx->ec_funclocal.floc_restore_cmdmod)
|
||||
@@ -280,7 +303,8 @@ call_dfunc(
|
||||
STACK_TV_BOT(STACK_FRAME_FUNC_OFF)->vval.v_number = ectx->ec_dfunc_idx;
|
||||
STACK_TV_BOT(STACK_FRAME_IIDX_OFF)->vval.v_number = ectx->ec_iidx;
|
||||
STACK_TV_BOT(STACK_FRAME_INSTR_OFF)->vval.v_string = (void *)ectx->ec_instr;
|
||||
STACK_TV_BOT(STACK_FRAME_OUTER_OFF)->vval.v_string = (void *)ectx->ec_outer;
|
||||
STACK_TV_BOT(STACK_FRAME_OUTER_OFF)->vval.v_string =
|
||||
(void *)ectx->ec_outer_ref;
|
||||
STACK_TV_BOT(STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string = (void *)floc;
|
||||
STACK_TV_BOT(STACK_FRAME_IDX_OFF)->vval.v_number = ectx->ec_frame_idx;
|
||||
ectx->ec_frame_idx = ectx->ec_stack.ga_len;
|
||||
@@ -300,30 +324,40 @@ call_dfunc(
|
||||
if (pt != NULL || ufunc->uf_partial != NULL
|
||||
|| (ufunc->uf_flags & FC_CLOSURE))
|
||||
{
|
||||
outer_T *outer = ALLOC_CLEAR_ONE(outer_T);
|
||||
outer_ref_T *ref = ALLOC_CLEAR_ONE(outer_ref_T);
|
||||
|
||||
if (outer == NULL)
|
||||
if (ref == NULL)
|
||||
return FAIL;
|
||||
if (pt != NULL)
|
||||
{
|
||||
*outer = pt->pt_outer;
|
||||
outer->out_up_is_copy = TRUE;
|
||||
ref->or_outer = &pt->pt_outer;
|
||||
++pt->pt_refcount;
|
||||
ref->or_partial = pt;
|
||||
}
|
||||
else if (ufunc->uf_partial != NULL)
|
||||
{
|
||||
*outer = ufunc->uf_partial->pt_outer;
|
||||
outer->out_up_is_copy = TRUE;
|
||||
ref->or_outer = &ufunc->uf_partial->pt_outer;
|
||||
++ufunc->uf_partial->pt_refcount;
|
||||
ref->or_partial = ufunc->uf_partial;
|
||||
}
|
||||
else
|
||||
{
|
||||
outer->out_stack = &ectx->ec_stack;
|
||||
outer->out_frame_idx = ectx->ec_frame_idx;
|
||||
outer->out_up = ectx->ec_outer;
|
||||
ref->or_outer = ALLOC_CLEAR_ONE(outer_T);
|
||||
if (ref->or_outer == NULL)
|
||||
{
|
||||
vim_free(ref);
|
||||
return FAIL;
|
||||
}
|
||||
ref->or_outer_allocated = TRUE;
|
||||
ref->or_outer->out_stack = &ectx->ec_stack;
|
||||
ref->or_outer->out_frame_idx = ectx->ec_frame_idx;
|
||||
if (ectx->ec_outer_ref != NULL)
|
||||
ref->or_outer->out_up = ectx->ec_outer_ref->or_outer;
|
||||
}
|
||||
ectx->ec_outer = outer;
|
||||
ectx->ec_outer_ref = ref;
|
||||
}
|
||||
else
|
||||
ectx->ec_outer = NULL;
|
||||
ectx->ec_outer_ref = NULL;
|
||||
|
||||
++ufunc->uf_calls;
|
||||
|
||||
@@ -476,7 +510,6 @@ handle_closure_in_use(ectx_T *ectx, int free_arguments)
|
||||
pt->pt_funcstack = funcstack;
|
||||
pt->pt_outer.out_stack = &funcstack->fs_ga;
|
||||
pt->pt_outer.out_frame_idx = ectx->ec_frame_idx - top;
|
||||
pt->pt_outer.out_up = ectx->ec_outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -587,7 +620,13 @@ func_return(ectx_T *ectx)
|
||||
if (ret_idx == ectx->ec_frame_idx + STACK_FRAME_IDX_OFF)
|
||||
ret_idx = 0;
|
||||
|
||||
vim_free(ectx->ec_outer);
|
||||
if (ectx->ec_outer_ref != NULL)
|
||||
{
|
||||
if (ectx->ec_outer_ref->or_outer_allocated)
|
||||
vim_free(ectx->ec_outer_ref->or_outer);
|
||||
partial_unref(ectx->ec_outer_ref->or_partial);
|
||||
vim_free(ectx->ec_outer_ref);
|
||||
}
|
||||
|
||||
// Restore the previous frame.
|
||||
ectx->ec_dfunc_idx = prev_dfunc_idx;
|
||||
@@ -595,7 +634,7 @@ func_return(ectx_T *ectx)
|
||||
+ STACK_FRAME_IIDX_OFF)->vval.v_number;
|
||||
ectx->ec_instr = (void *)STACK_TV(ectx->ec_frame_idx
|
||||
+ STACK_FRAME_INSTR_OFF)->vval.v_string;
|
||||
ectx->ec_outer = (void *)STACK_TV(ectx->ec_frame_idx
|
||||
ectx->ec_outer_ref = (void *)STACK_TV(ectx->ec_frame_idx
|
||||
+ STACK_FRAME_OUTER_OFF)->vval.v_string;
|
||||
floc = (void *)STACK_TV(ectx->ec_frame_idx
|
||||
+ STACK_FRAME_FUNCLOCAL_OFF)->vval.v_string;
|
||||
@@ -623,6 +662,7 @@ func_return(ectx_T *ectx)
|
||||
ectx->ec_stack.ga_len = top;
|
||||
|
||||
funcdepth_decrement();
|
||||
--ex_nesting_level;
|
||||
return OK;
|
||||
}
|
||||
|
||||
@@ -696,7 +736,7 @@ call_bfunc(int func_idx, int argcount, ectx_T *ectx)
|
||||
* If the function is compiled this will add a stack frame and set the
|
||||
* instruction pointer at the start of the function.
|
||||
* Otherwise the function is called here.
|
||||
* If "pt" is not null use "pt->pt_outer" for ec_outer.
|
||||
* If "pt" is not null use "pt->pt_outer" for ec_outer_ref->or_outer.
|
||||
* "iptr" can be used to replace the instruction with a more efficient one.
|
||||
*/
|
||||
static int
|
||||
@@ -712,14 +752,11 @@ call_ufunc(
|
||||
int error;
|
||||
int idx;
|
||||
int did_emsg_before = did_emsg;
|
||||
#ifdef FEAT_PROFILE
|
||||
int profiling = do_profiling == PROF_YES && ufunc->uf_profiling;
|
||||
#else
|
||||
# define profiling FALSE
|
||||
#endif
|
||||
compiletype_T compile_type = COMPILE_TYPE(ufunc);
|
||||
|
||||
if (func_needs_compiling(ufunc, profiling)
|
||||
&& compile_def_function(ufunc, FALSE, profiling, NULL) == FAIL)
|
||||
if (func_needs_compiling(ufunc, compile_type)
|
||||
&& compile_def_function(ufunc, FALSE, compile_type, NULL)
|
||||
== FAIL)
|
||||
return FAIL;
|
||||
if (ufunc->uf_def_status == UF_COMPILED)
|
||||
{
|
||||
@@ -1295,24 +1332,31 @@ fill_partial_and_closure(partial_T *pt, ufunc_T *ufunc, ectx_T *ectx)
|
||||
dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data)
|
||||
+ ectx->ec_dfunc_idx;
|
||||
|
||||
// The closure needs to find arguments and local
|
||||
// variables in the current stack.
|
||||
// The closure may need to find arguments and local variables in the
|
||||
// current stack.
|
||||
pt->pt_outer.out_stack = &ectx->ec_stack;
|
||||
pt->pt_outer.out_frame_idx = ectx->ec_frame_idx;
|
||||
pt->pt_outer.out_up = ectx->ec_outer;
|
||||
pt->pt_outer.out_up_is_copy = TRUE;
|
||||
if (ectx->ec_outer_ref != NULL)
|
||||
{
|
||||
// The current context already has a context, link to that one.
|
||||
pt->pt_outer.out_up = ectx->ec_outer_ref->or_outer;
|
||||
if (ectx->ec_outer_ref->or_partial != NULL)
|
||||
{
|
||||
pt->pt_outer.out_up_partial = ectx->ec_outer_ref->or_partial;
|
||||
++pt->pt_outer.out_up_partial->pt_refcount;
|
||||
}
|
||||
}
|
||||
|
||||
// If this function returns and the closure is still
|
||||
// being used, we need to make a copy of the context
|
||||
// (arguments and local variables). Store a reference
|
||||
// to the partial so we can handle that.
|
||||
// If this function returns and the closure is still being used, we
|
||||
// need to make a copy of the context (arguments and local variables).
|
||||
// Store a reference to the partial so we can handle that.
|
||||
if (ga_grow(&ectx->ec_funcrefs, 1) == FAIL)
|
||||
{
|
||||
vim_free(pt);
|
||||
return FAIL;
|
||||
}
|
||||
// Extra variable keeps the count of closures created
|
||||
// in the current function call.
|
||||
// Extra variable keeps the count of closures created in the current
|
||||
// function call.
|
||||
++(((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_frame_idx
|
||||
+ STACK_FRAME_SIZE + dfunc->df_varcount)->vval.v_number;
|
||||
|
||||
@@ -1348,6 +1392,36 @@ typedef struct subs_expr_S {
|
||||
// Get pointer to a local variable on the stack. Negative for arguments.
|
||||
#define STACK_TV_VAR(idx) (((typval_T *)ectx->ec_stack.ga_data) + ectx->ec_frame_idx + STACK_FRAME_SIZE + idx)
|
||||
|
||||
// Set when calling do_debug().
|
||||
static ectx_T *debug_context = NULL;
|
||||
static int debug_arg_count;
|
||||
|
||||
/*
|
||||
* When debugging lookup "name" and return the typeval.
|
||||
* When not found return NULL.
|
||||
*/
|
||||
typval_T *
|
||||
lookup_debug_var(char_u *name)
|
||||
{
|
||||
int idx;
|
||||
dfunc_T *dfunc;
|
||||
ectx_T *ectx = debug_context;
|
||||
|
||||
if (ectx == NULL)
|
||||
return NULL;
|
||||
dfunc = ((dfunc_T *)def_functions.ga_data) + ectx->ec_dfunc_idx;
|
||||
|
||||
// Go through the local variable names, from last to first.
|
||||
for (idx = debug_arg_count - 1; idx >= 0; --idx)
|
||||
{
|
||||
char_u *s = ((char_u **)dfunc->df_var_names.ga_data)[idx];
|
||||
if (STRCMP(s, name) == 0)
|
||||
return STACK_TV_VAR(idx);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Execute instructions in execution context "ectx".
|
||||
* Return OK or FAIL;
|
||||
@@ -2355,7 +2429,8 @@ exec_instructions(ectx_T *ectx)
|
||||
case ISN_STOREOUTER:
|
||||
{
|
||||
int depth = iptr->isn_arg.outer.outer_depth;
|
||||
outer_T *outer = ectx->ec_outer;
|
||||
outer_T *outer = ectx->ec_outer_ref == NULL ? NULL
|
||||
: ectx->ec_outer_ref->or_outer;
|
||||
|
||||
while (depth > 1 && outer != NULL)
|
||||
{
|
||||
@@ -2740,17 +2815,18 @@ exec_instructions(ectx_T *ectx)
|
||||
}
|
||||
break;
|
||||
|
||||
// return from a :def function call
|
||||
case ISN_RETURN_ZERO:
|
||||
// return from a :def function call without a value
|
||||
case ISN_RETURN_VOID:
|
||||
if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
|
||||
goto theend;
|
||||
tv = STACK_TV_BOT(0);
|
||||
++ectx->ec_stack.ga_len;
|
||||
tv->v_type = VAR_NUMBER;
|
||||
tv->v_type = VAR_VOID;
|
||||
tv->vval.v_number = 0;
|
||||
tv->v_lock = 0;
|
||||
// FALLTHROUGH
|
||||
|
||||
// return from a :def function call with what is on the stack
|
||||
case ISN_RETURN:
|
||||
{
|
||||
garray_T *trystack = &ectx->ec_trystack;
|
||||
@@ -2774,7 +2850,7 @@ exec_instructions(ectx_T *ectx)
|
||||
}
|
||||
break;
|
||||
|
||||
// push a function reference to a compiled function
|
||||
// push a partial, a reference to a compiled function
|
||||
case ISN_FUNCREF:
|
||||
{
|
||||
partial_T *pt = ALLOC_CLEAR_ONE(partial_T);
|
||||
@@ -2791,7 +2867,6 @@ exec_instructions(ectx_T *ectx)
|
||||
if (fill_partial_and_closure(pt, pt_dfunc->df_ufunc,
|
||||
ectx) == FAIL)
|
||||
goto theend;
|
||||
|
||||
tv = STACK_TV_BOT(0);
|
||||
++ectx->ec_stack.ga_len;
|
||||
tv->vval.v_partial = pt;
|
||||
@@ -4053,7 +4128,7 @@ exec_instructions(ectx_T *ectx)
|
||||
funccall_T cookie;
|
||||
ufunc_T *cur_ufunc =
|
||||
(((dfunc_T *)def_functions.ga_data)
|
||||
+ ectx->ec_dfunc_idx)->df_ufunc;
|
||||
+ ectx->ec_dfunc_idx)->df_ufunc;
|
||||
|
||||
cookie.func = cur_ufunc;
|
||||
if (iptr->isn_type == ISN_PROF_START)
|
||||
@@ -4068,6 +4143,25 @@ exec_instructions(ectx_T *ectx)
|
||||
}
|
||||
break;
|
||||
|
||||
case ISN_DEBUG:
|
||||
if (ex_nesting_level <= debug_break_level)
|
||||
{
|
||||
char_u *line;
|
||||
ufunc_T *ufunc = (((dfunc_T *)def_functions.ga_data)
|
||||
+ ectx->ec_dfunc_idx)->df_ufunc;
|
||||
|
||||
SOURCING_LNUM = iptr->isn_lnum;
|
||||
debug_context = ectx;
|
||||
debug_arg_count = iptr->isn_arg.number;
|
||||
line = ((char_u **)ufunc->uf_lines.ga_data)[
|
||||
iptr->isn_lnum - 1];
|
||||
if (line == NULL)
|
||||
line = (char_u *)"[empty]";
|
||||
do_debug(line);
|
||||
debug_context = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case ISN_SHUFFLE:
|
||||
{
|
||||
typval_T tmp_tv;
|
||||
@@ -4227,6 +4321,7 @@ call_def_function(
|
||||
int save_emsg_silent_def = emsg_silent_def;
|
||||
int save_did_emsg_def = did_emsg_def;
|
||||
int orig_funcdepth;
|
||||
int orig_nesting_level = ex_nesting_level;
|
||||
|
||||
// Get pointer to item in the stack.
|
||||
#undef STACK_TV
|
||||
@@ -4242,8 +4337,8 @@ call_def_function(
|
||||
|
||||
if (ufunc->uf_def_status == UF_NOT_COMPILED
|
||||
|| ufunc->uf_def_status == UF_COMPILE_ERROR
|
||||
|| (func_needs_compiling(ufunc, PROFILING(ufunc))
|
||||
&& compile_def_function(ufunc, FALSE, PROFILING(ufunc), NULL)
|
||||
|| (func_needs_compiling(ufunc, COMPILE_TYPE(ufunc))
|
||||
&& compile_def_function(ufunc, FALSE, COMPILE_TYPE(ufunc), NULL)
|
||||
== FAIL))
|
||||
{
|
||||
if (did_emsg_cumul + did_emsg == did_emsg_before)
|
||||
@@ -4279,6 +4374,7 @@ call_def_function(
|
||||
ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
|
||||
ga_init2(&ectx.ec_funcrefs, sizeof(partial_T *), 10);
|
||||
ectx.ec_did_emsg_before = did_emsg_before;
|
||||
++ex_nesting_level;
|
||||
|
||||
idx = argc - ufunc->uf_args.ga_len;
|
||||
if (idx > 0 && ufunc->uf_va_name == NULL)
|
||||
@@ -4384,22 +4480,31 @@ call_def_function(
|
||||
// by copy_func().
|
||||
if (partial != NULL || base_ufunc->uf_partial != NULL)
|
||||
{
|
||||
ectx.ec_outer = ALLOC_CLEAR_ONE(outer_T);
|
||||
if (ectx.ec_outer == NULL)
|
||||
ectx.ec_outer_ref = ALLOC_CLEAR_ONE(outer_ref_T);
|
||||
if (ectx.ec_outer_ref == NULL)
|
||||
goto failed_early;
|
||||
if (partial != NULL)
|
||||
{
|
||||
if (partial->pt_outer.out_stack == NULL && current_ectx != NULL)
|
||||
{
|
||||
if (current_ectx->ec_outer != NULL)
|
||||
*ectx.ec_outer = *current_ectx->ec_outer;
|
||||
if (current_ectx->ec_outer_ref != NULL
|
||||
&& current_ectx->ec_outer_ref->or_outer != NULL)
|
||||
ectx.ec_outer_ref->or_outer =
|
||||
current_ectx->ec_outer_ref->or_outer;
|
||||
}
|
||||
else
|
||||
*ectx.ec_outer = partial->pt_outer;
|
||||
{
|
||||
ectx.ec_outer_ref->or_outer = &partial->pt_outer;
|
||||
++partial->pt_refcount;
|
||||
ectx.ec_outer_ref->or_partial = partial;
|
||||
}
|
||||
}
|
||||
else
|
||||
*ectx.ec_outer = base_ufunc->uf_partial->pt_outer;
|
||||
ectx.ec_outer->out_up_is_copy = TRUE;
|
||||
{
|
||||
ectx.ec_outer_ref->or_outer = &base_ufunc->uf_partial->pt_outer;
|
||||
++base_ufunc->uf_partial->pt_refcount;
|
||||
ectx.ec_outer_ref->or_partial = base_ufunc->uf_partial;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4513,17 +4618,16 @@ failed_early:
|
||||
// Free all local variables, but not arguments.
|
||||
for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
|
||||
clear_tv(STACK_TV(idx));
|
||||
ex_nesting_level = orig_nesting_level;
|
||||
|
||||
vim_free(ectx.ec_stack.ga_data);
|
||||
vim_free(ectx.ec_trystack.ga_data);
|
||||
|
||||
while (ectx.ec_outer != NULL)
|
||||
if (ectx.ec_outer_ref != NULL)
|
||||
{
|
||||
outer_T *up = ectx.ec_outer->out_up_is_copy
|
||||
? NULL : ectx.ec_outer->out_up;
|
||||
|
||||
vim_free(ectx.ec_outer);
|
||||
ectx.ec_outer = up;
|
||||
if (ectx.ec_outer_ref->or_outer_allocated)
|
||||
vim_free(ectx.ec_outer_ref->or_outer);
|
||||
partial_unref(ectx.ec_outer_ref->or_partial);
|
||||
vim_free(ectx.ec_outer_ref);
|
||||
}
|
||||
|
||||
// Not sure if this is necessary.
|
||||
@@ -4973,8 +5077,8 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
||||
case ISN_RETURN:
|
||||
smsg("%s%4d RETURN", pfx, current);
|
||||
break;
|
||||
case ISN_RETURN_ZERO:
|
||||
smsg("%s%4d RETURN 0", pfx, current);
|
||||
case ISN_RETURN_VOID:
|
||||
smsg("%s%4d RETURN void", pfx, current);
|
||||
break;
|
||||
case ISN_FUNCREF:
|
||||
{
|
||||
@@ -5277,13 +5381,19 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
||||
case ISN_CMDMOD_REV: smsg("%s%4d CMDMOD_REV", pfx, current); break;
|
||||
|
||||
case ISN_PROF_START:
|
||||
smsg("%s%4d PROFILE START line %d", pfx, current, iptr->isn_lnum);
|
||||
smsg("%s%4d PROFILE START line %d", pfx, current,
|
||||
iptr->isn_lnum);
|
||||
break;
|
||||
|
||||
case ISN_PROF_END:
|
||||
smsg("%s%4d PROFILE END", pfx, current);
|
||||
break;
|
||||
|
||||
case ISN_DEBUG:
|
||||
smsg("%s%4d DEBUG line %d varcount %lld", pfx, current,
|
||||
iptr->isn_lnum, iptr->isn_arg.number);
|
||||
break;
|
||||
|
||||
case ISN_UNPACK: smsg("%s%4d UNPACK %d%s", pfx, current,
|
||||
iptr->isn_arg.unpack.unp_count,
|
||||
iptr->isn_arg.unpack.unp_semicolon ? " semicolon" : "");
|
||||
@@ -5305,6 +5415,40 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle command line completion for the :disassemble command.
|
||||
*/
|
||||
void
|
||||
set_context_in_disassemble_cmd(expand_T *xp, char_u *arg)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
// Default: expand user functions, "debug" and "profile"
|
||||
xp->xp_context = EXPAND_DISASSEMBLE;
|
||||
xp->xp_pattern = arg;
|
||||
|
||||
// first argument already typed: only user function names
|
||||
if (*arg != NUL && *(p = skiptowhite(arg)) != NUL)
|
||||
{
|
||||
xp->xp_context = EXPAND_USER_FUNC;
|
||||
xp->xp_pattern = skipwhite(p);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Function given to ExpandGeneric() to obtain the list of :disassemble
|
||||
* arguments.
|
||||
*/
|
||||
char_u *
|
||||
get_disassemble_argument(expand_T *xp, int idx)
|
||||
{
|
||||
if (idx == 0)
|
||||
return (char_u *)"debug";
|
||||
if (idx == 1)
|
||||
return (char_u *)"profile";
|
||||
return get_user_func_name(xp, idx - 2);
|
||||
}
|
||||
|
||||
/*
|
||||
* ":disassemble".
|
||||
* We don't really need this at runtime, but we do have tests that require it,
|
||||
@@ -5320,6 +5464,18 @@ ex_disassemble(exarg_T *eap)
|
||||
isn_T *instr;
|
||||
int instr_count;
|
||||
int is_global = FALSE;
|
||||
compiletype_T compile_type = CT_NONE;
|
||||
|
||||
if (STRNCMP(arg, "profile", 7) == 0)
|
||||
{
|
||||
compile_type = CT_PROFILE;
|
||||
arg = skipwhite(arg + 7);
|
||||
}
|
||||
else if (STRNCMP(arg, "debug", 5) == 0)
|
||||
{
|
||||
compile_type = CT_DEBUG;
|
||||
arg = skipwhite(arg + 5);
|
||||
}
|
||||
|
||||
if (STRNCMP(arg, "<lambda>", 8) == 0)
|
||||
{
|
||||
@@ -5351,8 +5507,8 @@ ex_disassemble(exarg_T *eap)
|
||||
semsg(_(e_cannot_find_function_str), eap->arg);
|
||||
return;
|
||||
}
|
||||
if (func_needs_compiling(ufunc, eap->forceit)
|
||||
&& compile_def_function(ufunc, FALSE, eap->forceit, NULL) == FAIL)
|
||||
if (func_needs_compiling(ufunc, compile_type)
|
||||
&& compile_def_function(ufunc, FALSE, compile_type, NULL) == FAIL)
|
||||
return;
|
||||
if (ufunc->uf_def_status != UF_COMPILED)
|
||||
{
|
||||
@@ -5365,14 +5521,24 @@ ex_disassemble(exarg_T *eap)
|
||||
msg((char *)ufunc->uf_name);
|
||||
|
||||
dfunc = ((dfunc_T *)def_functions.ga_data) + ufunc->uf_dfunc_idx;
|
||||
switch (compile_type)
|
||||
{
|
||||
case CT_PROFILE:
|
||||
#ifdef FEAT_PROFILE
|
||||
instr = eap->forceit ? dfunc->df_instr_prof : dfunc->df_instr;
|
||||
instr_count = eap->forceit ? dfunc->df_instr_prof_count
|
||||
: dfunc->df_instr_count;
|
||||
#else
|
||||
instr = dfunc->df_instr;
|
||||
instr_count = dfunc->df_instr_count;
|
||||
instr = dfunc->df_instr_prof;
|
||||
instr_count = dfunc->df_instr_prof_count;
|
||||
break;
|
||||
#endif
|
||||
// FALLTHROUGH
|
||||
case CT_NONE:
|
||||
instr = dfunc->df_instr;
|
||||
instr_count = dfunc->df_instr_count;
|
||||
break;
|
||||
case CT_DEBUG:
|
||||
instr = dfunc->df_instr_debug;
|
||||
instr_count = dfunc->df_instr_debug_count;
|
||||
break;
|
||||
}
|
||||
|
||||
list_instructions("", instr, instr_count, ufunc);
|
||||
}
|
||||
|
||||
@@ -979,6 +979,7 @@ static char *reserved[] = {
|
||||
"true",
|
||||
"false",
|
||||
"null",
|
||||
"this",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user