Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2016-01-17 21:00:42 -08:00
30 changed files with 925 additions and 227 deletions
+12 -1
View File
@@ -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
View File
@@ -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 -1
View File
@@ -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
+6 -4
View File
@@ -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
+8
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
+1
View File
@@ -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));
+1
View File
@@ -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));
+3 -2
View File
@@ -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.
+2
View File
@@ -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)
+1
View File
@@ -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:
+2
View File
@@ -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)
+1
View File
@@ -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:
+52
View File
@@ -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
+101
View File
@@ -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
+18
View File
@@ -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
-26
View File
@@ -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
-3
View File
@@ -1,3 +0,0 @@
1 changed line 1
2 line 2
abc/def/
+94
View File
@@ -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
+14
View File
@@ -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,
/**/