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.c152
1 files changed, 82 insertions, 70 deletions
diff --git a/src/nvim/mark.c b/src/nvim/mark.c
index f41793c8a6..f1a1f25e6c 100644
--- a/src/nvim/mark.c
+++ b/src/nvim/mark.c
@@ -4,20 +4,27 @@
// mark.c: functions for setting marks and jumping to them
#include <assert.h>
-#include <inttypes.h>
#include <limits.h>
+#include <stdint.h>
+#include <stdio.h>
#include <string.h>
#include "nvim/ascii.h"
#include "nvim/buffer.h"
+#include "nvim/buffer_defs.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/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/mark.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
@@ -25,16 +32,15 @@
#include "nvim/message.h"
#include "nvim/move.h"
#include "nvim/normal.h"
-#include "nvim/option.h"
+#include "nvim/option_defs.h"
#include "nvim/os/input.h"
#include "nvim/os/os.h"
-#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/sign.h"
#include "nvim/strings.h"
#include "nvim/textobject.h"
-#include "nvim/ui.h"
+#include "nvim/undo_defs.h"
#include "nvim/vim.h"
// This file contains routines to maintain and manipulate marks.
@@ -545,6 +551,7 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags)
// Need to change buffer
fm_copy = *fm; // Copy, autocommand may change it
fm = &fm_copy;
+ // Jump to the file with the mark
res |= switch_to_mark_buf(fm, !(flags & kMarkJumpList));
// Failed switching buffer
if (res & kMarkMoveFailed) {
@@ -562,6 +569,7 @@ MarkMoveRes mark_move_to(fmark_T *fm, MarkMove flags)
// Move the cursor while keeping track of what changed for the caller
pos_T prev_pos = curwin->w_cursor;
pos_T pos = fm->mark;
+ // Set lnum again, autocommands my have changed it
curwin->w_cursor = fm->mark;
if (flags & kMarkBeginLine) {
beginline(BL_WHITE | BL_FIX);
@@ -645,29 +653,31 @@ fmark_T *getnextmark(pos_T *startpos, int dir, int begin_line)
// until the mark is used to avoid a long startup delay.
static void fname2fnum(xfmark_T *fm)
{
- if (fm->fname != NULL) {
- // First expand "~/" in the file name to the home directory.
- // Don't expand the whole name, it may contain other '~' chars.
+ if (fm->fname == NULL) {
+ return;
+ }
+
+ // First expand "~/" in the file name to the home directory.
+ // Don't expand the whole name, it may contain other '~' chars.
#ifdef BACKSLASH_IN_FILENAME
- if (fm->fname[0] == '~' && (fm->fname[1] == '/' || fm->fname[1] == '\\')) {
+ if (fm->fname[0] == '~' && (fm->fname[1] == '/' || fm->fname[1] == '\\')) {
#else
- if (fm->fname[0] == '~' && (fm->fname[1] == '/')) {
+ if (fm->fname[0] == '~' && (fm->fname[1] == '/')) {
#endif
- expand_env("~/", NameBuff, MAXPATHL);
- int len = (int)strlen(NameBuff);
- STRLCPY(NameBuff + len, fm->fname + 2, MAXPATHL - len);
- } else {
- STRLCPY(NameBuff, fm->fname, MAXPATHL);
- }
+ expand_env("~/", NameBuff, MAXPATHL);
+ int len = (int)strlen(NameBuff);
+ xstrlcpy(NameBuff + len, fm->fname + 2, (size_t)(MAXPATHL - len));
+ } else {
+ xstrlcpy(NameBuff, fm->fname, MAXPATHL);
+ }
- // Try to shorten the file name.
- os_dirname((char_u *)IObuff, IOSIZE);
- char *p = path_shorten_fname(NameBuff, IObuff);
+ // Try to shorten the file name.
+ os_dirname(IObuff, IOSIZE);
+ char *p = path_shorten_fname(NameBuff, IObuff);
- // buflist_new() will call fmarks_check_names()
- (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
- }
+ // buflist_new() will call fmarks_check_names()
+ (void)buflist_new(NameBuff, p, (linenr_T)1, 0);
}
// Check all file marks for a name that matches the file name in buf.
@@ -675,7 +685,7 @@ static void fname2fnum(xfmark_T *fm)
// Used for marks that come from the .shada file.
void fmarks_check_names(buf_T *buf)
{
- char_u *name = (char_u *)buf->b_ffname;
+ char *name = buf->b_ffname;
int i;
if (buf->b_ffname == NULL) {
@@ -683,12 +693,12 @@ void fmarks_check_names(buf_T *buf)
}
for (i = 0; i < NGLOBALMARKS; i++) {
- fmarks_check_one(&namedfm[i], (char *)name, buf);
+ fmarks_check_one(&namedfm[i], name, buf);
}
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
for (i = 0; i < wp->w_jumplistlen; i++) {
- fmarks_check_one(&wp->w_jumplist[i], (char *)name, buf);
+ fmarks_check_one(&wp->w_jumplist[i], name, buf);
}
}
}
@@ -773,12 +783,12 @@ void clrallmarks(buf_T *const buf)
// Get name of file from a filemark.
// When it's in the current buffer, return the text at the mark.
// Returns an allocated string.
-char_u *fm_getname(fmark_T *fmark, int lead_len)
+char *fm_getname(fmark_T *fmark, int lead_len)
{
if (fmark->fnum == curbuf->b_fnum) { // current buffer
- return (char_u *)mark_line(&(fmark->mark), lead_len);
+ return mark_line(&(fmark->mark), lead_len);
}
- return (char_u *)buflist_nr2name(fmark->fnum, false, true);
+ return buflist_nr2name(fmark->fnum, false, true);
}
/// Return the line at mark "mp". Truncate to fit in window.
@@ -810,9 +820,9 @@ static char *mark_line(pos_T *mp, int lead_len)
// print the marks
void ex_marks(exarg_T *eap)
{
- char_u *arg = (char_u *)eap->arg;
+ char *arg = eap->arg;
int i;
- char_u *name;
+ char *name;
pos_T *posp, *startp, *endp;
if (arg != NULL && *arg == NUL) {
@@ -827,7 +837,7 @@ void ex_marks(exarg_T *eap)
if (namedfm[i].fmark.fnum != 0) {
name = fm_getname(&namedfm[i].fmark, 15);
} else {
- name = (char_u *)namedfm[i].fname;
+ name = namedfm[i].fname;
}
if (name != NULL) {
show_one_mark(i >= NMARKS ? i - NMARKS + '0' : i + 'A',
@@ -859,11 +869,11 @@ void ex_marks(exarg_T *eap)
}
/// @param current in current file
-static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int current)
+static void show_one_mark(int c, char *arg, pos_T *p, char *name_arg, int current)
{
static bool did_title = false;
bool mustfree = false;
- char_u *name = name_arg;
+ char *name = name_arg;
if (c == -1) { // finish up
if (did_title) {
@@ -876,14 +886,14 @@ 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((char *)arg, c) != NULL)
+ && (arg == NULL || vim_strchr(arg, c) != NULL)
&& p->lnum != 0) {
// don't output anything if 'q' typed at --more-- prompt
if (name == NULL && current) {
- name = (char_u *)mark_line(p, 15);
+ name = mark_line(p, 15);
mustfree = true;
}
- if (!message_filtered((char *)name)) {
+ if (!message_filtered(name)) {
if (!did_title) {
// Highlight title
msg_puts_title(_("\nmark line col file/text"));
@@ -891,10 +901,10 @@ 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 %6" PRIdLINENR " %4d ", c, p->lnum, p->col);
- msg_outtrans((char *)IObuff);
+ snprintf(IObuff, IOSIZE, " %c %6" PRIdLINENR " %4d ", c, p->lnum, p->col);
+ msg_outtrans(IObuff);
if (name != NULL) {
- msg_outtrans_attr((char *)name, current ? HL_ATTR(HLF_D) : 0);
+ msg_outtrans_attr(name, current ? HL_ATTR(HLF_D) : 0);
}
}
}
@@ -907,7 +917,7 @@ static void show_one_mark(int c, char_u *arg, pos_T *p, char_u *name_arg, int cu
// ":delmarks[!] [marks]"
void ex_delmarks(exarg_T *eap)
{
- char_u *p;
+ char *p;
int from, to;
int i;
int lower;
@@ -923,14 +933,14 @@ void ex_delmarks(exarg_T *eap)
emsg(_(e_argreq));
} else {
// clear specified marks only
- for (p = (char_u *)eap->arg; *p != NUL; p++) {
+ for (p = eap->arg; *p != NUL; p++) {
lower = ASCII_ISLOWER(*p);
digit = ascii_isdigit(*p);
if (lower || digit || ASCII_ISUPPER(*p)) {
if (p[1] == '-') {
// clear range of marks
- from = *p;
- to = p[2];
+ from = (uint8_t)(*p);
+ to = (uint8_t)p[2];
if (!(lower ? ASCII_ISLOWER(p[2])
: (digit ? ascii_isdigit(p[2])
: ASCII_ISUPPER(p[2])))
@@ -941,7 +951,7 @@ void ex_delmarks(exarg_T *eap)
p += 2;
} else {
// clear one lower case mark
- from = to = *p;
+ from = to = (uint8_t)(*p);
}
for (i = from; i <= to; i++) {
@@ -996,7 +1006,7 @@ void ex_jumps(exarg_T *eap)
msg_puts_title(_("\n jump line col file/text"));
for (i = 0; i < curwin->w_jumplistlen && !got_int; i++) {
if (curwin->w_jumplist[i].fmark.mark.lnum != 0) {
- name = (char *)fm_getname(&curwin->w_jumplist[i].fmark, 16);
+ 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.
@@ -1014,11 +1024,11 @@ void ex_jumps(exarg_T *eap)
xfree(name);
break;
}
- snprintf((char *)IObuff, IOSIZE, "%c %2d %5" PRIdLINENR " %4d ",
+ snprintf(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(IObuff);
msg_outtrans_attr(name,
curwin->w_jumplist[i].fmark.fnum == curbuf->b_fnum
? HL_ATTR(HLF_D) : 0);
@@ -1042,7 +1052,7 @@ void ex_clearjumps(exarg_T *eap)
void ex_changes(exarg_T *eap)
{
int i;
- char_u *name;
+ char *name;
// Highlight title
msg_puts_title(_("\nchange line col text"));
@@ -1058,9 +1068,9 @@ void ex_changes(exarg_T *eap)
i > curwin->w_changelistidx ? i - curwin->w_changelistidx : curwin->w_changelistidx - i,
(long)curbuf->b_changelist[i].mark.lnum,
curbuf->b_changelist[i].mark.col);
- msg_outtrans((char *)IObuff);
- name = (char_u *)mark_line(&curbuf->b_changelist[i].mark, 17);
- msg_outtrans_attr((char *)name, HL_ATTR(HLF_D));
+ msg_outtrans(IObuff);
+ name = mark_line(&curbuf->b_changelist[i].mark, 17);
+ msg_outtrans_attr(name, HL_ATTR(HLF_D));
xfree(name);
os_breakcheck();
}
@@ -1370,18 +1380,21 @@ void mark_col_adjust(linenr_T lnum, colnr_T mincol, linenr_T lnum_amount, long c
// When deleting lines, this may create duplicate marks in the
// jumplist. They will be removed here for the specified window.
-// When "checktail" is true, removes tail jump if it matches current position.
-void cleanup_jumplist(win_T *wp, bool checktail)
+// When "loadfiles" is true first ensure entries have the "fnum" field set
+// (this may be a bit slow).
+void cleanup_jumplist(win_T *wp, bool loadfiles)
{
int i;
- // Load all the files from the jump list. This is
- // needed to properly clean up duplicate entries, but will take some
- // time.
- for (i = 0; i < wp->w_jumplistlen; i++) {
- if ((wp->w_jumplist[i].fmark.fnum == 0)
- && (wp->w_jumplist[i].fmark.mark.lnum != 0)) {
- fname2fnum(&wp->w_jumplist[i]);
+ if (loadfiles) {
+ // If specified, load all the files from the jump list. This is
+ // needed to properly clean up duplicate entries, but will take some
+ // time.
+ for (i = 0; i < wp->w_jumplistlen; i++) {
+ if ((wp->w_jumplist[i].fmark.fnum == 0)
+ && (wp->w_jumplist[i].fmark.mark.lnum != 0)) {
+ fname2fnum(&wp->w_jumplist[i]);
+ }
}
}
@@ -1429,8 +1442,8 @@ void cleanup_jumplist(win_T *wp, bool checktail)
// When pointer is below last jump, remove the jump if it matches the current
// line. This avoids useless/phantom jumps. #9805
- if (checktail && wp->w_jumplistlen
- && wp->w_jumplistidx == wp->w_jumplistlen) {
+ if (loadfiles // otherwise (i.e.: Shada), last entry should be kept
+ && wp->w_jumplistlen && wp->w_jumplistidx == wp->w_jumplistlen) {
const xfmark_T *fm_last = &wp->w_jumplist[wp->w_jumplistlen - 1];
if (fm_last->fmark.fnum == curbuf->b_fnum
&& fm_last->fmark.mark.lnum == wp->w_cursor.lnum) {
@@ -1479,9 +1492,8 @@ const void *mark_jumplist_iter(const void *const iter, const win_T *const win, x
*fm = *iter_mark;
if (iter_mark == &(win->w_jumplist[win->w_jumplistlen - 1])) {
return NULL;
- } else {
- return iter_mark + 1;
}
+ return iter_mark + 1;
}
/// Iterate over global marks
@@ -1698,18 +1710,18 @@ void mark_mb_adjustpos(buf_T *buf, pos_T *lp)
FUNC_ATTR_NONNULL_ALL
{
if (lp->col > 0 || lp->coladd > 1) {
- const char_u *const p = (char_u *)ml_get_buf(buf, lp->lnum, false);
- if (*p == NUL || (int)STRLEN(p) < lp->col) {
+ const char *const p = ml_get_buf(buf, lp->lnum, false);
+ if (*p == NUL || (int)strlen(p) < lp->col) {
lp->col = 0;
} else {
- lp->col -= utf_head_off((char *)p, (char *)p + lp->col);
+ lp->col -= utf_head_off(p, p + lp->col);
}
// Reset "coladd" when the cursor would be on the right half of a
// double-wide character.
if (lp->coladd == 1
&& p[lp->col] != TAB
- && vim_isprintc(utf_ptr2char((char *)p + lp->col))
- && ptr2cells((char *)p + lp->col) > 1) {
+ && vim_isprintc(utf_ptr2char(p + lp->col))
+ && ptr2cells(p + lp->col) > 1) {
lp->coladd = 0;
}
}