aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/vterm/vterm.h
blob: e66f40425a0cc22060fa04b72fe557e1121e51d5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#pragma once

#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#include "nvim/macros_defs.h"
#include "nvim/types_defs.h"
#include "nvim/vterm/vterm_defs.h"
#include "nvim/vterm/vterm_keycodes_defs.h"

#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "vterm/vterm.h.generated.h"
#endif

#define VTERM_VERSION_MAJOR 0
#define VTERM_VERSION_MINOR 3

// move a rect
static inline void vterm_rect_move(VTermRect *rect, int row_delta, int col_delta)
{
  rect->start_row += row_delta; rect->end_row += row_delta;
  rect->start_col += col_delta; rect->end_col += col_delta;
}

// Bit-field describing the content of the tagged union `VTermColor`.
typedef enum {
  // If the lower bit of `type` is not set, the colour is 24-bit RGB.
  VTERM_COLOR_RGB = 0x00,

  // The colour is an index into a palette of 256 colours.
  VTERM_COLOR_INDEXED = 0x01,

  // Mask that can be used to extract the RGB/Indexed bit.
  VTERM_COLOR_TYPE_MASK = 0x01,

  // If set, indicates that this colour should be the default foreground color, i.e. there was no
  // SGR request for another colour. When rendering this colour it is possible to ignore "idx" and
  // just use a colour that is not in the palette.
  VTERM_COLOR_DEFAULT_FG = 0x02,

  // If set, indicates that this colour should be the default background color, i.e. there was no
  // SGR request for another colour. A common option when rendering this colour is to not render a
  // background at all, for example by rendering the window transparently at this spot.
  VTERM_COLOR_DEFAULT_BG = 0x04,

  // Mask that can be used to extract the default foreground/background bit.
  VTERM_COLOR_DEFAULT_MASK = 0x06,
} VTermColorType;

// Returns true if the VTERM_COLOR_RGB `type` flag is set, indicating that the given VTermColor
// instance is an indexed colour.
#define VTERM_COLOR_IS_INDEXED(col) \
  (((col)->type & VTERM_COLOR_TYPE_MASK) == VTERM_COLOR_INDEXED)

// Returns true if the VTERM_COLOR_INDEXED `type` flag is set, indicating that the given VTermColor
// instance is an rgb colour.
#define VTERM_COLOR_IS_RGB(col) \
  (((col)->type & VTERM_COLOR_TYPE_MASK) == VTERM_COLOR_RGB)

// Returns true if the VTERM_COLOR_DEFAULT_FG `type` flag is set, indicating that the given
// VTermColor instance corresponds to the default foreground color.
#define VTERM_COLOR_IS_DEFAULT_FG(col) \
  (!!((col)->type & VTERM_COLOR_DEFAULT_FG))

// Returns true if the VTERM_COLOR_DEFAULT_BG `type` flag is set, indicating that the given
// VTermColor instance corresponds to the default background color.
#define VTERM_COLOR_IS_DEFAULT_BG(col) \
  (!!((col)->type & VTERM_COLOR_DEFAULT_BG))

// Constructs a new VTermColor instance representing the given RGB values.
static inline void vterm_color_rgb(VTermColor *col, uint8_t red, uint8_t green, uint8_t blue)
{
  col->type = VTERM_COLOR_RGB;
  col->rgb.red = red;
  col->rgb.green = green;
  col->rgb.blue = blue;
}

// Construct a new VTermColor instance representing an indexed color with the given index.
static inline void vterm_color_indexed(VTermColor *col, uint8_t idx)
{
  col->type = VTERM_COLOR_INDEXED;
  col->indexed.idx = idx;
}

// ------------
// Parser layer
// ------------

/// Flag to indicate non-final subparameters in a single CSI parameter.
/// Consider
///   CSI 1;2:3:4;5a
/// 1 4 and 5 are final.
/// 2 and 3 are non-final and will have this bit set
///
/// Don't confuse this with the final byte of the CSI escape; 'a' in this case.
#define CSI_ARG_FLAG_MORE (1U << 31)
#define CSI_ARG_MASK      (~(1U << 31))

#define CSI_ARG_HAS_MORE(a) ((a)& CSI_ARG_FLAG_MORE)
#define CSI_ARG(a)          ((a)& CSI_ARG_MASK)

// Can't use -1 to indicate a missing argument; use this instead
#define CSI_ARG_MISSING ((1UL<<31) - 1)

#define CSI_ARG_IS_MISSING(a) (CSI_ARG(a) == CSI_ARG_MISSING)
#define CSI_ARG_OR(a, def)     (CSI_ARG(a) == CSI_ARG_MISSING ? (def) : CSI_ARG(a))
#define CSI_ARG_COUNT(a)      (CSI_ARG(a) == CSI_ARG_MISSING || CSI_ARG(a) == 0 ? 1 : CSI_ARG(a))

enum {
  VTERM_UNDERLINE_OFF,
  VTERM_UNDERLINE_SINGLE,
  VTERM_UNDERLINE_DOUBLE,
  VTERM_UNDERLINE_CURLY,
};

enum {
  VTERM_BASELINE_NORMAL,
  VTERM_BASELINE_RAISE,
  VTERM_BASELINE_LOWER,
};

// Back-compat alias for the brief time it was in 0.3-RC1
#define vterm_screen_set_reflow  vterm_screen_enable_reflow

void vterm_scroll_rect(VTermRect rect, int downward, int rightward,
                       int (*moverect)(VTermRect src, VTermRect dest, void *user),
                       int (*eraserect)(VTermRect rect, int selective, void *user), void *user);

struct VTermScreen {
  VTerm *vt;
  VTermState *state;

  const VTermScreenCallbacks *callbacks;
  void *cbdata;

  VTermDamageSize damage_merge;
  // start_row == -1 => no damage
  VTermRect damaged;
  VTermRect pending_scrollrect;
  int pending_scroll_downward, pending_scroll_rightward;

  int rows;
  int cols;

  unsigned global_reverse : 1;
  unsigned reflow : 1;

  // Primary and Altscreen. buffers[1] is lazily allocated as needed
  ScreenCell *buffers[2];

  // buffer will == buffers[0] or buffers[1], depending on altscreen
  ScreenCell *buffer;

  // buffer for a single screen row used in scrollback storage callbacks
  VTermScreenCell *sb_buffer;

  ScreenPen pen;
};