[user_notifications] treat message as markdown

pull/1031/head
Tim Stack 2 years ago
parent ff91cfc3a0
commit b5cb38d454

@ -0,0 +1,16 @@
{
"$id": "https://lnav.org/event-session-loaded-v1.schema.json",
"title": "https://lnav.org/event-session-loaded-v1.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Event fired when a session is loaded.",
"properties": {
"$schema": {
"title": "/$schema",
"type": "string",
"examples": [
"https://lnav.org/event-session-loaded-v1.schema.json"
]
}
},
"additionalProperties": false
}

@ -51,3 +51,6 @@ The following tables describe the schema of the event JSON objects.
.. jsonschema:: ../schemas/event-log-msg-detected-v1.schema.json#
:lift_description:
.. jsonschema:: ../schemas/event-session-loaded-v1.schema.json#
:lift_description:

@ -1,3 +1,5 @@
-- Tracks the current step in the tutorial
CREATE TABLE lnav_tutorial_step
(
name TEXT NOT NULL PRIMARY KEY,
@ -7,6 +9,7 @@ CREATE TABLE lnav_tutorial_step
INSERT INTO lnav_tutorial_step
VALUES ('tutorial1', 1);
-- A description of each step in the tutorial with its achievements
CREATE TABLE lnav_tutorial_steps
(
name TEXT NOT NULL,
@ -15,6 +18,7 @@ CREATE TABLE lnav_tutorial_steps
PRIMARY KEY (name, step)
);
-- Tracks the progress through the achievements in a step of the tutorial
CREATE TABLE IF NOT EXISTS lnav_tutorial_progress
(
name TEXT NOT NULL,
@ -34,6 +38,8 @@ CREATE TABLE IF NOT EXISTS lnav_tutorial_lines
log_comment TEXT
);
-- Copy the tutorial data from the markdown frontmatter to
-- the appropriate tables.
CREATE TRIGGER IF NOT EXISTS add_tutorial_data
AFTER INSERT
ON lnav_events
@ -63,7 +69,14 @@ BEGIN
REPLACE INTO lnav_user_notifications (id, views, message)
SELECT *
FROM lnav_tutorial_log_notification;
END;
CREATE TRIGGER IF NOT EXISTS tutorial_move_log_after_load
AFTER INSERT
ON lnav_events
WHEN jget(new.content, '/$schema') = 'https://lnav.org/event-session-loaded-v1.schema.json'
BEGIN
UPDATE lnav_views SET top = 0 WHERE name = 'log';
END;
CREATE TRIGGER IF NOT EXISTS lnav_tutorial_view_listener UPDATE OF top
@ -124,7 +137,7 @@ SELECT *
UNION ALL
SELECT 'org.lnav.tutorial.log' AS id,
'["log"]' AS views,
'Press y to go to the next step in the tutorial' AS message)
'Press `y` to go to the next step in the tutorial' AS message)
LIMIT 1;
CREATE TRIGGER IF NOT EXISTS lnav_tutorial_progress_listener
@ -138,4 +151,4 @@ BEGIN
END;
REPLACE INTO lnav_user_notifications (id, views, message)
VALUES ('org.lnav.tutorial.text', '["text"]', 'Press "q" to go to the log view')
VALUES ('org.lnav.tutorial.text', '["text"]', 'Press `q` to go to the log view')

@ -5,7 +5,9 @@ steps:
description: "Move to an error"
view_ptr: /top
view_value: 6
notification: "Press e/Shift+E to move through the errors"
notification: |
Press `e`/`Shift+E` to move through the
<span class="-lnav_log-level-styles_error">errors</span>
comment: |
You found the error!
[Log formats](https://docs.lnav.org/en/latest/formats.html#format-file-reference)
@ -14,7 +16,9 @@ steps:
how the levels are displayed.
move-to-warning:
description: "Move to a warning"
notification: "Press w/Shift+W to move through the warnings"
notification: |
Press `w`/`Shift+W` to move through the
<span class="-lnav_log-level-styles_warning">warnings</span>
view_ptr: /top
view_value: 3
comment: |
@ -25,12 +29,12 @@ steps:
view.
- search-for-term:
description: "Search for something"
notification: "Press / to search for '1AF9...'"
notification: "Press `/` to search for '1AF9...'"
view_ptr: /search
view_value: 1AF9293A-F42D-4318-BCDF-60234B240955
move-to-next-hit:
description: "Move to the next hit"
notification: "Press n/Shift+N to move through the search hits"
notification: "Press `n`/`Shift+N` to move through the search hits"
view_ptr: /top
view_value: 53
comment: |
@ -43,7 +47,7 @@ steps:
the way back to the start of the line.
move-right:
description: "Move to the right"
notification: "Press > to move horizontally to view the search hit"
notification: "Press `>` to move horizontally to view the search hit"
view_ptr: /left
view_value: 150
---
@ -71,8 +75,8 @@ can then use the following hotkeys to jump to them in the log view:
To complete this step in the tutorial, you'll need to navigate to the
errors and warnings in the sample log file. You can check the upper-right
status bar for tips on what you need to do next. Now, press `q` to switch
to the log view and begin navigating the sample log file.
↗↗↗ status bar for tips on what you need to do next. Now, press `q` to
switch to the log view and begin navigating the sample log file.
## Step 2
@ -87,12 +91,13 @@ Press `q` to switch to the log view and try searching for the UUID.
## Conclusion
That's all for now, visit https://lnav.org/downloads to find how to
download/install a copy of lnav for your system. The full documentation
is available at https://docs.lnav.org.
That's all for now, thanks for your time! Visit the
[downloads](https://lnav.org/downloads) page to find out how to
download or install **lnav** for your system. The full
documentation is available at https://docs.lnav.org
## Colophon
The source for this tutorial is available here:
https://github.com/tstack/lnav/tree/master/docs/tutorials/tutorial1
https://github.com/tstack/lnav/tree/master/docs/tutorials/

@ -49,6 +49,7 @@ dump_internals(const char* internals_dir)
&lnav::events::file::open::handlers,
&lnav::events::file::format_detected::handlers,
&lnav::events::log::msg_detected::handlers,
&lnav::events::session::loaded::handlers,
})
{
dump_schema_to(*handlers, internals_dir);

@ -529,5 +529,5 @@ http://lnav.org
For support questions, email:
lnav@googlegroups.com
support@lnav.org
* lnav@googlegroups.com
* support@lnav.org

@ -1336,7 +1336,8 @@ looper()
= &lnav_data.ld_exec_context;
lnav_data.ld_status[LNS_TOP].set_top(0);
lnav_data.ld_status[LNS_TOP].set_enabled(false);
lnav_data.ld_status[LNS_TOP].set_default_role(
role_t::VCR_INACTIVE_STATUS);
lnav_data.ld_status[LNS_TOP].set_data_source(&lnav_data.ld_top_source);
lnav_data.ld_status[LNS_BOTTOM].set_top(-(rlc->get_height() + 1));
for (auto& stat_bar : lnav_data.ld_status) {

@ -105,6 +105,20 @@ const typed_json_path_container<msg_detected> msg_detected::handlers = typed_jso
} // namespace log
namespace session {
const std::string loaded::SCHEMA_ID
= "https://lnav.org/event-session-loaded-v1.schema.json";
const typed_json_path_container<loaded> loaded::handlers = typed_json_path_container<loaded>{
yajlpp::property_handler("$schema").for_field(&loaded::l_schema)
.with_example(loaded::SCHEMA_ID),
}
.with_schema_id2(loaded::SCHEMA_ID)
.with_description2("Event fired when a session is loaded.");
} // namespace session
int
register_events_tab(sqlite3* db)
{

@ -75,6 +75,17 @@ struct msg_detected {
} // namespace log
namespace session {
struct loaded {
std::string l_schema{SCHEMA_ID};
static const std::string SCHEMA_ID;
static const typed_json_path_container<loaded> handlers;
};
} // namespace session
int register_events_tab(sqlite3* db);
namespace details {

@ -72,7 +72,8 @@ namespace md4cpp {
};
static xml_entity_map
load_xml_entity_map() {
load_xml_entity_map()
{
static const intern_string_t name
= intern_string::lookup(xml_entities_json.get_name());
auto parse_res
@ -85,14 +86,16 @@ namespace md4cpp {
}
const xml_entity_map&
get_xml_entity_map() {
get_xml_entity_map()
{
static const auto retval = load_xml_entity_map();
return retval;
}
static emoji_map
load_emoji_map() {
load_emoji_map()
{
static const intern_string_t name
= intern_string::lookup(emojis_json.get_name());
auto parse_res
@ -110,7 +113,8 @@ namespace md4cpp {
}
const emoji_map&
get_emoji_map() {
get_emoji_map()
{
static const auto retval = load_emoji_map();
return retval;
@ -122,7 +126,8 @@ namespace md4cpp {
};
static event_handler::block
build_block(MD_BLOCKTYPE type, void *detail) {
build_block(MD_BLOCKTYPE type, void* detail)
{
switch (type) {
case MD_BLOCK_DOC:
return event_handler::block_doc{};
@ -162,7 +167,8 @@ namespace md4cpp {
}
static event_handler::span
build_span(MD_SPANTYPE type, void *detail) {
build_span(MD_SPANTYPE type, void* detail)
{
switch (type) {
case MD_SPAN_EM:
return event_handler::span_em{};
@ -186,7 +192,8 @@ namespace md4cpp {
}
static int
md4cpp_enter_block(MD_BLOCKTYPE type, void *detail, void *userdata) {
md4cpp_enter_block(MD_BLOCKTYPE type, void* detail, void* userdata)
{
auto* pu = static_cast<parse_userdata*>(userdata);
auto enter_res = pu->pu_handler.enter_block(build_block(type, detail));
@ -199,7 +206,8 @@ namespace md4cpp {
}
static int
md4cpp_leave_block(MD_BLOCKTYPE type, void *detail, void *userdata) {
md4cpp_leave_block(MD_BLOCKTYPE type, void* detail, void* userdata)
{
auto* pu = static_cast<parse_userdata*>(userdata);
auto leave_res = pu->pu_handler.leave_block(build_block(type, detail));
@ -212,7 +220,8 @@ namespace md4cpp {
}
static int
md4cpp_enter_span(MD_SPANTYPE type, void *detail, void *userdata) {
md4cpp_enter_span(MD_SPANTYPE type, void* detail, void* userdata)
{
auto* pu = static_cast<parse_userdata*>(userdata);
auto enter_res = pu->pu_handler.enter_span(build_span(type, detail));
@ -225,7 +234,8 @@ namespace md4cpp {
}
static int
md4cpp_leave_span(MD_SPANTYPE type, void *detail, void *userdata) {
md4cpp_leave_span(MD_SPANTYPE type, void* detail, void* userdata)
{
auto* pu = static_cast<parse_userdata*>(userdata);
auto leave_res = pu->pu_handler.leave_span(build_span(type, detail));
@ -238,7 +248,8 @@ namespace md4cpp {
}
static int
md4cpp_text(MD_TEXTTYPE type, const MD_CHAR *text, MD_SIZE size, void *userdata) {
md4cpp_text(MD_TEXTTYPE type, const MD_CHAR* text, MD_SIZE size, void* userdata)
{
auto* pu = static_cast<parse_userdata*>(userdata);
auto text_res = pu->pu_handler.text(type, string_fragment(text, 0, size));
if (text_res.isErr()) {
@ -251,7 +262,8 @@ namespace md4cpp {
namespace details {
Result<void, std::string>
parse(const string_fragment &sf, event_handler &eh) {
parse(const string_fragment& sf, event_handler& eh)
{
const char* utf8_errmsg = nullptr;
int utf8_faulty_bytes = 0;
@ -270,7 +282,8 @@ namespace md4cpp {
auto pu = parse_userdata{eh};
parser.abi_version = 0;
parser.flags = MD_DIALECT_GITHUB | MD_FLAG_UNDERLINE;
parser.flags = (MD_DIALECT_GITHUB | MD_FLAG_UNDERLINE)
& ~(MD_FLAG_PERMISSIVEAUTOLINKS);
parser.enter_block = md4cpp_enter_block;
parser.leave_block = md4cpp_leave_block;
parser.enter_span = md4cpp_enter_span;

@ -46,6 +46,7 @@
#include "base/paths.hh"
#include "command_executor.hh"
#include "config.h"
#include "lnav.events.hh"
#include "lnav.hh"
#include "lnav_util.hh"
#include "log_format_ext.hh"
@ -964,6 +965,9 @@ load_session()
lnav_data.ld_text_source.text_filters_changed();
}
};
lnav::events::publish(lnav_data.ld_db.in(),
lnav::events::session::loaded{});
}
static void

@ -101,7 +101,7 @@ statusview_curses::do_update()
top = this->sc_top < 0 ? height + this->sc_top : this->sc_top;
right = width;
auto attrs = vc.attrs_for_role(
this->sc_enabled ? role_t::VCR_STATUS : role_t::VCR_INACTIVE_STATUS);
this->sc_enabled ? this->sc_default_role : role_t::VCR_INACTIVE_STATUS);
auto pair = vc.ensure_color_pair(attrs.ta_fg_color, attrs.ta_bg_color);
wattr_set(this->sc_window, attrs.ta_attrs, pair, nullptr);

@ -171,6 +171,9 @@ public:
void set_enabled(bool value) { this->sc_enabled = value; }
bool get_enabled() const { return this->sc_enabled; }
void set_default_role(role_t role) { this->sc_default_role = role; }
role_t get_default_role() const { return this->sc_default_role; }
void window_change();
void do_update() override;
@ -180,6 +183,7 @@ private:
WINDOW* sc_window{nullptr};
int sc_top{0};
bool sc_enabled{true};
role_t sc_default_role{role_t::VCR_STATUS};
};
#endif

@ -34,8 +34,13 @@
#include "base/injector.hh"
#include "bound_tags.hh"
#include "config.h"
#include "lnav.hh"
#include "lnav_config.hh"
#include "logfile_sub_source.hh"
#include "md2attr_line.hh"
#include "md4cpp.hh"
#include "shlex.hh"
#include "shlex.resolver.hh"
#include "sql_util.hh"
#include "sqlitepp.client.hh"
@ -107,7 +112,23 @@ top_status_source::update_user_msg()
auto fetch_res = um_stmt.ums_stmt.fetch_row<std::string>();
fetch_res.match(
[&al](const std::string& value) {
al.with_ansi_string(value);
shlex lexer(value);
std::string user_note;
lexer.with_ignore_quotes(true).eval(
user_note, lnav_data.ld_exec_context.ec_global_vars);
md2attr_line mdal;
auto parse_res = md4cpp::parse(user_note, mdal);
if (parse_res.isOk()) {
al = parse_res.unwrap();
} else {
log_error("failed to parse user note as markdown: %s",
parse_res.unwrapErr().c_str());
al = user_note;
}
scrub_ansi_string(al.get_string(), &al.get_attrs());
al.append(" ");
},
[](const prepared_stmt::end_of_rows&) {},

@ -664,16 +664,12 @@ commands, which is especially useful when scripting lnav.
For more information, visit the lnav website at:
http://lnav.org[1]
▌[1] - http://lnav.org
http://lnav.org
For support questions, email:
lnav@googlegroups.com[1] support@lnav.org[2]
▌[1] - mailto:lnav@googlegroups.com
▌[2] - mailto:support@lnav.org
• lnav@googlegroups.com
• support@lnav.org
Command Reference

Loading…
Cancel
Save