Hi Bram,
2015/2/9(Mon) 2:21:55 UTC+9 h_east:
> Hi Bram and Nice Vim developers,
>
> 2015/1/6(Tue) 4:58:27 UTC+9 Bram Moolenaar:
> > Yasuhiro Matsumoto wrote:
> >
> > > bug.vim
> > > -------------------
> > > set nocompatible
> > >
> > > inoremap <F5> <C-R>=ListMonths()<CR>
> > >
> > > func! ListMonths()
> > > call complete(col('.'), ['January', 'February', 'March',
> > > \ 'April', 'May', 'June', 'July', 'August', 'September',
> > > \ 'October', 'November', 'December'])
> > > return ''
> > > endfunc
> > > -------------------
> > >
> > > 1. vim -u bug.vim -N
> > >
> > > 2. press F5
> > >
> > > 3. type Ctrl-L while popup menu is visible
> > >
> > > Ctrl-L should not behave like Ctrl-P. ins_compl_key2dir() handles
> > > suffix keys after CTRL-X. And also it handles keys while popup menu is
> > > visible (ex: CTRL-P/CTRL-N). This should be cleanly separated.
> > >
> > > https://gist.github.com/mattn/2c83d5a17c9e9505e43d
> >
> > Thanks!
>
> I update a patch. (Attached to this email)
> Please check.
Oops. My previous patch had a problem. so I attached a new patch.
Please check.
>
> And ...
> I found specification inconsistency between 'complete()' and 'backspace'
> option.
>
> How to reproduce:
> 1. cat test.vim
> inoremap <F5> <C-R>=ListMonths()<CR>
>
> func! ListMonths()
> call complete(1, ['One', 'Three'])
> return ''
> endfunc
>
> 2. vim -N -u test.vim
>
> 3. Enter insert-mode and input 'ab' and leave insert-mode.
> iab<Esc>
>
> 4. Reenter insert-mode and use 'complete()'
> a<F5>
>
> 5. Delete two characters.
> <C-H><C-H>
>
> What happen.
> - '4.' Edit start columns 3, but 'complete()' starts 1 (by 1st argument).
> - '5.' Can't delete column 1 and 2
> 'backspace' option not contain "start", So vim can not deleted this.
>
> I think this is specification inconsistency.
> How Let's fix?
> (a) Occurred an error when 'complete()' first argument is can not be deleted
> by under the influence of the 'backspace' option.
>
> (b) Adjust the first argument value implicitly in f_complete(). (In this
> case, Ajust 3)
>
> (c) Between 'complete()' is functioning to ignore the 'backspace' option.
>
> I would write the patch when you are determined.
Bram, Please decide a specification.
Best regards,
Hirohito Higashi (a.k.a h_east)
--
--
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
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.
diff -r bc645ee095ea src/edit.c
--- a/src/edit.c Tue Feb 17 16:04:57 2015 +0100
+++ b/src/edit.c Wed Feb 18 00:30:14 2015 +0900
@@ -34,8 +34,10 @@
#define CTRL_X_OMNI 13
#define CTRL_X_SPELL 14
#define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */
+#define CTRL_X_EVAL 16 /* for builtin function complete() */
#define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT]
+#define CTRL_X_MODE_LINE_OR_EVAL(m) (m == CTRL_X_WHOLE_LINE || m == CTRL_X_EVAL)
static char *ctrl_x_msgs[] =
{
@@ -55,6 +57,7 @@
N_(" Omni completion (^O^N^P)"),
N_(" Spelling suggestion (s^N^P)"),
N_(" Keyword Local completion (^N^P)"),
+ NULL, /* CTRL_X_EVAL doesn't use msg. */
};
static char e_hitend[] = N_("Hit end of paragraph");
@@ -802,7 +805,7 @@
* "compl_leader". Except when at the original match and
* there is nothing to add, CTRL-L works like CTRL-P then. */
if (c == Ctrl_L
- && (ctrl_x_mode != CTRL_X_WHOLE_LINE
+ && (!CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
|| (int)STRLEN(compl_shown_match->cp_str)
> curwin->w_cursor.col - compl_col))
{
@@ -2267,6 +2270,8 @@
#endif
case CTRL_X_SPELL:
return (c == Ctrl_S || c == Ctrl_P || c == Ctrl_N);
+ case CTRL_X_EVAL:
+ return (c == Ctrl_P || c == Ctrl_N);
}
EMSG(_(e_internal));
return FALSE;
@@ -2773,8 +2778,7 @@
-1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK)
return;
- /* Handle like dictionary completion. */
- ctrl_x_mode = CTRL_X_WHOLE_LINE;
+ ctrl_x_mode = CTRL_X_EVAL;
ins_compl_add_list(list);
compl_matches = ins_compl_make_cyclic();
@@ -3060,7 +3064,7 @@
/* When invoked to match whole lines for CTRL-X CTRL-L adjust the pattern
* to only match at the start of a line. Otherwise just match the
* pattern. Also need to double backslashes. */
- if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
char_u *pat_esc = vim_strsave_escaped(pat, (char_u *)"\\");
size_t len;
@@ -3181,7 +3185,7 @@
while (vim_regexec(regmatch, buf, (colnr_T)(ptr - buf)))
{
ptr = regmatch->startp[0];
- if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
ptr = find_line_end(ptr);
else
ptr = find_word_end(ptr);
@@ -3394,7 +3398,7 @@
* allow the word to be deleted, we won't match everything. */
if ((int)(p - line) - (int)compl_col < 0
|| ((int)(p - line) - (int)compl_col == 0
- && ctrl_x_mode != CTRL_X_OMNI))
+ && ctrl_x_mode != CTRL_X_OMNI) || ctrl_x_mode == CTRL_X_EVAL)
return K_BS;
/* Deleted more than what was used to find matches or didn't finish
@@ -4208,7 +4212,7 @@
/* For ^N/^P pick a new entry from e_cpt if compl_started is off,
* or if found_all says this entry is done. For ^X^L only use the
* entries from 'complete' that look in loaded buffers. */
- if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if ((ctrl_x_mode == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
&& (!compl_started || found_all))
{
found_all = FALSE;
@@ -4261,7 +4265,7 @@
break;
else
{
- if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
type = -1;
else if (*e_cpt == 'k' || *e_cpt == 's')
{
@@ -4406,9 +4410,10 @@
++msg_silent; /* Don't want messages for wrapscan. */
- /* ctrl_x_mode == CTRL_X_WHOLE_LINE || word-wise search that
+ /* CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
+ * || word-wise search that
* has added a word that was at the beginning of the line */
- if ( ctrl_x_mode == CTRL_X_WHOLE_LINE
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)
|| (compl_cont_status & CONT_SOL))
found_new_match = search_for_exact_line(ins_buf, pos,
compl_direction, compl_pattern);
@@ -4442,7 +4447,7 @@
&& ini->col == pos->col)
continue;
ptr = ml_get_buf(ins_buf, pos->lnum, FALSE) + pos->col;
- if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
if (compl_cont_status & CONT_ADDING)
{
@@ -4536,7 +4541,7 @@
/* break the loop for specialized modes (use 'complete' just for the
* generic ctrl_x_mode == 0) or when we've found a new match */
- if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+ if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
|| found_new_match != FAIL)
{
if (got_int)
@@ -4545,7 +4550,7 @@
if (type != -1)
ins_compl_check_keys(0);
- if ((ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE)
+ if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
|| compl_interrupted)
break;
compl_started = TRUE;
@@ -4561,13 +4566,13 @@
}
compl_started = TRUE;
- if ((ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if ((ctrl_x_mode == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
&& *e_cpt == NUL) /* Got to end of 'complete' */
found_new_match = FAIL;
i = -1; /* total of matches, unknown */
if (found_new_match == FAIL
- || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_WHOLE_LINE))
+ || (ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)))
i = ins_compl_make_cyclic();
/* If several matches were added (FORWARD) or the search failed and has
@@ -5052,7 +5057,7 @@
if (compl_length < 1)
compl_cont_status &= CONT_LOCAL;
}
- else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
compl_cont_status = CONT_ADDING | CONT_N_ADDS;
else
compl_cont_status = 0;
@@ -5183,7 +5188,7 @@
}
}
}
- else if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ else if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
compl_col = (colnr_T)(skipwhite(line) - line);
compl_length = (int)curs_col - (int)compl_col;
@@ -5348,7 +5353,7 @@
if (compl_cont_status & CONT_ADDING)
{
edit_submode_pre = (char_u *)_(" Adding");
- if (ctrl_x_mode == CTRL_X_WHOLE_LINE)
+ if (CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))
{
/* Insert a new line, keep indentation but ignore 'comments' */
#ifdef FEAT_COMMENTS