aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mark.c
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2023-08-21 14:52:17 +0200
committerbfredl <bjorn.linse@gmail.com>2023-08-26 12:02:05 +0200
commit008154954791001efcc46c28146e21403f3a698b (patch)
tree306721ca60456ba9562c16b9d41cf5ec8d5a360c /src/nvim/mark.c
parent1635c9e75e21e07c4331cf983e14a11c7e09b119 (diff)
downloadrneovim-008154954791001efcc46c28146e21403f3a698b.tar.gz
rneovim-008154954791001efcc46c28146e21403f3a698b.tar.bz2
rneovim-008154954791001efcc46c28146e21403f3a698b.zip
refactor(change): do API changes to buffer without curbuf switch
Most of the messy things when changing a non-current buffer is not about the buffer, it is about windows. In particular, it is about `curwin`. When editing a non-current buffer which is displayed in some other window in the current tabpage, one such window will be "borrowed" as the curwin. But this means if two or more non-current windows displayed the buffers, one of them will be treated differenty. this is not desirable. In particular, with nvim_buf_set_text, cursor _column_ position was only corrected for one single window. Two new tests are added: the test with just one non-current window passes, but the one with two didn't. Two corresponding such tests were also added for nvim_buf_set_lines. This already worked correctly on master, but make sure this is well-tested for future refactors. Also, nvim_create_buf no longer invokes autocmds just because you happened to use `scratch=true`. No option value was changed, therefore OptionSet must not be fired.
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r--src/nvim/mark.c84
1 files changed, 44 insertions, 40 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 5c36493b82..2e08a6f591 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1121,7 +1121,7 @@ void ex_changes(exarg_T *eap)
void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
ExtmarkOp op)
{
- mark_adjust_internal(line1, line2, amount, amount_after, true, op);
+ mark_adjust_buf(curbuf, line1, line2, amount, amount_after, true, true, op);
}
// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
@@ -1132,13 +1132,13 @@ void mark_adjust(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amoun
void mark_adjust_nofold(linenr_T line1, linenr_T line2, linenr_T amount, linenr_T amount_after,
ExtmarkOp op)
{
- mark_adjust_internal(line1, line2, amount, amount_after, false, op);
+ mark_adjust_buf(curbuf, line1, line2, amount, amount_after, false, true, op);
}
-static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount,
- linenr_T amount_after, bool adjust_folds, ExtmarkOp op)
+void mark_adjust_buf(buf_T *buf, linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after, bool adjust_folds, bool adj_cursor, ExtmarkOp op)
{
- int fnum = curbuf->b_fnum;
+ int fnum = buf->b_fnum;
linenr_T *lp;
static pos_T initpos = { 1, 0, 0 };
@@ -1149,7 +1149,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// named marks, lower case and upper case
for (int i = 0; i < NMARKS; i++) {
- ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum));
+ ONE_ADJUST(&(buf->b_namedm[i].mark.lnum));
if (namedfm[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
@@ -1161,54 +1161,56 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
// last Insert position
- ONE_ADJUST(&(curbuf->b_last_insert.mark.lnum));
+ ONE_ADJUST(&(buf->b_last_insert.mark.lnum));
// last change position
- ONE_ADJUST(&(curbuf->b_last_change.mark.lnum));
+ ONE_ADJUST(&(buf->b_last_change.mark.lnum));
// last cursor position, if it was set
- if (!equalpos(curbuf->b_last_cursor.mark, initpos)) {
- ONE_ADJUST(&(curbuf->b_last_cursor.mark.lnum));
+ if (!equalpos(buf->b_last_cursor.mark, initpos)) {
+ ONE_ADJUST(&(buf->b_last_cursor.mark.lnum));
}
// list of change positions
- for (int i = 0; i < curbuf->b_changelistlen; i++) {
- ONE_ADJUST_NODEL(&(curbuf->b_changelist[i].mark.lnum));
+ for (int i = 0; i < buf->b_changelistlen; i++) {
+ ONE_ADJUST_NODEL(&(buf->b_changelist[i].mark.lnum));
}
// Visual area
- ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_start.lnum));
- ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_end.lnum));
+ ONE_ADJUST_NODEL(&(buf->b_visual.vi_start.lnum));
+ ONE_ADJUST_NODEL(&(buf->b_visual.vi_end.lnum));
// quickfix marks
- if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) {
- curbuf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY;
+ if (!qf_mark_adjust(buf, NULL, line1, line2, amount, amount_after)) {
+ buf->b_has_qf_entry &= ~BUF_HAS_QF_ENTRY;
}
// location lists
bool found_one = false;
FOR_ALL_TAB_WINDOWS(tab, win) {
- found_one |= qf_mark_adjust(win, line1, line2, amount, amount_after);
+ found_one |= qf_mark_adjust(buf, win, line1, line2, amount, amount_after);
}
if (!found_one) {
- curbuf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY;
+ buf->b_has_qf_entry &= ~BUF_HAS_LL_ENTRY;
}
- sign_mark_adjust(line1, line2, amount, amount_after);
+ sign_mark_adjust(buf, line1, line2, amount, amount_after);
}
if (op != kExtmarkNOOP) {
- extmark_adjust(curbuf, line1, line2, amount, amount_after, op);
+ extmark_adjust(buf, line1, line2, amount, amount_after, op);
}
- // previous context mark
- ONE_ADJUST(&(curwin->w_pcmark.lnum));
+ if (curwin->w_buffer == buf) {
+ // previous context mark
+ ONE_ADJUST(&(curwin->w_pcmark.lnum));
- // previous pcmark
- ONE_ADJUST(&(curwin->w_prev_pcmark.lnum));
+ // previous pcpmark
+ ONE_ADJUST(&(curwin->w_prev_pcmark.lnum));
- // saved cursor for formatting
- if (saved_cursor.lnum != 0) {
- ONE_ADJUST_NODEL(&(saved_cursor.lnum));
+ // saved cursor for formatting
+ if (saved_cursor.lnum != 0) {
+ ONE_ADJUST_NODEL(&(saved_cursor.lnum));
+ }
}
// Adjust items in all windows related to the current buffer.
@@ -1223,7 +1225,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
}
- if (win->w_buffer == curbuf) {
+ if (win->w_buffer == buf) {
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// marks in the tag stack
for (int i = 0; i < win->w_tagstacklen; i++) {
@@ -1259,19 +1261,21 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
win->w_topline += amount_after;
win->w_topfill = 0;
}
- if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
- if (amount == MAXLNUM) { // line with cursor is deleted
- if (line1 <= 1) {
- win->w_cursor.lnum = 1;
- } else {
- win->w_cursor.lnum = line1 - 1;
+ if (adj_cursor) {
+ if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
+ if (amount == MAXLNUM) { // line with cursor is deleted
+ if (line1 <= 1) {
+ win->w_cursor.lnum = 1;
+ } else {
+ win->w_cursor.lnum = line1 - 1;
+ }
+ win->w_cursor.col = 0;
+ } else { // keep cursor on the same line
+ win->w_cursor.lnum += amount;
}
- win->w_cursor.col = 0;
- } else { // keep cursor on the same line
- win->w_cursor.lnum += amount;
+ } else if (amount_after && win->w_cursor.lnum > line2) {
+ win->w_cursor.lnum += amount_after;
}
- } else if (amount_after && win->w_cursor.lnum > line2) {
- win->w_cursor.lnum += amount_after;
}
}
@@ -1282,7 +1286,7 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
}
// adjust diffs
- diff_mark_adjust(line1, line2, amount, amount_after);
+ diff_mark_adjust(buf, line1, line2, amount, amount_after);
}
// This code is used often, needs to be fast.