Unnamed repository; edit this file 'description' to name the repository.
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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
use serde::{Deserialize, Serialize};

use crate::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum StatusLineElement {
    /// The editor mode (Normal, Insert, Visual/Selection)
    Mode,
    /// The LSP activity spinner
    Spinner,
    /// The file basename (the leaf of the open file's path)
    FileBaseName,
    /// The relative file path
    FileName,
    // The file modification indicator
    FileModificationIndicator,
    /// An indicator that shows `"[readonly]"` when a file cannot be written
    ReadOnlyIndicator,
    /// The file encoding
    FileEncoding,
    /// The file line endings (CRLF or LF)
    FileLineEnding,
    /// The file type (language ID or "text")
    FileType,
    /// A summary of the number of errors and warnings
    Diagnostics,
    /// A summary of the number of errors and warnings on file and workspace
    WorkspaceDiagnostics,
    /// The number of selections (cursors)
    Selections,
    /// The number of characters currently in primary selection
    PrimarySelectionLength,
    /// The cursor position
    Position,
    /// The separator string
    Separator,
    /// The cursor position as a percent of the total file
    PositionPercentage,
    /// The total line numbers of the current file
    TotalLineNumbers,
    /// A single space
    Spacer,
    /// Current version control information
    VersionControl,
    /// Indicator for selected register
    Register,
}

config_serde_adapter!(StatusLineElement);

#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
/// UNSTABLE
pub enum CursorKind {
    /// █
    Block,
    /// |
    Bar,
    /// _
    Underline,
    /// Hidden cursor, can set cursor position with this to let IME have correct cursor position.
    Hidden,
}

impl Default for CursorKind {
    fn default() -> Self {
        Self::Block
    }
}

config_serde_adapter!(CursorKind);

#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum WhitespaceRenderValue {
    None,
    // TODO
    // Selection,
    All,
}

config_serde_adapter!(WhitespaceRenderValue);

/// bufferline render modes
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum BufferLine {
    /// Don't render bufferline
    Never,
    /// Always render
    Always,
    /// Only if multiple buffers are open
    Multiple,
}

config_serde_adapter!(BufferLine);

#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum PopupBorderConfig {
    None,
    All,
    Popup,
    Menu,
}

config_serde_adapter!(PopupBorderConfig);

options! {
    struct UiConfig {
        /// Whether to display info boxes
        #[read = copy]
        auto_info: bool = true,
        /// Renders a line at the top of the editor displaying open buffers.
        /// Can be `always`, `never` or `multiple` (only shown if more than one
        /// buffer is in use)
        #[read = copy]
        bufferline: BufferLine = BufferLine::Never,
        /// Highlight all lines with a cursor
        #[read = copy]
        cursorline: bool = false,
        /// Highlight all columns with a cursor
        #[read = copy]
        cursorcolumn: bool = false,
        /// List of column positions at which to display the rulers.
        #[read = deref]
        rulers: List<u16> = List::default(),
        /// Whether to color the mode indicator with different colors depending on the mode itself
        #[read = copy]
        popup_border: bool = false,
        /// Whether to color the mode indicator with different colors depending on the mode itself
        #[read = copy]
        color_modes: bool = false,
    }

    struct WhiteSpaceRenderConfig {
        #[name = "whitespace.characters.space"]
        #[read = copy]
        space_char: char =  '·',   // U+00B7
        #[name = "whitespace.characters.nbsp"]
        #[read = copy]
        nbsp_char: char =  '⍽',    // U+237D
        #[name = "whitespace.characters.tab"]
        #[read = copy]
        tab_char: char =  '→',     // U+2192
        #[name = "whitespace.characters.tabpad"]
        #[read = copy]
        tabpad_char: char =  '⏎', // U+23CE
        #[name = "whitespace.characters.newline"]
        #[read = copy]
        newline_char: char =  ' ',
        #[name = "whitespace.render.default"]
        #[read = copy]
        render: WhitespaceRenderValue = WhitespaceRenderValue::None,
        #[name = "whitespace.render.space"]
        #[read = copy]
        render_space: Option<WhitespaceRenderValue> = None,
        #[name = "whitespace.render.nbsp"]
        #[read = copy]
        render_nbsp: Option<WhitespaceRenderValue> = None,
        #[name = "whitespace.render.tab"]
        #[read = copy]
        render_tab: Option<WhitespaceRenderValue> = None,
        #[name = "whitespace.render.newline"]
        #[read = copy]
        render_newline: Option<WhitespaceRenderValue> = None,
    }

    struct TerminfoConfig {
        /// Set to `true` to override automatic detection of terminal truecolor
        /// support in the event of a false negative
        #[name = "true-color"]
        #[read = copy]
        force_true_color: bool = false,
        /// Set to `true` to override automatic detection of terminal undercurl
        /// support in the event of a false negative
        #[name = "undercurl"]
        #[read = copy]
        force_undercurl: bool = false,
    }

    struct IndentGuidesConfig {
        /// Whether to render indent guides
        #[read = copy]
        render: bool = false,
        /// Character to use for rendering indent guides
        #[read = copy]
        character: char = '│',
        /// Number of indent levels to skip
        #[read = copy]
        skip_levels: u8 = 0,
    }

    struct CursorShapeConfig {
        /// Cursor shape in normal mode
        #[name = "cursor-shape.normal"]
        #[read = copy]
        normal_mode_cursor: CursorKind = CursorKind::Block,
        /// Cursor shape in select mode
        #[name = "cursor-shape.select"]
        #[read = copy]
        select_mode_cursor: CursorKind = CursorKind::Block,
        /// Cursor shape in insert mode
        #[name = "cursor-shape.insert"]
        #[read = copy]
        insert_mode_cursor: CursorKind = CursorKind::Block,
    }

    struct FilePickerConfig {
        /// Whether to exclude hidden files from any file pickers.
        #[name = "file-picker.hidden"]
        #[read = copy]
        hidden: bool = true,
        /// Follow symlinks instead of ignoring them
        #[name = "file-picker.follow-symlinks"]
        #[read = copy]
        follow_symlinks: bool = true,
        /// Ignore symlinks that point at files already shown in the picker
        #[name = "file-picker.deduplicate-links"]
        #[read = copy]
        deduplicate_links: bool = true,
        /// Enables reading ignore files from parent directories.
        #[name = "file-picker.parents"]
        #[read = copy]
        parents: bool = true,
        /// Enables reading `.ignore` files.
        #[name = "file-picker.ignore"]
        #[read = copy]
        ignore: bool = true,
        /// Enables reading `.gitignore` files.
        #[name = "file-picker.git-ignore"]
        #[read = copy]
        git_ignore: bool = true,
        /// Enables reading global .gitignore, whose path is specified in git's config: `core.excludefile` option.
        #[name = "file-picker.git-global"]
        #[read = copy]
        git_global: bool = true,
        /// Enables reading `.git/info/exclude` files.
        #[name = "file-picker.git-exclude"]
        #[read = copy]
        git_exclude: bool = true,
        /// Maximum Depth to recurse directories in file picker and global search.
        #[name = "file-picker.max-depth"]
        #[read = copy]
        max_depth: Option<usize> = None,
    }

    struct StatusLineConfig{
        /// A list of elements aligned to the left of the statusline
        #[name = "statusline.left"]
        #[read = deref]
        left: List<StatusLineElement> =  &[
            StatusLineElement::Mode,
            StatusLineElement::Spinner,
            StatusLineElement::FileName,
            StatusLineElement::ReadOnlyIndicator,
            StatusLineElement::FileModificationIndicator,
        ],
        /// A list of elements aligned to the middle of the statusline
        #[name = "statusline.center"]
        #[read = deref]
        center: List<StatusLineElement> =  List::default(),
        /// A list of elements aligned to the right of the statusline
        #[name = "statusline.right"]
        #[read = deref]
        right: List<StatusLineElement> =  &[
            StatusLineElement::Diagnostics,
            StatusLineElement::Selections,
            StatusLineElement::Register,
            StatusLineElement::Position,
            StatusLineElement::FileEncoding,
        ],
        /// The character used to separate elements in the statusline
        #[name = "statusline.seperator"]
        #[read = deref]
        seperator: String = "│",
        /// The text shown in the `mode` element for normal mode
        #[name = "statusline.mode.normal"]
        #[read = deref]
        mode_indicator_normal: String = "NOR",
        /// The text shown in the `mode` element for insert mode
        #[name = "statusline.mode.insert"]
        #[read = deref]
        mode_indicator_insert: String = "INS",
        /// The text shown in the `mode` element for select mode
        #[name = "statusline.mode.select"]
        #[read = deref]
        mode_indicator_select: String = "SEL",
    }
}