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

tstack / lnav / 23346808785-2859

20 Mar 2026 02:14PM UTC coverage: 69.012% (-0.009%) from 69.021%
23346808785-2859

push

github

tstack
[tests] update expected

52736 of 76416 relevant lines covered (69.01%)

522102.57 hits per line

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

89.53
/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
    play,
69
    edit,
70
    file,
71
    thread,
72
    tag,
73
    partition,
74
    busy,
75
};
76

77
constexpr auto ui_icon_count
78
    = lnav::enums::to_underlying(ui_icon_t::busy) + 1;
79

80
/** Roles that can be mapped to curses attributes using attrs_for_role() */
81
enum class role_t : int32_t {
82
    VCR_NONE = -1,
83

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

131
    VCR_QUOTED_CODE,
132
    VCR_CODE_BORDER,
133
    VCR_KEYWORD,
134
    VCR_STRING,
135
    VCR_COMMENT,
136
    VCR_DOC_DIRECTIVE,
137
    VCR_VARIABLE,
138
    VCR_SYMBOL,
139
    VCR_NULL,
140
    VCR_ASCII_CTRL,
141
    VCR_NON_ASCII,
142
    VCR_NUMBER,
143
    VCR_RE_SPECIAL,
144
    VCR_RE_REPEAT,
145
    VCR_FILE,
146

147
    VCR_DIFF_DELETE, /*< Deleted line in a diff. */
148
    VCR_DIFF_ADD, /*< Added line in a diff. */
149
    VCR_DIFF_SECTION, /*< Section marker in a diff. */
150

151
    VCR_LOW_THRESHOLD,
152
    VCR_MED_THRESHOLD,
153
    VCR_HIGH_THRESHOLD,
154

155
    VCR_H1,
156
    VCR_H2,
157
    VCR_H3,
158
    VCR_H4,
159
    VCR_H5,
160
    VCR_H6,
161

162
    VCR_HR,
163
    VCR_HYPERLINK,
164
    VCR_LIST_GLYPH,
165
    VCR_BREADCRUMB,
166
    VCR_TABLE_BORDER,
167
    VCR_TABLE_HEADER,
168
    VCR_QUOTE_BORDER,
169
    VCR_QUOTED_TEXT,
170
    VCR_FOOTNOTE_BORDER,
171
    VCR_FOOTNOTE_TEXT,
172
    VCR_SNIPPET_BORDER,
173
    VCR_INDENT_GUIDE,
174
    VCR_INLINE_CODE,
175
    VCR_FUNCTION,
176
    VCR_TYPE,
177
    VCR_SEP_REF_ACC,
178
    VCR_SUGGESTION,
179
    VCR_SELECTED_TEXT,
180
    VCR_FUZZY_MATCH,
181

182
    VCR_OBJECT_KEY,
183

184
    VCR_SPECTRO_THRESHOLD0,
185
    VCR_SPECTRO_THRESHOLD1,
186
    VCR_SPECTRO_THRESHOLD2,
187
    VCR_SPECTRO_THRESHOLD3,
188
    VCR_SPECTRO_THRESHOLD4,
189
    VCR_SPECTRO_THRESHOLD5,
190
    VCR_SPECTRO_THRESHOLD6,
191

192
    VCR__MAX
193
};
194

195
struct text_attrs {
196
    enum class style : uint32_t {
197
        none = 0x0000,
198
        struck = 0x0001u,
199
        bold = 0x0002u,
200
        undercurl = 0x0004u,
201
        underline = 0x0008u,
202
        italic = 0x0010u,
203
        altcharset = 0x0020u,
204
        blink = 0x0040u,
205
        reverse = 0x1000u,
206
    };
207

208
    static text_attrs with_struck()
656✔
209
    {
210
        return text_attrs{
211
            lnav::enums::to_underlying(style::struck),
212
        };
656✔
213
    }
214

215
    static text_attrs with_bold()
879✔
216
    {
217
        return text_attrs{
218
            lnav::enums::to_underlying(style::bold),
219
        };
879✔
220
    }
221

222
    static text_attrs with_undercurl()
223
    {
224
        return text_attrs{
225
            lnav::enums::to_underlying(style::undercurl),
226
        };
227
    }
228

229
    static text_attrs with_underline()
50,698✔
230
    {
231
        return text_attrs{
232
            lnav::enums::to_underlying(style::underline),
233
        };
50,698✔
234
    }
235

236
    static text_attrs with_italic()
656✔
237
    {
238
        return text_attrs{
239
            lnav::enums::to_underlying(style::italic),
240
        };
656✔
241
    }
242

243
    static text_attrs with_reverse()
51,024✔
244
    {
245
        return text_attrs{
246
            lnav::enums::to_underlying(style::reverse),
247
        };
51,024✔
248
    }
249

250
    static text_attrs with_altcharset()
131✔
251
    {
252
        return text_attrs{
253
            lnav::enums::to_underlying(style::altcharset),
254
        };
131✔
255
    }
256

257
    static text_attrs with_blink()
258
    {
259
        return text_attrs{
260
            lnav::enums::to_underlying(style::blink),
261
        };
262
    }
263

264
    template<typename... Args>
265
    static text_attrs with_styles(Args... args)
252✔
266
    {
267
        auto retval = text_attrs{};
252✔
268

269
        for (auto arg : {args...}) {
756✔
270
            retval.ta_attrs |= lnav::enums::to_underlying(arg);
504✔
271
        }
272
        return retval;
252✔
273
    }
274

275
    bool empty() const
55,100✔
276
    {
277
        return this->ta_attrs == 0 && this->ta_fg_color.empty()
43,963✔
278
            && this->ta_bg_color.empty();
99,063✔
279
    }
280

281
    text_attrs operator|(const text_attrs& other) const
62,625✔
282
    {
283
        return text_attrs{
284
            this->ta_attrs | other.ta_attrs,
62,625✔
285
            !this->ta_fg_color.empty() ? this->ta_fg_color : other.ta_fg_color,
62,625✔
286
            !this->ta_bg_color.empty() ? this->ta_bg_color : other.ta_bg_color,
62,625✔
287
        };
187,875✔
288
    }
289

290
    text_attrs operator|(const style other) const
858✔
291
    {
292
        return text_attrs{
293
            this->ta_attrs | lnav::enums::to_underlying(other),
1,716✔
294
            this->ta_fg_color,
295
            this->ta_bg_color,
296
        };
858✔
297
    }
298

299
    text_attrs& operator|=(const style other)
786,313✔
300
    {
301
        this->ta_attrs |= lnav::enums::to_underlying(other);
786,313✔
302
        return *this;
786,313✔
303
    }
304

305
    void clear_style(style other)
13✔
306
    {
307
        this->ta_attrs &= ~lnav::enums::to_underlying(other);
13✔
308
    }
13✔
309

310
    bool has_style(style other) const
31,615✔
311
    {
312
        return this->ta_attrs & lnav::enums::to_underlying(other);
31,615✔
313
    }
314

315
    bool operator==(const text_attrs& other) const
×
316
    {
317
        return this->ta_attrs == other.ta_attrs
×
318
            && this->ta_fg_color == other.ta_fg_color
×
319
            && this->ta_bg_color == other.ta_bg_color;
×
320
    }
321

322
    uint32_t ta_attrs{0};
323
    styling::color_unit ta_fg_color{styling::color_unit::EMPTY};
324
    styling::color_unit ta_bg_color{styling::color_unit::EMPTY};
325
    std::optional<text_align_t> ta_align;
326
};
327

328
struct block_elem_t {
329
    char32_t value;
330
    role_t role;
331

332
    bool operator==(const block_elem_t& rhs) const
333
    {
334
        return this->value == rhs.value && this->role == rhs.role;
335
    }
336
};
337

338
struct ui_command {
339
    source_location uc_location;
340
    std::string uc_command;
341

342
    bool operator==(const ui_command& rhs) const
343
    {
344
        return this->uc_location == rhs.uc_location
345
            && this->uc_command == rhs.uc_command;
346
    }
347
};
348

349
using string_attr_value = mapbox::util::variant<int64_t,
350
                                                role_t,
351
                                                text_attrs,
352
                                                intern_string_t,
353
                                                std::string,
354
                                                std::shared_ptr<logfile>,
355
                                                bookmark_metadata*,
356
                                                string_fragment,
357
                                                block_elem_t,
358
                                                styling::color_unit,
359
                                                ui_icon_t,
360
                                                const char*,
361
                                                ui_command,
362
                                                text_format_t>;
363

364
class string_attr_type_base {
365
public:
366
    explicit constexpr string_attr_type_base(const char* name) noexcept
367
        : sat_name(name)
368
    {
369
    }
370

371
    const char* const sat_name;
372
};
373

374
using string_attr_pair
375
    = std::pair<const string_attr_type_base*, string_attr_value>;
376

377
template<typename T>
378
class string_attr_type : public string_attr_type_base {
379
public:
380
    using value_type = T;
381

382
    explicit constexpr string_attr_type(const char* name) noexcept
383
        : string_attr_type_base(name)
384
    {
385
    }
386

387
    template<typename U = T>
388
    std::enable_if_t<std::is_void_v<U>, string_attr_pair> value() const
124,651✔
389
    {
390
        return std::make_pair(this, string_attr_value{mapbox::util::no_init{}});
124,651✔
391
    }
392

393
    template<std::size_t N>
394
    std::enable_if_t<(N > 0) && std::is_same_v<std::string, T>,
395
                     string_attr_pair>
396
    value(const char (&val)[N]) const
×
397
    {
398
        return std::make_pair(this, std::string(val));
×
399
    }
400

401
    template<typename U = T>
402
    constexpr std::enable_if_t<!std::is_void_v<U>
403
                                   && std::is_convertible_v<U, T>,
404
                               string_attr_pair>
405
    value(U&& val) const
1,614,178✔
406
    {
407
        if constexpr (std::is_same_v<const char*, U>
408
                      && std::is_same_v<std::string, T>)
409
        {
410
            return std::make_pair(this, std::string(val));
411
        }
412
        return std::make_pair(this, val);
1,614,178✔
413
    }
414
};
415

416
extern const string_attr_type<void> SA_ORIGINAL_LINE;
417
extern const string_attr_type<void> SA_BODY;
418
extern const string_attr_type<void> SA_SRC_FILE;
419
extern const string_attr_type<void> SA_SRC_LINE;
420
extern const string_attr_type<void> SA_SRC_LOC;
421
extern const string_attr_type<void> SA_THREAD_ID;
422
extern const string_attr_type<void> SA_DURATION;
423
extern const string_attr_type<void> SA_EXTRA_CONTENT;
424
extern const string_attr_type<ui_icon_t> SA_HIDDEN;
425
extern const string_attr_type<void> SA_REPLACED;
426
extern const string_attr_type<intern_string_t> SA_FORMAT;
427
extern const string_attr_type<void> SA_REMOVED;
428
extern const string_attr_type<void> SA_PREFORMATTED;
429
extern const string_attr_type<std::string> SA_INVALID;
430
extern const string_attr_type<std::string> SA_ERROR;
431
extern const string_attr_type<int64_t> SA_LEVEL;
432
extern const string_attr_type<int64_t> SA_ORIGIN_OFFSET;
433
extern const string_attr_type<text_format_t> SA_QUOTED_TEXT;
434

435
extern const string_attr_type<std::string> VC_ANCHOR;
436
extern const string_attr_type<role_t> VC_ROLE;
437
extern const string_attr_type<role_t> VC_ROLE_FG;
438
extern const string_attr_type<text_attrs> VC_STYLE;
439
extern const string_attr_type<const char*> VC_GRAPHIC;
440
extern const string_attr_type<block_elem_t> VC_BLOCK_ELEM;
441
extern const string_attr_type<styling::color_unit> VC_FOREGROUND;
442
extern const string_attr_type<styling::color_unit> VC_BACKGROUND;
443
extern const string_attr_type<std::string> VC_HYPERLINK;
444
extern const string_attr_type<ui_icon_t> VC_ICON;
445
extern const string_attr_type<ui_command> VC_COMMAND;
446

447
namespace lnav {
448

449
namespace string::attrs {
450

451
template<typename S>
452
std::pair<S, string_attr_pair>
453
preformatted(S str)
454
{
455
    return std::make_pair(std::move(str), SA_PREFORMATTED.value());
456
}
457

458
template<typename S>
459
std::pair<S, string_attr_pair>
460
href(S str, std::string href)
18✔
461
{
462
    return std::make_pair(std::move(str), VC_HYPERLINK.value(std::move(href)));
18✔
463
}
464

465
}  // namespace string::attrs
466

467
namespace roles {
468

469
template<typename S>
470
std::pair<S, string_attr_pair>
471
for_flag(S str, bool flag)
16✔
472
{
473
    return std::make_pair(
474
        std::move(str),
16✔
475
        VC_ROLE.value(flag ? role_t::VCR_OK : role_t::VCR_ERROR));
32✔
476
}
477

478
template<typename S>
479
std::pair<S, string_attr_pair>
480
error(S str)
457✔
481
{
482
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_ERROR));
457✔
483
}
484

485
template<typename S>
486
std::pair<S, string_attr_pair>
487
warning(S str)
437✔
488
{
489
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_WARNING));
437✔
490
}
491

492
template<typename S>
493
std::pair<S, string_attr_pair>
494
status(S str)
495
{
496
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STATUS));
497
}
498

499
template<typename S>
500
std::pair<S, string_attr_pair>
501
inactive_status(S str)
502
{
503
    return std::make_pair(std::move(str),
504
                          VC_ROLE.value(role_t::VCR_INACTIVE_STATUS));
505
}
506

507
template<typename S>
508
std::pair<S, string_attr_pair>
509
status_title(S str)
17✔
510
{
511
    return std::make_pair(std::move(str),
17✔
512
                          VC_ROLE.value(role_t::VCR_STATUS_TITLE));
34✔
513
}
514

515
template<typename S>
516
std::pair<S, string_attr_pair>
517
status_subtitle(S str)
518
{
519
    return std::make_pair(std::move(str),
520
                          VC_ROLE.value(role_t::VCR_STATUS_SUBTITLE));
521
}
522

523
template<typename S>
524
std::pair<S, string_attr_pair>
525
ok(S str)
3✔
526
{
527
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_OK));
3✔
528
}
529

530
template<typename S>
531
std::pair<S, string_attr_pair>
532
hidden(S str)
28✔
533
{
534
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HIDDEN));
28✔
535
}
536

537
template<typename S>
538
std::pair<S, string_attr_pair>
539
file(S str)
375✔
540
{
541
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_FILE));
375✔
542
}
543

544
template<typename S>
545
std::pair<S, string_attr_pair>
546
symbol(S str)
16,184✔
547
{
548
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_SYMBOL));
16,184✔
549
}
550

551
template<typename S>
552
std::pair<S, string_attr_pair>
553
keyword(S str)
150✔
554
{
555
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_KEYWORD));
150✔
556
}
557

558
template<typename S>
559
std::pair<S, string_attr_pair>
560
variable(S str)
2,670✔
561
{
562
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_VARIABLE));
2,670✔
563
}
564

565
template<typename S>
566
std::pair<S, string_attr_pair>
567
number(S str)
4,409✔
568
{
569
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_NUMBER));
4,409✔
570
}
571

572
template<typename S>
573
std::pair<S, string_attr_pair>
574
comment(S str)
4✔
575
{
576
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_COMMENT));
4✔
577
}
578

579
template<typename S>
580
std::pair<S, string_attr_pair>
581
identifier(S str)
3,000✔
582
{
583
    return std::make_pair(std::move(str),
3,000✔
584
                          VC_ROLE.value(role_t::VCR_IDENTIFIER));
6,000✔
585
}
586

587
template<typename S>
588
std::pair<S, string_attr_pair>
589
string(S str)
1✔
590
{
591
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STRING));
1✔
592
}
593

594
template<typename S>
595
std::pair<S, string_attr_pair>
596
hr(S str)
×
597
{
598
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HR));
×
599
}
600

601
template<typename S>
602
std::pair<S, string_attr_pair>
603
hyperlink(S str)
332✔
604
{
605
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HYPERLINK));
332✔
606
}
607

608
template<typename S>
609
std::pair<S, string_attr_pair>
610
list_glyph(S str)
386✔
611
{
612
    return std::make_pair(std::move(str),
386✔
613
                          VC_ROLE.value(role_t::VCR_LIST_GLYPH));
772✔
614
}
615

616
template<typename S>
617
std::pair<S, string_attr_pair>
618
breadcrumb(S str)
619
{
620
    return std::make_pair(std::move(str),
621
                          VC_ROLE.value(role_t::VCR_BREADCRUMB));
622
}
623

624
template<typename S>
625
std::pair<S, string_attr_pair>
626
quoted_code(S str)
2,933✔
627
{
628
    return std::make_pair(std::move(str),
2,933✔
629
                          VC_ROLE.value(role_t::VCR_QUOTED_CODE));
5,866✔
630
}
631

632
template<typename S>
633
std::pair<S, string_attr_pair>
634
code_border(S str)
635
{
636
    return std::make_pair(std::move(str),
637
                          VC_ROLE.value(role_t::VCR_CODE_BORDER));
638
}
639

640
template<typename S>
641
std::pair<S, string_attr_pair>
642
snippet_border(S str)
1✔
643
{
644
    return std::make_pair(std::move(str),
1✔
645
                          VC_ROLE.value(role_t::VCR_SNIPPET_BORDER));
2✔
646
}
647

648
template<typename S>
649
std::pair<S, string_attr_pair>
650
table_border(S str)
924✔
651
{
652
    return std::make_pair(std::move(str),
924✔
653
                          VC_ROLE.value(role_t::VCR_TABLE_BORDER));
1,848✔
654
}
655

656
template<typename S>
657
std::pair<S, string_attr_pair>
658
table_header(S str)
×
659
{
660
    return std::make_pair(std::move(str),
×
661
                          VC_ROLE.value(role_t::VCR_TABLE_HEADER));
×
662
}
663

664
template<typename S>
665
std::pair<S, string_attr_pair>
666
quote_border(S str)
667
{
668
    return std::make_pair(std::move(str),
669
                          VC_ROLE.value(role_t::VCR_QUOTE_BORDER));
670
}
671

672
template<typename S>
673
std::pair<S, string_attr_pair>
674
quoted_text(S str)
675
{
676
    return std::make_pair(std::move(str),
677
                          VC_ROLE.value(role_t::VCR_QUOTED_TEXT));
678
}
679

680
template<typename S>
681
std::pair<S, string_attr_pair>
682
footnote_border(S str)
683
{
684
    return std::make_pair(std::move(str),
685
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_BORDER));
686
}
687

688
template<typename S>
689
std::pair<S, string_attr_pair>
690
footnote_text(S str)
646✔
691
{
692
    return std::make_pair(std::move(str),
646✔
693
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_TEXT));
1,292✔
694
}
695

696
template<typename S>
697
std::pair<S, string_attr_pair>
698
h1(S str)
699
{
700
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H1));
701
}
702

703
template<typename S>
704
std::pair<S, string_attr_pair>
705
h2(S str)
63✔
706
{
707
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H2));
63✔
708
}
709

710
template<typename S>
711
std::pair<S, string_attr_pair>
712
h3(S str)
×
713
{
714
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H3));
×
715
}
716

717
template<typename S>
718
std::pair<S, string_attr_pair>
719
h4(S str)
720
{
721
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H4));
722
}
723

724
template<typename S>
725
std::pair<S, string_attr_pair>
726
h5(S str)
×
727
{
728
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H5));
×
729
}
730

731
template<typename S>
732
std::pair<S, string_attr_pair>
733
h6(S str)
734
{
735
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H6));
736
}
737

738
template<typename S>
739
std::pair<S, string_attr_pair>
740
suggestion(S str)
741
{
742
    return std::make_pair(std::move(str),
743
                          VC_ROLE.value(role_t::VCR_SUGGESTION));
744
}
745

746
namespace literals {
747

748
constexpr std::pair<string_fragment, role_t> operator"" _ok(const char* str,
52✔
749
                                                            std::size_t len)
750
{
751
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_OK);
52✔
752
}
753

754
constexpr std::pair<string_fragment, role_t> operator"" _error(const char* str,
963✔
755
                                                               std::size_t len)
756
{
757
    return std::make_pair(string_fragment{str, 0, (int) len},
963✔
758
                          role_t::VCR_ERROR);
1,926✔
759
}
760

761
constexpr std::pair<string_fragment, role_t> operator"" _warning(
38✔
762
    const char* str, std::size_t len)
763
{
764
    return std::make_pair(string_fragment{str, 0, (int) len},
38✔
765
                          role_t::VCR_WARNING);
76✔
766
}
767

768
constexpr std::pair<string_fragment, role_t> operator"" _info(const char* str,
46,517✔
769
                                                              std::size_t len)
770
{
771
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_INFO);
46,517✔
772
}
773

774
constexpr std::pair<string_fragment, role_t> operator"" _status_title(
775
    const char* str, std::size_t len)
776
{
777
    return std::make_pair(string_fragment{str, 0, (int) len},
778
                          role_t::VCR_STATUS_TITLE);
779
}
780

781
constexpr std::pair<string_fragment, role_t> operator"" _status_subtitle(
×
782
    const char* str, std::size_t len)
783
{
784
    return std::make_pair(string_fragment{str, 0, (int) len},
×
785
                          role_t::VCR_STATUS_SUBTITLE);
×
786
}
787

788
constexpr std::pair<string_fragment, role_t> operator"" _symbol(const char* str,
47✔
789
                                                                std::size_t len)
790
{
791
    return std::make_pair(string_fragment{str, 0, (int) len},
47✔
792
                          role_t::VCR_SYMBOL);
94✔
793
}
794

795
constexpr std::pair<string_fragment, role_t> operator"" _keyword(
5✔
796
    const char* str, std::size_t len)
797
{
798
    return std::make_pair(string_fragment{str, 0, (int) len},
5✔
799
                          role_t::VCR_KEYWORD);
10✔
800
}
801

802
constexpr std::pair<string_fragment, role_t> operator"" _variable(
235✔
803
    const char* str, std::size_t len)
804
{
805
    return std::make_pair(string_fragment{str, 0, (int) len},
235✔
806
                          role_t::VCR_VARIABLE);
470✔
807
}
808

809
constexpr std::pair<string_fragment, role_t> operator"" _comment(
66✔
810
    const char* str, std::size_t len)
811
{
812
    return std::make_pair(string_fragment{str, 0, (int) len},
66✔
813
                          role_t::VCR_COMMENT);
132✔
814
}
815

816
constexpr std::pair<string_fragment, role_t> operator"" _hotkey(const char* str,
715✔
817
                                                                std::size_t len)
818
{
819
    return std::make_pair(string_fragment{str, 0, (int) len},
715✔
820
                          role_t::VCR_STATUS_HOTKEY);
1,430✔
821
}
822

823
constexpr std::pair<string_fragment, role_t> operator"" _h1(const char* str,
85✔
824
                                                            std::size_t len)
825
{
826
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H1);
85✔
827
}
828

829
constexpr std::pair<string_fragment, role_t> operator"" _h2(const char* str,
145✔
830
                                                            std::size_t len)
831
{
832
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H2);
145✔
833
}
834

835
constexpr std::pair<string_fragment, role_t> operator"" _h3(const char* str,
77✔
836
                                                            std::size_t len)
837
{
838
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H3);
77✔
839
}
840

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

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

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

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

866
constexpr std::pair<string_fragment, role_t> operator"" _list_glyph(
720✔
867
    const char* str, std::size_t len)
868
{
869
    return std::make_pair(string_fragment{str, 0, (int) len},
720✔
870
                          role_t::VCR_LIST_GLYPH);
1,440✔
871
}
872

873
constexpr std::pair<string_fragment, role_t> operator"" _breadcrumb(
57✔
874
    const char* str, std::size_t len)
875
{
876
    return std::make_pair(string_fragment{str, 0, (int) len},
57✔
877
                          role_t::VCR_BREADCRUMB);
114✔
878
}
879

880
constexpr std::pair<string_fragment, role_t> operator"" _quoted_code(
1✔
881
    const char* str, std::size_t len)
882
{
883
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
884
                          role_t::VCR_QUOTED_CODE);
2✔
885
}
886

887
constexpr std::pair<string_fragment, role_t> operator"" _code_border(
332✔
888
    const char* str, std::size_t len)
889
{
890
    return std::make_pair(string_fragment{str, 0, (int) len},
332✔
891
                          role_t::VCR_CODE_BORDER);
664✔
892
}
893

894
constexpr std::pair<string_fragment, role_t> operator"" _table_header(
107✔
895
    const char* str, std::size_t len)
896
{
897
    return std::make_pair(string_fragment{str, 0, (int) len},
107✔
898
                          role_t::VCR_TABLE_HEADER);
214✔
899
}
900

901
constexpr std::pair<string_fragment, role_t> operator"" _table_border(
902
    const char* str, std::size_t len)
903
{
904
    return std::make_pair(string_fragment{str, 0, (int) len},
905
                          role_t::VCR_TABLE_BORDER);
906
}
907

908
constexpr std::pair<string_fragment, role_t> operator"" _quote_border(
100✔
909
    const char* str, std::size_t len)
910
{
911
    return std::make_pair(string_fragment{str, 0, (int) len},
100✔
912
                          role_t::VCR_QUOTE_BORDER);
200✔
913
}
914

915
constexpr std::pair<string_fragment, role_t> operator"" _quoted_text(
916
    const char* str, std::size_t len)
917
{
918
    return std::make_pair(string_fragment{str, 0, (int) len},
919
                          role_t::VCR_QUOTED_TEXT);
920
}
921

922
constexpr std::pair<string_fragment, role_t> operator"" _footnote_border(
328✔
923
    const char* str, std::size_t len)
924
{
925
    return std::make_pair(string_fragment{str, 0, (int) len},
328✔
926
                          role_t::VCR_FOOTNOTE_BORDER);
656✔
927
}
928

929
constexpr std::pair<string_fragment, role_t> operator"" _footnote_text(
930
    const char* str, std::size_t len)
931
{
932
    return std::make_pair(string_fragment{str, 0, (int) len},
933
                          role_t::VCR_FOOTNOTE_BORDER);
934
}
935

936
constexpr std::pair<string_fragment, role_t> operator"" _snippet_border(
2,097✔
937
    const char* str, std::size_t len)
938
{
939
    return std::make_pair(string_fragment{str, 0, (int) len},
2,097✔
940
                          role_t::VCR_SNIPPET_BORDER);
4,194✔
941
}
942

943
inline std::pair<std::string, string_attr_pair> operator"" _link(
944
    const char* str, std::size_t len)
945
{
946
    return std::make_pair(std::string(str, len),
947
                          VC_HYPERLINK.value(std::string(str, len)));
948
}
949

950
}  // namespace literals
951

952
}  // namespace roles
953
}  // namespace lnav
954

955
#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