When user complete function return like below...

{"words": [...], "refresh": "always"}

vim call user complete function again immediately. If the function return 
-1, completion will be canceled.

For example,
----------
int documentation;
int document;
----------

Type '/m<cr>cw'. When user complete function work on this time, and show 
following candidates:
This is meaning: returned findstart=4, and return following:

----------
{"words": ["documentation", "document"], "refresh": "always"}
----------

When user type 'a' which is not match for candidates, it call user comlete 
function again.
If user complete function return -1 for this, "." register will be broken.

When 'a' was typed, ins_compl_addleader() is called. 
in ins_compl_addleader(), compl_leader is reset all times.
But compl_leader must not reset for 'always'. 'always' re-call user 
complete function with findstart=1. So it break
compl_col and curs_col. i.e. "." register will be broken.

Patch is here: https://gist.github.com/1631857
(https://raw.github.com/gist/1631857/gistfile1.diff)

And I found a bug. When 'always' is returned and returned -1 for 
findstart=1, candidates will empty.
Then, if type <c-n> key to select next item(or call feedkeys() to do that), 
vim crash in ins_compl_next().

diff -r 0dabc2ce136c src/edit.c
--- a/src/edit.c        Tue Jan 10 22:31:32 2012 +0100
+++ b/src/edit.c        Wed Jan 18 16:55:02 2012 +0900
@@ -3465,11 +3465,17 @@
     if (ins_compl_need_restart())
        ins_compl_restart();
 
-    vim_free(compl_leader);
-    compl_leader = vim_strnsave(ml_get_curline() + compl_col,
-                                    (int)(curwin->w_cursor.col - compl_col));
-    if (compl_leader != NULL)
-       ins_compl_new_leader();
+    /* When 'always' is set, don't reset compl_leader. While completing,
+     * cursor don't point original position. So if change compl_leader, it
+     * break redo register. */
+    if (!compl_opt_refresh_always)
+    {
+       vim_free(compl_leader);
+       compl_leader = vim_strnsave(ml_get_curline() + compl_col,
+                                (int)(curwin->w_cursor.col - compl_col));
+       if (compl_leader != NULL)
+           ins_compl_new_leader();
+    }
 }
 
 /*
@@ -4554,6 +4560,11 @@
     int            found_end = FALSE;
     int            advance;
 
+    /* When user complete function return -1 for findstart which is next
+     * time of 'always'., compl_shown_match become NULL. */
+    if (compl_shown_match == NULL)
+       return -1;
+
     if (compl_leader != NULL
                        && (compl_shown_match->cp_flags & ORIGINAL_TEXT) == 0)
     {

--


- Yasuhiro Matsumoto

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

Raspunde prin e-mail lui