Skip to content

Commit

Permalink
[mouse] refactor overlay menu
Browse files Browse the repository at this point in the history
  • Loading branch information
tstack committed Apr 19, 2024
1 parent 65634ad commit 45d8e27
Show file tree
Hide file tree
Showing 31 changed files with 547 additions and 208 deletions.
2 changes: 2 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,7 @@ add_library(
styling.cc
text_anonymizer.cc
text_format.cc
text_overlay_menu.cc
textfile_highlighters.cc
textfile_sub_source.cc
textview_curses.cc
Expand Down Expand Up @@ -608,6 +609,7 @@ add_library(
termios_guard.hh
text_anonymizer.hh
text_format.hh
text_overlay_menu.hh
textfile_highlighters.hh
textfile_sub_source.hh
textview_curses.hh
Expand Down
2 changes: 2 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ noinst_HEADERS = \
term_extra.hh \
text_anonymizer.hh \
text_format.hh \
text_overlay_menu.hh \
textfile_highlighters.hh \
textfile_sub_source.hh \
textview_curses.hh \
Expand Down Expand Up @@ -506,6 +507,7 @@ libdiag_a_SOURCES = \
styling.cc \
text_anonymizer.cc \
text_format.cc \
text_overlay_menu.cc \
textfile_sub_source.cc \
timer.cc \
sql_commands.cc \
Expand Down
3 changes: 2 additions & 1 deletion src/base/intern_string.cc
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,9 @@ string_fragment::sub_cell_range(int cell_start, int cell_end) const
if (cell_start == cell_index) {
byte_start = byte_index;
}
if (cell_index == cell_end) {
if (!byte_end && cell_index >= cell_end) {
byte_end = byte_index;
break;
}
auto read_res = ww898::utf::utf8::read(
[this, &byte_index]() { return this->sf_string[byte_index++]; });
Expand Down
4 changes: 4 additions & 0 deletions src/base/is_utf8.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,13 +76,17 @@ is_utf8(string_fragment str, nonstd::optional<unsigned char> terminator)
break;
}

retval.usr_column_width_guess += 1;
if (retval.usr_message != nullptr) {
i += 1;
continue;
}

valid_end = i;
if (ustr[i] <= 0x7F) /* 00..7F */ {
if (ustr[i] == '\t') {
retval.usr_column_width_guess += 7;
}
i += 1;
} else if (ustr[i] >= 0xC2 && ustr[i] <= 0xDF) /* C2..DF 80..BF */ {
if (i + 1 < str.length()) /* Expect a 2nd byte */ {
Expand Down
1 change: 1 addition & 0 deletions src/base/is_utf8.hh
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ struct utf8_scan_result {
string_fragment usr_valid_frag{string_fragment::invalid()};
nonstd::optional<string_fragment> usr_remaining;
bool usr_has_ansi{false};
size_t usr_column_width_guess{0};

const char* remaining_ptr(const string_fragment& frag) const
{
Expand Down
74 changes: 74 additions & 0 deletions src/base/string_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,77 @@ formatter<lnav::tainted_string>::format(const lnav::tainted_string& ts,
return format_to(ctx.out(), FMT_STRING("{:?}"), ts.ts_str);
}
} // namespace fmt

namespace lnav {
namespace pcre2pp {

static bool
is_meta(char ch)
{
switch (ch) {
case '\\':
case '^':
case '$':
case '.':
case '[':
case ']':
case '(':
case ')':
case '*':
case '+':
case '?':
case '{':
case '}':
return true;
default:
return false;
}
}

static nonstd::optional<const char*>
char_escape_seq(char ch)
{
switch (ch) {
case '\t':
return "\\t";
case '\n':
return "\\n";
}

return nonstd::nullopt;
}

std::string
quote(string_fragment str)
{
std::string retval;

while (true) {
auto cp_pair_opt = str.consume_codepoint();
if (!cp_pair_opt) {
break;
}

auto cp_pair = cp_pair_opt.value();
if ((cp_pair.first & ~0xff) == 0) {
if (is_meta(cp_pair.first)) {
retval.push_back('\\');
} else {
auto esc_seq = char_escape_seq(cp_pair.first);
if (esc_seq) {
retval.append(esc_seq.value());
str = cp_pair_opt->second;
continue;
}
}
}
ww898::utf::utf8::write(cp_pair.first,
[&retval](char ch) { retval.push_back(ch); });
str = cp_pair_opt->second;
}

return retval;
}

} // namespace pcre2pp
} // namespace lnav
12 changes: 10 additions & 2 deletions src/base/string_util.hh
Original file line number Diff line number Diff line change
Expand Up @@ -282,9 +282,17 @@ private:
namespace fmt {
template<>
struct formatter<lnav::tainted_string> : formatter<string_view> {
auto format(const lnav::tainted_string& ts, format_context& ctx)
-> decltype(ctx.out()) const;
auto format(const lnav::tainted_string& ts,
format_context& ctx) -> decltype(ctx.out()) const;
};
} // namespace fmt

namespace lnav {
namespace pcre2pp {

std::string quote(string_fragment sf);

}
} // namespace lnav

#endif
99 changes: 99 additions & 0 deletions src/data_scanner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -304,3 +304,102 @@ data_scanner::cleanup_end()
}
}
}

nonstd::optional<data_scanner::tokenize_result>
data_scanner::tokenize2(text_format_t tf)
{
auto retval = this->tokenize_int(tf);

if (this->ds_last_bracket_matched) {
this->ds_matching_brackets.pop_back();
this->ds_last_bracket_matched = false;
}
if (retval) {
auto dt = retval.value().tr_token;
switch (dt) {
case DT_LSQUARE:
case DT_LCURLY:
case DT_LPAREN:
this->ds_matching_brackets.emplace_back(retval.value());
break;
case DT_RSQUARE:
case DT_RCURLY:
case DT_RPAREN:
if (!this->ds_matching_brackets.empty()
&& this->ds_matching_brackets.back().tr_token
== to_opener(dt))
{
this->ds_last_bracket_matched = true;
}
break;
default:
break;
}
}

return retval;
}

nonstd::optional<data_scanner::tokenize_result>
data_scanner::find_matching_bracket(text_format_t tf, tokenize_result tr)
{
switch (tr.tr_token) {
case DT_LSQUARE:
case DT_LCURLY:
case DT_LPAREN: {
auto curr_size = this->ds_matching_brackets.size();
while (true) {
auto tok_res = this->tokenize2(tf);
if (!tok_res) {
break;
}

if (this->ds_matching_brackets.size() == curr_size
&& this->ds_last_bracket_matched)
{
return tokenize_result{
DNT_GROUP,
{
tr.tr_capture.c_begin,
tok_res->tr_capture.c_end,
},
{
tr.tr_capture.c_begin,
tok_res->tr_capture.c_end,
},
tr.tr_data,
};
}
}
break;
}
case DT_RSQUARE:
case DT_RCURLY:
case DT_RPAREN: {
for (auto riter = this->ds_matching_brackets.rbegin();
riter != this->ds_matching_brackets.rend();
++riter)
{
if (riter->tr_token == to_opener(tr.tr_token)) {
return data_scanner::tokenize_result{
DNT_GROUP,
{
riter->tr_capture.c_begin,
tr.tr_capture.c_end,
},
{
riter->tr_capture.c_begin,
tr.tr_capture.c_end,
},
tr.tr_data,
};
}
}
break;
}
default:
break;
}

return nonstd::nullopt;
}
25 changes: 25 additions & 0 deletions src/data_scanner.hh
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,9 @@ public:
nonstd::optional<tokenize_result> tokenize2(text_format_t tf
= text_format_t::TF_UNKNOWN);

nonstd::optional<tokenize_result> find_matching_bracket(text_format_t tf,
tokenize_result tr);

void reset() { this->ds_next_offset = this->ds_init_offset; }

int get_init_offset() const { return this->ds_init_offset; }
Expand All @@ -222,15 +225,37 @@ private:

bool is_credit_card(string_fragment frag) const;

nonstd::optional<tokenize_result> tokenize_int(text_format_t tf
= text_format_t::TF_UNKNOWN);

std::string ds_line;
shared_buffer_ref ds_sbr;
string_fragment ds_input;
int ds_init_offset{0};
int ds_next_offset{0};
bool ds_bol{true};
bool ds_units{false};
std::vector<tokenize_result> ds_matching_brackets;
bool ds_last_bracket_matched{false};
};

inline data_token_t
to_opener(data_token_t dt)
{
switch (dt) {
case DT_XML_CLOSE_TAG:
return DT_XML_OPEN_TAG;
case DT_RCURLY:
return DT_LCURLY;
case DT_RSQUARE:
return DT_LSQUARE;
case DT_RPAREN:
return DT_LPAREN;
default:
ensure(0);
}
}

inline data_token_t
to_closer(data_token_t dt)
{
Expand Down
4 changes: 2 additions & 2 deletions src/data_scanner_re.cc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* Generated by re2c 3.1 on Mon Apr 1 11:22:40 2024 */
/* Generated by re2c 3.1 on Thu Apr 18 13:48:53 2024 */
#line 1 "../../lnav/src/data_scanner_re.re"
/**
* Copyright (c) 2015, Timothy Stack
Expand Down Expand Up @@ -48,7 +48,7 @@ enum YYCONDTYPE {
#line 38 "../../lnav/src/data_scanner_re.re"


nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2(text_format_t tf)
nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf)
{
data_token_t token_out = DT_INVALID;
capture_t cap_all;
Expand Down
2 changes: 1 addition & 1 deletion src/data_scanner_re.re
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@

/*!conditions:re2c*/

nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize2(text_format_t tf)
nonstd::optional<data_scanner::tokenize_result> data_scanner::tokenize_int(text_format_t tf)
{
data_token_t token_out = DT_INVALID;
capture_t cap_all;
Expand Down
Loading

0 comments on commit 45d8e27

Please sign in to comment.