aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mark.c
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-29 22:40:31 +0000
commit339e2d15cc26fe86988ea06468d912a46c8d6f29 (patch)
treea6167fc8fcfc6ae2dc102f57b2473858eac34063 /src/nvim/mark.c
parent067dc73729267c0262438a6fdd66e586f8496946 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.gz
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.tar.bz2
rneovim-339e2d15cc26fe86988ea06468d912a46c8d6f29.zip
Merge remote-tracking branch 'upstream/master' into fix_repeatcmdline
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r--src/nvim/mark.c318
1 files changed, 157 insertions, 161 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index f1a1f25e6c..5839cf7a2e 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -1,6 +1,3 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
// mark.c: functions for setting marks and jumping to them
#include <assert.h>
@@ -9,7 +6,7 @@
#include <stdio.h>
#include <string.h>
-#include "nvim/ascii.h"
+#include "nvim/ascii_defs.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
@@ -17,14 +14,13 @@
#include "nvim/diff.h"
#include "nvim/edit.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/typval_defs.h"
#include "nvim/ex_cmds_defs.h"
#include "nvim/extmark.h"
#include "nvim/extmark_defs.h"
#include "nvim/fold.h"
#include "nvim/gettext.h"
#include "nvim/globals.h"
-#include "nvim/highlight_defs.h"
+#include "nvim/highlight.h"
#include "nvim/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -32,16 +28,15 @@
#include "nvim/message.h"
#include "nvim/move.h"
#include "nvim/normal.h"
-#include "nvim/option_defs.h"
+#include "nvim/option_vars.h"
+#include "nvim/os/fs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
-#include "nvim/sign.h"
#include "nvim/strings.h"
#include "nvim/textobject.h"
-#include "nvim/undo_defs.h"
-#include "nvim/vim.h"
+#include "nvim/vim_defs.h"
// This file contains routines to maintain and manipulate marks.
@@ -51,9 +46,6 @@
// There are marks 'A - 'Z (set by user) and '0 to '9 (set when writing
// shada).
-/// Global marks (marks with file number or name)
-static xfmark_T namedfm[NGLOBALMARKS];
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "mark.c.generated.h"
#endif
@@ -80,11 +72,12 @@ void free_xfmark(xfmark_T fm)
}
/// Free and clear fmark_T item
-void clear_fmark(fmark_T *fm)
+void clear_fmark(fmark_T *const fm, const Timestamp timestamp)
FUNC_ATTR_NONNULL_ALL
{
free_fmark(*fm);
- CLEAR_POINTER(fm);
+ *fm = (fmark_T)INIT_FMARK;
+ fm->timestamp = timestamp;
}
// Set named mark "c" to position "pos".
@@ -239,7 +232,7 @@ fmark_T *get_jumplist(win_T *win, int count)
return NULL;
}
- for (;;) {
+ while (true) {
if (win->w_jumplistidx + count < 0
|| win->w_jumplistidx + count >= win->w_jumplistlen) {
return NULL;
@@ -445,11 +438,11 @@ fmark_T *mark_get_motion(buf_T *buf, win_T *win, int name)
listcmd_busy = true; // avoid that '' is changed
if (name == '{' || name == '}') { // to previous/next paragraph
oparg_T oa;
- if (findpar(&oa.inclusive, name == '}' ? FORWARD : BACKWARD, 1L, NUL, false)) {
+ if (findpar(&oa.inclusive, name == '}' ? FORWARD : BACKWARD, 1, NUL, false)) {
mark = pos_to_mark(buf, NULL, win->w_cursor);
}
} else if (name == '(' || name == ')') { // to previous/next sentence
- if (findsent(name == ')' ? FORWARD : BACKWARD, 1L)) {
+ if (findsent(name == ')' ? FORWARD : BACKWARD, 1)) {
mark = pos_to_mark(buf, NULL, win->w_cursor);
}
}
@@ -521,11 +514,10 @@ fmark_T *pos_to_mark(buf_T *buf, fmark_T *fmp, pos_T pos)
/// @return whether the buffer was switched or not.
static MarkMoveRes switch_to_mark_buf(fmark_T *fm, bool pcmark_on_switch)
{
- bool res;
if (fm->fnum != curbuf->b_fnum) {
// Switch to another file.
int getfile_flag = pcmark_on_switch ? GETF_SETMARK : 0;
- res = buflist_getfile(fm->fnum, (linenr_T)1, getfile_flag, false) == OK;
+ bool res = buflist_getfile(fm->fnum, fm->mark.lnum, getfile_flag, false) == OK;
return res == true ? kMarkSwitchedBuf : kMarkMoveFailed;
}
return 0;
@@ -542,7 +534,11 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags)
{
static fmark_T fm_copy = INIT_FMARK;
MarkMoveRes res = kMarkMoveSuccess;
- if (!mark_check(fm)) {
+ const char *errormsg = NULL;
+ if (!mark_check(fm, &errormsg)) {
+ if (errormsg != NULL) {
+ emsg(errormsg);
+ }
res = kMarkMoveFailed;
goto end;
}
@@ -558,7 +554,10 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags)
goto end;
}
// Check line count now that the **destination buffer is loaded**.
- if (!mark_check_line_bounds(curbuf, fm)) {
+ if (!mark_check_line_bounds(curbuf, fm, &errormsg)) {
+ if (errormsg != NULL) {
+ emsg(errormsg);
+ }
res |= kMarkMoveFailed;
goto end;
}
@@ -617,11 +616,8 @@ fmarkv_T mark_view_make(linenr_T topline, pos_T pos)
/// @return next mark or NULL if no mark is found.
fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line)
{
- int i;
fmark_T *result = NULL;
- pos_T pos;
-
- pos = *startpos;
+ pos_T pos = *startpos;
if (dir == BACKWARD && begin_line) {
pos.col = 0;
@@ -629,7 +625,7 @@ fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line)
pos.col = MAXCOL;
}
- for (i = 0; i < NMARKS; i++) {
+ for (int i = 0; i < NMARKS; i++) {
if (curbuf->b_namedm[i].mark.lnum > 0) {
if (dir == FORWARD) {
if ((result == NULL || lt(curbuf->b_namedm[i].mark, result->mark))
@@ -677,7 +673,7 @@ static void fname2fnum(xfmark_T *fm)
char *p = path_shorten_fname(NameBuff, IObuff);
// buflist_new() will call fmarks_check_names()
- (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
+ (void)buflist_new(NameBuff, p, 1, 0);
}
// Check all file marks for a name that matches the file name in buf.
@@ -686,18 +682,17 @@ static void fname2fnum(xfmark_T *fm)
void fmarks_check_names(buf_T *buf)
{
char *name = buf->b_ffname;
- int i;
if (buf->b_ffname == NULL) {
return;
}
- for (i = 0; i < NGLOBALMARKS; i++) {
+ for (int i = 0; i < NGLOBALMARKS; i++) {
fmarks_check_one(&namedfm[i], name, buf);
}
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- for (i = 0; i < wp->w_jumplistlen; i++) {
+ for (int i = 0; i < wp->w_jumplistlen; i++) {
fmarks_check_one(&wp->w_jumplist[i], name, buf);
}
}
@@ -715,43 +710,45 @@ static void fmarks_check_one(xfmark_T *fm, char *name, buf_T *buf)
/// Check the position in @a fm is valid.
///
-/// Emit error message and return accordingly.
-///
/// Checks for:
/// - NULL raising unknown mark error.
/// - Line number <= 0 raising mark not set.
/// - Line number > buffer line count, raising invalid mark.
+///
/// @param fm[in] File mark to check.
+/// @param errormsg[out] Error message, if any.
///
/// @return true if the mark passes all the above checks, else false.
-bool mark_check(fmark_T *fm)
+bool mark_check(fmark_T *fm, const char **errormsg)
{
if (fm == NULL) {
- emsg(_(e_umark));
+ *errormsg = _(e_umark);
return false;
} else if (fm->mark.lnum <= 0) {
// In both cases it's an error but only raise when equals to 0
if (fm->mark.lnum == 0) {
- emsg(_(e_marknotset));
+ *errormsg = _(e_marknotset);
}
return false;
}
// Only check for valid line number if the buffer is loaded.
- if (fm->fnum == curbuf->handle && !mark_check_line_bounds(curbuf, fm)) {
+ if (fm->fnum == curbuf->handle && !mark_check_line_bounds(curbuf, fm, errormsg)) {
return false;
}
return true;
}
/// Check if a mark line number is greater than the buffer line count, and set e_markinval.
+///
/// @note Should be done after the buffer is loaded into memory.
/// @param buf Buffer where the mark is set.
/// @param fm Mark to check.
+/// @param errormsg[out] Error message, if any.
/// @return true if below line count else false.
-bool mark_check_line_bounds(buf_T *buf, fmark_T *fm)
+bool mark_check_line_bounds(buf_T *buf, fmark_T *fm, const char **errormsg)
{
if (buf != NULL && fm->mark.lnum > buf->b_ml.ml_line_count) {
- emsg(_(e_markinval));
+ *errormsg = _(e_markinval);
return false;
}
return true;
@@ -762,20 +759,20 @@ bool mark_check_line_bounds(buf_T *buf, fmark_T *fm)
/// Used mainly when trashing the entire buffer during ":e" type commands.
///
/// @param[out] buf Buffer to clear marks in.
-void clrallmarks(buf_T *const buf)
+void clrallmarks(buf_T *const buf, const Timestamp timestamp)
FUNC_ATTR_NONNULL_ALL
{
for (size_t i = 0; i < NMARKS; i++) {
- clear_fmark(&buf->b_namedm[i]);
+ clear_fmark(&buf->b_namedm[i], timestamp);
}
- clear_fmark(&buf->b_last_cursor);
+ clear_fmark(&buf->b_last_cursor, timestamp);
buf->b_last_cursor.mark.lnum = 1;
- clear_fmark(&buf->b_last_insert);
- clear_fmark(&buf->b_last_change);
+ clear_fmark(&buf->b_last_insert, timestamp);
+ clear_fmark(&buf->b_last_change, timestamp);
buf->b_op_start.lnum = 0; // start/end op mark cleared
buf->b_op_end.lnum = 0;
for (int i = 0; i < buf->b_changelistlen; i++) {
- clear_fmark(&buf->b_changelist[i]);
+ clear_fmark(&buf->b_changelist[i], timestamp);
}
buf->b_changelistlen = 0;
}
@@ -795,18 +792,17 @@ char *fm_getname(fmark_T *fmark, int lead_len)
/// The returned string has been allocated.
static char *mark_line(pos_T *mp, int lead_len)
{
- char *s, *p;
- int len;
+ char *p;
if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) {
return xstrdup("-invalid-");
}
assert(Columns >= 0);
// Allow for up to 5 bytes per character.
- s = xstrnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
+ char *s = xstrnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
// Truncate the line to fit it in the window
- len = 0;
+ int len = 0;
for (p = s; *p != NUL; MB_PTR_ADV(p)) {
len += ptr2cells(p);
if (len >= Columns - lead_len) {
@@ -821,19 +817,18 @@ static char *mark_line(pos_T *mp, int lead_len)
void ex_marks(exarg_T *eap)
{
char *arg = eap->arg;
- int i;
char *name;
- pos_T *posp, *startp, *endp;
+ pos_T *posp;
if (arg != NULL && *arg == NUL) {
arg = NULL;
}
show_one_mark('\'', arg, &curwin->w_pcmark, NULL, true);
- for (i = 0; i < NMARKS; i++) {
+ for (int i = 0; i < NMARKS; i++) {
show_one_mark(i + 'a', arg, &curbuf->b_namedm[i].mark, NULL, true);
}
- for (i = 0; i < NGLOBALMARKS; i++) {
+ for (int i = 0; i < NGLOBALMARKS; i++) {
if (namedfm[i].fmark.fnum != 0) {
name = fm_getname(&namedfm[i].fmark, 15);
} else {
@@ -855,8 +850,8 @@ void ex_marks(exarg_T *eap)
show_one_mark('.', arg, &curbuf->b_last_change.mark, NULL, true);
// Show the marks as where they will jump to.
- startp = &curbuf->b_visual.vi_start;
- endp = &curbuf->b_visual.vi_end;
+ pos_T *startp = &curbuf->b_visual.vi_start;
+ pos_T *endp = &curbuf->b_visual.vi_end;
if ((lt(*startp, *endp) || endp->lnum == 0) && startp->lnum != 0) {
posp = startp;
} else {
@@ -880,7 +875,7 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren
did_title = false;
} else {
if (arg == NULL) {
- msg(_("No marks set"));
+ msg(_("No marks set"), 0);
} else {
semsg(_("E283: No marks matching \"%s\""), arg);
}
@@ -902,9 +897,9 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren
msg_putchar('\n');
if (!got_int) {
snprintf(IObuff, IOSIZE, " %c %6" PRIdLINENR " %4d ", c, p->lnum, p->col);
- msg_outtrans(IObuff);
+ msg_outtrans(IObuff, 0);
if (name != NULL) {
- msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
+ msg_outtrans(name, current ? HL_ATTR(HLF_D) : 0);
}
}
}
@@ -917,33 +912,30 @@ static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int curren
// ":delmarks[!] [marks]"
void ex_delmarks(exarg_T *eap)
{
- char *p;
int from, to;
- int i;
- int lower;
- int digit;
int n;
if (*eap->arg == NUL && eap->forceit) {
// clear all marks
- clrallmarks(curbuf);
+ clrallmarks(curbuf, os_time());
} else if (eap->forceit) {
emsg(_(e_invarg));
} else if (*eap->arg == NUL) {
emsg(_(e_argreq));
} else {
// clear specified marks only
- for (p = eap->arg; *p != NUL; p++) {
- lower = ASCII_ISLOWER(*p);
- digit = ascii_isdigit(*p);
+ const Timestamp timestamp = os_time();
+ for (char *p = eap->arg; *p != NUL; p++) {
+ int lower = ASCII_ISLOWER(*p);
+ int digit = ascii_isdigit(*p);
if (lower || digit || ASCII_ISUPPER(*p)) {
if (p[1] == '-') {
// clear range of marks
from = (uint8_t)(*p);
to = (uint8_t)p[2];
if (!(lower ? ASCII_ISLOWER(p[2])
- : (digit ? ascii_isdigit(p[2])
- : ASCII_ISUPPER(p[2])))
+ : (digit ? ascii_isdigit(p[2])
+ : ASCII_ISUPPER(p[2])))
|| to < from) {
semsg(_(e_invarg2), p);
return;
@@ -954,9 +946,10 @@ void ex_delmarks(exarg_T *eap)
from = to = (uint8_t)(*p);
}
- for (i = from; i <= to; i++) {
+ for (int i = from; i <= to; i++) {
if (lower) {
curbuf->b_namedm[i - 'a'].mark.lnum = 0;
+ curbuf->b_namedm[i - 'a'].timestamp = timestamp;
} else {
if (digit) {
n = i - '0' + NMARKS;
@@ -965,25 +958,29 @@ void ex_delmarks(exarg_T *eap)
}
namedfm[n].fmark.mark.lnum = 0;
namedfm[n].fmark.fnum = 0;
+ namedfm[n].fmark.timestamp = timestamp;
XFREE_CLEAR(namedfm[n].fname);
}
}
} else {
switch (*p) {
case '"':
- CLEAR_FMARK(&curbuf->b_last_cursor); break;
+ clear_fmark(&curbuf->b_last_cursor, timestamp);
+ break;
case '^':
- CLEAR_FMARK(&curbuf->b_last_insert); break;
+ clear_fmark(&curbuf->b_last_insert, timestamp);
+ break;
case '.':
- CLEAR_FMARK(&curbuf->b_last_change); break;
+ clear_fmark(&curbuf->b_last_change, timestamp);
+ break;
case '[':
- curbuf->b_op_start.lnum = 0; break;
+ curbuf->b_op_start.lnum = 0; break;
case ']':
- curbuf->b_op_end.lnum = 0; break;
+ curbuf->b_op_end.lnum = 0; break;
case '<':
curbuf->b_visual.vi_start.lnum = 0; break;
case '>':
- curbuf->b_visual.vi_end.lnum = 0; break;
+ curbuf->b_visual.vi_end.lnum = 0; break;
case ' ':
break;
default:
@@ -998,15 +995,12 @@ void ex_delmarks(exarg_T *eap)
// print the jumplist
void ex_jumps(exarg_T *eap)
{
- int i;
- char *name;
-
cleanup_jumplist(curwin, true);
// Highlight title
msg_puts_title(_("\n jump line col file/text"));
- for (i = 0; i < curwin->w_jumplistlen && !got_int; i++) {
+ for (int i = 0; i < curwin->w_jumplistlen && !got_int; i++) {
if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
- name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
+ char *name = fm_getname(&curwin->w_jumplist[i].fmark, 16);
// Make sure to output the current indicator, even when on an wiped
// out buffer. ":filter" may still skip it.
@@ -1028,10 +1022,9 @@ void ex_jumps(exarg_T *eap)
i == curwin->w_jumplistidx ? '>' : ' ',
i > curwin->w_jumplistidx ? i - curwin->w_jumplistidx : curwin->w_jumplistidx - i,
curwin->w_jumplist[i].fmark.mark.lnum, curwin->w_jumplist[i].fmark.mark.col);
- msg_outtrans(IObuff);
- msg_outtrans_attr(name,
- curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
- ? HL_ATTR(HLF_D) : 0);
+ msg_outtrans(IObuff, 0);
+ msg_outtrans(name,
+ curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum ? HL_ATTR(HLF_D) : 0);
xfree(name);
os_breakcheck();
}
@@ -1051,26 +1044,24 @@ void ex_clearjumps(exarg_T *eap)
// print the changelist
void ex_changes(exarg_T *eap)
{
- int i;
- char *name;
-
// Highlight title
msg_puts_title(_("\nchange line col text"));
- for (i = 0; i < curbuf->b_changelistlen && !got_int; i++) {
+ for (int i = 0; i < curbuf->b_changelistlen && !got_int; i++) {
if (curbuf->b_changelist[i].mark.lnum != 0) {
msg_putchar('\n');
if (got_int) {
break;
}
- snprintf(IObuff, IOSIZE, "%c %3d %5ld %4d ",
+ snprintf(IObuff, IOSIZE, "%c %3d %5" PRIdLINENR " %4d ",
i == curwin->w_changelistidx ? '>' : ' ',
- i > curwin->w_changelistidx ? i - curwin->w_changelistidx : curwin->w_changelistidx - i,
- (long)curbuf->b_changelist[i].mark.lnum,
+ i >
+ curwin->w_changelistidx ? i - curwin->w_changelistidx : curwin->w_changelistidx - i,
+ curbuf->b_changelist[i].mark.lnum,
curbuf->b_changelist[i].mark.col);
- msg_outtrans(IObuff);
- name = mark_line(&curbuf->b_changelist[i].mark, 17);
- msg_outtrans_attr(name, HL_ATTR(HLF_D));
+ msg_outtrans(IObuff, 0);
+ char *name = mark_line(&curbuf->b_changelist[i].mark, 17);
+ msg_outtrans(name, HL_ATTR(HLF_D));
xfree(name);
os_breakcheck();
}
@@ -1109,19 +1100,19 @@ void ex_changes(exarg_T *eap)
} \
}
-// Adjust marks between line1 and line2 (inclusive) to move 'amount' lines.
+// Adjust marks between "line1" and "line2" (inclusive) to move "amount" lines.
// Must be called before changed_*(), appended_lines() or deleted_lines().
// May be called before or after changing the text.
-// When deleting lines line1 to line2, use an 'amount' of MAXLNUM: The marks
-// within this range are made invalid.
-// If 'amount_after' is non-zero adjust marks after line2.
+// When deleting lines "line1" to "line2", use an "amount" of MAXLNUM: The
+// marks within this range are made invalid.
+// If "amount_after" is non-zero adjust marks after "line2".
// Example: Delete lines 34 and 35: mark_adjust(34, 35, MAXLNUM, -2);
// Example: Insert two lines below 55: mark_adjust(56, MAXLNUM, 2, 0);
// or: mark_adjust(56, 55, MAXLNUM, 2);
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, false, op);
}
// mark_adjust_nofold() does the same as mark_adjust() but without adjusting
@@ -1132,84 +1123,83 @@ 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, false, 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 by_api, ExtmarkOp op)
{
- int i;
- int fnum = curbuf->b_fnum;
+ int fnum = buf->b_fnum;
linenr_T *lp;
static pos_T initpos = { 1, 0, 0 };
- if (line2 < line1 && amount_after == 0L) { // nothing to do
+ if (line2 < line1 && amount_after == 0) { // nothing to do
return;
}
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// named marks, lower case and upper case
- for (i = 0; i < NMARKS; i++) {
- ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum));
+ for (int i = 0; i < NMARKS; i++) {
+ ONE_ADJUST(&(buf->b_namedm[i].mark.lnum));
if (namedfm[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
}
- for (i = NMARKS; i < NGLOBALMARKS; i++) {
+ for (int i = NMARKS; i < NGLOBALMARKS; i++) {
if (namedfm[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
}
// 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 (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);
}
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.
@@ -1217,17 +1207,17 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// Marks in the jumplist. When deleting lines, this may create
// duplicate marks in the jumplist, they will be removed later.
- for (i = 0; i < win->w_jumplistlen; i++) {
+ for (int i = 0; i < win->w_jumplistlen; i++) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(win->w_jumplist[i].fmark.mark.lnum));
}
}
}
- if (win->w_buffer == curbuf) {
+ if (win->w_buffer == buf) {
if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// marks in the tag stack
- for (i = 0; i < win->w_tagstacklen; i++) {
+ for (int i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
ONE_ADJUST_NODEL(&(win->w_tagstack[i].fmark.mark.lnum));
}
@@ -1242,22 +1232,29 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
// topline and cursor position for windows with the same buffer
// other than the current window
- if (win != curwin) {
+ if (win != curwin || by_api) {
if (win->w_topline >= line1 && win->w_topline <= line2) {
if (amount == MAXLNUM) { // topline is deleted
if (line1 <= 1) {
win->w_topline = 1;
} else {
- win->w_topline = line1 - 1;
+ // api: if the deleted region was replaced with new contents, display that
+ win->w_topline = (by_api && amount_after > line1 - line2 - 1) ? line1 : line1 - 1;
}
- } else { // keep topline on the same line
+ } else if (win->w_topline > line1) {
+ // keep topline on the same line, unless inserting just
+ // above it (we probably want to see that line then)
win->w_topline += amount;
}
win->w_topfill = 0;
- } else if (amount_after && win->w_topline > line2) {
+ // api: display new line if inserted right at topline
+ // TODO(bfredl): maybe always?
+ } else if (amount_after && win->w_topline > line2 + (by_api ? 1 : 0)) {
win->w_topline += amount_after;
win->w_topfill = 0;
}
+ }
+ if (win != curwin && !by_api) {
if (win->w_cursor.lnum >= line1 && win->w_cursor.lnum <= line2) {
if (amount == MAXLNUM) { // line with cursor is deleted
if (line1 <= 1) {
@@ -1281,7 +1278,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.
@@ -1306,24 +1303,23 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount
// position.
// "spaces_removed" is the number of spaces that were removed, matters when the
// cursor is inside them.
-void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long col_amount,
+void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, colnr_T col_amount,
int spaces_removed)
{
- int i;
int fnum = curbuf->b_fnum;
pos_T *posp;
- if ((col_amount == 0L && lnum_amount == 0L) || (cmdmod.cmod_flags & CMOD_LOCKMARKS)) {
+ if ((col_amount == 0 && lnum_amount == 0) || (cmdmod.cmod_flags & CMOD_LOCKMARKS)) {
return; // nothing to do
}
// named marks, lower case and upper case
- for (i = 0; i < NMARKS; i++) {
+ for (int i = 0; i < NMARKS; i++) {
COL_ADJUST(&(curbuf->b_namedm[i].mark));
if (namedfm[i].fmark.fnum == fnum) {
COL_ADJUST(&(namedfm[i].fmark.mark));
}
}
- for (i = NMARKS; i < NGLOBALMARKS; i++) {
+ for (int i = NMARKS; i < NGLOBALMARKS; i++) {
if (namedfm[i].fmark.fnum == fnum) {
COL_ADJUST(&(namedfm[i].fmark.mark));
}
@@ -1336,7 +1332,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c
COL_ADJUST(&(curbuf->b_last_change.mark));
// list of change positions
- for (i = 0; i < curbuf->b_changelistlen; i++) {
+ for (int i = 0; i < curbuf->b_changelistlen; i++) {
COL_ADJUST(&(curbuf->b_changelist[i].mark));
}
@@ -1356,7 +1352,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c
// Adjust items in all windows related to the current buffer.
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
// marks in the jumplist
- for (i = 0; i < win->w_jumplistlen; i++) {
+ for (int i = 0; i < win->w_jumplistlen; i++) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
COL_ADJUST(&(win->w_jumplist[i].fmark.mark));
}
@@ -1364,7 +1360,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c
if (win->w_buffer == curbuf) {
// marks in the tag stack
- for (i = 0; i < win->w_tagstacklen; i++) {
+ for (int i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
COL_ADJUST(&(win->w_tagstack[i].fmark.mark));
}
@@ -1457,9 +1453,7 @@ void cleanup_jumplist(win_T *wp, bool loadfiles)
// Copy the jumplist from window "from" to window "to".
void copy_jumplist(win_T *from, win_T *to)
{
- int i;
-
- for (i = 0; i < from->w_jumplistlen; i++) {
+ for (int i = 0; i < from->w_jumplistlen; i++) {
to->w_jumplist[i] = from->w_jumplist[i];
if (from->w_jumplist[i].fname != NULL) {
to->w_jumplist[i].fname = xstrdup(from->w_jumplist[i].fname);
@@ -1523,9 +1517,9 @@ const void *mark_global_iter(const void *const iter, char *const name, xfmark_T
return NULL;
}
size_t iter_off = (size_t)(iter_mark - &(namedfm[0]));
- *name = (char)(iter_off < NMARKS ?
- 'A' + (char)iter_off :
- '0' + (char)(iter_off - NMARKS));
+ *name = (char)(iter_off < NMARKS
+ ? 'A' + (char)iter_off
+ : '0' + (char)(iter_off - NMARKS));
*fm = *iter_mark;
while ((size_t)(++iter_mark - &(namedfm[0])) < ARRAY_SIZE(namedfm)) {
if (iter_mark->fmark.mark.lnum) {
@@ -1587,11 +1581,15 @@ const void *mark_buffer_iter(const void *const iter, const buf_T *const buf, cha
FUNC_ATTR_NONNULL_ARG(2, 3, 4) FUNC_ATTR_WARN_UNUSED_RESULT
{
*name = NUL;
- char mark_name = (char)(iter == NULL ? NUL :
- iter == &(buf->b_last_cursor) ? '"' :
- iter == &(buf->b_last_insert) ? '^' :
- iter == &(buf->b_last_change) ? '.' :
- 'a' + (char)((const fmark_T *)iter - &(buf->b_namedm[0])));
+ char mark_name = (char)(iter == NULL
+ ? NUL
+ : (iter == &(buf->b_last_cursor)
+ ? '"'
+ : (iter == &(buf->b_last_insert)
+ ? '^'
+ : (iter == &(buf->b_last_change)
+ ? '.'
+ : 'a' + (const fmark_T *)iter - &(buf->b_namedm[0])))));
const fmark_T *iter_mark = next_buffer_mark(buf, &mark_name);
while (iter_mark != NULL && iter_mark->mark.lnum == 0) {
iter_mark = next_buffer_mark(buf, &mark_name);
@@ -1671,9 +1669,7 @@ bool mark_set_local(const char name, buf_T *const buf, const fmark_T fm, const b
// Free items in the jumplist of window "wp".
void free_jumplist(win_T *wp)
{
- int i;
-
- for (i = 0; i < wp->w_jumplistlen; i++) {
+ for (int i = 0; i < wp->w_jumplistlen; i++) {
free_xfmark(wp->w_jumplist[i]);
}
wp->w_jumplistlen = 0;
@@ -1710,7 +1706,7 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
FUNC_ATTR_NONNULL_ALL
{
if (lp->col > 0 || lp->coladd > 1) {
- const char *const p = ml_get_buf(buf, lp->lnum, false);
+ const char *const p = ml_get_buf(buf, lp->lnum);
if (*p == NUL || (int)strlen(p) < lp->col) {
lp->col = 0;
} else {