From b55726b35075148ae29c5ae635e85a11e09e9dfa Mon Sep 17 00:00:00 2001 From: solawing <316786359@qq.com> Date: Sat, 16 May 2015 16:51:37 +0800 Subject: edit.c: fix flicker in popup menu --- src/nvim/edit.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/src/nvim/edit.c b/src/nvim/edit.c index dbbcf4f1b9..f0b79110ea 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2928,11 +2928,16 @@ static void ins_compl_new_leader(void) else { spell_bad_len = 0; /* need to redetect bad word */ /* - * Matches were cleared, need to search for them now. First display - * the changed text before the cursor. Set "compl_restarting" to - * avoid that the first match is inserted. + * Matches were cleared, need to search for them now. + * If it's user complete function and refresh_always, + * not use "compl_leader" as prefix filter. + * Set "compl_restarting" to avoid that the first match is inserted. */ - update_screen(0); + if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) + && compl_opt_refresh_always){ + xfree(compl_leader); + compl_leader = NULL; + } compl_restarting = TRUE; if (ins_complete(Ctrl_N) == FAIL) compl_cont_status = 0; @@ -2976,11 +2981,13 @@ static void ins_compl_addleader(int c) (*mb_char2bytes)(c, buf); buf[cc] = NUL; ins_char_bytes(buf, cc); - if (compl_opt_refresh_always) + if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) + && compl_opt_refresh_always) AppendToRedobuff(buf); } else { ins_char(c); - if (compl_opt_refresh_always) + if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) + && compl_opt_refresh_always) AppendCharToRedobuff(c); } @@ -2988,15 +2995,10 @@ static void ins_compl_addleader(int c) if (ins_compl_need_restart()) ins_compl_restart(); - /* When 'always' is set, don't reset compl_leader. While completing, - * cursor doesn't point original position, changing compl_leader would - * break redo. */ - if (!compl_opt_refresh_always) { - xfree(compl_leader); - compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col, - (int)(curwin->w_cursor.col - compl_col)); - ins_compl_new_leader(); - } + xfree(compl_leader); + compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col, + (int)(curwin->w_cursor.col - compl_col)); + ins_compl_new_leader(); } /* @@ -3005,6 +3007,10 @@ static void ins_compl_addleader(int c) */ static void ins_compl_restart(void) { + /* update screen before restart. + * so if complete is blocked, + * will stay to the last popup menu and reduce flick */ + update_screen(0); ins_compl_free(); compl_started = FALSE; compl_matches = 0; -- cgit From edb5fb88aae686dd6949cd074595318e9f998676 Mon Sep 17 00:00:00 2001 From: solawing <316786359@qq.com> Date: Tue, 5 Jan 2016 11:23:41 +0800 Subject: edit.c: fix incorrect redo buffer --- src/nvim/edit.c | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/nvim/edit.c b/src/nvim/edit.c index f0b79110ea..434a26b58d 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -2464,6 +2464,14 @@ void ins_compl_show_pum(void) /* Need to build the popup menu list. */ compl_match_arraysize = 0; compl = compl_first_match; + /* + * If it's user complete function and refresh_always, + * not use "compl_leader" as prefix filter. + */ + if (ins_compl_need_restart()){ + xfree(compl_leader); + compl_leader = NULL; + } if (compl_leader != NULL) lead_len = (int)STRLEN(compl_leader); do { @@ -2929,15 +2937,8 @@ static void ins_compl_new_leader(void) spell_bad_len = 0; /* need to redetect bad word */ /* * Matches were cleared, need to search for them now. - * If it's user complete function and refresh_always, - * not use "compl_leader" as prefix filter. * Set "compl_restarting" to avoid that the first match is inserted. */ - if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) - && compl_opt_refresh_always){ - xfree(compl_leader); - compl_leader = NULL; - } compl_restarting = TRUE; if (ins_complete(Ctrl_N) == FAIL) compl_cont_status = 0; @@ -2949,8 +2950,9 @@ static void ins_compl_new_leader(void) /* Show the popup menu with a different set of matches. */ ins_compl_show_pum(); - /* Don't let Enter select the original text when there is no popup menu. */ - if (compl_match_array == NULL) + /* Don't let Enter select the original text when there is no popup menu. + * Don't let Enter select when use user function and refresh_always is set */ + if (compl_match_array == NULL || ins_compl_need_restart()) compl_enter_selects = FALSE; } @@ -2981,14 +2983,8 @@ static void ins_compl_addleader(int c) (*mb_char2bytes)(c, buf); buf[cc] = NUL; ins_char_bytes(buf, cc); - if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) - && compl_opt_refresh_always) - AppendToRedobuff(buf); } else { ins_char(c); - if ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) - && compl_opt_refresh_always) - AppendCharToRedobuff(c); } /* If we didn't complete finding matches we must search again. */ @@ -3009,7 +3005,7 @@ static void ins_compl_restart(void) { /* update screen before restart. * so if complete is blocked, - * will stay to the last popup menu and reduce flick */ + * will stay to the last popup menu and reduce flicker */ update_screen(0); ins_compl_free(); compl_started = FALSE; -- cgit From fd14f64e26cda66b2661bafb4da1626c7d0aaad7 Mon Sep 17 00:00:00 2001 From: solawing <316786359@qq.com> Date: Fri, 29 Jan 2016 21:56:20 +0800 Subject: tests: add always complete test --- test/functional/viml/completion_spec.lua | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua index 12f542de7f..892a40fbf6 100644 --- a/test/functional/viml/completion_spec.lua +++ b/test/functional/viml/completion_spec.lua @@ -100,4 +100,43 @@ describe('completion', function() eq('', eval('getline(3)')) end) end) + describe('with always option', function () + before_each(function () + source([[ +function! TestCompletion(findstart, base) abort + if a:findstart + let line = getline('.') + let start = col('.') - 1 + while start > 0 && line[start - 1] =~ '\a' + let start -= 1 + endwhile + return start + else + let ret = [] + for m in split("January February March April May June July Auguest September October November December") + if m =~ a:base " match by regex + call add(ret, m) + endif + endfor + return {'words':ret, 'refresh':'always'} + endif +endfunction + +set completeopt=menuone,noselect +set completefunc=TestCompletion + ]]) + end ) + + it('should complete when add more char', function () + -- to select first word after input char: + -- work, not work. + -- but work. there may have some bugs with + feed('igu') + eq('Auguest', eval('getline(1)')) + end) + it("shouldn't break repeat", function () + feed('oJaun', '.') + eq('June', eval('getline(3)')) + end) + end) end) -- cgit From 7567afbbe50ad82880fdc07b90e892e7d8bb9198 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sat, 13 Feb 2016 15:20:13 -0500 Subject: test: completion_spec: minor edits --- test/functional/viml/completion_spec.lua | 66 ++++++++++++++++---------------- 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua index 892a40fbf6..4bb9707cda 100644 --- a/test/functional/viml/completion_spec.lua +++ b/test/functional/viml/completion_spec.lua @@ -2,7 +2,7 @@ local helpers = require('test.functional.helpers') local clear, feed = helpers.clear, helpers.feed local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq -local execute, source = helpers.execute, helpers.source +local execute, source, expect = helpers.execute, helpers.source, helpers.expect describe('completion', function() before_each(function() @@ -100,43 +100,45 @@ describe('completion', function() eq('', eval('getline(3)')) end) end) - describe('with always option', function () - before_each(function () + + describe("refresh:always", function() + before_each(function() source([[ -function! TestCompletion(findstart, base) abort - if a:findstart - let line = getline('.') - let start = col('.') - 1 - while start > 0 && line[start - 1] =~ '\a' - let start -= 1 - endwhile - return start - else - let ret = [] - for m in split("January February March April May June July Auguest September October November December") - if m =~ a:base " match by regex - call add(ret, m) - endif - endfor - return {'words':ret, 'refresh':'always'} - endif -endfunction + function! TestCompletion(findstart, base) abort + if a:findstart + let line = getline('.') + let start = col('.') - 1 + while start > 0 && line[start - 1] =~ '\a' + let start -= 1 + endwhile + return start + else + let ret = [] + for m in split("January February March April May June July August September October November December") + if m =~ a:base " match by regex + call add(ret, m) + endif + endfor + return {'words':ret, 'refresh':'always'} + endif + endfunction -set completeopt=menuone,noselect -set completefunc=TestCompletion + set completeopt=menuone,noselect + set completefunc=TestCompletion ]]) end ) - it('should complete when add more char', function () - -- to select first word after input char: - -- work, not work. - -- but work. there may have some bugs with - feed('igu') - eq('Auguest', eval('getline(1)')) + it('completes on each input char', function () + feed('igu') + expect('August') end) - it("shouldn't break repeat", function () - feed('oJaun', '.') - eq('June', eval('getline(3)')) + it("repeats correctly after backspace #2674", function () + feed('oJa') + feed('.') + expect([[ + + June + June]]) end) end) end) -- cgit