[doc.meta] detect indents for guidelines

pull/1205/head
Tim Stack 9 months ago
parent f3bdc50e70
commit 4ee3b91111

@ -114,8 +114,7 @@ Interface changes:
used to draw the overlay contents now as well. (The
overlay is used to display the parser details, comments,
and annotations.)
* Added indent guidelines to the data reformatted in the pretty-print
view.
* Added indent guidelines when structured data is detected.
Breaking changes:
* Removed the `-w` command-line option. This option was

@ -164,6 +164,7 @@ struct text_attrs {
struct block_elem_t {
wchar_t value;
role_t role;
};
using string_attr_value = mapbox::util::variant<int64_t,

@ -85,6 +85,7 @@ struct metadata_builder {
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::set<size_t> mb_indents;
metadata to_metadata() &&
{
@ -92,6 +93,7 @@ struct metadata_builder {
std::move(this->mb_intervals),
std::move(this->mb_root_node),
std::move(this->mb_type_intervals),
std::move(this->mb_indents),
};
}
};
@ -270,6 +272,9 @@ public:
data_scanner::token2name(dt),
tokenize_res->to_string().c_str());
#endif
if (dt != DT_WHITE) {
this->sw_at_start = false;
}
switch (dt) {
case DT_XML_DECL_TAG:
case DT_XML_EMPTY_TAG:
@ -386,8 +391,24 @@ public:
break;
case DT_LINE:
this->sw_line_number += 1;
this->sw_at_start = true;
break;
case DT_WHITE:
if (this->sw_at_start) {
size_t indent_size = 0;
for (auto ch : tokenize_res->to_string_fragment()) {
if (ch == '\t') {
do {
indent_size += 1;
} while (indent_size % 8);
} else {
indent_size += 1;
}
}
this->sw_indents.insert(indent_size);
this->sw_at_start = false;
}
break;
default:
if (dt == DT_GARBAGE) {
@ -435,6 +456,7 @@ public:
mb.mb_root_node = std::move(this->sw_hier_stage);
mb.mb_intervals = std::move(this->sw_intervals);
mb.mb_type_intervals = std::move(this->sw_type_intervals);
mb.mb_indents = std::move(this->sw_indents);
discover_metadata_int(this->sw_line, mb);
@ -549,6 +571,8 @@ private:
data_scanner sw_scanner;
int sw_depth{0};
size_t sw_line_number{0};
bool sw_at_start{true};
std::set<size_t> sw_indents;
std::vector<element> sw_values{};
std::vector<interval_state> sw_interval_state;
std::vector<lnav::document::section_interval_t> sw_intervals;

@ -31,6 +31,7 @@
#define lnav_attr_line_breadcrumbs_hh
#include <map>
#include <set>
#include <string>
#include <vector>
@ -113,6 +114,7 @@ struct metadata {
sections_tree_t m_sections_tree;
std::unique_ptr<hier_node> m_sections_root;
section_types_tree_t m_section_types_tree;
std::set<size_t> m_indents;
std::vector<breadcrumb::possibility> possibility_provider(
const std::vector<section_key_t>& path);

@ -245,7 +245,10 @@ pretty_printer::write_element(const pretty_printer::element& el)
void
pretty_printer::append_indent()
{
static const auto INDENT_GUIDELINE = block_elem_t{L'\u258f'};
static const auto INDENT_GUIDELINE = block_elem_t{
L'\u258f',
role_t::VCR_INDENT_GUIDE,
};
this->pp_stream << std::string(
this->pp_leading_indent + this->pp_soft_indent, ' ');
@ -259,9 +262,6 @@ pretty_printer::append_indent()
this->pp_post_attrs.emplace_back(
line_range{off, off + 1},
VC_BLOCK_ELEM.value(INDENT_GUIDELINE));
this->pp_post_attrs.emplace_back(
line_range{off, off + 1},
VC_ROLE.value(role_t::VCR_INDENT_GUIDE));
}
this->pp_stream << " ";
}

@ -83,8 +83,20 @@ textfile_sub_source::text_value_for_line(textview_curses& tc,
} else {
auto ll = lf->begin() + lfo->lfo_filter_state.tfs_index[line];
auto read_result = lf->read_line(ll);
this->tss_line_indent_size = 0;
if (read_result.isOk()) {
value_out = to_string(read_result.unwrap());
for (const auto& ch : value_out) {
if (ch == ' ') {
this->tss_line_indent_size += 1;
} else if (ch == '\t') {
do {
this->tss_line_indent_size += 1;
} while (this->tss_line_indent_size % 8);
} else {
break;
}
}
if (lf->has_line_metadata()
&& this->tas_display_time_offset)
{
@ -168,32 +180,45 @@ textfile_sub_source::text_attrs_for_line(textview_curses& tc,
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));
});
const auto& meta = meta_opt.value().get();
meta.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));
});
for (const auto& indent : meta.ms_metadata.m_indents) {
if (indent < this->tss_line_indent_size) {
auto guide_lr = line_range{
(int) indent,
(int) (indent + 1),
line_range::unit::codepoint,
};
value_out.emplace_back(
guide_lr,
VC_BLOCK_ELEM.value(block_elem_t{
L'\u258f', role_t::VCR_INDENT_GUIDE}));
}
}
}
}
}

@ -181,6 +181,7 @@ private:
std::deque<std::shared_ptr<logfile>> tss_hidden_files;
std::unordered_map<std::string, rendered_file> tss_rendered_files;
std::unordered_map<std::string, metadata_state> tss_doc_metadata;
size_t tss_line_indent_size{0};
};
#endif

@ -342,7 +342,9 @@ view_curses::mvwattrline(WINDOW* window,
graphic = iter->sa_value.get<int64_t>();
attrs = text_attrs{};
} else if (iter->sa_type == &VC_BLOCK_ELEM) {
block_elem = iter->sa_value.get<block_elem_t>().value;
auto be = iter->sa_value.get<block_elem_t>();
block_elem = be.value;
attrs = vc.attrs_for_role(be.role);
} else if (iter->sa_type == &VC_STYLE) {
attrs = iter->sa_value.get<text_attrs>();
} else if (iter->sa_type == &SA_LEVEL) {

Loading…
Cancel
Save