• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tstack / lnav / 24959179949-2999

26 Apr 2026 02:37PM UTC coverage: 69.227% (+0.09%) from 69.141%
24959179949-2999

push

github

tstack
[tests] fix paths

53969 of 77959 relevant lines covered (69.23%)

568944.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.51
/src/base/string_attr_type.hh
1
/**
2
 * Copyright (c) 2020, Timothy Stack
3
 *
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *
9
 * * Redistributions of source code must retain the above copyright notice, this
10
 * list of conditions and the following disclaimer.
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 * this list of conditions and the following disclaimer in the documentation
13
 * and/or other materials provided with the distribution.
14
 * * Neither the name of Timothy Stack nor the names of its contributors
15
 * may be used to endorse or promote products derived from this software
16
 * without specific prior written permission.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
19
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21
 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
22
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
29

30
#ifndef lnav_string_attr_type_hh
31
#define lnav_string_attr_type_hh
32

33
#include <memory>
34
#include <optional>
35
#include <string>
36
#include <utility>
37

38
#include <stdint.h>
39

40
#include "base/file_range.hh"
41
#include "base/intern_string.hh"
42
#include "base/string_util.hh"
43
#include "color_spaces.hh"
44
#include "enum_util.hh"
45
#include "mapbox/variant.hpp"
46
#include "text_format_enum.hh"
47

48
class logfile;
49
struct bookmark_metadata;
50

51
enum class ui_icon_t : int32_t {
52
    hidden,
53
    ok,
54
    info,
55
    warning,
56
    error,
57

58
    log_level_trace,
59
    log_level_debug,
60
    log_level_info,
61
    log_level_stats,
62
    log_level_notice,
63
    log_level_warning,
64
    log_level_error,
65
    log_level_critical,
66
    log_level_fatal,
67

68
    breakpoint,
69
    disabled_breakpoint,
70

71
    play,
72
    edit,
73
    file,
74
    thread,
75
    tag,
76
    partition,
77
    busy,
78
    reload,
79
};
80

81
constexpr auto ui_icon_count
82
    = lnav::enums::to_underlying(ui_icon_t::reload) + 1;
83

84
/** Roles that can be mapped to curses attributes using attrs_for_role() */
85
enum class role_t : int32_t {
86
    VCR_NONE = -1,
87

88
    VCR_TEXT, /*< Raw text. */
89
    VCR_IDENTIFIER,
90
    VCR_SEARCH, /*< A search hit. */
91
    VCR_OK,
92
    VCR_INFO,
93
    VCR_ERROR, /*< An error message. */
94
    VCR_WARNING, /*< A warning message. */
95
    VCR_ALT_ROW, /*< Highlight for alternating rows in a list */
96
    VCR_HIDDEN,
97
    VCR_CURSOR_LINE,
98
    VCR_DISABLED_CURSOR_LINE,
99
    VCR_ADJUSTED_TIME,
100
    VCR_SKEWED_TIME,
101
    VCR_OFFSET_TIME,
102
    VCR_TIME_AGO,
103
    VCR_TIME_COLUMN,
104
    VCR_TIME_COLUMN_TO_TEXT,
105
    VCR_FILE_OFFSET,
106
    VCR_INVALID_MSG,
107
    VCR_STATUS, /*< Normal status line text. */
108
    VCR_WARN_STATUS,
109
    VCR_ALERT_STATUS, /*< Alert status line text. */
110
    VCR_ACTIVE_STATUS, /*< */
111
    VCR_ACTIVE_STATUS2, /*< */
112
    VCR_STATUS_TITLE,
113
    VCR_STATUS_SUBTITLE,
114
    VCR_STATUS_INFO,
115
    VCR_STATUS_STITCH_TITLE_TO_SUB,
116
    VCR_STATUS_STITCH_SUB_TO_TITLE,
117
    VCR_STATUS_STITCH_SUB_TO_NORMAL,
118
    VCR_STATUS_STITCH_NORMAL_TO_SUB,
119
    VCR_STATUS_STITCH_TITLE_TO_NORMAL,
120
    VCR_STATUS_STITCH_NORMAL_TO_TITLE,
121
    VCR_STATUS_TITLE_HOTKEY,
122
    VCR_STATUS_DISABLED_TITLE,
123
    VCR_STATUS_HOTKEY,
124
    VCR_ALERT_STATUS_TITLE,
125
    VCR_STATUS_STITCH_ALERT_TITLE_TO_NORMAL,
126
    VCR_STATUS_STITCH_NORMAL_TO_ALERT_TITLE,
127
    VCR_INACTIVE_STATUS,
128
    VCR_INACTIVE_WARN_STATUS,
129
    VCR_INACTIVE_ALERT_STATUS,
130
    VCR_SCROLLBAR,
131
    VCR_SCROLLBAR_ERROR,
132
    VCR_SCROLLBAR_WARNING,
133
    VCR_FOCUSED,
134
    VCR_DISABLED_FOCUSED,
135
    VCR_POPUP,
136
    VCR_POPUP_BORDER,
137
    VCR_COLOR_HINT,
138

139
    VCR_QUOTED_CODE,
140
    VCR_CODE_BORDER,
141
    VCR_KEYWORD,
142
    VCR_STRING,
143
    VCR_COMMENT,
144
    VCR_DOC_DIRECTIVE,
145
    VCR_VARIABLE,
146
    VCR_SYMBOL,
147
    VCR_NULL,
148
    VCR_ASCII_CTRL,
149
    VCR_NON_ASCII,
150
    VCR_NUMBER,
151
    VCR_RE_SPECIAL,
152
    VCR_RE_REPEAT,
153
    VCR_FILE,
154

155
    VCR_DIFF_DELETE, /*< Deleted line in a diff. */
156
    VCR_DIFF_ADD, /*< Added line in a diff. */
157
    VCR_DIFF_SECTION, /*< Section marker in a diff. */
158

159
    VCR_LOW_THRESHOLD,
160
    VCR_MED_THRESHOLD,
161
    VCR_HIGH_THRESHOLD,
162

163
    VCR_H1,
164
    VCR_H2,
165
    VCR_H3,
166
    VCR_H4,
167
    VCR_H5,
168
    VCR_H6,
169

170
    VCR_HR,
171
    VCR_HYPERLINK,
172
    VCR_LIST_GLYPH,
173
    VCR_BREADCRUMB,
174
    VCR_TABLE_BORDER,
175
    VCR_TABLE_HEADER,
176
    VCR_QUOTE_BORDER,
177
    VCR_QUOTED_TEXT,
178
    VCR_FOOTNOTE_BORDER,
179
    VCR_FOOTNOTE_TEXT,
180
    VCR_SNIPPET_BORDER,
181
    VCR_INDENT_GUIDE,
182
    VCR_INLINE_CODE,
183
    VCR_FUNCTION,
184
    VCR_TYPE,
185
    VCR_SEP_REF_ACC,
186
    VCR_SUGGESTION,
187
    VCR_SELECTED_TEXT,
188
    VCR_FUZZY_MATCH,
189

190
    VCR_OBJECT_KEY,
191

192
    VCR_SPECTRO_THRESHOLD0,
193
    VCR_SPECTRO_THRESHOLD1,
194
    VCR_SPECTRO_THRESHOLD2,
195
    VCR_SPECTRO_THRESHOLD3,
196
    VCR_SPECTRO_THRESHOLD4,
197
    VCR_SPECTRO_THRESHOLD5,
198
    VCR_SPECTRO_THRESHOLD6,
199

200
    VCR_TIMELINE_BAR,
201

202
    VCR__MAX
203
};
204

205
struct text_attrs {
206
    enum class style : uint32_t {
207
        none = 0x0000,
208
        struck = 0x0001u,
209
        bold = 0x0002u,
210
        undercurl = 0x0004u,
211
        underline = 0x0008u,
212
        italic = 0x0010u,
213
        altcharset = 0x0020u,
214
        blink = 0x0040u,
215
        reverse = 0x1000u,
216
    };
217

218
    static text_attrs with_struck()
697✔
219
    {
220
        return text_attrs{
221
            lnav::enums::to_underlying(style::struck),
222
        };
697✔
223
    }
224

225
    static text_attrs with_bold()
921✔
226
    {
227
        return text_attrs{
228
            lnav::enums::to_underlying(style::bold),
229
        };
921✔
230
    }
231

232
    static text_attrs with_undercurl()
233
    {
234
        return text_attrs{
235
            lnav::enums::to_underlying(style::undercurl),
236
        };
237
    }
238

239
    static text_attrs with_underline()
54,737✔
240
    {
241
        return text_attrs{
242
            lnav::enums::to_underlying(style::underline),
243
        };
54,737✔
244
    }
245

246
    static text_attrs with_italic()
697✔
247
    {
248
        return text_attrs{
249
            lnav::enums::to_underlying(style::italic),
250
        };
697✔
251
    }
252

253
    static text_attrs with_reverse()
53,141✔
254
    {
255
        return text_attrs{
256
            lnav::enums::to_underlying(style::reverse),
257
        };
53,141✔
258
    }
259

260
    static text_attrs with_altcharset()
114✔
261
    {
262
        return text_attrs{
263
            lnav::enums::to_underlying(style::altcharset),
264
        };
114✔
265
    }
266

267
    static text_attrs with_blink()
268
    {
269
        return text_attrs{
270
            lnav::enums::to_underlying(style::blink),
271
        };
272
    }
273

274
    template<typename... Args>
275
    static text_attrs with_styles(Args... args)
250✔
276
    {
277
        auto retval = text_attrs{};
250✔
278

279
        for (auto arg : {args...}) {
536✔
280
            retval.ta_attrs |= lnav::enums::to_underlying(arg);
286✔
281
        }
282
        return retval;
250✔
283
    }
284

285
    bool empty() const
57,881✔
286
    {
287
        return this->ta_attrs == 0 && this->ta_fg_color.empty()
46,096✔
288
            && this->ta_bg_color.empty();
103,977✔
289
    }
290

291
    text_attrs operator|(const text_attrs& other) const
60,599✔
292
    {
293
        return text_attrs{
294
            this->ta_attrs | other.ta_attrs,
60,599✔
295
            !this->ta_fg_color.empty() ? this->ta_fg_color : other.ta_fg_color,
60,599✔
296
            !this->ta_bg_color.empty() ? this->ta_bg_color : other.ta_bg_color,
60,599✔
297
        };
181,797✔
298
    }
299

300
    text_attrs operator|(const style other) const
866✔
301
    {
302
        return text_attrs{
303
            this->ta_attrs | lnav::enums::to_underlying(other),
1,732✔
304
            this->ta_fg_color,
305
            this->ta_bg_color,
306
        };
866✔
307
    }
308

309
    text_attrs& operator|=(const style other)
898,713✔
310
    {
311
        this->ta_attrs |= lnav::enums::to_underlying(other);
898,713✔
312
        return *this;
898,713✔
313
    }
314

315
    void clear_style(style other)
×
316
    {
317
        this->ta_attrs &= ~lnav::enums::to_underlying(other);
×
318
    }
319

320
    bool has_style(style other) const
30,621✔
321
    {
322
        return this->ta_attrs & lnav::enums::to_underlying(other);
30,621✔
323
    }
324

325
    bool operator==(const text_attrs& other) const
×
326
    {
327
        return this->ta_attrs == other.ta_attrs
×
328
            && this->ta_fg_color == other.ta_fg_color
×
329
            && this->ta_bg_color == other.ta_bg_color;
×
330
    }
331

332
    uint32_t ta_attrs{0};
333
    styling::color_unit ta_fg_color{styling::color_unit::EMPTY};
334
    styling::color_unit ta_bg_color{styling::color_unit::EMPTY};
335
    std::optional<text_align_t> ta_align;
336
};
337

338
struct block_elem_t {
339
    char32_t value;
340
    role_t role;
341

342
    bool operator==(const block_elem_t& rhs) const
343
    {
344
        return this->value == rhs.value && this->role == rhs.role;
345
    }
346
};
347

348
struct ui_command {
349
    source_location uc_location;
350
    std::string uc_command;
351

352
    bool operator==(const ui_command& rhs) const
353
    {
354
        return this->uc_location == rhs.uc_location
355
            && this->uc_command == rhs.uc_command;
356
    }
357
};
358

359
using string_attr_value = mapbox::util::variant<int64_t,
360
                                                role_t,
361
                                                text_attrs,
362
                                                intern_string_t,
363
                                                std::string,
364
                                                std::shared_ptr<logfile>,
365
                                                bookmark_metadata*,
366
                                                string_fragment,
367
                                                block_elem_t,
368
                                                styling::color_unit,
369
                                                ui_icon_t,
370
                                                const char*,
371
                                                ui_command,
372
                                                text_format_t>;
373

374
class string_attr_type_base {
375
public:
376
    explicit constexpr string_attr_type_base(const char* name) noexcept
377
        : sat_name(name)
378
    {
379
    }
380

381
    const char* const sat_name;
382
};
383

384
using string_attr_pair
385
    = std::pair<const string_attr_type_base*, string_attr_value>;
386

387
template<typename T>
388
class string_attr_type : public string_attr_type_base {
389
public:
390
    using value_type = T;
391

392
    explicit constexpr string_attr_type(const char* name) noexcept
393
        : string_attr_type_base(name)
394
    {
395
    }
396

397
    template<typename U = T>
398
    std::enable_if_t<std::is_void_v<U>, string_attr_pair> value() const
130,558✔
399
    {
400
        return std::make_pair(this, string_attr_value{mapbox::util::no_init{}});
130,558✔
401
    }
402

403
    template<std::size_t N>
404
    std::enable_if_t<(N > 0) && std::is_same_v<std::string, T>,
405
                     string_attr_pair>
406
    value(const char (&val)[N]) const
×
407
    {
408
        return std::make_pair(this, std::string(val));
×
409
    }
410

411
    template<typename U = T>
412
    constexpr std::enable_if_t<!std::is_void_v<U>
413
                                   && std::is_convertible_v<U, T>,
414
                               string_attr_pair>
415
    value(U&& val) const
1,783,769✔
416
    {
417
        if constexpr (std::is_same_v<const char*, U>
418
                      && std::is_same_v<std::string, T>)
419
        {
420
            return std::make_pair(this, std::string(val));
421
        }
422
        return std::make_pair(this, val);
1,783,769✔
423
    }
424
};
425

426
extern const string_attr_type<void> SA_ORIGINAL_LINE;
427
extern const string_attr_type<void> SA_BODY;
428
extern const string_attr_type<void> SA_SRC_FILE;
429
extern const string_attr_type<void> SA_SRC_LINE;
430
extern const string_attr_type<void> SA_SRC_LOC;
431
extern const string_attr_type<void> SA_THREAD_ID;
432
extern const string_attr_type<void> SA_DURATION;
433
extern const string_attr_type<void> SA_EXTRA_CONTENT;
434
extern const string_attr_type<ui_icon_t> SA_HIDDEN;
435
extern const string_attr_type<void> SA_REPLACED;
436
extern const string_attr_type<intern_string_t> SA_FORMAT;
437
extern const string_attr_type<void> SA_REMOVED;
438
extern const string_attr_type<void> SA_PREFORMATTED;
439
extern const string_attr_type<std::string> SA_INVALID;
440
extern const string_attr_type<std::string> SA_ERROR;
441
extern const string_attr_type<int64_t> SA_LEVEL;
442
extern const string_attr_type<int64_t> SA_ORIGIN_OFFSET;
443
extern const string_attr_type<text_format_t> SA_QUOTED_TEXT;
444

445
extern const string_attr_type<std::string> VC_ANCHOR;
446
extern const string_attr_type<role_t> VC_ROLE;
447
extern const string_attr_type<role_t> VC_ROLE_FG;
448
extern const string_attr_type<text_attrs> VC_STYLE;
449
extern const string_attr_type<const char*> VC_GRAPHIC;
450
extern const string_attr_type<block_elem_t> VC_BLOCK_ELEM;
451
extern const string_attr_type<styling::color_unit> VC_FOREGROUND;
452
extern const string_attr_type<styling::color_unit> VC_BACKGROUND;
453
extern const string_attr_type<std::string> VC_HYPERLINK;
454
extern const string_attr_type<ui_icon_t> VC_ICON;
455
extern const string_attr_type<ui_command> VC_COMMAND;
456

457
namespace lnav {
458

459
namespace string::attrs {
460

461
template<typename S>
462
std::pair<S, string_attr_pair>
463
preformatted(S str)
464
{
465
    return std::make_pair(std::move(str), SA_PREFORMATTED.value());
466
}
467

468
template<typename S>
469
std::pair<S, string_attr_pair>
470
href(S str, std::string href)
18✔
471
{
472
    return std::make_pair(std::move(str), VC_HYPERLINK.value(std::move(href)));
18✔
473
}
474

475
}  // namespace string::attrs
476

477
namespace roles {
478

479
template<typename S>
480
std::pair<S, string_attr_pair>
481
for_flag(S str, bool flag)
18✔
482
{
483
    return std::make_pair(
484
        std::move(str),
18✔
485
        VC_ROLE.value(flag ? role_t::VCR_OK : role_t::VCR_ERROR));
36✔
486
}
487

488
template<typename S>
489
std::pair<S, string_attr_pair>
490
error(S str)
527✔
491
{
492
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_ERROR));
527✔
493
}
494

495
template<typename S>
496
std::pair<S, string_attr_pair>
497
warning(S str)
492✔
498
{
499
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_WARNING));
492✔
500
}
501

502
template<typename S>
503
std::pair<S, string_attr_pair>
504
status(S str)
505
{
506
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STATUS));
507
}
508

509
template<typename S>
510
std::pair<S, string_attr_pair>
511
inactive_status(S str)
512
{
513
    return std::make_pair(std::move(str),
514
                          VC_ROLE.value(role_t::VCR_INACTIVE_STATUS));
515
}
516

517
template<typename S>
518
std::pair<S, string_attr_pair>
519
status_title(S str)
16✔
520
{
521
    return std::make_pair(std::move(str),
16✔
522
                          VC_ROLE.value(role_t::VCR_STATUS_TITLE));
32✔
523
}
524

525
template<typename S>
526
std::pair<S, string_attr_pair>
527
status_subtitle(S str)
528
{
529
    return std::make_pair(std::move(str),
530
                          VC_ROLE.value(role_t::VCR_STATUS_SUBTITLE));
531
}
532

533
template<typename S>
534
std::pair<S, string_attr_pair>
535
ok(S str)
496✔
536
{
537
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_OK));
496✔
538
}
539

540
template<typename S>
541
std::pair<S, string_attr_pair>
542
time_ago(S str)
354✔
543
{
544
    return std::make_pair(std::move(str),
354✔
545
                          VC_ROLE.value(role_t::VCR_TIME_AGO));
708✔
546
}
547

548
template<typename S>
549
std::pair<S, string_attr_pair>
550
hidden(S str)
28✔
551
{
552
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HIDDEN));
28✔
553
}
554

555
template<typename S>
556
std::pair<S, string_attr_pair>
557
file(S str)
390✔
558
{
559
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_FILE));
390✔
560
}
561

562
template<typename S>
563
std::pair<S, string_attr_pair>
564
symbol(S str)
16,197✔
565
{
566
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_SYMBOL));
16,197✔
567
}
568

569
template<typename S>
570
std::pair<S, string_attr_pair>
571
keyword(S str)
150✔
572
{
573
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_KEYWORD));
150✔
574
}
575

576
template<typename S>
577
std::pair<S, string_attr_pair>
578
variable(S str)
2,691✔
579
{
580
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_VARIABLE));
2,691✔
581
}
582

583
template<typename S>
584
std::pair<S, string_attr_pair>
585
number(S str)
5,008✔
586
{
587
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_NUMBER));
5,008✔
588
}
589

590
template<typename S>
591
std::pair<S, string_attr_pair>
592
comment(S str)
6✔
593
{
594
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_COMMENT));
6✔
595
}
596

597
template<typename S>
598
std::pair<S, string_attr_pair>
599
identifier(S str)
3,199✔
600
{
601
    return std::make_pair(std::move(str),
3,199✔
602
                          VC_ROLE.value(role_t::VCR_IDENTIFIER));
6,398✔
603
}
604

605
template<typename S>
606
std::pair<S, string_attr_pair>
607
string(S str)
1✔
608
{
609
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STRING));
1✔
610
}
611

612
template<typename S>
613
std::pair<S, string_attr_pair>
614
hr(S str)
×
615
{
616
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HR));
×
617
}
618

619
template<typename S>
620
std::pair<S, string_attr_pair>
621
hyperlink(S str)
332✔
622
{
623
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HYPERLINK));
332✔
624
}
625

626
template<typename S>
627
std::pair<S, string_attr_pair>
628
list_glyph(S str)
388✔
629
{
630
    return std::make_pair(std::move(str),
388✔
631
                          VC_ROLE.value(role_t::VCR_LIST_GLYPH));
776✔
632
}
633

634
template<typename S>
635
std::pair<S, string_attr_pair>
636
breadcrumb(S str)
637
{
638
    return std::make_pair(std::move(str),
639
                          VC_ROLE.value(role_t::VCR_BREADCRUMB));
640
}
641

642
template<typename S>
643
std::pair<S, string_attr_pair>
644
quoted_code(S str)
3,084✔
645
{
646
    return std::make_pair(std::move(str),
3,084✔
647
                          VC_ROLE.value(role_t::VCR_QUOTED_CODE));
6,168✔
648
}
649

650
template<typename S>
651
std::pair<S, string_attr_pair>
652
code_border(S str)
653
{
654
    return std::make_pair(std::move(str),
655
                          VC_ROLE.value(role_t::VCR_CODE_BORDER));
656
}
657

658
template<typename S>
659
std::pair<S, string_attr_pair>
660
snippet_border(S str)
1✔
661
{
662
    return std::make_pair(std::move(str),
1✔
663
                          VC_ROLE.value(role_t::VCR_SNIPPET_BORDER));
2✔
664
}
665

666
template<typename S>
667
std::pair<S, string_attr_pair>
668
table_border(S str)
937✔
669
{
670
    return std::make_pair(std::move(str),
937✔
671
                          VC_ROLE.value(role_t::VCR_TABLE_BORDER));
1,874✔
672
}
673

674
template<typename S>
675
std::pair<S, string_attr_pair>
676
table_header(S str)
×
677
{
678
    return std::make_pair(std::move(str),
×
679
                          VC_ROLE.value(role_t::VCR_TABLE_HEADER));
×
680
}
681

682
template<typename S>
683
std::pair<S, string_attr_pair>
684
quote_border(S str)
685
{
686
    return std::make_pair(std::move(str),
687
                          VC_ROLE.value(role_t::VCR_QUOTE_BORDER));
688
}
689

690
template<typename S>
691
std::pair<S, string_attr_pair>
692
quoted_text(S str)
693
{
694
    return std::make_pair(std::move(str),
695
                          VC_ROLE.value(role_t::VCR_QUOTED_TEXT));
696
}
697

698
template<typename S>
699
std::pair<S, string_attr_pair>
700
footnote_border(S str)
701
{
702
    return std::make_pair(std::move(str),
703
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_BORDER));
704
}
705

706
template<typename S>
707
std::pair<S, string_attr_pair>
708
footnote_text(S str)
646✔
709
{
710
    return std::make_pair(std::move(str),
646✔
711
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_TEXT));
1,292✔
712
}
713

714
template<typename S>
715
std::pair<S, string_attr_pair>
716
h1(S str)
717
{
718
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H1));
719
}
720

721
template<typename S>
722
std::pair<S, string_attr_pair>
723
h2(S str)
63✔
724
{
725
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H2));
63✔
726
}
727

728
template<typename S>
729
std::pair<S, string_attr_pair>
730
h3(S str)
×
731
{
732
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H3));
×
733
}
734

735
template<typename S>
736
std::pair<S, string_attr_pair>
737
h4(S str)
738
{
739
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H4));
740
}
741

742
template<typename S>
743
std::pair<S, string_attr_pair>
744
h5(S str)
×
745
{
746
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H5));
×
747
}
748

749
template<typename S>
750
std::pair<S, string_attr_pair>
751
h6(S str)
752
{
753
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H6));
754
}
755

756
template<typename S>
757
std::pair<S, string_attr_pair>
758
suggestion(S str)
759
{
760
    return std::make_pair(std::move(str),
761
                          VC_ROLE.value(role_t::VCR_SUGGESTION));
762
}
763

764
namespace literals {
765

766
constexpr std::pair<string_fragment, role_t> operator"" _ok(const char* str,
52✔
767
                                                            std::size_t len)
768
{
769
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_OK);
52✔
770
}
771

772
constexpr std::pair<string_fragment, role_t> operator"" _error(const char* str,
1,046✔
773
                                                               std::size_t len)
774
{
775
    return std::make_pair(string_fragment{str, 0, (int) len},
1,046✔
776
                          role_t::VCR_ERROR);
2,092✔
777
}
778

779
constexpr std::pair<string_fragment, role_t> operator"" _warning(
56✔
780
    const char* str, std::size_t len)
781
{
782
    return std::make_pair(string_fragment{str, 0, (int) len},
56✔
783
                          role_t::VCR_WARNING);
112✔
784
}
785

786
constexpr std::pair<string_fragment, role_t> operator"" _info(const char* str,
50,422✔
787
                                                              std::size_t len)
788
{
789
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_INFO);
50,422✔
790
}
791

792
constexpr std::pair<string_fragment, role_t> operator"" _status_title(
793
    const char* str, std::size_t len)
794
{
795
    return std::make_pair(string_fragment{str, 0, (int) len},
796
                          role_t::VCR_STATUS_TITLE);
797
}
798

799
constexpr std::pair<string_fragment, role_t> operator"" _status_subtitle(
×
800
    const char* str, std::size_t len)
801
{
802
    return std::make_pair(string_fragment{str, 0, (int) len},
×
803
                          role_t::VCR_STATUS_SUBTITLE);
×
804
}
805

806
constexpr std::pair<string_fragment, role_t> operator"" _symbol(const char* str,
47✔
807
                                                                std::size_t len)
808
{
809
    return std::make_pair(string_fragment{str, 0, (int) len},
47✔
810
                          role_t::VCR_SYMBOL);
94✔
811
}
812

813
constexpr std::pair<string_fragment, role_t> operator"" _keyword(
5✔
814
    const char* str, std::size_t len)
815
{
816
    return std::make_pair(string_fragment{str, 0, (int) len},
5✔
817
                          role_t::VCR_KEYWORD);
10✔
818
}
819

820
constexpr std::pair<string_fragment, role_t> operator"" _variable(
235✔
821
    const char* str, std::size_t len)
822
{
823
    return std::make_pair(string_fragment{str, 0, (int) len},
235✔
824
                          role_t::VCR_VARIABLE);
470✔
825
}
826

827
constexpr std::pair<string_fragment, role_t> operator"" _comment(
67✔
828
    const char* str, std::size_t len)
829
{
830
    return std::make_pair(string_fragment{str, 0, (int) len},
67✔
831
                          role_t::VCR_COMMENT);
134✔
832
}
833

834
constexpr std::pair<string_fragment, role_t> operator"" _hotkey(const char* str,
807✔
835
                                                                std::size_t len)
836
{
837
    return std::make_pair(string_fragment{str, 0, (int) len},
807✔
838
                          role_t::VCR_STATUS_HOTKEY);
1,614✔
839
}
840

841
constexpr std::pair<string_fragment, role_t> operator"" _h1(const char* str,
125✔
842
                                                            std::size_t len)
843
{
844
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H1);
125✔
845
}
846

847
constexpr std::pair<string_fragment, role_t> operator"" _h2(const char* str,
159✔
848
                                                            std::size_t len)
849
{
850
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H2);
159✔
851
}
852

853
constexpr std::pair<string_fragment, role_t> operator"" _h3(const char* str,
84✔
854
                                                            std::size_t len)
855
{
856
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H3);
84✔
857
}
858

859
constexpr std::pair<string_fragment, role_t> operator"" _h4(const char* str,
1,911✔
860
                                                            std::size_t len)
861
{
862
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H4);
1,911✔
863
}
864

865
constexpr std::pair<string_fragment, role_t> operator"" _h5(const char* str,
36✔
866
                                                            std::size_t len)
867
{
868
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H5);
36✔
869
}
870

871
constexpr std::pair<string_fragment, role_t> operator"" _hr(const char* str,
872
                                                            std::size_t len)
873
{
874
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_HR);
875
}
876

877
constexpr std::pair<string_fragment, role_t> operator"" _hyperlink(
1✔
878
    const char* str, std::size_t len)
879
{
880
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
881
                          role_t::VCR_HYPERLINK);
2✔
882
}
883

884
constexpr std::pair<string_fragment, role_t> operator"" _list_glyph(
813✔
885
    const char* str, std::size_t len)
886
{
887
    return std::make_pair(string_fragment{str, 0, (int) len},
813✔
888
                          role_t::VCR_LIST_GLYPH);
1,626✔
889
}
890

891
constexpr std::pair<string_fragment, role_t> operator"" _breadcrumb(
51✔
892
    const char* str, std::size_t len)
893
{
894
    return std::make_pair(string_fragment{str, 0, (int) len},
51✔
895
                          role_t::VCR_BREADCRUMB);
102✔
896
}
897

898
constexpr std::pair<string_fragment, role_t> operator"" _quoted_code(
1✔
899
    const char* str, std::size_t len)
900
{
901
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
902
                          role_t::VCR_QUOTED_CODE);
2✔
903
}
904

905
constexpr std::pair<string_fragment, role_t> operator"" _code_border(
340✔
906
    const char* str, std::size_t len)
907
{
908
    return std::make_pair(string_fragment{str, 0, (int) len},
340✔
909
                          role_t::VCR_CODE_BORDER);
680✔
910
}
911

912
constexpr std::pair<string_fragment, role_t> operator"" _table_header(
134✔
913
    const char* str, std::size_t len)
914
{
915
    return std::make_pair(string_fragment{str, 0, (int) len},
134✔
916
                          role_t::VCR_TABLE_HEADER);
268✔
917
}
918

919
constexpr std::pair<string_fragment, role_t> operator"" _table_border(
920
    const char* str, std::size_t len)
921
{
922
    return std::make_pair(string_fragment{str, 0, (int) len},
923
                          role_t::VCR_TABLE_BORDER);
924
}
925

926
constexpr std::pair<string_fragment, role_t> operator"" _quote_border(
100✔
927
    const char* str, std::size_t len)
928
{
929
    return std::make_pair(string_fragment{str, 0, (int) len},
100✔
930
                          role_t::VCR_QUOTE_BORDER);
200✔
931
}
932

933
constexpr std::pair<string_fragment, role_t> operator"" _quoted_text(
934
    const char* str, std::size_t len)
935
{
936
    return std::make_pair(string_fragment{str, 0, (int) len},
937
                          role_t::VCR_QUOTED_TEXT);
938
}
939

940
constexpr std::pair<string_fragment, role_t> operator"" _footnote_border(
328✔
941
    const char* str, std::size_t len)
942
{
943
    return std::make_pair(string_fragment{str, 0, (int) len},
328✔
944
                          role_t::VCR_FOOTNOTE_BORDER);
656✔
945
}
946

947
constexpr std::pair<string_fragment, role_t> operator"" _footnote_text(
948
    const char* str, std::size_t len)
949
{
950
    return std::make_pair(string_fragment{str, 0, (int) len},
951
                          role_t::VCR_FOOTNOTE_BORDER);
952
}
953

954
constexpr std::pair<string_fragment, role_t> operator"" _snippet_border(
2,186✔
955
    const char* str, std::size_t len)
956
{
957
    return std::make_pair(string_fragment{str, 0, (int) len},
2,186✔
958
                          role_t::VCR_SNIPPET_BORDER);
4,372✔
959
}
960

961
inline std::pair<std::string, string_attr_pair> operator"" _link(
962
    const char* str, std::size_t len)
963
{
964
    return std::make_pair(std::string(str, len),
965
                          VC_HYPERLINK.value(std::string(str, len)));
966
}
967

968
}  // namespace literals
969

970
}  // namespace roles
971
}  // namespace lnav
972

973
#endif
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc