aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2023-07-13 08:32:17 +0800
committerGitHub <noreply@github.com>2023-07-13 08:32:17 +0800
commit0ce39108684ed7b6af03e47da0a4e0a022e41936 (patch)
tree4a9a5ac4e2b106784b0be62f8742e9ee0dd41f2d
parent9359701eae7bd8a59e4a916e085cc686f609d693 (diff)
downloadrneovim-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.c9
-rw-r--r--test/functional/ui/decorations_spec.lua124
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()