1#ifndef NVIM_MARK_H
2#define NVIM_MARK_H
3
4#include "nvim/macros.h"
5#include "nvim/ascii.h"
6#include "nvim/buffer_defs.h"
7#include "nvim/func_attr.h"
8#include "nvim/mark_defs.h"
9#include "nvim/memory.h"
10#include "nvim/pos.h"
11#include "nvim/os/time.h"
12#include "nvim/ex_cmds_defs.h" // for exarg_T
13
14/// Set fmark using given value
15#define SET_FMARK(fmarkp_, mark_, fnum_) \
16 do { \
17 fmark_T *const fmarkp__ = fmarkp_; \
18 fmarkp__->mark = mark_; \
19 fmarkp__->fnum = fnum_; \
20 fmarkp__->timestamp = os_time(); \
21 fmarkp__->additional_data = NULL; \
22 } while (0)
23
24/// Free and set fmark using given value
25#define RESET_FMARK(fmarkp_, mark_, fnum_) \
26 do { \
27 fmark_T *const fmarkp___ = fmarkp_; \
28 free_fmark(*fmarkp___); \
29 SET_FMARK(fmarkp___, mark_, fnum_); \
30 } while (0)
31
32/// Clear given fmark
33#define CLEAR_FMARK(fmarkp_) \
34 RESET_FMARK(fmarkp_, ((pos_T) { 0, 0, 0 }), 0)
35
36/// Set given extended mark (regular mark + file name)
37#define SET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
38 do { \
39 xfmark_T *const xfmarkp__ = xfmarkp_; \
40 xfmarkp__->fname = fname_; \
41 SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
42 } while (0)
43
44/// Free and set given extended mark (regular mark + file name)
45#define RESET_XFMARK(xfmarkp_, mark_, fnum_, fname_) \
46 do { \
47 xfmark_T *const xfmarkp__ = xfmarkp_; \
48 free_xfmark(*xfmarkp__); \
49 xfmarkp__->fname = fname_; \
50 SET_FMARK(&(xfmarkp__->fmark), mark_, fnum_); \
51 } while (0)
52
53/// Convert mark name to the offset
54static inline int mark_global_index(const char name)
55 FUNC_ATTR_CONST
56{
57 return (ASCII_ISUPPER(name)
58 ? (name - 'A')
59 : (ascii_isdigit(name)
60 ? (NMARKS + (name - '0'))
61 : -1));
62}
63
64/// Convert local mark name to the offset
65static inline int mark_local_index(const char name)
66 FUNC_ATTR_CONST
67{
68 return (ASCII_ISLOWER(name)
69 ? (name - 'a')
70 : (name == '"'
71 ? NMARKS
72 : (name == '^'
73 ? NMARKS + 1
74 : (name == '.'
75 ? NMARKS + 2
76 : -1))));
77}
78
79static inline bool lt(pos_T, pos_T) REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
80static inline bool equalpos(pos_T, pos_T)
81 REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
82static inline bool ltoreq(pos_T, pos_T)
83 REAL_FATTR_CONST REAL_FATTR_ALWAYS_INLINE;
84static inline void clearpos(pos_T *)
85 REAL_FATTR_ALWAYS_INLINE;
86
87/// Return true if position a is before (less than) position b.
88static inline bool lt(pos_T a, pos_T b)
89{
90 if (a.lnum != b.lnum) {
91 return a.lnum < b.lnum;
92 } else if (a.col != b.col) {
93 return a.col < b.col;
94 } else {
95 return a.coladd < b.coladd;
96 }
97}
98
99/// Return true if position a and b are equal.
100static inline bool equalpos(pos_T a, pos_T b)
101{
102 return (a.lnum == b.lnum) && (a.col == b.col) && (a.coladd == b.coladd);
103}
104
105/// Return true if position a is less than or equal to b.
106static inline bool ltoreq(pos_T a, pos_T b)
107{
108 return lt(a, b) || equalpos(a, b);
109}
110
111/// Clear the pos_T structure pointed to by a.
112static inline void clearpos(pos_T *a)
113{
114 a->lnum = 0;
115 a->col = 0;
116 a->coladd = 0;
117}
118
119#ifdef INCLUDE_GENERATED_DECLARATIONS
120# include "mark.h.generated.h"
121#endif
122#endif // NVIM_MARK_H
123