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

tstack / lnav / 18736722727-2602

23 Oct 2025 03:35AM UTC coverage: 69.333% (-0.7%) from 70.006%
18736722727-2602

push

github

tstack
[tests] update expected output

50430 of 72736 relevant lines covered (69.33%)

425990.7 hits per line

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

86.63
/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
};
71

72
constexpr auto ui_icon_count = lnav::enums::to_underlying(ui_icon_t::edit) + 1;
73

74
/** Roles that can be mapped to curses attributes using attrs_for_role() */
75
enum class role_t : int32_t {
76
    VCR_NONE = -1,
77

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

124
    VCR_QUOTED_CODE,
125
    VCR_CODE_BORDER,
126
    VCR_KEYWORD,
127
    VCR_STRING,
128
    VCR_COMMENT,
129
    VCR_DOC_DIRECTIVE,
130
    VCR_VARIABLE,
131
    VCR_SYMBOL,
132
    VCR_NULL,
133
    VCR_ASCII_CTRL,
134
    VCR_NON_ASCII,
135
    VCR_NUMBER,
136
    VCR_RE_SPECIAL,
137
    VCR_RE_REPEAT,
138
    VCR_FILE,
139

140
    VCR_DIFF_DELETE, /*< Deleted line in a diff. */
141
    VCR_DIFF_ADD, /*< Added line in a diff. */
142
    VCR_DIFF_SECTION, /*< Section marker in a diff. */
143

144
    VCR_LOW_THRESHOLD,
145
    VCR_MED_THRESHOLD,
146
    VCR_HIGH_THRESHOLD,
147

148
    VCR_H1,
149
    VCR_H2,
150
    VCR_H3,
151
    VCR_H4,
152
    VCR_H5,
153
    VCR_H6,
154

155
    VCR_HR,
156
    VCR_HYPERLINK,
157
    VCR_LIST_GLYPH,
158
    VCR_BREADCRUMB,
159
    VCR_TABLE_BORDER,
160
    VCR_TABLE_HEADER,
161
    VCR_QUOTE_BORDER,
162
    VCR_QUOTED_TEXT,
163
    VCR_FOOTNOTE_BORDER,
164
    VCR_FOOTNOTE_TEXT,
165
    VCR_SNIPPET_BORDER,
166
    VCR_INDENT_GUIDE,
167
    VCR_INLINE_CODE,
168
    VCR_FUNCTION,
169
    VCR_TYPE,
170
    VCR_SEP_REF_ACC,
171
    VCR_SUGGESTION,
172
    VCR_SELECTED_TEXT,
173
    VCR_FUZZY_MATCH,
174

175
    VCR_OBJECT_KEY,
176

177
    VCR__MAX
178
};
179

180
struct text_attrs {
181
    enum class style : uint32_t {
182
        none = 0x0000,
183
        struck = 0x0001u,
184
        bold = 0x0002u,
185
        undercurl = 0x0004u,
186
        underline = 0x0008u,
187
        italic = 0x0010u,
188
        altcharset = 0x0020u,
189
        blink = 0x0040u,
190
        reverse = 0x1000u,
191
    };
192

193
    static text_attrs with_struck()
595✔
194
    {
195
        return text_attrs{
196
            lnav::enums::to_underlying(style::struck),
197
        };
595✔
198
    }
199

200
    static text_attrs with_bold()
797✔
201
    {
202
        return text_attrs{
203
            lnav::enums::to_underlying(style::bold),
204
        };
797✔
205
    }
206

207
    static text_attrs with_undercurl()
208
    {
209
        return text_attrs{
210
            lnav::enums::to_underlying(style::undercurl),
211
        };
212
    }
213

214
    static text_attrs with_underline()
5,195✔
215
    {
216
        return text_attrs{
217
            lnav::enums::to_underlying(style::underline),
218
        };
5,195✔
219
    }
220

221
    static text_attrs with_italic()
1,080✔
222
    {
223
        return text_attrs{
224
            lnav::enums::to_underlying(style::italic),
225
        };
1,080✔
226
    }
227

228
    static text_attrs with_reverse()
24,435✔
229
    {
230
        return text_attrs{
231
            lnav::enums::to_underlying(style::reverse),
232
        };
24,435✔
233
    }
234

235
    static text_attrs with_altcharset()
34✔
236
    {
237
        return text_attrs{
238
            lnav::enums::to_underlying(style::altcharset),
239
        };
34✔
240
    }
241

242
    static text_attrs with_blink()
243
    {
244
        return text_attrs{
245
            lnav::enums::to_underlying(style::blink),
246
        };
247
    }
248

249
    template<typename... Args>
250
    static text_attrs with_styles(Args... args)
247✔
251
    {
252
        auto retval = text_attrs{};
247✔
253

254
        for (auto arg : {args...}) {
741✔
255
            retval.ta_attrs |= lnav::enums::to_underlying(arg);
494✔
256
        }
257
        return retval;
247✔
258
    }
259

260
    bool empty() const
50,047✔
261
    {
262
        return this->ta_attrs == 0 && this->ta_fg_color.empty()
39,387✔
263
            && this->ta_bg_color.empty();
89,434✔
264
    }
265

266
    text_attrs operator|(const text_attrs& other) const
82,217✔
267
    {
268
        return text_attrs{
269
            this->ta_attrs | other.ta_attrs,
82,217✔
270
            !this->ta_fg_color.empty() ? this->ta_fg_color : other.ta_fg_color,
82,217✔
271
            !this->ta_bg_color.empty() ? this->ta_bg_color : other.ta_bg_color,
82,217✔
272
        };
246,651✔
273
    }
274

275
    text_attrs operator|(const style other) const
842✔
276
    {
277
        return text_attrs{
278
            this->ta_attrs | lnav::enums::to_underlying(other),
1,684✔
279
            this->ta_fg_color,
280
            this->ta_bg_color,
281
        };
842✔
282
    }
283

284
    text_attrs& operator|=(const style other)
636,507✔
285
    {
286
        this->ta_attrs |= lnav::enums::to_underlying(other);
636,507✔
287
        return *this;
636,507✔
288
    }
289

290
    void clear_style(style other)
23✔
291
    {
292
        this->ta_attrs &= ~lnav::enums::to_underlying(other);
23✔
293
    }
23✔
294

295
    bool has_style(style other) const
36,905✔
296
    {
297
        return this->ta_attrs & lnav::enums::to_underlying(other);
36,905✔
298
    }
299

300
    bool operator==(const text_attrs& other) const
×
301
    {
302
        return this->ta_attrs == other.ta_attrs
×
303
            && this->ta_fg_color == other.ta_fg_color
×
304
            && this->ta_bg_color == other.ta_bg_color;
×
305
    }
306

307
    uint32_t ta_attrs{0};
308
    styling::color_unit ta_fg_color{styling::color_unit::EMPTY};
309
    styling::color_unit ta_bg_color{styling::color_unit::EMPTY};
310
    std::optional<text_align_t> ta_align;
311
};
312

313
struct block_elem_t {
314
    char32_t value;
315
    role_t role;
316

317
    bool operator==(const block_elem_t& rhs) const
318
    {
319
        return this->value == rhs.value && this->role == rhs.role;
320
    }
321
};
322

323
struct ui_command {
324
    source_location uc_location;
325
    std::string uc_command;
326

327
    bool operator==(const ui_command& rhs) const
328
    {
329
        return this->uc_location == rhs.uc_location
330
            && this->uc_command == rhs.uc_command;
331
    }
332
};
333

334
using string_attr_value = mapbox::util::variant<int64_t,
335
                                                role_t,
336
                                                text_attrs,
337
                                                intern_string_t,
338
                                                std::string,
339
                                                std::shared_ptr<logfile>,
340
                                                bookmark_metadata*,
341
                                                string_fragment,
342
                                                block_elem_t,
343
                                                styling::color_unit,
344
                                                ui_icon_t,
345
                                                const char*,
346
                                                ui_command,
347
                                                text_format_t>;
348

349
class string_attr_type_base {
350
public:
351
    explicit constexpr string_attr_type_base(const char* name) noexcept
352
        : sat_name(name)
353
    {
354
    }
355

356
    const char* const sat_name;
357
};
358

359
using string_attr_pair
360
    = std::pair<const string_attr_type_base*, string_attr_value>;
361

362
template<typename T>
363
class string_attr_type : public string_attr_type_base {
364
public:
365
    using value_type = T;
366

367
    explicit constexpr string_attr_type(const char* name) noexcept
368
        : string_attr_type_base(name)
369
    {
370
    }
371

372
    template<typename U = T>
373
    std::enable_if_t<std::is_void_v<U>, string_attr_pair> value() const
120,884✔
374
    {
375
        return std::make_pair(this, string_attr_value{mapbox::util::no_init{}});
120,884✔
376
    }
377

378
    template<std::size_t N>
379
    std::enable_if_t<(N > 0) && std::is_same_v<std::string, T>,
380
                     string_attr_pair>
381
    value(const char (&val)[N]) const
14✔
382
    {
383
        return std::make_pair(this, std::string(val));
28✔
384
    }
385

386
    template<typename U = T>
387
    constexpr std::enable_if_t<!std::is_void_v<U>
388
                                   && std::is_convertible_v<U, T>,
389
                               string_attr_pair>
390
    value(U&& val) const
1,199,849✔
391
    {
392
        if constexpr (std::is_same_v<const char*, U>
393
                      && std::is_same_v<std::string, T>)
394
        {
395
            return std::make_pair(this, std::string(val));
396
        }
397
        return std::make_pair(this, val);
1,199,849✔
398
    }
399
};
400

401
extern const string_attr_type<void> SA_ORIGINAL_LINE;
402
extern const string_attr_type<void> SA_BODY;
403
extern const string_attr_type<void> SA_SRC_FILE;
404
extern const string_attr_type<void> SA_SRC_LINE;
405
extern const string_attr_type<void> SA_THREAD_ID;
406
extern const string_attr_type<void> SA_DURATION;
407
extern const string_attr_type<void> SA_EXTRA_CONTENT;
408
extern const string_attr_type<ui_icon_t> SA_HIDDEN;
409
extern const string_attr_type<void> SA_REPLACED;
410
extern const string_attr_type<intern_string_t> SA_FORMAT;
411
extern const string_attr_type<void> SA_REMOVED;
412
extern const string_attr_type<void> SA_PREFORMATTED;
413
extern const string_attr_type<std::string> SA_INVALID;
414
extern const string_attr_type<std::string> SA_ERROR;
415
extern const string_attr_type<int64_t> SA_LEVEL;
416
extern const string_attr_type<int64_t> SA_ORIGIN_OFFSET;
417
extern const string_attr_type<text_format_t> SA_QUOTED_TEXT;
418

419
extern const string_attr_type<std::string> VC_ANCHOR;
420
extern const string_attr_type<role_t> VC_ROLE;
421
extern const string_attr_type<role_t> VC_ROLE_FG;
422
extern const string_attr_type<text_attrs> VC_STYLE;
423
extern const string_attr_type<const char*> VC_GRAPHIC;
424
extern const string_attr_type<block_elem_t> VC_BLOCK_ELEM;
425
extern const string_attr_type<styling::color_unit> VC_FOREGROUND;
426
extern const string_attr_type<styling::color_unit> VC_BACKGROUND;
427
extern const string_attr_type<std::string> VC_HYPERLINK;
428
extern const string_attr_type<ui_icon_t> VC_ICON;
429
extern const string_attr_type<ui_command> VC_COMMAND;
430

431
namespace lnav {
432

433
namespace string::attrs {
434

435
template<typename S>
436
std::pair<S, string_attr_pair>
437
preformatted(S str)
438
{
439
    return std::make_pair(std::move(str), SA_PREFORMATTED.value());
440
}
441

442
template<typename S>
443
std::pair<S, string_attr_pair>
444
href(S str, std::string href)
16✔
445
{
446
    return std::make_pair(std::move(str), VC_HYPERLINK.value(std::move(href)));
16✔
447
}
448

449
}  // namespace string::attrs
450

451
namespace roles {
452

453
template<typename S>
454
std::pair<S, string_attr_pair>
455
for_flag(S str, bool flag)
×
456
{
457
    return std::make_pair(
458
        std::move(str),
×
459
        VC_ROLE.value(flag ? role_t::VCR_OK : role_t::VCR_ERROR));
×
460
}
461

462
template<typename S>
463
std::pair<S, string_attr_pair>
464
error(S str)
550✔
465
{
466
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_ERROR));
550✔
467
}
468

469
template<typename S>
470
std::pair<S, string_attr_pair>
471
warning(S str)
345✔
472
{
473
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_WARNING));
345✔
474
}
475

476
template<typename S>
477
std::pair<S, string_attr_pair>
478
status(S str)
479
{
480
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STATUS));
481
}
482

483
template<typename S>
484
std::pair<S, string_attr_pair>
485
inactive_status(S str)
486
{
487
    return std::make_pair(std::move(str),
488
                          VC_ROLE.value(role_t::VCR_INACTIVE_STATUS));
489
}
490

491
template<typename S>
492
std::pair<S, string_attr_pair>
493
status_title(S str)
40✔
494
{
495
    return std::make_pair(std::move(str),
40✔
496
                          VC_ROLE.value(role_t::VCR_STATUS_TITLE));
80✔
497
}
498

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

507
template<typename S>
508
std::pair<S, string_attr_pair>
509
ok(S str)
3✔
510
{
511
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_OK));
3✔
512
}
513

514
template<typename S>
515
std::pair<S, string_attr_pair>
516
hidden(S str)
×
517
{
518
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HIDDEN));
×
519
}
520

521
template<typename S>
522
std::pair<S, string_attr_pair>
523
file(S str)
375✔
524
{
525
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_FILE));
375✔
526
}
527

528
template<typename S>
529
std::pair<S, string_attr_pair>
530
symbol(S str)
16,033✔
531
{
532
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_SYMBOL));
16,033✔
533
}
534

535
template<typename S>
536
std::pair<S, string_attr_pair>
537
keyword(S str)
150✔
538
{
539
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_KEYWORD));
150✔
540
}
541

542
template<typename S>
543
std::pair<S, string_attr_pair>
544
variable(S str)
2,577✔
545
{
546
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_VARIABLE));
2,577✔
547
}
548

549
template<typename S>
550
std::pair<S, string_attr_pair>
551
number(S str)
4,009✔
552
{
553
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_NUMBER));
4,009✔
554
}
555

556
template<typename S>
557
std::pair<S, string_attr_pair>
558
comment(S str)
5✔
559
{
560
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_COMMENT));
5✔
561
}
562

563
template<typename S>
564
std::pair<S, string_attr_pair>
565
identifier(S str)
2,645✔
566
{
567
    return std::make_pair(std::move(str),
2,645✔
568
                          VC_ROLE.value(role_t::VCR_IDENTIFIER));
5,290✔
569
}
570

571
template<typename S>
572
std::pair<S, string_attr_pair>
573
string(S str)
1✔
574
{
575
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STRING));
1✔
576
}
577

578
template<typename S>
579
std::pair<S, string_attr_pair>
580
hr(S str)
×
581
{
582
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HR));
×
583
}
584

585
template<typename S>
586
std::pair<S, string_attr_pair>
587
hyperlink(S str)
326✔
588
{
589
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HYPERLINK));
326✔
590
}
591

592
template<typename S>
593
std::pair<S, string_attr_pair>
594
list_glyph(S str)
360✔
595
{
596
    return std::make_pair(std::move(str),
360✔
597
                          VC_ROLE.value(role_t::VCR_LIST_GLYPH));
720✔
598
}
599

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

608
template<typename S>
609
std::pair<S, string_attr_pair>
610
quoted_code(S str)
2,668✔
611
{
612
    return std::make_pair(std::move(str),
2,668✔
613
                          VC_ROLE.value(role_t::VCR_QUOTED_CODE));
5,336✔
614
}
615

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

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

632
template<typename S>
633
std::pair<S, string_attr_pair>
634
table_border(S str)
913✔
635
{
636
    return std::make_pair(std::move(str),
913✔
637
                          VC_ROLE.value(role_t::VCR_TABLE_BORDER));
1,826✔
638
}
639

640
template<typename S>
641
std::pair<S, string_attr_pair>
642
table_header(S str)
×
643
{
644
    return std::make_pair(std::move(str),
×
645
                          VC_ROLE.value(role_t::VCR_TABLE_HEADER));
×
646
}
647

648
template<typename S>
649
std::pair<S, string_attr_pair>
650
quote_border(S str)
651
{
652
    return std::make_pair(std::move(str),
653
                          VC_ROLE.value(role_t::VCR_QUOTE_BORDER));
654
}
655

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

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

672
template<typename S>
673
std::pair<S, string_attr_pair>
674
footnote_text(S str)
642✔
675
{
676
    return std::make_pair(std::move(str),
642✔
677
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_TEXT));
1,284✔
678
}
679

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

687
template<typename S>
688
std::pair<S, string_attr_pair>
689
h2(S str)
63✔
690
{
691
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H2));
63✔
692
}
693

694
template<typename S>
695
std::pair<S, string_attr_pair>
696
h3(S str)
×
697
{
698
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H3));
×
699
}
700

701
template<typename S>
702
std::pair<S, string_attr_pair>
703
h4(S str)
704
{
705
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H4));
706
}
707

708
template<typename S>
709
std::pair<S, string_attr_pair>
710
h5(S str)
×
711
{
712
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H5));
×
713
}
714

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

722
template<typename S>
723
std::pair<S, string_attr_pair>
724
suggestion(S str)
725
{
726
    return std::make_pair(std::move(str),
727
                          VC_ROLE.value(role_t::VCR_SUGGESTION));
728
}
729

730
namespace literals {
731

732
constexpr std::pair<string_fragment, role_t> operator"" _ok(const char* str,
36✔
733
                                                            std::size_t len)
734
{
735
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_OK);
36✔
736
}
737

738
constexpr std::pair<string_fragment, role_t> operator"" _error(const char* str,
14✔
739
                                                               std::size_t len)
740
{
741
    return std::make_pair(string_fragment{str, 0, (int) len},
14✔
742
                          role_t::VCR_ERROR);
28✔
743
}
744

745
constexpr std::pair<string_fragment, role_t> operator"" _warning(
13✔
746
    const char* str, std::size_t len)
747
{
748
    return std::make_pair(string_fragment{str, 0, (int) len},
13✔
749
                          role_t::VCR_WARNING);
26✔
750
}
751

752
constexpr std::pair<string_fragment, role_t> operator"" _info(const char* str,
119✔
753
                                                              std::size_t len)
754
{
755
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_INFO);
119✔
756
}
757

758
constexpr std::pair<string_fragment, role_t> operator"" _status_title(
759
    const char* str, std::size_t len)
760
{
761
    return std::make_pair(string_fragment{str, 0, (int) len},
762
                          role_t::VCR_STATUS_TITLE);
763
}
764

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

772
constexpr std::pair<string_fragment, role_t> operator"" _symbol(const char* str,
40✔
773
                                                                std::size_t len)
774
{
775
    return std::make_pair(string_fragment{str, 0, (int) len},
40✔
776
                          role_t::VCR_SYMBOL);
80✔
777
}
778

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

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

793
constexpr std::pair<string_fragment, role_t> operator"" _comment(
50✔
794
    const char* str, std::size_t len)
795
{
796
    return std::make_pair(string_fragment{str, 0, (int) len},
50✔
797
                          role_t::VCR_COMMENT);
100✔
798
}
799

800
constexpr std::pair<string_fragment, role_t> operator"" _hotkey(const char* str,
739✔
801
                                                                std::size_t len)
802
{
803
    return std::make_pair(string_fragment{str, 0, (int) len},
739✔
804
                          role_t::VCR_STATUS_HOTKEY);
1,478✔
805
}
806

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

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

819
constexpr std::pair<string_fragment, role_t> operator"" _h3(const char* str,
×
820
                                                            std::size_t len)
821
{
822
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H3);
×
823
}
824

825
constexpr std::pair<string_fragment, role_t> operator"" _h4(const char* str,
1,875✔
826
                                                            std::size_t len)
827
{
828
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H4);
1,875✔
829
}
830

831
constexpr std::pair<string_fragment, role_t> operator"" _h5(const char* str,
30✔
832
                                                            std::size_t len)
833
{
834
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H5);
30✔
835
}
836

837
constexpr std::pair<string_fragment, role_t> operator"" _hr(const char* str,
838
                                                            std::size_t len)
839
{
840
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_HR);
841
}
842

843
constexpr std::pair<string_fragment, role_t> operator"" _hyperlink(
1✔
844
    const char* str, std::size_t len)
845
{
846
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
847
                          role_t::VCR_HYPERLINK);
2✔
848
}
849

850
constexpr std::pair<string_fragment, role_t> operator"" _list_glyph(
743✔
851
    const char* str, std::size_t len)
852
{
853
    return std::make_pair(string_fragment{str, 0, (int) len},
743✔
854
                          role_t::VCR_LIST_GLYPH);
1,486✔
855
}
856

857
constexpr std::pair<string_fragment, role_t> operator"" _breadcrumb(
40✔
858
    const char* str, std::size_t len)
859
{
860
    return std::make_pair(string_fragment{str, 0, (int) len},
40✔
861
                          role_t::VCR_BREADCRUMB);
80✔
862
}
863

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

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

878
constexpr std::pair<string_fragment, role_t> operator"" _table_header(
65✔
879
    const char* str, std::size_t len)
880
{
881
    return std::make_pair(string_fragment{str, 0, (int) len},
65✔
882
                          role_t::VCR_TABLE_HEADER);
130✔
883
}
884

885
constexpr std::pair<string_fragment, role_t> operator"" _table_border(
886
    const char* str, std::size_t len)
887
{
888
    return std::make_pair(string_fragment{str, 0, (int) len},
889
                          role_t::VCR_TABLE_BORDER);
890
}
891

892
constexpr std::pair<string_fragment, role_t> operator"" _quote_border(
85✔
893
    const char* str, std::size_t len)
894
{
895
    return std::make_pair(string_fragment{str, 0, (int) len},
85✔
896
                          role_t::VCR_QUOTE_BORDER);
170✔
897
}
898

899
constexpr std::pair<string_fragment, role_t> operator"" _quoted_text(
900
    const char* str, std::size_t len)
901
{
902
    return std::make_pair(string_fragment{str, 0, (int) len},
903
                          role_t::VCR_QUOTED_TEXT);
904
}
905

906
constexpr std::pair<string_fragment, role_t> operator"" _footnote_border(
325✔
907
    const char* str, std::size_t len)
908
{
909
    return std::make_pair(string_fragment{str, 0, (int) len},
325✔
910
                          role_t::VCR_FOOTNOTE_BORDER);
650✔
911
}
912

913
constexpr std::pair<string_fragment, role_t> operator"" _footnote_text(
914
    const char* str, std::size_t len)
915
{
916
    return std::make_pair(string_fragment{str, 0, (int) len},
917
                          role_t::VCR_FOOTNOTE_BORDER);
918
}
919

920
constexpr std::pair<string_fragment, role_t> operator"" _snippet_border(
1,814✔
921
    const char* str, std::size_t len)
922
{
923
    return std::make_pair(string_fragment{str, 0, (int) len},
1,814✔
924
                          role_t::VCR_SNIPPET_BORDER);
3,628✔
925
}
926

927
inline std::pair<std::string, string_attr_pair> operator"" _link(
928
    const char* str, std::size_t len)
929
{
930
    return std::make_pair(std::string(str, len),
931
                          VC_HYPERLINK.value(std::string(str, len)));
932
}
933

934
}  // namespace literals
935

936
}  // namespace roles
937
}  // namespace lnav
938

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

© 2026 Coveralls, Inc