[themes] add dracula theme

Various improvements to styling.

Empty opids are not valid.
pull/1161/merge
Tim Stack 10 months ago
parent 02e801cf6a
commit 5c0333fd64

@ -73,6 +73,15 @@ Features:
`dashed` and `dotted` line styles and colors. `dashed` and `dotted` line styles and colors.
* Added an `options` column to the `lnav_views` table * Added an `options` column to the `lnav_views` table
to allow more control over overlays. to allow more control over overlays.
* Added a "Dracula" theme as described at:
https://draculatheme.com
* Added the following styles for themes:
- `/ui/theme-defs/<theme_name>/syntax-styles/inline-code`
- `/ui/theme-defs/<theme_name>/syntax-styles/type`
- `/ui/theme-defs/<theme_name>/syntax-styles/function`
- `/ui/theme-defs/<theme_name>/syntax-styles/separators-references-accessors`
* Multi-line block comments (i.e. `/* ... */`) and strings
are now recognized and styled as appropriate.
Bug Fixes: Bug Fixes:
* Binary data piped into stdin should now be treated the same * Binary data piped into stdin should now be treated the same

@ -478,6 +478,11 @@
"title": "/ui/theme-defs/<theme_name>/syntax-styles", "title": "/ui/theme-defs/<theme_name>/syntax-styles",
"type": "object", "type": "object",
"properties": { "properties": {
"inline-code": {
"description": "Styling for inline code blocks",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/inline-code",
"$ref": "#/definitions/style"
},
"quoted-code": { "quoted-code": {
"description": "Styling for quoted code blocks", "description": "Styling for quoted code blocks",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/quoted-code", "title": "/ui/theme-defs/<theme_name>/syntax-styles/quoted-code",
@ -523,6 +528,21 @@
"title": "/ui/theme-defs/<theme_name>/syntax-styles/number", "title": "/ui/theme-defs/<theme_name>/syntax-styles/number",
"$ref": "#/definitions/style" "$ref": "#/definitions/style"
}, },
"type": {
"description": "Styling for types in source files",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/type",
"$ref": "#/definitions/style"
},
"function": {
"description": "Styling for functions in source files",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/function",
"$ref": "#/definitions/style"
},
"separators-references-accessors": {
"description": "Styling for sigils in source files",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/separators-references-accessors",
"$ref": "#/definitions/style"
},
"re-special": { "re-special": {
"description": "Styling for special characters in regular expressions", "description": "Styling for special characters in regular expressions",
"title": "/ui/theme-defs/<theme_name>/syntax-styles/re-special", "title": "/ui/theme-defs/<theme_name>/syntax-styles/re-special",

@ -45,7 +45,7 @@ nonstd::optional<
std::reference_wrapper<std::conditional_t<std::is_const<C>::value, std::reference_wrapper<std::conditional_t<std::is_const<C>::value,
const typename C::mapped_type, const typename C::mapped_type,
typename C::mapped_type>>> typename C::mapped_type>>>
find(C& container, typename C::key_type& key) find(C& container, const typename C::key_type& key)
{ {
auto iter = container.find(key); auto iter = container.find(key);
if (iter != container.end()) { if (iter != container.end()) {

@ -126,6 +126,10 @@ enum class role_t : int32_t {
VCR_FOOTNOTE_BORDER, VCR_FOOTNOTE_BORDER,
VCR_FOOTNOTE_TEXT, VCR_FOOTNOTE_TEXT,
VCR_SNIPPET_BORDER, VCR_SNIPPET_BORDER,
VCR_INLINE_CODE,
VCR_FUNCTION,
VCR_TYPE,
VCR_SEP_REF_ACC,
VCR__MAX VCR__MAX
}; };

@ -47,6 +47,9 @@ static struct {
{ {
"quot", "quot",
}, },
{
"comm",
},
{ {
"url", "url",
}, },

@ -34,11 +34,13 @@
#include "pcrepp/pcre2pp.hh" #include "pcrepp/pcre2pp.hh"
#include "shared_buffer.hh" #include "shared_buffer.hh"
#include "text_format.hh"
enum data_token_t { enum data_token_t {
DT_INVALID = -1, DT_INVALID = -1,
DT_QUOTED_STRING = 0, DT_QUOTED_STRING = 0,
DT_COMMENT,
DT_URL, DT_URL,
DT_PATH, DT_PATH,
DT_MAC_ADDRESS, DT_MAC_ADDRESS,
@ -178,6 +180,13 @@ public:
capture_t tr_inner_capture; capture_t tr_inner_capture;
const char* tr_data{nullptr}; const char* tr_data{nullptr};
string_fragment to_string_fragment() const
{
return string_fragment::from_byte_range(this->tr_data,
this->tr_capture.c_begin,
this->tr_capture.c_end);
}
std::string to_string() const std::string to_string() const
{ {
return {&this->tr_data[this->tr_capture.c_begin], return {&this->tr_data[this->tr_capture.c_begin],
@ -185,7 +194,8 @@ public:
} }
}; };
nonstd::optional<tokenize_result> tokenize2(); nonstd::optional<tokenize_result> tokenize2(text_format_t tf
= text_format_t::TF_UNKNOWN);
void reset() { this->ds_next_offset = this->ds_init_offset; } void reset() { this->ds_next_offset = this->ds_init_offset; }

File diff suppressed because it is too large Load Diff

@ -35,7 +35,7 @@
#include "config.h" #include "config.h"
#include "data_scanner.hh" #include "data_scanner.hh"
nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2() nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2(text_format_t tf)
{ {
data_token_t token_out = DT_INVALID; data_token_t token_out = DT_INVALID;
capture_t cap_all; capture_t cap_all;
@ -152,11 +152,34 @@ nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2()
cap_inner.c_end -= 1; cap_inner.c_end -= 1;
return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()}; return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()};
} }
("u"|"r")?'"""'[^\x00\x1b]*'"""' {
CAPTURE(DT_QUOTED_STRING);
switch (this->ds_input[cap_inner.c_begin]) {
case 'u':
case 'r':
cap_inner.c_begin += 1;
break;
}
cap_inner.c_begin += 1;
cap_inner.c_end -= 1;
return tokenize_result{token_out, cap_all, cap_inner, this->ds_input.data()};
}
"/" "*" ([^\x00*]|"*"+[^\x00/])* "*"+ "/" {
RET(DT_COMMENT);
}
[a-qstv-zA-QSTV-Z]"'" { [a-qstv-zA-QSTV-Z]"'" {
CAPTURE(DT_WORD); CAPTURE(DT_WORD);
} }
("u"|"r")?"'"('\\'.|"''"|[^\x00\x1b'\\])*"'"/[^sS] { ("u"|"r")?"'"('\\'.|"''"|[^\x00\x1b'\\])*"'"/[^sS] {
CAPTURE(DT_QUOTED_STRING); CAPTURE(DT_QUOTED_STRING);
if (tf == text_format_t::TF_RUST) {
auto sf = this->to_string_fragment(cap_all);
auto split_res = sf.split_when([](char ch) { return ch != '\'' && !isalnum(ch); });
cap_all.c_end = split_res.first.sf_end;
cap_inner.c_end = split_res.first.sf_end;
this->ds_next_offset = cap_all.c_end;
return tokenize_result{DT_SYMBOL, cap_all, cap_inner, this->ds_input.data()};
}
switch (this->ds_input[cap_inner.c_begin]) { switch (this->ds_input[cap_inner.c_begin]) {
case 'u': case 'u':
case 'r': case 'r':

@ -83,6 +83,7 @@ hier_node::lookup_path(const hier_node* root,
struct metadata_builder { struct metadata_builder {
std::vector<section_interval_t> mb_intervals; std::vector<section_interval_t> mb_intervals;
std::vector<section_type_interval_t> mb_type_intervals;
std::unique_ptr<hier_node> mb_root_node; std::unique_ptr<hier_node> mb_root_node;
metadata to_metadata() && metadata to_metadata() &&
@ -90,6 +91,7 @@ struct metadata_builder {
return { return {
std::move(this->mb_intervals), std::move(this->mb_intervals),
std::move(this->mb_root_node), std::move(this->mb_root_node),
std::move(this->mb_type_intervals),
}; };
} }
}; };
@ -239,8 +241,8 @@ discover_metadata(const attr_line_t& al)
class structure_walker { class structure_walker {
public: public:
explicit structure_walker(attr_line_t& al, line_range lr) explicit structure_walker(attr_line_t& al, line_range lr, text_format_t tf)
: sw_line(al), sw_range(lr), : sw_line(al), sw_range(lr), sw_text_format(tf),
sw_scanner(string_fragment::from_str_range( sw_scanner(string_fragment::from_str_range(
al.get_string(), lr.lr_start, lr.lr_end)) al.get_string(), lr.lr_start, lr.lr_end))
{ {
@ -254,7 +256,8 @@ public:
size_t garbage_count = 0; size_t garbage_count = 0;
while (garbage_count < 1000) { while (garbage_count < 1000) {
auto tokenize_res = this->sw_scanner.tokenize2(); auto tokenize_res
= this->sw_scanner.tokenize2(this->sw_text_format);
if (!tokenize_res) { if (!tokenize_res) {
break; break;
} }
@ -262,11 +265,22 @@ public:
auto dt = tokenize_res->tr_token; auto dt = tokenize_res->tr_token;
element el(tokenize_res->tr_token, tokenize_res->tr_capture); element el(tokenize_res->tr_token, tokenize_res->tr_capture);
#if 0
log_debug("tok %s %s",
data_scanner::token2name(dt),
tokenize_res->to_string().c_str());
#endif
switch (dt) { switch (dt) {
case DT_XML_DECL_TAG: case DT_XML_DECL_TAG:
case DT_XML_EMPTY_TAG: case DT_XML_EMPTY_TAG:
this->sw_values.emplace_back(el); this->sw_values.emplace_back(el);
break; break;
case DT_COMMENT:
this->sw_type_intervals.emplace_back(
el.e_capture.c_begin,
el.e_capture.c_end,
section_types_t::comment);
break;
case DT_XML_OPEN_TAG: case DT_XML_OPEN_TAG:
this->flush_values(); this->flush_values();
this->sw_interval_state.back().is_start this->sw_interval_state.back().is_start
@ -373,6 +387,16 @@ public:
if (dt == DT_GARBAGE) { if (dt == DT_GARBAGE) {
garbage_count += 1; garbage_count += 1;
} }
if (dt == DT_QUOTED_STRING) {
auto quoted_sf = tokenize_res->to_string_fragment();
if (quoted_sf.find('\n')) {
this->sw_type_intervals.emplace_back(
el.e_capture.c_begin,
el.e_capture.c_end,
section_types_t::multiline_string);
}
}
this->sw_values.emplace_back(el); this->sw_values.emplace_back(el);
break; break;
} }
@ -396,6 +420,7 @@ public:
mb.mb_root_node = std::move(this->sw_hier_stage); mb.mb_root_node = std::move(this->sw_hier_stage);
mb.mb_intervals = std::move(this->sw_intervals); mb.mb_intervals = std::move(this->sw_intervals);
mb.mb_type_intervals = std::move(this->sw_type_intervals);
discover_metadata_int(this->sw_line, mb); discover_metadata_int(this->sw_line, mb);
@ -506,20 +531,22 @@ private:
attr_line_t& sw_line; attr_line_t& sw_line;
line_range sw_range; line_range sw_range;
text_format_t sw_text_format;
data_scanner sw_scanner; data_scanner sw_scanner;
int sw_depth{0}; int sw_depth{0};
size_t sw_line_number{0}; size_t sw_line_number{0};
std::vector<element> sw_values{}; std::vector<element> sw_values{};
std::vector<interval_state> sw_interval_state; std::vector<interval_state> sw_interval_state;
std::vector<lnav::document::section_interval_t> sw_intervals; std::vector<lnav::document::section_interval_t> sw_intervals;
std::vector<lnav::document::section_type_interval_t> sw_type_intervals;
std::vector<std::unique_ptr<lnav::document::hier_node>> sw_hier_nodes; std::vector<std::unique_ptr<lnav::document::hier_node>> sw_hier_nodes;
std::unique_ptr<lnav::document::hier_node> sw_hier_stage; std::unique_ptr<lnav::document::hier_node> sw_hier_stage;
}; };
metadata metadata
discover_structure(attr_line_t& al, struct line_range lr) discover_structure(attr_line_t& al, struct line_range lr, text_format_t tf)
{ {
return structure_walker(al, lr).walk(); return structure_walker(al, lr, tf).walk();
} }
std::vector<breadcrumb::possibility> std::vector<breadcrumb::possibility>

@ -40,6 +40,7 @@
#include "intervaltree/IntervalTree.h" #include "intervaltree/IntervalTree.h"
#include "mapbox/variant.hpp" #include "mapbox/variant.hpp"
#include "optional.hpp" #include "optional.hpp"
#include "text_format.hh"
namespace lnav { namespace lnav {
namespace document { namespace document {
@ -48,6 +49,16 @@ using section_key_t = mapbox::util::variant<std::string, size_t>;
using section_interval_t = interval_tree::Interval<file_off_t, section_key_t>; using section_interval_t = interval_tree::Interval<file_off_t, section_key_t>;
using sections_tree_t = interval_tree::IntervalTree<file_off_t, section_key_t>; using sections_tree_t = interval_tree::IntervalTree<file_off_t, section_key_t>;
enum class section_types_t {
comment,
multiline_string,
};
using section_type_interval_t
= interval_tree::Interval<file_off_t, section_types_t>;
using section_types_tree_t
= interval_tree::IntervalTree<file_off_t, section_types_t>;
struct hier_node { struct hier_node {
hier_node* hn_parent{nullptr}; hier_node* hn_parent{nullptr};
file_off_t hn_start{0}; file_off_t hn_start{0};
@ -101,6 +112,7 @@ struct hier_node {
struct metadata { struct metadata {
sections_tree_t m_sections_tree; sections_tree_t m_sections_tree;
std::unique_ptr<hier_node> m_sections_root; std::unique_ptr<hier_node> m_sections_root;
section_types_tree_t m_section_types_tree;
std::vector<breadcrumb::possibility> possibility_provider( std::vector<breadcrumb::possibility> possibility_provider(
const std::vector<section_key_t>& path); const std::vector<section_key_t>& path);
@ -108,7 +120,9 @@ struct metadata {
metadata discover_metadata(const attr_line_t& al); metadata discover_metadata(const attr_line_t& al);
metadata discover_structure(attr_line_t& al, struct line_range lr); metadata discover_structure(attr_line_t& al,
struct line_range lr,
text_format_t tf = text_format_t::TF_UNKNOWN);
} // namespace document } // namespace document
} // namespace lnav } // namespace lnav

@ -765,6 +765,10 @@ static const struct json_path_container theme_styles_handlers = {
}; };
static const struct json_path_container theme_syntax_styles_handlers = { static const struct json_path_container theme_syntax_styles_handlers = {
yajlpp::property_handler("inline-code")
.with_description("Styling for inline code blocks")
.for_child(&lnav_theme::lt_style_inline_code)
.with_children(style_config_handlers),
yajlpp::property_handler("quoted-code") yajlpp::property_handler("quoted-code")
.with_description("Styling for quoted code blocks") .with_description("Styling for quoted code blocks")
.for_child(&lnav_theme::lt_style_quoted_code) .for_child(&lnav_theme::lt_style_quoted_code)
@ -802,6 +806,18 @@ static const struct json_path_container theme_syntax_styles_handlers = {
.with_description("Styling for numbers in source files") .with_description("Styling for numbers in source files")
.for_child(&lnav_theme::lt_style_number) .for_child(&lnav_theme::lt_style_number)
.with_children(style_config_handlers), .with_children(style_config_handlers),
yajlpp::property_handler("type")
.with_description("Styling for types in source files")
.for_child(&lnav_theme::lt_style_type)
.with_children(style_config_handlers),
yajlpp::property_handler("function")
.with_description("Styling for functions in source files")
.for_child(&lnav_theme::lt_style_function)
.with_children(style_config_handlers),
yajlpp::property_handler("separators-references-accessors")
.with_description("Styling for sigils in source files")
.for_child(&lnav_theme::lt_style_sep_ref_acc)
.with_children(style_config_handlers),
yajlpp::property_handler("re-special") yajlpp::property_handler("re-special")
.with_description( .with_description(
"Styling for special characters in regular expressions") "Styling for special characters in regular expressions")

@ -1601,7 +1601,7 @@ external_log_format::annotate(uint64_t line_number,
} }
auto opid_cap = md[pat.p_opid_field_index]; auto opid_cap = md[pat.p_opid_field_index];
if (opid_cap) { if (opid_cap && !opid_cap->empty()) {
sa.emplace_back(to_line_range(opid_cap.value()), sa.emplace_back(to_line_range(opid_cap.value()),
logline::L_OPID.value()); logline::L_OPID.value());
} }
@ -2070,7 +2070,8 @@ external_log_format::get_subline(const logline& ll,
this->jlf_line_attrs.emplace_back( this->jlf_line_attrs.emplace_back(
lr, SA_BODY.value()); lr, SA_BODY.value());
} else if (lv_iter->lv_meta.lvm_name } else if (lv_iter->lv_meta.lvm_name
== this->elf_opid_field) == this->elf_opid_field
&& !lr.empty())
{ {
this->jlf_line_attrs.emplace_back( this->jlf_line_attrs.emplace_back(
lr, logline::L_OPID.value()); lr, logline::L_OPID.value());
@ -2230,7 +2231,9 @@ external_log_format::get_subline(const logline& ll,
} }
} }
lv.lv_origin.lr_end = this->jlf_cached_line.size() - 1; lv.lv_origin.lr_end = this->jlf_cached_line.size() - 1;
if (lv.lv_meta.lvm_name == this->elf_opid_field) { if (lv.lv_meta.lvm_name == this->elf_opid_field
&& !lv.lv_origin.empty())
{
this->jlf_line_attrs.emplace_back(lv.lv_origin, this->jlf_line_attrs.emplace_back(lv.lv_origin,
logline::L_OPID.value()); logline::L_OPID.value());
} }

@ -1,4 +1,3 @@
/** /**
* Copyright (c) 2007-2012, Timothy Stack * Copyright (c) 2007-2012, Timothy Stack
* *

@ -438,7 +438,7 @@ md2attr_line::leave_span(const md4cpp::event_handler::span& sp)
}; };
last_block.with_attr({ last_block.with_attr({
lr, lr,
VC_ROLE.value(role_t::VCR_QUOTED_CODE), VC_ROLE.value(role_t::VCR_INLINE_CODE),
}); });
last_block.with_attr({ last_block.with_attr({
lr, lr,

@ -256,7 +256,14 @@ public:
template<typename T, std::size_t N> template<typename T, std::size_t N>
static code from_const(const T (&str)[N], int options = 0) static code from_const(const T (&str)[N], int options = 0)
{ {
return from(string_fragment::from_const(str), options).unwrap(); auto res = from(string_fragment::from_const(str), options);
if (res.isErr()) {
fprintf(stderr, "failed to compile constant regex: %s\n", str);
fprintf(stderr, " %s\n", res.unwrapErr().get_message().c_str());
}
return res.unwrap();
} }
const std::string& get_pattern() const { return this->p_pattern; } const std::string& get_pattern() const { return this->p_pattern; }

@ -186,6 +186,7 @@ struct lnav_theme {
positioned_property<style_config> lt_style_status_subtitle; positioned_property<style_config> lt_style_status_subtitle;
positioned_property<style_config> lt_style_status_info; positioned_property<style_config> lt_style_status_info;
positioned_property<style_config> lt_style_status_hotkey; positioned_property<style_config> lt_style_status_hotkey;
positioned_property<style_config> lt_style_inline_code;
positioned_property<style_config> lt_style_quoted_code; positioned_property<style_config> lt_style_quoted_code;
positioned_property<style_config> lt_style_code_border; positioned_property<style_config> lt_style_code_border;
positioned_property<style_config> lt_style_keyword; positioned_property<style_config> lt_style_keyword;
@ -195,6 +196,9 @@ struct lnav_theme {
positioned_property<style_config> lt_style_variable; positioned_property<style_config> lt_style_variable;
positioned_property<style_config> lt_style_symbol; positioned_property<style_config> lt_style_symbol;
positioned_property<style_config> lt_style_number; positioned_property<style_config> lt_style_number;
positioned_property<style_config> lt_style_function;
positioned_property<style_config> lt_style_type;
positioned_property<style_config> lt_style_sep_ref_acc;
positioned_property<style_config> lt_style_re_special; positioned_property<style_config> lt_style_re_special;
positioned_property<style_config> lt_style_re_repeat; positioned_property<style_config> lt_style_re_repeat;
positioned_property<style_config> lt_style_diff_delete; positioned_property<style_config> lt_style_diff_delete;

@ -48,6 +48,22 @@ detect_text_format(string_fragment sf,
".xz", ".xz",
".zst", ".zst",
}; };
static const auto C_EXTS = std::set<ghc::filesystem::path>{
".h",
".hh",
".hpp",
".c",
".cc",
".cpp",
".tpp",
};
static const auto PY_EXT = ghc::filesystem::path(".py");
static const auto RS_EXT = ghc::filesystem::path(".rs");
static const auto JAVA_EXT = ghc::filesystem::path(".java");
static const auto TOML_EXT = ghc::filesystem::path(".toml");
static const auto XML_EXT = ghc::filesystem::path(".xml");
static const auto YAML_EXT = ghc::filesystem::path(".yaml");
static const auto YML_EXT = ghc::filesystem::path(".yml");
static const auto MD_EXT = ghc::filesystem::path(".md"); static const auto MD_EXT = ghc::filesystem::path(".md");
static const auto MARKDOWN_EXT = ghc::filesystem::path(".markdown"); static const auto MARKDOWN_EXT = ghc::filesystem::path(".markdown");
@ -66,7 +82,7 @@ detect_text_format(string_fragment sf,
= lnav::pcre2pp::code::from_const(R"( = lnav::pcre2pp::code::from_const(R"(
(?: (?:
^\s*use\s+[\w+:\{\}]+;$| ^\s*use\s+[\w+:\{\}]+;$|
^\s*(?:pub)?\s+(?:const|enum|fn)\s+\w+.*$| ^\s*(?:pub enum|pub const|(?:pub )?fn)\s+\w+.*$|
^\s*impl\s+\w+.*$ ^\s*impl\s+\w+.*$
) )
)", )",
@ -103,16 +119,43 @@ detect_text_format(string_fragment sf,
")", ")",
PCRE2_MULTILINE | PCRE2_CASELESS); PCRE2_MULTILINE | PCRE2_CASELESS);
text_format_t retval = text_format_t::TF_UNKNOWN;
if (path) { if (path) {
while (FILTER_EXTS.count(path->extension()) > 0) { while (FILTER_EXTS.count(path->extension()) > 0) {
path = path->stem(); path = path->stem();
} }
if (path->extension() == MD_EXT || path->extension() == MARKDOWN_EXT) { auto ext = path->extension();
if (ext == MD_EXT || ext == MARKDOWN_EXT) {
return text_format_t::TF_MARKDOWN; return text_format_t::TF_MARKDOWN;
} }
if (C_EXTS.count(ext) > 0) {
return text_format_t::TF_C_LIKE;
}
if (ext == PY_EXT) {
return text_format_t::TF_PYTHON;
}
if (ext == RS_EXT) {
return text_format_t::TF_RUST;
}
if (ext == TOML_EXT) {
return text_format_t::TF_TOML;
}
if (ext == JAVA_EXT) {
return text_format_t::TF_JAVA;
}
if (ext == YAML_EXT || ext == YML_EXT) {
return text_format_t::TF_YAML;
}
if (ext == XML_EXT) {
return text_format_t::TF_XML;
}
} }
{ {
@ -152,5 +195,5 @@ detect_text_format(string_fragment sf,
return text_format_t::TF_XML; return text_format_t::TF_XML;
} }
return retval; return text_format_t::TF_UNKNOWN;
} }

@ -93,6 +93,7 @@ setup_highlights(highlight_map_t& hm)
"\\bconst\\b|" "\\bconst\\b|"
"\\bcontinue\\b|" "\\bcontinue\\b|"
"\\bcrate\\b|" "\\bcrate\\b|"
"\\bdyn\\b|"
"\\belse\\b|" "\\belse\\b|"
"\\bif\\b|" "\\bif\\b|"
"\\bif let\\b|" "\\bif let\\b|"
@ -397,6 +398,14 @@ setup_highlights(highlight_map_t& hm)
hm[{highlight_source_t::INTERNAL, "1.strings"}] hm[{highlight_source_t::INTERNAL, "1.strings"}]
= highlighter(xpcre_compile(R"((?<![A-WY-Za-qstv-z])'(?:\\.|[^'])*')")) = highlighter(xpcre_compile(R"((?<![A-WY-Za-qstv-z])'(?:\\.|[^'])*')"))
.with_nestable(false) .with_nestable(false)
.with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA)
.with_text_format(text_format_t::TF_MARKDOWN)
.with_text_format(text_format_t::TF_PYTHON)
.with_text_format(text_format_t::TF_SQL)
.with_text_format(text_format_t::TF_XML)
.with_text_format(text_format_t::TF_YAML)
.with_text_format(text_format_t::TF_TOML)
.with_role(role_t::VCR_STRING); .with_role(role_t::VCR_STRING);
hm[{highlight_source_t::INTERNAL, "1.stringb"}] hm[{highlight_source_t::INTERNAL, "1.stringb"}]
= highlighter(xpcre_compile("`(?:\\\\.|[^`])*`")) = highlighter(xpcre_compile("`(?:\\\\.|[^`])*`"))
@ -461,4 +470,33 @@ setup_highlights(highlight_map_t& hm)
.with_text_format(text_format_t::TF_C_LIKE) .with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA) .with_text_format(text_format_t::TF_JAVA)
.with_role(role_t::VCR_NUMBER); .with_role(role_t::VCR_NUMBER);
hm[{highlight_source_t::INTERNAL, "fun"}]
= highlighter(xpcre_compile(R"((\w+)\()"))
.with_nestable(false)
.with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA)
.with_text_format(text_format_t::TF_PYTHON)
.with_text_format(text_format_t::TF_RUST)
.with_text_format(text_format_t::TF_SQL)
.with_role(role_t::VCR_FUNCTION);
hm[{highlight_source_t::INTERNAL, "sep"}]
= highlighter(xpcre_compile(R"(\.|\s+&(?=\w)|(?<=\w)&\s+|::|\%\b)"))
.with_nestable(false)
.with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA)
.with_text_format(text_format_t::TF_PYTHON)
.with_text_format(text_format_t::TF_RUST)
.with_text_format(text_format_t::TF_SQL)
.with_role(role_t::VCR_SEP_REF_ACC);
hm[{highlight_source_t::INTERNAL, "type"}]
= highlighter(
xpcre_compile(
R"(\b(class|struct|enum(?:\s+class)?)\s+(\w+)\b|\b(\w+_t)\b)"))
.with_nestable(false)
.with_text_format(text_format_t::TF_C_LIKE)
.with_text_format(text_format_t::TF_JAVA)
.with_text_format(text_format_t::TF_PYTHON)
.with_text_format(text_format_t::TF_RUST)
.with_text_format(text_format_t::TF_SQL)
.with_role(role_t::VCR_TYPE);
} }

@ -33,6 +33,7 @@
#include "base/fs_util.hh" #include "base/fs_util.hh"
#include "base/injector.hh" #include "base/injector.hh"
#include "base/itertools.hh" #include "base/itertools.hh"
#include "base/map_util.hh"
#include "bound_tags.hh" #include "bound_tags.hh"
#include "config.h" #include "config.h"
#include "lnav.events.hh" #include "lnav.events.hh"
@ -70,7 +71,7 @@ textfile_sub_source::text_value_for_line(textview_curses& tc,
text_sub_source::line_flags_t flags) text_sub_source::line_flags_t flags)
{ {
if (!this->tss_files.empty()) { if (!this->tss_files.empty()) {
std::shared_ptr<logfile> lf = this->current_file(); const auto lf = this->current_file();
auto rend_iter = this->tss_rendered_files.find(lf->get_filename()); auto rend_iter = this->tss_rendered_files.find(lf->get_filename());
if (rend_iter == this->tss_rendered_files.end()) { if (rend_iter == this->tss_rendered_files.end()) {
auto* lfo = dynamic_cast<line_filter_observer*>( auto* lfo = dynamic_cast<line_filter_observer*>(
@ -159,6 +160,41 @@ textfile_sub_source::text_attrs_for_line(textview_curses& tc,
VC_ROLE.value(bar_role)); VC_ROLE.value(bar_role));
} }
} }
auto meta_opt
= lnav::map::find(this->tss_doc_metadata, lf->get_filename());
if (meta_opt) {
auto ll_next_iter = ll + 1;
auto end_offset = (ll_next_iter == lf->end())
? lf->get_index_size() - 1
: ll_next_iter->get_offset() - 1;
meta_opt->get()
.ms_metadata.m_section_types_tree.visit_overlapping(
ll->get_offset(),
end_offset,
[&value_out, &ll, end_offset](const auto& iv) {
auto lr = line_range{0, -1};
if (iv.start > ll->get_offset()) {
lr.lr_start = iv.start - ll->get_offset();
}
if (iv.stop < end_offset) {
lr.lr_end = iv.stop - ll->get_offset();
} else {
lr.lr_end = end_offset - ll->get_offset();
}
auto role = role_t::VCR_NONE;
switch (iv.value) {
case lnav::document::section_types_t::comment:
role = role_t::VCR_COMMENT;
break;
case lnav::document::section_types_t::
multiline_string:
role = role_t::VCR_STRING;
break;
}
value_out.emplace_back(lr, VC_ROLE.value(role));
});
}
} }
} }
@ -742,7 +778,9 @@ textfile_sub_source::rescan_files(
st.st_mtime, st.st_mtime,
static_cast<file_ssize_t>(st.st_size), static_cast<file_ssize_t>(st.st_size),
lnav::document::discover_structure( lnav::document::discover_structure(
content, line_range{0, -1}), content,
line_range{0, -1},
lf->get_text_format()),
}; };
} else { } else {
log_error( log_error(

@ -0,0 +1,290 @@
{
"$schema": "https://lnav.org/schemas/config-v1.schema.json",
"ui": {
"theme-defs": {
"dracula": {
"vars": {
"black": "#282A36",
"red": "#FF5555",
"green": "#50FA7B",
"yellow": "#F1FA8C",
"blue": "#BD93F9",
"magenta": "#FF79C6",
"cyan": "#8BE9FD",
"white": "#F8F8F2",
"orange": "#FFB86C",
"purple": "#BD93F9",
"pink": "#FF79C6",
"semantic_highlight_color": "semantic()"
},
"styles": {
"identifier": {
"color": "semantic()"
},
"text": {
"color": "#f6f6f6",
"background-color": "$black"
},
"alt-text": {
"background-color": "#1c1c1c"
},
"ok": {
"color": "$green",
"bold": true
},
"info": {
"color": "$magenta",
"bold": true
},
"error": {
"color": "$red",
"bold": true
},
"warning": {
"color": "$yellow",
"bold": true
},
"hidden": {
"color": "$yellow",
"bold": true
},
"cursor-line": {
"color": "$cyan",
"background-color": "#44475A",
"bold": true
},
"disabled-cursor-line": {
"color": "$cyan",
"background-color": "#2a2c38"
},
"adjusted-time": {
"color": "$magenta"
},
"skewed-time": {
"color": "$yellow"
},
"offset-time": {
"color": "$cyan"
},
"invalid-msg": {
"color": "$yellow"
},
"focused": {
"color": "$black",
"background-color": "$white"
},
"disabled-focused": {
"color": "$white",
"background-color": "#333"
},
"popup": {
"color": "$black",
"background-color": "$cyan"
},
"scrollbar": {
"color": "$black",
"background-color": "#888"
},
"h1": {
"color": "$purple",
"bold": true
},
"h2": {
"color": "$purple",
"underline": true
},
"h3": {
"color": "$purple"
},
"h4": {
"underline": true
},
"h5": {
"underline": true
},
"h6": {
"underline": true
},
"hr": {
"color": "#6272A4"
},
"hyperlink": {
"underline": true
},
"list-glyph": {
"color": "$cyan"
},
"breadcrumb": {
"color": "#99a"
},
"table-border": {
"color": "#444"
},
"table-header": {
"bold": true
},
"quote-border": {
"color": "#666",
"background-color": "#444"
},
"quoted-text": {
"color": "$yellow",
"background-color": "#444"
},
"footnote-border": {
"color": "$blue",
"background-color": "#444"
},
"footnote-text": {
"color": "$cyan",
"background-color": "#444"
},
"snippet-border": {
"color": "$cyan"
}
},
"syntax-styles": {
"inline-code": {
"color": "$green",
"background-color": "#121212"
},
"quoted-code": {
"color": "$orange",
"background-color": "#121212"
},
"code-border": {
"color": "#444",
"background-color": "#121212"
},
"keyword": {
"color": "$pink",
"bold": true
},
"string": {
"color": "$yellow",
"bold": true
},
"comment": {
"color": "#6272A4"
},
"doc-directive": {
"color": "$pink"
},
"variable": {
"color": "$orange"
},
"symbol": {
"color": "#78dce8"
},
"re-special": {
"color": "$cyan"
},
"re-repeat": {
"color": "$yellow"
},
"diff-delete": {
"color": "#f00"
},
"diff-add": {
"color": "#0f0"
},
"diff-section": {
"color": "#6272A4"
},
"spectrogram-low": {
"background-color": "$green"
},
"spectrogram-medium": {
"background-color": "$yellow"
},
"spectrogram-high": {
"background-color": "$red"
},
"file": {
"color": "$blue"
},
"number": {
"bold": true
},
"function": {
"color": "$green"
},
"separators-references-accessors": {
"color": "$pink"
},
"type": {
"color": "$cyan"
}
},
"status-styles": {
"disabled-title": {
"color": "#5394ec",
"background-color": "#353535",
"bold": true
},
"title": {
"color": "#f6f6f6",
"background-color": "#5394ec",
"bold": true
},
"subtitle": {
"color": "#555",
"background-color": "#66d9ee",
"bold": true
},
"info": {
"color": "#aaa",
"background-color": "#2f2f2f"
},
"title-hotkey": {
"color": "$black",
"background-color": "#5394ec",
"underline": true
},
"hotkey": {
"color": "#fff",
"underline": true
},
"text": {
"color": "#f6f6f6",
"background-color": "#353535"
},
"warn": {
"color": "$yellow",
"background-color": "#353535"
},
"alert": {
"color": "$red",
"background-color": "#353535"
},
"active": {
"color": "$green",
"background-color": "#353535"
},
"inactive": {
"color": "#555",
"background-color": "#2f2f2f"
},
"inactive-alert": {
"color": "$red",
"background-color": "#2f2f2f"
}
},
"log-level-styles": {
"warning": {
"color": "$yellow"
},
"error": {
"color": "$red"
},
"critical": {
"color": "$red"
},
"fatal": {
"color": "$red"
}
}
}
}
}
}

@ -140,6 +140,10 @@
} }
}, },
"syntax-styles": { "syntax-styles": {
"inline-code": {
"color": "$red",
"background-color": "#121212"
},
"quoted-code": { "quoted-code": {
"color": "#eee", "color": "#eee",
"background-color": "#121212" "background-color": "#121212"
@ -197,6 +201,15 @@
}, },
"number": { "number": {
"bold": true "bold": true
},
"function": {
"color": "$cyan"
},
"separators-references-accessors": {
"color": "$red"
},
"type": {
"color": "$blue"
} }
}, },
"status-styles": { "status-styles": {

@ -1,6 +1,7 @@
THEME_FILES = \ THEME_FILES = \
$(srcdir)/%reldir%/default-theme.json \ $(srcdir)/%reldir%/default-theme.json \
$(srcdir)/%reldir%/dracula.json \
$(srcdir)/%reldir%/eldar.json \ $(srcdir)/%reldir%/eldar.json \
$(srcdir)/%reldir%/grayscale.json \ $(srcdir)/%reldir%/grayscale.json \
$(srcdir)/%reldir%/monocai.json \ $(srcdir)/%reldir%/monocai.json \

@ -944,6 +944,8 @@ view_colors::init_roles(const lnav_theme& lt,
= this->to_attrs(lt, bar_sc, reporter); = this->to_attrs(lt, bar_sc, reporter);
} }
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_INLINE_CODE)]
= this->to_attrs(lt, lt.lt_style_inline_code, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_QUOTED_CODE)] this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_QUOTED_CODE)]
= this->to_attrs(lt, lt.lt_style_quoted_code, reporter); = this->to_attrs(lt, lt.lt_style_quoted_code, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_CODE_BORDER)] this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_CODE_BORDER)]
@ -962,6 +964,12 @@ view_colors::init_roles(const lnav_theme& lt,
= this->to_attrs(lt, lt.lt_style_symbol, reporter); = this->to_attrs(lt, lt.lt_style_symbol, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_NUMBER)] this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_NUMBER)]
= this->to_attrs(lt, lt.lt_style_number, reporter); = this->to_attrs(lt, lt.lt_style_number, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_FUNCTION)]
= this->to_attrs(lt, lt.lt_style_function, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_TYPE)]
= this->to_attrs(lt, lt.lt_style_type, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_SEP_REF_ACC)]
= this->to_attrs(lt, lt.lt_style_sep_ref_acc, reporter);
this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_RE_SPECIAL)] this->vc_role_attrs[lnav::enums::to_underlying(role_t::VCR_RE_SPECIAL)]
= this->to_attrs(lt, lt.lt_style_re_special, reporter); = this->to_attrs(lt, lt.lt_style_re_special, reporter);

@ -366,8 +366,9 @@ dist_noinst_DATA = \
logfile_with_zones.0 \ logfile_with_zones.0 \
logfile_xml_msg.0 \ logfile_xml_msg.0 \
multiline.lnav \ multiline.lnav \
nested.lnav \
mvwattrline_output.0 \ mvwattrline_output.0 \
nested.lnav \
pyfile_0.py \
textfile_0.md \ textfile_0.md \
textfile_ansi.0 \ textfile_ansi.0 \
textfile_ansi_expanding.0 \ textfile_ansi_expanding.0 \

@ -0,0 +1,11 @@
/*
* 📂 HELLO, WORLD!
*/
#include <stdio.h>
int
main()
{
printf("Hello, World!\n");
}

@ -1150,6 +1150,8 @@ EXPECTED_FILES = \
$(srcdir)/%reldir%/test_sql_xml_func.sh_fefeb387ae14d4171225ea06cbbff3ec43990cf0.out \ $(srcdir)/%reldir%/test_sql_xml_func.sh_fefeb387ae14d4171225ea06cbbff3ec43990cf0.out \
$(srcdir)/%reldir%/test_sql_yaml_func.sh_dc189d02e8979b7ed245d5d750f68b9965984699.err \ $(srcdir)/%reldir%/test_sql_yaml_func.sh_dc189d02e8979b7ed245d5d750f68b9965984699.err \
$(srcdir)/%reldir%/test_sql_yaml_func.sh_dc189d02e8979b7ed245d5d750f68b9965984699.out \ $(srcdir)/%reldir%/test_sql_yaml_func.sh_dc189d02e8979b7ed245d5d750f68b9965984699.out \
$(srcdir)/%reldir%/test_text_file.sh_4226123565a53b4e3f80e602c1f294721e8e07bf.err \
$(srcdir)/%reldir%/test_text_file.sh_4226123565a53b4e3f80e602c1f294721e8e07bf.out \
$(srcdir)/%reldir%/test_text_file.sh_5b51b55dff7332c5bee2c9b797c401c5614d574a.err \ $(srcdir)/%reldir%/test_text_file.sh_5b51b55dff7332c5bee2c9b797c401c5614d574a.err \
$(srcdir)/%reldir%/test_text_file.sh_5b51b55dff7332c5bee2c9b797c401c5614d574a.out \ $(srcdir)/%reldir%/test_text_file.sh_5b51b55dff7332c5bee2c9b797c401c5614d574a.out \
$(srcdir)/%reldir%/test_text_file.sh_6a24078983cf1b7a80b6fb65d5186cd125498136.err \ $(srcdir)/%reldir%/test_text_file.sh_6a24078983cf1b7a80b6fb65d5186cd125498136.err \

@ -260,6 +260,131 @@
/ui/theme-defs/default/syntax-styles/symbol/color -> default-theme.json:114 /ui/theme-defs/default/syntax-styles/symbol/color -> default-theme.json:114
/ui/theme-defs/default/syntax-styles/variable/color -> default-theme.json:111 /ui/theme-defs/default/syntax-styles/variable/color -> default-theme.json:111
/ui/theme-defs/default/vars/semantic_highlight_color -> default-theme.json:7 /ui/theme-defs/default/vars/semantic_highlight_color -> default-theme.json:7
/ui/theme-defs/dracula/log-level-styles/critical/color -> dracula.json:281
/ui/theme-defs/dracula/log-level-styles/error/color -> dracula.json:278
/ui/theme-defs/dracula/log-level-styles/fatal/color -> dracula.json:284
/ui/theme-defs/dracula/log-level-styles/warning/color -> dracula.json:275
/ui/theme-defs/dracula/status-styles/active/background-color -> dracula.json:262
/ui/theme-defs/dracula/status-styles/active/color -> dracula.json:261
/ui/theme-defs/dracula/status-styles/alert/background-color -> dracula.json:258
/ui/theme-defs/dracula/status-styles/alert/color -> dracula.json:257
/ui/theme-defs/dracula/status-styles/disabled-title/background-color -> dracula.json:222
/ui/theme-defs/dracula/status-styles/disabled-title/bold -> dracula.json:223
/ui/theme-defs/dracula/status-styles/disabled-title/color -> dracula.json:221
/ui/theme-defs/dracula/status-styles/hotkey/color -> dracula.json:245
/ui/theme-defs/dracula/status-styles/hotkey/underline -> dracula.json:246
/ui/theme-defs/dracula/status-styles/inactive-alert/background-color -> dracula.json:270
/ui/theme-defs/dracula/status-styles/inactive-alert/color -> dracula.json:269
/ui/theme-defs/dracula/status-styles/inactive/background-color -> dracula.json:266
/ui/theme-defs/dracula/status-styles/inactive/color -> dracula.json:265
/ui/theme-defs/dracula/status-styles/info/background-color -> dracula.json:237
/ui/theme-defs/dracula/status-styles/info/color -> dracula.json:236
/ui/theme-defs/dracula/status-styles/subtitle/background-color -> dracula.json:232
/ui/theme-defs/dracula/status-styles/subtitle/bold -> dracula.json:233
/ui/theme-defs/dracula/status-styles/subtitle/color -> dracula.json:231
/ui/theme-defs/dracula/status-styles/text/background-color -> dracula.json:250
/ui/theme-defs/dracula/status-styles/text/color -> dracula.json:249
/ui/theme-defs/dracula/status-styles/title-hotkey/background-color -> dracula.json:241
/ui/theme-defs/dracula/status-styles/title-hotkey/color -> dracula.json:240
/ui/theme-defs/dracula/status-styles/title-hotkey/underline -> dracula.json:242
/ui/theme-defs/dracula/status-styles/title/background-color -> dracula.json:227
/ui/theme-defs/dracula/status-styles/title/bold -> dracula.json:228
/ui/theme-defs/dracula/status-styles/title/color -> dracula.json:226
/ui/theme-defs/dracula/status-styles/warn/background-color -> dracula.json:254
/ui/theme-defs/dracula/status-styles/warn/color -> dracula.json:253
/ui/theme-defs/dracula/styles/adjusted-time/color -> dracula.json:61
/ui/theme-defs/dracula/styles/alt-text/background-color -> dracula.json:29
/ui/theme-defs/dracula/styles/breadcrumb/color -> dracula.json:118
/ui/theme-defs/dracula/styles/cursor-line/background-color -> dracula.json:53
/ui/theme-defs/dracula/styles/cursor-line/bold -> dracula.json:54
/ui/theme-defs/dracula/styles/cursor-line/color -> dracula.json:52
/ui/theme-defs/dracula/styles/disabled-cursor-line/background-color -> dracula.json:58
/ui/theme-defs/dracula/styles/disabled-cursor-line/color -> dracula.json:57
/ui/theme-defs/dracula/styles/disabled-focused/background-color -> dracula.json:78
/ui/theme-defs/dracula/styles/disabled-focused/color -> dracula.json:77
/ui/theme-defs/dracula/styles/error/bold -> dracula.json:41
/ui/theme-defs/dracula/styles/error/color -> dracula.json:40
/ui/theme-defs/dracula/styles/focused/background-color -> dracula.json:74
/ui/theme-defs/dracula/styles/focused/color -> dracula.json:73
/ui/theme-defs/dracula/styles/footnote-border/background-color -> dracula.json:136
/ui/theme-defs/dracula/styles/footnote-border/color -> dracula.json:135
/ui/theme-defs/dracula/styles/footnote-text/background-color -> dracula.json:140
/ui/theme-defs/dracula/styles/footnote-text/color -> dracula.json:139
/ui/theme-defs/dracula/styles/h1/bold -> dracula.json:90
/ui/theme-defs/dracula/styles/h1/color -> dracula.json:89
/ui/theme-defs/dracula/styles/h2/color -> dracula.json:93
/ui/theme-defs/dracula/styles/h2/underline -> dracula.json:94
/ui/theme-defs/dracula/styles/h3/color -> dracula.json:97
/ui/theme-defs/dracula/styles/h4/underline -> dracula.json:100
/ui/theme-defs/dracula/styles/h5/underline -> dracula.json:103
/ui/theme-defs/dracula/styles/h6/underline -> dracula.json:106
/ui/theme-defs/dracula/styles/hidden/bold -> dracula.json:49
/ui/theme-defs/dracula/styles/hidden/color -> dracula.json:48
/ui/theme-defs/dracula/styles/hr/color -> dracula.json:109
/ui/theme-defs/dracula/styles/hyperlink/underline -> dracula.json:112
/ui/theme-defs/dracula/styles/identifier/color -> dracula.json:22
/ui/theme-defs/dracula/styles/info/bold -> dracula.json:37
/ui/theme-defs/dracula/styles/info/color -> dracula.json:36
/ui/theme-defs/dracula/styles/invalid-msg/color -> dracula.json:70
/ui/theme-defs/dracula/styles/list-glyph/color -> dracula.json:115
/ui/theme-defs/dracula/styles/offset-time/color -> dracula.json:67
/ui/theme-defs/dracula/styles/ok/bold -> dracula.json:33
/ui/theme-defs/dracula/styles/ok/color -> dracula.json:32
/ui/theme-defs/dracula/styles/popup/background-color -> dracula.json:82
/ui/theme-defs/dracula/styles/popup/color -> dracula.json:81
/ui/theme-defs/dracula/styles/quote-border/background-color -> dracula.json:128
/ui/theme-defs/dracula/styles/quote-border/color -> dracula.json:127
/ui/theme-defs/dracula/styles/quoted-text/background-color -> dracula.json:132
/ui/theme-defs/dracula/styles/quoted-text/color -> dracula.json:131
/ui/theme-defs/dracula/styles/scrollbar/background-color -> dracula.json:86
/ui/theme-defs/dracula/styles/scrollbar/color -> dracula.json:85
/ui/theme-defs/dracula/styles/skewed-time/color -> dracula.json:64
/ui/theme-defs/dracula/styles/snippet-border/color -> dracula.json:143
/ui/theme-defs/dracula/styles/table-border/color -> dracula.json:121
/ui/theme-defs/dracula/styles/table-header/bold -> dracula.json:124
/ui/theme-defs/dracula/styles/text/background-color -> dracula.json:26
/ui/theme-defs/dracula/styles/text/color -> dracula.json:25
/ui/theme-defs/dracula/styles/warning/bold -> dracula.json:45
/ui/theme-defs/dracula/styles/warning/color -> dracula.json:44
/ui/theme-defs/dracula/syntax-styles/code-border/background-color -> dracula.json:157
/ui/theme-defs/dracula/syntax-styles/code-border/color -> dracula.json:156
/ui/theme-defs/dracula/syntax-styles/comment/color -> dracula.json:168
/ui/theme-defs/dracula/syntax-styles/diff-add/color -> dracula.json:189
/ui/theme-defs/dracula/syntax-styles/diff-delete/color -> dracula.json:186
/ui/theme-defs/dracula/syntax-styles/diff-section/color -> dracula.json:192
/ui/theme-defs/dracula/syntax-styles/doc-directive/color -> dracula.json:171
/ui/theme-defs/dracula/syntax-styles/file/color -> dracula.json:204
/ui/theme-defs/dracula/syntax-styles/function/color -> dracula.json:210
/ui/theme-defs/dracula/syntax-styles/inline-code/background-color -> dracula.json:149
/ui/theme-defs/dracula/syntax-styles/inline-code/color -> dracula.json:148
/ui/theme-defs/dracula/syntax-styles/keyword/bold -> dracula.json:161
/ui/theme-defs/dracula/syntax-styles/keyword/color -> dracula.json:160
/ui/theme-defs/dracula/syntax-styles/number/bold -> dracula.json:207
/ui/theme-defs/dracula/syntax-styles/quoted-code/background-color -> dracula.json:153
/ui/theme-defs/dracula/syntax-styles/quoted-code/color -> dracula.json:152
/ui/theme-defs/dracula/syntax-styles/re-repeat/color -> dracula.json:183
/ui/theme-defs/dracula/syntax-styles/re-special/color -> dracula.json:180
/ui/theme-defs/dracula/syntax-styles/separators-references-accessors/color -> dracula.json:213
/ui/theme-defs/dracula/syntax-styles/spectrogram-high/background-color -> dracula.json:201
/ui/theme-defs/dracula/syntax-styles/spectrogram-low/background-color -> dracula.json:195
/ui/theme-defs/dracula/syntax-styles/spectrogram-medium/background-color -> dracula.json:198
/ui/theme-defs/dracula/syntax-styles/string/bold -> dracula.json:165
/ui/theme-defs/dracula/syntax-styles/string/color -> dracula.json:164
/ui/theme-defs/dracula/syntax-styles/symbol/color -> dracula.json:177
/ui/theme-defs/dracula/syntax-styles/type/color -> dracula.json:216
/ui/theme-defs/dracula/syntax-styles/variable/color -> dracula.json:174
/ui/theme-defs/dracula/vars/black -> dracula.json:7
/ui/theme-defs/dracula/vars/blue -> dracula.json:11
/ui/theme-defs/dracula/vars/cyan -> dracula.json:13
/ui/theme-defs/dracula/vars/green -> dracula.json:9
/ui/theme-defs/dracula/vars/magenta -> dracula.json:12
/ui/theme-defs/dracula/vars/orange -> dracula.json:15
/ui/theme-defs/dracula/vars/pink -> dracula.json:17
/ui/theme-defs/dracula/vars/purple -> dracula.json:16
/ui/theme-defs/dracula/vars/red -> dracula.json:8
/ui/theme-defs/dracula/vars/semantic_highlight_color -> dracula.json:18
/ui/theme-defs/dracula/vars/white -> dracula.json:14
/ui/theme-defs/dracula/vars/yellow -> dracula.json:10
/ui/theme-defs/eldar/log-level-styles/critical/color -> eldar.json:189 /ui/theme-defs/eldar/log-level-styles/critical/color -> eldar.json:189
/ui/theme-defs/eldar/log-level-styles/error/color -> eldar.json:186 /ui/theme-defs/eldar/log-level-styles/error/color -> eldar.json:186
/ui/theme-defs/eldar/log-level-styles/fatal/color -> eldar.json:192 /ui/theme-defs/eldar/log-level-styles/fatal/color -> eldar.json:192
@ -418,38 +543,38 @@
/ui/theme-defs/grayscale/vars/red -> grayscale.json:8 /ui/theme-defs/grayscale/vars/red -> grayscale.json:8
/ui/theme-defs/grayscale/vars/white -> grayscale.json:14 /ui/theme-defs/grayscale/vars/white -> grayscale.json:14
/ui/theme-defs/grayscale/vars/yellow -> grayscale.json:10 /ui/theme-defs/grayscale/vars/yellow -> grayscale.json:10
/ui/theme-defs/monocai/log-level-styles/critical/color -> monocai.json:264 /ui/theme-defs/monocai/log-level-styles/critical/color -> monocai.json:277
/ui/theme-defs/monocai/log-level-styles/error/color -> monocai.json:261 /ui/theme-defs/monocai/log-level-styles/error/color -> monocai.json:274
/ui/theme-defs/monocai/log-level-styles/fatal/color -> monocai.json:267 /ui/theme-defs/monocai/log-level-styles/fatal/color -> monocai.json:280
/ui/theme-defs/monocai/log-level-styles/warning/color -> monocai.json:258 /ui/theme-defs/monocai/log-level-styles/warning/color -> monocai.json:271
/ui/theme-defs/monocai/status-styles/active/background-color -> monocai.json:245 /ui/theme-defs/monocai/status-styles/active/background-color -> monocai.json:258
/ui/theme-defs/monocai/status-styles/active/color -> monocai.json:244 /ui/theme-defs/monocai/status-styles/active/color -> monocai.json:257
/ui/theme-defs/monocai/status-styles/alert/background-color -> monocai.json:241 /ui/theme-defs/monocai/status-styles/alert/background-color -> monocai.json:254
/ui/theme-defs/monocai/status-styles/alert/color -> monocai.json:240 /ui/theme-defs/monocai/status-styles/alert/color -> monocai.json:253
/ui/theme-defs/monocai/status-styles/disabled-title/background-color -> monocai.json:205 /ui/theme-defs/monocai/status-styles/disabled-title/background-color -> monocai.json:218
/ui/theme-defs/monocai/status-styles/disabled-title/bold -> monocai.json:206 /ui/theme-defs/monocai/status-styles/disabled-title/bold -> monocai.json:219
/ui/theme-defs/monocai/status-styles/disabled-title/color -> monocai.json:204 /ui/theme-defs/monocai/status-styles/disabled-title/color -> monocai.json:217
/ui/theme-defs/monocai/status-styles/hotkey/color -> monocai.json:228 /ui/theme-defs/monocai/status-styles/hotkey/color -> monocai.json:241
/ui/theme-defs/monocai/status-styles/hotkey/underline -> monocai.json:229 /ui/theme-defs/monocai/status-styles/hotkey/underline -> monocai.json:242
/ui/theme-defs/monocai/status-styles/inactive-alert/background-color -> monocai.json:253 /ui/theme-defs/monocai/status-styles/inactive-alert/background-color -> monocai.json:266
/ui/theme-defs/monocai/status-styles/inactive-alert/color -> monocai.json:252 /ui/theme-defs/monocai/status-styles/inactive-alert/color -> monocai.json:265
/ui/theme-defs/monocai/status-styles/inactive/background-color -> monocai.json:249 /ui/theme-defs/monocai/status-styles/inactive/background-color -> monocai.json:262
/ui/theme-defs/monocai/status-styles/inactive/color -> monocai.json:248 /ui/theme-defs/monocai/status-styles/inactive/color -> monocai.json:261
/ui/theme-defs/monocai/status-styles/info/background-color -> monocai.json:220 /ui/theme-defs/monocai/status-styles/info/background-color -> monocai.json:233
/ui/theme-defs/monocai/status-styles/info/color -> monocai.json:219 /ui/theme-defs/monocai/status-styles/info/color -> monocai.json:232
/ui/theme-defs/monocai/status-styles/subtitle/background-color -> monocai.json:215 /ui/theme-defs/monocai/status-styles/subtitle/background-color -> monocai.json:228
/ui/theme-defs/monocai/status-styles/subtitle/bold -> monocai.json:216 /ui/theme-defs/monocai/status-styles/subtitle/bold -> monocai.json:229
/ui/theme-defs/monocai/status-styles/subtitle/color -> monocai.json:214 /ui/theme-defs/monocai/status-styles/subtitle/color -> monocai.json:227
/ui/theme-defs/monocai/status-styles/text/background-color -> monocai.json:233 /ui/theme-defs/monocai/status-styles/text/background-color -> monocai.json:246
/ui/theme-defs/monocai/status-styles/text/color -> monocai.json:232 /ui/theme-defs/monocai/status-styles/text/color -> monocai.json:245
/ui/theme-defs/monocai/status-styles/title-hotkey/background-color -> monocai.json:224 /ui/theme-defs/monocai/status-styles/title-hotkey/background-color -> monocai.json:237
/ui/theme-defs/monocai/status-styles/title-hotkey/color -> monocai.json:223 /ui/theme-defs/monocai/status-styles/title-hotkey/color -> monocai.json:236
/ui/theme-defs/monocai/status-styles/title-hotkey/underline -> monocai.json:225 /ui/theme-defs/monocai/status-styles/title-hotkey/underline -> monocai.json:238
/ui/theme-defs/monocai/status-styles/title/background-color -> monocai.json:210 /ui/theme-defs/monocai/status-styles/title/background-color -> monocai.json:223
/ui/theme-defs/monocai/status-styles/title/bold -> monocai.json:211 /ui/theme-defs/monocai/status-styles/title/bold -> monocai.json:224
/ui/theme-defs/monocai/status-styles/title/color -> monocai.json:209 /ui/theme-defs/monocai/status-styles/title/color -> monocai.json:222
/ui/theme-defs/monocai/status-styles/warn/background-color -> monocai.json:237 /ui/theme-defs/monocai/status-styles/warn/background-color -> monocai.json:250
/ui/theme-defs/monocai/status-styles/warn/color -> monocai.json:236 /ui/theme-defs/monocai/status-styles/warn/color -> monocai.json:249
/ui/theme-defs/monocai/styles/adjusted-time/color -> monocai.json:58 /ui/theme-defs/monocai/styles/adjusted-time/color -> monocai.json:58
/ui/theme-defs/monocai/styles/alt-text/background-color -> monocai.json:26 /ui/theme-defs/monocai/styles/alt-text/background-color -> monocai.json:26
/ui/theme-defs/monocai/styles/breadcrumb/color -> monocai.json:115 /ui/theme-defs/monocai/styles/breadcrumb/color -> monocai.json:115
@ -503,28 +628,33 @@
/ui/theme-defs/monocai/styles/text/color -> monocai.json:22 /ui/theme-defs/monocai/styles/text/color -> monocai.json:22
/ui/theme-defs/monocai/styles/warning/bold -> monocai.json:42 /ui/theme-defs/monocai/styles/warning/bold -> monocai.json:42
/ui/theme-defs/monocai/styles/warning/color -> monocai.json:41 /ui/theme-defs/monocai/styles/warning/color -> monocai.json:41
/ui/theme-defs/monocai/syntax-styles/code-border/background-color -> monocai.json:149 /ui/theme-defs/monocai/syntax-styles/code-border/background-color -> monocai.json:153
/ui/theme-defs/monocai/syntax-styles/code-border/color -> monocai.json:148 /ui/theme-defs/monocai/syntax-styles/code-border/color -> monocai.json:152
/ui/theme-defs/monocai/syntax-styles/comment/color -> monocai.json:160 /ui/theme-defs/monocai/syntax-styles/comment/color -> monocai.json:164
/ui/theme-defs/monocai/syntax-styles/diff-add/color -> monocai.json:181 /ui/theme-defs/monocai/syntax-styles/diff-add/color -> monocai.json:185
/ui/theme-defs/monocai/syntax-styles/diff-delete/color -> monocai.json:178 /ui/theme-defs/monocai/syntax-styles/diff-delete/color -> monocai.json:182
/ui/theme-defs/monocai/syntax-styles/diff-section/color -> monocai.json:184 /ui/theme-defs/monocai/syntax-styles/diff-section/color -> monocai.json:188
/ui/theme-defs/monocai/syntax-styles/doc-directive/color -> monocai.json:163 /ui/theme-defs/monocai/syntax-styles/doc-directive/color -> monocai.json:167
/ui/theme-defs/monocai/syntax-styles/file/color -> monocai.json:196 /ui/theme-defs/monocai/syntax-styles/file/color -> monocai.json:200
/ui/theme-defs/monocai/syntax-styles/keyword/bold -> monocai.json:153 /ui/theme-defs/monocai/syntax-styles/function/color -> monocai.json:206
/ui/theme-defs/monocai/syntax-styles/keyword/color -> monocai.json:152 /ui/theme-defs/monocai/syntax-styles/inline-code/background-color -> monocai.json:145
/ui/theme-defs/monocai/syntax-styles/number/bold -> monocai.json:199 /ui/theme-defs/monocai/syntax-styles/inline-code/color -> monocai.json:144
/ui/theme-defs/monocai/syntax-styles/quoted-code/background-color -> monocai.json:145 /ui/theme-defs/monocai/syntax-styles/keyword/bold -> monocai.json:157
/ui/theme-defs/monocai/syntax-styles/quoted-code/color -> monocai.json:144 /ui/theme-defs/monocai/syntax-styles/keyword/color -> monocai.json:156
/ui/theme-defs/monocai/syntax-styles/re-repeat/color -> monocai.json:175 /ui/theme-defs/monocai/syntax-styles/number/bold -> monocai.json:203
/ui/theme-defs/monocai/syntax-styles/re-special/color -> monocai.json:172 /ui/theme-defs/monocai/syntax-styles/quoted-code/background-color -> monocai.json:149
/ui/theme-defs/monocai/syntax-styles/spectrogram-high/background-color -> monocai.json:193 /ui/theme-defs/monocai/syntax-styles/quoted-code/color -> monocai.json:148
/ui/theme-defs/monocai/syntax-styles/spectrogram-low/background-color -> monocai.json:187 /ui/theme-defs/monocai/syntax-styles/re-repeat/color -> monocai.json:179
/ui/theme-defs/monocai/syntax-styles/spectrogram-medium/background-color -> monocai.json:190 /ui/theme-defs/monocai/syntax-styles/re-special/color -> monocai.json:176
/ui/theme-defs/monocai/syntax-styles/string/bold -> monocai.json:157 /ui/theme-defs/monocai/syntax-styles/separators-references-accessors/color -> monocai.json:209
/ui/theme-defs/monocai/syntax-styles/string/color -> monocai.json:156 /ui/theme-defs/monocai/syntax-styles/spectrogram-high/background-color -> monocai.json:197
/ui/theme-defs/monocai/syntax-styles/symbol/color -> monocai.json:169 /ui/theme-defs/monocai/syntax-styles/spectrogram-low/background-color -> monocai.json:191
/ui/theme-defs/monocai/syntax-styles/variable/color -> monocai.json:166 /ui/theme-defs/monocai/syntax-styles/spectrogram-medium/background-color -> monocai.json:194
/ui/theme-defs/monocai/syntax-styles/string/bold -> monocai.json:161
/ui/theme-defs/monocai/syntax-styles/string/color -> monocai.json:160
/ui/theme-defs/monocai/syntax-styles/symbol/color -> monocai.json:173
/ui/theme-defs/monocai/syntax-styles/type/color -> monocai.json:212
/ui/theme-defs/monocai/syntax-styles/variable/color -> monocai.json:170
/ui/theme-defs/monocai/vars/black -> monocai.json:7 /ui/theme-defs/monocai/vars/black -> monocai.json:7
/ui/theme-defs/monocai/vars/blue -> monocai.json:11 /ui/theme-defs/monocai/vars/blue -> monocai.json:11
/ui/theme-defs/monocai/vars/cyan -> monocai.json:13 /ui/theme-defs/monocai/vars/cyan -> monocai.json:13

@ -32,10 +32,10 @@ Lnav takes a list of files to view and/or you can use the flag
arguments to load well-known log files, such as the syslog log files. arguments to load well-known log files, such as the syslog log files.
The flag arguments are: The flag arguments are:
•  -a  Load all of the most recent log file types. • -a Load all of the most recent log file types.
•  -r  Recursively load files from the given directory • -r Recursively load files from the given directory
hierarchies. hierarchies.
•  -R  Load older rotated log files as well. • -R Load older rotated log files as well.
When using the flag arguments, lnav will look for the files relative When using the flag arguments, lnav will look for the files relative
to the current directory and its parent directories. In other words, to the current directory and its parent directories. In other words,
@ -43,7 +43,7 @@ if you are working within a directory that has the well-known log
files, those will be preferred over any others. files, those will be preferred over any others.
If you do not want the default syslog file to be loaded when no files If you do not want the default syslog file to be loaded when no files
are specified, you can pass the  -N  flag. are specified, you can pass the -N flag.
Any files given on the command-line are scanned to determine their log Any files given on the command-line are scanned to determine their log
file format and to create an index for each line in the file. You do file format and to create an index for each line in the file. You do
@ -56,10 +56,10 @@ Lnav will also display data piped in on the standard input.
To automatically execute queries or lnav commands after the files have To automatically execute queries or lnav commands after the files have
been loaded, you can use the following options: been loaded, you can use the following options:
•  -c cmd  A command, query, or file to execute. The • -c cmd A command, query, or file to execute. The
first character determines the type of operation: a colon first character determines the type of operation: a colon
( : ) is used for the built-in commands; a semi-colon ( ; ( : ) is used for the built-in commands; a semi-colon ( ;
) for SQL queries; and a pipe symbol ( | ) for executing ) for SQL queries; and a pipe symbol ( | ) for executing
a file containing other commands. For example, to open a file containing other commands. For example, to open
the file "foo.log" and go to the tenth line in the file, the file "foo.log" and go to the tenth line in the file,
you can do: you can do:
@ -68,13 +68,13 @@ been loaded, you can use the following options:
This option can be given multiple times to execute This option can be given multiple times to execute
multiple operations in sequence. multiple operations in sequence.
•  -f file  A file that contains commands, queries, or • -f file A file that contains commands, queries, or
files to execute. This option is a shortcut for  -c '|file' files to execute. This option is a shortcut for -c '|file'
. You can use a dash ( - ) to execute commands from the . You can use a dash ( - ) to execute commands from the
standard input. standard input.
To execute commands/queries without opening the interactive text UI, To execute commands/queries without opening the interactive text UI,
you can pass the  -n  option. This combination of options allows you you can pass the -n option. This combination of options allows you
to write scripts for processing logs with lnav. For example, to get a to write scripts for processing logs with lnav. For example, to get a
list of IP addresses that dhclient has bound to in CSV format: list of IP addresses that dhclient has bound to in CSV format:
@ -99,7 +99,7 @@ The main part of the display shows the log lines from the files
interleaved based on time-of-day. New lines are automatically loaded interleaved based on time-of-day. New lines are automatically loaded
as they are appended to the files and, if you are viewing the bottom as they are appended to the files and, if you are viewing the bottom
of the files, lnav will scroll down to display the new lines, much of the files, lnav will scroll down to display the new lines, much
like  tail -f . like tail -f .
On color displays, the lines will be highlighted as follows: On color displays, the lines will be highlighted as follows:
@ -120,22 +120,22 @@ and right-hand side of the bar, for search hits and bookmarks.
The bar on the left side indicates the file the log message is from. A The bar on the left side indicates the file the log message is from. A
break in the bar means that the next log message comes from a break in the bar means that the next log message comes from a
different file. The color of the bar is derived from the file name. different file. The color of the bar is derived from the file name.
Pressing the left-arrow or  h  will reveal the source file names for Pressing the left-arrow or h will reveal the source file names for
each message and pressing again will show the full paths. each message and pressing again will show the full paths.
Above and below the main body are status lines that display a variety Above and below the main body are status lines that display a variety
of information. The top line displays: of information. The top line displays:
• The current time, configurable by the  /ui/clock-format  • The current time, configurable by the /ui/clock-format
property. property.
• The highest priority message from the  lnav_user_notifications  • The highest priority message from the lnav_user_notifications
table. You can insert rows into this table to display table. You can insert rows into this table to display
your own status messages. The default message displayed your own status messages. The default message displayed
on startup explains how to focus on the next status line on startup explains how to focus on the next status line
at the top, which is an interactive breadcrumb bar. at the top, which is an interactive breadcrumb bar.
The second status line at the top display breadcrumbs for the top line The second status line at the top display breadcrumbs for the top line
in the main view. Pressing  ENTER  will focus input on the breadcrumb in the main view. Pressing ENTER will focus input on the breadcrumb
bar, the cursor keys can be used to select a breadcrumb. The common bar, the cursor keys can be used to select a breadcrumb. The common
breadcrumbs are: breadcrumbs are:
@ -150,7 +150,7 @@ breadcrumbs are:
Notes: Notes:
1. Pressing  CTRL-A / CTRL-E  will select the first/last 1. Pressing CTRL-A / CTRL-E will select the first/last
breadcrumb. breadcrumb.
2. Typing text while a breadcrumb is selected will 2. Typing text while a breadcrumb is selected will
perform a fuzzy search on the possibilities. perform a fuzzy search on the possibilities.
@ -188,7 +188,7 @@ results. The views are organized into a stack so that any time you
activate a new view with a key press or command, the new view is activate a new view with a key press or command, the new view is
pushed onto the stack. Pressing the same key again will pop the view pushed onto the stack. Pressing the same key again will pop the view
off of the stack and return you to the previous view. Note that you off of the stack and return you to the previous view. Note that you
can always use  q  to pop the top view off of the stack. can always use q to pop the top view off of the stack.
Default Key Bindings Default Key Bindings
@ -199,16 +199,16 @@ can always use  q  to pop the top view off of the stack.
? View/leave this help message. ? View/leave this help message.
q Leave the current view or quit the program when in q Leave the current view or quit the program when in
the log file view. the log file view.
Q Similar to  q , except it will try to sync the top Q Similar to q , except it will try to sync the top
time between the current and former views. For time between the current and former views. For
example, when leaving the spectrogram view with  Q example, when leaving the spectrogram view with Q
, the top time in that view will be matched to the , the top time in that view will be matched to the
top time in the log view. top time in the log view.
TAB Toggle focusing on the filter editor or the main TAB Toggle focusing on the filter editor or the main
view. view.
ENTER Focus on the breadcrumb bar. ENTER Focus on the breadcrumb bar.
a/A Restore the view that was previously popped with  q a/A Restore the view that was previously popped with q
/ Q . The  A  hotkey will try to match the top / Q . The A hotkey will try to match the top
times between the two views. times between the two views.
X Close the current text file or log file. X Close the current text file or log file.
@ -291,13 +291,13 @@ can always use  q  to pop the top view off of the stack.
m Mark/unmark the line at the top of the display. m Mark/unmark the line at the top of the display.
The line will be highlighted with reverse video to The line will be highlighted with reverse video to
indicate that it is a user bookmark. You can use indicate that it is a user bookmark. You can use
the  u  hotkey to iterate through marks you have the u hotkey to iterate through marks you have
added. added.
M Mark/unmark all the lines between the top of the M Mark/unmark all the lines between the top of the
display and the last line marked/unmarked. display and the last line marked/unmarked.
J Mark/unmark the next line after the previously J Mark/unmark the next line after the previously
marked line. marked line.
K Like  J  except it toggles the mark on the K Like J except it toggles the mark on the
previous line. previous line.
c Copy the marked text to the X11 selection buffer c Copy the marked text to the X11 selection buffer
or OS X clipboard. or OS X clipboard.
@ -334,12 +334,12 @@ can always use  q  to pop the top view off of the stack.
log lines for each bucket of time. The bars are log lines for each bucket of time. The bars are
layed out horizontally with colored segments layed out horizontally with colored segments
representing the different log levels. You can use representing the different log levels. You can use
the  z  hotkey to change the size of the time the z hotkey to change the size of the time
buckets (e.g. ten minutes, one hour, one day). buckets (e.g. ten minutes, one hour, one day).
I Switch between the log and histogram views while I Switch between the log and histogram views while
keeping the time displayed at the top of each view keeping the time displayed at the top of each view
in sync. For example, if the top line in the log in sync. For example, if the top line in the log
view is "11:40", hitting  I  will switch to the view is "11:40", hitting I will switch to the
histogram view and scrolled to display "11:00" at histogram view and scrolled to display "11:00" at
the top (if the zoom level is hours). the top (if the zoom level is hours).
z/Shift Z Zoom in or out one step in the histogram view. z/Shift Z Zoom in or out one step in the histogram view.
@ -415,14 +415,14 @@ can always use  q  to pop the top view off of the stack.
below for more information. below for more information.
|<script> [arg1...] Execute an lnav script contained in a format |<script> [arg1...] Execute an lnav script contained in a format
directory (e.g. ~/.lnav/formats/default). The directory (e.g. ~/.lnav/formats/default). The
script can contain lines starting with  : ,  ; , script can contain lines starting with : , ; ,
or  |  to execute commands, SQL queries or execute or | to execute commands, SQL queries or execute
other files in lnav. Any values after the script other files in lnav. Any values after the script
name are treated as arguments can be referenced in name are treated as arguments can be referenced in
the script using  $1 ,  $2 , and so on, like in a the script using $1 , $2 , and so on, like in a
shell script. shell script.
CTRL+], ESCAPE Abort command-line entry started with  / ,  : ,  ; CTRL+], ESCAPE Abort command-line entry started with / , : , ;
, or  | . , or | .
Note: The regular expression format used by lnav is PCRE[1] Note: The regular expression format used by lnav is PCRE[1]
▌(Perl-Compatible Regular Expressions). ▌(Perl-Compatible Regular Expressions).
@ -499,10 +499,10 @@ Some commonly used format tables are:
leading timestamp followed by the message. leading timestamp followed by the message.
NOTE: You can get a dump of the schema for the internal tables, and NOTE: You can get a dump of the schema for the internal tables, and
any attached databases, by running the  .schema  SQL command. any attached databases, by running the .schema SQL command.
The columns available for the top log line in the view will The columns available for the top log line in the view will
automatically be displayed after pressing the semicolon ( ; ) key. All automatically be displayed after pressing the semicolon ( ; ) key. All
log tables contain at least the following columns: log tables contain at least the following columns:
Column Description Column Description
@ -528,7 +528,7 @@ The following tables include the basic columns as listed above and
include a few more columns since the log file format is more include a few more columns since the log file format is more
structured. structured.
•  syslog_log  • syslog_log
Column Description Column Description
═════════════════════════════════════════════════════════════════ ═════════════════════════════════════════════════════════════════
@ -536,7 +536,7 @@ structured.
log_procname The name of the process that sent the message. log_procname The name of the process that sent the message.
log_pid The process ID of the process that sent the log_pid The process ID of the process that sent the
message. message.
•  access_log  (The column names are the same as those in • access_log (The column names are the same as those in
the Microsoft LogParser tool.) the Microsoft LogParser tool.)
Column Description Column Description
@ -551,8 +551,8 @@ structured.
sc_bytes The number of bytes sent to the client. sc_bytes The number of bytes sent to the client.
cs_referrer The URL of the referring page. cs_referrer The URL of the referring page.
cs_user_agent The user agent string. cs_user_agent The user agent string.
•  strace_log  (Currently, you need to run strace with • strace_log (Currently, you need to run strace with
the  -tt -T options so there are timestamps for each the -tt -T options so there are timestamps for each
function call.) function call.)
Column Description Column Description
@ -580,7 +580,7 @@ use with care.)
For log formats that lack message structure, lnav can parse the log For log formats that lack message structure, lnav can parse the log
message and attempt to extract any data fields that it finds. This message and attempt to extract any data fields that it finds. This
feature is available through the  logline  log table. This table is feature is available through the logline log table. This table is
dynamically created and defined based on the message at the top of the dynamically created and defined based on the message at the top of the
log view. For example, given the following log message from "sudo", log view. For example, given the following log message from "sudo",
lnav will create the "logline" table with columns for "TTY", "PWD", lnav will create the "logline" table with columns for "TTY", "PWD",
@ -625,12 +625,12 @@ view as a template.
Environment variables can be used in SQL statements by prefixing the Environment variables can be used in SQL statements by prefixing the
variable name with a dollar-sign ($). For example, to read the value variable name with a dollar-sign ($). For example, to read the value
of the  HOME  variable, you can do: of the HOME variable, you can do:
;SELECT $HOME;  ;SELECT $HOME; 
To select the syslog messages that have a hostname field that is equal To select the syslog messages that have a hostname field that is equal
to the  HOSTNAME  variable: to the HOSTNAME variable:
;SELECT * FROM syslog_log WHERE log_hostname = $HOSTNAME;  ;SELECT * FROM syslog_log WHERE log_hostname = $HOSTNAME; 

@ -1,6 +1,6 @@
✘ error: invalid value for property “/ui/theme” ✘ error: invalid value for property “/ui/theme”
reason: unknown theme -- “baddy” reason: unknown theme -- “baddy”
 |   = help: The available themes are: default, eldar, grayscale, monocai, night-owl, solarized-dark, solarized-light  |   = help: The available themes are: default, dracula, eldar, grayscale, monocai, night-owl, solarized-dark, solarized-light
 --> command-option:1  --> command-option:1
 = help: Property Synopsis  = help: Property Synopsis
/ui/theme theme_name /ui/theme theme_name

@ -1,6 +1,6 @@
192.168.202.254 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/tramp HTTP/1.0" 200 134 "-" "gPXE/0.9.7" 192.168.202.254 - - [20/Jul/2009:22:59:26 +0000] "GET /vmw/cgi/tramp HTTP/1.0" 200 134 "-" "gPXE/0.9.7"
Hello, World! Hello, World!
This is  markdown  now! This is  markdown  now!
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7" 192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkboot.gz HTTP/1.0" 404 46210 "-" "gPXE/0.9.7"
192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7" 192.168.202.254 - - [20/Jul/2009:22:59:29 +0000] "GET /vmw/vSphere/default/vmkernel.gz HTTP/1.0" 200 78929 "-" "gPXE/0.9.7"

@ -3,7 +3,7 @@
Lnav follows the usual GNU style for configuring and installing Lnav follows the usual GNU style for configuring and installing
software: software:
Run  ./autogen.sh  if compiling from a cloned repository. Run ./autogen.sh if compiling from a cloned repository.
$ ./configure  $ ./configure 
$ make  $ make 

@ -0,0 +1,9 @@
# Test file for syntax-highlighting
def hello(abc):
"""
 This is a multi-line string
 @param abc: blah blah
 """
return abc + 1

@ -56,7 +56,7 @@ with highlights. Errors are red and warnings are yellow.
Usage Usage
The only file installed is the executable,  lnav . You can execute it The only file installed is the executable, lnav . You can execute it
with no arguments to view the default set of files: with no arguments to view the default set of files:
$ lnav  $ lnav 
@ -65,9 +65,9 @@ You can view all the syslog messages by running:
$ lnav /var/log/messages*  $ lnav /var/log/messages* 
Usage with  systemd-journald  Usage with  systemd-journald 
On systems running  systemd-journald , you can use  lnav  as the On systems running systemd-journald , you can use lnav as the
pager: pager:
$ journalctl | lnav  $ journalctl | lnav 
@ -76,35 +76,35 @@ or in follow mode:
$ journalctl -f | lnav  $ journalctl -f | lnav 
Since  journalctl 's default output format omits the year, if you are Since journalctl 's default output format omits the year, if you are
viewing logs which span multiple years you will need to change the viewing logs which span multiple years you will need to change the
output format to include the year, otherwise  lnav  gets confused: output format to include the year, otherwise lnav gets confused:
$ journalctl -o short-iso | lnav  $ journalctl -o short-iso | lnav 
It is also possible to use  journalctl 's json output format and  lnav It is also possible to use journalctl 's json output format and lnav
will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT: will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT:
$ journalctl -o json | lnav  $ journalctl -o json | lnav 
In case some MESSAGE fields contain special characters such as ANSI In case some MESSAGE fields contain special characters such as ANSI
color codes which are considered as unprintable by journalctl, color codes which are considered as unprintable by journalctl,
specifying  journalctl 's  -a  option might be preferable in order to specifying journalctl 's -a option might be preferable in order to
output those messages still in a non-binary representation: output those messages still in a non-binary representation:
$ journalctl -a -o json | lnav  $ journalctl -a -o json | lnav 
If using systemd v236 or newer, the output fields can be limited to If using systemd v236 or newer, the output fields can be limited to
the ones actually recognized by  lnav  for increased efficiency: the ones actually recognized by lnav for increased efficiency:
$ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav  $ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav 
If your system has been running for a long time, for increased If your system has been running for a long time, for increased
efficiency you may want to limit the number of log lines fed into  lnav efficiency you may want to limit the number of log lines fed into lnav
, e.g. via  journalctl 's  -n  or  --since=...  options. , e.g. via journalctl 's -n or --since=... options.
In case of a persistent journal, you may want to limit the number of In case of a persistent journal, you may want to limit the number of
log lines fed into  lnav  via  journalctl 's  -b  option. log lines fed into lnav via journalctl 's -b option.
Support Support
@ -162,7 +162,7 @@ The following software packages are required to build lnav:
Lnav follows the usual GNU style for configuring and installing Lnav follows the usual GNU style for configuring and installing
software: software:
Run  ./autogen.sh  if compiling from a cloned repository. Run ./autogen.sh if compiling from a cloned repository.
$ ./configure  $ ./configure 
$ make  $ make 

@ -27,7 +27,7 @@ with highlights. Errors are red and warnings are yellow.
Usage Usage
The only file installed is the executable,  lnav . You can execute it The only file installed is the executable, lnav . You can execute it
with no arguments to view the default set of files: with no arguments to view the default set of files:
$ lnav  $ lnav 
@ -36,9 +36,9 @@ You can view all the syslog messages by running:
$ lnav /var/log/messages*  $ lnav /var/log/messages* 
Usage with  systemd-journald  Usage with  systemd-journald 
On systems running  systemd-journald , you can use  lnav  as the On systems running systemd-journald , you can use lnav as the
pager: pager:
$ journalctl | lnav  $ journalctl | lnav 
@ -47,35 +47,35 @@ or in follow mode:
$ journalctl -f | lnav  $ journalctl -f | lnav 
Since  journalctl 's default output format omits the year, if you are Since journalctl 's default output format omits the year, if you are
viewing logs which span multiple years you will need to change the viewing logs which span multiple years you will need to change the
output format to include the year, otherwise  lnav  gets confused: output format to include the year, otherwise lnav gets confused:
$ journalctl -o short-iso | lnav  $ journalctl -o short-iso | lnav 
It is also possible to use  journalctl 's json output format and  lnav It is also possible to use journalctl 's json output format and lnav
will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT: will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT:
$ journalctl -o json | lnav  $ journalctl -o json | lnav 
In case some MESSAGE fields contain special characters such as ANSI In case some MESSAGE fields contain special characters such as ANSI
color codes which are considered as unprintable by journalctl, color codes which are considered as unprintable by journalctl,
specifying  journalctl 's  -a  option might be preferable in order to specifying journalctl 's -a option might be preferable in order to
output those messages still in a non-binary representation: output those messages still in a non-binary representation:
$ journalctl -a -o json | lnav  $ journalctl -a -o json | lnav 
If using systemd v236 or newer, the output fields can be limited to If using systemd v236 or newer, the output fields can be limited to
the ones actually recognized by  lnav  for increased efficiency: the ones actually recognized by lnav for increased efficiency:
$ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav  $ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav 
If your system has been running for a long time, for increased If your system has been running for a long time, for increased
efficiency you may want to limit the number of log lines fed into  lnav efficiency you may want to limit the number of log lines fed into lnav
, e.g. via  journalctl 's  -n  or  --since=...  options. , e.g. via journalctl 's -n or --since=... options.
In case of a persistent journal, you may want to limit the number of In case of a persistent journal, you may want to limit the number of
log lines fed into  lnav  via  journalctl 's  -b  option. log lines fed into lnav via journalctl 's -b option.
Support Support
@ -133,7 +133,7 @@ The following software packages are required to build lnav:
Lnav follows the usual GNU style for configuring and installing Lnav follows the usual GNU style for configuring and installing
software: software:
Run  ./autogen.sh  if compiling from a cloned repository. Run ./autogen.sh if compiling from a cloned repository.
$ ./configure  $ ./configure 
$ make  $ make 

@ -1,31 +1,31 @@
/** /**
* Copyright (c) 2018, Timothy Stack  * Copyright (c) 2018, Timothy Stack
*  *
* All rights reserved.  * All rights reserved.
*  *
* Redistribution and use in source and binary forms, with or without  * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:  * modification, are permitted provided that the following conditions are met:
*  *
* * Redistributions of source code must retain the above copyright notice, this  * * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.  * list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,  * * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation  * this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.  * and/or other materials provided with the distribution.
* * Neither the name of Timothy Stack nor the names of its contributors  * * Neither the name of Timothy Stack nor the names of its contributors
* may be used to endorse or promote products derived from this software  * may be used to endorse or promote products derived from this software
* without specific prior written permission.  * without specific prior written permission.
*  *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ''AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY  * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/  */
#include "log_level.hh" #include "log_level.hh"

@ -27,7 +27,7 @@ with highlights. Errors are red and warnings are yellow.
Usage Usage
The only file installed is the executable,  lnav . You can execute it The only file installed is the executable, lnav . You can execute it
with no arguments to view the default set of files: with no arguments to view the default set of files:
$ lnav  $ lnav 
@ -36,9 +36,9 @@ You can view all the syslog messages by running:
$ lnav /var/log/messages*  $ lnav /var/log/messages* 
Usage with  systemd-journald  Usage with  systemd-journald 
On systems running  systemd-journald , you can use  lnav  as the On systems running systemd-journald , you can use lnav as the
pager: pager:
$ journalctl | lnav  $ journalctl | lnav 
@ -47,35 +47,35 @@ or in follow mode:
$ journalctl -f | lnav  $ journalctl -f | lnav 
Since  journalctl 's default output format omits the year, if you are Since journalctl 's default output format omits the year, if you are
viewing logs which span multiple years you will need to change the viewing logs which span multiple years you will need to change the
output format to include the year, otherwise  lnav  gets confused: output format to include the year, otherwise lnav gets confused:
$ journalctl -o short-iso | lnav  $ journalctl -o short-iso | lnav 
It is also possible to use  journalctl 's json output format and  lnav It is also possible to use journalctl 's json output format and lnav
will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT: will make use of additional fields such as PRIORITY and _SYSTEMD_UNIT:
$ journalctl -o json | lnav  $ journalctl -o json | lnav 
In case some MESSAGE fields contain special characters such as ANSI In case some MESSAGE fields contain special characters such as ANSI
color codes which are considered as unprintable by journalctl, color codes which are considered as unprintable by journalctl,
specifying  journalctl 's  -a  option might be preferable in order to specifying journalctl 's -a option might be preferable in order to
output those messages still in a non-binary representation: output those messages still in a non-binary representation:
$ journalctl -a -o json | lnav  $ journalctl -a -o json | lnav 
If using systemd v236 or newer, the output fields can be limited to If using systemd v236 or newer, the output fields can be limited to
the ones actually recognized by  lnav  for increased efficiency: the ones actually recognized by lnav for increased efficiency:
$ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav  $ journalctl -o json --output-fields=MESSAGE,PRIORITY,_PID,SYSLOG_IDENTIFIER,_SYSTEMD_UNIT | lnav 
If your system has been running for a long time, for increased If your system has been running for a long time, for increased
efficiency you may want to limit the number of log lines fed into  lnav efficiency you may want to limit the number of log lines fed into lnav
, e.g. via  journalctl 's  -n  or  --since=...  options. , e.g. via journalctl 's -n or --since=... options.
In case of a persistent journal, you may want to limit the number of In case of a persistent journal, you may want to limit the number of
log lines fed into  lnav  via  journalctl 's  -b  option. log lines fed into lnav via journalctl 's -b option.
Support Support
@ -133,7 +133,7 @@ The following software packages are required to build lnav:
Lnav follows the usual GNU style for configuring and installing Lnav follows the usual GNU style for configuring and installing
software: software:
Run  ./autogen.sh  if compiling from a cloned repository. Run ./autogen.sh if compiling from a cloned repository.
$ ./configure  $ ./configure 
$ make  $ make 

@ -0,0 +1,9 @@
# Test file for syntax-highlighting
def hello(abc):
"""
This is a multi-line string
@param abc: blah blah
"""
return abc + 1

@ -37,3 +37,6 @@ run_cap_test ${lnav_test} -n \
run_cap_test ${lnav_test} -n \ run_cap_test ${lnav_test} -n \
${test_dir}/textfile_0.md ${test_dir}/textfile_0.md
run_cap_test ${lnav_test} -n \
${test_dir}/pyfile_0.py

Loading…
Cancel
Save