diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/marktree.h | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-userreg.tar.gz rneovim-userreg.tar.bz2 rneovim-userreg.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/marktree.h')
-rw-r--r-- | src/nvim/marktree.h | 183 |
1 files changed, 126 insertions, 57 deletions
diff --git a/src/nvim/marktree.h b/src/nvim/marktree.h index 5ce4b2cd24..c76359d3f9 100644 --- a/src/nvim/marktree.h +++ b/src/nvim/marktree.h @@ -1,140 +1,209 @@ -#ifndef NVIM_MARKTREE_H -#define NVIM_MARKTREE_H +#pragma once -#include <assert.h> #include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include "nvim/assert.h" -#include "nvim/garray.h" -#include "nvim/map.h" +#include "klib/kvec.h" +#include "nvim/decoration_defs.h" +#include "nvim/garray_defs.h" // IWYU pragma: keep #include "nvim/map_defs.h" -#include "nvim/pos.h" -#include "nvim/types.h" - -struct mtnode_s; +#include "nvim/pos_defs.h" // IWYU pragma: keep +// only for debug functions: +#include "nvim/api/private/defs.h" // IWYU pragma: keep #define MT_MAX_DEPTH 20 #define MT_BRANCH_FACTOR 10 +// note max branch is actually 2*MT_BRANCH_FACTOR +// and strictly this is ceil(log2(2*MT_BRANCH_FACTOR + 1)) +// as we need a pseudo-index for "right before this node" +#define MT_LOG2_BRANCH 5 typedef struct { int32_t row; int32_t col; -} mtpos_t; +} MTPos; +#define MTPos(r, c) ((MTPos){ .row = (r), .col = (c) }) -typedef struct mtnode_s mtnode_t; -typedef struct { - int oldcol; - int i; -} iterstate_t; +typedef struct mtnode_s MTNode; typedef struct { - mtpos_t pos; + MTPos pos; int lvl; - mtnode_t *node; + MTNode *x; int i; - iterstate_t s[MT_MAX_DEPTH]; + struct { + int oldcol; + int i; + } s[MT_MAX_DEPTH]; + + size_t intersect_idx; + MTPos intersect_pos; + MTPos intersect_pos_x; } MarkTreeIter; +#define marktree_itr_valid(itr) ((itr)->x != NULL) +// access raw key: flags in MT_FLAG_EXTERNAL_MASK and decor_data are safe to modify. +#define mt_itr_rawkey(itr) ((itr)->x->key[(itr)->i]) + // Internal storage // // NB: actual marks have flags > 0, so we can use (row,col,0) pseudo-key for // "space before (row,col)" typedef struct { - mtpos_t pos; + MTPos pos; uint32_t ns; uint32_t id; - int32_t hl_id; uint16_t flags; - uint16_t priority; - Decoration *decor_full; -} mtkey_t; -#define MT_INVALID_KEY (mtkey_t) { { -1, -1 }, 0, 0, 0, 0, 0, NULL } + DecorInlineData decor_data; // "ext" tag in flags +} MTKey; + +typedef struct { + MTKey start; + MTPos end_pos; + bool end_right_gravity; +} MTPair; + +#define MT_INVALID_KEY (MTKey) { { -1, -1 }, 0, 0, 0, { .hl = DECOR_HIGHLIGHT_INLINE_INIT } } #define MT_FLAG_REAL (((uint16_t)1) << 0) #define MT_FLAG_END (((uint16_t)1) << 1) #define MT_FLAG_PAIRED (((uint16_t)1) << 2) -#define MT_FLAG_HL_EOL (((uint16_t)1) << 3) - -#define DECOR_LEVELS 4 -#define MT_FLAG_DECOR_OFFSET 4 -#define MT_FLAG_DECOR_MASK (((uint16_t)(DECOR_LEVELS - 1)) << MT_FLAG_DECOR_OFFSET) - -// next flag is (((uint16_t)1) << 6) +// orphaned: the other side of this paired mark was deleted. this mark must be deleted very soon! +#define MT_FLAG_ORPHANED (((uint16_t)1) << 3) +#define MT_FLAG_NO_UNDO (((uint16_t)1) << 4) +#define MT_FLAG_INVALIDATE (((uint16_t)1) << 5) +#define MT_FLAG_INVALID (((uint16_t)1) << 6) +// discriminant for union +#define MT_FLAG_DECOR_EXT (((uint16_t)1) << 7) + +// TODO(bfredl): flags for decorations. These cover the cases where we quickly needs +// to skip over irrelevant marks internally. When we refactor this more, also make all info +// for ExtmarkType included here +#define MT_FLAG_DECOR_HL (((uint16_t)1) << 8) +#define MT_FLAG_DECOR_SIGNTEXT (((uint16_t)1) << 9) +// TODO(bfredl): for now this means specifically number_hl, line_hl, cursorline_hl +// needs to clean up the name. +#define MT_FLAG_DECOR_SIGNHL (((uint16_t)1) << 10) +#define MT_FLAG_DECOR_VIRT_LINES (((uint16_t)1) << 11) +#define MT_FLAG_DECOR_VIRT_TEXT_INLINE (((uint16_t)1) << 12) // These _must_ be last to preserve ordering of marks #define MT_FLAG_RIGHT_GRAVITY (((uint16_t)1) << 14) #define MT_FLAG_LAST (((uint16_t)1) << 15) -#define MT_FLAG_EXTERNAL_MASK (MT_FLAG_DECOR_MASK | MT_FLAG_RIGHT_GRAVITY | MT_FLAG_HL_EOL) +#define MT_FLAG_DECOR_MASK (MT_FLAG_DECOR_EXT| MT_FLAG_DECOR_HL | MT_FLAG_DECOR_SIGNTEXT \ + | MT_FLAG_DECOR_SIGNHL | MT_FLAG_DECOR_VIRT_LINES \ + | MT_FLAG_DECOR_VIRT_TEXT_INLINE) -#define MARKTREE_END_FLAG (((uint64_t)1) << 63) +#define MT_FLAG_EXTERNAL_MASK (MT_FLAG_DECOR_MASK | MT_FLAG_NO_UNDO \ + | MT_FLAG_INVALIDATE | MT_FLAG_INVALID) + +// this is defined so that start and end of the same range have adjacent ids +#define MARKTREE_END_FLAG ((uint64_t)1) static inline uint64_t mt_lookup_id(uint32_t ns, uint32_t id, bool enda) { - return (uint64_t)ns << 32 | id | (enda?MARKTREE_END_FLAG:0); + return (uint64_t)ns << 33 | (id <<1) | (enda ? MARKTREE_END_FLAG : 0); } -#undef MARKTREE_END_FLAG -static inline uint64_t mt_lookup_key(mtkey_t key) +static inline uint64_t mt_lookup_key_side(MTKey key, bool end) +{ + return mt_lookup_id(key.ns, key.id, end); +} + +static inline uint64_t mt_lookup_key(MTKey key) { return mt_lookup_id(key.ns, key.id, key.flags & MT_FLAG_END); } -static inline bool mt_paired(mtkey_t key) +static inline bool mt_paired(MTKey key) { return key.flags & MT_FLAG_PAIRED; } -static inline bool mt_end(mtkey_t key) +static inline bool mt_end(MTKey key) { return key.flags & MT_FLAG_END; } -static inline bool mt_start(mtkey_t key) +static inline bool mt_start(MTKey key) { return mt_paired(key) && !mt_end(key); } -static inline bool mt_right(mtkey_t key) +static inline bool mt_right(MTKey key) { return key.flags & MT_FLAG_RIGHT_GRAVITY; } -static inline uint8_t marktree_decor_level(mtkey_t key) +static inline bool mt_no_undo(MTKey key) +{ + return key.flags & MT_FLAG_NO_UNDO; +} + +static inline bool mt_invalidate(MTKey key) +{ + return key.flags & MT_FLAG_INVALIDATE; +} + +static inline bool mt_invalid(MTKey key) { - return (uint8_t)((key.flags&MT_FLAG_DECOR_MASK) >> MT_FLAG_DECOR_OFFSET); + return key.flags & MT_FLAG_INVALID; } -static inline uint16_t mt_flags(bool right_gravity, uint8_t decor_level) +static inline bool mt_decor_any(MTKey key) +{ + return key.flags & MT_FLAG_DECOR_MASK; +} + +static inline bool mt_decor_sign(MTKey key) +{ + return key.flags & (MT_FLAG_DECOR_SIGNTEXT | MT_FLAG_DECOR_SIGNHL); +} + +static inline uint16_t mt_flags(bool right_gravity, bool no_undo, bool invalidate, bool decor_ext) { - assert(decor_level < DECOR_LEVELS); return (uint16_t)((right_gravity ? MT_FLAG_RIGHT_GRAVITY : 0) - | (decor_level << MT_FLAG_DECOR_OFFSET)); + | (no_undo ? MT_FLAG_NO_UNDO : 0) + | (invalidate ? MT_FLAG_INVALIDATE : 0) + | (decor_ext ? MT_FLAG_DECOR_EXT : 0)); +} + +static inline MTPair mtpair_from(MTKey start, MTKey end) +{ + return (MTPair){ .start = start, .end_pos = end.pos, .end_right_gravity = mt_right(end) }; } +static inline DecorInline mt_decor(MTKey key) +{ + return (DecorInline){ .ext = key.flags & MT_FLAG_DECOR_EXT, .data = key.decor_data }; +} + +typedef kvec_withinit_t(uint64_t, 4) Intersection; + struct mtnode_s { int32_t n; - int32_t level; + int16_t level; + int16_t p_idx; // index in parent + Intersection intersect; // TODO(bfredl): we could consider having a only-sometimes-valid // index into parent for faster "cached" lookup. - mtnode_t *parent; - mtkey_t key[2 * MT_BRANCH_FACTOR - 1]; - mtnode_t *ptr[]; + MTNode *parent; + MTKey key[2 * MT_BRANCH_FACTOR - 1]; + MTNode *ptr[]; }; -// TODO(bfredl): the iterator is pretty much everpresent, make it part of the -// tree struct itself? +static inline uint64_t mt_dbg_id(uint64_t id) +{ + return (id>>1)&0xffffffff; +} + typedef struct { - mtnode_t *root; + MTNode *root; size_t n_keys, n_nodes; - // TODO(bfredl): the pointer to node could be part of the larger - // Map(uint64_t, ExtmarkItem) essentially; PMap(uint64_t) id2node[1]; } MarkTree; #ifdef INCLUDE_GENERATED_DECLARATIONS # include "marktree.h.generated.h" #endif - -#endif // NVIM_MARKTREE_H |