Merge remote-tracking branch 'vim/master'

This commit is contained in:
ichizok
2021-06-16 18:08:02 +09:00
101 changed files with 2241 additions and 700 deletions
+6
View File
@@ -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? ##
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1 -1
View File
@@ -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*
+1 -1
View File
@@ -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('≼')
+4 -1
View File
@@ -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
+1
View File
@@ -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"
+7 -2
View File
@@ -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 -1
View File
@@ -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
+3 -3
View File
@@ -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
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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
<
+5 -3
View File
@@ -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
+5 -5
View File
@@ -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
+8
View File
@@ -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}*
+2 -2
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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*
+3 -3
View File
@@ -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
View File
@@ -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
+4 -1
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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.
+85
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
+4 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+12
View File
@@ -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
View File
@@ -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;
+4 -1
View File
@@ -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
}
+9
View File
@@ -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;
}
+18
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
+3
View File
@@ -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
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2 -2
View File
@@ -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);
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
/*
+4
View File
@@ -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
+16
View File
@@ -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>", @:)
+43 -12
View File
@@ -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')
+118 -1
View File
@@ -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
+24
View File
@@ -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
+6
View File
@@ -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()
+1 -1
View File
@@ -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'],
+6 -4
View File
@@ -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()
+10
View File
@@ -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
+20
View File
@@ -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
+13
View File
@@ -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
+26
View File
@@ -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
+56
View File
@@ -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
+60
View File
@@ -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
+7
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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
+15
View File
@@ -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
+13
View File
@@ -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
+2
View File
@@ -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',
+62 -38
View File
@@ -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
+18
View File
@@ -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
+77
View File
@@ -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
+13
View File
@@ -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
+9
View File
@@ -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:')
+55
View File
@@ -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
+9 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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)
{
+94
View File
@@ -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,
/**/
+18 -3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+1
View File
@@ -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