neovim

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

parser.h (2556B)


      1 #pragma once
      2 
      3 #include <assert.h>
      4 #include <stdbool.h>
      5 #include <stddef.h>
      6 
      7 #include "klib/kvec.h"
      8 #include "nvim/mbyte_defs.h"
      9 #include "nvim/viml/parser/parser_defs.h"  // IWYU pragma: keep
     10 
     11 #include "viml/parser/parser.h.generated.h"
     12 #include "viml/parser/parser.h.inline.generated.h"
     13 
     14 /// Initialize a new parser state instance
     15 ///
     16 /// @param[out]  ret_pstate  Parser state to initialize.
     17 /// @param[in]  get_line  Line getter function.
     18 /// @param[in]  cookie  Argument for the get_line function.
     19 /// @param[in]  colors  Where to save highlighting. May be NULL if it is not
     20 ///                     needed.
     21 static inline void viml_parser_init(ParserState *const ret_pstate, const ParserLineGetter get_line,
     22                                    void *const cookie, ParserHighlight *const colors)
     23  FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ARG(1, 2)
     24 {
     25  *ret_pstate = (ParserState) {
     26    .reader = {
     27      .get_line = get_line,
     28      .cookie = cookie,
     29      .conv = MBYTE_NONE_CONV,
     30    },
     31    .pos = { 0, 0 },
     32    .colors = colors,
     33    .can_continuate = false,
     34  };
     35  kvi_init(ret_pstate->reader.lines);
     36  kvi_init(ret_pstate->stack);
     37 }
     38 
     39 /// Advance position by a given number of bytes
     40 ///
     41 /// At maximum advances to the next line.
     42 ///
     43 /// @param  pstate  Parser state to advance.
     44 /// @param[in]  len  Number of bytes to advance.
     45 static inline void viml_parser_advance(ParserState *const pstate, const size_t len)
     46  FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
     47 {
     48  assert(pstate->pos.line == kv_size(pstate->reader.lines) - 1);
     49  const ParserLine pline = kv_last(pstate->reader.lines);
     50  if (pstate->pos.col + len >= pline.size) {
     51    pstate->pos.line++;
     52    pstate->pos.col = 0;
     53  } else {
     54    pstate->pos.col += len;
     55  }
     56 }
     57 
     58 /// Record highlighting of some region of text
     59 ///
     60 /// @param  pstate  Parser state to work with.
     61 /// @param[in]  start  Start position of the highlight.
     62 /// @param[in]  len  Highlighting chunk length.
     63 /// @param[in]  group  Highlight group.
     64 static inline void viml_parser_highlight(ParserState *const pstate, const ParserPosition start,
     65                                         const size_t len, const char *const group)
     66  FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_NONNULL_ALL
     67 {
     68  if (pstate->colors == NULL || len == 0) {
     69    return;
     70  }
     71  assert(kv_size(*pstate->colors) == 0
     72         || kv_Z(*pstate->colors, 0).start.line < start.line
     73         || kv_Z(*pstate->colors, 0).end_col <= start.col);
     74  kvi_push(*pstate->colors, ((ParserHighlightChunk) {
     75    .start = start,
     76    .end_col = start.col + len,
     77    .group = group,
     78  }));
     79 }