Skip to content

Commit d4caf4f

Browse files
committed
[session] use permalink when restoring log view state
1 parent 23f7320 commit d4caf4f

7 files changed

+83
-70
lines changed

NEWS.md

+2
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ Bug Fixes:
108108
command.
109109
* The `:set-file-timezone` command was not working correctly in some
110110
cases.
111+
* The location of views should be restored from the session when filters
112+
are active.
111113
112114
## lnav v0.12.4
113115

src/listview_curses.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -183,9 +183,8 @@ listview_curses::reload_data()
183183
auto curr_sel = this->get_selection();
184184

185185
if (curr_sel == -1_vl) {
186-
curr_sel = 0_vl;
186+
this->set_selection_without_context(0_vl);
187187
}
188-
this->set_selection_without_context(curr_sel);
189188
}
190189

191190
this->update_top_from_selection();
@@ -969,7 +968,8 @@ listview_curses::handle_mouse(mouse_event& me)
969968
this->lv_mouse_time = me.me_time;
970969
this->lv_focused_overlay_top -= 1_vl;
971970
if (this->lv_focused_overlay_selection
972-
>= this->lv_focused_overlay_top + (oc.oc_height - 1_vl))
971+
>= this->lv_focused_overlay_top
972+
+ (oc.oc_height - 1_vl))
973973
{
974974
this->lv_focused_overlay_selection
975975
= this->lv_focused_overlay_top

src/log_data_helper.cc

+3-4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "log_data_helper.hh"
3333

3434
#include "config.h"
35+
#include "logfile.hh"
3536
#include "pugixml/pugixml.hpp"
3637
#include "sql_util.hh"
3738
#include "xml_util.hh"
@@ -53,21 +54,19 @@ log_data_helper::clear()
5354
bool
5455
log_data_helper::parse_line(content_line_t line, bool allow_middle)
5556
{
56-
logfile::iterator ll;
57-
bool retval = false;
57+
auto retval = false;
5858

5959
this->ldh_source_line = this->ldh_line_index = line;
6060

6161
this->ldh_file = this->ldh_log_source.find(this->ldh_line_index);
62-
ll = this->ldh_file->begin() + this->ldh_line_index;
62+
auto ll = this->ldh_file->begin() + this->ldh_line_index;
6363
this->ldh_y_offset = 0;
6464
while (allow_middle && ll->is_continued()) {
6565
--ll;
6666
this->ldh_y_offset += 1;
6767
}
6868
this->ldh_line = ll;
6969
if (!ll->is_message()) {
70-
log_warning("failed to parse line %d", line);
7170
this->ldh_parser.reset();
7271
this->ldh_scanner.reset();
7372
this->ldh_namer.reset();

src/session_data.cc

+49-19
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,7 @@ read_files(yajlpp_parse_context* ypc,
864864
static const struct json_path_container view_def_handlers = {
865865
json_path_handler("top_line").for_field(&view_state::vs_top),
866866
json_path_handler("focused_line").for_field(&view_state::vs_selection),
867+
json_path_handler("anchor").for_field(&view_state::vs_anchor),
867868
json_path_handler("search").for_field(&view_state::vs_search),
868869
json_path_handler("word_wrap").for_field(&view_state::vs_word_wrap),
869870
json_path_handler("filtering").for_field(&view_state::vs_filtering),
@@ -1595,6 +1596,7 @@ save_session_with_id(const std::string& session_id)
15951596

15961597
for (int lpc = 0; lpc < LNV__MAX; lpc++) {
15971598
auto& tc = lnav_data.ld_views[lpc];
1599+
auto* ta = dynamic_cast<text_anchors*>(tc.get_sub_source());
15981600

15991601
top_view_map.gen(lnav_view_strings[lpc]);
16001602

@@ -1614,6 +1616,15 @@ save_session_with_id(const std::string& session_id)
16141616
{
16151617
view_map.gen("focused_line");
16161618
view_map.gen((long long) tc.get_selection());
1619+
1620+
if (ta != nullptr) {
1621+
auto anchor_opt
1622+
= ta->anchor_for_row(tc.get_selection());
1623+
if (anchor_opt) {
1624+
view_map.gen("anchor");
1625+
view_map.gen(anchor_opt.value());
1626+
}
1627+
}
16171628
}
16181629

16191630
view_map.gen("search");
@@ -1836,6 +1847,7 @@ lnav::session::restore_view_states()
18361847
for (size_t view_index = 0; view_index < LNV__MAX; view_index++) {
18371848
const auto& vs = session_data.sd_view_states[view_index];
18381849
auto& tview = lnav_data.ld_views[view_index];
1850+
auto* ta = dynamic_cast<text_anchors*>(tview.get_sub_source());
18391851
bool has_loc = false;
18401852

18411853
if (view_index == LNV_TEXT) {
@@ -1878,29 +1890,11 @@ lnav::session::restore_view_states()
18781890
if (row_opt) {
18791891
log_info("setting LOG view to desired loc: %s",
18801892
anchor.c_str());
1881-
lnav_data.ld_views[LNV_LOG].set_selection(row_opt.value());
1893+
tview.set_selection(row_opt.value());
18821894
}
18831895
}
18841896
}
18851897

1886-
if (!has_loc && vs.vs_top >= 0
1887-
&& (view_index == LNV_LOG || tview.get_top() == 0_vl
1888-
|| tview.get_top() == tview.get_top_for_last_row()))
1889-
{
1890-
log_info("restoring %s view top: %d",
1891-
lnav_view_strings[view_index],
1892-
vs.vs_top);
1893-
lnav_data.ld_views[view_index].set_top(vis_line_t(vs.vs_top), true);
1894-
lnav_data.ld_views[view_index].set_selection(-1_vl);
1895-
}
1896-
if (!has_loc && vs.vs_selection) {
1897-
log_info("restoring %s view selection: %d",
1898-
lnav_view_strings[view_index],
1899-
vs.vs_selection.value());
1900-
lnav_data.ld_views[view_index].set_selection(
1901-
vis_line_t(vs.vs_selection.value()));
1902-
}
1903-
19041898
if (!vs.vs_search.empty()) {
19051899
tview.execute_search(vs.vs_search);
19061900
tview.set_follow_search_for(-1, {});
@@ -1934,6 +1928,42 @@ lnav::session::restore_view_states()
19341928
};
19351929
}
19361930
}
1931+
1932+
if (!has_loc && vs.vs_top >= 0
1933+
&& (view_index == LNV_LOG || tview.get_top() == 0_vl
1934+
|| tview.get_top() == tview.get_top_for_last_row()))
1935+
{
1936+
log_info("restoring %s view top: %d",
1937+
lnav_view_strings[view_index],
1938+
vs.vs_top);
1939+
tview.set_top(vis_line_t(vs.vs_top), true);
1940+
tview.set_selection(-1_vl);
1941+
}
1942+
if (!has_loc && vs.vs_selection) {
1943+
log_info("restoring %s view selection: %d",
1944+
lnav_view_strings[view_index],
1945+
vs.vs_selection.value());
1946+
tview.set_selection(vis_line_t(vs.vs_selection.value()));
1947+
}
1948+
if (ta != nullptr && vs.vs_anchor && !vs.vs_anchor->empty()) {
1949+
auto curr_anchor = ta->anchor_for_row(tview.get_selection());
1950+
1951+
if (!curr_anchor || curr_anchor.value() != vs.vs_anchor.value()) {
1952+
log_info("%s view anchor mismatch %s != %s",
1953+
lnav_view_strings[view_index],
1954+
curr_anchor.value_or("").c_str(),
1955+
vs.vs_anchor.value().c_str());
1956+
1957+
auto row_opt = ta->row_for_anchor(vs.vs_anchor.value());
1958+
if (row_opt) {
1959+
tview.set_selection(row_opt.value());
1960+
}
1961+
}
1962+
}
1963+
log_info("%s view actual top/selection: %d/%d",
1964+
lnav_view_strings[view_index],
1965+
tview.get_top(),
1966+
tview.get_selection());
19371967
}
19381968
}
19391969

src/session_data.hh

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ struct file_state {
4747
struct view_state {
4848
int64_t vs_top{0};
4949
std::optional<int64_t> vs_selection;
50+
std::optional<std::string> vs_anchor;
5051
std::string vs_search;
5152
bool vs_word_wrap{false};
5253
bool vs_filtering{true};

src/textinput_curses.cc

+22-43
Original file line numberDiff line numberDiff line change
@@ -258,41 +258,39 @@ textinput_curses::textinput_curses()
258258
}
259259

260260
void
261-
textinput_curses::set_content(const attr_line_t& al)
261+
textinput_curses::content_to_lines(std::string content, int x)
262262
{
263-
auto al_copy = al;
263+
auto al = attr_line_t(content);
264264

265265
if (!this->tc_prefix.empty()) {
266-
al_copy.insert(0, this->tc_prefix);
266+
al.insert(0, this->tc_prefix);
267+
x += this->tc_prefix.length();
267268
}
268-
highlight_syntax(this->tc_text_format, al_copy, this->tc_prefix.length());
269+
highlight_syntax(this->tc_text_format, al, x);
269270
if (!this->tc_prefix.empty()) {
270271
// XXX yuck
271-
al_copy.erase(0, this->tc_prefix.al_string.size());
272+
al.erase(0, this->tc_prefix.al_string.size());
272273
}
273-
this->tc_doc_meta = lnav::document::discover(al_copy)
274+
this->tc_doc_meta = lnav::document::discover(al)
274275
.with_text_format(this->tc_text_format)
275276
.save_words()
276277
.perform();
277-
lnav::document::hier_node::depth_first(
278-
this->tc_doc_meta.m_sections_root.get(),
279-
[this](lnav::document::hier_node* hn) {
280-
log_debug("hier_node: %p %s",
281-
hn,
282-
fmt::format(FMT_STRING("{}"),
283-
this->tc_doc_meta.path_for_range(
284-
hn->hn_start, hn->hn_start))
285-
.c_str());
286-
});
287-
this->tc_lines = al_copy.split_lines();
288-
if (endswith(al_copy.al_string, "\n")) {
278+
this->tc_lines = al.split_lines();
279+
if (endswith(al.al_string, "\n")) {
289280
this->tc_lines.emplace_back();
290281
}
291282
if (this->tc_lines.empty()) {
292283
this->tc_lines.emplace_back();
293284
} else {
294285
this->apply_highlights();
295286
}
287+
}
288+
289+
void
290+
textinput_curses::set_content(std::string content)
291+
{
292+
this->content_to_lines(std::move(content), this->tc_prefix.length());
293+
296294
this->tc_change_log.clear();
297295
this->tc_marks.clear();
298296
this->tc_notice = std::nullopt;
@@ -1601,6 +1599,10 @@ textinput_curses::replace_selection_no_change(string_fragment sf)
16011599

16021600
this->tc_drag_selection = std::nullopt;
16031601
if (retval == sf) {
1602+
if (!sf.empty()) {
1603+
this->content_to_lines(this->get_content(),
1604+
this->get_cursor_offset());
1605+
}
16041606
} else {
16051607
this->update_lines();
16061608
}
@@ -1713,31 +1715,8 @@ textinput_curses::move_cursor_to(input_point ip)
17131715
void
17141716
textinput_curses::update_lines()
17151717
{
1716-
auto content = attr_line_t(this->get_content());
1717-
auto x = this->get_cursor_offset();
1718-
1719-
if (!this->tc_prefix.empty()) {
1720-
content.insert(0, this->tc_prefix);
1721-
x += this->tc_prefix.length();
1722-
}
1723-
highlight_syntax(this->tc_text_format, content, x);
1724-
if (!this->tc_prefix.empty()) {
1725-
// XXX yuck
1726-
content.erase(0, this->tc_prefix.al_string.size());
1727-
}
1728-
this->tc_doc_meta = lnav::document::discover(content)
1729-
.with_text_format(this->tc_text_format)
1730-
.save_words()
1731-
.perform();
1732-
this->tc_lines = content.split_lines();
1733-
if (endswith(content.al_string, "\n")) {
1734-
this->tc_lines.emplace_back();
1735-
}
1736-
if (this->tc_lines.empty()) {
1737-
this->tc_lines.emplace_back();
1738-
} else {
1739-
this->apply_highlights();
1740-
}
1718+
const auto x = this->get_cursor_offset();
1719+
this->content_to_lines(this->get_content(), x);
17411720
this->ensure_cursor_visible();
17421721

17431722
this->tc_marks.clear();

src/textinput_curses.hh

+3-1
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ public:
290290

291291
textinput_curses(const textinput_curses&) = delete;
292292

293-
void set_content(const attr_line_t& al);
293+
void set_content(std::string al);
294294

295295
void set_height(int height);
296296

@@ -304,6 +304,8 @@ public:
304304

305305
bool handle_key(const ncinput& ch);
306306

307+
void content_to_lines(std::string content, int x);
308+
307309
void update_lines();
308310

309311
void ensure_cursor_visible();

0 commit comments

Comments
 (0)