summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/eval.txt82
-rw-r--r--src/evalfunc.c13
-rw-r--r--src/testdir/Make_all.mak2
-rw-r--r--src/testdir/test_autocmd.vim90
-rw-r--r--src/testdir/test_filechanged.vim146
-rw-r--r--src/version.c4
6 files changed, 217 insertions, 120 deletions
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 3db9151c6..c41fdcee1 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1,4 +1,4 @@
-*eval.txt* For Vim version 8.1. Last change: 2019 Jan 21
+*eval.txt* For Vim version 8.1. Last change: 2019 Jan 24
VIM REFERENCE MANUAL by Bram Moolenaar
@@ -662,6 +662,16 @@ is not available it returns -1 or the default value you specify: >
:echo get(myblob, idx, 999)
+Blob iteration ~
+
+The |:for| loop executes commands for each byte of a Blob. The loop variable is
+set to each byte in the Blob. Example: >
+ :for byte in 0z112233
+ : call Doit(byte)
+ :endfor
+This calls Doit() with 0x11, 0x22 and 0x33.
+
+
Blob concatenation ~
Two blobs can be concatenated with the "+" operator: >
@@ -793,8 +803,9 @@ Expression syntax summary, from least to most significant:
etc. As above, append ? for ignoring case, # for
matching case
- expr5 is expr5 same |List| instance
- expr5 isnot expr5 different |List| instance
+ expr5 is expr5 same |List|, |Dictionary| or |Blob| instance
+ expr5 isnot expr5 different |List|, |Dictionary| or |Blob|
+ instance
|expr5| expr6
expr6 + expr6 .. number addition, list or blob concatenation
@@ -962,12 +973,12 @@ Dictionary and arguments, use |get()| to get the function name: >
if get(Part1, 'name') == get(Part2, 'name')
" Part1 and Part2 refer to the same function
-When using "is" or "isnot" with a |List| or a |Dictionary| this checks if the
-expressions are referring to the same |List| or |Dictionary| instance. A copy
-of a |List| is different from the original |List|. When using "is" without
-a |List| or a |Dictionary| it is equivalent to using "equal", using "isnot"
-equivalent to using "not equal". Except that a different type means the
-values are different: >
+Using "is" or "isnot" with a |List|, |Dictionary| or |Blob| checks whether
+the expressions are referring to the same |List|, |Dictionary| or |Blob|
+instance. A copy of a |List| is different from the original |List|. When
+using "is" without a |List|, |Dictionary| or |Blob|, it is equivalent to
+using "equal", using "isnot" equivalent to using "not equal". Except that
+a different type means the values are different: >
echo 4 == '4'
1
echo 4 is '4'
@@ -1012,16 +1023,16 @@ can be matched like an ordinary character. Examples:
expr5 and expr6 *expr5* *expr6*
---------------
-expr6 + expr6 .. Number addition or |List| concatenation *expr-+*
-expr6 - expr6 .. Number subtraction *expr--*
-expr6 . expr6 .. String concatenation *expr-.*
+expr6 + expr6 Number addition, |List| or |Blob| concatenation *expr-+*
+expr6 - expr6 Number subtraction *expr--*
+expr6 . expr6 String concatenation *expr-.*
For |Lists| only "+" is possible and then both expr6 must be a list. The
result is a new list with the two lists Concatenated.
-expr7 * expr7 .. Number multiplication *expr-star*
-expr7 / expr7 .. Number division *expr-/*
-expr7 % expr7 .. Number modulo *expr-%*
+expr7 * expr7 Number multiplication *expr-star*
+expr7 / expr7 Number division *expr-/*
+expr7 % expr7 Number modulo *expr-%*
For all, except ".", Strings are converted to Numbers.
For bitwise operators see |and()|, |or()| and |xor()|.
@@ -4121,6 +4132,9 @@ feedkeys({string} [, {mode}]) *feedkeys()*
't' Handle keys as if typed; otherwise they are handled as
if coming from a mapping. This matters for undo,
opening folds, etc.
+ 'L' Lowlevel input. Only works for Unix or when using the
+ GUI. Keys are used as if they were coming from the
+ terminal. Other flags are not used. *E980*
'i' Insert the string instead of appending (see above).
'x' Execute commands until typeahead is empty. This is
similar to using ":normal!". You can call feedkeys()
@@ -5740,6 +5754,10 @@ job_start({command} [, {options}]) *job_start()*
|:!cmd| this does not wait for the job to finish.
To start a job in a terminal window see |term_start()|.
+ If the job fails to start then |job_status()| on the returned
+ Job object results in "fail" and none of the callbacks will be
+ invoked.
+
{command} can be a String. This works best on MS-Windows. On
Unix it is split up in white-separated parts to be passed to
execvp(). Arguments in double quotes can contain white space.
@@ -11044,28 +11062,34 @@ This does NOT work: >
NOTE: The ":append" and ":insert" commands don't work
properly inside a ":while" and ":for" loop.
-:for {var} in {list} *:for* *E690* *E732*
+:for {var} in {object} *:for* *E690* *E732*
:endfo[r] *:endfo* *:endfor*
Repeat the commands between ":for" and ":endfor" for
- each item in {list}. Variable {var} is set to the
- value of each item.
- When an error is detected for a command inside the
- loop, execution continues after the "endfor".
- Changing {list} inside the loop affects what items are
- used. Make a copy if this is unwanted: >
+ each item in {object}. {object} can be a |List| or
+ a |Blob|. Variable {var} is set to the value of each
+ item. When an error is detected for a command inside
+ the loop, execution continues after the "endfor".
+ Changing {object} inside the loop affects what items
+ are used. Make a copy if this is unwanted: >
:for item in copy(mylist)
-< When not making a copy, Vim stores a reference to the
- next item in the list, before executing the commands
- with the current item. Thus the current item can be
- removed without effect. Removing any later item means
- it will not be found. Thus the following example
- works (an inefficient way to make a list empty): >
+<
+ When {object} is a |List| and not making a copy, Vim
+ stores a reference to the next item in the |List|
+ before executing the commands with the current item.
+ Thus the current item can be removed without effect.
+ Removing any later item means it will not be found.
+ Thus the following example works (an inefficient way
+ to make a |List| empty): >
for item in mylist
call remove(mylist, 0)
endfor
-< Note that reordering the list (e.g., with sort() or
+< Note that reordering the |List| (e.g., with sort() or
reverse()) may have unexpected effects.
+ When {object} is a |Blob|, Vim always makes a copy to
+ iterate over. Unlike with |List|, modifying the
+ |Blob| does not affect the iteration.
+
:for [{var1}, {var2}, ...] in {listlist}
:endfo[r]
Like ":for" above, but each item in {listlist} must be
diff --git a/src/evalfunc.c b/src/evalfunc.c
index 5bba7eaf0..269423f92 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -3674,6 +3674,7 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
int typed = FALSE;
int execute = FALSE;
int dangerous = FALSE;
+ int lowlevel = FALSE;
char_u *keys_esc;
/* This is not allowed in the sandbox. If the commands would still be
@@ -3697,6 +3698,7 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
case 'i': insert = TRUE; break;
case 'x': execute = TRUE; break;
case '!': dangerous = TRUE; break;
+ case 'L': lowlevel = TRUE; break;
}
}
}
@@ -3708,7 +3710,16 @@ f_feedkeys(typval_T *argvars, typval_T *rettv UNUSED)
keys_esc = vim_strsave_escape_csi(keys);
if (keys_esc != NULL)
{
- ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
+ if (lowlevel)
+ {
+#ifdef USE_INPUT_BUF
+ add_to_input_buf(keys, (int)STRLEN(keys));
+#else
+ emsg(_("E980: lowlevel input not supported"));
+#endif
+ }
+ else
+ ins_typebuf(keys_esc, (remap ? REMAP_YES : REMAP_NONE),
insert ? 0 : typebuf.tb_len, !typed, FALSE);
vim_free(keys_esc);
if (vgetc_busy
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index 8ed464229..39b688911 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -121,6 +121,7 @@ NEW_TESTS = \
test_feedkeys \
test_file_perm \
test_file_size \
+ test_filechanged \
test_fileformat \
test_filetype \
test_filter_cmd \
@@ -316,6 +317,7 @@ NEW_TESTS_RES = \
test_exit.res \
test_farsi.res \
test_file_size.res \
+ test_filechanged.res \
test_find_complete.res \
test_fixeol.res \
test_fnameescape.res \
diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index 6f27fe512..0eabc2e30 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -1386,92 +1386,4 @@ func Test_Changed_FirstTime()
bwipe!
endfunc
-func Test_FileChangedShell_reload()
- if !has('unix')
- return
- endif
- augroup testreload
- au FileChangedShell Xchanged let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
- augroup END
- new Xchanged
- call setline(1, 'reload this')
- write
- " Need to wait until the timestamp would change by at least a second.
- sleep 2
- silent !echo 'extra line' >>Xchanged
- checktime
- call assert_equal('changed', g:reason)
- call assert_equal(2, line('$'))
- call assert_equal('extra line', getline(2))
-
- " Only triggers once
- let g:reason = ''
- checktime
- call assert_equal('', g:reason)
-
- " When deleted buffer is not reloaded
- silent !rm Xchanged
- let g:reason = ''
- checktime
- call assert_equal('deleted', g:reason)
- call assert_equal(2, line('$'))
- call assert_equal('extra line', getline(2))
-
- " When recreated buffer is reloaded
- call setline(1, 'buffer is changed')
- silent !echo 'new line' >>Xchanged
- let g:reason = ''
- checktime
- call assert_equal('conflict', g:reason)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- " Only mode changed
- silent !chmod +x Xchanged
- let g:reason = ''
- checktime
- call assert_equal('mode', g:reason)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- " Only time changed
- sleep 2
- silent !touch Xchanged
- let g:reason = ''
- checktime
- call assert_equal('time', g:reason)
- call assert_equal(1, line('$'))
- call assert_equal('new line', getline(1))
-
- if has('persistent_undo')
- " With an undo file the reload can be undone and a change before the
- " reload.
- set undofile
- call setline(2, 'before write')
- write
- call setline(2, 'after write')
- sleep 2
- silent !echo 'different line' >>Xchanged
- let g:reason = ''
- checktime
- call assert_equal('conflict', g:reason)
- call assert_equal(3, line('$'))
- call assert_equal('before write', getline(2))
- call assert_equal('different line', getline(3))
- " undo the reload
- undo
- call assert_equal(2, line('$'))
- call assert_equal('after write', getline(2))
- " undo the change before reload
- undo
- call assert_equal(2, line('$'))
- call assert_equal('before write', getline(2))
-
- set noundofile
- endif
-
-
- au! testreload
- bwipe!
- call delete('Xchanged')
-endfunc
+" FileChangedShell tested in test_filechanged.vim
diff --git a/src/testdir/test_filechanged.vim b/src/testdir/test_filechanged.vim
new file mode 100644
index 000000000..ab34420b4
--- /dev/null
+++ b/src/testdir/test_filechanged.vim
@@ -0,0 +1,146 @@
+" Tests for when a file was changed outside of Vim.
+
+func Test_FileChangedShell_reload()
+ if !has('unix')
+ return
+ endif
+ augroup testreload
+ au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
+ augroup END
+ new Xchanged_r
+ call setline(1, 'reload this')
+ write
+ " Need to wait until the timestamp would change by at least a second.
+ sleep 2
+ silent !echo 'extra line' >>Xchanged_r
+ checktime
+ call assert_equal('changed', g:reason)
+ call assert_equal(2, line('$'))
+ call assert_equal('extra line', getline(2))
+
+ " Only triggers once
+ let g:reason = ''
+ checktime
+ call assert_equal('', g:reason)
+
+ " When deleted buffer is not reloaded
+ silent !rm Xchanged_r
+ let g:reason = ''
+ checktime
+ call assert_equal('deleted', g:reason)
+ call assert_equal(2, line('$'))
+ call assert_equal('extra line', getline(2))
+
+ " When recreated buffer is reloaded
+ call setline(1, 'buffer is changed')
+ silent !echo 'new line' >>Xchanged_r
+ let g:reason = ''
+ checktime
+ call assert_equal('conflict', g:reason)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ " Only mode changed
+ silent !chmod +x Xchanged_r
+ let g:reason = ''
+ checktime
+ call assert_equal('mode', g:reason)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ " Only time changed
+ sleep 2
+ silent !touch Xchanged_r
+ let g:reason = ''
+ checktime
+ call assert_equal('time', g:reason)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ if has('persistent_undo')
+ " With an undo file the reload can be undone and a change before the
+ " reload.
+ set undofile
+ call setline(2, 'before write')
+ write
+ call setline(2, 'after write')
+ sleep 2
+ silent !echo 'different line' >>Xchanged_r
+ let g:reason = ''
+ checktime
+ call assert_equal('conflict', g:reason)
+ call assert_equal(3, line('$'))
+ call assert_equal('before write', getline(2))
+ call assert_equal('different line', getline(3))
+ " undo the reload
+ undo
+ call assert_equal(2, line('$'))
+ call assert_equal('after write', getline(2))
+ " undo the change before reload
+ undo
+ call assert_equal(2, line('$'))
+ call assert_equal('before write', getline(2))
+
+ set noundofile
+ endif
+
+ au! testreload
+ bwipe!
+ call delete('Xchanged_r')
+endfunc
+
+func Test_file_changed_dialog()
+ if !has('unix')
+ return
+ endif
+ au! FileChangedShell
+
+ new Xchanged_d
+ call setline(1, 'reload this')
+ write
+ " Need to wait until the timestamp would change by at least a second.
+ sleep 2
+ silent !echo 'extra line' >>Xchanged_d
+ call feedkeys('L', 'L')
+ checktime
+ call assert_match('W11:', v:warningmsg)
+ call assert_equal(2, line('$'))
+ call assert_equal('reload this', getline(1))
+ call assert_equal('extra line', getline(2))
+
+ " delete buffer, only shows an error, no prompt
+ silent !rm Xchanged_d
+ checktime
+ call assert_match('E211:', v:warningmsg)
+ call assert_equal(2, line('$'))
+ call assert_equal('extra line', getline(2))
+
+ " Recreate buffer and reload
+ call setline(1, 'buffer is changed')
+ silent !echo 'new line' >Xchanged_d
+ call feedkeys('L', 'L')
+ checktime
+ call assert_match('W12:', v:warningmsg)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ " Only mode changed, reload
+ silent !chmod +x Xchanged_d
+ call feedkeys('L', 'L')
+ checktime
+ call assert_match('W16:', v:warningmsg)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ " Only time changed, no prompt
+ sleep 2
+ silent !touch Xchanged_d
+ let v:warningmsg = ''
+ checktime
+ call assert_equal('', v:warningmsg)
+ call assert_equal(1, line('$'))
+ call assert_equal('new line', getline(1))
+
+ bwipe!
+ call delete('Xchanged_d')
+endfunc
diff --git a/src/version.c b/src/version.c
index 980501532..d69c3cb0e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -788,7 +788,9 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
- 84,
+ 815,
+/**/
+ 814,
/**/
813,
/**/