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

tstack / lnav / 22507085525-2793

27 Feb 2026 10:49PM UTC coverage: 68.948% (-0.02%) from 68.966%
22507085525-2793

push

github

tstack
fix mixup of O_CLOEXEC with FD_CLOEXEC

52007 of 75429 relevant lines covered (68.95%)

440500.48 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
    busy,
73
};
74

75
constexpr auto ui_icon_count = lnav::enums::to_underlying(ui_icon_t::busy) + 1;
76

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

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

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

143
    VCR_DIFF_DELETE, /*< Deleted line in a diff. */
144
    VCR_DIFF_ADD, /*< Added line in a diff. */
145
    VCR_DIFF_SECTION, /*< Section marker in a diff. */
146

147
    VCR_LOW_THRESHOLD,
148
    VCR_MED_THRESHOLD,
149
    VCR_HIGH_THRESHOLD,
150

151
    VCR_H1,
152
    VCR_H2,
153
    VCR_H3,
154
    VCR_H4,
155
    VCR_H5,
156
    VCR_H6,
157

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

178
    VCR_OBJECT_KEY,
179

180
    VCR_SPECTRO_THRESHOLD0,
181
    VCR_SPECTRO_THRESHOLD1,
182
    VCR_SPECTRO_THRESHOLD2,
183
    VCR_SPECTRO_THRESHOLD3,
184
    VCR_SPECTRO_THRESHOLD4,
185
    VCR_SPECTRO_THRESHOLD5,
186
    VCR_SPECTRO_THRESHOLD6,
187

188
    VCR__MAX
189
};
190

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

204
    static text_attrs with_struck()
630✔
205
    {
206
        return text_attrs{
207
            lnav::enums::to_underlying(style::struck),
208
        };
630✔
209
    }
210

211
    static text_attrs with_bold()
853✔
212
    {
213
        return text_attrs{
214
            lnav::enums::to_underlying(style::bold),
215
        };
853✔
216
    }
217

218
    static text_attrs with_undercurl()
219
    {
220
        return text_attrs{
221
            lnav::enums::to_underlying(style::undercurl),
222
        };
223
    }
224

225
    static text_attrs with_underline()
48,303✔
226
    {
227
        return text_attrs{
228
            lnav::enums::to_underlying(style::underline),
229
        };
48,303✔
230
    }
231

232
    static text_attrs with_italic()
630✔
233
    {
234
        return text_attrs{
235
            lnav::enums::to_underlying(style::italic),
236
        };
630✔
237
    }
238

239
    static text_attrs with_reverse()
49,441✔
240
    {
241
        return text_attrs{
242
            lnav::enums::to_underlying(style::reverse),
243
        };
49,441✔
244
    }
245

246
    static text_attrs with_altcharset()
131✔
247
    {
248
        return text_attrs{
249
            lnav::enums::to_underlying(style::altcharset),
250
        };
131✔
251
    }
252

253
    static text_attrs with_blink()
254
    {
255
        return text_attrs{
256
            lnav::enums::to_underlying(style::blink),
257
        };
258
    }
259

260
    template<typename... Args>
261
    static text_attrs with_styles(Args... args)
250✔
262
    {
263
        auto retval = text_attrs{};
250✔
264

265
        for (auto arg : {args...}) {
750✔
266
            retval.ta_attrs |= lnav::enums::to_underlying(arg);
500✔
267
        }
268
        return retval;
250✔
269
    }
270

271
    bool empty() const
53,350✔
272
    {
273
        return this->ta_attrs == 0 && this->ta_fg_color.empty()
42,605✔
274
            && this->ta_bg_color.empty();
95,955✔
275
    }
276

277
    text_attrs operator|(const text_attrs& other) const
62,624✔
278
    {
279
        return text_attrs{
280
            this->ta_attrs | other.ta_attrs,
62,624✔
281
            !this->ta_fg_color.empty() ? this->ta_fg_color : other.ta_fg_color,
62,624✔
282
            !this->ta_bg_color.empty() ? this->ta_bg_color : other.ta_bg_color,
62,624✔
283
        };
187,872✔
284
    }
285

286
    text_attrs operator|(const style other) const
850✔
287
    {
288
        return text_attrs{
289
            this->ta_attrs | lnav::enums::to_underlying(other),
1,700✔
290
            this->ta_fg_color,
291
            this->ta_bg_color,
292
        };
850✔
293
    }
294

295
    text_attrs& operator|=(const style other)
756,093✔
296
    {
297
        this->ta_attrs |= lnav::enums::to_underlying(other);
756,093✔
298
        return *this;
756,093✔
299
    }
300

301
    void clear_style(style other)
13✔
302
    {
303
        this->ta_attrs &= ~lnav::enums::to_underlying(other);
13✔
304
    }
13✔
305

306
    bool has_style(style other) const
30,935✔
307
    {
308
        return this->ta_attrs & lnav::enums::to_underlying(other);
30,935✔
309
    }
310

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

318
    uint32_t ta_attrs{0};
319
    styling::color_unit ta_fg_color{styling::color_unit::EMPTY};
320
    styling::color_unit ta_bg_color{styling::color_unit::EMPTY};
321
    std::optional<text_align_t> ta_align;
322
};
323

324
struct block_elem_t {
325
    char32_t value;
326
    role_t role;
327

328
    bool operator==(const block_elem_t& rhs) const
329
    {
330
        return this->value == rhs.value && this->role == rhs.role;
331
    }
332
};
333

334
struct ui_command {
335
    source_location uc_location;
336
    std::string uc_command;
337

338
    bool operator==(const ui_command& rhs) const
339
    {
340
        return this->uc_location == rhs.uc_location
341
            && this->uc_command == rhs.uc_command;
342
    }
343
};
344

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

360
class string_attr_type_base {
361
public:
362
    explicit constexpr string_attr_type_base(const char* name) noexcept
363
        : sat_name(name)
364
    {
365
    }
366

367
    const char* const sat_name;
368
};
369

370
using string_attr_pair
371
    = std::pair<const string_attr_type_base*, string_attr_value>;
372

373
template<typename T>
374
class string_attr_type : public string_attr_type_base {
375
public:
376
    using value_type = T;
377

378
    explicit constexpr string_attr_type(const char* name) noexcept
379
        : string_attr_type_base(name)
380
    {
381
    }
382

383
    template<typename U = T>
384
    std::enable_if_t<std::is_void_v<U>, string_attr_pair> value() const
124,150✔
385
    {
386
        return std::make_pair(this, string_attr_value{mapbox::util::no_init{}});
124,150✔
387
    }
388

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

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

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

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

442
namespace lnav {
443

444
namespace string::attrs {
445

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

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

460
}  // namespace string::attrs
461

462
namespace roles {
463

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

473
template<typename S>
474
std::pair<S, string_attr_pair>
475
error(S str)
423✔
476
{
477
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_ERROR));
423✔
478
}
479

480
template<typename S>
481
std::pair<S, string_attr_pair>
482
warning(S str)
403✔
483
{
484
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_WARNING));
403✔
485
}
486

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

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

502
template<typename S>
503
std::pair<S, string_attr_pair>
504
status_title(S str)
17✔
505
{
506
    return std::make_pair(std::move(str),
17✔
507
                          VC_ROLE.value(role_t::VCR_STATUS_TITLE));
34✔
508
}
509

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

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

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

532
template<typename S>
533
std::pair<S, string_attr_pair>
534
file(S str)
372✔
535
{
536
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_FILE));
372✔
537
}
538

539
template<typename S>
540
std::pair<S, string_attr_pair>
541
symbol(S str)
15,936✔
542
{
543
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_SYMBOL));
15,936✔
544
}
545

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

553
template<typename S>
554
std::pair<S, string_attr_pair>
555
variable(S str)
2,639✔
556
{
557
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_VARIABLE));
2,639✔
558
}
559

560
template<typename S>
561
std::pair<S, string_attr_pair>
562
number(S str)
4,243✔
563
{
564
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_NUMBER));
4,243✔
565
}
566

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

574
template<typename S>
575
std::pair<S, string_attr_pair>
576
identifier(S str)
2,832✔
577
{
578
    return std::make_pair(std::move(str),
2,832✔
579
                          VC_ROLE.value(role_t::VCR_IDENTIFIER));
5,664✔
580
}
581

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

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

596
template<typename S>
597
std::pair<S, string_attr_pair>
598
hyperlink(S str)
332✔
599
{
600
    return std::make_pair(std::move(str), VC_ROLE.value(role_t::VCR_HYPERLINK));
332✔
601
}
602

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

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

619
template<typename S>
620
std::pair<S, string_attr_pair>
621
quoted_code(S str)
2,804✔
622
{
623
    return std::make_pair(std::move(str),
2,804✔
624
                          VC_ROLE.value(role_t::VCR_QUOTED_CODE));
5,608✔
625
}
626

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

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

643
template<typename S>
644
std::pair<S, string_attr_pair>
645
table_border(S str)
909✔
646
{
647
    return std::make_pair(std::move(str),
909✔
648
                          VC_ROLE.value(role_t::VCR_TABLE_BORDER));
1,818✔
649
}
650

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

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

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

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

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

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

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

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

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

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

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

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

741
namespace literals {
742

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

749
constexpr std::pair<string_fragment, role_t> operator"" _error(const char* str,
230✔
750
                                                               std::size_t len)
751
{
752
    return std::make_pair(string_fragment{str, 0, (int) len},
230✔
753
                          role_t::VCR_ERROR);
460✔
754
}
755

756
constexpr std::pair<string_fragment, role_t> operator"" _warning(
32✔
757
    const char* str, std::size_t len)
758
{
759
    return std::make_pair(string_fragment{str, 0, (int) len},
32✔
760
                          role_t::VCR_WARNING);
64✔
761
}
762

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

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

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

783
constexpr std::pair<string_fragment, role_t> operator"" _symbol(const char* str,
47✔
784
                                                                std::size_t len)
785
{
786
    return std::make_pair(string_fragment{str, 0, (int) len},
47✔
787
                          role_t::VCR_SYMBOL);
94✔
788
}
789

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

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

804
constexpr std::pair<string_fragment, role_t> operator"" _comment(
66✔
805
    const char* str, std::size_t len)
806
{
807
    return std::make_pair(string_fragment{str, 0, (int) len},
66✔
808
                          role_t::VCR_COMMENT);
132✔
809
}
810

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

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

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

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

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

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

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

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

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

868
constexpr std::pair<string_fragment, role_t> operator"" _breadcrumb(
57✔
869
    const char* str, std::size_t len)
870
{
871
    return std::make_pair(string_fragment{str, 0, (int) len},
57✔
872
                          role_t::VCR_BREADCRUMB);
114✔
873
}
874

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

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

889
constexpr std::pair<string_fragment, role_t> operator"" _table_header(
68✔
890
    const char* str, std::size_t len)
891
{
892
    return std::make_pair(string_fragment{str, 0, (int) len},
68✔
893
                          role_t::VCR_TABLE_HEADER);
136✔
894
}
895

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

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

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

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

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

931
constexpr std::pair<string_fragment, role_t> operator"" _snippet_border(
2,032✔
932
    const char* str, std::size_t len)
933
{
934
    return std::make_pair(string_fragment{str, 0, (int) len},
2,032✔
935
                          role_t::VCR_SNIPPET_BORDER);
4,064✔
936
}
937

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

945
}  // namespace literals
946

947
}  // namespace roles
948
}  // namespace lnav
949

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