diff options
author | zeertzjq <zeertzjq@outlook.com> | 2023-07-13 08:32:17 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-13 08:32:17 +0800 |
commit | 0ce39108684ed7b6af03e47da0a4e0a022e41936 (patch) | |
tree | 4a9a5ac4e2b106784b0be62f8742e9ee0dd41f2d | |
parent | 9359701eae7bd8a59e4a916e085cc686f609d693 (diff) | |
download | rneovim-0ce39108684ed7b6af03e47da0a4e0a022e41936.tar.gz rneovim-0ce39108684ed7b6af03e47da0a4e0a022e41936.tar.bz2 rneovim-0ce39108684ed7b6af03e47da0a4e0a022e41936.zip |
fix(ui): cursor pos with left gravity inline virt_text at eol (#24329)
Problem: Cursor is not after inline virtual text with left gravity
when inserting after the end of the line.
Solution: Add width of inline virtual text with left gravity to cursor
virtcol in Insert mode even if on a NUL.
-rw-r--r-- | src/nvim/charset.c | 9 | ||||
-rw-r--r-- | test/functional/ui/decorations_spec.lua | 124 |
2 files changed, 102 insertions, 31 deletions
diff --git a/src/nvim/charset.c b/src/nvim/charset.c index c2745a66a0..c6efb4b3b4 100644 --- a/src/nvim/charset.c +++ b/src/nvim/charset.c @@ -1089,12 +1089,11 @@ void getvcol(win_T *wp, pos_T *pos, colnr_T *start, colnr_T *cursor, colnr_T *en // cursor at end *cursor = vcol + incr - 1; } else { - if (!on_NUL) { - // cursor is after inserted text, unless on the NUL + if (!on_NUL || !(State & MODE_NORMAL)) { vcol += cts.cts_cur_text_width_left; - if ((State & MODE_INSERT) == 0) { - vcol += cts.cts_cur_text_width_right; - } + } + if (!on_NUL && (State & MODE_NORMAL)) { + vcol += cts.cts_cur_text_width_right; } // cursor at start *cursor = vcol + head; diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua index b526aa86c8..cee1e32114 100644 --- a/test/functional/ui/decorations_spec.lua +++ b/test/functional/ui/decorations_spec.lua @@ -2218,71 +2218,143 @@ bbbbbbb]]) ]]} end) - it('cursor position is correct when inserting around a virtual text with right gravity set to false', function() + it('cursor position is correct when inserting around a virtual text with left gravity', function() + screen:try_resize(50, 3) insert('foo foo foo foo') meths.buf_set_extmark(0, ns, 0, 8, { virt_text = { { 'virtual text', 'Special' } }, virt_text_pos = 'inline', right_gravity = false }) feed('0') feed('8l') - screen:expect { grid = [[ + screen:expect{grid=[[ foo foo {10:virtual text}^foo foo | {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| | - ]]} + ]]} feed('i') - screen:expect { grid = [[ + screen:expect{grid=[[ foo foo {10:virtual text}^foo foo | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed([[<C-\><C-O>]]) + screen:expect{grid=[[ + foo foo {10:virtual text}^foo foo | {1:~ }| + {8:-- (insert) --} | + ]]} + + feed('D') + screen:expect{grid=[[ + foo foo {10:virtual text}^ | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('<C-U>') + screen:expect{grid=[[ + {10:virtual text}^ | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('a') + screen:expect{grid=[[ + {10:virtual text}a^ | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('<Esc>') + screen:expect{grid=[[ + {10:virtual text}^a | {1:~ }| + | + ]]} + + feed('x') + screen:expect{grid=[[ + {10:^virtual text} | {1:~ }| - {1:~ }| - {8:-- INSERT --} | - ]]} + | + ]]} end) it('cursor position is correct when inserting around virtual texts with both left and right gravity', function() + screen:try_resize(50, 3) insert('foo foo foo foo') meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '>>', 'Special' }}, virt_text_pos = 'inline', right_gravity = false }) meths.buf_set_extmark(0, ns, 0, 8, { virt_text = {{ '<<', 'Special' }}, virt_text_pos = 'inline', right_gravity = true }) feed('08l') - screen:expect{ grid = [[ + screen:expect{grid=[[ foo foo {10:>><<}^foo foo | {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| - {1:~ }| | - ]]} + ]]} feed('i') - screen:expect { grid = [[ + screen:expect{grid=[[ foo foo {10:>>^<<}foo foo | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('a') + screen:expect{grid=[[ + foo foo {10:>>}a{10:^<<}foo foo | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed([[<C-\><C-O>]]) + screen:expect{grid=[[ + foo foo {10:>>}a{10:<<}^foo foo | {1:~ }| + {8:-- (insert) --} | + ]]} + + feed('D') + screen:expect{grid=[[ + foo foo {10:>>}a{10:^<<} | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('<BS>') + screen:expect{grid=[[ + foo foo {10:>>^<<} | {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('<C-U>') + screen:expect{grid=[[ + {10:>>^<<} | {1:~ }| - {1:~ }| + {8:-- INSERT --} | + ]]} + + feed('a') + screen:expect{grid=[[ + {10:>>}a{10:^<<} | {1:~ }| {8:-- INSERT --} | - ]]} + ]]} + + feed('<Esc>') + screen:expect{grid=[[ + {10:>>}^a{10:<<} | + {1:~ }| + | + ]]} + + feed('x') + screen:expect{grid=[[ + {10:^>><<} | + {1:~ }| + | + ]]} end) it('draws correctly with no wrap multiple virtual text, where one is hidden', function() |