[vim/vim] Fix: Prevent flicker when LSP server is slow (PR #18439)

17 views
Skip to first unread message

girish

unread,
Sep 29, 2025, 12:06:28 PM (yesterday) Sep 29
to vim/vim, Subscribed

Ref: girishji/vimcomplete#101 (comment)

In insert-mode completion, the leader text is temporarily deleted while searching for completion candidates.
If the LSP server responds slowly, the client may call :sleep to wait, which triggers out_flush().
This causes the deleted text to briefly disappear before being redrawn when results arrive, producing a visible flicker.

There are two possible fixes:

  1. Suppress flushing while a user function (e.g. LSP client) is waiting.
  2. Reinsert the deleted text before invoking the user function.

This PR implements (1), which is the simpler solution, though somewhat heavy-handed. If you think this may introduce unwanted side effects, I can rework it to use (2).


You can view, comment on, or merge this pull request online at:

  https://github.com/vim/vim/pull/18439

Commit Summary

  • f63a12d Fix: Prevent flicker when LSP server is slow

File Changes

(4 files)

Patch Links:


Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439@github.com>

girish

unread,
Sep 29, 2025, 2:24:02 PM (yesterday) Sep 29
to vim/vim, Push

@girishji pushed 2 commits.


View it on GitHub or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/before/f63a12d7db0d11671a804247df49aca92f3c1bbc/after/a52036312c06d5f953329553e4853af7cc8c1e3a@github.com>

Christian Brabandt

unread,
Sep 29, 2025, 4:48:41 PM (yesterday) Sep 29
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#18439)

thanks


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/c3348999241@github.com>

Christian Brabandt

unread,
Sep 29, 2025, 5:00:27 PM (yesterday) Sep 29
to vim/vim, Subscribed

Closed #18439 via 71b97f2.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/issue_event/19993403412@github.com>

Maxim Kim

unread,
Sep 29, 2025, 7:27:48 PM (yesterday) Sep 29
to vim/vim, Subscribed
habamax left a comment (vim/vim#18439)

Thx. It is better and worse at the same time :).


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/c3349377517@github.com>

Maxim Kim

unread,
Sep 29, 2025, 7:38:41 PM (24 hours ago) Sep 29
to vim/vim, Subscribed
habamax left a comment (vim/vim#18439)

Screencast doesn't show, but there are noticeable delays between keypress and char insertion, which feels not great.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/c3349397920@github.com>

girish

unread,
Sep 29, 2025, 9:34:40 PM (22 hours ago) Sep 29
to vim/vim, Subscribed
girishji left a comment (vim/vim#18439)

I'll look into this.


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/c3349616625@github.com>

Christian Brabandt

unread,
3:59 PM (4 hours ago) 3:59 PM
to vim/vim, Subscribed
chrisbra left a comment (vim/vim#18439)

That patch is wrong. It causes overflow of out_pos, because when no_flush is set, out_char_nf() happily writes out-of-bound because the out_pos counter is no longer reset when out_flush() is called. I'll revert this for now.

It causes segfault on MS-Windows: #18450

Stack trace:

==377936==T0: stack [0x000000e40000,0x000000f40000) size 0x100000; local=0x000000f3eec0
==377936==AddressSanitizer Init done
=================================================================
==377936==ERROR: AddressSanitizer: global-buffer-overflow on address 0x7ff61ef5c0c0 at pc 0x7ff61eb98668 bp 0x000000f35560 sp 0x000000f35568
WRITE of size 1 at 0x7ff61ef5c0c0 thread T0
    #0 0x7ff61eb98667 in out_str_nf c:\Users\Christian Brabandt\code\vim\src\term.c:2893
    #1 0x7ff61eb9dd06 in out_str c:\Users\Christian Brabandt\code\vim\src\term.c:2987
    #2 0x7ff61eb134fc in windgoto c:\Users\Christian Brabandt\code\vim\src\screen.c:3213
    #3 0x7ff61eb18907 in screen_char c:\Users\Christian Brabandt\code\vim\src\screen.c:1978
    #4 0x7ff61eb1513d in screen_puts_len c:\Users\Christian Brabandt\code\vim\src\screen.c:1501
    #5 0x7ff61ea0be19 in screen_puts_mbyte c:\Users\Christian Brabandt\code\vim\src\message.c:2238
    #6 0x7ff61ea0b2fb in msg_puts_display c:\Users\Christian Brabandt\code\vim\src\message.c:2553
    #7 0x7ff61ea0bcd8 in msg_puts_attr_len c:\Users\Christian Brabandt\code\vim\src\message.c:2362
    #8 0x7ff61ea0feb1 in msg_outtrans_len_attr c:\Users\Christian Brabandt\code\vim\src\message.c:1816
    #9 0x7ff61ea0dd4a in msg_outtrans_attr c:\Users\Christian Brabandt\code\vim\src\message.c:1696
    #10 0x7ff61ea0dd4a in msg_attr_keep c:\Users\Christian Brabandt\code\vim\src\message.c:192
    #11 0x7ff61ea10448 in msg_attr c:\Users\Christian Brabandt\code\vim\src\message.c:139
    #12 0x7ff61ea10448 in msg_source c:\Users\Christian Brabandt\code\vim\src\message.c:553
    #13 0x7ff61ea0d45e in emsg_core c:\Users\Christian Brabandt\code\vim\src\message.c:782
    #14 0x7ff61ebca4e6 in undo_allowed c:\Users\Christian Brabandt\code\vim\src\undo.c:338
    #15 0x7ff61e9b4a83 in f_complete c:\Users\Christian Brabandt\code\vim\src\insexpand.c:3877
    #16 0x7ff61e8ec29c in call_internal_func c:\Users\Christian Brabandt\code\vim\src\evalfunc.c:3497
    #17 0x7ff61ebe8cdb in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4176
    #18 0x7ff61ebe9d75 in get_func_tv c:\Users\Christian Brabandt\code\vim\src\userfunc.c:2190
    #19 0x7ff61ebd4c73 in ex_call_inner c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6510
    #20 0x7ff61ebe5264 in ex_call c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6868
    #21 0x7ff61e92a52c in do_one_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:2629
    #22 0x7ff61e931b04 in do_cmdline c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:1041
    #23 0x7ff61ebdb3d5 in call_user_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3312
    #24 0x7ff61ebda2b1 in call_user_func_check c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3485
    #25 0x7ff61ebe909c in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4158
    #26 0x7ff61ebe9d75 in get_func_tv c:\Users\Christian Brabandt\code\vim\src\userfunc.c:2190
    #27 0x7ff61ebd4c73 in ex_call_inner c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6510
    #28 0x7ff61ebe5264 in ex_call c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6868
    #29 0x7ff61e92a52c in do_one_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:2629
    #30 0x7ff61e931b04 in do_cmdline c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:1041
    #31 0x7ff61ebdb3d5 in call_user_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3312
    #32 0x7ff61ebda2b1 in call_user_func_check c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3485
    #33 0x7ff61ebe909c in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4158
    #34 0x7ff61ebeb943 in call_callback c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3818
    #35 0x7ff61e9ac80a in expand_by_function c:\Users\Christian Brabandt\code\vim\src\insexpand.c:3612
    #36 0x7ff61e9a7b68 in get_next_completion_match c:\Users\Christian Brabandt\code\vim\src\insexpand.c:5357
    #37 0x7ff61e9a6d6e in ins_compl_get_exp c:\Users\Christian Brabandt\code\vim\src\insexpand.c:5599
    #38 0x7ff61e9a59b2 in find_next_completion_match c:\Users\Christian Brabandt\code\vim\src\insexpand.c:6151
    #39 0x7ff61e9a55a9 in ins_compl_next c:\Users\Christian Brabandt\code\vim\src\insexpand.c:6265
    #40 0x7ff61e9b6eee in ins_complete c:\Users\Christian Brabandt\code\vim\src\insexpand.c:7320
    #41 0x7ff61e8b6ff4 in edit c:\Users\Christian Brabandt\code\vim\src\edit.c:1329
    #42 0x7ff61ea3139a in invoke_edit c:\Users\Christian Brabandt\code\vim\src\normal.c:7139
    #43 0x7ff61ea318e9 in nv_edit c:\Users\Christian Brabandt\code\vim\src\normal.c:7110
    #44 0x7ff61ea43efc in normal_cmd c:\Users\Christian Brabandt\code\vim\src\normal.c:952
    #45 0x7ff61e92d809 in exec_normal c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:9436
    #46 0x7ff61e8e70b3 in f_feedkeys c:\Users\Christian Brabandt\code\vim\src\evalfunc.c:5151
    #47 0x7ff61e8ec29c in call_internal_func c:\Users\Christian Brabandt\code\vim\src\evalfunc.c:3497
    #48 0x7ff61ebe8cdb in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4176
    #49 0x7ff61ebe9d75 in get_func_tv c:\Users\Christian Brabandt\code\vim\src\userfunc.c:2190
    #50 0x7ff61ebd4c73 in ex_call_inner c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6510
    #51 0x7ff61ebe5264 in ex_call c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6868
    #52 0x7ff61e92a52c in do_one_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:2629
    #53 0x7ff61e931b04 in do_cmdline c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:1041
    #54 0x7ff61e930e83 in do_cmdline_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:635
    #55 0x7ff61eba1977 in f_assert_fails c:\Users\Christian Brabandt\code\vim\src\testing.c:624
    #56 0x7ff61e8ec29c in call_internal_func c:\Users\Christian Brabandt\code\vim\src\evalfunc.c:3497
    #57 0x7ff61ebe8cdb in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4176
    #58 0x7ff61ebe9d75 in get_func_tv c:\Users\Christian Brabandt\code\vim\src\userfunc.c:2190
    #59 0x7ff61ebd4c73 in ex_call_inner c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6510
    #60 0x7ff61ebe5264 in ex_call c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6868
    #61 0x7ff61e92a52c in do_one_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:2629
    #62 0x7ff61e931b04 in do_cmdline c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:1041
    #63 0x7ff61ebdb3d5 in call_user_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3312
    #64 0x7ff61ebda2b1 in call_user_func_check c:\Users\Christian Brabandt\code\vim\src\userfunc.c:3485
    #65 0x7ff61ebe909c in call_func c:\Users\Christian Brabandt\code\vim\src\userfunc.c:4158
    #66 0x7ff61ebe9d75 in get_func_tv c:\Users\Christian Brabandt\code\vim\src\userfunc.c:2190
    #67 0x7ff61ebd4c73 in ex_call_inner c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6510
    #68 0x7ff61ebe5264 in ex_call c:\Users\Christian Brabandt\code\vim\src\userfunc.c:6868
    #69 0x7ff61e92a52c in do_one_cmd c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:2629
    #70 0x7ff61e931b04 in do_cmdline c:\Users\Christian Brabandt\code\vim\src\ex_docmd.c:1041
    #71 0x7ff61ea3ddb3 in nv_colon c:\Users\Christian Brabandt\code\vim\src\normal.c:3170
    #72 0x7ff61ea43efc in normal_cmd c:\Users\Christian Brabandt\code\vim\src\normal.c:952
    #73 0x7ff61e9d07e9 in main_loop c:\Users\Christian Brabandt\code\vim\src\main.c:1635
    #74 0x7ff61e9cf31e in vim_main2 c:\Users\Christian Brabandt\code\vim\src\main.c:973
    #75 0x7ff61e9cfd8b in VimMain c:\Users\Christian Brabandt\code\vim\src\main.c:446
    #76 0x7ff61ec7322f in wWinMain c:\Users\Christian Brabandt\code\vim\src\os_w32exe.c:39
    #77 0x7ff61e7e35b1 in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:118
    #78 0x7ff61e7e35b1 in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
    #79 0x7ffc5f3de8d6  (C:\Windows\System32\KERNEL32.DLL+0x18002e8d6)
    #80 0x7ffc60d68d9b  (C:\Windows\SYSTEM32\ntdll.dll+0x180008d9b)

0x7ff61ef5c0c0 is located 0 bytes after global variable 'out_buf' defined in 'term.c:2759:15' (0x7ff61ef5b8c0) of size 2048
SUMMARY: AddressSanitizer: global-buffer-overflow c:\Users\Christian Brabandt\code\vim\src\term.c:2893 in out_str_nf
Shadow bytes around the buggy address:
  0x7ff61ef5be00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ff61ef5be80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ff61ef5bf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ff61ef5bf80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x7ff61ef5c000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x7ff61ef5c080: 00 00 00 00 00 00 00 00[f9]f9 f9 f9 f9 f9 f9 f9
  0x7ff61ef5c100: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x7ff61ef5c180: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x7ff61ef5c200: f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
  0x7ff61ef5c280: f9 f9 f9 f9 f9 f9 f9 f9 04 f9 f9 f9 04 f9 f9 f9
  0x7ff61ef5c300: 00 f9 f9 f9 04 f9 f9 f9 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==377936==ABORTING


Reply to this email directly, view it on GitHub.

You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/pull/18439/c3353604750@github.com>

Reply all
Reply to author
Forward
0 new messages