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

tstack / lnav / 19612931027-2708

23 Nov 2025 02:52PM UTC coverage: 68.84% (-0.04%) from 68.876%
19612931027-2708

push

github

tstack
[tests] fix piper test

51153 of 74307 relevant lines covered (68.84%)

432164.33 hits per line

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

90.7
/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_SPECTRO_THRESHOLD0,
178
    VCR_SPECTRO_THRESHOLD1,
179
    VCR_SPECTRO_THRESHOLD2,
180
    VCR_SPECTRO_THRESHOLD3,
181
    VCR_SPECTRO_THRESHOLD4,
182
    VCR_SPECTRO_THRESHOLD5,
183
    VCR_SPECTRO_THRESHOLD6,
184

185
    VCR__MAX
186
};
187

188
struct text_attrs {
189
    enum class style : uint32_t {
190
        none = 0x0000,
191
        struck = 0x0001u,
192
        bold = 0x0002u,
193
        undercurl = 0x0004u,
194
        underline = 0x0008u,
195
        italic = 0x0010u,
196
        altcharset = 0x0020u,
197
        blink = 0x0040u,
198
        reverse = 0x1000u,
199
    };
200

201
    static text_attrs with_struck()
617✔
202
    {
203
        return text_attrs{
204
            lnav::enums::to_underlying(style::struck),
205
        };
617✔
206
    }
207

208
    static text_attrs with_bold()
821✔
209
    {
210
        return text_attrs{
211
            lnav::enums::to_underlying(style::bold),
212
        };
821✔
213
    }
214

215
    static text_attrs with_undercurl()
216
    {
217
        return text_attrs{
218
            lnav::enums::to_underlying(style::undercurl),
219
        };
220
    }
221

222
    static text_attrs with_underline()
47,293✔
223
    {
224
        return text_attrs{
225
            lnav::enums::to_underlying(style::underline),
226
        };
47,293✔
227
    }
228

229
    static text_attrs with_italic()
617✔
230
    {
231
        return text_attrs{
232
            lnav::enums::to_underlying(style::italic),
233
        };
617✔
234
    }
235

236
    static text_attrs with_reverse()
48,650✔
237
    {
238
        return text_attrs{
239
            lnav::enums::to_underlying(style::reverse),
240
        };
48,650✔
241
    }
242

243
    static text_attrs with_altcharset()
114✔
244
    {
245
        return text_attrs{
246
            lnav::enums::to_underlying(style::altcharset),
247
        };
114✔
248
    }
249

250
    static text_attrs with_blink()
251
    {
252
        return text_attrs{
253
            lnav::enums::to_underlying(style::blink),
254
        };
255
    }
256

257
    template<typename... Args>
258
    static text_attrs with_styles(Args... args)
249✔
259
    {
260
        auto retval = text_attrs{};
249✔
261

262
        for (auto arg : {args...}) {
747✔
263
            retval.ta_attrs |= lnav::enums::to_underlying(arg);
498✔
264
        }
265
        return retval;
249✔
266
    }
267

268
    bool empty() const
51,880✔
269
    {
270
        return this->ta_attrs == 0 && this->ta_fg_color.empty()
41,373✔
271
            && this->ta_bg_color.empty();
93,253✔
272
    }
273

274
    text_attrs operator|(const text_attrs& other) const
60,178✔
275
    {
276
        return text_attrs{
277
            this->ta_attrs | other.ta_attrs,
60,178✔
278
            !this->ta_fg_color.empty() ? this->ta_fg_color : other.ta_fg_color,
60,178✔
279
            !this->ta_bg_color.empty() ? this->ta_bg_color : other.ta_bg_color,
60,178✔
280
        };
180,534✔
281
    }
282

283
    text_attrs operator|(const style other) const
846✔
284
    {
285
        return text_attrs{
286
            this->ta_attrs | lnav::enums::to_underlying(other),
1,692✔
287
            this->ta_fg_color,
288
            this->ta_bg_color,
289
        };
846✔
290
    }
291

292
    text_attrs& operator|=(const style other)
724,481✔
293
    {
294
        this->ta_attrs |= lnav::enums::to_underlying(other);
724,481✔
295
        return *this;
724,481✔
296
    }
297

298
    void clear_style(style other)
10✔
299
    {
300
        this->ta_attrs &= ~lnav::enums::to_underlying(other);
10✔
301
    }
10✔
302

303
    bool has_style(style other) const
29,817✔
304
    {
305
        return this->ta_attrs & lnav::enums::to_underlying(other);
29,817✔
306
    }
307

308
    bool operator==(const text_attrs& other) const
×
309
    {
310
        return this->ta_attrs == other.ta_attrs
×
311
            && this->ta_fg_color == other.ta_fg_color
×
312
            && this->ta_bg_color == other.ta_bg_color;
×
313
    }
314

315
    uint32_t ta_attrs{0};
316
    styling::color_unit ta_fg_color{styling::color_unit::EMPTY};
317
    styling::color_unit ta_bg_color{styling::color_unit::EMPTY};
318
    std::optional<text_align_t> ta_align;
319
};
320

321
struct block_elem_t {
322
    char32_t value;
323
    role_t role;
324

325
    bool operator==(const block_elem_t& rhs) const
326
    {
327
        return this->value == rhs.value && this->role == rhs.role;
328
    }
329
};
330

331
struct ui_command {
332
    source_location uc_location;
333
    std::string uc_command;
334

335
    bool operator==(const ui_command& rhs) const
336
    {
337
        return this->uc_location == rhs.uc_location
338
            && this->uc_command == rhs.uc_command;
339
    }
340
};
341

342
using string_attr_value = mapbox::util::variant<int64_t,
343
                                                role_t,
344
                                                text_attrs,
345
                                                intern_string_t,
346
                                                std::string,
347
                                                std::shared_ptr<logfile>,
348
                                                bookmark_metadata*,
349
                                                string_fragment,
350
                                                block_elem_t,
351
                                                styling::color_unit,
352
                                                ui_icon_t,
353
                                                const char*,
354
                                                ui_command,
355
                                                text_format_t>;
356

357
class string_attr_type_base {
358
public:
359
    explicit constexpr string_attr_type_base(const char* name) noexcept
360
        : sat_name(name)
361
    {
362
    }
363

364
    const char* const sat_name;
365
};
366

367
using string_attr_pair
368
    = std::pair<const string_attr_type_base*, string_attr_value>;
369

370
template<typename T>
371
class string_attr_type : public string_attr_type_base {
372
public:
373
    using value_type = T;
374

375
    explicit constexpr string_attr_type(const char* name) noexcept
376
        : string_attr_type_base(name)
377
    {
378
    }
379

380
    template<typename U = T>
381
    std::enable_if_t<std::is_void_v<U>, string_attr_pair> value() const
123,054✔
382
    {
383
        return std::make_pair(this, string_attr_value{mapbox::util::no_init{}});
123,054✔
384
    }
385

386
    template<std::size_t N>
387
    std::enable_if_t<(N > 0) && std::is_same_v<std::string, T>,
388
                     string_attr_pair>
389
    value(const char (&val)[N]) const
14✔
390
    {
391
        return std::make_pair(this, std::string(val));
28✔
392
    }
393

394
    template<typename U = T>
395
    constexpr std::enable_if_t<!std::is_void_v<U>
396
                                   && std::is_convertible_v<U, T>,
397
                               string_attr_pair>
398
    value(U&& val) const
1,519,265✔
399
    {
400
        if constexpr (std::is_same_v<const char*, U>
401
                      && std::is_same_v<std::string, T>)
402
        {
403
            return std::make_pair(this, std::string(val));
404
        }
405
        return std::make_pair(this, val);
1,519,265✔
406
    }
407
};
408

409
extern const string_attr_type<void> SA_ORIGINAL_LINE;
410
extern const string_attr_type<void> SA_BODY;
411
extern const string_attr_type<void> SA_SRC_FILE;
412
extern const string_attr_type<void> SA_SRC_LINE;
413
extern const string_attr_type<void> SA_THREAD_ID;
414
extern const string_attr_type<void> SA_DURATION;
415
extern const string_attr_type<void> SA_EXTRA_CONTENT;
416
extern const string_attr_type<ui_icon_t> SA_HIDDEN;
417
extern const string_attr_type<void> SA_REPLACED;
418
extern const string_attr_type<intern_string_t> SA_FORMAT;
419
extern const string_attr_type<void> SA_REMOVED;
420
extern const string_attr_type<void> SA_PREFORMATTED;
421
extern const string_attr_type<std::string> SA_INVALID;
422
extern const string_attr_type<std::string> SA_ERROR;
423
extern const string_attr_type<int64_t> SA_LEVEL;
424
extern const string_attr_type<int64_t> SA_ORIGIN_OFFSET;
425
extern const string_attr_type<text_format_t> SA_QUOTED_TEXT;
426

427
extern const string_attr_type<std::string> VC_ANCHOR;
428
extern const string_attr_type<role_t> VC_ROLE;
429
extern const string_attr_type<role_t> VC_ROLE_FG;
430
extern const string_attr_type<text_attrs> VC_STYLE;
431
extern const string_attr_type<const char*> VC_GRAPHIC;
432
extern const string_attr_type<block_elem_t> VC_BLOCK_ELEM;
433
extern const string_attr_type<styling::color_unit> VC_FOREGROUND;
434
extern const string_attr_type<styling::color_unit> VC_BACKGROUND;
435
extern const string_attr_type<std::string> VC_HYPERLINK;
436
extern const string_attr_type<ui_icon_t> VC_ICON;
437
extern const string_attr_type<ui_command> VC_COMMAND;
438

439
namespace lnav {
440

441
namespace string::attrs {
442

443
template<typename S>
444
std::pair<S, string_attr_pair>
445
preformatted(S str)
446
{
447
    return std::make_pair(std::move(str), SA_PREFORMATTED.value());
448
}
449

450
template<typename S>
451
std::pair<S, string_attr_pair>
452
href(S str, std::string href)
18✔
453
{
454
    return std::make_pair(std::move(str), VC_HYPERLINK.value(std::move(href)));
18✔
455
}
456

457
}  // namespace string::attrs
458

459
namespace roles {
460

461
template<typename S>
462
std::pair<S, string_attr_pair>
463
for_flag(S str, bool flag)
16✔
464
{
465
    return std::make_pair(
466
        std::move(str),
16✔
467
        VC_ROLE.value(flag ? role_t::VCR_OK : role_t::VCR_ERROR));
32✔
468
}
469

470
template<typename S>
471
std::pair<S, string_attr_pair>
472
error(S str)
385✔
473
{
474
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_ERROR));
385✔
475
}
476

477
template<typename S>
478
std::pair<S, string_attr_pair>
479
warning(S str)
366✔
480
{
481
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_WARNING));
366✔
482
}
483

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

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

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

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

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

522
template<typename S>
523
std::pair<S, string_attr_pair>
524
hidden(S str)
8✔
525
{
526
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HIDDEN));
8✔
527
}
528

529
template<typename S>
530
std::pair<S, string_attr_pair>
531
file(S str)
370✔
532
{
533
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_FILE));
370✔
534
}
535

536
template<typename S>
537
std::pair<S, string_attr_pair>
538
symbol(S str)
15,913✔
539
{
540
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_SYMBOL));
15,913✔
541
}
542

543
template<typename S>
544
std::pair<S, string_attr_pair>
545
keyword(S str)
150✔
546
{
547
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_KEYWORD));
150✔
548
}
549

550
template<typename S>
551
std::pair<S, string_attr_pair>
552
variable(S str)
2,568✔
553
{
554
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_VARIABLE));
2,568✔
555
}
556

557
template<typename S>
558
std::pair<S, string_attr_pair>
559
number(S str)
4,112✔
560
{
561
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_NUMBER));
4,112✔
562
}
563

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

571
template<typename S>
572
std::pair<S, string_attr_pair>
573
identifier(S str)
2,746✔
574
{
575
    return std::make_pair(std::move(str),
2,746✔
576
                          VC_ROLE.value(role_t::VCR_IDENTIFIER));
5,492✔
577
}
578

579
template<typename S>
580
std::pair<S, string_attr_pair>
581
string(S str)
1✔
582
{
583
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_STRING));
1✔
584
}
585

586
template<typename S>
587
std::pair<S, string_attr_pair>
588
hr(S str)
×
589
{
590
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HR));
×
591
}
592

593
template<typename S>
594
std::pair<S, string_attr_pair>
595
hyperlink(S str)
328✔
596
{
597
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HYPERLINK));
328✔
598
}
599

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

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

616
template<typename S>
617
std::pair<S, string_attr_pair>
618
quoted_code(S str)
2,755✔
619
{
620
    return std::make_pair(std::move(str),
2,755✔
621
                          VC_ROLE.value(role_t::VCR_QUOTED_CODE));
5,510✔
622
}
623

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

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

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

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

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

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

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

680
template<typename S>
681
std::pair<S, string_attr_pair>
682
footnote_text(S str)
646✔
683
{
684
    return std::make_pair(std::move(str),
646✔
685
                          VC_ROLE.value(role_t::VCR_FOOTNOTE_TEXT));
1,292✔
686
}
687

688
template<typename S>
689
std::pair<S, string_attr_pair>
690
h1(S str)
691
{
692
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H1));
693
}
694

695
template<typename S>
696
std::pair<S, string_attr_pair>
697
h2(S str)
63✔
698
{
699
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_H2));
63✔
700
}
701

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

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

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

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

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

738
namespace literals {
739

740
constexpr std::pair<string_fragment, role_t> operator"" _ok(const char* str,
36✔
741
                                                            std::size_t len)
742
{
743
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_OK);
36✔
744
}
745

746
constexpr std::pair<string_fragment, role_t> operator"" _error(const char* str,
220✔
747
                                                               std::size_t len)
748
{
749
    return std::make_pair(string_fragment{str, 0, (int) len},
220✔
750
                          role_t::VCR_ERROR);
440✔
751
}
752

753
constexpr std::pair<string_fragment, role_t> operator"" _warning(
27✔
754
    const char* str, std::size_t len)
755
{
756
    return std::make_pair(string_fragment{str, 0, (int) len},
27✔
757
                          role_t::VCR_WARNING);
54✔
758
}
759

760
constexpr std::pair<string_fragment, role_t> operator"" _info(const char* str,
43,219✔
761
                                                              std::size_t len)
762
{
763
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_INFO);
43,219✔
764
}
765

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

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

780
constexpr std::pair<string_fragment, role_t> operator"" _symbol(const char* str,
44✔
781
                                                                std::size_t len)
782
{
783
    return std::make_pair(string_fragment{str, 0, (int) len},
44✔
784
                          role_t::VCR_SYMBOL);
88✔
785
}
786

787
constexpr std::pair<string_fragment, role_t> operator"" _keyword(
5✔
788
    const char* str, std::size_t len)
789
{
790
    return std::make_pair(string_fragment{str, 0, (int) len},
5✔
791
                          role_t::VCR_KEYWORD);
10✔
792
}
793

794
constexpr std::pair<string_fragment, role_t> operator"" _variable(
211✔
795
    const char* str, std::size_t len)
796
{
797
    return std::make_pair(string_fragment{str, 0, (int) len},
211✔
798
                          role_t::VCR_VARIABLE);
422✔
799
}
800

801
constexpr std::pair<string_fragment, role_t> operator"" _comment(
51✔
802
    const char* str, std::size_t len)
803
{
804
    return std::make_pair(string_fragment{str, 0, (int) len},
51✔
805
                          role_t::VCR_COMMENT);
102✔
806
}
807

808
constexpr std::pair<string_fragment, role_t> operator"" _hotkey(const char* str,
715✔
809
                                                                std::size_t len)
810
{
811
    return std::make_pair(string_fragment{str, 0, (int) len},
715✔
812
                          role_t::VCR_STATUS_HOTKEY);
1,430✔
813
}
814

815
constexpr std::pair<string_fragment, role_t> operator"" _h1(const char* str,
63✔
816
                                                            std::size_t len)
817
{
818
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H1);
63✔
819
}
820

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

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

833
constexpr std::pair<string_fragment, role_t> operator"" _h4(const char* str,
1,860✔
834
                                                            std::size_t len)
835
{
836
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H4);
1,860✔
837
}
838

839
constexpr std::pair<string_fragment, role_t> operator"" _h5(const char* str,
30✔
840
                                                            std::size_t len)
841
{
842
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_H5);
30✔
843
}
844

845
constexpr std::pair<string_fragment, role_t> operator"" _hr(const char* str,
846
                                                            std::size_t len)
847
{
848
    return std::make_pair(string_fragment{str, 0, (int) len}, role_t::VCR_HR);
849
}
850

851
constexpr std::pair<string_fragment, role_t> operator"" _hyperlink(
1✔
852
    const char* str, std::size_t len)
853
{
854
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
855
                          role_t::VCR_HYPERLINK);
2✔
856
}
857

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

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

872
constexpr std::pair<string_fragment, role_t> operator"" _quoted_code(
1✔
873
    const char* str, std::size_t len)
874
{
875
    return std::make_pair(string_fragment{str, 0, (int) len},
1✔
876
                          role_t::VCR_QUOTED_CODE);
2✔
877
}
878

879
constexpr std::pair<string_fragment, role_t> operator"" _code_border(
332✔
880
    const char* str, std::size_t len)
881
{
882
    return std::make_pair(string_fragment{str, 0, (int) len},
332✔
883
                          role_t::VCR_CODE_BORDER);
664✔
884
}
885

886
constexpr std::pair<string_fragment, role_t> operator"" _table_header(
65✔
887
    const char* str, std::size_t len)
888
{
889
    return std::make_pair(string_fragment{str, 0, (int) len},
65✔
890
                          role_t::VCR_TABLE_HEADER);
130✔
891
}
892

893
constexpr std::pair<string_fragment, role_t> operator"" _table_border(
894
    const char* str, std::size_t len)
895
{
896
    return std::make_pair(string_fragment{str, 0, (int) len},
897
                          role_t::VCR_TABLE_BORDER);
898
}
899

900
constexpr std::pair<string_fragment, role_t> operator"" _quote_border(
100✔
901
    const char* str, std::size_t len)
902
{
903
    return std::make_pair(string_fragment{str, 0, (int) len},
100✔
904
                          role_t::VCR_QUOTE_BORDER);
200✔
905
}
906

907
constexpr std::pair<string_fragment, role_t> operator"" _quoted_text(
908
    const char* str, std::size_t len)
909
{
910
    return std::make_pair(string_fragment{str, 0, (int) len},
911
                          role_t::VCR_QUOTED_TEXT);
912
}
913

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

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

928
constexpr std::pair<string_fragment, role_t> operator"" _snippet_border(
2,010✔
929
    const char* str, std::size_t len)
930
{
931
    return std::make_pair(string_fragment{str, 0, (int) len},
2,010✔
932
                          role_t::VCR_SNIPPET_BORDER);
4,020✔
933
}
934

935
inline std::pair<std::string, string_attr_pair> operator"" _link(
936
    const char* str, std::size_t len)
937
{
938
    return std::make_pair(std::string(str, len),
939
                          VC_HYPERLINK.value(std::string(str, len)));
940
}
941

942
}  // namespace literals
943

944
}  // namespace roles
945
}  // namespace lnav
946

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