aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/mark.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/mark.c')
-rw-r--r--src/nvim/mark.c737
1 files changed, 463 insertions, 274 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index 39f18b333d..66855c66b5 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -13,7 +13,9 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
+#include "nvim/cursor.h"
#include "nvim/diff.h"
+#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/extmark.h"
@@ -24,6 +26,7 @@
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
+#include "nvim/move.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/os/input.h"
@@ -61,7 +64,8 @@ static xfmark_T namedfm[NGLOBALMARKS];
*/
int setmark(int c)
{
- return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
+ fmarkv_T view = mark_view_make(curwin->w_topline, curwin->w_cursor);
+ return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum, &view);
}
/// Free fmark_T item
@@ -90,9 +94,10 @@ void clear_fmark(fmark_T *fm)
* When "c" is upper case use file "fnum".
* Returns OK on success, FAIL if bad name given.
*/
-int setmark_pos(int c, pos_T *pos, int fnum)
+int setmark_pos(int c, pos_T *pos, int fnum, fmarkv_T *view_pt)
{
int i;
+ fmarkv_T view = view_pt != NULL ? *view_pt : (fmarkv_T)INIT_FMARKV;
// Check for a special key (may cause islower() to crash).
if (c < 0) {
@@ -117,7 +122,7 @@ int setmark_pos(int c, pos_T *pos, int fnum)
}
if (c == '"') {
- RESET_FMARK(&buf->b_last_cursor, *pos, buf->b_fnum);
+ RESET_FMARK(&buf->b_last_cursor, *pos, buf->b_fnum, view);
return OK;
}
@@ -147,7 +152,7 @@ int setmark_pos(int c, pos_T *pos, int fnum)
if (ASCII_ISLOWER(c)) {
i = c - 'a';
- RESET_FMARK(buf->b_namedm + i, *pos, fnum);
+ RESET_FMARK(buf->b_namedm + i, *pos, fnum, view);
return OK;
}
if (ASCII_ISUPPER(c) || ascii_isdigit(c)) {
@@ -156,7 +161,7 @@ int setmark_pos(int c, pos_T *pos, int fnum)
} else {
i = c - 'A';
}
- RESET_XFMARK(namedfm + i, *pos, fnum, NULL);
+ RESET_XFMARK(namedfm + i, *pos, fnum, view, NULL);
return OK;
}
return FAIL;
@@ -171,7 +176,7 @@ void setpcmark(void)
xfmark_T *fm;
// for :global the mark is set only once
- if (global_busy || listcmd_busy || cmdmod.keepjumps) {
+ if (global_busy || listcmd_busy || (cmdmod.cmod_flags & CMOD_KEEPJUMPS)) {
return;
}
@@ -202,7 +207,8 @@ void setpcmark(void)
curwin->w_jumplistidx = curwin->w_jumplistlen;
fm = &curwin->w_jumplist[curwin->w_jumplistlen - 1];
- SET_XFMARK(fm, curwin->w_pcmark, curbuf->b_fnum, NULL);
+ fmarkv_T view = mark_view_make(curwin->w_topline, curwin->w_pcmark);
+ SET_XFMARK(fm, curwin->w_pcmark, curbuf->b_fnum, view, NULL);
}
/*
@@ -217,249 +223,411 @@ void checkpcmark(void)
&& (equalpos(curwin->w_pcmark, curwin->w_cursor)
|| curwin->w_pcmark.lnum == 0)) {
curwin->w_pcmark = curwin->w_prev_pcmark;
- curwin->w_prev_pcmark.lnum = 0; // Show it has been checked
}
+ curwin->w_prev_pcmark.lnum = 0; // it has been checked
}
-/*
- * move "count" positions in the jump list (count may be negative)
- */
-pos_T *movemark(int count)
+/// Get mark in "count" position in the |jumplist| relative to the current index.
+///
+/// If the mark is in a different buffer, it will be skipped unless the buffer exists.
+///
+/// @note cleanup_jumplist() is run, which removes duplicate marks, and
+/// changes win->w_jumplistidx.
+/// @param[in] win window to get jumplist from.
+/// @param[in] count count to move may be negative.
+///
+/// @return mark, NULL if out of jumplist bounds.
+fmark_T *get_jumplist(win_T *win, int count)
{
- pos_T *pos;
- xfmark_T *jmp;
+ xfmark_T *jmp = NULL;
- cleanup_jumplist(curwin, true);
+ cleanup_jumplist(win, true);
- if (curwin->w_jumplistlen == 0) { // nothing to jump to
- return (pos_T *)NULL;
+ if (win->w_jumplistlen == 0) { // nothing to jump to
+ return NULL;
}
for (;;) {
- if (curwin->w_jumplistidx + count < 0
- || curwin->w_jumplistidx + count >= curwin->w_jumplistlen) {
- return (pos_T *)NULL;
+ if (win->w_jumplistidx + count < 0
+ || win->w_jumplistidx + count >= win->w_jumplistlen) {
+ return NULL;
}
- /*
- * if first CTRL-O or CTRL-I command after a jump, add cursor position
- * to list. Careful: If there are duplicates (CTRL-O immediately after
- * starting Vim on a file), another entry may have been removed.
- */
- if (curwin->w_jumplistidx == curwin->w_jumplistlen) {
+ // if first CTRL-O or CTRL-I command after a jump, add cursor position
+ // to list. Careful: If there are duplicates (CTRL-O immediately after
+ // starting Vim on a file), another entry may have been removed.
+ if (win->w_jumplistidx == win->w_jumplistlen) {
setpcmark();
- --curwin->w_jumplistidx; // skip the new entry
- if (curwin->w_jumplistidx + count < 0) {
- return (pos_T *)NULL;
+ win->w_jumplistidx--; // skip the new entry
+ if (win->w_jumplistidx + count < 0) {
+ return NULL;
}
}
- curwin->w_jumplistidx += count;
+ win->w_jumplistidx += count;
- jmp = curwin->w_jumplist + curwin->w_jumplistidx;
+ jmp = win->w_jumplist + win->w_jumplistidx;
if (jmp->fmark.fnum == 0) {
+ // Resolve the fnum (buff number) in the mark before returning it (shada)
fname2fnum(jmp);
}
if (jmp->fmark.fnum != curbuf->b_fnum) {
- // jump to other file
- if (buflist_findnr(jmp->fmark.fnum) == NULL) { // Skip this one ..
+ // Needs to switch buffer, if it can't find it skip the mark
+ if (buflist_findnr(jmp->fmark.fnum) == NULL) {
count += count < 0 ? -1 : 1;
continue;
}
- if (buflist_getfile(jmp->fmark.fnum, jmp->fmark.mark.lnum,
- 0, FALSE) == FAIL) {
- return (pos_T *)NULL;
- }
- // Set lnum again, autocommands my have changed it
- curwin->w_cursor = jmp->fmark.mark;
- pos = (pos_T *)-1;
- } else {
- pos = &(jmp->fmark.mark);
}
- return pos;
+ break;
}
+ return &jmp->fmark;
}
-/*
- * Move "count" positions in the changelist (count may be negative).
- */
-pos_T *movechangelist(int count)
+/// Get mark in "count" position in the |changelist| relative to the current index.
+///
+/// @note Changes the win->w_changelistidx.
+/// @param[in] win window to get jumplist from.
+/// @param[in] count count to move may be negative.
+///
+/// @return mark, NULL if out of bounds.
+fmark_T *get_changelist(buf_T *buf, win_T *win, int count)
{
int n;
+ fmark_T *fm;
- if (curbuf->b_changelistlen == 0) { // nothing to jump to
- return (pos_T *)NULL;
+ if (buf->b_changelistlen == 0) { // nothing to jump to
+ return NULL;
}
- n = curwin->w_changelistidx;
+ n = win->w_changelistidx;
if (n + count < 0) {
if (n == 0) {
- return (pos_T *)NULL;
+ return NULL;
}
n = 0;
- } else if (n + count >= curbuf->b_changelistlen) {
- if (n == curbuf->b_changelistlen - 1) {
- return (pos_T *)NULL;
+ } else if (n + count >= buf->b_changelistlen) {
+ if (n == buf->b_changelistlen - 1) {
+ return NULL;
}
- n = curbuf->b_changelistlen - 1;
+ n = buf->b_changelistlen - 1;
} else {
n += count;
}
- curwin->w_changelistidx = n;
- return &(curbuf->b_changelist[n].mark);
+ win->w_changelistidx = n;
+ fm = &(buf->b_changelist[n]);
+ // Changelist marks are always buffer local, Shada does not set it when loading
+ fm->fnum = curbuf->handle;
+ return &(buf->b_changelist[n]);
}
-/*
- * Find mark "c" in buffer pointed to by "buf".
- * If "changefile" is TRUE it's allowed to edit another file for '0, 'A, etc.
- * If "fnum" is not NULL store the fnum there for '0, 'A etc., don't edit
- * another file.
- * Returns:
- * - pointer to pos_T if found. lnum is 0 when mark not set, -1 when mark is
- * in another file which can't be gotten. (caller needs to check lnum!)
- * - NULL if there is no mark called 'c'.
- * - -1 if mark is in other file and jumped there (only if changefile is TRUE)
- */
-pos_T *getmark_buf(buf_T *buf, int c, bool changefile)
+/// Get a named mark.
+///
+/// All types of marks, even those that are not technically a mark will be returned as such. Use
+/// mark_move_to() to move to the mark.
+/// @note Some of the pointers are statically allocated, if in doubt make a copy. For more
+/// information read mark_get_local().
+/// @param buf Buffer to get the mark from.
+/// @param win Window to get or calculate the mark from (motion type marks, context mark).
+/// @param fmp[out] Optional pointer to store the result in, as a workaround for the note above.
+/// @param flag MarkGet value
+/// @param name Name of the mark.
+///
+/// @return Mark if found, otherwise NULL. For @c kMarkBufLocal, NULL is returned
+/// when no mark is found in @a buf.
+fmark_T *mark_get(buf_T *buf, win_T *win, fmark_T *fmp, MarkGet flag, int name)
{
- return getmark_buf_fnum(buf, c, changefile, NULL);
+ fmark_T *fm = NULL;
+ if (ASCII_ISUPPER(name) || ascii_isdigit(name)) {
+ // Global marks
+ xfmark_T *xfm = mark_get_global(!(flag & kMarkAllNoResolve), name);
+ fm = &xfm->fmark;
+ // Only wanted marks belonging to the buffer
+ if ((flag & kMarkBufLocal) && xfm->fmark.fnum != buf->handle) {
+ return NULL;
+ }
+ } else if (name > 0 && name < NMARK_LOCAL_MAX) {
+ // Local Marks
+ fm = mark_get_local(buf, win, name);
+ }
+ if (fmp != NULL && fm != NULL) {
+ *fmp = *fm;
+ return fmp;
+ }
+ return fm;
}
-pos_T *getmark(int c, bool changefile)
+/// Get a global mark {A-Z0-9}.
+///
+/// @param name the name of the mark.
+/// @param resolve Whether to try resolving the mark fnum (i.e., load the buffer stored in
+/// the mark fname and update the xfmark_T (expensive)).
+///
+/// @return Mark
+xfmark_T *mark_get_global(bool resolve, int name)
{
- return getmark_buf_fnum(curbuf, c, changefile, NULL);
+ xfmark_T *mark;
+
+ if (ascii_isdigit(name)) {
+ name = name - '0' + NMARKS;
+ } else if (ASCII_ISUPPER(name)) {
+ name -= 'A';
+ } else {
+ // Not a valid mark name
+ assert(false);
+ }
+ mark = &namedfm[name];
+
+ if (resolve && mark->fmark.fnum == 0) {
+ // Resolve filename to fnum (SHADA marks)
+ fname2fnum(mark);
+ }
+ return mark;
}
-pos_T *getmark_buf_fnum(buf_T *buf, int c, bool changefile, int *fnum)
+/// Get a local mark (lowercase and symbols).
+///
+/// Some marks are not actually marks, but positions that are never adjusted or motions presented as
+/// marks. Search first for marks and fallback to finding motion type marks. If it's known
+/// ahead of time that the mark is actually a motion use the mark_get_motion() directly.
+///
+/// @note Lowercase, last_cursor '"', last insert '^', last change '.' are not statically
+/// allocated, everything else is.
+/// @param name the name of the mark.
+/// @param win window to retrieve marks that belong to it (motions and context mark).
+/// @param buf buf to retrieve marks that belong to it.
+///
+/// @return Mark, NULL if not found.
+fmark_T *mark_get_local(buf_T *buf, win_T *win, int name)
{
- pos_T *posp;
- pos_T *startp, *endp;
- static pos_T pos_copy;
+ fmark_T *mark = NULL;
+ if (ASCII_ISLOWER(name)) {
+ // normal named mark
+ mark = &buf->b_namedm[name - 'a'];
+ // to start of previous operator
+ } else if (name == '[') {
+ mark = pos_to_mark(buf, NULL, buf->b_op_start);
+ // to end of previous operator
+ } else if (name == ']') {
+ mark = pos_to_mark(buf, NULL, buf->b_op_end);
+ // visual marks
+ } else if (name == '<' || name == '>') {
+ mark = mark_get_visual(buf, name);
+ // previous context mark
+ } else if (name == '\'' || name == '`') {
+ // TODO(muniter): w_pcmark should be stored as a mark, but causes a nasty bug.
+ mark = pos_to_mark(curbuf, NULL, win->w_pcmark);
+ // to position when leaving buffer
+ } else if (name == '"') {
+ mark = &(buf->b_last_cursor);
+ // to where last Insert mode stopped
+ } else if (name == '^') {
+ mark = &(buf->b_last_insert);
+ // to where last change was made
+ } else if (name == '.') {
+ mark = &buf->b_last_change;
+ // Mark that are actually not marks but motions, e.g {, }, (, ), ...
+ } else {
+ mark = mark_get_motion(buf, win, name);
+ }
- posp = NULL;
+ if (mark) {
+ mark->fnum = buf->b_fnum;
+ }
- // Check for special key, can't be a mark name and might cause islower()
- // to crash.
- if (c < 0) {
- return posp;
- }
- if (c > '~') { // check for islower()/isupper()
- } else if (c == '\'' || c == '`') { // previous context mark
- pos_copy = curwin->w_pcmark; // need to make a copy because
- posp = &pos_copy; // w_pcmark may be changed soon
- } else if (c == '"') { // to pos when leaving buffer
- posp = &(buf->b_last_cursor.mark);
- } else if (c == '^') { // to where Insert mode stopped
- posp = &(buf->b_last_insert.mark);
- } else if (c == '.') { // to where last change was made
- posp = &(buf->b_last_change.mark);
- } else if (c == '[') { // to start of previous operator
- posp = &(buf->b_op_start);
- } else if (c == ']') { // to end of previous operator
- posp = &(buf->b_op_end);
- } else if (c == '{' || c == '}') { // to previous/next paragraph
- pos_T pos;
+ return mark;
+}
+
+/// Get marks that are actually motions but return them as marks
+///
+/// Gets the following motions as marks: '{', '}', '(', ')'
+/// @param name name of the mark
+/// @param win window to retrieve the cursor to calculate the mark.
+/// @param buf buf to wrap motion marks with it's buffer number (fm->fnum).
+///
+/// @return[static] Mark.
+fmark_T *mark_get_motion(buf_T *buf, win_T *win, int name)
+{
+ fmark_T *mark = NULL;
+ const pos_T pos = curwin->w_cursor;
+ const bool slcb = listcmd_busy;
+ listcmd_busy = true; // avoid that '' is changed
+ if (name == '{' || name == '}') { // to previous/next paragraph
oparg_T oa;
- bool slcb = listcmd_busy;
-
- pos = curwin->w_cursor;
- listcmd_busy = true; // avoid that '' is changed
- if (findpar(&oa.inclusive,
- c == '}' ? FORWARD : BACKWARD, 1L, NUL, FALSE)) {
- pos_copy = curwin->w_cursor;
- posp = &pos_copy;
+ if (findpar(&oa.inclusive, name == '}' ? FORWARD : BACKWARD, 1L, NUL, false)) {
+ mark = pos_to_mark(buf, NULL, win->w_cursor);
}
- curwin->w_cursor = pos;
- listcmd_busy = slcb;
- } else if (c == '(' || c == ')') { // to previous/next sentence
- pos_T pos;
- bool slcb = listcmd_busy;
-
- pos = curwin->w_cursor;
- listcmd_busy = true; // avoid that '' is changed
- if (findsent(c == ')' ? FORWARD : BACKWARD, 1L)) {
- pos_copy = curwin->w_cursor;
- posp = &pos_copy;
+ } else if (name == '(' || name == ')') { // to previous/next sentence
+ if (findsent(name == ')' ? FORWARD : BACKWARD, 1L)) {
+ mark = pos_to_mark(buf, NULL, win->w_cursor);
}
- curwin->w_cursor = pos;
- listcmd_busy = slcb;
- } else if (c == '<' || c == '>') { // start/end of visual area
- startp = &buf->b_visual.vi_start;
- endp = &buf->b_visual.vi_end;
- if (((c == '<') == lt(*startp, *endp) || endp->lnum == 0)
- && startp->lnum != 0) {
- posp = startp;
+ }
+ curwin->w_cursor = pos;
+ listcmd_busy = slcb;
+ return mark;
+}
+
+/// Get visual marks '<', '>'
+///
+/// This marks are different to normal marks:
+/// 1. Never adjusted.
+/// 2. Different behavior depending on editor state (visual mode).
+/// 3. Not saved in shada.
+/// 4. Re-ordered when defined in reverse.
+/// @param buf Buffer to get the mark from.
+/// @param name Mark name '<' or '>'.
+///
+/// @return[static] Mark
+fmark_T *mark_get_visual(buf_T *buf, int name)
+{
+ fmark_T *mark = NULL;
+ if (name == '<' || name == '>') {
+ // start/end of visual area
+ pos_T startp = buf->b_visual.vi_start;
+ pos_T endp = buf->b_visual.vi_end;
+ if (((name == '<') == lt(startp, endp) || endp.lnum == 0)
+ && startp.lnum != 0) {
+ mark = pos_to_mark(buf, NULL, startp);
} else {
- posp = endp;
+ mark = pos_to_mark(buf, NULL, endp);
}
- // For Visual line mode, set mark at begin or end of line
- if (buf->b_visual.vi_mode == 'V') {
- pos_copy = *posp;
- posp = &pos_copy;
- if (c == '<') {
- pos_copy.col = 0;
+ if (mark != NULL && buf->b_visual.vi_mode == 'V') {
+ if (name == '<') {
+ mark->mark.col = 0;
} else {
- pos_copy.col = MAXCOL;
+ mark->mark.col = MAXCOL;
}
- pos_copy.coladd = 0;
- }
- } else if (ASCII_ISLOWER(c)) { // normal named mark
- posp = &(buf->b_namedm[c - 'a'].mark);
- } else if (ASCII_ISUPPER(c) || ascii_isdigit(c)) { // named file mark
- if (ascii_isdigit(c)) {
- c = c - '0' + NMARKS;
- } else {
- c -= 'A';
+ mark->mark.coladd = 0;
}
- posp = &(namedfm[c].fmark.mark);
+ }
+ return mark;
+}
+
+/// Wrap a pos_T into an fmark_T, used to abstract marks handling.
+///
+/// Pass an fmp if multiple c
+/// @note view fields are set to 0.
+/// @param buf for fmark->fnum.
+/// @param pos for fmrak->mark.
+/// @param fmp pointer to save the mark.
+///
+/// @return[static] Mark with the given information.
+fmark_T *pos_to_mark(buf_T *buf, fmark_T *fmp, pos_T pos)
+{
+ static fmark_T fms = INIT_FMARK;
+ fmark_T *fm = fmp == NULL ? &fms : fmp;
+ fm->fnum = buf->handle;
+ fm->mark = pos;
+ return fm;
+}
- if (namedfm[c].fmark.fnum == 0) {
- fname2fnum(&namedfm[c]);
+/// Attempt to switch to the buffer of the given global mark
+///
+/// @param fm
+/// @param pcmark_on_switch leave a context mark when switching buffer.
+/// @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;
+ return res == true ? kMarkSwitchedBuf : kMarkMoveFailed;
+ }
+ return 0;
+}
+
+/// Move to the given file mark, changing the buffer and cursor position.
+///
+/// Validate the mark, switch to the buffer, and move the cursor.
+/// @param fm Mark, can be NULL will raise E78: Unknown mark
+/// @param flags MarkMove flags to configure the movement to the mark.
+///
+/// @return MarkMovekRes flags representing the outcome
+MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags)
+{
+ static fmark_T fm_copy = INIT_FMARK;
+ MarkMoveRes res = kMarkMoveSuccess;
+ if (!mark_check(fm)) {
+ res = kMarkMoveFailed;
+ goto end;
+ }
+
+ if (fm->fnum != curbuf->handle) {
+ // Need to change buffer
+ fm_copy = *fm; // Copy, autocommand may change it
+ fm = &fm_copy;
+ res |= switch_to_mark_buf(fm, !(flags & kMarkJumpList));
+ // Failed switching buffer
+ if (res & kMarkMoveFailed) {
+ goto end;
+ }
+ // Check line count now that the **destination buffer is loaded**.
+ if (!mark_check_line_bounds(curbuf, fm)) {
+ res |= kMarkMoveFailed;
+ goto end;
}
+ } else if (flags & kMarkContext) {
+ // Doing it in this condition avoids double context mark when switching buffer.
+ setpcmark();
+ }
+ // Move the cursor while keeping track of what changed for the caller
+ pos_T prev_pos = curwin->w_cursor;
+ pos_T pos = fm->mark;
+ curwin->w_cursor = fm->mark;
+ if (flags & kMarkBeginLine) {
+ beginline(BL_WHITE | BL_FIX);
+ }
+ res = prev_pos.lnum != pos.lnum ? res | kMarkChangedLine | kMarkChangedCursor : res;
+ res = prev_pos.col != pos.col ? res | kMarkChangedCol | kMarkChangedCursor : res;
+ if (flags & kMarkSetView) {
+ mark_view_restore(fm);
+ }
- if (fnum != NULL) {
- *fnum = namedfm[c].fmark.fnum;
- } else if (namedfm[c].fmark.fnum != buf->b_fnum) {
- // mark is in another file
- posp = &pos_copy;
-
- if (namedfm[c].fmark.mark.lnum != 0
- && changefile && namedfm[c].fmark.fnum) {
- if (buflist_getfile(namedfm[c].fmark.fnum,
- (linenr_T)1, GETF_SETMARK, FALSE) == OK) {
- // Set the lnum now, autocommands could have changed it
- curwin->w_cursor = namedfm[c].fmark.mark;
- return (pos_T *)-1;
- }
- pos_copy.lnum = -1; // can't get file
- } else {
- pos_copy.lnum = 0; // mark exists, but is not valid in current buffer
- }
+ if (res & kMarkSwitchedBuf || res & kMarkChangedCursor) {
+ check_cursor();
+ }
+end:
+ return res;
+}
+
+/// Restore the mark view.
+/// By remembering the offset between topline and mark lnum at the time of
+/// definition, this function restores the "view".
+/// @note Assumes the mark has been checked, is valid.
+/// @param fm the named mark.
+void mark_view_restore(fmark_T *fm)
+{
+ if (fm != NULL && fm->view.topline_offset >= 0) {
+ linenr_T topline = fm->mark.lnum - fm->view.topline_offset;
+ // If the mark does not have a view, topline_offset is MAXLNUM,
+ // and this check can prevent restoring mark view in that case.
+ if (topline >= 1) {
+ set_topline(curwin, topline);
}
}
+}
- return posp;
+fmarkv_T mark_view_make(linenr_T topline, pos_T pos)
+{
+ return (fmarkv_T){ pos.lnum - topline };
}
-/// Search for the next named mark in the current file.
+/// Search for the next named mark in the current file from a start position.
///
-/// @param startpos where to start
-/// @param dir direction for search
+/// @param startpos where to start.
+/// @param dir direction for search.
///
-/// @return pointer to pos_T of the next mark or NULL if no mark is found.
-pos_T *getnextmark(pos_T *startpos, int dir, int begin_line)
+/// @return next mark or NULL if no mark is found.
+fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line)
{
int i;
- pos_T *result = NULL;
+ fmark_T *result = NULL;
pos_T pos;
pos = *startpos;
- // When searching backward and leaving the cursor on the first non-blank,
- // position must be in a previous line.
- // When searching forward and leaving the cursor on the first non-blank,
- // position must be in a next line.
if (dir == BACKWARD && begin_line) {
pos.col = 0;
} else if (dir == FORWARD && begin_line) {
@@ -469,14 +637,14 @@ pos_T *getnextmark(pos_T *startpos, int dir, int begin_line)
for (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))
+ if ((result == NULL || lt(curbuf->b_namedm[i].mark, result->mark))
&& lt(pos, curbuf->b_namedm[i].mark)) {
- result = &curbuf->b_namedm[i].mark;
+ result = &curbuf->b_namedm[i];
}
} else {
- if ((result == NULL || lt(*result, curbuf->b_namedm[i].mark))
+ if ((result == NULL || lt(result->mark, curbuf->b_namedm[i].mark))
&& lt(curbuf->b_namedm[i].mark, pos)) {
- result = &curbuf->b_namedm[i].mark;
+ result = &curbuf->b_namedm[i];
}
}
}
@@ -518,7 +686,7 @@ static void fname2fnum(xfmark_T *fm)
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((char *)NameBuff, (char *)p, (linenr_T)1, 0);
}
}
@@ -529,7 +697,7 @@ static void fname2fnum(xfmark_T *fm)
*/
void fmarks_check_names(buf_T *buf)
{
- char_u *name = buf->b_ffname;
+ char_u *name = (char_u *)buf->b_ffname;
int i;
if (buf->b_ffname == NULL) {
@@ -551,35 +719,54 @@ static void fmarks_check_one(xfmark_T *fm, char_u *name, buf_T *buf)
{
if (fm->fmark.fnum == 0
&& fm->fname != NULL
- && fnamecmp(name, fm->fname) == 0) {
+ && FNAMECMP(name, fm->fname) == 0) {
fm->fmark.fnum = buf->b_fnum;
XFREE_CLEAR(fm->fname);
}
}
-/*
- * Check a if a position from a mark is valid.
- * Give and error message and return FAIL if not.
- */
-int check_mark(pos_T *pos)
+/// 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.
+///
+/// @return true if the mark passes all the above checks, else false.
+bool mark_check(fmark_T *fm)
{
- if (pos == NULL) {
+ if (fm == NULL) {
emsg(_(e_umark));
- return FAIL;
- }
- if (pos->lnum <= 0) {
- // lnum is negative if mark is in another file can can't get that
- // file, error message already give then.
- if (pos->lnum == 0) {
+ 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));
}
- return FAIL;
+ return false;
}
- if (pos->lnum > curbuf->b_ml.ml_line_count) {
+ // Only check for valid line number if the buffer is loaded.
+ if (fm->fnum == curbuf->handle && !mark_check_line_bounds(curbuf, fm)) {
+ 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.
+/// @return true if below line count else false.
+bool mark_check_line_bounds(buf_T *buf, fmark_T *fm)
+{
+ if (buf != NULL && fm->mark.lnum > buf->b_ml.ml_line_count) {
emsg(_(e_markinval));
- return FAIL;
+ return false;
}
- return OK;
+ return true;
}
/// Clear all marks and change list in the given buffer
@@ -615,7 +802,7 @@ char_u *fm_getname(fmark_T *fmark, int lead_len)
if (fmark->fnum == curbuf->b_fnum) { // current buffer
return mark_line(&(fmark->mark), lead_len);
}
- return buflist_nr2name(fmark->fnum, FALSE, TRUE);
+ return (char_u *)buflist_nr2name(fmark->fnum, false, true);
}
/*
@@ -630,14 +817,14 @@ static char_u *mark_line(pos_T *mp, int lead_len)
if (mp->lnum == 0 || mp->lnum > curbuf->b_ml.ml_line_count) {
return vim_strsave((char_u *)"-invalid-");
}
- assert(Columns >= 0 && (size_t)Columns <= SIZE_MAX);
+ assert(Columns >= 0);
// Allow for up to 5 bytes per character.
- s = vim_strnsave(skipwhite(ml_get(mp->lnum)), (size_t)Columns * 5);
+ s = vim_strnsave((char_u *)skipwhite((char *)ml_get(mp->lnum)), (size_t)Columns * 5);
// Truncate the line to fit it in the window
len = 0;
for (p = s; *p != NUL; MB_PTR_ADV(p)) {
- len += ptr2cells(p);
+ len += ptr2cells((char *)p);
if (len >= Columns - lead_len) {
break;
}
@@ -651,7 +838,7 @@ static char_u *mark_line(pos_T *mp, int lead_len)
*/
void ex_marks(exarg_T *eap)
{
- char_u *arg = eap->arg;
+ char_u *arg = (char_u *)eap->arg;
int i;
char_u *name;
pos_T *posp, *startp, *endp;
@@ -668,7 +855,7 @@ void ex_marks(exarg_T *eap)
if (namedfm[i].fmark.fnum != 0) {
name = fm_getname(&namedfm[i].fmark, 15);
} else {
- name = namedfm[i].fname;
+ name = (char_u *)namedfm[i].fname;
}
if (name != NULL) {
show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
@@ -717,7 +904,7 @@ static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int cu
}
}
} else if (!got_int
- && (arg == NULL || vim_strchr(arg, c) != NULL)
+ && (arg == NULL || vim_strchr((char *)arg, c) != NULL)
&& p->lnum != 0) {
// don't output anything if 'q' typed at --more-- prompt
if (name == NULL && current) {
@@ -732,8 +919,8 @@ static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int cu
}
msg_putchar('\n');
if (!got_int) {
- snprintf((char *)IObuff, IOSIZE, " %c %6ld %4d ", c, p->lnum, p->col);
- msg_outtrans(IObuff);
+ snprintf((char *)IObuff, IOSIZE, " %c %6" PRIdLINENR " %4d ", c, p->lnum, p->col);
+ msg_outtrans((char *)IObuff);
if (name != NULL) {
msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
}
@@ -767,7 +954,7 @@ void ex_delmarks(exarg_T *eap)
emsg(_(e_argreq));
} else {
// clear specified marks only
- for (p = eap->arg; *p != NUL; ++p) {
+ for (p = (char_u *)eap->arg; *p != NUL; p++) {
lower = ASCII_ISLOWER(*p);
digit = ascii_isdigit(*p);
if (lower || digit || ASCII_ISUPPER(*p)) {
@@ -844,6 +1031,11 @@ void ex_jumps(exarg_T *eap)
if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
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.
+ if (name == NULL && i == curwin->w_jumplistidx) {
+ name = vim_strsave((char_u *)"-invalid-");
+ }
// apply :filter /pat/ or file name not available
if (name == NULL || message_filtered(name)) {
xfree(name);
@@ -855,13 +1047,11 @@ void ex_jumps(exarg_T *eap)
xfree(name);
break;
}
- sprintf((char *)IObuff, "%c %2d %5ld %4d ",
- 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);
+ snprintf((char *)IObuff, IOSIZE, "%c %2d %5" PRIdLINENR " %4d ",
+ 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((char *)IObuff);
msg_outtrans_attr(name,
curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
? HL_ATTR(HLF_D) : 0);
@@ -905,7 +1095,7 @@ void ex_changes(exarg_T *eap)
: curwin->w_changelistidx - i,
(long)curbuf->b_changelist[i].mark.lnum,
curbuf->b_changelist[i].mark.col);
- msg_outtrans(IObuff);
+ msg_outtrans((char *)IObuff);
name = mark_line(&curbuf->b_changelist[i].mark, 17);
msg_outtrans_attr(name, HL_ATTR(HLF_D));
xfree(name);
@@ -918,7 +1108,7 @@ void ex_changes(exarg_T *eap)
}
}
-#define one_adjust(add) \
+#define ONE_ADJUST(add) \
{ \
lp = add; \
if (*lp >= line1 && *lp <= line2) \
@@ -933,7 +1123,7 @@ void ex_changes(exarg_T *eap)
}
// don't delete the line, just put at first deleted line
-#define one_adjust_nodel(add) \
+#define ONE_ADJUST_NODEL(add) \
{ \
lp = add; \
if (*lp >= line1 && *lp <= line2) \
@@ -958,7 +1148,8 @@ void ex_changes(exarg_T *eap)
* 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, long amount, long amount_after, ExtmarkOp op)
+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);
}
@@ -968,14 +1159,14 @@ void mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_after,
// This is only useful when folds need to be moved in a way different to
// calling foldMarkAdjust() with arguments line1, line2, amount, amount_after,
// for an example of why this may be necessary, see do_move().
-void mark_adjust_nofold(linenr_T line1, linenr_T line2, long amount, long amount_after,
+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);
}
-static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, long amount_after,
- bool adjust_folds, ExtmarkOp op)
+static void mark_adjust_internal(linenr_T line1, linenr_T line2, linenr_T amount,
+ linenr_T amount_after, bool adjust_folds, ExtmarkOp op)
{
int i;
int fnum = curbuf->b_fnum;
@@ -986,40 +1177,39 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
return;
}
- if (!cmdmod.lockmarks) {
+ 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));
+ ONE_ADJUST(&(curbuf->b_namedm[i].mark.lnum));
if (namedfm[i].fmark.fnum == fnum) {
- one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
if (namedfm[i].fmark.fnum == fnum) {
- one_adjust_nodel(&(namedfm[i].fmark.mark.lnum));
+ ONE_ADJUST_NODEL(&(namedfm[i].fmark.mark.lnum));
}
}
// last Insert position
- one_adjust(&(curbuf->b_last_insert.mark.lnum));
+ ONE_ADJUST(&(curbuf->b_last_insert.mark.lnum));
// last change position
- one_adjust(&(curbuf->b_last_change.mark.lnum));
+ ONE_ADJUST(&(curbuf->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));
+ ONE_ADJUST(&(curbuf->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 (i = 0; i < curbuf->b_changelistlen; i++) {
+ ONE_ADJUST_NODEL(&(curbuf->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(&(curbuf->b_visual.vi_start.lnum));
+ ONE_ADJUST_NODEL(&(curbuf->b_visual.vi_end.lnum));
// quickfix marks
if (!qf_mark_adjust(NULL, line1, line2, amount, amount_after)) {
@@ -1042,44 +1232,44 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
}
// previous context mark
- one_adjust(&(curwin->w_pcmark.lnum));
+ ONE_ADJUST(&(curwin->w_pcmark.lnum));
// previous pcmark
- one_adjust(&(curwin->w_prev_pcmark.lnum));
+ ONE_ADJUST(&(curwin->w_prev_pcmark.lnum));
// saved cursor for formatting
if (saved_cursor.lnum != 0) {
- one_adjust_nodel(&(saved_cursor.lnum));
+ ONE_ADJUST_NODEL(&(saved_cursor.lnum));
}
/*
* Adjust items in all windows related to the current buffer.
*/
FOR_ALL_TAB_WINDOWS(tab, win) {
- if (!cmdmod.lockmarks) {
+ 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++) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
- one_adjust_nodel(&(win->w_jumplist[i].fmark.mark.lnum));
+ ONE_ADJUST_NODEL(&(win->w_jumplist[i].fmark.mark.lnum));
}
}
}
if (win->w_buffer == curbuf) {
- if (!cmdmod.lockmarks) {
+ if ((cmdmod.cmod_flags & CMOD_LOCKMARKS) == 0) {
// marks in the tag stack
for (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));
+ ONE_ADJUST_NODEL(&(win->w_tagstack[i].fmark.mark.lnum));
}
}
}
// the displayed Visual area
if (win->w_old_cursor_lnum != 0) {
- one_adjust_nodel(&(win->w_old_cursor_lnum));
- one_adjust_nodel(&(win->w_old_visual_lnum));
+ ONE_ADJUST_NODEL(&(win->w_old_cursor_lnum));
+ ONE_ADJUST_NODEL(&(win->w_old_visual_lnum));
}
// topline and cursor position for windows with the same buffer
@@ -1127,14 +1317,14 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
}
// This code is used often, needs to be fast.
-#define col_adjust(pp) \
+#define COL_ADJUST(pp) \
{ \
posp = pp; \
if (posp->lnum == lnum && posp->col >= mincol) \
{ \
posp->lnum += lnum_amount; \
assert(col_amount > INT_MIN && col_amount <= INT_MAX); \
- if (col_amount < 0 && posp->col <= (colnr_T)-col_amount) { \
+ if (col_amount < 0 && posp->col <= (colnr_T) - col_amount) { \
posp->col = 0; \
} else if (posp->col < spaces_removed) { \
posp->col = (int)col_amount + spaces_removed; \
@@ -1149,52 +1339,52 @@ static void mark_adjust_internal(linenr_T line1, linenr_T line2, long amount, lo
// 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, long lnum_amount, long col_amount,
+void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long col_amount,
int spaces_removed)
{
int i;
int fnum = curbuf->b_fnum;
pos_T *posp;
- if ((col_amount == 0L && lnum_amount == 0L) || cmdmod.lockmarks) {
+ if ((col_amount == 0L && lnum_amount == 0L) || (cmdmod.cmod_flags & CMOD_LOCKMARKS)) {
return; // nothing to do
}
// named marks, lower case and upper case
for (i = 0; i < NMARKS; i++) {
- col_adjust(&(curbuf->b_namedm[i].mark));
+ COL_ADJUST(&(curbuf->b_namedm[i].mark));
if (namedfm[i].fmark.fnum == fnum) {
- col_adjust(&(namedfm[i].fmark.mark));
+ COL_ADJUST(&(namedfm[i].fmark.mark));
}
}
for (i = NMARKS; i < NGLOBALMARKS; i++) {
if (namedfm[i].fmark.fnum == fnum) {
- col_adjust(&(namedfm[i].fmark.mark));
+ COL_ADJUST(&(namedfm[i].fmark.mark));
}
}
// last Insert position
- col_adjust(&(curbuf->b_last_insert.mark));
+ COL_ADJUST(&(curbuf->b_last_insert.mark));
// last change position
- col_adjust(&(curbuf->b_last_change.mark));
+ COL_ADJUST(&(curbuf->b_last_change.mark));
// list of change positions
- for (i = 0; i < curbuf->b_changelistlen; ++i) {
- col_adjust(&(curbuf->b_changelist[i].mark));
+ for (i = 0; i < curbuf->b_changelistlen; i++) {
+ COL_ADJUST(&(curbuf->b_changelist[i].mark));
}
// Visual area
- col_adjust(&(curbuf->b_visual.vi_start));
- col_adjust(&(curbuf->b_visual.vi_end));
+ COL_ADJUST(&(curbuf->b_visual.vi_start));
+ COL_ADJUST(&(curbuf->b_visual.vi_end));
// previous context mark
- col_adjust(&(curwin->w_pcmark));
+ COL_ADJUST(&(curwin->w_pcmark));
// previous pcmark
- col_adjust(&(curwin->w_prev_pcmark));
+ COL_ADJUST(&(curwin->w_prev_pcmark));
// saved cursor for formatting
- col_adjust(&saved_cursor);
+ COL_ADJUST(&saved_cursor);
/*
* Adjust items in all windows related to the current buffer.
@@ -1203,7 +1393,7 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_a
// marks in the jumplist
for (i = 0; i < win->w_jumplistlen; ++i) {
if (win->w_jumplist[i].fmark.fnum == fnum) {
- col_adjust(&(win->w_jumplist[i].fmark.mark));
+ COL_ADJUST(&(win->w_jumplist[i].fmark.mark));
}
}
@@ -1211,13 +1401,13 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, long lnum_amount, long col_a
// marks in the tag stack
for (i = 0; i < win->w_tagstacklen; i++) {
if (win->w_tagstack[i].fmark.fnum == fnum) {
- col_adjust(&(win->w_tagstack[i].fmark.mark));
+ COL_ADJUST(&(win->w_tagstack[i].fmark.mark));
}
}
// cursor position for other windows with the same buffer
if (win != curwin) {
- col_adjust(&win->w_cursor);
+ COL_ADJUST(&win->w_cursor);
}
}
}
@@ -1306,7 +1496,7 @@ void copy_jumplist(win_T *from, win_T *to)
for (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 = vim_strsave(from->w_jumplist[i].fname);
+ to->w_jumplist[i].fname = xstrdup(from->w_jumplist[i].fname);
}
}
to->w_jumplistlen = from->w_jumplistlen;
@@ -1315,7 +1505,7 @@ void copy_jumplist(win_T *from, win_T *to)
/// Iterate over jumplist items
///
-/// @warning No jumplist-editing functions must be run while iteration is in
+/// @warning No jumplist-editing functions must be called while iteration is in
/// progress.
///
/// @param[in] iter Iterator. Pass NULL to start iteration.
@@ -1328,7 +1518,7 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win, x
FUNC_ATTR_NONNULL_ARG(2, 3) FUNC_ATTR_WARN_UNUSED_RESULT
{
if (iter == NULL && win->w_jumplistlen == 0) {
- *fm = (xfmark_T) { { { 0, 0, 0 }, 0, 0, NULL }, NULL };
+ *fm = (xfmark_T)INIT_XFMARK;
return NULL;
}
const xfmark_T *const iter_mark =
@@ -1345,7 +1535,7 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win, x
/// Iterate over global marks
///
-/// @warning No mark-editing functions must be run while iteration is in
+/// @warning No mark-editing functions must be called while iteration is in
/// progress.
///
/// @param[in] iter Iterator. Pass NULL to start iteration.
@@ -1419,7 +1609,7 @@ static inline const fmark_T *next_buffer_mark(const buf_T *const buf, char *cons
/// Iterate over buffer marks
///
-/// @warning No mark-editing functions must be run while iteration is in
+/// @warning No mark-editing functions must be called while iteration is in
/// progress.
///
/// @param[in] iter Iterator. Pass NULL to start iteration.
@@ -1536,7 +1726,7 @@ void free_jumplist(win_T *wp)
void set_last_cursor(win_T *win)
{
if (win->w_buffer != NULL) {
- RESET_FMARK(&win->w_buffer->b_last_cursor, win->w_cursor, 0);
+ RESET_FMARK(&win->w_buffer->b_last_cursor, win->w_cursor, 0, ((fmarkv_T)INIT_FMARKV));
}
}
@@ -1574,14 +1764,13 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
// double-wide character.
if (lp->coladd == 1
&& p[lp->col] != TAB
- && vim_isprintc(utf_ptr2char(p + lp->col))
- && ptr2cells(p + lp->col) > 1) {
+ && vim_isprintc(utf_ptr2char((char *)p + lp->col))
+ && ptr2cells((char *)p + lp->col) > 1) {
lp->coladd = 0;
}
}
}
-
// Add information about mark 'mname' to list 'l'
static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, const char *fname)
FUNC_ATTR_NONNULL_ARG(1, 2, 3)
@@ -1609,7 +1798,6 @@ static int add_mark(list_T *l, const char *mname, const pos_T *pos, int bufnr, c
return OK;
}
-
/// Get information about marks local to a buffer.
///
/// @param[in] buf Buffer to get the marks from
@@ -1639,9 +1827,10 @@ void get_buf_local_marks(const buf_T *buf, list_T *l)
/// Get a global mark
///
+/// @note Mark might not have it's fnum resolved.
/// @param[in] Name of named mark
/// @param[out] Global/file mark
-xfmark_T get_global_mark(char name)
+xfmark_T get_raw_global_mark(char name)
{
return namedfm[mark_global_index(name)];
}
@@ -1658,9 +1847,9 @@ void get_global_marks(list_T *l)
// Marks 'A' to 'Z' and '0' to '9'
for (int i = 0; i < NMARKS + EXTRA_MARKS; i++) {
if (namedfm[i].fmark.fnum != 0) {
- name = (char *)buflist_nr2name(namedfm[i].fmark.fnum, true, true);
+ name = buflist_nr2name(namedfm[i].fmark.fnum, true, true);
} else {
- name = (char *)namedfm[i].fname;
+ name = namedfm[i].fname;
}
if (name != NULL) {
mname[1] = i >= NMARKS ? (char)(i - NMARKS + '0') : (char)(i + 'A');