I found a discrepancy between the two methods for custom insert-mode completion,
'completefunc' and complete(). The latter doesn't respect the ':set
completeopt+=longest' setting; its completions always expand to the first match,
not just the longest common text of matches.
I see no reason for not observing that setting, and think that this is a bug in
the complete() function.
This can be reproduced starting from Vim 7.0 up to 7.2.323, on Windows/x86 and
Linux/x86.
To reproduce, source attached file, which contains both types of
(calendar-month) completion functions, taken from the Vim help:
vim -N -u NONE
:source complete(func).vim
iM<F5><CR>
M<F6><CR><Esc>
" Both complete() and 'completefunc' expand to the first match, "March".
:set completeopt+=longest
iM<F5><CR>
M<F6><CR>
" complete() still expands to the full first match, "March".
" 'completefunc' correctly just inserts the longest common string, "Ma".
-- regards, ingo
PS: Speaking of discrepancies, another glaring one is that complete() takes
{startCol}, so range is [1, col('.')], but 'completefunc' has a zero-based range
of [0, col('.')[. Sadly, it would be even more stupid to change any of those two
now to correct the inconsistency.
--
-- Ingo Karkat -- /^-- /^-- /^-- /^-- /^-- /^-- http://ingo-karkat.de/ --
-- http://vim.sourceforge.net/account/profile.php?user_id=9713 --
> Hi Vim developers,
>
> I found a discrepancy between the two methods for custom insert-mode
> completion, 'completefunc' and complete(). The latter doesn't respect
> the ':set completeopt+=longest' setting; its completions always expand
> to the first match, not just the longest common text of matches. I
> see no reason for not observing that setting, and think that this is a
> bug in the complete() function.
No, this works as intended. The whole idea of complete() is that the
script has full control over the matches. If you want to return the
longest matching text, then pass that to complete().
'completefunc' and complete() are intentionally different. Otherwise we
could omit one of them.
--
From "know your smileys":
C=}>;*{)) Drunk, devilish chef with a toupee in an updraft,
a mustache, and a double chin
/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
At least the way I use completion, 'completeopt=longest' is orthogonal to the
content and number of matches. Take the calendar-month example I used. When I
type "M", and perform completion, it'll offer "March" and "May"; by default (no
"longest"), the first match "March" is inserted.
I use 'completeopt=longest' to have only "Ma" inserted, so that I can refine and
select the match by typing additional letters instead of repeating CTRL-N to go
through all matches sequentially.
If my script passed only the common text "Ma" on completion, I would lose the
ability to preview all matches (via the "match n of m" message and the popup
menu), and would then have to re-start the custom completion in order to complete.
So, in my daily use 'completeopt=longest' is just a preference that allows to
gradually refine the number of matches while avoiding sequential browsing
through the list of matches, it has nothing to do with what kind of matches are
displayed.
> 'completefunc' and complete() are intentionally different. Otherwise we
> could omit one of them.
Yes, there's quite some overlap; the way I've seen it, complete() offers a
simple interface for short lists of matches, while 'completefunc' is for more
complex implementations that may search multiple buffers for matches and
gradually build up the matches via complete_add().
If the behavior of 'completeopt=longest' is the actual difference, I wonder
whether it's not possible to emulate that by temporarily modifying the
'completeopt' value before invoking complete() (and why this fact isn't
mentioned in the help ;-).
I can probably re-write my script to use 'completefunc', so this isn't a serious
issue. In any case, thanks for clarifying this, Bram!
-- regards, ingo
After some more days of contemplation, I still find this behavior odd. Bram, can
your standpoint be paraphased as such: complete() doesn't respect
'completeopt=longest', because it may result in only partial insertion of match
text, and complete() should always offer the script full control over what is
inserted.
(But then, what's the point of protecting the inserted match; I can always use
<BS> to partially remove text from the match after completion?! And, if a script
really wants this, it could temporarily remove 'longest' from 'completeopt' to
achieve this. Are there any examples where this is useful?)
Please give me a short note if you won't consider changing this; I will then
submit a patch for the help, as I think this special behavior needs to be
mentioned somewhere.
-- regards, ingo
You can try changing the source code to make it work like you want.
Problem is that the insert completion is a bit of a mess and very hard
to understand. I rather leave it alone.
Perhaps you can insert this line:
compl_get_longest = (vim_strchr(p_cot, 'l') != NULL);
near the end of set_completion(). Might work, might break some
things...
--
hundred-and-one symptoms of being an internet addict:
123. You ask the car dealer to install an extra cigarette lighter
on your new car to power your notebook.
All right, so my reasoning isn't totally off and you're open to changes in this
area. Thanks!
As I mentioned, it's quite easy to switch to 'completefunc' to work around this
issue. But anyway, I put it on my list to look into next time I dig into Vim's
sources. (I'm more into Vim scripting.) This might warrant a low-priority entry
on todo.txt, too, so that maybe someone else is inclined to consider this.
> the insert completion is a bit of a mess
Sorry to hear; this is such a great and powerful feature.
-- regards, ingo