Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 400ee59

Browse filesBrowse files
hashincludejustinmk
authored andcommitted
API: fix cursor position when lines are added #9961
Restore code removed in #9674.
1 parent b3adfa0 commit 400ee59
Copy full SHA for 400ee59

File tree

Expand file treeCollapse file tree

2 files changed

+56
-0
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+56
-0
lines changed

‎src/nvim/api/buffer.c

Copy file name to clipboardExpand all lines: src/nvim/api/buffer.c
+21Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,7 @@ void nvim_buf_set_lines(uint64_t channel_id,
474474
false);
475475

476476
changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra, true);
477+
fix_cursor((linenr_T)start, (linenr_T)end, (linenr_T)extra);
477478

478479
end:
479480
for (size_t i = 0; i < new_len; i++) {
@@ -1106,6 +1107,26 @@ Integer nvim_buf_set_virtual_text(Buffer buffer,
11061107
return 0;
11071108
}
11081109

1110+
// Check if deleting lines made the cursor position invalid.
1111+
// Changed lines from `lo` to `hi`; added `extra` lines (negative if deleted).
1112+
static void fix_cursor(linenr_T lo, linenr_T hi, linenr_T extra)
1113+
{
1114+
if (curwin->w_cursor.lnum >= lo) {
1115+
// Adjust cursor position if it's in/after the changed lines.
1116+
if (curwin->w_cursor.lnum >= hi) {
1117+
curwin->w_cursor.lnum += extra;
1118+
check_cursor_col();
1119+
} else if (extra < 0) {
1120+
curwin->w_cursor.lnum = lo;
1121+
check_cursor();
1122+
} else {
1123+
check_cursor_col();
1124+
}
1125+
changed_cline_bef_curs();
1126+
}
1127+
invalidate_botline();
1128+
}
1129+
11091130
// Normalizes 0-based indexes to buffer line numbers
11101131
static int64_t normalize_index(buf_T *buf, int64_t index, bool *oob)
11111132
{

‎test/functional/api/buffer_spec.lua

Copy file name to clipboardExpand all lines: test/functional/api/buffer_spec.lua
+35Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,41 @@ describe('api/buf', function()
3939
eq(1, curbuf_depr('line_count'))
4040
end)
4141

42+
it('cursor position is maintained after lines are inserted #9961', function()
43+
-- replace the buffer contents with these three lines.
44+
request('nvim_buf_set_lines', 0, 0, -1, 1, {"line1", "line2", "line3", "line4"})
45+
-- Set the current cursor to {3, 2}.
46+
curwin('set_cursor', {3, 2})
47+
48+
-- add 2 lines and delete 1 line above the current cursor position.
49+
request('nvim_buf_set_lines', 0, 1, 2, 1, {"line5", "line6"})
50+
-- check the current set of lines in the buffer.
51+
eq({"line1", "line5", "line6", "line3", "line4"}, buffer('get_lines', 0, 0, -1, 1))
52+
-- cursor should be moved below by 1 line.
53+
eq({4, 2}, curwin('get_cursor'))
54+
55+
-- add a line after the current cursor position.
56+
request('nvim_buf_set_lines', 0, 5, 5, 1, {"line7"})
57+
-- check the current set of lines in the buffer.
58+
eq({"line1", "line5", "line6", "line3", "line4", "line7"}, buffer('get_lines', 0, 0, -1, 1))
59+
-- cursor position is unchanged.
60+
eq({4, 2}, curwin('get_cursor'))
61+
62+
-- overwrite current cursor line.
63+
request('nvim_buf_set_lines', 0, 3, 5, 1, {"line8", "line9"})
64+
-- check the current set of lines in the buffer.
65+
eq({"line1", "line5", "line6", "line8", "line9", "line7"}, buffer('get_lines', 0, 0, -1, 1))
66+
-- cursor position is unchanged.
67+
eq({4, 2}, curwin('get_cursor'))
68+
69+
-- delete current cursor line.
70+
request('nvim_buf_set_lines', 0, 3, 5, 1, {})
71+
-- check the current set of lines in the buffer.
72+
eq({"line1", "line5", "line6", "line7"}, buffer('get_lines', 0, 0, -1, 1))
73+
-- cursor position is unchanged.
74+
eq({4, 2}, curwin('get_cursor'))
75+
end)
76+
4277
it('line_count has defined behaviour for unloaded buffers', function()
4378
-- we'll need to know our bufnr for when it gets unloaded
4479
local bufnr = curbuf('get_number')

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.