neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

buffer_defs.h (61870B)


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