mirror of
https://github.com/macvim-dev/macvim.git
synced 2026-06-07 15:37:14 +02:00
Merge remote-tracking branch 'vim/master'
This commit is contained in:
+12
-1
@@ -1,4 +1,4 @@
|
||||
*editing.txt* For Vim version 7.4. Last change: 2016 Jan 03
|
||||
*editing.txt* For Vim version 7.4. Last change: 2016 Jan 17
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -639,6 +639,7 @@ list of the current window.
|
||||
:0argadd x x a b c
|
||||
:1argadd x a x b c
|
||||
:$argadd x a b c x
|
||||
And after the last one:
|
||||
:+2argadd y a b c x y
|
||||
There is no check for duplicates, it is possible to
|
||||
add a file to the argument list twice.
|
||||
@@ -1458,6 +1459,16 @@ using zip, "[blowfish]" when using blowfish, etc.
|
||||
When writing an undo file, the same key and method will be used for the text
|
||||
in the undo file. |persistent-undo|.
|
||||
|
||||
To test for blowfish support you can use these conditions: >
|
||||
has('crypt-blowfish')
|
||||
has('crypt-blowfish2')
|
||||
This works since Vim 7.4.1099 while blowfish support was added earlier.
|
||||
Thus the condition failing doesn't mean blowfish is not supported. You can
|
||||
test for blowfish with: >
|
||||
v:version >= 703
|
||||
And for blowfish2 with: >
|
||||
v:version > 704 || (v:version == 704 && has('patch401'))
|
||||
<
|
||||
*E817* *E818* *E819* *E820*
|
||||
When encryption does not work properly, you would be able to write your text
|
||||
to a file and never be able to read it back. Therefore a test is performed to
|
||||
|
||||
+39
-12
@@ -1,4 +1,4 @@
|
||||
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 16
|
||||
*eval.txt* For Vim version 7.4. Last change: 2016 Jan 17
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -873,7 +873,7 @@ cursor: >
|
||||
:let c = getline(".")[col(".") - 1]
|
||||
|
||||
If the length of the String is less than the index, the result is an empty
|
||||
String. A negative index always results in an empty string (reason: backwards
|
||||
String. A negative index always results in an empty string (reason: backward
|
||||
compatibility). Use [-1:] to get the last byte.
|
||||
|
||||
If expr8 is a |List| then it results the item at index expr1. See |list-index|
|
||||
@@ -1851,7 +1851,7 @@ getcmdpos() Number return cursor position in command-line
|
||||
getcmdtype() String return current command-line type
|
||||
getcmdwintype() String return current command-line window type
|
||||
getcurpos() List position of the cursor
|
||||
getcwd() String the current working directory
|
||||
getcwd( [{winnr} [, {tabnr}]]) String get the current working directory
|
||||
getfontname( [{name}]) String name of font being used
|
||||
getfperm( {fname}) String file permissions of file {fname}
|
||||
getfsize( {fname}) Number size in bytes of file {fname}
|
||||
@@ -1882,7 +1882,8 @@ globpath( {path}, {expr} [, {nosuf} [, {list} [, {alllinks}]]])
|
||||
String do glob({expr}) for all dirs in {path}
|
||||
has( {feature}) Number TRUE if feature {feature} supported
|
||||
has_key( {dict}, {key}) Number TRUE if {dict} has entry {key}
|
||||
haslocaldir() Number TRUE if current window executed |:lcd|
|
||||
haslocaldir( [{winnr} [, {tabnr}]])
|
||||
Number TRUE if the window executed |:lcd|
|
||||
hasmapto( {what} [, {mode} [, {abbr}]])
|
||||
Number TRUE if mapping to {what} exists
|
||||
histadd( {history},{item}) String add an item to a history
|
||||
@@ -1950,6 +1951,7 @@ nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum}
|
||||
nr2char( {expr}[, {utf8}]) String single char with ASCII/UTF8 value {expr}
|
||||
or( {expr}, {expr}) Number bitwise OR
|
||||
pathshorten( {expr}) String shorten directory names in a path
|
||||
perleval( {expr}) any evaluate |Perl| expression
|
||||
pow( {x}, {y}) Float {x} to the power of {y}
|
||||
prevnonblank( {lnum}) Number line nr of non-blank line <= {lnum}
|
||||
printf( {fmt}, {expr1}...) String format text
|
||||
@@ -3521,8 +3523,16 @@ getcurpos() Get the position of the cursor. This is like getpos('.'), but
|
||||
call setpos('.', save_cursor)
|
||||
<
|
||||
*getcwd()*
|
||||
getcwd() The result is a String, which is the name of the current
|
||||
getcwd([{winnr} [, {tabnr}]])
|
||||
The result is a String, which is the name of the current
|
||||
working directory.
|
||||
Without arguments, for the current window.
|
||||
|
||||
With {winnr} return the local current directory of this window
|
||||
in the current tab page.
|
||||
With {winnr} and {tabnr} return the local current directory of
|
||||
the window in the specified tab page.
|
||||
Return an empty string if the arguments are invalid.
|
||||
|
||||
getfsize({fname}) *getfsize()*
|
||||
The result is a Number, which is the size in bytes of the
|
||||
@@ -3858,9 +3868,15 @@ has_key({dict}, {key}) *has_key()*
|
||||
The result is a Number, which is 1 if |Dictionary| {dict} has
|
||||
an entry with key {key}. Zero otherwise.
|
||||
|
||||
haslocaldir() *haslocaldir()*
|
||||
The result is a Number, which is 1 when the current
|
||||
window has set a local path via |:lcd|, and 0 otherwise.
|
||||
haslocaldir([{winnr} [, {tabnr}]]) *haslocaldir()*
|
||||
The result is a Number, which is 1 when the window has set a
|
||||
local path via |:lcd|, and 0 otherwise.
|
||||
|
||||
Without arguments use the current window.
|
||||
With {winnr} use this window in the current tab page.
|
||||
With {winnr} and {tabnr} use the window in the specified tab
|
||||
page.
|
||||
Return 0 if the arguments are invalid.
|
||||
|
||||
hasmapto({what} [, {mode} [, {abbr}]]) *hasmapto()*
|
||||
The result is a Number, which is 1 if there is a mapping that
|
||||
@@ -4547,8 +4563,8 @@ matchadd({group}, {pattern}[, {priority}[, {id} [, {dict}]]])
|
||||
respectively. If the {id} argument is not specified or -1,
|
||||
|matchadd()| automatically chooses a free ID.
|
||||
|
||||
The optional {dict} argmument allows for further custom
|
||||
values. Currently this is used to specify a match specifc
|
||||
The optional {dict} argument allows for further custom
|
||||
values. Currently this is used to specify a match specific
|
||||
conceal character that will be shown for |hl-Conceal|
|
||||
highlighted matches. The dict can have the following members:
|
||||
|
||||
@@ -4778,6 +4794,17 @@ pathshorten({expr}) *pathshorten()*
|
||||
< ~/.v/a/myfile.vim ~
|
||||
It doesn't matter if the path exists or not.
|
||||
|
||||
perleval({expr}) *perleval()*
|
||||
Evaluate Perl expression {expr} in scalar context and return
|
||||
its result converted to Vim data structures. If value can't be
|
||||
converted, it is returned as a string Perl representation.
|
||||
Note: If you want an array or hash, {expr} must return a
|
||||
reference to it.
|
||||
Example: >
|
||||
:echo perleval('[1 .. 4]')
|
||||
< [1, 2, 3, 4]
|
||||
{only available when compiled with the |+perl| feature}
|
||||
|
||||
pow({x}, {y}) *pow()*
|
||||
Return the power of {x} to the exponent {y} as a |Float|.
|
||||
{x} and {y} must evaluate to a |Float| or a |Number|.
|
||||
@@ -5292,7 +5319,7 @@ search({pattern} [, {flags} [, {stopline} [, {timeout}]]]) *search()*
|
||||
|
||||
'ignorecase', 'smartcase' and 'magic' are used.
|
||||
|
||||
When the 'z' flag is not given seaching always starts in
|
||||
When the 'z' flag is not given, searching always starts in
|
||||
column zero and then matches before the cursor are skipped.
|
||||
When the 'c' flag is present in 'cpo' the next search starts
|
||||
after the match. Without the 'c' flag the next search starts
|
||||
@@ -7658,7 +7685,7 @@ This does NOT work: >
|
||||
From Vim version 4.5 until 5.0, every Ex command in
|
||||
between the ":if" and ":endif" is ignored. These two
|
||||
commands were just to allow for future expansions in a
|
||||
backwards compatible way. Nesting was allowed. Note
|
||||
backward compatible way. Nesting was allowed. Note
|
||||
that any ":else" or ":elseif" was ignored, the "else"
|
||||
part was not executed either.
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*if_mzsch.txt* For Vim version 7.4. Last change: 2012 Dec 17
|
||||
*if_mzsch.txt* For Vim version 7.4. Last change: 2016 Jan 16
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Sergey Khorev
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
*mlang.txt* For Vim version 7.4. Last change: 2012 Jan 15
|
||||
*mlang.txt* For Vim version 7.4. Last change: 2016 Jan 16
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -97,13 +97,15 @@ If you used the self-installing .exe file, message translations should work
|
||||
already. Otherwise get the libintl.dll file if you don't have it yet:
|
||||
|
||||
http://sourceforge.net/projects/gettext
|
||||
Or:
|
||||
https://mlocati.github.io/gettext-iconv-windows/
|
||||
|
||||
This also contains tools xgettext, msgformat and others.
|
||||
|
||||
libintl.dll should be placed in same directory with (g)vim.exe, or some
|
||||
place where PATH environment value describe. Message files (vim.mo)
|
||||
have to be placed in "$VIMRUNTIME/lang/xx/LC_MESSAGES", where "xx" is the
|
||||
abbreviation of the language (mostly two letters).
|
||||
place where PATH environment value describe. Vim also finds libintl-8.dll.
|
||||
Message files (vim.mo) have to be placed in "$VIMRUNTIME/lang/xx/LC_MESSAGES",
|
||||
where "xx" is the abbreviation of the language (mostly two letters).
|
||||
|
||||
If you write your own translations you need to generate the .po file and
|
||||
convert it to a .mo file. You need to get the source distribution and read
|
||||
|
||||
@@ -3404,12 +3404,18 @@ $VIMRUNTIME starting.txt /*$VIMRUNTIME*
|
||||
== change.txt /*==*
|
||||
> change.txt /*>*
|
||||
>> change.txt /*>>*
|
||||
>backtrace repeat.txt /*>backtrace*
|
||||
>bt repeat.txt /*>bt*
|
||||
>cont repeat.txt /*>cont*
|
||||
>down repeat.txt /*>down*
|
||||
>finish repeat.txt /*>finish*
|
||||
>frame repeat.txt /*>frame*
|
||||
>interrupt repeat.txt /*>interrupt*
|
||||
>next repeat.txt /*>next*
|
||||
>quit repeat.txt /*>quit*
|
||||
>step repeat.txt /*>step*
|
||||
>up repeat.txt /*>up*
|
||||
>where repeat.txt /*>where*
|
||||
? pattern.txt /*?*
|
||||
?<CR> pattern.txt /*?<CR>*
|
||||
@ repeat.txt /*@*
|
||||
@@ -7179,6 +7185,7 @@ mzscheme-examples if_mzsch.txt /*mzscheme-examples*
|
||||
mzscheme-funcref if_mzsch.txt /*mzscheme-funcref*
|
||||
mzscheme-mzeval if_mzsch.txt /*mzscheme-mzeval*
|
||||
mzscheme-sandbox if_mzsch.txt /*mzscheme-sandbox*
|
||||
mzscheme-setup if_mzsch.txt /*mzscheme-setup*
|
||||
mzscheme-threads if_mzsch.txt /*mzscheme-threads*
|
||||
mzscheme-vim if_mzsch.txt /*mzscheme-vim*
|
||||
mzscheme-vimext if_mzsch.txt /*mzscheme-vimext*
|
||||
@@ -7625,6 +7632,7 @@ perl-overview if_perl.txt /*perl-overview*
|
||||
perl-patterns pattern.txt /*perl-patterns*
|
||||
perl-using if_perl.txt /*perl-using*
|
||||
perl.vim syntax.txt /*perl.vim*
|
||||
perleval() eval.txt /*perleval()*
|
||||
persistent-undo undo.txt /*persistent-undo*
|
||||
pexpr-option print.txt /*pexpr-option*
|
||||
pfn-option print.txt /*pfn-option*
|
||||
|
||||
+2
-37
@@ -1,4 +1,4 @@
|
||||
*todo.txt* For Vim version 7.4. Last change: 2016 Jan 15
|
||||
*todo.txt* For Vim version 7.4. Last change: 2016 Jan 17
|
||||
|
||||
|
||||
VIM REFERENCE MANUAL by Bram Moolenaar
|
||||
@@ -97,8 +97,6 @@ Should use /usr/local/share/applications or /usr/share/applications.
|
||||
Or use $XDG_DATA_DIRS.
|
||||
Also need to run update-desktop-database (Kuriyama Kazunobu, 2015 Nov 4)
|
||||
|
||||
Add has('crypt-blowfish') and has('crypt-blowfish2') (Smu Johnson)
|
||||
|
||||
Access to uninitialized memory in match_backref() regexp_nda.c:4882
|
||||
(Dominique Pelle, 2015 Nov 6)
|
||||
|
||||
@@ -125,42 +123,16 @@ github with a URL like this:
|
||||
https://github.com/vim/vim/compare/v7.4.920%5E...v7.4.920.diff
|
||||
Diff for version.c contains more context, can't skip a patch.
|
||||
>
|
||||
Can src/GvimExt/Make_cyg.mak be removed?
|
||||
Same for src/xxd/Make_cyg.mak
|
||||
|
||||
When t_Co is changed from termresponse, the OptionSet autocmmand event isn't
|
||||
triggered. Use the code from the end of set_num_option() in
|
||||
set_color_count().
|
||||
|
||||
Python: ":py raw_input('prompt')" doesn't work. (Manu Hack)
|
||||
|
||||
Patch to fix cursor position in right-left mode with concealing.
|
||||
(Hirohito Higashi, 2016 Jan 13)
|
||||
|
||||
Plugin to use Vim in MANPAGER. Konfekt, PR #491
|
||||
|
||||
Using uninitialized memory. (Dominique Pelle, 2015 Nov 4)
|
||||
|
||||
Patch for explaining the help. (Christian Brabandt, 2015 Jan 8)
|
||||
Should be in the user manual?
|
||||
|
||||
Patch to recognize string slice for variable followed by colon.
|
||||
(Hirohito Higashi, 2015 Nov 24)
|
||||
|
||||
Patch to add debug backtrace. (Alberto Fanjul, 2015 Sep 27)
|
||||
Update 2016 Jan 2. Issue #433
|
||||
|
||||
Patch to gvim.nsi for appveyor build. (Ken Takata, 2016 Jan 12)
|
||||
|
||||
Patch to improve behavior of dead keys on MS-Windows. (John Wellesz, 2015 Aug
|
||||
25) https://github.com/vim/vim/pull/399.diff
|
||||
|
||||
Patch to make mzscheme (racket) interface work. (Yukihiro Nakadaira, 2015 Jan
|
||||
10) Doesn't work for me, need to build from source. Include anyway?
|
||||
Additional patch by Ken Takata, 2016 Jan 13.
|
||||
Merged patch by Yasuhiro Nakadaira,, 2016 Jan 14.
|
||||
Update for INSSTALLpc.txt by Ken Takata, Jan 14.
|
||||
|
||||
MS-Windows: When editing a file with a leading space, writing it uses the
|
||||
wrong name. (Aram, 2014 Nov 7) Vim 7.4.
|
||||
|
||||
@@ -171,19 +143,12 @@ Half-finished patch to fix the Problem using cgn to change a search hit when
|
||||
replacement includes hit. Reported by John Beckett, fix by Christian Brabandt,
|
||||
2016 Jan 11.
|
||||
|
||||
Patch to fix pointer cast warning in VS2015. (Mike Williams, 2015 Dec 13)
|
||||
Patch to make building GVimExt with VS2015. (Mike Williams, 2015 Dec 13)
|
||||
|
||||
Value returned by virtcol() changes depending on how lines wrap. This is
|
||||
inconsistent with the documentation.
|
||||
|
||||
Patch to add perleval(). (Damien, 2015 Dec 8, update 2016 Jan 4)
|
||||
|
||||
Can we cache the syntax attributes, so that updates for 'relativenumber' and
|
||||
'cursorline'/'cursorcolumn' are a lot faster?
|
||||
|
||||
Patch to add window and tab arguments to getcwd(). (Thinca, 2015 Nov 15)
|
||||
|
||||
Build with Python on Mac does not always use the right library.
|
||||
(Kazunobu Kuriyama, 2015 Mar 28)
|
||||
|
||||
@@ -286,7 +251,7 @@ Is this the right solution? Need to cleanup langmap behavior:
|
||||
- Remove LANGMAP_ADJUST() in other parts of the code. Make sure the mode is
|
||||
covered by the above change.
|
||||
So that replaying the register doesn't use keymap/langmap and still does the
|
||||
same thing. Remarks on issue 543.
|
||||
same thing. Remarks on issue 543 (Roland Puntaier).
|
||||
|
||||
Patch to add grepfile(). (Scott Prager, 2015 May 26)
|
||||
Work in progress.
|
||||
|
||||
+43
-39
@@ -1,4 +1,4 @@
|
||||
*usr_02.txt* For Vim version 7.4. Last change: 2016 Jan 15
|
||||
*usr_02.txt* For Vim version 7.4. Last change: 2016 Jan 16
|
||||
|
||||
VIM USER MANUAL - by Bram Moolenaar
|
||||
|
||||
@@ -554,38 +554,42 @@ Summary: *help-summary* >
|
||||
8) Ex-commands always start with ":", so to go to the :s command help: >
|
||||
:help :s
|
||||
|
||||
9) Key combinations. They usually start with a single letter indicating
|
||||
the mode for which they can be used. E.g.: >
|
||||
:help i_CTRL-X
|
||||
< takes you to the family of Ctrl-X commands for insert mode which can be
|
||||
used to auto complete different things. Note, that certain keys will
|
||||
always be written the same, e.g. Control will always be CTRL.
|
||||
For normal mode commands there is no prefix and the topic is available at
|
||||
:h CTRL-<Letter>. E.g. >
|
||||
:help CTRL-W
|
||||
< In contrast >
|
||||
:help c_CTRL-R
|
||||
< will describe what the Ctrl-R does when entering commands in the Command
|
||||
line and >
|
||||
:help v_Ctrl-A
|
||||
< talks about incrementing numbers in visual mode and >
|
||||
:help g_CTRL-A
|
||||
< talks about the g<C-A> command (e.g. you have to press "g" then <Ctrl-A>).
|
||||
Here the "g" stand for the normal command "g" which always expects a second
|
||||
key before doing something similar to the commands starting with "z"
|
||||
9) Commands specifically for debugging start with ">". To go to to the help
|
||||
for the "cont" debug command: >
|
||||
:help >cont
|
||||
|
||||
10) Regexp items always start with /. So to get help for the "\+" quantifier
|
||||
10) Key combinations. They usually start with a single letter indicating
|
||||
the mode for which they can be used. E.g.: >
|
||||
:help i_CTRL-X
|
||||
< takes you to the family of Ctrl-X commands for insert mode which can be
|
||||
used to auto complete different things. Note, that certain keys will
|
||||
always be written the same, e.g. Control will always be CTRL.
|
||||
For normal mode commands there is no prefix and the topic is available at
|
||||
:h CTRL-<Letter>. E.g. >
|
||||
:help CTRL-W
|
||||
< In contrast >
|
||||
:help c_CTRL-R
|
||||
< will describe what the Ctrl-R does when entering commands in the Command
|
||||
line and >
|
||||
:help v_Ctrl-A
|
||||
< talks about incrementing numbers in visual mode and >
|
||||
:help g_CTRL-A
|
||||
< talks about the g<C-A> command (e.g. you have to press "g" then <Ctrl-A>).
|
||||
Here the "g" stand for the normal command "g" which always expects a second
|
||||
key before doing something similar to the commands starting with "z"
|
||||
|
||||
11) Regexp items always start with /. So to get help for the "\+" quantifier
|
||||
in Vim regexes: >
|
||||
:help /\+
|
||||
< If you need to know everything about regular expressions, start reading
|
||||
at: >
|
||||
< If you need to know everything about regular expressions, start reading
|
||||
at: >
|
||||
:help pattern.txt
|
||||
|
||||
11) Registers always start with "quote". To find out about the special ":"
|
||||
12) Registers always start with "quote". To find out about the special ":"
|
||||
register: >
|
||||
:help quote:
|
||||
|
||||
12) Vim Script (VimL) is available at >
|
||||
13) Vim Script (VimL) is available at >
|
||||
:help eval.txt
|
||||
< Certain aspects of the language are available at :h expr-X where "X" is a
|
||||
single letter. E.g. >
|
||||
@@ -600,7 +604,7 @@ Summary: *help-summary* >
|
||||
< talks about the append VimL function rather than how to append text in the
|
||||
current buffer.
|
||||
|
||||
13) Mappings are talked about in the help page :h |map.txt|. Use >
|
||||
14) Mappings are talked about in the help page :h |map.txt|. Use >
|
||||
:help mapmode-i
|
||||
< to find out about the |:imap| command. Also use :map-topic
|
||||
to find out about certain subtopics particular for mappings. e.g: >
|
||||
@@ -609,19 +613,19 @@ Summary: *help-summary* >
|
||||
:help map-bar
|
||||
< for how the '|' is handled in mappings.
|
||||
|
||||
14) Command definitions are talked about :h command-topic, so use >
|
||||
15) Command definitions are talked about :h command-topic, so use >
|
||||
:help command-bar
|
||||
< to find out about the '!' argument for custom commands.
|
||||
|
||||
15) Window management commands always start with CTRL-W, so you find the
|
||||
16) Window management commands always start with CTRL-W, so you find the
|
||||
corresponding help at :h CTRL-W_letter. E.g. >
|
||||
:help CTRL-W_p
|
||||
< for moving the previous accessed window). You can also access >
|
||||
< for moving the previous accessed window. You can also access >
|
||||
:help windows.txt
|
||||
< and read your way through if you are looking for window handling
|
||||
commands.
|
||||
|
||||
16) Use |:helpgrep| to search in all help pages (and also of any installed
|
||||
17) Use |:helpgrep| to search in all help pages (and also of any installed
|
||||
plugins). See |:helpgrep| for how to use it.
|
||||
To search for a topic: >
|
||||
:helpgrep topic
|
||||
@@ -632,7 +636,7 @@ Summary: *help-summary* >
|
||||
:copen
|
||||
< Move around to the match you like and press Enter to jump to that help.
|
||||
|
||||
17) The user manual. This describes help topics for beginners in a rather
|
||||
18) The user manual. This describes help topics for beginners in a rather
|
||||
friendly way. Start at |usr_toc.txt| to find the table of content (as you
|
||||
might have guessed): >
|
||||
:help usr_toc.txt
|
||||
@@ -645,31 +649,31 @@ Summary: *help-summary* >
|
||||
:help 10.1
|
||||
< goes to chapter 10.1 in |usr_10.txt| and talks about recording macros.
|
||||
|
||||
18) Highlighting groups. Always start with hl-groupname. E.g. >
|
||||
19) Highlighting groups. Always start with hl-groupname. E.g. >
|
||||
:help hl-WarningMsg
|
||||
< talks about the WarningMsg highlighting group.
|
||||
|
||||
19) Syntax highlighting is namespaced to :syn-topic e.g. >
|
||||
20) Syntax highlighting is namespaced to :syn-topic e.g. >
|
||||
:help :syn-conceal
|
||||
< talks about the conceal argument for the :syn command.
|
||||
|
||||
20) Quickfix commands usually start with :c while location list commands
|
||||
21) Quickfix commands usually start with :c while location list commands
|
||||
usually start with :l
|
||||
|
||||
21) Autocommand events can be found by their name: >
|
||||
22) Autocommand events can be found by their name: >
|
||||
:help BufWinLeave
|
||||
< To see all possible events: >
|
||||
:help autocommands-events
|
||||
|
||||
22) Command-line switches always start with "-". So for the help of the -f
|
||||
23) Command-line switches always start with "-". So for the help of the -f
|
||||
command switch of Vim use: >
|
||||
:help -f
|
||||
|
||||
23) Optional features always start with "+". To find out about the
|
||||
24) Optional features always start with "+". To find out about the
|
||||
conceal feature use: >
|
||||
:help +conceal
|
||||
|
||||
24) Documentation for included filetype specific functionality is usually
|
||||
25) Documentation for included filetype specific functionality is usually
|
||||
available in the form ft-<filetype>-<functionality>. So >
|
||||
:help ft-c-syntax
|
||||
< talks about the C syntax file and the option it provides. Sometimes,
|
||||
@@ -679,7 +683,7 @@ Summary: *help-summary* >
|
||||
:help ft-tex-plugin
|
||||
< are available.
|
||||
|
||||
25) Error and Warning codes can be looked up directly in the help. So >
|
||||
26) Error and Warning codes can be looked up directly in the help. So >
|
||||
:help E297
|
||||
< takes you exactly to the description of the swap error message and >
|
||||
:help W10
|
||||
|
||||
@@ -921,6 +921,7 @@ Various: *various-functions*
|
||||
|
||||
luaeval() evaluate Lua expression
|
||||
mzeval() evaluate |MzScheme| expression
|
||||
perleval() evaluate Perl expression (|+perl|)
|
||||
py3eval() evaluate Python expression (|+python3|)
|
||||
pyeval() evaluate Python expression (|+python|)
|
||||
wordcount() get byte/word/char count of buffer
|
||||
|
||||
+6
-3
@@ -1948,7 +1948,7 @@ unittest unittests: $(UNITTEST_TARGETS)
|
||||
./$$t || exit 1; echo $$t passed; \
|
||||
done
|
||||
|
||||
# Run individual test, assuming that Vim was already compiled.
|
||||
# Run individual OLD style test, assuming that Vim was already compiled.
|
||||
test1 \
|
||||
test_argument_0count \
|
||||
test_argument_count \
|
||||
@@ -1963,6 +1963,7 @@ test1 \
|
||||
test_erasebackword \
|
||||
test_eval \
|
||||
test_fixeol \
|
||||
test_getcwd \
|
||||
test_insertcount \
|
||||
test_listchars \
|
||||
test_listlbr \
|
||||
@@ -1972,7 +1973,6 @@ test1 \
|
||||
test_match_conceal \
|
||||
test_nested_function \
|
||||
test_options \
|
||||
test_perl \
|
||||
test_qf_title \
|
||||
test_ruby \
|
||||
test_search_mbyte \
|
||||
@@ -1995,7 +1995,9 @@ test1 \
|
||||
test100 test101 test102 test103 test104 test105 test106 test107 test108:
|
||||
cd testdir; rm -f $@.out; $(MAKE) -f Makefile $@.out VIMPROG=../$(VIMTARGET) $(GUI_TESTARG) SCRIPTSOURCE=../$(SCRIPTSOURCE)
|
||||
|
||||
test_assert \
|
||||
# Run individual NEW style test, assuming that Vim was already compiled.
|
||||
test_arglist \
|
||||
test_assert \
|
||||
test_backspace_opt \
|
||||
test_cdo \
|
||||
test_cursor_func \
|
||||
@@ -2005,6 +2007,7 @@ test_assert \
|
||||
test_increment \
|
||||
test_lispwords \
|
||||
test_menu \
|
||||
test_perl \
|
||||
test_quickfix \
|
||||
test_searchpos \
|
||||
test_set \
|
||||
|
||||
+98
-47
@@ -657,6 +657,9 @@ static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_or __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
#ifdef FEAT_PERL
|
||||
static void f_perleval __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
#endif
|
||||
#ifdef FEAT_FLOAT
|
||||
static void f_pow __ARGS((typval_T *argvars, typval_T *rettv));
|
||||
#endif
|
||||
@@ -858,6 +861,7 @@ static int can_free_funccal __ARGS((funccall_T *fc, int copyID)) ;
|
||||
static void free_funccal __ARGS((funccall_T *fc, int free_val));
|
||||
static void add_nr_var __ARGS((dict_T *dp, dictitem_T *v, char *name, varnumber_T nr));
|
||||
static win_T *find_win_by_nr __ARGS((typval_T *vp, tabpage_T *tp));
|
||||
static win_T *find_tabwin __ARGS((typval_T *wvp, typval_T *tvp));
|
||||
static void getwinvar __ARGS((typval_T *argvars, typval_T *rettv, int off));
|
||||
static int searchpair_cmn __ARGS((typval_T *argvars, pos_T *match_pos));
|
||||
static int search_cmn __ARGS((typval_T *argvars, pos_T *match_pos, int *flagsp));
|
||||
@@ -3684,7 +3688,7 @@ do_unlet_var(lp, name_end, forceit)
|
||||
{
|
||||
listitem_T *li;
|
||||
listitem_T *ll_li = lp->ll_li;
|
||||
int ll_n1 = lp->ll_n1;
|
||||
int ll_n1 = lp->ll_n1;
|
||||
|
||||
while (ll_li != NULL && (lp->ll_empty2 || lp->ll_n2 >= ll_n1))
|
||||
{
|
||||
@@ -8181,7 +8185,7 @@ static struct fst
|
||||
{"getcmdtype", 0, 0, f_getcmdtype},
|
||||
{"getcmdwintype", 0, 0, f_getcmdwintype},
|
||||
{"getcurpos", 0, 0, f_getcurpos},
|
||||
{"getcwd", 0, 0, f_getcwd},
|
||||
{"getcwd", 0, 2, f_getcwd},
|
||||
{"getfontname", 0, 1, f_getfontname},
|
||||
{"getfperm", 1, 1, f_getfperm},
|
||||
{"getfsize", 1, 1, f_getfsize},
|
||||
@@ -8205,7 +8209,7 @@ static struct fst
|
||||
{"globpath", 2, 5, f_globpath},
|
||||
{"has", 1, 1, f_has},
|
||||
{"has_key", 2, 2, f_has_key},
|
||||
{"haslocaldir", 0, 0, f_haslocaldir},
|
||||
{"haslocaldir", 0, 2, f_haslocaldir},
|
||||
{"hasmapto", 1, 3, f_hasmapto},
|
||||
{"highlightID", 1, 1, f_hlID}, /* obsolete */
|
||||
{"highlight_exists",1, 1, f_hlexists}, /* obsolete */
|
||||
@@ -8271,6 +8275,9 @@ static struct fst
|
||||
{"nr2char", 1, 2, f_nr2char},
|
||||
{"or", 2, 2, f_or},
|
||||
{"pathshorten", 1, 1, f_pathshorten},
|
||||
#ifdef FEAT_PERL
|
||||
{"perleval", 1, 1, f_perleval},
|
||||
#endif
|
||||
#ifdef FEAT_FLOAT
|
||||
{"pow", 2, 2, f_pow},
|
||||
#endif
|
||||
@@ -9122,30 +9129,11 @@ f_arglistid(argvars, rettv)
|
||||
typval_T *rettv;
|
||||
{
|
||||
win_T *wp;
|
||||
tabpage_T *tp = NULL;
|
||||
long n;
|
||||
|
||||
rettv->vval.v_number = -1;
|
||||
if (argvars[0].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
if (argvars[1].v_type != VAR_UNKNOWN)
|
||||
{
|
||||
n = get_tv_number(&argvars[1]);
|
||||
if (n >= 0)
|
||||
tp = find_tabpage(n);
|
||||
}
|
||||
else
|
||||
tp = curtab;
|
||||
|
||||
if (tp != NULL)
|
||||
{
|
||||
wp = find_win_by_nr(&argvars[0], tp);
|
||||
if (wp != NULL)
|
||||
rettv->vval.v_number = wp->w_alist->id;
|
||||
}
|
||||
}
|
||||
else
|
||||
rettv->vval.v_number = curwin->w_alist->id;
|
||||
wp = find_tabwin(&argvars[0], &argvars[1]);
|
||||
if (wp != NULL)
|
||||
rettv->vval.v_number = wp->w_alist->id;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -12063,25 +12051,36 @@ f_getcmdwintype(argvars, rettv)
|
||||
*/
|
||||
static void
|
||||
f_getcwd(argvars, rettv)
|
||||
typval_T *argvars UNUSED;
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
win_T *wp = NULL;
|
||||
char_u *cwd;
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = NULL;
|
||||
cwd = alloc(MAXPATHL);
|
||||
if (cwd != NULL)
|
||||
|
||||
wp = find_tabwin(&argvars[0], &argvars[1]);
|
||||
if (wp != NULL)
|
||||
{
|
||||
if (mch_dirname(cwd, MAXPATHL) != FAIL)
|
||||
if (wp->w_localdir != NULL)
|
||||
rettv->vval.v_string = vim_strsave(wp->w_localdir);
|
||||
else if(globaldir != NULL)
|
||||
rettv->vval.v_string = vim_strsave(globaldir);
|
||||
else
|
||||
{
|
||||
rettv->vval.v_string = vim_strsave(cwd);
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
if (rettv->vval.v_string != NULL)
|
||||
slash_adjust(rettv->vval.v_string);
|
||||
#endif
|
||||
cwd = alloc(MAXPATHL);
|
||||
if (cwd != NULL)
|
||||
{
|
||||
if (mch_dirname(cwd, MAXPATHL) != FAIL)
|
||||
rettv->vval.v_string = vim_strsave(cwd);
|
||||
vim_free(cwd);
|
||||
}
|
||||
}
|
||||
vim_free(cwd);
|
||||
#ifdef BACKSLASH_IN_FILENAME
|
||||
if (rettv->vval.v_string != NULL)
|
||||
slash_adjust(rettv->vval.v_string);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12710,6 +12709,38 @@ find_win_by_nr(vp, tp)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Find window specified by "wvp" in tabpage "tvp".
|
||||
*/
|
||||
static win_T *
|
||||
find_tabwin(wvp, tvp)
|
||||
typval_T *wvp; /* VAR_UNKNOWN for current window */
|
||||
typval_T *tvp; /* VAR_UNKNOWN for current tab page */
|
||||
{
|
||||
win_T *wp = NULL;
|
||||
tabpage_T *tp = NULL;
|
||||
long n;
|
||||
|
||||
if (wvp->v_type != VAR_UNKNOWN)
|
||||
{
|
||||
if (tvp->v_type != VAR_UNKNOWN)
|
||||
{
|
||||
n = get_tv_number(tvp);
|
||||
if (n >= 0)
|
||||
tp = find_tabpage(n);
|
||||
}
|
||||
else
|
||||
tp = curtab;
|
||||
|
||||
if (tp != NULL)
|
||||
wp = find_win_by_nr(wvp, tp);
|
||||
}
|
||||
else
|
||||
wp = curwin;
|
||||
|
||||
return wp;
|
||||
}
|
||||
|
||||
/*
|
||||
* "getwinvar()" function
|
||||
*/
|
||||
@@ -13557,10 +13588,13 @@ f_has_key(argvars, rettv)
|
||||
*/
|
||||
static void
|
||||
f_haslocaldir(argvars, rettv)
|
||||
typval_T *argvars UNUSED;
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
rettv->vval.v_number = (curwin->w_localdir != NULL);
|
||||
win_T *wp = NULL;
|
||||
|
||||
wp = find_tabwin(&argvars[0], &argvars[1]);
|
||||
rettv->vval.v_number = (wp != NULL && wp->w_localdir != NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -15500,6 +15534,23 @@ f_pathshorten(argvars, rettv)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FEAT_PERL
|
||||
/*
|
||||
* "perleval()" function
|
||||
*/
|
||||
static void
|
||||
f_perleval(argvars, rettv)
|
||||
typval_T *argvars;
|
||||
typval_T *rettv;
|
||||
{
|
||||
char_u *str;
|
||||
char_u buf[NUMBUFLEN];
|
||||
|
||||
str = get_tv_string_buf(&argvars[0], buf);
|
||||
do_perleval(str, rettv);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_FLOAT
|
||||
/*
|
||||
* "pow()" function
|
||||
@@ -21856,15 +21907,15 @@ get_funccal()
|
||||
funccal = current_funccal;
|
||||
if (debug_backtrace_level > 0)
|
||||
{
|
||||
for (i = 0; i < debug_backtrace_level; i++)
|
||||
{
|
||||
temp_funccal = funccal->caller;
|
||||
if (temp_funccal)
|
||||
funccal = temp_funccal;
|
||||
for (i = 0; i < debug_backtrace_level; i++)
|
||||
{
|
||||
temp_funccal = funccal->caller;
|
||||
if (temp_funccal)
|
||||
funccal = temp_funccal;
|
||||
else
|
||||
/* backtrace level overflow. reset to max */
|
||||
debug_backtrace_level = i;
|
||||
}
|
||||
/* backtrace level overflow. reset to max */
|
||||
debug_backtrace_level = i;
|
||||
}
|
||||
}
|
||||
return funccal;
|
||||
}
|
||||
@@ -23384,8 +23435,8 @@ ret_free:
|
||||
* Also handles a Funcref in a List or Dictionary.
|
||||
* Returns the function name in allocated memory, or NULL for failure.
|
||||
* flags:
|
||||
* TFN_INT: internal function name OK
|
||||
* TFN_QUIET: be quiet
|
||||
* TFN_INT: internal function name OK
|
||||
* TFN_QUIET: be quiet
|
||||
* TFN_NO_AUTOLOAD: do not use script autoloading
|
||||
* Advances "pp" to just after the function name (if no error).
|
||||
*/
|
||||
|
||||
+3
-2
@@ -2909,6 +2909,7 @@ alist_add_list(count, files, after)
|
||||
int after; /* where to add: 0 = before first one */
|
||||
{
|
||||
int i;
|
||||
int old_argcount = ARGCOUNT;
|
||||
|
||||
if (ga_grow(&ALIST(curwin)->al_ga, count) == OK)
|
||||
{
|
||||
@@ -2925,8 +2926,8 @@ alist_add_list(count, files, after)
|
||||
ARGLIST[after + i].ae_fnum = buflist_add(files[i], BLN_LISTED);
|
||||
}
|
||||
ALIST(curwin)->al_ga.ga_len += count;
|
||||
if (curwin->w_arg_idx >= after)
|
||||
++curwin->w_arg_idx;
|
||||
if (old_argcount > 0 && curwin->w_arg_idx >= after)
|
||||
curwin->w_arg_idx += count;
|
||||
return after;
|
||||
}
|
||||
|
||||
|
||||
+2
-6
@@ -7335,14 +7335,10 @@ delete_recursive(char_u *name)
|
||||
/* A symbolic link to a directory itself is deleted, not the directory it
|
||||
* points to. */
|
||||
if (
|
||||
# if defined(WIN32)
|
||||
mch_isdir(name) && !mch_is_symbolic_link(name)
|
||||
# else
|
||||
# ifdef UNIX
|
||||
# if defined(UNIX) || defined(WIN32)
|
||||
mch_isrealdir(name)
|
||||
# else
|
||||
# else
|
||||
mch_isdir(name)
|
||||
# endif
|
||||
# endif
|
||||
)
|
||||
{
|
||||
|
||||
+89
-19
@@ -301,18 +301,18 @@ static struct
|
||||
};
|
||||
|
||||
/* Local variables */
|
||||
static int s_button_pending = -1;
|
||||
static int s_button_pending = -1;
|
||||
|
||||
/* s_getting_focus is set when we got focus but didn't see mouse-up event yet,
|
||||
* so don't reset s_button_pending. */
|
||||
static int s_getting_focus = FALSE;
|
||||
static int s_getting_focus = FALSE;
|
||||
|
||||
static int s_x_pending;
|
||||
static int s_y_pending;
|
||||
static UINT s_kFlags_pending;
|
||||
static UINT s_wait_timer = 0; /* Timer for get char from user */
|
||||
static int s_timed_out = FALSE;
|
||||
static int dead_key = 0; /* 0 - no dead key, 1 - dead key pressed */
|
||||
static int s_x_pending;
|
||||
static int s_y_pending;
|
||||
static UINT s_kFlags_pending;
|
||||
static UINT s_wait_timer = 0; /* Timer for get char from user */
|
||||
static int s_timed_out = FALSE;
|
||||
static int dead_key = 0; /* 0: no dead key, 1: dead key pressed */
|
||||
|
||||
#ifdef WIN3264
|
||||
static OSVERSIONINFO os_version; /* like it says. Init in gui_mch_init() */
|
||||
@@ -641,6 +641,8 @@ _OnSysChar(
|
||||
int modifiers;
|
||||
int ch = cch; /* special keys are negative */
|
||||
|
||||
dead_key = 0;
|
||||
|
||||
/* TRACE("OnSysChar(%d, %c)\n", ch, ch); */
|
||||
|
||||
/* OK, we have a character key (given by ch) which was entered with the
|
||||
@@ -1710,6 +1712,34 @@ gui_mch_draw_part_cursor(
|
||||
DeleteBrush(hbr);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Generates a VK_SPACE when the internal dead_key flag is set to output the
|
||||
* dead key's nominal character and re-post the original message.
|
||||
*/
|
||||
static void
|
||||
outputDeadKey_rePost(MSG originalMsg)
|
||||
{
|
||||
static MSG deadCharExpel;
|
||||
|
||||
if (!dead_key)
|
||||
return;
|
||||
|
||||
dead_key = 0;
|
||||
|
||||
/* Make Windows generate the dead key's character */
|
||||
deadCharExpel.message = originalMsg.message;
|
||||
deadCharExpel.hwnd = originalMsg.hwnd;
|
||||
deadCharExpel.wParam = VK_SPACE;
|
||||
|
||||
MyTranslateMessage(&deadCharExpel);
|
||||
|
||||
/* re-generate the current character free of the dead char influence */
|
||||
PostMessage(originalMsg.hwnd, originalMsg.message, originalMsg.wParam,
|
||||
originalMsg.lParam);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process a single Windows message.
|
||||
* If one is not available we hang until one is.
|
||||
@@ -1790,21 +1820,48 @@ process_message(void)
|
||||
if (msg.message == WM_KEYDOWN || msg.message == WM_SYSKEYDOWN)
|
||||
{
|
||||
vk = (int) msg.wParam;
|
||||
|
||||
/*
|
||||
* If a dead key was pressed and the user presses VK_SPACE, VK_BACK, or
|
||||
* VK_ESCAPE it means that he actually wants to deal with the dead char
|
||||
* now, so do nothing special and let Windows handle it.
|
||||
* Handle dead keys in special conditions in other cases we let Windows
|
||||
* handle them and do not interfere.
|
||||
*
|
||||
* Note that VK_SPACE combines with the dead_key's character and only
|
||||
* one WM_CHAR will be generated by TranslateMessage(), in the two
|
||||
* other cases two WM_CHAR will be generated: the dead char and VK_BACK
|
||||
* or VK_ESCAPE. That is most likely what the user expects.
|
||||
* The dead_key flag must be reset on several occasions:
|
||||
* - in _OnChar() (or _OnSysChar()) as any dead key was necessarily
|
||||
* consumed at that point (This is when we let Windows combine the
|
||||
* dead character on its own)
|
||||
*
|
||||
* - Before doing something special such as regenerating keypresses to
|
||||
* expel the dead character as this could trigger an infinite loop if
|
||||
* for some reason MyTranslateMessage() do not trigger a call
|
||||
* immediately to _OnChar() (or _OnSysChar()).
|
||||
*/
|
||||
if (dead_key && (vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
|
||||
if (dead_key)
|
||||
{
|
||||
dead_key = 0;
|
||||
MyTranslateMessage(&msg);
|
||||
return;
|
||||
/*
|
||||
* If a dead key was pressed and the user presses VK_SPACE,
|
||||
* VK_BACK, or VK_ESCAPE it means that he actually wants to deal
|
||||
* with the dead char now, so do nothing special and let Windows
|
||||
* handle it.
|
||||
*
|
||||
* Note that VK_SPACE combines with the dead_key's character and
|
||||
* only one WM_CHAR will be generated by TranslateMessage(), in
|
||||
* the two other cases two WM_CHAR will be generated: the dead
|
||||
* char and VK_BACK or VK_ESCAPE. That is most likely what the
|
||||
* user expects.
|
||||
*/
|
||||
if ((vk == VK_SPACE || vk == VK_BACK || vk == VK_ESCAPE))
|
||||
{
|
||||
dead_key = 0;
|
||||
MyTranslateMessage(&msg);
|
||||
return;
|
||||
}
|
||||
/* In modes where we are not typing, dead keys should behave
|
||||
* normally */
|
||||
else if (!(get_real_state() & (INSERT | CMDLINE | SELECTMODE)))
|
||||
{
|
||||
outputDeadKey_rePost(msg);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check for CTRL-BREAK */
|
||||
@@ -1822,6 +1879,19 @@ process_message(void)
|
||||
if (special_keys[i].key_sym == vk
|
||||
&& (vk != VK_SPACE || !(GetKeyState(VK_MENU) & 0x8000)))
|
||||
{
|
||||
/*
|
||||
* Behave as exected if we have a dead key and the special key
|
||||
* is a key that would normally trigger the dead key nominal
|
||||
* character output (such as a NUMPAD printable character or
|
||||
* the TAB key, etc...).
|
||||
*/
|
||||
if (dead_key && (special_keys[i].vim_code0 == 'K'
|
||||
|| vk == VK_TAB || vk == CAR))
|
||||
{
|
||||
outputDeadKey_rePost(msg);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef FEAT_MENU
|
||||
/* Check for <F10>: Windows selects the menu. When <F10> is
|
||||
* mapped we want to use the mapping instead. */
|
||||
|
||||
+297
-17
@@ -117,7 +117,9 @@
|
||||
#if (PERL_REVISION == 5) && (PERL_VERSION >= 14) && defined(_MSC_VER)
|
||||
/* Using PL_errgv to get the error message after perl_eval_sv() causes a crash
|
||||
* with MSVC and Perl version 5.14. */
|
||||
# define AVOID_PL_ERRGV
|
||||
# define CHECK_EVAL_ERR(len) SvPV(perl_get_sv("@", GV_ADD), (len));
|
||||
#else
|
||||
# define CHECK_EVAL_ERR(len) SvPV(GvSV(PL_errgv), (len));
|
||||
#endif
|
||||
|
||||
/* Compatibility hacks over */
|
||||
@@ -279,6 +281,13 @@ typedef int perl_key;
|
||||
# define PL_thr_key *dll_PL_thr_key
|
||||
# endif
|
||||
# endif
|
||||
# define Perl_hv_iternext_flags dll_Perl_hv_iternext_flags
|
||||
# define Perl_hv_iterinit dll_Perl_hv_iterinit
|
||||
# define Perl_hv_iterkey dll_Perl_hv_iterkey
|
||||
# define Perl_hv_iterval dll_Perl_hv_iterval
|
||||
# define Perl_av_fetch dll_Perl_av_fetch
|
||||
# define Perl_av_len dll_Perl_av_len
|
||||
# define Perl_sv_2nv_flags dll_Perl_sv_2nv_flags
|
||||
|
||||
/*
|
||||
* Declare HANDLE for perl.dll and function pointers.
|
||||
@@ -422,6 +431,13 @@ static SV* (*Perl_Isv_yes_ptr)(register PerlInterpreter*);
|
||||
static perl_key* (*Perl_Gthr_key_ptr)_((pTHX));
|
||||
#endif
|
||||
static void (*boot_DynaLoader)_((pTHX_ CV*));
|
||||
static HE * (*Perl_hv_iternext_flags)(pTHX_ HV *, I32);
|
||||
static I32 (*Perl_hv_iterinit)(pTHX_ HV *);
|
||||
static char * (*Perl_hv_iterkey)(pTHX_ HE *, I32 *);
|
||||
static SV * (*Perl_hv_iterval)(pTHX_ HV *, HE *);
|
||||
static SV** (*Perl_av_fetch)(pTHX_ AV *, SSize_t, I32);
|
||||
static SSize_t (*Perl_av_len)(pTHX_ AV *);
|
||||
static NV (*Perl_sv_2nv_flags)(pTHX_ SV *const, const I32);
|
||||
|
||||
/*
|
||||
* Table of name to function pointer of perl.
|
||||
@@ -554,6 +570,13 @@ static struct {
|
||||
{"Perl_Gthr_key_ptr", (PERL_PROC*)&Perl_Gthr_key_ptr},
|
||||
#endif
|
||||
{"boot_DynaLoader", (PERL_PROC*)&boot_DynaLoader},
|
||||
{"Perl_hv_iternext_flags", (PERL_PROC*)&Perl_hv_iternext_flags},
|
||||
{"Perl_hv_iterinit", (PERL_PROC*)&Perl_hv_iterinit},
|
||||
{"Perl_hv_iterkey", (PERL_PROC*)&Perl_hv_iterkey},
|
||||
{"Perl_hv_iterval", (PERL_PROC*)&Perl_hv_iterval},
|
||||
{"Perl_av_fetch", (PERL_PROC*)&Perl_av_fetch},
|
||||
{"Perl_av_len", (PERL_PROC*)&Perl_av_len},
|
||||
{"Perl_sv_2nv_flags", (PERL_PROC*)&Perl_sv_2nv_flags},
|
||||
{"", NULL},
|
||||
};
|
||||
|
||||
@@ -656,7 +679,7 @@ perl_end()
|
||||
perl_free(perl_interp);
|
||||
perl_interp = NULL;
|
||||
#if (PERL_REVISION == 5) && (PERL_VERSION >= 10)
|
||||
Perl_sys_term();
|
||||
Perl_sys_term();
|
||||
#endif
|
||||
}
|
||||
#ifdef DYNAMIC_PERL
|
||||
@@ -910,11 +933,7 @@ ex_perl(eap)
|
||||
|
||||
SvREFCNT_dec(sv);
|
||||
|
||||
#ifdef AVOID_PL_ERRGV
|
||||
err = SvPV(perl_get_sv("@", GV_ADD), length);
|
||||
#else
|
||||
err = SvPV(GvSV(PL_errgv), length);
|
||||
#endif
|
||||
err = CHECK_EVAL_ERR(length);
|
||||
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
@@ -949,6 +968,275 @@ replace_line(line, end)
|
||||
return OK;
|
||||
}
|
||||
|
||||
static struct ref_map_S {
|
||||
void *vim_ref;
|
||||
SV *perl_ref;
|
||||
struct ref_map_S *next;
|
||||
} *ref_map = NULL;
|
||||
|
||||
static void
|
||||
ref_map_free(void)
|
||||
{
|
||||
struct ref_map_S *tofree;
|
||||
struct ref_map_S *refs = ref_map;
|
||||
|
||||
while (refs) {
|
||||
tofree = refs;
|
||||
refs = refs->next;
|
||||
vim_free(tofree);
|
||||
}
|
||||
ref_map = NULL;
|
||||
}
|
||||
|
||||
static struct ref_map_S *
|
||||
ref_map_find_SV(sv)
|
||||
SV *const sv;
|
||||
{
|
||||
struct ref_map_S *refs = ref_map;
|
||||
int count = 350;
|
||||
|
||||
while (refs) {
|
||||
if (refs->perl_ref == sv)
|
||||
break;
|
||||
refs = refs->next;
|
||||
count--;
|
||||
}
|
||||
|
||||
if (!refs && count > 0) {
|
||||
refs = (struct ref_map_S *)alloc(sizeof(struct ref_map_S));
|
||||
if (!refs)
|
||||
return NULL;
|
||||
refs->perl_ref = sv;
|
||||
refs->vim_ref = NULL;
|
||||
refs->next = ref_map;
|
||||
ref_map = refs;
|
||||
}
|
||||
|
||||
return refs;
|
||||
}
|
||||
|
||||
static int
|
||||
perl_to_vim(sv, rettv)
|
||||
SV *sv;
|
||||
typval_T *rettv;
|
||||
{
|
||||
if (SvROK(sv))
|
||||
sv = SvRV(sv);
|
||||
|
||||
switch (SvTYPE(sv)) {
|
||||
case SVt_NULL:
|
||||
break;
|
||||
case SVt_NV: /* float */
|
||||
#ifdef FEAT_FLOAT
|
||||
rettv->v_type = VAR_FLOAT;
|
||||
rettv->vval.v_float = SvNV(sv);
|
||||
break;
|
||||
#endif
|
||||
case SVt_IV: /* integer */
|
||||
if (!SvROK(sv)) { /* references should be string */
|
||||
rettv->vval.v_number = SvIV(sv);
|
||||
break;
|
||||
}
|
||||
case SVt_PV: /* string */
|
||||
{
|
||||
size_t len = 0;
|
||||
char * str_from = SvPV(sv, len);
|
||||
char_u *str_to = (char_u*)alloc(sizeof(char_u) * (len + 1));
|
||||
|
||||
if (str_to) {
|
||||
str_to[len] = '\0';
|
||||
|
||||
while (len--) {
|
||||
if (str_from[len] == '\0')
|
||||
str_to[len] = '\n';
|
||||
else
|
||||
str_to[len] = str_from[len];
|
||||
}
|
||||
}
|
||||
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = str_to;
|
||||
break;
|
||||
}
|
||||
case SVt_PVAV: /* list */
|
||||
{
|
||||
SSize_t size;
|
||||
listitem_T * item;
|
||||
SV ** item2;
|
||||
list_T * list;
|
||||
struct ref_map_S * refs;
|
||||
|
||||
if ((refs = ref_map_find_SV(sv)) == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (refs->vim_ref)
|
||||
list = (list_T *) refs->vim_ref;
|
||||
else
|
||||
{
|
||||
if ((list = list_alloc()) == NULL)
|
||||
return FAIL;
|
||||
refs->vim_ref = list;
|
||||
|
||||
for (size = av_len((AV*)sv); size >= 0; size--)
|
||||
{
|
||||
if ((item = listitem_alloc()) == NULL)
|
||||
break;
|
||||
|
||||
item->li_tv.v_type = VAR_NUMBER;
|
||||
item->li_tv.v_lock = 0;
|
||||
item->li_tv.vval.v_number = 0;
|
||||
list_insert(list, item, list->lv_first);
|
||||
|
||||
item2 = av_fetch((AV *)sv, size, 0);
|
||||
|
||||
if (item2 == NULL || *item2 == NULL ||
|
||||
perl_to_vim(*item2, &item->li_tv) == FAIL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
list->lv_refcount++;
|
||||
rettv->v_type = VAR_LIST;
|
||||
rettv->vval.v_list = list;
|
||||
break;
|
||||
}
|
||||
case SVt_PVHV: /* dictionary */
|
||||
{
|
||||
HE * entry;
|
||||
size_t key_len;
|
||||
char * key;
|
||||
dictitem_T * item;
|
||||
SV * item2;
|
||||
dict_T * dict;
|
||||
struct ref_map_S * refs;
|
||||
|
||||
if ((refs = ref_map_find_SV(sv)) == NULL)
|
||||
return FAIL;
|
||||
|
||||
if (refs->vim_ref)
|
||||
dict = (dict_T *) refs->vim_ref;
|
||||
else
|
||||
{
|
||||
|
||||
if ((dict = dict_alloc()) == NULL)
|
||||
return FAIL;
|
||||
refs->vim_ref = dict;
|
||||
|
||||
hv_iterinit((HV *)sv);
|
||||
|
||||
for (entry = hv_iternext((HV *)sv); entry; entry = hv_iternext((HV *)sv))
|
||||
{
|
||||
key_len = 0;
|
||||
key = hv_iterkey(entry, (I32 *)&key_len);
|
||||
|
||||
if (!key || !key_len || strlen(key) < key_len) {
|
||||
EMSG2("Malformed key Dictionary '%s'", key && *key ? key : "(empty)");
|
||||
break;
|
||||
}
|
||||
|
||||
if ((item = dictitem_alloc((char_u *)key)) == NULL)
|
||||
break;
|
||||
|
||||
item->di_tv.v_type = VAR_NUMBER;
|
||||
item->di_tv.v_lock = 0;
|
||||
item->di_tv.vval.v_number = 0;
|
||||
|
||||
if (dict_add(dict, item) == FAIL) {
|
||||
dictitem_free(item);
|
||||
break;
|
||||
}
|
||||
item2 = hv_iterval((HV *)sv, entry);
|
||||
if (item2 == NULL || perl_to_vim(item2, &item->di_tv) == FAIL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dict->dv_refcount++;
|
||||
rettv->v_type = VAR_DICT;
|
||||
rettv->vval.v_dict = dict;
|
||||
break;
|
||||
}
|
||||
default: /* not convertible */
|
||||
{
|
||||
char *val = SvPV_nolen(sv);
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = val ? vim_strsave((char_u *)val) : NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* "perleval()"
|
||||
*/
|
||||
void
|
||||
do_perleval(str, rettv)
|
||||
char_u *str;
|
||||
typval_T *rettv;
|
||||
{
|
||||
char *err = NULL;
|
||||
STRLEN err_len = 0;
|
||||
SV *sv = NULL;
|
||||
#ifdef HAVE_SANDBOX
|
||||
SV *safe;
|
||||
#endif
|
||||
|
||||
if (perl_interp == NULL)
|
||||
{
|
||||
#ifdef DYNAMIC_PERL
|
||||
if (!perl_enabled(TRUE))
|
||||
{
|
||||
EMSG(_(e_noperl));
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
perl_init();
|
||||
}
|
||||
|
||||
{
|
||||
dSP;
|
||||
ENTER;
|
||||
SAVETMPS;
|
||||
|
||||
#ifdef HAVE_SANDBOX
|
||||
if (sandbox)
|
||||
{
|
||||
safe = get_sv("VIM::safe", FALSE);
|
||||
# ifndef MAKE_TEST /* avoid a warning for unreachable code */
|
||||
if (safe == NULL || !SvTRUE(safe))
|
||||
EMSG(_("E299: Perl evaluation forbidden in sandbox without the Safe module"));
|
||||
else
|
||||
# endif
|
||||
{
|
||||
sv = newSVpv((char *)str, 0);
|
||||
PUSHMARK(SP);
|
||||
XPUSHs(safe);
|
||||
XPUSHs(sv);
|
||||
PUTBACK;
|
||||
call_method("reval", G_SCALAR);
|
||||
SPAGAIN;
|
||||
SvREFCNT_dec(sv);
|
||||
sv = POPs;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* HAVE_SANDBOX */
|
||||
sv = eval_pv((char *)str, 0);
|
||||
|
||||
if (sv) {
|
||||
perl_to_vim(sv, rettv);
|
||||
ref_map_free();
|
||||
err = CHECK_EVAL_ERR(err_len);
|
||||
}
|
||||
PUTBACK;
|
||||
FREETMPS;
|
||||
LEAVE;
|
||||
}
|
||||
if (err_len)
|
||||
msg_split((char_u *)err, highlight_attr[HLF_E]);
|
||||
}
|
||||
|
||||
/*
|
||||
* ":perldo".
|
||||
*/
|
||||
@@ -984,11 +1272,7 @@ ex_perldo(eap)
|
||||
sv_catpvn(sv, "}", 1);
|
||||
perl_eval_sv(sv, G_DISCARD | G_NOARGS);
|
||||
SvREFCNT_dec(sv);
|
||||
#ifdef AVOID_PL_ERRGV
|
||||
str = SvPV(perl_get_sv("@", GV_ADD), length);
|
||||
#else
|
||||
str = SvPV(GvSV(PL_errgv), length);
|
||||
#endif
|
||||
str = CHECK_EVAL_ERR(length);
|
||||
if (length)
|
||||
goto err;
|
||||
|
||||
@@ -1002,11 +1286,7 @@ ex_perldo(eap)
|
||||
sv_setpv(GvSV(PL_defgv), (char *)ml_get(i));
|
||||
PUSHMARK(sp);
|
||||
perl_call_pv("VIM::perldo", G_SCALAR | G_EVAL);
|
||||
#ifdef AVOID_PL_ERRGV
|
||||
str = SvPV(perl_get_sv("@", GV_ADD), length);
|
||||
#else
|
||||
str = SvPV(GvSV(PL_errgv), length);
|
||||
#endif
|
||||
str = CHECK_EVAL_ERR(length);
|
||||
if (length)
|
||||
break;
|
||||
SPAGAIN;
|
||||
|
||||
+1
-1
@@ -5521,7 +5521,7 @@ run_eval(const char *cmd, typval_T *rettv
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ConvertFromPyObject(run_ret, rettv) == -1)
|
||||
if (run_ret != Py_None && ConvertFromPyObject(run_ret, rettv) == -1)
|
||||
EMSG(_("E859: Failed to convert returned python object to vim value"));
|
||||
Py_DECREF(run_ret);
|
||||
}
|
||||
|
||||
+27
-7
@@ -3129,6 +3129,17 @@ mch_isdir(char_u *name)
|
||||
return (f & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* return TRUE if "name" is a directory, NOT a symlink to a directory
|
||||
* return FALSE if "name" is not a directory
|
||||
* return FALSE for error
|
||||
*/
|
||||
int
|
||||
mch_isrealdir(char_u *name)
|
||||
{
|
||||
return mch_isdir(name) && !mch_is_symbolic_link(name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create directory "name".
|
||||
* Return 0 on success, -1 on error.
|
||||
@@ -3190,10 +3201,10 @@ mch_is_hard_link(char_u *fname)
|
||||
}
|
||||
|
||||
/*
|
||||
* Return TRUE if file "fname" is a symbolic link.
|
||||
* Return TRUE if "name" is a symbolic link (or a junction).
|
||||
*/
|
||||
int
|
||||
mch_is_symbolic_link(char_u *fname)
|
||||
mch_is_symbolic_link(char_u *name)
|
||||
{
|
||||
HANDLE hFind;
|
||||
int res = FALSE;
|
||||
@@ -3204,7 +3215,7 @@ mch_is_symbolic_link(char_u *fname)
|
||||
WIN32_FIND_DATAW findDataW;
|
||||
|
||||
if (enc_codepage >= 0 && (int)GetACP() != enc_codepage)
|
||||
wn = enc_to_utf16(fname, NULL);
|
||||
wn = enc_to_utf16(name, NULL);
|
||||
if (wn != NULL)
|
||||
{
|
||||
hFind = FindFirstFileW(wn, &findDataW);
|
||||
@@ -3213,7 +3224,7 @@ mch_is_symbolic_link(char_u *fname)
|
||||
&& GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
|
||||
{
|
||||
/* Retry with non-wide function (for Windows 98). */
|
||||
hFind = FindFirstFile(fname, &findDataA);
|
||||
hFind = FindFirstFile(name, &findDataA);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fileFlags = findDataA.dwFileAttributes;
|
||||
@@ -3229,7 +3240,7 @@ mch_is_symbolic_link(char_u *fname)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
hFind = FindFirstFile(fname, &findDataA);
|
||||
hFind = FindFirstFile(name, &findDataA);
|
||||
if (hFind != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fileFlags = findDataA.dwFileAttributes;
|
||||
@@ -3241,7 +3252,8 @@ mch_is_symbolic_link(char_u *fname)
|
||||
FindClose(hFind);
|
||||
|
||||
if ((fileFlags & FILE_ATTRIBUTE_REPARSE_POINT)
|
||||
&& reparseTag == IO_REPARSE_TAG_SYMLINK)
|
||||
&& (reparseTag == IO_REPARSE_TAG_SYMLINK
|
||||
|| reparseTag == IO_REPARSE_TAG_MOUNT_POINT))
|
||||
res = TRUE;
|
||||
|
||||
return res;
|
||||
@@ -5839,7 +5851,8 @@ mch_delay(
|
||||
|
||||
|
||||
/*
|
||||
* this version of remove is not scared by a readonly (backup) file
|
||||
* This version of remove is not scared by a readonly (backup) file.
|
||||
* This can also remove a symbolic link like Unix.
|
||||
* Return 0 for success, -1 for failure.
|
||||
*/
|
||||
int
|
||||
@@ -5850,6 +5863,13 @@ mch_remove(char_u *name)
|
||||
int n;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* On Windows, deleting a directory's symbolic link is done by
|
||||
* RemoveDirectory(): mch_rmdir. It seems unnatural, but it is fact.
|
||||
*/
|
||||
if (mch_isdir(name) && mch_is_symbolic_link(name))
|
||||
return mch_rmdir(name);
|
||||
|
||||
win32_setattrs(name, FILE_ATTRIBUTE_NORMAL);
|
||||
|
||||
#ifdef FEAT_MBYTE
|
||||
|
||||
@@ -6,3 +6,4 @@ void perl_win_free __ARGS((win_T *wp));
|
||||
void perl_buf_free __ARGS((buf_T *bp));
|
||||
void ex_perl __ARGS((exarg_T *eap));
|
||||
void ex_perldo __ARGS((exarg_T *eap));
|
||||
void do_perleval __ARGS((char_u *str, typval_T *rettv));
|
||||
|
||||
@@ -21,6 +21,7 @@ int mch_setperm __ARGS((char_u *name, long perm));
|
||||
void mch_hide __ARGS((char_u *name));
|
||||
int mch_ishidden __ARGS((char_u *name));
|
||||
int mch_isdir __ARGS((char_u *name));
|
||||
int mch_isrealdir __ARGS((char_u *name));
|
||||
int mch_mkdir __ARGS((char_u *name));
|
||||
int mch_rmdir __ARGS((char_u *name));
|
||||
int mch_is_hard_link __ARGS((char_u *fname));
|
||||
|
||||
@@ -103,6 +103,7 @@ SCRIPTS_ALL = \
|
||||
test_erasebackword.out \
|
||||
test_eval.out \
|
||||
test_fixeol.out \
|
||||
test_getcwd.out \
|
||||
test_insertcount.out \
|
||||
test_listchars.out \
|
||||
test_listlbr.out \
|
||||
@@ -112,7 +113,6 @@ SCRIPTS_ALL = \
|
||||
test_match_conceal.out \
|
||||
test_nested_function.out \
|
||||
test_options.out \
|
||||
test_perl.out \
|
||||
test_qf_title.out \
|
||||
test_ruby.out \
|
||||
test_search_mbyte.out \
|
||||
@@ -178,7 +178,8 @@ NEW_TESTS = test_arglist.res \
|
||||
test_increment.res \
|
||||
test_quickfix.res \
|
||||
test_viml.res \
|
||||
test_alot.res
|
||||
test_alot.res \
|
||||
test_perl.res
|
||||
|
||||
|
||||
# Explicit dependencies.
|
||||
|
||||
@@ -329,6 +329,8 @@ EOF
|
||||
:$put =string(l)
|
||||
:let d=pyeval('{"a": "b", "c": 1, "d": ["e"]}')
|
||||
:$put =sort(items(d))
|
||||
:let v:errmsg = ''
|
||||
:$put ='pyeval(\"None\") = ' . pyeval('None') . v:errmsg
|
||||
:if has('float')
|
||||
: let f=pyeval('0.0')
|
||||
: $put =string(f)
|
||||
|
||||
@@ -86,6 +86,7 @@ ll:[1]
|
||||
['a', 'b']
|
||||
['c', 1]
|
||||
['d', ['e']]
|
||||
pyeval("None") = 0
|
||||
0.0
|
||||
"\0": Vim(let):E859:
|
||||
{"\0": 1}: Vim(let):E859:
|
||||
|
||||
@@ -326,6 +326,8 @@ EOF
|
||||
:$put =string(l)
|
||||
:let d=py3eval('{"a": "b", "c": 1, "d": ["e"]}')
|
||||
:$put =sort(items(d))
|
||||
:let v:errmsg = ''
|
||||
:$put ='py3eval(\"None\") = ' . py3eval('None') . v:errmsg
|
||||
:if has('float')
|
||||
: let f=py3eval('0.0')
|
||||
: $put =string(f)
|
||||
|
||||
@@ -86,6 +86,7 @@ ll:[1]
|
||||
['a', 'b']
|
||||
['c', 1]
|
||||
['d', ['e']]
|
||||
py3eval("None") = 0
|
||||
0.0
|
||||
"\0": Vim(let):E859:
|
||||
{"\0": 1}: Vim(let):E859:
|
||||
|
||||
@@ -20,3 +20,55 @@ func Test_argidx()
|
||||
1argdelete
|
||||
call assert_equal(0, argidx())
|
||||
endfunc
|
||||
|
||||
func Test_argadd()
|
||||
%argdelete
|
||||
argadd a b c
|
||||
call assert_equal(0, argidx())
|
||||
|
||||
%argdelete
|
||||
argadd a
|
||||
call assert_equal(0, argidx())
|
||||
argadd b c d
|
||||
call assert_equal(0, argidx())
|
||||
|
||||
call Init_abc()
|
||||
argadd x
|
||||
call Assert_argc(['a', 'b', 'x', 'c'])
|
||||
call assert_equal(1, argidx())
|
||||
|
||||
call Init_abc()
|
||||
0argadd x
|
||||
call Assert_argc(['x', 'a', 'b', 'c'])
|
||||
call assert_equal(2, argidx())
|
||||
|
||||
call Init_abc()
|
||||
1argadd x
|
||||
call Assert_argc(['a', 'x', 'b', 'c'])
|
||||
call assert_equal(2, argidx())
|
||||
|
||||
call Init_abc()
|
||||
$argadd x
|
||||
call Assert_argc(['a', 'b', 'c', 'x'])
|
||||
call assert_equal(1, argidx())
|
||||
|
||||
call Init_abc()
|
||||
$argadd x
|
||||
+2argadd y
|
||||
call Assert_argc(['a', 'b', 'c', 'x', 'y'])
|
||||
call assert_equal(1, argidx())
|
||||
endfunc
|
||||
|
||||
func Init_abc()
|
||||
args a b c
|
||||
next
|
||||
endfunc
|
||||
|
||||
func Assert_argc(l)
|
||||
call assert_equal(len(a:l), argc())
|
||||
let i = 0
|
||||
while i < len(a:l) && i < argc()
|
||||
call assert_equal(a:l[i], argv(i))
|
||||
let i += 1
|
||||
endwhile
|
||||
endfunc
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
Tests for getcwd(), haslocaldir(), and :lcd vim: set ft=vim :
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:" Do all test in a separate window to avoid E211 when we recursively
|
||||
:" delete the Xtopdir directory during cleanup
|
||||
:"
|
||||
:" This will cause a few errors, do it silently.
|
||||
:set visualbell
|
||||
:set nocp viminfo+=nviminfo
|
||||
:"
|
||||
:function! DeleteDirectory(dir)
|
||||
: if has("win16") || has("win32") || has("win64") || has("dos16") || has("dos32")
|
||||
: exec "silent !rmdir /Q /S " . a:dir
|
||||
: else
|
||||
: exec "silent !rm -rf " . a:dir
|
||||
: endif
|
||||
:endfun
|
||||
:"
|
||||
:function! GetCwdInfo(win, tab)
|
||||
: let tab_changed = 0
|
||||
: let mod = ":t"
|
||||
: if a:tab > 0 && a:tab != tabpagenr()
|
||||
: let tab_changed = 1
|
||||
: exec "tabnext " . a:tab
|
||||
: endif
|
||||
: let bufname = fnamemodify(bufname(winbufnr(a:win)), mod)
|
||||
: if tab_changed
|
||||
: tabprevious
|
||||
: endif
|
||||
: if a:win == 0 && a:tab == 0
|
||||
: let dirname = fnamemodify(getcwd(), mod)
|
||||
: let lflag = haslocaldir()
|
||||
: elseif a:tab == 0
|
||||
: let dirname = fnamemodify(getcwd(a:win), mod)
|
||||
: let lflag = haslocaldir(a:win)
|
||||
: else
|
||||
: let dirname = fnamemodify(getcwd(a:win, a:tab), mod)
|
||||
: let lflag = haslocaldir(a:win, a:tab)
|
||||
: endif
|
||||
: return bufname . ' ' . dirname . ' ' . lflag
|
||||
:endfunction
|
||||
:" On windows a stale "Xtopdir" directory may exist, remove it so that
|
||||
:" we start from a clean state.
|
||||
:call DeleteDirectory("Xtopdir")
|
||||
:let r=[]
|
||||
:new
|
||||
:let cwd=getcwd()
|
||||
:let test_out = cwd . '/test.out'
|
||||
:call mkdir('Xtopdir')
|
||||
:cd Xtopdir
|
||||
:call mkdir('Xdir1')
|
||||
:call mkdir('Xdir2')
|
||||
:call mkdir('Xdir3')
|
||||
:new a
|
||||
:new b
|
||||
:new c
|
||||
:3wincmd w
|
||||
:lcd Xdir1
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:wincmd W
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:wincmd W
|
||||
:lcd Xdir3
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("a"), 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("b"), 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("c"), 0))
|
||||
:wincmd W
|
||||
:call add(r, GetCwdInfo(bufwinnr("a"), tabpagenr()))
|
||||
:call add(r, GetCwdInfo(bufwinnr("b"), tabpagenr()))
|
||||
:call add(r, GetCwdInfo(bufwinnr("c"), tabpagenr()))
|
||||
:"
|
||||
:tabnew x
|
||||
:new y
|
||||
:new z
|
||||
:3wincmd w
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:wincmd W
|
||||
:lcd Xdir2
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:wincmd W
|
||||
:lcd Xdir3
|
||||
:call add(r, GetCwdInfo(0, 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("x"), 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("y"), 0))
|
||||
:call add(r, GetCwdInfo(bufwinnr("z"), 0))
|
||||
:let tp_nr = tabpagenr()
|
||||
:tabrewind
|
||||
:call add(r, GetCwdInfo(3, tp_nr))
|
||||
:call add(r, GetCwdInfo(2, tp_nr))
|
||||
:call add(r, GetCwdInfo(1, tp_nr))
|
||||
:"
|
||||
:call writefile(r, test_out, "a")
|
||||
:q
|
||||
:exec "cd " . cwd
|
||||
:call DeleteDirectory("Xtopdir")
|
||||
:qa!
|
||||
ENDTEST
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
a Xdir1 1
|
||||
b Xtopdir 0
|
||||
c Xdir3 1
|
||||
a Xdir1 1
|
||||
b Xtopdir 0
|
||||
c Xdir3 1
|
||||
a Xdir1 1
|
||||
b Xtopdir 0
|
||||
c Xdir3 1
|
||||
x Xtopdir 0
|
||||
y Xdir2 1
|
||||
z Xdir3 1
|
||||
x Xtopdir 0
|
||||
y Xdir2 1
|
||||
z Xdir3 1
|
||||
x Xtopdir 0
|
||||
y Xdir2 1
|
||||
z Xdir3 1
|
||||
@@ -1,26 +0,0 @@
|
||||
Tests for perl interface. vim: set ft=vim :
|
||||
|
||||
STARTTEST
|
||||
:so small.vim
|
||||
:set nocompatible viminfo+=nviminfo
|
||||
:if !has('perl') | e! test.ok | wq! test.out | endif
|
||||
:" change buffer contents
|
||||
:perl VIM::DoCommand("normal /^1\n")
|
||||
:perl $curline = VIM::Eval("line('.')")
|
||||
:perl $curbuf->Set($curline, "1 changed line 1")
|
||||
:" evaluate a List
|
||||
:perl VIM::DoCommand("normal /^2\n")
|
||||
:perl $curline = VIM::Eval("line('.')")
|
||||
:let l = ["abc", "def"]
|
||||
:perl << EOF
|
||||
$l = VIM::Eval("l");
|
||||
$curbuf->Append($curline, $l);
|
||||
EOF
|
||||
:normal j
|
||||
:.perldo s|\n|/|g
|
||||
:?^1?,$w! test.out
|
||||
:qa!
|
||||
ENDTEST
|
||||
|
||||
1 line 1
|
||||
2 line 2
|
||||
@@ -1,3 +0,0 @@
|
||||
1 changed line 1
|
||||
2 line 2
|
||||
abc/def/
|
||||
@@ -0,0 +1,94 @@
|
||||
" Tests for Perl interface
|
||||
|
||||
if !has('perl')
|
||||
finish
|
||||
end
|
||||
|
||||
func Test_change_buffer()
|
||||
call setline(line('$'), ['1 line 1'])
|
||||
perl VIM::DoCommand("normal /^1\n")
|
||||
perl $curline = VIM::Eval("line('.')")
|
||||
perl $curbuf->Set($curline, "1 changed line 1")
|
||||
call assert_equal('1 changed line 1', getline('$'))
|
||||
endfunc
|
||||
|
||||
func Test_evaluate_list()
|
||||
call setline(line('$'), ['2 line 2'])
|
||||
perl VIM::DoCommand("normal /^2\n")
|
||||
perl $curline = VIM::Eval("line('.')")
|
||||
let l = ["abc", "def"]
|
||||
perl << EOF
|
||||
$l = VIM::Eval("l");
|
||||
$curbuf->Append($curline, $l);
|
||||
EOF
|
||||
normal j
|
||||
.perldo s|\n|/|g
|
||||
call assert_equal('abc/def/', getline('$'))
|
||||
endfunc
|
||||
|
||||
fu <SID>catch_peval(expr)
|
||||
try
|
||||
call perleval(a:expr)
|
||||
catch
|
||||
return v:exception
|
||||
endtry
|
||||
call assert_true(0, 'no exception for `perleval("'.a:expr.'")`')
|
||||
return ''
|
||||
endf
|
||||
|
||||
function Test_perleval()
|
||||
call assert_false(perleval('undef'))
|
||||
|
||||
" scalar
|
||||
call assert_equal(0, perleval('0'))
|
||||
call assert_equal(2, perleval('2'))
|
||||
call assert_equal(-2, perleval('-2'))
|
||||
if has('float')
|
||||
call assert_equal(2.5, perleval('2.5'))
|
||||
else
|
||||
call assert_equal(2, perleval('2.5'))
|
||||
end
|
||||
|
||||
sandbox call assert_equal(2, perleval('2'))
|
||||
|
||||
call assert_equal('abc', perleval('"abc"'))
|
||||
call assert_equal("abc\ndef", perleval('"abc\0def"'))
|
||||
|
||||
" ref
|
||||
call assert_equal([], perleval('[]'))
|
||||
call assert_equal(['word', 42, [42],{}], perleval('["word", 42, [42], {}]'))
|
||||
|
||||
call assert_equal({}, perleval('{}'))
|
||||
call assert_equal({'foo': 'bar'}, perleval('{foo => "bar"}'))
|
||||
|
||||
perl our %h; our @a;
|
||||
let a = perleval('[\(%h, %h, @a, @a)]')
|
||||
call assert_true((a[0] is a[1]))
|
||||
call assert_true((a[2] is a[3]))
|
||||
perl undef %h; undef @a;
|
||||
|
||||
call assert_true(<SID>catch_peval('{"" , 0}') =~ 'Malformed key Dictionary')
|
||||
call assert_true(<SID>catch_peval('{"\0" , 0}') =~ 'Malformed key Dictionary')
|
||||
call assert_true(<SID>catch_peval('{"foo\0bar" , 0}') =~ 'Malformed key Dictionary')
|
||||
|
||||
call assert_equal('*VIM', perleval('"*VIM"'))
|
||||
call assert_true(perleval('\\0') =~ 'SCALAR(0x\x\+)')
|
||||
endf
|
||||
|
||||
function Test_perldo()
|
||||
sp __TEST__
|
||||
exe 'read ' g:testname
|
||||
perldo s/perl/vieux_chameau/g
|
||||
1
|
||||
call assert_false(search('\Cperl'))
|
||||
bw!
|
||||
endf
|
||||
|
||||
function Test_VIM_package()
|
||||
perl VIM::DoCommand('let l:var = "foo"')
|
||||
call assert_equal(l:var, 'foo')
|
||||
|
||||
set noet
|
||||
perl VIM::SetOption('et')
|
||||
call assert_true(&et)
|
||||
endf
|
||||
@@ -756,6 +756,20 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1129,
|
||||
/**/
|
||||
1128,
|
||||
/**/
|
||||
1127,
|
||||
/**/
|
||||
1126,
|
||||
/**/
|
||||
1125,
|
||||
/**/
|
||||
1124,
|
||||
/**/
|
||||
1123,
|
||||
/**/
|
||||
1122,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user