Skip to content

Commit 9cda6f5

Browse files
committed
[text] for lines with invalid UTF-8 content, show a hex dump
1 parent f6a34f4 commit 9cda6f5

44 files changed

Lines changed: 199 additions & 46 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

NEWS.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ Interface changes:
237237
* The parser-details overlay now mentions any search
238238
tables that match the focused line. Now, you don't
239239
have to remember the names of the tables.
240+
* If a text file contains invalid UTF-8 content, the
241+
invalid bytes will be shown as the replacement
242+
character (�) and, when the line is focused, an
243+
overlay will show a hex dump of the line.
240244

241245
Bug Fixes:
242246
* If a file path contains a hash (`#`), check if the path

src/base/lnav.console.cc

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -718,12 +718,16 @@ println(FILE* file, const attr_line_t& al)
718718
for (auto lpc = start; lpc < actual_end;) {
719719
auto cp_start = lpc;
720720
auto read_res = ww898::utf::utf8::read(
721-
[&str, &lpc]() { return str[lpc++]; });
721+
[&str, &lpc] { return str[lpc++]; });
722722

723723
if (read_res.isErr()) {
724-
sub.append(fmt::format(
724+
fmt::print(file, line_style, FMT_STRING("{}"), sub);
725+
sub.clear();
726+
fmt::print(
727+
file,
728+
fmt::fg(fmt::terminal_color::yellow),
725729
FMT_STRING("{:?}"),
726-
fmt::string_view{&str[cp_start], lpc - cp_start}));
730+
fmt::string_view{&str[cp_start], lpc - cp_start});
727731
continue;
728732
}
729733

src/cmds.display.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2828
*/
2929

30+
#include "base/intern_string.hh"
3031
#include "lnav.hh"
3132
#include "readline_context.hh"
3233

@@ -117,14 +118,14 @@ com_toggle_field(exec_context& ec,
117118
args[lpc].length() - dot - 1);
118119
} else if (tc->get_inner_height() == 0) {
119120
return ec.make_error("no log messages to hide");
120-
} else if (sel) {
121-
auto cl = lss.at(sel.value());
121+
} else {
122+
auto cl = lss.at(sel.value_or(0_vl));
122123
auto lf = lss.find(cl);
123124
format = lf->get_format();
124125
name = intern_string::lookup(args[lpc]);
125126
}
126127

127-
if (format->hide_field(name, hide)) {
128+
if (format && format->hide_field(name, hide)) {
128129
found_fields.push_back(args[lpc]);
129130
if (hide) {
130131
#if 0

src/db_sub_source.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -991,6 +991,7 @@ db_label_source::reset_user_state()
991991

992992
std::optional<attr_line_t>
993993
db_overlay_source::list_header_for_overlay(const listview_curses& lv,
994+
media_t media,
994995
vis_line_t line)
995996
{
996997
attr_line_t retval;

src/db_sub_source.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ public:
208208
std::vector<attr_line_t>& value_out) override;
209209

210210
std::optional<attr_line_t> list_header_for_overlay(
211-
const listview_curses& lv, vis_line_t line) override;
211+
const listview_curses& lv, media_t media, vis_line_t line) override;
212212

213213
void set_show_details_in_overlay(bool val) override
214214
{

src/field_overlay_source.cc

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,37 +1072,41 @@ field_overlay_source::list_static_overlay(const listview_curses& lv,
10721072

10731073
std::optional<attr_line_t>
10741074
field_overlay_source::list_header_for_overlay(const listview_curses& lv,
1075+
media_t media,
10751076
vis_line_t vl)
10761077
{
10771078
attr_line_t retval;
10781079

10791080
retval.append(this->fos_lss.get_filename_offset(), ' ');
10801081
if (this->fos_contexts.top().c_show) {
1081-
retval
1082-
.appendf(FMT_STRING("\u258C Line {:L} parser details. "
1083-
"Press "),
1084-
(int) vl)
1085-
.append("p"_hotkey)
1086-
.append(" to hide this panel.");
1082+
retval.appendf(FMT_STRING("\u258C Line {:L} parser details."),
1083+
(int) vl);
1084+
if (media == media_t::display) {
1085+
retval.append(" Press ")
1086+
.append("p"_hotkey)
1087+
.append(" to hide this panel.");
1088+
}
10871089
} else {
10881090
retval.append("\u258C Line ")
10891091
.append(
10901092
lnav::roles::number(fmt::format(FMT_STRING("{:L}"), (int) vl)))
10911093
.append(" metadata");
10921094
}
10931095

1094-
if (lv.get_overlay_selection()) {
1095-
retval.append(" ")
1096-
.append("SPC"_hotkey)
1097-
.append(": hide/show field ")
1098-
.append("c"_hotkey)
1099-
.append(": copy field value ")
1100-
.append("Esc"_hotkey)
1101-
.append(": exit this panel");
1102-
} else {
1103-
retval.append(" Press ")
1104-
.append("CTRL-]"_hotkey)
1105-
.append(" to focus on this panel");
1096+
if (media == media_t::display) {
1097+
if (lv.get_overlay_selection()) {
1098+
retval.append(" ")
1099+
.append("SPC"_hotkey)
1100+
.append(": hide/show field ")
1101+
.append("c"_hotkey)
1102+
.append(": copy field value ")
1103+
.append("Esc"_hotkey)
1104+
.append(": exit this panel");
1105+
} else {
1106+
retval.append(" Press ")
1107+
.append("CTRL-]"_hotkey)
1108+
.append(" to focus on this panel");
1109+
}
11061110
}
11071111

11081112
return retval;

src/field_overlay_source.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ public:
6464
attr_line_t& value_out) override;
6565

6666
std::optional<attr_line_t> list_header_for_overlay(
67-
const listview_curses& lv, vis_line_t vl) override;
67+
const listview_curses& lv, media_t media, vis_line_t vl) override;
6868

6969
void list_value_for_overlay(const listview_curses& lv,
7070
vis_line_t row,

src/line_buffer.cc

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1270,9 +1270,10 @@ line_buffer::load_next_line(file_range prev_line)
12701270
}
12711271
retval.li_utf8_scan_result = scan_res;
12721272
if (!scan_res.is_valid()) {
1273-
log_warning("fd(%d): line is not utf8 -- %lld",
1273+
log_warning("fd(%d): line is not utf8 -- %lld:%d",
12741274
this->lb_fd.get(),
1275-
retval.li_file_range.fr_offset);
1275+
retval.li_file_range.fr_offset,
1276+
scan_res.usr_valid_frag.length());
12761277
}
12771278
}
12781279

@@ -1334,10 +1335,6 @@ line_buffer::load_next_line(file_range prev_line)
13341335
}
13351336

13361337
offset += retval.li_file_range.fr_size;
1337-
1338-
done = true;
1339-
} else if (!retval.li_utf8_scan_result.is_valid()) {
1340-
retval.li_partial = true;
13411338
done = true;
13421339
} else {
13431340
if (!this->is_pipe() || !this->is_pipe_closed()) {

src/listview_curses.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,9 @@ listview_curses::do_update()
673673
if (row_overlay_content.size() > 1) {
674674
auto hdr
675675
= this->lv_overlay_source->list_header_for_overlay(
676-
*this, row);
676+
*this,
677+
list_overlay_source::media_t::display,
678+
row);
677679
if (hdr) {
678680
auto ov_hdr_attrs = text_attrs::with_underline();
679681
auto ov_hdr = hdr.value();

src/listview_curses.hh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public:
126126
}
127127

128128
virtual std::optional<attr_line_t> list_header_for_overlay(
129-
const listview_curses& lv, vis_line_t line)
129+
const listview_curses& lv, media_t media, vis_line_t line)
130130
{
131131
return std::nullopt;
132132
}

0 commit comments

Comments
 (0)