decoration.h (3599B)
1 #pragma once 2 3 #include <stdbool.h> 4 #include <stddef.h> // IWYU pragma: keep 5 #include <stdint.h> 6 7 #include "klib/kvec.h" 8 #include "nvim/decoration_defs.h" // IWYU pragma: keep 9 #include "nvim/macros_defs.h" 10 #include "nvim/marktree_defs.h" 11 #include "nvim/pos_defs.h" // IWYU pragma: keep 12 #include "nvim/sign_defs.h" // IWYU pragma: keep 13 #include "nvim/types_defs.h" 14 15 // actual Decor* data is in decoration_defs.h 16 17 /// Keep in sync with VirtTextPos in decoration_defs.h 18 EXTERN const char *const virt_text_pos_str[] INIT( = { "eol", "eol_right_align", "inline", 19 "overlay", "right_align", "win_col" }); 20 21 /// Keep in sync with HlMode in decoration_defs.h 22 EXTERN const char *const hl_mode_str[] INIT( = { "", "replace", "combine", "blend" }); 23 24 typedef enum { 25 kDecorKindHighlight, 26 kDecorKindSign, 27 kDecorKindVirtText, 28 kDecorKindVirtLines, 29 kDecorKindUIWatched, 30 } DecorRangeKindEnum; 31 32 typedef uint8_t DecorRangeKind; 33 34 typedef struct { 35 int start_row; 36 int start_col; 37 int end_row; 38 int end_col; 39 int ordering; ///< range insertion order 40 DecorPriorityInternal priority_internal; 41 bool owned; ///< ephemeral decoration, free memory immediately 42 DecorRangeKind kind; 43 // next pointers MUST NOT be used, these are separate ranges 44 // vt->next could be pointing to freelist memory at this point 45 union { 46 DecorSignHighlight sh; 47 DecorVirtText *vt; 48 struct { 49 uint32_t ns_id; 50 uint32_t mark_id; 51 VirtTextPos pos; 52 } ui; 53 } data; 54 int attr_id; ///< cached lookup of inl.hl_id if it was a highlight 55 /// Screen column to draw the virtual text. 56 /// When -1, it should be drawn on the current screen line after deciding where. 57 /// When -3, it may be drawn at a position yet to be assigned. 58 /// When -10, it has just been added. 59 /// When INT_MIN, it should no longer be drawn. 60 int draw_col; 61 } DecorRange; 62 63 /// DecorRange can be removed from `DecorState` list in any order, 64 /// so we track available slots using a freelist (with `next_free_i`). 65 /// The list head is in `DecorState.free_slot_i`. 66 typedef union { 67 DecorRange range; 68 int next_free_i; 69 } DecorRangeSlot; 70 71 typedef struct { 72 MarkTreeIter itr[1]; 73 kvec_t(DecorRangeSlot) slots; 74 kvec_t(int) ranges_i; 75 /// Indices in [0; current_end) of `ranges_i` point to ranges that start 76 /// before current position. Sorted by priority and order of insertion. 77 int current_end; 78 /// Indices in [future_begin, kv_size(ranges_i)) of `ranges_i` point to 79 /// ranges that start after current position. Sorted by starting position. 80 int future_begin; 81 /// Head of DecorRangeSlot freelist. -1 if none are freed. 82 int free_slot_i; 83 /// Index for keeping track of range insertion order. 84 int new_range_ordering; 85 win_T *win; 86 int top_row; 87 int row; 88 int col_until; 89 int current; 90 int eol_col; 91 92 int conceal; 93 schar_T conceal_char; 94 int conceal_attr; 95 96 TriState spell; 97 98 bool running_decor_provider; 99 bool itr_valid; 100 } DecorState; 101 102 EXTERN DecorState decor_state INIT( = { 0 }); 103 // TODO(bfredl): These should maybe be per-buffer, so that all resources 104 // associated with a buffer can be freed when the buffer is unloaded. 105 EXTERN kvec_t(DecorSignHighlight) decor_items INIT( = KV_INITIAL_VALUE); 106 107 #include "decoration.h.generated.h" 108 #include "decoration.h.inline.generated.h" 109 110 static inline int decor_redraw_col(win_T *wp, int col, int win_col, bool hidden, DecorState *state) 111 FUNC_ATTR_ALWAYS_INLINE 112 { 113 if (col <= state->col_until) { 114 return state->current; 115 } 116 return decor_redraw_col_impl(wp, col, win_col, hidden, state); 117 }