Data Structures | Macros | Typedefs | Enumerations | Functions
shada.c File Reference
#include <assert.h>
#include <errno.h>
#include <inttypes.h>
#include <msgpack.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <uv.h>
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/eval/decode.h"
#include "nvim/eval/encode.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/fileio.h"
#include "nvim/garray.h"
#include "nvim/globals.h"
#include "nvim/lib/khash.h"
#include "nvim/lib/kvec.h"
#include "nvim/macros.h"
#include "nvim/mark.h"
#include "nvim/memory.h"
#include "nvim/message.h"
#include "nvim/msgpack_rpc/helpers.h"
#include "nvim/ops.h"
#include "nvim/option.h"
#include "nvim/os/fileio.h"
#include "nvim/os/os.h"
#include "nvim/os/time.h"
#include "nvim/path.h"
#include "nvim/pos.h"
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/search.h"
#include "nvim/shada.h"
#include "nvim/strings.h"
#include "nvim/version.h"
#include "nvim/vim.h"

Data Structures

struct  ShadaEntry
 Structure defining a single ShaDa file entry. More...
 
struct  hm_llist_entry
 One entry in sized linked list. More...
 
struct  HMLList
 Sized linked list structure for history merger. More...
 
struct  HistoryMergerState
 
struct  PossiblyFreedShadaEntry
 ShadaEntry structure that knows whether it should be freed. More...
 
struct  FileMarks
 Structure that holds one file marks. More...
 
struct  WriteMergerState
 
struct  sd_read_def
 Structure containing necessary pointers for reading ShaDa files. More...
 
struct  sd_write_def
 Structure containing necessary pointers for writing ShaDa files. More...
 

Macros

#define SEARCH_KEY_MAGIC   "sm"
 
#define SEARCH_KEY_SMARTCASE   "sc"
 
#define SEARCH_KEY_HAS_LINE_OFFSET   "sl"
 
#define SEARCH_KEY_PLACE_CURSOR_AT_END   "se"
 
#define SEARCH_KEY_IS_LAST_USED   "su"
 
#define SEARCH_KEY_IS_SUBSTITUTE_PATTERN   "ss"
 
#define SEARCH_KEY_HIGHLIGHTED   "sh"
 
#define SEARCH_KEY_OFFSET   "so"
 
#define SEARCH_KEY_PAT   "sp"
 
#define SEARCH_KEY_BACKWARD   "sb"
 
#define REG_KEY_TYPE   "rt"
 
#define REG_KEY_WIDTH   "rw"
 
#define REG_KEY_CONTENTS   "rc"
 
#define REG_KEY_UNNAMED   "ru"
 
#define KEY_LNUM   "l"
 
#define KEY_COL   "c"
 
#define KEY_FILE   "f"
 
#define KEY_NAME_CHAR   "n"
 
#define RERR   "E575: "
 
#define RCERR   "E576: "
 
#define SERR   "E886: "
 Common prefix for all “system” errors. More...
 
#define RNERR   "E136: "
 Common prefix for all “rename” errors. More...
 
#define WERR   "E574: "
 Common prefix for all ignorable “write” errors. More...
 
#define SHADA_LAST_ENTRY   ((uint64_t)kSDItemChange)
 
#define DEF_SDE(name, attr, ...)
 
#define DEFAULT_POS   { 1, 0, 0 }
 
#define HMLL_FORALL(hmll, cur_entry, code)
 
#define HMS_ITER(hms_p, cur_entry, code)   HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)
 
#define MERGE_JUMPS(jumps_size, jumps, jumps_type, timestamp_attr, mark_attr, entry, fname_cond, free_func, fin_func, idxadj_func, afterfree_func)
 
#define SDE_TO_XFMARK(entry)   fm
 
#define ADJUST_IDX(i)
 
#define DUMMY_AFTERFREE(entry)
 
#define SDE_TO_FMARK(entry)   fm
 
#define AFTERFREE(entry)   (entry).data.filemark.fname = NULL
 
#define DUMMY_IDX_ADJ(i)
 
#define PACK_STATIC_STR(s)
 
#define PACK_BIN(s)
 
#define DUMP_ADDITIONAL_ELEMENTS(src, what)
 
#define DUMP_ADDITIONAL_DATA(src, what)
 
#define CHECK_DEFAULT(entry, attr)   (sd_default_values[entry.type].data.attr == entry.data.attr)
 
#define ONE_IF_NOT_DEFAULT(entry, attr)   ((size_t)(!CHECK_DEFAULT(entry, attr)))
 
#define PACK_BOOL(entry, name, attr)
 
#define FORMAT_MARK_ENTRY(entry_name, name_fmt, name_fmt_arg)
 
#define COMPARE_WITH_ENTRY(wms_entry_, entry)
 
#define FREE_POSSIBLY_FREED_SHADA_ENTRY(entry)
 
#define SDE_TO_PFSDE(entry)   ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })
 
#define AFTERFREE_DUMMY(entry)
 
#define DUMMY_IDX_ADJ(i)
 
#define PACK_WMS_ARRAY(wms_array)
 
#define PACK_WMS_ENTRY(wms_entry)
 
#define READERR(entry_name, error_desc)
 
#define CHECK_KEY(key, expected)
 
#define CLEAR_GA_AND_ERROR_OUT(ga)
 
#define ID(s)   s
 
#define BINDUP(b)   xmemdupz(b.ptr, b.size)
 
#define TOINT(s)   ((int)(s))
 
#define TOLONG(s)   ((long)(s))
 
#define TOCHAR(s)   ((char)(s))
 
#define TOU8(s)   ((uint8_t)(s))
 
#define TOSIZE(s)   ((size_t)(s))
 
#define CHECKED_ENTRY(condition, error_desc, entry_name, obj, tgt, attr, proc)
 
#define CHECK_KEY_IS_STR(un, entry_name)
 
#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, proc)
 
#define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc)
 
#define BOOLEAN_KEY(un, entry_name, name, tgt)   TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)
 
#define STRING_KEY(un, entry_name, name, tgt)   TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, BINDUP)
 
#define CONVERTED_STRING_KEY(un, entry_name, name, tgt)
 
#define INT_KEY(un, entry_name, name, tgt, proc)
 
#define INTEGER_KEY(un, entry_name, name, tgt)   INT_KEY(un, entry_name, name, tgt, TOINT)
 
#define LONG_KEY(un, entry_name, name, tgt)   INT_KEY(un, entry_name, name, tgt, TOLONG)
 
#define ADDITIONAL_KEY(un)
 
#define BIN_CONVERTED(b)   (xmemdupz((b.ptr), (b.size)))
 
#define SET_ADDITIONAL_DATA(tgt, name)
 
#define SET_ADDITIONAL_ELEMENTS(src, src_maxsize, tgt, name)
 

Typedefs

typedef void(* SearchPatternGetter) (SearchPattern *)
 Callback function for add_search_pattern. More...
 
typedef struct hm_llist_entry HMLListEntry
 One entry in sized linked list. More...
 
typedef void(* ShaDaReadCloser) (struct sd_read_def *const sd_reader) REAL_FATTR_NONNULL_ALL
 Function used to close files defined by ShaDaReadDef. More...
 
typedef ptrdiff_t(* ShaDaFileReader) (struct sd_read_def *const sd_reader, void *const dest, const size_t size) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT
 Function used to read ShaDa files. More...
 
typedef int(* ShaDaFileSkipper) (struct sd_read_def *const sd_reader, const size_t offset) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT
 Function used to skip in ShaDa files. More...
 
typedef struct sd_read_def ShaDaReadDef
 Structure containing necessary pointers for reading ShaDa files. More...
 
typedef void(* ShaDaWriteCloser) (struct sd_write_def *const sd_writer) REAL_FATTR_NONNULL_ALL
 Function used to close files defined by ShaDaWriteDef. More...
 
typedef ptrdiff_t(* ShaDaFileWriter) (struct sd_write_def *const sd_writer, const void *const src, const size_t size) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT
 Function used to write ShaDa files. More...
 
typedef struct sd_write_def ShaDaWriteDef
 Structure containing necessary pointers for writing ShaDa files. More...
 

Enumerations

enum  ShadaEntryType {
  kSDItemUnknown = -1, kSDItemMissing = 0, kSDItemHeader = 1, kSDItemSearchPattern = 2,
  kSDItemSubString = 3, kSDItemHistoryEntry = 4, kSDItemRegister = 5, kSDItemVariable = 6,
  kSDItemGlobalMark = 7, kSDItemJump = 8, kSDItemBufferList = 9, kSDItemLocalMark = 10,
  kSDItemChange = 11
}
 
enum  ShaDaReadResult {
  kSDReadStatusSuccess, kSDReadStatusFinished, kSDReadStatusReadError, kSDReadStatusNotShaDa,
  kSDReadStatusMalformed
}
 Possible results when reading ShaDa file. More...
 
enum  ShaDaWriteResult { kSDWriteSuccessfull, kSDWriteReadNotShada, kSDWriteFailed, kSDWriteIgnError }
 Possible results of shada_write function. More...
 
enum  SRNIFlags {
  kSDReadHeader = (1 << kSDItemHeader), kSDReadUndisableableData, kSDReadRegisters = (1 << kSDItemRegister), kSDReadHistory = (1 << kSDItemHistoryEntry),
  kSDReadVariables = (1 << kSDItemVariable), kSDReadBufferList = (1 << kSDItemBufferList), kSDReadUnknown = (1 << (SHADA_LAST_ENTRY + 1)), kSDReadGlobalMarks = (1 << kSDItemGlobalMark),
  kSDReadLocalMarks = (1 << kSDItemLocalMark), kSDReadChanges = (1 << kSDItemChange)
}
 Flags for shada_read_next_item. More...
 

Functions

int shada_write_file (const char *const file, bool nomerge)
 
int shada_read_marks (void)
 
int shada_read_everything (const char *const fname, const bool forceit, const bool missing_ok)
 
void shada_encode_regs (msgpack_sbuffer *const sbuf) FUNC_ATTR_NONNULL_ALL
 
void shada_encode_jumps (msgpack_sbuffer *const sbuf) FUNC_ATTR_NONNULL_ALL
 
void shada_encode_buflist (msgpack_sbuffer *const sbuf) FUNC_ATTR_NONNULL_ALL
 
void shada_encode_gvars (msgpack_sbuffer *const sbuf) FUNC_ATTR_NONNULL_ALL
 
void shada_read_sbuf (msgpack_sbuffer *const sbuf, const int flags) FUNC_ATTR_NONNULL_ALL
 

Macro Definition Documentation

◆ ADDITIONAL_KEY

#define ADDITIONAL_KEY (   un)
Value:
else { /* NOLINT(readability/braces) */ \
ga_grow(&ad_ga, 1); \
memcpy(((char *)ad_ga.ga_data) + ((size_t)ad_ga.ga_len \
* sizeof(*un.data.via.map.ptr)), \
un.data.via.map.ptr + i, \
sizeof(*un.data.via.map.ptr)); \
ad_ga.ga_len++; \
}

◆ ADJUST_IDX

#define ADJUST_IDX (   i)
Value:
curwin->w_jumplistidx++; \
}

◆ AFTERFREE

#define AFTERFREE (   entry)    (entry).data.filemark.fname = NULL

◆ AFTERFREE_DUMMY

#define AFTERFREE_DUMMY (   entry)

◆ BIN_CONVERTED

#define BIN_CONVERTED (   b)    (xmemdupz((b.ptr), (b.size)))

◆ BINDUP

#define BINDUP (   b)    xmemdupz(b.ptr, b.size)

◆ BOOLEAN_KEY

#define BOOLEAN_KEY (   un,
  entry_name,
  name,
  tgt 
)    TYPED_KEY(un, entry_name, name, "a boolean", tgt, BOOLEAN, boolean, ID)

◆ CHECK_DEFAULT

#define CHECK_DEFAULT (   entry,
  attr 
)    (sd_default_values[entry.type].data.attr == entry.data.attr)

◆ CHECK_KEY

#define CHECK_KEY (   key,
  expected 
)
Value:
( \
key.via.str.size == sizeof(expected) - 1 \
&& STRNCMP(key.via.str.ptr, expected, sizeof(expected) - 1) == 0)

◆ CHECK_KEY_IS_STR

#define CHECK_KEY_IS_STR (   un,
  entry_name 
)
Value:
if (un.data.via.map.ptr[i].key.type != MSGPACK_OBJECT_STR) { \
semsg(_(READERR(entry_name, "has key which is not a string")), \
initial_fpos); \
CLEAR_GA_AND_ERROR_OUT(ad_ga); \
} else if (un.data.via.map.ptr[i].key.via.str.size == 0) { \
semsg(_(READERR(entry_name, "has empty key")), initial_fpos); \
CLEAR_GA_AND_ERROR_OUT(ad_ga); \
}

◆ CHECKED_ENTRY

#define CHECKED_ENTRY (   condition,
  error_desc,
  entry_name,
  obj,
  tgt,
  attr,
  proc 
)
Value:
do { \
if (!(condition)) { \
semsg(_(READERR(entry_name, error_desc)), initial_fpos); \
CLEAR_GA_AND_ERROR_OUT(ad_ga); \
} \
tgt = proc(obj.via.attr); \
} while (0)

◆ CHECKED_KEY

#define CHECKED_KEY (   un,
  entry_name,
  name,
  error_desc,
  tgt,
  condition,
  attr,
  proc 
)
Value:
else if (CHECK_KEY( /* NOLINT(readability/braces) */ \
un.data.via.map.ptr[i].key, name)) { \
CHECKED_ENTRY(condition, "has " name " key value " error_desc, \
entry_name, un.data.via.map.ptr[i].val, \
tgt, attr, proc); \
}

◆ CLEAR_GA_AND_ERROR_OUT

#define CLEAR_GA_AND_ERROR_OUT (   ga)
Value:
do { \
ga_clear(&ga); \
goto shada_read_next_item_error; \
} while (0)

◆ COMPARE_WITH_ENTRY

#define COMPARE_WITH_ENTRY (   wms_entry_,
  entry 
)
Value:
do { \
PossiblyFreedShadaEntry *const wms_entry = (wms_entry_); \
if (wms_entry->data.type != kSDItemMissing) { \
if (wms_entry->data.timestamp >= (entry).timestamp) { \
shada_free_shada_entry(&(entry)); \
break; \
} \
if (wms_entry->can_free_entry) { \
shada_free_shada_entry(&wms_entry->data); \
} \
} \
*wms_entry = pfs_entry; \
} while (0)

◆ CONVERTED_STRING_KEY

#define CONVERTED_STRING_KEY (   un,
  entry_name,
  name,
  tgt 
)
Value:
TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, \

◆ DEF_SDE

#define DEF_SDE (   name,
  attr,
  ... 
)
Value:
[kSDItem##name] = { \
.timestamp = 0, \
.type = kSDItem##name, \
.data = { \
.attr = { __VA_ARGS__ } \
} \
}

◆ DEFAULT_POS

#define DEFAULT_POS   { 1, 0, 0 }

◆ DUMMY_AFTERFREE

#define DUMMY_AFTERFREE (   entry)

◆ DUMMY_IDX_ADJ [1/2]

#define DUMMY_IDX_ADJ (   i)

◆ DUMMY_IDX_ADJ [2/2]

#define DUMMY_IDX_ADJ (   i)

◆ DUMP_ADDITIONAL_DATA

#define DUMP_ADDITIONAL_DATA (   src,
  what 
)
Value:
do { \
dict_T *const d = (src); \
if (d != NULL) { \
size_t todo = d->dv_hashtab.ht_used; \
for (const hashitem_T *hi= d->dv_hashtab.ht_array; todo; hi++) { \
if (!HASHITEM_EMPTY(hi)) { \
todo--; \
dictitem_T *const di = TV_DICT_HI2DI(hi); \
const size_t key_len = strlen((const char *)hi->hi_key); \
msgpack_pack_str(spacker, key_len); \
msgpack_pack_str_body(spacker, (const char *)hi->hi_key, key_len); \
if (encode_vim_to_msgpack(spacker, &di->di_tv, \
_("additional data of ShaDa " what)) \
== FAIL) { \
goto shada_pack_entry_error; \
} \
} \
} \
} \
} while (0)

◆ DUMP_ADDITIONAL_ELEMENTS

#define DUMP_ADDITIONAL_ELEMENTS (   src,
  what 
)
Value:
do { \
if ((src) != NULL) { \
TV_LIST_ITER((src), li, { \
_("additional elements of ShaDa " what)) \
== FAIL) { \
goto shada_pack_entry_error; \
} \
}); \
} \
} while (0)

◆ FORMAT_MARK_ENTRY

#define FORMAT_MARK_ENTRY (   entry_name,
  name_fmt,
  name_fmt_arg 
)
Value:
do { \
typval_T ad_tv = { \
.v_type = VAR_DICT, \
.vval.v_dict = entry.data.filemark.additional_data \
}; \
size_t ad_len; \
char *const ad = encode_tv2string(&ad_tv, &ad_len); \
vim_snprintf_add(S_LEN(ret), \
entry_name " {" name_fmt " file=[%zu]\"%.512s\", " \
"pos={l=%" PRIdLINENR ",c=%" PRIdCOLNR ",a=%" PRIdCOLNR "}, " \
"ad={%p:[%zu]%.64s} }", \
name_fmt_arg, \
strlen(entry.data.filemark.fname), \
entry.data.filemark.fname, \
entry.data.filemark.mark.lnum, \
entry.data.filemark.mark.col, \
entry.data.filemark.mark.coladd, \
(void *)entry.data.filemark.additional_data, \
ad_len, \
ad); \
} while (0)

◆ FREE_POSSIBLY_FREED_SHADA_ENTRY

#define FREE_POSSIBLY_FREED_SHADA_ENTRY (   entry)
Value:
do { \
if (entry.can_free_entry) { \
shada_free_shada_entry(&entry.data); \
} \
} while (0)

◆ HMLL_FORALL

#define HMLL_FORALL (   hmll,
  cur_entry,
  code 
)
Value:
for (HMLListEntry *cur_entry = (hmll)->first; cur_entry != NULL; \
cur_entry = cur_entry->next) { \
code \
} \

Iterate over HMLList in forward direction

Parameters
hmllPointer to the list.
cur_entryName of the variable to iterate over.
codeCode to execute on each iteration.
Returns
for cycle header (use HMLL_FORALL(hmll, cur_entry) {body}).

◆ HMS_ITER

#define HMS_ITER (   hms_p,
  cur_entry,
  code 
)    HMLL_FORALL(&((hms_p)->hmll), cur_entry, code)

Iterate over all history entries in history merger, in order

Parameters
[in]hms_pMerger structure to iterate over.
[out]cur_entryName of the iterator variable.
codeCode to execute on each iteration.
Returns
for cycle header. Use HMS_ITER(hms_p, cur_entry) {body}.

◆ ID

#define ID (   s)    s

◆ INT_KEY

#define INT_KEY (   un,
  entry_name,
  name,
  tgt,
  proc 
)
Value:
CHECKED_KEY(un, entry_name, name, "which is not an integer", tgt, \
((un.data.via.map.ptr[i].val.type \
== MSGPACK_OBJECT_POSITIVE_INTEGER) \
|| (un.data.via.map.ptr[i].val.type \
== MSGPACK_OBJECT_NEGATIVE_INTEGER)), \
i64, proc)

◆ INTEGER_KEY

#define INTEGER_KEY (   un,
  entry_name,
  name,
  tgt 
)    INT_KEY(un, entry_name, name, tgt, TOINT)

◆ KEY_COL

#define KEY_COL   "c"

◆ KEY_FILE

#define KEY_FILE   "f"

◆ KEY_LNUM

#define KEY_LNUM   "l"

◆ KEY_NAME_CHAR

#define KEY_NAME_CHAR   "n"

◆ LONG_KEY

#define LONG_KEY (   un,
  entry_name,
  name,
  tgt 
)    INT_KEY(un, entry_name, name, tgt, TOLONG)

◆ MERGE_JUMPS

#define MERGE_JUMPS (   jumps_size,
  jumps,
  jumps_type,
  timestamp_attr,
  mark_attr,
  entry,
  fname_cond,
  free_func,
  fin_func,
  idxadj_func,
  afterfree_func 
)

◆ ONE_IF_NOT_DEFAULT

#define ONE_IF_NOT_DEFAULT (   entry,
  attr 
)    ((size_t)(!CHECK_DEFAULT(entry, attr)))

◆ PACK_BIN

#define PACK_BIN (   s)
Value:
do { \
const String s_ = (s); \
msgpack_pack_bin(spacker, s_.size); \
if (s_.size > 0) { \
msgpack_pack_bin_body(spacker, s_.data, s_.size); \
} \
} while (0)

◆ PACK_BOOL

#define PACK_BOOL (   entry,
  name,
  attr 
)
Value:
do { \
if (!CHECK_DEFAULT(entry, search_pattern.attr)) { \
PACK_STATIC_STR(name); \
if (sd_default_values[entry.type].data.search_pattern.attr) { \
msgpack_pack_false(spacker); \
} else { \
msgpack_pack_true(spacker); \
} \
} \
} while (0)

◆ PACK_STATIC_STR

#define PACK_STATIC_STR (   s)
Value:
do { \
msgpack_pack_str(spacker, sizeof(s) - 1); \
msgpack_pack_str_body(spacker, s, sizeof(s) - 1); \
} while (0)

◆ PACK_WMS_ARRAY

#define PACK_WMS_ARRAY (   wms_array)
Value:
do { \
for (size_t i_ = 0; i_ < ARRAY_SIZE(wms_array); i_++) { \
if (wms_array[i_].data.type != kSDItemMissing) { \
if (shada_pack_pfreed_entry(packer, wms_array[i_], max_kbyte) \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
} \
} \
} while (0)

◆ PACK_WMS_ENTRY

#define PACK_WMS_ENTRY (   wms_entry)
Value:
do { \
if (wms_entry.data.type != kSDItemMissing) { \
if (shada_pack_pfreed_entry(packer, wms_entry, max_kbyte) \
ret = kSDWriteFailed; \
goto shada_write_exit; \
} \
} \
} while (0)

◆ RCERR

#define RCERR   "E576: "

Common prefix for critical read errors

I.e. errors that make shada_read_next_item return kSDReadStatusNotShaDa.

◆ READERR

#define READERR (   entry_name,
  error_desc 
)
Value:
RERR "Error while reading ShaDa file: " \
entry_name " entry at position %" PRIu64 " " \
error_desc

◆ REG_KEY_CONTENTS

#define REG_KEY_CONTENTS   "rc"

◆ REG_KEY_TYPE

#define REG_KEY_TYPE   "rt"

◆ REG_KEY_UNNAMED

#define REG_KEY_UNNAMED   "ru"

◆ REG_KEY_WIDTH

#define REG_KEY_WIDTH   "rw"

◆ RERR

#define RERR   "E575: "

Common prefix for all errors inside ShaDa file

I.e. errors occurred while parsing, but not system errors occurred while reading.

◆ RNERR

#define RNERR   "E136: "

Common prefix for all “rename” errors.

◆ SDE_TO_FMARK

#define SDE_TO_FMARK (   entry)    fm

◆ SDE_TO_PFSDE

#define SDE_TO_PFSDE (   entry)    ((PossiblyFreedShadaEntry) { .can_free_entry = true, .data = entry })

◆ SDE_TO_XFMARK

#define SDE_TO_XFMARK (   entry)    fm

◆ SEARCH_KEY_BACKWARD

#define SEARCH_KEY_BACKWARD   "sb"

◆ SEARCH_KEY_HAS_LINE_OFFSET

#define SEARCH_KEY_HAS_LINE_OFFSET   "sl"

◆ SEARCH_KEY_HIGHLIGHTED

#define SEARCH_KEY_HIGHLIGHTED   "sh"

◆ SEARCH_KEY_IS_LAST_USED

#define SEARCH_KEY_IS_LAST_USED   "su"

◆ SEARCH_KEY_IS_SUBSTITUTE_PATTERN

#define SEARCH_KEY_IS_SUBSTITUTE_PATTERN   "ss"

◆ SEARCH_KEY_MAGIC

#define SEARCH_KEY_MAGIC   "sm"

◆ SEARCH_KEY_OFFSET

#define SEARCH_KEY_OFFSET   "so"

◆ SEARCH_KEY_PAT

#define SEARCH_KEY_PAT   "sp"

◆ SEARCH_KEY_PLACE_CURSOR_AT_END

#define SEARCH_KEY_PLACE_CURSOR_AT_END   "se"

◆ SEARCH_KEY_SMARTCASE

#define SEARCH_KEY_SMARTCASE   "sc"

◆ SERR

#define SERR   "E886: "

Common prefix for all “system” errors.

◆ SET_ADDITIONAL_DATA

#define SET_ADDITIONAL_DATA (   tgt,
  name 
)
Value:
do { \
if (ad_ga.ga_len) { \
msgpack_object obj = { \
.type = MSGPACK_OBJECT_MAP, \
.via = { \
.map = { \
.size = (uint32_t)ad_ga.ga_len, \
.ptr = ad_ga.ga_data, \
} \
} \
}; \
typval_T adtv; \
if (msgpack_to_vim(obj, &adtv) == FAIL \
|| adtv.v_type != VAR_DICT) { \
semsg(_(READERR(name, \
"cannot be converted to a VimL dictionary")), \
initial_fpos); \
ga_clear(&ad_ga); \
tv_clear(&adtv); \
goto shada_read_next_item_error; \
} \
tgt = adtv.vval.v_dict; \
} \
ga_clear(&ad_ga); \
} while (0)

◆ SET_ADDITIONAL_ELEMENTS

#define SET_ADDITIONAL_ELEMENTS (   src,
  src_maxsize,
  tgt,
  name 
)
Value:
do { \
if ((src).size > (size_t)(src_maxsize)) { \
msgpack_object obj = { \
.type = MSGPACK_OBJECT_ARRAY, \
.via = { \
.array = { \
.size = ((src).size - (uint32_t)(src_maxsize)), \
.ptr = (src).ptr + (src_maxsize), \
} \
} \
}; \
typval_T aetv; \
if (msgpack_to_vim(obj, &aetv) == FAIL) { \
semsg(_(READERR(name, "cannot be converted to a VimL list")), \
initial_fpos); \
tv_clear(&aetv); \
goto shada_read_next_item_error; \
} \
assert(aetv.v_type == VAR_LIST); \
(tgt) = aetv.vval.v_list; \
} \
} while (0)

◆ SHADA_LAST_ENTRY

#define SHADA_LAST_ENTRY   ((uint64_t)kSDItemChange)

◆ STRING_KEY

#define STRING_KEY (   un,
  entry_name,
  name,
  tgt 
)    TYPED_KEY(un, entry_name, name, "a binary", tgt, BIN, bin, BINDUP)

◆ TOCHAR

#define TOCHAR (   s)    ((char)(s))

◆ TOINT

#define TOINT (   s)    ((int)(s))

◆ TOLONG

#define TOLONG (   s)    ((long)(s))

◆ TOSIZE

#define TOSIZE (   s)    ((size_t)(s))

◆ TOU8

#define TOU8 (   s)    ((uint8_t)(s))

◆ TYPED_KEY

#define TYPED_KEY (   un,
  entry_name,
  name,
  type_name,
  tgt,
  objtype,
  attr,
  proc 
)
Value:
CHECKED_KEY(un, entry_name, name, "which is not " type_name, tgt, \
un.data.via.map.ptr[i].val.type == MSGPACK_OBJECT_##objtype, \
attr, proc)

◆ WERR

#define WERR   "E574: "

Common prefix for all ignorable “write” errors.

Typedef Documentation

◆ HMLListEntry

typedef struct hm_llist_entry HMLListEntry

One entry in sized linked list.

◆ SearchPatternGetter

typedef void(* SearchPatternGetter) (SearchPattern *)

Callback function for add_search_pattern.

◆ ShaDaFileReader

typedef ptrdiff_t(* ShaDaFileReader) (struct sd_read_def *const sd_reader, void *const dest, const size_t size) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT

Function used to read ShaDa files.

◆ ShaDaFileSkipper

typedef int(* ShaDaFileSkipper) (struct sd_read_def *const sd_reader, const size_t offset) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT

Function used to skip in ShaDa files.

◆ ShaDaFileWriter

typedef ptrdiff_t(* ShaDaFileWriter) (struct sd_write_def *const sd_writer, const void *const src, const size_t size) REAL_FATTR_NONNULL_ALL REAL_FATTR_WARN_UNUSED_RESULT

Function used to write ShaDa files.

◆ ShaDaReadCloser

typedef void(* ShaDaReadCloser) (struct sd_read_def *const sd_reader) REAL_FATTR_NONNULL_ALL

Function used to close files defined by ShaDaReadDef.

◆ ShaDaReadDef

typedef struct sd_read_def ShaDaReadDef

Structure containing necessary pointers for reading ShaDa files.

◆ ShaDaWriteCloser

typedef void(* ShaDaWriteCloser) (struct sd_write_def *const sd_writer) REAL_FATTR_NONNULL_ALL

Function used to close files defined by ShaDaWriteDef.

◆ ShaDaWriteDef

typedef struct sd_write_def ShaDaWriteDef

Structure containing necessary pointers for writing ShaDa files.

Enumeration Type Documentation

◆ ShadaEntryType

Possible ShaDa entry types

Warning
Enum values are part of the API and must not be altered.

All values that are not in enum are ignored.

Enumerator
kSDItemUnknown 

Unknown item.

kSDItemMissing 

Missing value. Should never appear in a file.

kSDItemHeader 

Header. Present for debugging purposes.

kSDItemSearchPattern 

Last search pattern (not history item). Comes from user searches (e.g. when typing "/pat") or :substitute command calls.

kSDItemSubString 

Last substitute replacement string.

kSDItemHistoryEntry 

History item.

kSDItemRegister 

Register.

kSDItemVariable 

Global variable.

kSDItemGlobalMark 

Global mark definition.

kSDItemJump 

Item from jump list.

kSDItemBufferList 

Buffer list.

kSDItemLocalMark 

Buffer-local mark.

kSDItemChange 

Item from buffer change list.

◆ ShaDaReadResult

Possible results when reading ShaDa file.

Enumerator
kSDReadStatusSuccess 

Reading was successful.

kSDReadStatusFinished 

Nothing more to read.

kSDReadStatusReadError 

Failed to read from file.

kSDReadStatusNotShaDa 

Input is most likely not a ShaDa file.

kSDReadStatusMalformed 

Error in the currently read item.

◆ ShaDaWriteResult

Possible results of shada_write function.

Enumerator
kSDWriteSuccessfull 

Writing was successful.

kSDWriteReadNotShada 

Writing was successful, but when reading it attempted to read file that did not look like a ShaDa file.

kSDWriteFailed 

Writing was not successful (e.g. because there was no space left on device).

kSDWriteIgnError 

Writing resulted in a error which can be ignored (e.g. when trying to dump a function reference or self-referencing container in a variable).

◆ SRNIFlags

enum SRNIFlags

Flags for shada_read_next_item.

Enumerator
kSDReadHeader 

Determines whether header should be read (it is usually ignored).

kSDReadUndisableableData 

Data reading which cannot be disabled by &shada or other options except for disabling reading ShaDa as a whole.

kSDReadRegisters 

Determines whether registers should be read (may only be disabled when writing, but not when reading).

kSDReadHistory 

Determines whether history should be read (can only be disabled by &history).

kSDReadVariables 

Determines whether variables should be read (disabled by removing ! from &shada).

kSDReadBufferList 

Determines whether buffer list should be read (disabled by removing % entry from &shada).

kSDReadUnknown 

Determines whether unknown items should be read (usually disabled).

kSDReadGlobalMarks 

Determines whether global marks should be read. Can only be disabled by having f0 in &shada when writing.

kSDReadLocalMarks 

Determines whether local marks should be read. Can only be disabled by disabling &shada or putting '0 there. Is also used for v:oldfiles.

kSDReadChanges 

Determines whether change list should be read. Can only be disabled by disabling &shada or putting '0 there.

Function Documentation

◆ shada_encode_buflist()

void shada_encode_buflist ( msgpack_sbuffer *const  sbuf)

Write buffer list ShaDa entry in given msgpack_sbuffer.

Parameters
[in]sbuftarget msgpack_sbuffer to write to.

◆ shada_encode_gvars()

void shada_encode_gvars ( msgpack_sbuffer *const  sbuf)

Write global variables ShaDa entries in given msgpack_sbuffer.

Parameters
[in]sbuftarget msgpack_sbuffer to write to.

◆ shada_encode_jumps()

void shada_encode_jumps ( msgpack_sbuffer *const  sbuf)

Write jumplist ShaDa entries in given msgpack_sbuffer.

Parameters
[in]sbuftarget msgpack_sbuffer to write to.

◆ shada_encode_regs()

void shada_encode_regs ( msgpack_sbuffer *const  sbuf)

Write registers ShaDa entries in given msgpack_sbuffer.

Parameters
[in]sbuftarget msgpack_sbuffer to write to.

◆ shada_read_everything()

int shada_read_everything ( const char *const  fname,
const bool  forceit,
const bool  missing_ok 
)

Read all information from ShaDa file

Parameters
[in]fnameFile to write to. If it is NULL or empty then default
[in]forceitIf true, use forced reading (prioritize file contents over current Neovim state).
[in]missing_okIf true, do not error out when file is missing.
Returns
OK in case of success, FAIL otherwise.

◆ shada_read_marks()

int shada_read_marks ( void  )

Read marks information from ShaDa file

Returns
OK in case of success, FAIL otherwise.

◆ shada_read_sbuf()

void shada_read_sbuf ( msgpack_sbuffer *const  sbuf,
const int  flags 
)

Read ShaDa from msgpack_sbuffer.

Parameters
[in]filemsgpack_sbuffer to read from.
[in]flagsFlags, see ShaDaReadFileFlags enum.

◆ shada_write_file()

int shada_write_file ( const char *const  file,
bool  nomerge 
)

Write ShaDa file to a given location

Parameters
[in]fnameFile to write to. If it is NULL or empty then default location is used.
[in]nomergeIf true then old file is ignored.
Returns
OK if writing was successful, FAIL otherwise.
CHECK_DEFAULT
#define CHECK_DEFAULT(entry, attr)
_
#define _(x)
Definition: gettext.h:20
msgpack_to_vim
int msgpack_to_vim(const msgpack_object mobj, typval_T *const rettv) FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
Convert msgpack object to a VimL one.
Definition: decode.c:924
hm_llist_entry
One entry in sized linked list.
Definition: shada.c:293
ptr
char_u * ptr
Definition: normal.c:3176
STRNCMP
#define STRNCMP(d, s, n)
Definition: vim.h:222
i
static void int i
Definition: edit.c:3002
size
size_t size
Definition: regexp_nfa.c:5109
READERR
#define READERR(entry_name, error_desc)
Definition: shada.c:3314
encode_tv2string
char * encode_tv2string(typval_T *tv, size_t *len) FUNC_ATTR_NONNULL_ARG(1) FUNC_ATTR_MALLOC
Definition: encode.c:843
CHECK_KEY
#define CHECK_KEY(key, expected)
Definition: shada.c:3318
what
dict_T * what
Definition: funcs.c:8989
kSDWriteFailed
@ kSDWriteFailed
Definition: shada.c:172
ret
const int ret
Definition: eval.c:722
window_S::w_jumplistlen
int w_jumplistlen
Definition: buffer_defs.h:1427
BIN_CONVERTED
#define BIN_CONVERTED(b)
Definition: shada.c:3390
TV_LIST_ITEM_TV
#define TV_LIST_ITEM_TV(li)
Definition: typval.h:855
VAR_LIST
@ VAR_LIST
List, .v_list is used.
Definition: typval.h:120
String
Definition: defs.h:77
s
char_u * s
Definition: eval.c:764
encode_vim_to_msgpack
int encode_vim_to_msgpack(msgpack_packer *const packer, typval_T *const tv, const char *const objname)
li
listitem_T * li
Definition: eval.c:7346
curwin
EXTERN win_T * curwin
Definition: globals.h:438
FAIL
return FAIL
Definition: ex_docmd.c:5240
window_S::w_jumplistidx
int w_jumplistidx
Definition: buffer_defs.h:1428
PRIdCOLNR
#define PRIdCOLNR
Format used to print values which have colnr_T type.
Definition: pos.h:14
src
char_u * src
Definition: env.c:583
S_LEN
#define S_LEN(s)
Definition: macros.h:32
kSDItemMissing
@ kSDItemMissing
Missing value. Should never appear in a file.
Definition: shada.c:140
RERR
#define RERR
Definition: shada.c:114
TYPED_KEY
#define TYPED_KEY(un, entry_name, name, type_name, tgt, objtype, attr, proc)
Definition: shada.c:3359
name
char_u * name
Definition: userfunc.c:821
ARRAY_SIZE
#define ARRAY_SIZE(arr)
Definition: macros.h:122
TV_DICT_HI2DI
tv_copy & TV_DICT_HI2DI(hi) ->di_tv, rettv
VAR_DICT
@ VAR_DICT
Dictionary, .v_dict is used.
Definition: typval.h:121
PRIdLINENR
#define PRIdLINENR
Format used to print values which have linenr_T type.
Definition: pos.h:9
NULL
return NULL
Definition: eval.c:10355
di
dictitem_T *const di
Definition: typval.c:1683
hashitem_S
Definition: hashtab.h:38
HASHITEM_EMPTY
#define HASHITEM_EMPTY(hi)
Definition: hashtab.h:19
CHECKED_KEY
#define CHECKED_KEY(un, entry_name, name, error_desc, tgt, condition, attr, proc)
Definition: shada.c:3351