Hello. This is more a question to experts than finalized patch: I am not sure that my approach is correct and it breaks one test, but I attach the patch, just to clarify what I mean to do.
The problem I encoutered when whole-line completion started to consider other buffers is that it is not easy to match the line later in the current file. For example, if I have file like this: ----------- line1 l_ line2 ----------- and press ^X^L, it substitutes the previous line, line1. Then, by double-pressing ^N, I expect it to go to other direction and substitute line2. But in fact it starts to suggest matches from other files. I traced edit.c a little and found that it puts all matches into a double linked list, starting with compl_first_match. It first walks the current buffer in direction of search (backward for whole line case), then wraps to the other part, the continues to other buffers. When the buffer reverses, the last source become the first, and the on which is accessible immediately will appear somewhere in the end of list. To fix it, I attempted to put the insertion position to the wrapping position in the resulted list when buffer switched from current to a next one. It looks like it helped, but has broken test32. I have not yet investigated what happened there - the test format is not easy to follow. The patch is attached. There are the change and tests which should assert the desired behavior. Thanks, Max -- -- 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 vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
From 4ba010b203efcc5941df1609b31807dd0f443acf Mon Sep 17 00:00:00 2001 From: Max Kirillov <m...@max630.net> Date: Tue, 13 Aug 2013 20:40:51 +0300 Subject: [PATCH] [RFC] completion: propose matches from the current buffer first when direction switches NB: this change has broken test32 When there is a file like 'wordA w_ wordB' (_ is cursor), and ^P^N^N (or ^X^L^N^N) is pressed, wordB should be suggested instead of matches from further sources in 'cpt'. For this purpose, when ins_compl_get_exp() goes from current buffer to nex one, compl_curr_match in moved to the point where the current buffer has wrapped. --- src/edit.c | 24 ++++++++++++++++++++++++ src/testdir/test100.in | 24 ++++++++++++++++++++++++ src/testdir/test100.ok | 1 + src/testdir/test101.in | 24 ++++++++++++++++++++++++ src/testdir/test101.ok | 1 + src/testdir/test99.in | 25 +++++++++++++++++++++++++ src/testdir/test99.ok | 2 ++ 7 files changed, 101 insertions(+) create mode 100644 src/testdir/test100.in create mode 100644 src/testdir/test100.ok create mode 100644 src/testdir/test101.in create mode 100644 src/testdir/test101.ok create mode 100644 src/testdir/test99.in create mode 100644 src/testdir/test99.ok diff --git a/src/edit.c b/src/edit.c index b76ebe5..999e34d 100644 --- a/src/edit.c +++ b/src/edit.c @@ -4145,6 +4145,20 @@ ins_compl_add_tv(tv, dir) } #endif +static int compare_pos(const pos_T *pos1, const pos_T *pos2) +{ + if (pos1->lnum < pos2->lnum) + return -1; + else if (pos1->lnum > pos2->lnum) + return 1; + if (pos1->col < pos2->col) + return -1; + else if (pos1->col > pos2->col) + return 1; + else + return 0; +} + /* * Get the next expansion(s), using "compl_pattern". * The search starts at position "ini" in curbuf and in the direction @@ -4179,6 +4193,7 @@ ins_compl_get_exp(ini) char_u *dict = NULL; int dict_f = 0; compl_T *old_match; + compl_T *current_buffer_wrapped_here = NULL; if (!compl_started) { @@ -4279,6 +4294,9 @@ ins_compl_get_exp(ini) else type = -1; + if (*e_cpt == '.' && current_buffer_wrapped_here != NULL) + compl_curr_match = current_buffer_wrapped_here; + current_buffer_wrapped_here = NULL; /* in any case e_cpt is advanced to the next entry */ (void)copy_option_part(&e_cpt, IObuff, IOSIZE, ","); @@ -4392,6 +4410,7 @@ ins_compl_get_exp(ini) for (;;) { int flags = 0; + pos_T old_pos = *pos; ++msg_silent; /* Don't want messages for wrapscan. */ @@ -4406,6 +4425,11 @@ ins_compl_get_exp(ini) compl_direction, compl_pattern, 1L, SEARCH_KEEP + SEARCH_NFMSG, RE_LAST, (linenr_T)0, NULL); + if (*e_cpt == '.' && found_new_match != FAIL + && ((compl_direction == FORWARD && compare_pos(&old_pos, pos) >= 0) + || (compl_direction == BACKWARD && compare_pos(&old_pos, pos) <= 0))) { + current_buffer_wrapped_here = compl_curr_match; + } --msg_silent; if (!compl_started) { diff --git a/src/testdir/test100.in b/src/testdir/test100.in new file mode 100644 index 0000000..d725d81 --- /dev/null +++ b/src/testdir/test100.in @@ -0,0 +1,24 @@ +aaaa + +STARTTEST +:e Xfile2 +:a +line5 +line6 +. +:w +:split Xfile1 +:a +line1 +line2 +l +line3 +line4 +. +:w +:3 +0c$l$a:.w test.out +:qa! +ENDTEST + +aaa diff --git a/src/testdir/test100.ok b/src/testdir/test100.ok new file mode 100644 index 0000000..dc3f36e --- /dev/null +++ b/src/testdir/test100.ok @@ -0,0 +1 @@ +line3 diff --git a/src/testdir/test101.in b/src/testdir/test101.in new file mode 100644 index 0000000..368cc57 --- /dev/null +++ b/src/testdir/test101.in @@ -0,0 +1,24 @@ +aaaa + +STARTTEST +:e Xfile2 +:a +line5 +line6 +. +:w +:split Xfile1 +:a +line1 +line2 +l +line3 +line4 +. +:w +:3 +0c$l$a:.w test.out +:qa! +ENDTEST + +aaa diff --git a/src/testdir/test101.ok b/src/testdir/test101.ok new file mode 100644 index 0000000..dc3f36e --- /dev/null +++ b/src/testdir/test101.ok @@ -0,0 +1 @@ +line3 diff --git a/src/testdir/test99.in b/src/testdir/test99.in new file mode 100644 index 0000000..58dda9a --- /dev/null +++ b/src/testdir/test99.in @@ -0,0 +1,25 @@ +aaaa + +STARTTEST +:e Xfile2 +:a +line5 +line6 +. +:w +:split Xfile1 +:a +line1 +line2 +l +line3 +line4 +. +:w +:3 +$a:.w test.out +0c$l$a:.w >>test.out +:qa! +ENDTEST + +aaa diff --git a/src/testdir/test99.ok b/src/testdir/test99.ok new file mode 100644 index 0000000..1e4b716 --- /dev/null +++ b/src/testdir/test99.ok @@ -0,0 +1,2 @@ +line2 +l -- 1.7.10.4