// 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>
#include <inttypes.h>
#include <string.h>
#include <limits.h>
#include "nvim/vim.h"
#include "nvim/ascii.h"
#include "nvim/mark.h"
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/diff.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/fileio.h"
#include "nvim/fold.h"
#include "nvim/mbyte.h"
#include "nvim/memline.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/normal.h"
#include "nvim/option.h"
#include "nvim/path.h"
#include "nvim/quickfix.h"
#include "nvim/search.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/os/input.h"
/*
* This file contains routines to maintain and manipulate marks.
*/
/*
* If a named file mark's lnum is non-zero, it is valid.
* If a named file mark's fnum is non-zero, it is for an existing buffer,
* otherwise it is from .shada and namedfm[n].fname is the file name.
* 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
/*
* Set named mark "c" at current cursor position.
* Returns OK on success, FAIL if bad name given.
*/
int setmark(int c)
{
return setmark_pos(c, &curwin->w_cursor, curbuf->b_fnum);
}
/// Free fmark_T item
void free_fmark(fmark_T fm)
{
tv_dict_unref(fm.additional_data);
}
/// Free xfmark_T item
void free_xfmark(xfmark_T fm)
{
xfree(fm.fname);
free_fmark(fm.fmark);
}
/// Free and clear fmark_T item
void clear_fmark(fmark_T *fm)
FUNC_ATTR_NONNULL_ALL
{
free_fmark(*fm);
memset(fm, 0, sizeof(*fm));
}
/*
* Set named mark "c" to position "pos".
* 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 i;
/* Check for a special key (may cause islower() to crash). */
if (c < 0)
return FAIL;
if (c == '\'' || c == '`') {
if (pos == &curwin->w_cursor) {
setpcmark();
/* keep it even when the cursor doesn't move */
curwin->w_prev_pcmark = curwin->w_pcmark;
} else
curwin->w_pcmark = *pos;
return OK;
}
// Can't set a mark in a non-existant buffer.
buf_T *buf = buflist_findnr(fnum);
if (buf == NULL) {
return FAIL;
}
if (c == '"') {
RESET_FMARK(&buf->b_last_cursor, *pos, buf->b_fnum);
return OK;
}
/* Allow setting '[ and '] for an autocommand that simulates reading a
* file. */
if (c == '[') {
|