mirror of https://github.com/tstack/lnav.git
[wrap] start support for word wrapping and fix a variety of glitches
This commit is contained in:
parent
50d50fb5a8
commit
c3d51190c8
|
@ -189,6 +189,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
void invalidate() {
|
||||
this->cleanup();
|
||||
};
|
||||
|
||||
/** @param gpd The sink to send results to. */
|
||||
void set_control(grep_proc_control *gpc)
|
||||
{
|
||||
|
|
|
@ -325,6 +325,9 @@ COMMANDS
|
|||
Enable a inactive 'filter-in' or 'filter-out'
|
||||
expression.
|
||||
|
||||
disable-word-wrap Disable word wrapping in the log and text file views.
|
||||
enable-word-wrap Enable word wrapping in the log and text file views.
|
||||
|
||||
open <filename>[:<line>]
|
||||
Open the given file within lnav and, if it is a
|
||||
text file, switch to the text view and jump to
|
||||
|
@ -348,7 +351,7 @@ COMMANDS
|
|||
|
||||
session <cmd> Add the given command to the session file
|
||||
(~/.lnav/session). Any commands listed in the session file
|
||||
are executed on startup. Only the highlight and
|
||||
are executed on startup. Only the highlight, word-wrap, and
|
||||
filter-related commands can be added to the session file.
|
||||
|
||||
create-logline-table <table-name>
|
||||
|
|
|
@ -148,6 +148,10 @@ public:
|
|||
int row,
|
||||
string_attrs_t &value_out);
|
||||
|
||||
size_t text_size_for_line(textview_curses &tc, int row, bool raw) {
|
||||
return 0;
|
||||
};
|
||||
|
||||
int value_for_row(vis_line_t row)
|
||||
{
|
||||
int grow = row / (this->buckets_per_group() + 1);
|
||||
|
|
|
@ -86,9 +86,14 @@ public:
|
|||
// if false is returned, the merge is complete
|
||||
bool get_top(owner_t *&owner, iterator_t& iterator)
|
||||
{
|
||||
owner = top_node_ptr_mbr->owner_ptr;
|
||||
iterator = top_node_ptr_mbr->current_iterator;
|
||||
return iterator != top_node_ptr_mbr->end_iterator;
|
||||
if (top_node_ptr_mbr->has_iterator) {
|
||||
owner = top_node_ptr_mbr->owner_ptr;
|
||||
iterator = top_node_ptr_mbr->current_iterator;
|
||||
return iterator != top_node_ptr_mbr->end_iterator;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -422,6 +427,7 @@ void kmerge_tree_c<T, owner_t, iterator_t, comparitor>::compare_nodes(kmerge_tre
|
|||
node_rec* parent_ptr = node_ptr->parent_ptr;
|
||||
|
||||
parent_ptr->owner_ptr = winner_ptr->owner_ptr;
|
||||
parent_ptr->has_iterator = winner_ptr->has_iterator;
|
||||
parent_ptr->current_iterator = winner_ptr->current_iterator;
|
||||
parent_ptr->end_iterator = winner_ptr->end_iterator;
|
||||
parent_ptr->source_node_ptr = winner_ptr;
|
||||
|
|
|
@ -49,6 +49,7 @@ listview_curses::listview_curses()
|
|||
lv_height(0),
|
||||
lv_needs_update(true),
|
||||
lv_show_scrollbar(true),
|
||||
lv_word_wrap(false),
|
||||
lv_mouse_y(-1),
|
||||
lv_mouse_mode(LV_MODE_NONE)
|
||||
{ }
|
||||
|
@ -102,12 +103,12 @@ bool listview_curses::handle_key(int ch)
|
|||
case 'b':
|
||||
case KEY_BACKSPACE:
|
||||
case KEY_PPAGE:
|
||||
this->shift_top(-height);
|
||||
this->shift_top(-(this->rows_available(this->lv_top, RD_UP) - vis_line_t(1)));
|
||||
break;
|
||||
|
||||
case ' ':
|
||||
case KEY_NPAGE:
|
||||
this->shift_top(height);
|
||||
this->shift_top(this->rows_available(this->lv_top, RD_DOWN) - vis_line_t(1));
|
||||
break;
|
||||
|
||||
case KEY_HOME:
|
||||
|
@ -115,10 +116,9 @@ bool listview_curses::handle_key(int ch)
|
|||
break;
|
||||
|
||||
case KEY_END: {
|
||||
vis_line_t tail_bottom(this->get_inner_height() - height + 1);
|
||||
vis_line_t last_line(this->get_inner_height() - 1);
|
||||
vis_line_t tail_bottom(this->get_top_for_last_row());
|
||||
|
||||
tail_bottom = max(vis_line_t(0), tail_bottom);
|
||||
if (this->get_top() == last_line)
|
||||
this->set_top(tail_bottom);
|
||||
else if (tail_bottom <= this->get_top())
|
||||
|
@ -155,7 +155,7 @@ bool listview_curses::handle_key(int ch)
|
|||
void listview_curses::do_update(void)
|
||||
{
|
||||
if (this->lv_window != NULL && this->lv_needs_update) {
|
||||
vis_line_t y(this->lv_y), height, bottom, lines, row;
|
||||
vis_line_t y(this->lv_y), height, bottom, row;
|
||||
attr_line_t overlay_line;
|
||||
vis_line_t overlay_height(0);
|
||||
struct line_range lr;
|
||||
|
@ -168,19 +168,13 @@ void listview_curses::do_update(void)
|
|||
}
|
||||
|
||||
this->get_dimensions(height, width);
|
||||
lr.lr_start = this->lv_left;
|
||||
lr.lr_end = this->lv_left + width;
|
||||
|
||||
row_count = this->get_inner_height();
|
||||
if (this->lv_top >= (int)row_count) {
|
||||
this->lv_top = max(vis_line_t(0), vis_line_t(row_count) - height);
|
||||
}
|
||||
|
||||
row = this->lv_top;
|
||||
lines = min(height - overlay_height,
|
||||
vis_line_t(row_count) - this->lv_top);
|
||||
bottom = y + height;
|
||||
for (; y < bottom; ++y) {
|
||||
while (y < bottom) {
|
||||
lr.lr_start = this->lv_left;
|
||||
lr.lr_end = this->lv_left + width;
|
||||
if (this->lv_overlay_source != NULL &&
|
||||
this->lv_overlay_source->list_value_for_overlay(
|
||||
*this,
|
||||
|
@ -188,24 +182,31 @@ void listview_curses::do_update(void)
|
|||
overlay_line)) {
|
||||
this->mvwattrline(this->lv_window, y, 0, overlay_line, lr);
|
||||
overlay_line.clear();
|
||||
++y;
|
||||
}
|
||||
else if (lines > 0) {
|
||||
else if (row < row_count) {
|
||||
attr_line_t al;
|
||||
|
||||
this->lv_source->listview_value_for_row(*this, row, al);
|
||||
this->mvwattrline(this->lv_window, y, 0, al, lr);
|
||||
--lines;
|
||||
do {
|
||||
this->mvwattrline(this->lv_window, y, 0, al, lr);
|
||||
lr.lr_start += width;
|
||||
lr.lr_end += width;
|
||||
++y;
|
||||
} while (this->lv_word_wrap && y < bottom && lr.lr_start < al.length());
|
||||
++row;
|
||||
}
|
||||
else {
|
||||
wmove(this->lv_window, y, 0);
|
||||
wclrtoeol(this->lv_window);
|
||||
++y;
|
||||
}
|
||||
}
|
||||
|
||||
if (this->lv_show_scrollbar) {
|
||||
double progress = 1.0;
|
||||
double coverage = 1.0;
|
||||
vis_line_t lines;
|
||||
|
||||
if (this->get_inner_height() > 0) {
|
||||
progress = (double)this->lv_top / (double)row_count;
|
||||
|
|
|
@ -66,6 +66,9 @@ public:
|
|||
vis_line_t row,
|
||||
attr_line_t &value_out) = 0;
|
||||
|
||||
virtual size_t listview_size_for_row(const listview_curses &lv,
|
||||
vis_line_t row) = 0;
|
||||
|
||||
virtual std::string listview_source_name(const listview_curses &lv) {
|
||||
return "";
|
||||
};
|
||||
|
@ -149,6 +152,49 @@ public:
|
|||
void set_show_scrollbar(bool ss) { this->lv_show_scrollbar = ss; };
|
||||
bool get_show_scrollbar() const { return this->lv_show_scrollbar; };
|
||||
|
||||
void set_word_wrap(bool ww) { this->lv_word_wrap = ww; };
|
||||
bool get_word_wrap() const { return this->lv_word_wrap; };
|
||||
|
||||
enum row_direction_t {
|
||||
RD_UP = -1,
|
||||
RD_DOWN = 1,
|
||||
};
|
||||
|
||||
vis_line_t rows_available(vis_line_t line, row_direction_t dir) {
|
||||
unsigned long width;
|
||||
vis_line_t height;
|
||||
vis_line_t retval(0);
|
||||
|
||||
this->get_dimensions(height, width);
|
||||
if (this->lv_word_wrap) {
|
||||
size_t row_count = this->lv_source->listview_rows(*this);
|
||||
|
||||
while ((height > 0) && (line >= 0) && (line < row_count)) {
|
||||
size_t len = this->lv_source->listview_size_for_row(*this, line);
|
||||
|
||||
do {
|
||||
len -= std::min(width, len);
|
||||
--height;
|
||||
} while (len > 0);
|
||||
line += vis_line_t(dir);
|
||||
++retval;
|
||||
}
|
||||
}
|
||||
else {
|
||||
switch (dir) {
|
||||
case RD_UP:
|
||||
retval = std::min(height, line + vis_line_t(1));
|
||||
break;
|
||||
case RD_DOWN:
|
||||
retval = std::min(height,
|
||||
vis_line_t(this->lv_source->listview_rows(*this) - line));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
/** @param win The curses window this view is attached to. */
|
||||
void set_window(WINDOW *win) { this->lv_window = win; };
|
||||
|
||||
|
@ -192,12 +238,24 @@ public:
|
|||
/** @return The line number that is displayed at the bottom. */
|
||||
vis_line_t get_bottom()
|
||||
{
|
||||
vis_line_t retval, height;
|
||||
unsigned long width;
|
||||
vis_line_t retval = this->lv_top;
|
||||
|
||||
this->get_dimensions(height, width);
|
||||
retval = std::min(this->lv_top + height - vis_line_t(1),
|
||||
vis_line_t(this->get_inner_height() - 1));
|
||||
retval += vis_line_t(this->rows_available(retval, RD_DOWN) - 1);
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
vis_line_t get_top_for_last_row() {
|
||||
vis_line_t retval(0);
|
||||
|
||||
if (this->get_inner_height() > 0) {
|
||||
vis_line_t last_line(this->get_inner_height() - 1);
|
||||
|
||||
retval = last_line - vis_line_t(this->rows_available(last_line, RD_UP) - 1);
|
||||
if ((retval + 1) < this->get_inner_height()) {
|
||||
++retval;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
@ -259,7 +317,10 @@ public:
|
|||
*/
|
||||
unsigned int shift_left(int offset)
|
||||
{
|
||||
if (offset < 0 && this->lv_left < (unsigned int)-offset) {
|
||||
if (this->lv_word_wrap) {
|
||||
alerter::singleton().chime();
|
||||
}
|
||||
else if (offset < 0 && this->lv_left < (unsigned int)-offset) {
|
||||
this->set_left(0);
|
||||
}
|
||||
else {
|
||||
|
@ -353,6 +414,7 @@ protected:
|
|||
* is needed.
|
||||
*/
|
||||
bool lv_show_scrollbar; /*< Draw the scrollbar in the view. */
|
||||
bool lv_word_wrap;
|
||||
|
||||
struct timeval lv_mouse_time;
|
||||
int lv_scroll_accel;
|
||||
|
|
30
src/lnav.cc
30
src/lnav.cc
|
@ -529,10 +529,9 @@ void rebuild_indexes(bool force)
|
|||
logfile_sub_source &lss = lnav_data.ld_log_source;
|
||||
textview_curses & log_view = lnav_data.ld_views[LNV_LOG];
|
||||
textview_curses & text_view = lnav_data.ld_views[LNV_TEXT];
|
||||
vis_line_t old_bottom(0), height(0);
|
||||
vis_line_t old_bottom(0);
|
||||
content_line_t top_content = content_line_t(-1);
|
||||
|
||||
unsigned long width;
|
||||
bool scroll_down;
|
||||
size_t old_count;
|
||||
time_t old_time;
|
||||
|
@ -552,9 +551,8 @@ void rebuild_indexes(bool force)
|
|||
bool new_data = false;
|
||||
size_t new_count;
|
||||
|
||||
text_view.get_dimensions(height, width);
|
||||
old_bottom = text_view.get_top() + height;
|
||||
scroll_down = (size_t)old_bottom > tss->text_line_count();
|
||||
old_bottom = text_view.get_top_for_last_row();
|
||||
scroll_down = text_view.get_top() >= old_bottom;
|
||||
|
||||
for (iter = tss->tss_files.begin();
|
||||
iter != tss->tss_files.end(); ) {
|
||||
|
@ -619,15 +617,14 @@ void rebuild_indexes(bool force)
|
|||
text_view.reload_data();
|
||||
|
||||
new_count = tss->text_line_count();
|
||||
if (scroll_down && new_count >= (size_t)old_bottom) {
|
||||
text_view.set_top(vis_line_t(new_count - height + 1));
|
||||
if (scroll_down && text_view.get_top_for_last_row() > text_view.get_top()) {
|
||||
text_view.set_top(text_view.get_top_for_last_row());
|
||||
}
|
||||
}
|
||||
|
||||
old_time = lnav_data.ld_top_time;
|
||||
log_view.get_dimensions(height, width);
|
||||
old_bottom = log_view.get_top() + height;
|
||||
scroll_down = (size_t)old_bottom > old_count;
|
||||
old_bottom = log_view.get_top_for_last_row();
|
||||
scroll_down = log_view.get_top() >= old_bottom;
|
||||
if (force) {
|
||||
old_count = 0;
|
||||
}
|
||||
|
@ -638,8 +635,8 @@ void rebuild_indexes(bool force)
|
|||
|
||||
log_view.reload_data();
|
||||
|
||||
if (scroll_down && new_count >= (size_t)old_bottom) {
|
||||
log_view.set_top(vis_line_t(new_count - height + 1));
|
||||
if (scroll_down && log_view.get_top_for_last_row() > log_view.get_top()) {
|
||||
log_view.set_top(log_view.get_top_for_last_row());
|
||||
}
|
||||
else if (!scroll_down && force) {
|
||||
content_line_t new_top_content = content_line_t(-1);
|
||||
|
@ -658,6 +655,9 @@ void rebuild_indexes(bool force)
|
|||
start_line = force ? grep_line_t(0) : grep_line_t(-1);
|
||||
|
||||
if (force) {
|
||||
if (lnav_data.ld_search_child[LNV_LOG].get() != NULL) {
|
||||
lnav_data.ld_search_child[LNV_LOG]->get_grep_proc()->invalidate();
|
||||
}
|
||||
log_view.match_reset();
|
||||
}
|
||||
|
||||
|
@ -707,6 +707,10 @@ public:
|
|||
value_out = this->tds_lines[row];
|
||||
};
|
||||
|
||||
size_t text_size_for_line(textview_curses &tc, int row, bool raw) {
|
||||
return this->tds_lines[row].length();
|
||||
};
|
||||
|
||||
private:
|
||||
vector<string> tds_lines;
|
||||
};
|
||||
|
@ -1981,7 +1985,7 @@ void execute_search(lnav_view_t view, const std::string ®ex)
|
|||
}
|
||||
gc.reset();
|
||||
|
||||
fprintf(stderr, "start search for: %s\n", regex.c_str());
|
||||
fprintf(stderr, "start search for: '%s'\n", regex.c_str());
|
||||
|
||||
if (regex.empty()) {
|
||||
lnav_data.ld_bottom_source.grep_error("");
|
||||
|
|
|
@ -592,6 +592,36 @@ static string com_disable_filter(string cmdline, vector<string> &args)
|
|||
return retval;
|
||||
}
|
||||
|
||||
static string com_enable_word_wrap(string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "";
|
||||
|
||||
if (args.size() == 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
lnav_data.ld_views[LNV_LOG].set_word_wrap(true);
|
||||
lnav_data.ld_views[LNV_TEXT].set_word_wrap(true);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static string com_disable_word_wrap(string cmdline, vector<string> &args)
|
||||
{
|
||||
string retval = "";
|
||||
|
||||
if (args.size() == 0) {
|
||||
|
||||
}
|
||||
else {
|
||||
lnav_data.ld_views[LNV_LOG].set_word_wrap(false);
|
||||
lnav_data.ld_views[LNV_TEXT].set_word_wrap(false);
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static std::vector<string> custom_logline_tables;
|
||||
|
||||
static string com_create_logline_table(string cmdline, vector<string> &args)
|
||||
|
@ -656,14 +686,16 @@ static string com_session(string cmdline, vector<string> &args)
|
|||
string retval = "error: expecting a command to save to the session file";
|
||||
|
||||
if (args.size() == 0) {}
|
||||
else if (args.size() > 2) {
|
||||
else if (args.size() >= 2) {
|
||||
/* XXX put these in a map */
|
||||
if (args[1] != "highlight" &&
|
||||
args[1] != "enable-word-wrap" &&
|
||||
args[1] != "disable-word-wrap" &&
|
||||
args[1] != "filter-in" &&
|
||||
args[1] != "filter-out" &&
|
||||
args[1] != "enable-filter" &&
|
||||
args[1] != "disable-filter") {
|
||||
retval = "error: only the highlight and filter commands are "
|
||||
retval = "error: only the highlight, filter, and word-wrap commands are "
|
||||
"supported";
|
||||
}
|
||||
else if (getenv("HOME") == NULL) {
|
||||
|
@ -1130,6 +1162,8 @@ void init_lnav_commands(readline_context::command_map_t &cmd_map)
|
|||
cmd_map["write-csv-to"] = com_save_to;
|
||||
cmd_map["enable-filter"] = com_enable_filter;
|
||||
cmd_map["disable-filter"] = com_disable_filter;
|
||||
cmd_map["enable-word-wrap"] = com_enable_word_wrap;
|
||||
cmd_map["disable-word-wrap"] = com_disable_word_wrap;
|
||||
cmd_map["create-logline-table"] = com_create_logline_table;
|
||||
cmd_map["delete-logline-table"] = com_delete_logline_table;
|
||||
cmd_map["open"] = com_open;
|
||||
|
|
|
@ -225,6 +225,20 @@ public:
|
|||
return retval;
|
||||
};
|
||||
|
||||
size_t line_length(iterator ll) {
|
||||
iterator next_line = ll + 1;
|
||||
size_t retval;
|
||||
|
||||
if (next_line == this->end()) {
|
||||
retval = this->lf_index_size - ll->get_offset();
|
||||
}
|
||||
else {
|
||||
retval = next_line->get_offset() - ll->get_offset() - 1;
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
void read_full_message(iterator ll, std::string &msg_out, int max_lines=50);
|
||||
|
||||
/**
|
||||
|
|
|
@ -170,8 +170,6 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc,
|
|||
{
|
||||
content_line_t line(0);
|
||||
|
||||
size_t tab;
|
||||
|
||||
assert(row >= 0);
|
||||
assert((size_t)row < this->lss_index.size());
|
||||
|
||||
|
@ -189,10 +187,6 @@ void logfile_sub_source::text_value_for_line(textview_curses &tc,
|
|||
this->lss_token_value =
|
||||
this->lss_token_file->read_line(this->lss_token_line);
|
||||
|
||||
while ((tab = this->lss_token_value.find('\t')) != string::npos) {
|
||||
this->lss_token_value = this->lss_token_value.replace(tab, 1, 8, ' ');
|
||||
}
|
||||
|
||||
this->lss_token_date_end = 0;
|
||||
value_out = this->lss_token_value;
|
||||
if (this->lss_flags & F_SCRUB) {
|
||||
|
|
|
@ -130,6 +130,14 @@ public:
|
|||
int row,
|
||||
string_attrs_t &value_out);
|
||||
|
||||
size_t text_size_for_line(textview_curses &tc, int row, bool raw) {
|
||||
content_line_t line = this->lss_index[row];
|
||||
logfile *lf = this->find(line);
|
||||
logfile::iterator ll = lf->begin() + line;
|
||||
|
||||
return lf->line_length(ll) + (this->lss_flags & F_TIME_OFFSET ? 13 : 0);
|
||||
};
|
||||
|
||||
void text_mark(bookmark_type_t *bm, int line, bool added)
|
||||
{
|
||||
content_line_t cl = this->lss_index[line];
|
||||
|
|
|
@ -450,8 +450,9 @@ static void load_time_bookmarks(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (part_name == NULL)
|
||||
if (part_name == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!dts.scan(log_time, NULL, &log_tm, log_tv)) {
|
||||
continue;
|
||||
|
@ -530,7 +531,7 @@ static void load_time_bookmarks(void)
|
|||
|
||||
lss.find(lf->get_filename().c_str(), base_content_line);
|
||||
|
||||
fprintf(stderr, "checking bookmarks for %s\n", lf->get_filename().c_str());
|
||||
fprintf(stderr, "checking time offsets for %s\n", lf->get_filename().c_str());
|
||||
|
||||
logfile::iterator line_iter = lf->begin();
|
||||
|
||||
|
@ -687,7 +688,7 @@ static int read_last_search(yajlpp_parse_context *ypc, const unsigned char *str,
|
|||
ypc->get_path_fragment(-2));
|
||||
view_index = view_name - lnav_view_strings;
|
||||
|
||||
if (view_index < LNV__MAX) {
|
||||
if (view_index < LNV__MAX && !regex.empty()) {
|
||||
execute_search((lnav_view_t)view_index, regex);
|
||||
lnav_data.ld_views[view_index].set_follow_search(false);
|
||||
}
|
||||
|
@ -786,6 +787,7 @@ static void save_time_bookmarks(void)
|
|||
auto_mem<sqlite3_stmt> stmt(sqlite3_finalize);
|
||||
|
||||
if (sqlite3_open(db_path.c_str(), db.out()) != SQLITE_OK) {
|
||||
fprintf(stderr, "error: unable to open bookmark DB -- %s\n", db_path.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -813,7 +815,7 @@ static void save_time_bookmarks(void)
|
|||
stmt.out(),
|
||||
NULL) != SQLITE_OK) {
|
||||
fprintf(stderr,
|
||||
"error: could not prepare bookmark replace statemnt -- %s\n",
|
||||
"error: could not prepare bookmark delete statemnt -- %s\n",
|
||||
sqlite3_errmsg(db));
|
||||
return;
|
||||
}
|
||||
|
@ -1065,7 +1067,7 @@ static void save_time_bookmarks(void)
|
|||
}
|
||||
|
||||
if (sqlite3_bind_int64(stmt.in(), 6, offset.tv_usec) != SQLITE_OK) {
|
||||
fprintf(stderr, "error: could not bind offset_sec -- %s\n",
|
||||
fprintf(stderr, "error: could not bind offset_usec -- %s\n",
|
||||
sqlite3_errmsg(db.in()));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -410,7 +410,7 @@ void sql_strftime(char *buffer, size_t buffer_size, time_t time, int millis)
|
|||
|
||||
gmtime_r(&time, &gmtm);
|
||||
snprintf(buffer, buffer_size,
|
||||
"% 4d-%02d-%02dT%02d:%02d:%02d.%03d",
|
||||
"%4d-%02d-%02dT%02d:%02d:%02d.%03d",
|
||||
gmtm.tm_year + 1900,
|
||||
gmtm.tm_mon + 1,
|
||||
gmtm.tm_mday,
|
||||
|
|
|
@ -81,6 +81,16 @@ public:
|
|||
value_out[lr].insert(make_string_attr("file", this->current_file()));
|
||||
};
|
||||
|
||||
size_t text_size_for_line(textview_curses &tc, int line, bool raw) {
|
||||
size_t retval = 0;
|
||||
|
||||
if (!this->tss_files.empty()) {
|
||||
retval = this->current_file()->line_length(this->current_file()->begin() + line);
|
||||
}
|
||||
|
||||
return retval;
|
||||
};
|
||||
|
||||
logfile *current_file(void) const
|
||||
{
|
||||
if (this->tss_files.empty()) {
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
std::string &value_out,
|
||||
bool raw = false) = 0;
|
||||
|
||||
virtual size_t text_size_for_line(textview_curses &tc, int line, bool raw = false) = 0;
|
||||
|
||||
/**
|
||||
* Inform the source that the given line has been marked/unmarked. This
|
||||
* callback function can be used to translate between between visible line
|
||||
|
@ -350,6 +352,10 @@ public:
|
|||
vis_line_t line,
|
||||
attr_line_t &value_out);
|
||||
|
||||
size_t listview_size_for_row(const listview_curses &lv, vis_line_t row) {
|
||||
return this->tc_sub_source->text_size_for_line(*this, row);
|
||||
};
|
||||
|
||||
std::string listview_source_name(const listview_curses &lv) {
|
||||
return this->tc_sub_source == NULL ? "" :
|
||||
this->tc_sub_source->text_source_name(*this);
|
||||
|
|
|
@ -213,6 +213,8 @@ public:
|
|||
/** @return The attributes for the string. */
|
||||
string_attrs_t &get_attrs() { return this->al_attrs; };
|
||||
|
||||
size_t length() const { return this->al_string.length(); };
|
||||
|
||||
void operator=(const std::string &rhs) { this->al_string = rhs; };
|
||||
|
||||
/** Clear the string and the attributes for the string. */
|
||||
|
|
|
@ -69,6 +69,10 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
size_t listview_size_for_row(const listview_curses &lv, vis_line_t row) {
|
||||
return 100;
|
||||
};
|
||||
|
||||
bool attrline_next_token(const view_curses &vc,
|
||||
int line,
|
||||
struct line_range &lr,
|
||||
|
|
Loading…
Reference in New Issue