1 #ifndef NVIM_BUFFER_DEFS_H
2 #define NVIM_BUFFER_DEFS_H
3 
4 #include <stdbool.h>
5 #include <stdint.h>
6 // for FILE
7 #include <stdio.h>
8 
9 typedef struct file_buffer buf_T;  // Forward declaration
10 
11 // Reference to a buffer that stores the value of buf_free_count.
12 // bufref_valid() only needs to check "buf" when the count differs.
13 typedef struct {
14   buf_T *br_buf;
15   int br_fnum;
16   int br_buf_free_count;
17 } bufref_T;
18 
19 // for garray_T
20 #include "nvim/garray.h"
21 // for ScreenGrid
22 #include "nvim/grid_defs.h"
23 // for HLF_COUNT
24 #include "nvim/highlight_defs.h"
25 // for pos_T, lpos_T and linenr_T
26 #include "nvim/pos.h"
27 // for the number window-local and buffer-local options
28 #include "nvim/option_defs.h"
29 // for jump list and tag stack sizes in a buffer and mark types
30 #include "nvim/mark_defs.h"
31 // for u_header_T; needs buf_T.
32 #include "nvim/undo_defs.h"
33 // for hashtab_T
34 #include "nvim/hashtab.h"
35 // for dict_T
36 #include "nvim/eval/typval.h"
37 // for proftime_T
38 #include "nvim/profile.h"
39 // for String
40 #include "nvim/api/private/defs.h"
41 // for Map(K, V)
42 #include "nvim/map.h"
43 // for kvec
44 #include "nvim/lib/kvec.h"
45 // for marktree
46 #include "nvim/marktree.h"
47 
48 #define GETFILE_SUCCESS(x)    ((x) <= 0)
49 #define MODIFIABLE(buf) (buf->b_p_ma)
50 
51 /*
52  * Flags for w_valid.
53  * These are set when something in a window structure becomes invalid, except
54  * when the cursor is moved.  Call check_cursor_moved() before testing one of
55  * the flags.
56  * These are reset when that thing has been updated and is valid again.
57  *
58  * Every function that invalidates one of these must call one of the
59  * invalidate_* functions.
60  *
61  * w_valid is supposed to be used only in screen.c.  From other files, use the
62  * functions that set or reset the flags.
63  *
64  * VALID_BOTLINE    VALID_BOTLINE_AP
65  *     on       on      w_botline valid
66  *     off      on      w_botline approximated
67  *     off      off     w_botline not valid
68  *     on       off     not possible
69  */
70 #define VALID_WROW      0x01    // w_wrow (window row) is valid
71 #define VALID_WCOL      0x02    // w_wcol (window col) is valid
72 #define VALID_VIRTCOL   0x04    // w_virtcol (file col) is valid
73 #define VALID_CHEIGHT   0x08    // w_cline_height and w_cline_folded valid
74 #define VALID_CROW      0x10    // w_cline_row is valid
75 #define VALID_BOTLINE   0x20    // w_botine and w_empty_rows are valid
76 #define VALID_BOTLINE_AP 0x40   // w_botine is approximated
77 #define VALID_TOPLINE   0x80    // w_topline is valid (for cursor position)
78 
79 // flags for b_flags
80 #define BF_RECOVERED    0x01    // buffer has been recovered
81 #define BF_CHECK_RO     0x02    // need to check readonly when loading file
82                                 // into buffer (set by ":e", may be reset by
83                                 // ":buf")
84 #define BF_NEVERLOADED  0x04    // file has never been loaded into buffer,
85                                 // many variables still need to be set
86 #define BF_NOTEDITED    0x08    // Set when file name is changed after
87                                 // starting to edit, reset when file is
88                                 // written out.
89 #define BF_NEW          0x10    // file didn't exist when editing started
90 #define BF_NEW_W        0x20    // Warned for BF_NEW and file created
91 #define BF_READERR      0x40    // got errors while reading the file
92 #define BF_DUMMY        0x80    // dummy buffer, only used internally
93 #define BF_PRESERVED    0x100   // ":preserve" was used
94 #define BF_SYN_SET      0x200   // 'syntax' option was set
95 
96 // Mask to check for flags that prevent normal writing
97 #define BF_WRITE_MASK   (BF_NOTEDITED + BF_NEW + BF_READERR)
98 
99 typedef struct window_S win_T;
100 typedef struct wininfo_S wininfo_T;
101 typedef struct frame_S frame_T;
102 typedef uint64_t disptick_T;  // display tick type
103 
104 // for struct memline (it needs memfile_T)
105 #include "nvim/memline_defs.h"
106 // for struct memfile, bhdr_T, blocknr_T... (it needs buf_T)
107 #include "nvim/memfile_defs.h"
108 
109 // for regprog_T. Needs win_T and buf_T.
110 #include "nvim/regexp_defs.h"
111 // for synstate_T (needs reg_extmatch_T, win_T, buf_T)
112 #include "nvim/syntax_defs.h"
113 // for sign_entry_T
114 #include "nvim/os/fs_defs.h"    // for FileID
115 #include "nvim/sign_defs.h"
116 #include "nvim/terminal.h"      // for Terminal
117 
118 /*
119  * The taggy struct is used to store the information about a :tag command.
120  */
121 typedef struct taggy {
122   char_u *tagname;         // tag name
123   fmark_T fmark;                // cursor position BEFORE ":tag"
124   int cur_match;                // match number
125   int cur_fnum;                 // buffer number used for cur_match
126   char_u *user_data;            // used with tagfunc
127 } taggy_T;
128 
129 typedef struct buffblock buffblock_T;
130 typedef struct buffheader buffheader_T;
131 
132 /*
133  * structure used to store one block of the stuff/redo/recording buffers
134  */
135 struct buffblock {
136   buffblock_T *b_next;  // pointer to next buffblock
137   char_u b_str[1];      // contents (actually longer)
138 };
139 
140 /*
141  * header used for the stuff buffer and the redo buffer
142  */
143 struct buffheader {
144   buffblock_T bh_first;  // first (dummy) block of list
145   buffblock_T *bh_curr;  // buffblock for appending
146   size_t bh_index;          // index for reading
147   size_t bh_space;          // space in bh_curr for appending
148 };
149 
150 typedef struct {
151   buffheader_T sr_redobuff;
152   buffheader_T sr_old_redobuff;
153 } save_redo_T;
154 
155 /*
156  * Structure that contains all options that are local to a window.
157  * Used twice in a window: for the current buffer and for all buffers.
158  * Also used in wininfo_T.
159  */
160 typedef struct {
161   int wo_arab;
162 #define w_p_arab w_onebuf_opt.wo_arab  // 'arabic'
163   int wo_bri;
164 #define w_p_bri w_onebuf_opt.wo_bri    // 'breakindent'
165   char_u *wo_briopt;
166 #define w_p_briopt w_onebuf_opt.wo_briopt  // 'breakindentopt'
167   int wo_diff;
168 #define w_p_diff w_onebuf_opt.wo_diff  // 'diff'
169   char_u *wo_fdc;
170 #define w_p_fdc w_onebuf_opt.wo_fdc    // 'foldcolumn'
171   char_u *wo_fdc_save;
172 #define w_p_fdc_save w_onebuf_opt.wo_fdc_save  // 'fdc' saved for diff mode
173   int wo_fen;
174 #define w_p_fen w_onebuf_opt.wo_fen    // 'foldenable'
175   int wo_fen_save;
176   // 'foldenable' saved for diff mode
177 #define w_p_fen_save w_onebuf_opt.wo_fen_save
178   char_u *wo_fdi;
179 #define w_p_fdi w_onebuf_opt.wo_fdi    // 'foldignore'
180   long wo_fdl;
181 #define w_p_fdl w_onebuf_opt.wo_fdl    // 'foldlevel'
182   int wo_fdl_save;
183   // 'foldlevel' state saved for diff mode
184 #define w_p_fdl_save w_onebuf_opt.wo_fdl_save
185   char_u *wo_fdm;
186 #define w_p_fdm w_onebuf_opt.wo_fdm    // 'foldmethod'
187   char_u *wo_fdm_save;
188 #define w_p_fdm_save w_onebuf_opt.wo_fdm_save  // 'fdm' saved for diff mode
189   long wo_fml;
190 #define w_p_fml w_onebuf_opt.wo_fml    // 'foldminlines'
191   long wo_fdn;
192 #define w_p_fdn w_onebuf_opt.wo_fdn    // 'foldnestmax'
193   char_u *wo_fde;
194 #define w_p_fde w_onebuf_opt.wo_fde    // 'foldexpr'
195   char_u *wo_fdt;
196 #define w_p_fdt w_onebuf_opt.wo_fdt   // 'foldtext'
197   char_u *wo_fmr;
198 #define w_p_fmr w_onebuf_opt.wo_fmr    // 'foldmarker'
199   int wo_lbr;
200 #define w_p_lbr w_onebuf_opt.wo_lbr    // 'linebreak'
201   int wo_list;
202 #define w_p_list w_onebuf_opt.wo_list   // 'list'
203   int wo_nu;
204 #define w_p_nu w_onebuf_opt.wo_nu       // 'number'
205   int wo_rnu;
206 #define w_p_rnu w_onebuf_opt.wo_rnu     // 'relativenumber'
207   long wo_nuw;
208 #define w_p_nuw w_onebuf_opt.wo_nuw    // 'numberwidth'
209   int wo_wfh;
210 #define w_p_wfh w_onebuf_opt.wo_wfh    // 'winfixheight'
211   int wo_wfw;
212 #define w_p_wfw w_onebuf_opt.wo_wfw    // 'winfixwidth'
213   int wo_pvw;
214 #define w_p_pvw w_onebuf_opt.wo_pvw    // 'previewwindow'
215   int wo_rl;
216 #define w_p_rl w_onebuf_opt.wo_rl      // 'rightleft'
217   char_u *wo_rlc;
218 #define w_p_rlc w_onebuf_opt.wo_rlc    // 'rightleftcmd'
219   long wo_scr;
220 #define w_p_scr w_onebuf_opt.wo_scr     // 'scroll'
221   int wo_spell;
222 #define w_p_spell w_onebuf_opt.wo_spell  // 'spell'
223   int wo_cuc;
224 #define w_p_cuc w_onebuf_opt.wo_cuc    // 'cursorcolumn'
225   int wo_cul;
226 #define w_p_cul w_onebuf_opt.wo_cul    // 'cursorline'
227   char_u *wo_culopt;
228 #define w_p_culopt w_onebuf_opt.wo_culopt  // 'cursorlineopt'
229   char_u *wo_cc;
230 #define w_p_cc w_onebuf_opt.wo_cc      // 'colorcolumn'
231   char_u *wo_sbr;
232 #define w_p_sbr w_onebuf_opt.wo_sbr    // 'showbreak'
233   char_u *wo_stl;
234 #define w_p_stl w_onebuf_opt.wo_stl     // 'statusline'
235   int wo_scb;
236 #define w_p_scb w_onebuf_opt.wo_scb    // 'scrollbind'
237   int wo_diff_saved;           // options were saved for starting diff mode
238 #define w_p_diff_saved w_onebuf_opt.wo_diff_saved
239   int wo_scb_save;              // 'scrollbind' saved for diff mode
240 #define w_p_scb_save w_onebuf_opt.wo_scb_save
241   int wo_wrap;
242 #define w_p_wrap w_onebuf_opt.wo_wrap   // 'wrap'
243   int wo_wrap_save;             // 'wrap' state saved for diff mode
244 #define w_p_wrap_save w_onebuf_opt.wo_wrap_save
245   char_u *wo_cocu;                 // 'concealcursor'
246 #define w_p_cocu w_onebuf_opt.wo_cocu
247   long wo_cole;                         // 'conceallevel'
248 #define w_p_cole w_onebuf_opt.wo_cole
249   int wo_crb;
250 #define w_p_crb w_onebuf_opt.wo_crb    // 'cursorbind'
251   int wo_crb_save;              // 'cursorbind' state saved for diff mode
252 #define w_p_crb_save w_onebuf_opt.wo_crb_save
253   char_u *wo_scl;
254 #define w_p_scl w_onebuf_opt.wo_scl    // 'signcolumn'
255   char_u *wo_winhl;
256 #define w_p_winhl w_onebuf_opt.wo_winhl    // 'winhighlight'
257   char_u *wo_fcs;
258 #define w_p_fcs w_onebuf_opt.wo_fcs    // 'fillchars'
259   char_u *wo_lcs;
260 #define w_p_lcs w_onebuf_opt.wo_lcs    // 'listchars'
261   long wo_winbl;
262 #define w_p_winbl w_onebuf_opt.wo_winbl  // 'winblend'
263 
264   LastSet wo_script_ctx[WV_COUNT];        // SCTXs for window-local options
265 #define w_p_script_ctx w_onebuf_opt.wo_script_ctx
266 } winopt_T;
267 
268 /*
269  * Window info stored with a buffer.
270  *
271  * Two types of info are kept for a buffer which are associated with a
272  * specific window:
273  * 1. Each window can have a different line number associated with a buffer.
274  * 2. The window-local options for a buffer work in a similar way.
275  * The window-info is kept in a list at b_wininfo.  It is kept in
276  * most-recently-used order.
277  */
278 struct wininfo_S {
279   wininfo_T *wi_next;         // next entry or NULL for last entry
280   wininfo_T *wi_prev;         // previous entry or NULL for first entry
281   win_T *wi_win;          // pointer to window that did set wi_fpos
282   pos_T wi_fpos;                // last cursor position in the file
283   bool wi_optset;               // true when wi_opt has useful values
284   winopt_T wi_opt;              // local window options
285   bool wi_fold_manual;          // copy of w_fold_manual
286   garray_T wi_folds;            // clone of w_folds
287 };
288 
289 /*
290  * Argument list: Array of file names.
291  * Used for the global argument list and the argument lists local to a window.
292  *
293  * TODO: move struct arglist to another header
294  */
295 typedef struct arglist {
296   garray_T al_ga;               // growarray with the array of file names
297   int al_refcount;              // number of windows using this arglist
298   int id;                       ///< id of this arglist
299 } alist_T;
300 
301 // For each argument remember the file name as it was given, and the buffer
302 // number that contains the expanded file name (required for when ":cd" is
303 // used).
304 //
305 // TODO(Felipe): move aentry_T to another header
306 typedef struct argentry {
307   char_u *ae_fname;        // file name as specified
308   int ae_fnum;                  // buffer number with expanded file name
309 } aentry_T;
310 
311 #define ALIST(win) (win)->w_alist
312 #define GARGLIST        ((aentry_T *)global_alist.al_ga.ga_data)
313 #define ARGLIST         ((aentry_T *)ALIST(curwin)->al_ga.ga_data)
314 #define WARGLIST(wp)    ((aentry_T *)ALIST(wp)->al_ga.ga_data)
315 #define AARGLIST(al)    ((aentry_T *)((al)->al_ga.ga_data))
316 #define GARGCOUNT       (global_alist.al_ga.ga_len)
317 #define ARGCOUNT        (ALIST(curwin)->al_ga.ga_len)
318 #define WARGCOUNT(wp)   (ALIST(wp)->al_ga.ga_len)
319 
320 /*
321  * Used for the typeahead buffer: typebuf.
322  */
323 typedef struct {
324   char_u *tb_buf;          // buffer for typed characters
325   char_u *tb_noremap;      // mapping flags for characters in tb_buf[]
326   int tb_buflen;                // size of tb_buf[]
327   int tb_off;                   // current position in tb_buf[]
328   int tb_len;                   // number of valid bytes in tb_buf[]
329   int tb_maplen;                // nr of mapped bytes in tb_buf[]
330   int tb_silent;                // nr of silently mapped bytes in tb_buf[]
331   int tb_no_abbr_cnt;           // nr of bytes without abbrev. in tb_buf[]
332   int tb_change_cnt;            // nr of time tb_buf was changed; never zero
333 } typebuf_T;
334 
335 // Struct to hold the saved typeahead for save_typeahead().
336 typedef struct {
337   typebuf_T save_typebuf;
338   bool typebuf_valid;                       // true when save_typebuf valid
339   int old_char;
340   int old_mod_mask;
341   buffheader_T save_readbuf1;
342   buffheader_T save_readbuf2;
343   String save_inputbuf;
344 } tasave_T;
345 
346 /*
347  * Structure used for mappings and abbreviations.
348  */
349 typedef struct mapblock mapblock_T;
350 struct mapblock {
351   mapblock_T *m_next;          // next mapblock in list
352   char_u *m_keys;          // mapped from, lhs
353   char_u *m_str;           // mapped to, rhs
354   char_u *m_orig_str;      // rhs as entered by the user
355   int m_keylen;                 // strlen(m_keys)
356   int m_mode;                   // valid mode
357   int m_noremap;                // if non-zero no re-mapping for m_str
358   char m_silent;                // <silent> used, don't echo commands
359   char m_nowait;                // <nowait> used
360   char m_expr;                  // <expr> used, m_str is an expression
361   sctx_T m_script_ctx;          // SCTX where map was defined
362 };
363 
364 /// Used for highlighting in the status line.
365 typedef struct stl_hlrec stl_hlrec_t;
366 struct stl_hlrec {
367   char_u *start;
368   int userhl;                   // 0: no HL, 1-9: User HL, < 0 for syn ID
369 };
370 
371 /// Used for building the status line.
372 typedef struct stl_item stl_item_t;
373 struct stl_item {
374   // Where the item starts in the status line output buffer
375   char_u *start;
376   // Function to run for ClickFunc items.
377   char *cmd;
378   // The minimum width of the item
379   int minwid;
380   // The maximum width of the item
381   int maxwid;
382   enum {
383     Normal,
384     Empty,
385     Group,
386     Separate,
387     Highlight,
388     TabPage,
389     ClickFunc,
390     Trunc,
391   } type;
392 };
393 
394 // values for b_syn_spell: what to do with toplevel text
395 #define SYNSPL_DEFAULT  0       // spell check if @Spell not defined
396 #define SYNSPL_TOP      1       // spell check toplevel text
397 #define SYNSPL_NOTOP    2       // don't spell check toplevel text
398 
399 // values for b_syn_foldlevel: how to compute foldlevel on a line
400 #define SYNFLD_START    0       // use level of item at start of line
401 #define SYNFLD_MINIMUM  1       // use lowest local minimum level on line
402 
403 // avoid #ifdefs for when b_spell is not available
404 #define B_SPELL(buf)  ((buf)->b_spell)
405 
406 typedef struct qf_info_S qf_info_T;
407 
408 /*
409  * Used for :syntime: timing of executing a syntax pattern.
410  */
411 typedef struct {
412   proftime_T total;             // total time used
413   proftime_T slowest;           // time of slowest call
414   long count;                   // nr of times used
415   long match;                   // nr of times matched
416 } syn_time_T;
417 
418 /*
419  * These are items normally related to a buffer.  But when using ":ownsyntax"
420  * a window may have its own instance.
421  */
422 typedef struct {
423   hashtab_T b_keywtab;                  // syntax keywords hash table
424   hashtab_T b_keywtab_ic;               // idem, ignore case
425   int b_syn_error;                      // TRUE when error occurred in HL
426   bool b_syn_slow;                      // true when 'redrawtime' reached
427   int b_syn_ic;                         // ignore case for :syn cmds
428   int b_syn_foldlevel;                  // how to compute foldlevel on a line
429   int b_syn_spell;                      // SYNSPL_ values
430   garray_T b_syn_patterns;              // table for syntax patterns
431   garray_T b_syn_clusters;              // table for syntax clusters
432   int b_spell_cluster_id;               // @Spell cluster ID or 0
433   int b_nospell_cluster_id;             // @NoSpell cluster ID or 0
434   int b_syn_containedin;                // TRUE when there is an item with a
435                                         // "containedin" argument
436   int b_syn_sync_flags;                 // flags about how to sync
437   int16_t b_syn_sync_id;                // group to sync on
438   long b_syn_sync_minlines;             // minimal sync lines offset
439   long b_syn_sync_maxlines;             // maximal sync lines offset
440   long b_syn_sync_linebreaks;           // offset for multi-line pattern
441   char_u *b_syn_linecont_pat;      // line continuation pattern
442   regprog_T *b_syn_linecont_prog;     // line continuation program
443   syn_time_T b_syn_linecont_time;
444   int b_syn_linecont_ic;                // ignore-case flag for above
445   int b_syn_topgrp;                     // for ":syntax include"
446   int b_syn_conceal;                    // auto-conceal for :syn cmds
447   int b_syn_folditems;                  // number of patterns with the HL_FOLD
448                                         // flag set
449   // b_sst_array[] contains the state stack for a number of lines, for the
450   // start of that line (col == 0).  This avoids having to recompute the
451   // syntax state too often.
452   // b_sst_array[] is allocated to hold the state for all displayed lines,
453   // and states for 1 out of about 20 other lines.
454   // b_sst_array        pointer to an array of synstate_T
455   // b_sst_len          number of entries in b_sst_array[]
456   // b_sst_first        pointer to first used entry in b_sst_array[] or NULL
457   // b_sst_firstfree    pointer to first free entry in b_sst_array[] or NULL
458   // b_sst_freecount    number of free entries in b_sst_array[]
459   // b_sst_check_lnum   entries after this lnum need to be checked for
460   //                    validity (MAXLNUM means no check needed)
461   synstate_T *b_sst_array;
462   int b_sst_len;
463   synstate_T *b_sst_first;
464   synstate_T *b_sst_firstfree;
465   int b_sst_freecount;
466   linenr_T b_sst_check_lnum;
467   disptick_T b_sst_lasttick;    // last display tick
468 
469   // for spell checking
470   garray_T b_langp;             // list of pointers to slang_T, see spell.c
471   bool b_spell_ismw[256];       // flags: is midword char
472   char_u *b_spell_ismw_mb;  // multi-byte midword chars
473   char_u *b_p_spc;         // 'spellcapcheck'
474   regprog_T *b_cap_prog;      // program for 'spellcapcheck'
475   char_u *b_p_spf;         // 'spellfile'
476   char_u *b_p_spl;         // 'spelllang'
477   char_u *b_p_spo;         // 'spelloptions'
478   int b_cjk;                    // all CJK letters as OK
479   char_u b_syn_chartab[32];     // syntax iskeyword option
480   char_u *b_syn_isk;            // iskeyword option
481 } synblock_T;
482 
483 /// Type used for changedtick_di member in buf_T
484 ///
485 /// Primary exists so that literals of relevant type can be made.
486 typedef TV_DICTITEM_STRUCT(sizeof("changedtick")) ChangedtickDictItem;
487 
488 typedef struct {
489   LuaRef on_lines;
490   LuaRef on_bytes;
491   LuaRef on_changedtick;
492   LuaRef on_detach;
493   LuaRef on_reload;
494   bool utf_sizes;
495   bool preview;
496 } BufUpdateCallbacks;
497 #define BUF_UPDATE_CALLBACKS_INIT { LUA_NOREF, LUA_NOREF, LUA_NOREF, \
498                                     LUA_NOREF, LUA_NOREF, false, false }
499 
500 EXTERN int curbuf_splice_pending INIT(= 0);
501 
502 #define BUF_HAS_QF_ENTRY 1
503 #define BUF_HAS_LL_ENTRY 2
504 
505 // Maximum number of maphash blocks we will have
506 #define MAX_MAPHASH 256
507 
508 /*
509  * buffer: structure that holds information about one file
510  *
511  * Several windows can share a single Buffer
512  * A buffer is unallocated if there is no memfile for it.
513  * A buffer is new if the associated file has never been loaded yet.
514  */
515 
516 struct file_buffer {
517   handle_T handle;              // unique id for the buffer (buffer number)
518 #define b_fnum handle
519 
520   memline_T b_ml;               // associated memline (also contains line count
521 
522   buf_T *b_next;          // links in list of buffers
523   buf_T *b_prev;
524 
525   int b_nwindows;               // nr of windows open on this buffer
526 
527   int b_flags;                  // various BF_ flags
528   int b_locked;                 // Buffer is being closed or referenced, don't
529                                 // let autocommands wipe it out.
530   int b_ro_locked;              // Non-zero when the buffer can't be changed.
531                                 // Used for FileChangedRO
532 
533   //
534   // b_ffname   has the full path of the file (NULL for no name).
535   // b_sfname   is the name as the user typed it (or NULL).
536   // b_fname    is the same as b_sfname, unless ":cd" has been done,
537   //            then it is the same as b_ffname (NULL for no name).
538   //
539   char_u *b_ffname;        // full path file name, allocated
540   char_u *b_sfname;        // short file name, allocated, may be equal to
541                            // b_ffname
542   char_u *b_fname;         // current file name, points to b_ffname or
543                            // b_sfname
544 
545   bool file_id_valid;
546   FileID file_id;
547 
548   int b_changed;                // 'modified': Set to true if something in the
549                                 // file has been changed and not written out.
550   bool b_changed_invalid;       // Set if BufModified autocmd has not been
551                                 // triggered since the last time b_changed was
552                                 // modified.
553 
554   /// Change-identifier incremented for each change, including undo.
555   ///
556   /// This is a dictionary item used to store b:changedtick.
557   ChangedtickDictItem changedtick_di;
558 
559   varnumber_T b_last_changedtick;       // b:changedtick when TextChanged or
560                                         // TextChangedI was last triggered.
561   varnumber_T b_last_changedtick_pum;   // b:changedtick when TextChangedP was
562                                         // last triggered.
563 
564   bool b_saving;                /* Set to true if we are in the middle of
565                                    saving the buffer. */
566 
567   /*
568    * Changes to a buffer require updating of the display.  To minimize the
569    * work, remember changes made and update everything at once.
570    */
571   bool b_mod_set;               /* true when there are changes since the last
572                                    time the display was updated */
573   linenr_T b_mod_top;           // topmost lnum that was changed
574   linenr_T b_mod_bot;           // lnum below last changed line, AFTER the
575                                 // change
576   long b_mod_xlines;            // number of extra buffer lines inserted;
577                                 // negative when lines were deleted
578   wininfo_T *b_wininfo;       // list of last used info for each window
579   disptick_T b_mod_tick_syn;    // last display tick syntax was updated
580   disptick_T b_mod_tick_decor;  // last display tick decoration providers
581                                 // where invoked
582 
583   long b_mtime;                 // last change time of original file
584   long b_mtime_read;            // last change time when reading
585   uint64_t b_orig_size;         // size of original file in bytes
586   int b_orig_mode;              // mode of original file
587   time_t b_last_used;           // time when the buffer was last used; used
588                                 // for viminfo
589 
590   fmark_T b_namedm[NMARKS];     // current named marks (mark.c)
591 
592   // These variables are set when VIsual_active becomes FALSE
593   visualinfo_T b_visual;
594   int b_visual_mode_eval;            // b_visual.vi_mode for visualmode()
595 
596   fmark_T b_last_cursor;        // cursor position when last unloading this
597                                 // buffer
598   fmark_T b_last_insert;        // where Insert mode was left
599   fmark_T b_last_change;        // position of last change: '. mark
600 
601   /*
602    * the changelist contains old change positions
603    */
604   fmark_T b_changelist[JUMPLISTSIZE];
605   int b_changelistlen;                  // number of active entries
606   bool b_new_change;                    // set by u_savecommon()
607 
608   /*
609    * Character table, only used in charset.c for 'iskeyword'
610    * bitset with 4*64=256 bits: 1 bit per character 0-255.
611    */
612   uint64_t b_chartab[4];
613 
614   // Table used for mappings local to a buffer.
615   mapblock_T *(b_maphash[MAX_MAPHASH]);
616 
617   // First abbreviation local to a buffer.
618   mapblock_T *b_first_abbr;
619   // User commands local to the buffer.
620   garray_T b_ucmds;
621   /*
622    * start and end of an operator, also used for '[ and ']
623    */
624   pos_T b_op_start;
625   pos_T b_op_start_orig;  // used for Insstart_orig
626   pos_T b_op_end;
627 
628   bool b_marks_read;            // Have we read ShaDa marks yet?
629 
630   /*
631    * The following only used in undo.c.
632    */
633   u_header_T *b_u_oldhead;     // pointer to oldest header
634   u_header_T *b_u_newhead;     // pointer to newest header; may not be valid
635                                // if b_u_curhead is not NULL
636   u_header_T *b_u_curhead;     // pointer to current header
637   int b_u_numhead;              // current number of headers
638   bool b_u_synced;              // entry lists are synced
639   long b_u_seq_last;            // last used undo sequence number
640   long b_u_save_nr_last;        // counter for last file write
641   long b_u_seq_cur;             // hu_seq of header below which we are now
642   time_t b_u_time_cur;          // uh_time of header below which we are now
643   long b_u_save_nr_cur;         // file write nr after which we are now
644 
645   /*
646    * variables for "U" command in undo.c
647    */
648   char_u *b_u_line_ptr;    // saved line for "U" command
649   linenr_T b_u_line_lnum;       // line number of line in u_line
650   colnr_T b_u_line_colnr;       // optional column number
651 
652   bool b_scanned;               // ^N/^P have scanned this buffer
653 
654   // flags for use of ":lmap" and IM control
655   long b_p_iminsert;            // input mode for insert
656   long b_p_imsearch;            // input mode for search
657 #define B_IMODE_USE_INSERT -1   //  Use b_p_iminsert value for search
658 #define B_IMODE_NONE 0          //  Input via none
659 #define B_IMODE_LMAP 1          //  Input via langmap
660 #define B_IMODE_LAST 1
661 
662   int16_t b_kmap_state;         // using "lmap" mappings
663 #define KEYMAP_INIT    1       // 'keymap' was set, call keymap_init()
664 #define KEYMAP_LOADED  2       // 'keymap' mappings have been loaded
665   garray_T b_kmap_ga;           // the keymap table
666 
667   /*
668    * Options local to a buffer.
669    * They are here because their value depends on the type of file
670    * or contents of the file being edited.
671    */
672   bool b_p_initialized;                 // set when options initialized
673 
674   LastSet b_p_script_ctx[BV_COUNT];     // SCTXs for buffer-local options
675 
676   int b_p_ai;                   ///< 'autoindent'
677   int b_p_ai_nopaste;           ///< b_p_ai saved for paste mode
678   char_u *b_p_bkc;              ///< 'backupco
679   unsigned int b_bkc_flags;     ///< flags for 'backupco
680   int b_p_ci;                   ///< 'copyindent'
681   int b_p_bin;                  ///< 'binary'
682   int b_p_bomb;                 ///< 'bomb'
683   char_u *b_p_bh;               ///< 'bufhidden'
684   char_u *b_p_bt;               ///< 'buftype'
685   int b_has_qf_entry;           ///< quickfix exists for buffer
686   int b_p_bl;                   ///< 'buflisted'
687   long b_p_channel;             ///< 'channel'
688   int b_p_cin;                  ///< 'cindent'
689   char_u *b_p_cino;             ///< 'cinoptions'
690   char_u *b_p_cink;             ///< 'cinkeys'
691   char_u *b_p_cinw;             ///< 'cinwords'
692   char_u *b_p_com;              ///< 'comments'
693   char_u *b_p_cms;              ///< 'commentstring'
694   char_u *b_p_cpt;              ///< 'complete'
695 #ifdef BACKSLASH_IN_FILENAME
696   char_u *b_p_csl;              ///< 'completeslash'
697 #endif
698   char_u *b_p_cfu;              ///< 'completefunc'
699   char_u *b_p_ofu;              ///< 'omnifunc'
700   char_u *b_p_tfu;              ///< 'tagfunc'
701   int b_p_eol;                  ///< 'endofline'
702   int b_p_fixeol;               ///< 'fixendofline'
703   int b_p_et;                   ///< 'expandtab'
704   int b_p_et_nobin;             ///< b_p_et saved for binary mode
705   int b_p_et_nopaste;           ///< b_p_et saved for paste mode
706   char_u *b_p_fenc;             ///< 'fileencoding'
707   char_u *b_p_ff;               ///< 'fileformat'
708   char_u *b_p_ft;               ///< 'filetype'
709   char_u *b_p_fo;               ///< 'formatoptions'
710   char_u *b_p_flp;              ///< 'formatlistpat'
711   int b_p_inf;                  ///< 'infercase'
712   char_u *b_p_isk;              ///< 'iskeyword'
713   char_u *b_p_def;              ///< 'define' local value
714   char_u *b_p_inc;              ///< 'include'
715   char_u *b_p_inex;             ///< 'includeexpr'
716   uint32_t b_p_inex_flags;      ///< flags for 'includeexpr'
717   char_u *b_p_inde;             ///< 'indentexpr'
718   uint32_t b_p_inde_flags;      ///< flags for 'indentexpr'
719   char_u *b_p_indk;             ///< 'indentkeys'
720   char_u *b_p_fp;               ///< 'formatprg'
721   char_u *b_p_fex;              ///< 'formatexpr'
722   uint32_t b_p_fex_flags;       ///< flags for 'formatexpr'
723   char_u *b_p_kp;               ///< 'keywordprg'
724   int b_p_lisp;                 ///< 'lisp'
725   char_u *b_p_menc;             ///< 'makeencoding'
726   char_u *b_p_mps;              ///< 'matchpairs'
727   int b_p_ml;                   ///< 'modeline'
728   int b_p_ml_nobin;             ///< b_p_ml saved for binary mode
729   int b_p_ma;                   ///< 'modifiable'
730   char_u *b_p_nf;               ///< 'nrformats'
731   int b_p_pi;                   ///< 'preserveindent'
732   char_u *b_p_qe;               ///< 'quoteescape'
733   int b_p_ro;                   ///< 'readonly'
734   long b_p_sw;                  ///< 'shiftwidth'
735   long b_p_scbk;                ///< 'scrollback'
736   int b_p_si;                   ///< 'smartindent'
737   long b_p_sts;                 ///< 'softtabstop'
738   long b_p_sts_nopaste;         ///< b_p_sts saved for paste mode
739   char_u *b_p_sua;              ///< 'suffixesadd'
740   int b_p_swf;                  ///< 'swapfile'
741   long b_p_smc;                 ///< 'synmaxcol'
742   char_u *b_p_syn;              ///< 'syntax'
743   long b_p_ts;                  ///< 'tabstop'
744   long b_p_tw;                  ///< 'textwidth'
745   long b_p_tw_nobin;            ///< b_p_tw saved for binary mode
746   long b_p_tw_nopaste;          ///< b_p_tw saved for paste mode
747   long b_p_wm;                  ///< 'wrapmargin'
748   long b_p_wm_nobin;            ///< b_p_wm saved for binary mode
749   long b_p_wm_nopaste;          ///< b_p_wm saved for paste mode
750   char_u *b_p_vsts;             ///< 'varsofttabstop'
751   long *b_p_vsts_array;          ///< 'varsofttabstop' in internal format
752   char_u *b_p_vsts_nopaste;     ///< b_p_vsts saved for paste mode
753   char_u *b_p_vts;              ///< 'vartabstop'
754   long *b_p_vts_array;           ///< 'vartabstop' in internal format
755   char_u *b_p_keymap;           ///< 'keymap'
756 
757   // local values for options which are normally global
758   char_u *b_p_gp;               ///< 'grepprg' local value
759   char_u *b_p_mp;               ///< 'makeprg' local value
760   char_u *b_p_efm;              ///< 'errorformat' local value
761   char_u *b_p_ep;               ///< 'equalprg' local value
762   char_u *b_p_path;             ///< 'path' local value
763   int b_p_ar;                   ///< 'autoread' local value
764   char_u *b_p_tags;             ///< 'tags' local value
765   char_u *b_p_tc;               ///< 'tagcase' local value
766   unsigned b_tc_flags;          ///< flags for 'tagcase'
767   char_u *b_p_dict;             ///< 'dictionary' local value
768   char_u *b_p_tsr;              ///< 'thesaurus' local value
769   char_u *b_p_tsrfu;            ///< 'thesaurusfunc' local value
770   long b_p_ul;                  ///< 'undolevels' local value
771   int b_p_udf;                  ///< 'undofile'
772   char_u *b_p_lw;               ///< 'lispwords' local value
773 
774   // end of buffer options
775 
776   // values set from b_p_cino
777   int b_ind_level;
778   int b_ind_open_imag;
779   int b_ind_no_brace;
780   int b_ind_first_open;
781   int b_ind_open_extra;
782   int b_ind_close_extra;
783   int b_ind_open_left_imag;
784   int b_ind_jump_label;
785   int b_ind_case;
786   int b_ind_case_code;
787   int b_ind_case_break;
788   int b_ind_param;
789   int b_ind_func_type;
790   int b_ind_comment;
791   int b_ind_in_comment;
792   int b_ind_in_comment2;
793   int b_ind_cpp_baseclass;
794   int b_ind_continuation;
795   int b_ind_unclosed;
796   int b_ind_unclosed2;
797   int b_ind_unclosed_noignore;
798   int b_ind_unclosed_wrapped;
799   int b_ind_unclosed_whiteok;
800   int b_ind_matching_paren;
801   int b_ind_paren_prev;
802   int b_ind_maxparen;
803   int b_ind_maxcomment;
804   int b_ind_scopedecl;
805   int b_ind_scopedecl_code;
806   int b_ind_java;
807   int b_ind_js;
808   int b_ind_keep_case_label;
809   int b_ind_hash_comment;
810   int b_ind_cpp_namespace;
811   int b_ind_if_for_while;
812   int b_ind_cpp_extern_c;
813   int b_ind_pragma;
814 
815   linenr_T b_no_eol_lnum;       /* non-zero lnum when last line of next binary
816                                  * write should not have an end-of-line */
817 
818   int b_start_eol;              // last line had eol when it was read
819   int b_start_ffc;              // first char of 'ff' when edit started
820   char_u *b_start_fenc;    // 'fileencoding' when edit started or NULL
821   int b_bad_char;               // "++bad=" argument when edit started or 0
822   int b_start_bomb;             // 'bomb' when it was read
823 
824   ScopeDictDictItem b_bufvar;  ///< Variable for "b:" Dictionary.
825   dict_T *b_vars;  ///< b: scope dictionary.
826 
827   /* When a buffer is created, it starts without a swap file.  b_may_swap is
828    * then set to indicate that a swap file may be opened later.  It is reset
829    * if a swap file could not be opened.
830    */
831   bool b_may_swap;
832   bool b_did_warn;              /* Set to true if user has been warned on first
833                                    change of a read-only file */
834 
835   /* Two special kinds of buffers:
836    * help buffer  - used for help files, won't use a swap file.
837    * spell buffer - used for spell info, never displayed and doesn't have a
838    *                file name.
839    */
840   bool b_help;                  // TRUE for help file buffer (when set b_p_bt
841                                 // is "help")
842   bool b_spell;                 // True for a spell file buffer, most fields
843                                 // are not used!  Use the B_SPELL macro to
844                                 // access b_spell without #ifdef.
845 
846   char_u *b_prompt_text;        // set by prompt_setprompt()
847   Callback b_prompt_callback;   // set by prompt_setcallback()
848   Callback b_prompt_interrupt;  // set by prompt_setinterrupt()
849   int b_prompt_insert;          // value for restart_edit when entering
850                                 // a prompt buffer window.
851 
852   synblock_T b_s;               // Info related to syntax highlighting.  w_s
853                                 // normally points to this, but some windows
854                                 // may use a different synblock_T.
855 
856   sign_entry_T *b_signlist;     // list of placed signs
857   int b_signcols;               // last calculated number of sign columns
858   bool b_signcols_valid;        // calculated sign columns is valid
859 
860   Terminal *terminal;           // Terminal instance associated with the buffer
861 
862   dict_T *additional_data;      // Additional data from shada file if any.
863 
864   int b_mapped_ctrl_c;          // modes where CTRL-C is mapped
865 
866   MarkTree b_marktree[1];
867   Map(uint64_t, ExtmarkItem) b_extmark_index[1];
868   Map(uint64_t, ExtmarkNs) b_extmark_ns[1];         // extmark namespaces
869   size_t b_virt_line_blocks;    // number of virt_line blocks
870 
871   // array of channel_id:s which have asked to receive updates for this
872   // buffer.
873   kvec_t(uint64_t) update_channels;
874   // array of lua callbacks for buffer updates.
875   kvec_t(BufUpdateCallbacks) update_callbacks;
876 
877   // whether an update callback has requested codepoint size of deleted regions.
878   bool update_need_codepoints;
879 
880   // Measurements of the deleted or replaced region since the last update
881   // event. Some consumers of buffer changes need to know the byte size (like
882   // tree-sitter) or the corresponding UTF-32/UTF-16 size (like LSP) of the
883   // deleted text.
884   size_t deleted_bytes;
885   size_t deleted_bytes2;
886   size_t deleted_codepoints;
887   size_t deleted_codeunits;
888 
889   // The number for times the current line has been flushed in the memline.
890   int flush_count;
891 
892   int b_diff_failed;    // internal diff failed for this buffer
893 };
894 
895 /*
896  * Stuff for diff mode.
897  */
898 #define DB_COUNT 8     // up to four buffers can be diff'ed
899 
900 /*
901  * Each diffblock defines where a block of lines starts in each of the buffers
902  * and how many lines it occupies in that buffer.  When the lines are missing
903  * in the buffer the df_count[] is zero.  This is all counted in
904  * buffer lines.
905  * There is always at least one unchanged line in between the diffs.
906  * Otherwise it would have been included in the diff above or below it.
907  * df_lnum[] + df_count[] is the lnum below the change.  When in one buffer
908  * lines have been inserted, in the other buffer df_lnum[] is the line below
909  * the insertion and df_count[] is zero.  When appending lines at the end of
910  * the buffer, df_lnum[] is one beyond the end!
911  * This is using a linked list, because the number of differences is expected
912  * to be reasonable small.  The list is sorted on lnum.
913  */
914 typedef struct diffblock_S diff_T;
915 struct diffblock_S {
916   diff_T *df_next;
917   linenr_T df_lnum[DB_COUNT];           // line number in buffer
918   linenr_T df_count[DB_COUNT];          // nr of inserted/changed lines
919 };
920 
921 #define SNAP_HELP_IDX   0
922 #define SNAP_AUCMD_IDX 1
923 #define SNAP_COUNT     2
924 
925 /// Tab pages point to the top frame of each tab page.
926 /// Note: Most values are NOT valid for the current tab page!  Use "curwin",
927 /// "firstwin", etc. for that.  "tp_topframe" is always valid and can be
928 /// compared against "topframe" to find the current tab page.
929 typedef struct tabpage_S tabpage_T;
930 struct tabpage_S {
931   handle_T handle;
932   tabpage_T *tp_next;         ///< next tabpage or NULL
933   frame_T *tp_topframe;     ///< topframe for the windows
934   win_T *tp_curwin;       ///< current window in this Tab page
935   win_T *tp_prevwin;      ///< previous window in this Tab page
936   win_T *tp_firstwin;     ///< first window in this Tab page
937   win_T *tp_lastwin;      ///< last window in this Tab page
938   long tp_old_Rows;                 ///< Rows when Tab page was left
939   long tp_old_Columns;              ///< Columns when Tab page was left
940   long tp_ch_used;                  ///< value of 'cmdheight' when frame size
941                                     ///< was set
942 
943   diff_T *tp_first_diff;
944   buf_T *(tp_diffbuf[DB_COUNT]);
945   int tp_diff_invalid;              ///< list of diffs is outdated
946   int tp_diff_update;               ///< update diffs before redrawing
947   frame_T *(tp_snapshot[SNAP_COUNT]);    ///< window layout snapshots
948   ScopeDictDictItem tp_winvar;      ///< Variable for "t:" Dictionary.
949   dict_T *tp_vars;         ///< Internal variables, local to tab page.
950   char_u *tp_localdir;     ///< Absolute path of local cwd or NULL.
951   char_u *tp_prevdir;      ///< Previous directory.
952 };
953 
954 /*
955  * Structure to cache info for displayed lines in w_lines[].
956  * Each logical line has one entry.
957  * The entry tells how the logical line is currently displayed in the window.
958  * This is updated when displaying the window.
959  * When the display is changed (e.g., when clearing the screen) w_lines_valid
960  * is changed to exclude invalid entries.
961  * When making changes to the buffer, wl_valid is reset to indicate wl_size
962  * may not reflect what is actually in the buffer.  When wl_valid is FALSE,
963  * the entries can only be used to count the number of displayed lines used.
964  * wl_lnum and wl_lastlnum are invalid too.
965  */
966 typedef struct w_line {
967   linenr_T wl_lnum;             // buffer line number for logical line
968   uint16_t wl_size;             // height in screen lines
969   char wl_valid;                // TRUE values are valid for text in buffer
970   char wl_folded;               // TRUE when this is a range of folded lines
971   linenr_T wl_lastlnum;         // last buffer line number for logical line
972 } wline_T;
973 
974 /*
975  * Windows are kept in a tree of frames.  Each frame has a column (FR_COL)
976  * or row (FR_ROW) layout or is a leaf, which has a window.
977  */
978 struct frame_S {
979   char fr_layout;               // FR_LEAF, FR_COL or FR_ROW
980   int fr_width;
981   int fr_newwidth;              // new width used in win_equal_rec()
982   int fr_height;
983   int fr_newheight;             // new height used in win_equal_rec()
984   frame_T *fr_parent;       // containing frame or NULL
985   frame_T *fr_next;         // frame right or below in same parent, NULL
986                             // for last
987   frame_T *fr_prev;         // frame left or above in same parent, NULL
988                             // for first
989   // fr_child and fr_win are mutually exclusive
990   frame_T *fr_child;        // first contained frame
991   win_T *fr_win;          // window that fills this frame
992 };
993 
994 #define FR_LEAF 0       // frame is a leaf
995 #define FR_ROW  1       // frame with a row of windows
996 #define FR_COL  2       // frame with a column of windows
997 
998 /*
999  * Struct used for highlighting 'hlsearch' matches, matches defined by
1000  * ":match" and matches defined by match functions.
1001  * For 'hlsearch' there is one pattern for all windows.  For ":match" and the
1002  * match functions there is a different pattern for each window.
1003  */
1004 typedef struct {
1005   regmmatch_T rm;       // points to the regexp program; contains last found
1006                         // match (may continue in next line)
1007   buf_T *buf;     // the buffer to search for a match
1008   linenr_T lnum;        // the line to search for a match
1009   int attr;             // attributes to be used for a match
1010   int attr_cur;         // attributes currently active in win_line()
1011   linenr_T first_lnum;  // first lnum to search for multi-line pat
1012   colnr_T startcol;     // in win_line() points to char where HL starts
1013   colnr_T endcol;       // in win_line() points to char where HL ends
1014   bool is_addpos;       // position specified directly by matchaddpos()
1015   proftime_T tm;        // for a time limit
1016 } match_T;
1017 
1018 /// number of positions supported by matchaddpos()
1019 #define MAXPOSMATCH 8
1020 
1021 /// Same as lpos_T, but with additional field len.
1022 typedef struct {
1023   linenr_T lnum;   ///< line number
1024   colnr_T col;    ///< column number
1025   int len;    ///< length: 0 - to the end of line
1026 } llpos_T;
1027 
1028 /// posmatch_T provides an array for storing match items for matchaddpos()
1029 /// function.
1030 typedef struct posmatch posmatch_T;
1031 struct posmatch {
1032   llpos_T pos[MAXPOSMATCH];   ///< array of positions
1033   int cur;                ///< internal position counter
1034   linenr_T toplnum;            ///< top buffer line
1035   linenr_T botlnum;            ///< bottom buffer line
1036 };
1037 
1038 /*
1039  * matchitem_T provides a linked list for storing match items for ":match" and
1040  * the match functions.
1041  */
1042 typedef struct matchitem matchitem_T;
1043 struct matchitem {
1044   matchitem_T *next;
1045   int id;                   ///< match ID
1046   int priority;             ///< match priority
1047   char_u *pattern;          ///< pattern to highlight
1048   regmmatch_T match;        ///< regexp program for pattern
1049   posmatch_T pos;           ///< position matches
1050   match_T hl;               ///< struct for doing the actual highlighting
1051   int hlg_id;               ///< highlight group ID
1052   int conceal_char;         ///< cchar for Conceal highlighting
1053 };
1054 
1055 typedef int FloatAnchor;
1056 
1057 enum {
1058   kFloatAnchorEast  = 1,
1059   kFloatAnchorSouth = 2,
1060 };
1061 
1062 // NW -> 0
1063 // NE -> kFloatAnchorEast
1064 // SW -> kFloatAnchorSouth
1065 // SE -> kFloatAnchorSouth | kFloatAnchorEast
1066 EXTERN const char *const float_anchor_str[] INIT(= { "NW", "NE", "SW", "SE" });
1067 
1068 typedef enum {
1069   kFloatRelativeEditor = 0,
1070   kFloatRelativeWindow = 1,
1071   kFloatRelativeCursor = 2,
1072 } FloatRelative;
1073 
1074 EXTERN const char *const float_relative_str[] INIT(= { "editor", "win",
1075                                                        "cursor" });
1076 
1077 typedef enum {
1078   kWinStyleUnused = 0,
1079   kWinStyleMinimal,  /// Minimal UI: no number column, eob markers, etc
1080 } WinStyle;
1081 
1082 typedef struct {
1083   Window window;
1084   lpos_T bufpos;
1085   int height, width;
1086   double row, col;
1087   FloatAnchor anchor;
1088   FloatRelative relative;
1089   bool external;
1090   bool focusable;
1091   int zindex;
1092   WinStyle style;
1093   bool border;
1094   bool shadow;
1095   schar_T border_chars[8];
1096   int border_hl_ids[8];
1097   int border_attr[8];
1098   bool noautocmd;
1099 } FloatConfig;
1100 
1101 #define FLOAT_CONFIG_INIT ((FloatConfig){ .height = 0, .width = 0, \
1102                                           .bufpos = { -1, 0 }, \
1103                                           .row = 0, .col = 0, .anchor = 0, \
1104                                           .relative = 0, .external = false, \
1105                                           .focusable = true, \
1106                                           .zindex = kZIndexFloatDefault, \
1107                                           .style = kWinStyleUnused, \
1108                                           .noautocmd = false })
1109 
1110 // Structure to store last cursor position and topline.  Used by check_lnums()
1111 // and reset_lnums().
1112 typedef struct {
1113   int w_topline_save;   // original topline value
1114   int w_topline_corr;   // corrected topline value
1115   pos_T w_cursor_save;  // original cursor position
1116   pos_T w_cursor_corr;  // corrected cursor position
1117 } pos_save_T;
1118 
1119 /// Indices into vimmenu_T->strings[] and vimmenu_T->noremap[] for each mode
1120 /// \addtogroup MENU_INDEX
1121 /// @{
1122 enum {
1123   MENU_INDEX_INVALID      = -1,
1124   MENU_INDEX_NORMAL       = 0,
1125   MENU_INDEX_VISUAL       = 1,
1126   MENU_INDEX_SELECT       = 2,
1127   MENU_INDEX_OP_PENDING   = 3,
1128   MENU_INDEX_INSERT       = 4,
1129   MENU_INDEX_CMDLINE      = 5,
1130   MENU_INDEX_TIP          = 6,
1131   MENU_MODES              = 7,
1132 };
1133 
1134 typedef struct VimMenu vimmenu_T;
1135 
1136 struct VimMenu {
1137   int modes;                         ///< Which modes is this menu visible for
1138   int enabled;                       ///< for which modes the menu is enabled
1139   char_u *name;                 ///< Name of menu, possibly translated
1140   char_u *dname;                ///< Displayed Name ("name" without '&')
1141   char_u *en_name;              ///< "name" untranslated, NULL when
1142                                 ///< was not translated
1143   char_u *en_dname;             ///< NULL when "dname" untranslated
1144   int mnemonic;                      ///< mnemonic key (after '&')
1145   char_u *actext;               ///< accelerator text (after TAB)
1146   long priority;                     ///< Menu order priority
1147   char_u *strings[MENU_MODES];  ///< Mapped string for each mode
1148   int noremap[MENU_MODES];           ///< A \ref REMAP_VALUES flag for each mode
1149   bool silent[MENU_MODES];           ///< A silent flag for each mode
1150   vimmenu_T *children;             ///< Children of sub-menu
1151   vimmenu_T *parent;               ///< Parent of menu
1152   vimmenu_T *next;                 ///< Next item in menu
1153 };
1154 
1155 /// Structure which contains all information that belongs to a window.
1156 ///
1157 /// All row numbers are relative to the start of the window, except w_winrow.
1158 struct window_S {
1159   handle_T handle;                  ///< unique identifier for the window
1160 
1161   buf_T *w_buffer;            ///< buffer we are a window into (used
1162                               ///< often, keep it the first item!)
1163 
1164   synblock_T *w_s;                 ///< for :ownsyntax
1165 
1166   int w_hl_id_normal;               ///< 'winhighlight' normal id
1167   int w_hl_attr_normal;             ///< 'winhighlight' normal final attrs
1168 
1169   int w_hl_ids[HLF_COUNT];          ///< 'winhighlight' id
1170   int w_hl_attrs[HLF_COUNT];        ///< 'winhighlight' final attrs
1171 
1172   int w_hl_needs_update;            ///< attrs need to be recalculated
1173 
1174   win_T *w_prev;              ///< link to previous window
1175   win_T *w_next;              ///< link to next window
1176   bool w_closing;                   ///< window is being closed, don't let
1177                                     ///  autocommands close it too.
1178 
1179   frame_T *w_frame;             ///< frame containing this window
1180 
1181   pos_T w_cursor;                   ///< cursor position in buffer
1182 
1183   colnr_T w_curswant;               ///< Column we want to be at.  This is
1184                                     ///  used to try to stay in the same column
1185                                     ///  for up/down cursor motions.
1186 
1187   int w_set_curswant;               // If set, then update w_curswant the next
1188                                     // time through cursupdate() to the
1189                                     // current virtual column
1190 
1191   linenr_T w_last_cursorline;       ///< where last 'cursorline' was drawn
1192   pos_T w_last_cursormoved;         ///< for CursorMoved event
1193 
1194   // the next seven are used to update the visual part
1195   char w_old_visual_mode;           ///< last known VIsual_mode
1196   linenr_T w_old_cursor_lnum;       ///< last known end of visual part
1197   colnr_T w_old_cursor_fcol;        ///< first column for block visual part
1198   colnr_T w_old_cursor_lcol;        ///< last column for block visual part
1199   linenr_T w_old_visual_lnum;       ///< last known start of visual part
1200   colnr_T w_old_visual_col;         ///< last known start of visual part
1201   colnr_T w_old_curswant;           ///< last known value of Curswant
1202 
1203   // 'listchars' characters. Defaults set in set_chars_option().
1204   struct {
1205     int eol;
1206     int ext;
1207     int prec;
1208     int nbsp;
1209     int space;
1210     int tab1;                       ///< first tab character
1211     int tab2;                       ///< second tab character
1212     int tab3;                       ///< third tab character
1213     int lead;
1214     int trail;
1215     int *multispace;
1216     int conceal;
1217   } w_p_lcs_chars;
1218 
1219   // 'fillchars' characters. Defaults set in set_chars_option().
1220   struct {
1221     int stl;
1222     int stlnc;
1223     int vert;
1224     int fold;
1225     int foldopen;                    ///< when fold is open
1226     int foldclosed;                  ///< when fold is closed
1227     int foldsep;                     ///< continuous fold marker
1228     int diff;
1229     int msgsep;
1230     int eob;
1231   } w_p_fcs_chars;
1232 
1233   /*
1234    * "w_topline", "w_leftcol" and "w_skipcol" specify the offsets for
1235    * displaying the buffer.
1236    */
1237   linenr_T w_topline;               /* buffer line number of the line at the
1238                                        top of the window */
1239   char w_topline_was_set;           /* flag set to TRUE when topline is set,
1240                                        e.g. by winrestview() */
1241   int w_topfill;                    // number of filler lines above w_topline
1242   int w_old_topfill;                // w_topfill at last redraw
1243   bool w_botfill;                   // true when filler lines are actually
1244                                     // below w_topline (at end of file)
1245   bool w_old_botfill;               // w_botfill at last redraw
1246   colnr_T w_leftcol;                // window column number of the left most
1247                                     // character in the window; used when
1248                                     // 'wrap' is off
1249   colnr_T w_skipcol;                // starting column when a single line
1250                                     // doesn't fit in the window
1251 
1252   // "w_last_topline" and "w_last_leftcol" are used to determine if
1253   // a Scroll autocommand should be emitted.
1254   linenr_T w_last_topline;          ///< last known value for topline
1255   colnr_T w_last_leftcol;          ///< last known value for leftcol
1256   int w_last_width;                 ///< last known value for width
1257   int w_last_height;                ///< last known value for height
1258 
1259   //
1260   // Layout of the window in the screen.
1261   // May need to add "msg_scrolled" to "w_winrow" in rare situations.
1262   //
1263   int w_winrow;                     // first row of window in screen
1264   int w_height;                     // number of rows in window, excluding
1265                                     // status/command/winbar line(s)
1266   int w_status_height;              // number of status lines (0 or 1)
1267   int w_wincol;                     // Leftmost column of window in screen.
1268   int w_width;                      // Width of window, excluding separation.
1269   int w_vsep_width;                 // Number of separator columns (0 or 1).
1270   pos_save_T w_save_cursor;         // backup of cursor pos and topline
1271 
1272   // inner size of window, which can be overridden by external UI
1273   int w_height_inner;
1274   int w_width_inner;
1275   // external UI request. If non-zero, the inner size will use this.
1276   int w_height_request;
1277   int w_width_request;
1278 
1279   int w_border_adj[4];  // top, right, bottom, left
1280   // outer size of window grid, including border
1281   int w_height_outer;
1282   int w_width_outer;
1283 
1284   /*
1285    * === start of cached values ====
1286    */
1287   /*
1288    * Recomputing is minimized by storing the result of computations.
1289    * Use functions in screen.c to check if they are valid and to update.
1290    * w_valid is a bitfield of flags, which indicate if specific values are
1291    * valid or need to be recomputed.
1292    */
1293   int w_valid;
1294   pos_T w_valid_cursor;             /* last known position of w_cursor, used
1295                                        to adjust w_valid */
1296   colnr_T w_valid_leftcol;          // last known w_leftcol
1297 
1298   bool w_viewport_invalid;
1299 
1300   /*
1301    * w_cline_height is the number of physical lines taken by the buffer line
1302    * that the cursor is on.  We use this to avoid extra calls to plines_win().
1303    */
1304   int w_cline_height;               // current size of cursor line
1305   bool w_cline_folded;              // cursor line is folded
1306 
1307   int w_cline_row;                  // starting row of the cursor line
1308 
1309   colnr_T w_virtcol;                // column number of the cursor in the
1310                                     // buffer line, as opposed to the column
1311                                     // number we're at on the screen.  This
1312                                     // makes a difference on lines which span
1313                                     // more than one screen line or when
1314                                     // w_leftcol is non-zero
1315 
1316   /*
1317    * w_wrow and w_wcol specify the cursor position in the window.
1318    * This is related to positions in the window, not in the display or
1319    * buffer, thus w_wrow is relative to w_winrow.
1320    */
1321   int w_wrow, w_wcol;               // cursor position in window
1322 
1323   linenr_T w_botline;               // number of the line below the bottom of
1324                                     // the window
1325   int w_empty_rows;                 // number of ~ rows in window
1326   int w_filler_rows;                // number of filler rows at the end of the
1327                                     // window
1328 
1329   /*
1330    * Info about the lines currently in the window is remembered to avoid
1331    * recomputing it every time.  The allocated size of w_lines[] is Rows.
1332    * Only the w_lines_valid entries are actually valid.
1333    * When the display is up-to-date w_lines[0].wl_lnum is equal to w_topline
1334    * and w_lines[w_lines_valid - 1].wl_lnum is equal to w_botline.
1335    * Between changing text and updating the display w_lines[] represents
1336    * what is currently displayed.  wl_valid is reset to indicated this.
1337    * This is used for efficient redrawing.
1338    */
1339   int w_lines_valid;                // number of valid entries
1340   wline_T *w_lines;
1341 
1342   garray_T w_folds;                 // array of nested folds
1343   bool w_fold_manual;               // when true: some folds are opened/closed
1344                                     // manually
1345   bool w_foldinvalid;               // when true: folding needs to be
1346                                     // recomputed
1347   int w_nrwidth;                    // width of 'number' and 'relativenumber'
1348                                     // column being used
1349 
1350   /*
1351    * === end of cached values ===
1352    */
1353 
1354   int w_redr_type;                  // type of redraw to be performed on win
1355   int w_upd_rows;                   // number of window lines to update when
1356                                     // w_redr_type is REDRAW_TOP
1357   linenr_T w_redraw_top;            // when != 0: first line needing redraw
1358   linenr_T w_redraw_bot;            // when != 0: last line needing redraw
1359   bool w_redr_status;               // if true status line must be redrawn
1360   bool w_redr_border;               // if true border must be redrawn
1361 
1362   // remember what is shown in the ruler for this window (if 'ruler' set)
1363   pos_T w_ru_cursor;                // cursor position shown in ruler
1364   colnr_T w_ru_virtcol;             // virtcol shown in ruler
1365   linenr_T w_ru_topline;            // topline shown in ruler
1366   linenr_T w_ru_line_count;         // line count used for ruler
1367   int w_ru_topfill;                 // topfill shown in ruler
1368   char w_ru_empty;                  // TRUE if ruler shows 0-1 (empty line)
1369 
1370   int w_alt_fnum;                   // alternate file (for # and CTRL-^)
1371 
1372   alist_T *w_alist;             // pointer to arglist for this window
1373   int w_arg_idx;                    // current index in argument list (can be
1374                                     // out of range!)
1375   int w_arg_idx_invalid;            // editing another file than w_arg_idx
1376 
1377   char_u *w_localdir;          // absolute path of local directory or NULL
1378   char_u *w_prevdir;           // previous directory
1379   // Options local to a window.
1380   // They are local because they influence the layout of the window or
1381   // depend on the window layout.
1382   // There are two values: w_onebuf_opt is local to the buffer currently in
1383   // this window, w_allbuf_opt is for all buffers in this window.
1384   winopt_T w_onebuf_opt;
1385   winopt_T w_allbuf_opt;
1386 
1387   // A few options have local flags for P_INSECURE.
1388   uint32_t w_p_stl_flags;           // flags for 'statusline'
1389   uint32_t w_p_fde_flags;           // flags for 'foldexpr'
1390   uint32_t w_p_fdt_flags;           // flags for 'foldtext'
1391   int *w_p_cc_cols;         // array of columns to highlight or NULL
1392   char_u w_p_culopt_flags;     // flags for cursorline highlighting
1393   long w_p_siso;             // 'sidescrolloff' local value
1394   long w_p_so;               // 'scrolloff' local value
1395 
1396   int w_briopt_min;                 // minimum width for breakindent
1397   int w_briopt_shift;               // additional shift for breakindent
1398   bool w_briopt_sbr;                // sbr in 'briopt'
1399   int w_briopt_list;                // additional indent for lists
1400 
1401   // transform a pointer to a "onebuf" option into a "allbuf" option
1402 #define GLOBAL_WO(p)    ((char *)p + sizeof(winopt_T))
1403 
1404   long w_scbind_pos;
1405 
1406   ScopeDictDictItem w_winvar;  ///< Variable for "w:" dictionary.
1407   dict_T *w_vars;  ///< Dictionary with w: variables.
1408 
1409   /*
1410    * The w_prev_pcmark field is used to check whether we really did jump to
1411    * a new line after setting the w_pcmark.  If not, then we revert to
1412    * using the previous w_pcmark.
1413    */
1414   pos_T w_pcmark;               // previous context mark
1415   pos_T w_prev_pcmark;          // previous w_pcmark
1416 
1417   /*
1418    * the jumplist contains old cursor positions
1419    */
1420   xfmark_T w_jumplist[JUMPLISTSIZE];
1421   int w_jumplistlen;                    // number of active entries
1422   int w_jumplistidx;                    // current position
1423 
1424   int w_changelistidx;                  // current position in b_changelist
1425 
1426   matchitem_T *w_match_head;            // head of match list
1427   int w_next_match_id;                  // next match ID
1428 
1429   /*
1430    * the tagstack grows from 0 upwards:
1431    * entry 0: older
1432    * entry 1: newer
1433    * entry 2: newest
1434    */
1435   taggy_T w_tagstack[TAGSTACKSIZE];     // the tag stack
1436   int w_tagstackidx;                    // idx just below active entry
1437   int w_tagstacklen;                    // number of tags on stack
1438 
1439   ScreenGrid w_grid;                    // the grid specific to the window
1440   ScreenGrid w_grid_alloc;              // the grid specific to the window
1441   bool w_pos_changed;                   // true if window position changed
1442   bool w_floating;                       ///< whether the window is floating
1443   FloatConfig w_float_config;
1444 
1445   /*
1446    * w_fraction is the fractional row of the cursor within the window, from
1447    * 0 at the top row to FRACTION_MULT at the last row.
1448    * w_prev_fraction_row was the actual cursor row when w_fraction was last
1449    * calculated.
1450    */
1451   int w_fraction;
1452   int w_prev_fraction_row;
1453 
1454   linenr_T w_nrwidth_line_count;        /* line count when ml_nrwidth_width
1455                                          * was computed. */
1456   int w_nrwidth_width;                  // nr of chars to print line count.
1457 
1458   qf_info_T *w_llist;                 // Location list for this window
1459   // Location list reference used in the location list window.
1460   // In a non-location list window, w_llist_ref is NULL.
1461   qf_info_T *w_llist_ref;
1462 };
1463 
win_hl_attr(win_T * wp,int hlf)1464 static inline int win_hl_attr(win_T *wp, int hlf)
1465 {
1466   return wp->w_hl_attrs[hlf];
1467 }
1468 
1469 /// Macros defined in Vim, but not in Neovim
1470 #define CHANGEDTICK(buf) \
1471   (=== Include buffer.h & use buf_(get|set|inc) _changedtick ===)
1472 
1473 #endif // NVIM_BUFFER_DEFS_H
1474