]> granicus.if.org Git - vim/commitdiff
patch 8.1.0815: dialog for file changed outside of Vim not tested v8.1.0815
authorBram Moolenaar <Bram@vim.org>
Thu, 24 Jan 2019 20:58:10 +0000 (21:58 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 24 Jan 2019 20:58:10 +0000 (21:58 +0100)
Problem:    Dialog for file changed outside of Vim not tested.
Solution:   Add a test.  Move FileChangedShell test.  Add 'L' flag to
            feedkeys().

runtime/doc/eval.txt
src/evalfunc.c
src/testdir/Make_all.mak
src/testdir/test_autocmd.vim
src/testdir/test_filechanged.vim [new file with mode: 0644]
src/version.c

index 3db9151c65c4366a2635b408d519669f8f2d5596..c41fdcee1bb48ce3ccb55dfb871e16dcc50d3507 100644 (file)
@@ -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
index 5bba7eaf067c50b9618520bd6fc8acbf90e391d6..269423f9291a35a9fd3c2e9899e9a17ec8c83fba 100644 (file)
@@ -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
index 8ed4642298cc3031deaee54ed551ba3c73692dfe..39b6889112738482207f2e6647a34350a476a5d8 100644 (file)
@@ -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 \
index 6f27fe512c584a0340828f8a258e4b6b7b2faea4..0eabc2e30b0b74788c1c1d49da5b568cce3e9242 100644 (file)
@@ -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 (file)
index 0000000..ab34420
--- /dev/null
@@ -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
index 980501532bc5301516dc041971a77b9d8c1293d1..d69c3cb0eee52339da9e11250e2ead8561c2abf2 100644 (file)
@@ -788,7 +788,9 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
-    84,
+    815,
+/**/
+    814,
 /**/
     813,
 /**/