fish-shell/src/pager.h

183 lines
5.8 KiB
C
Raw Normal View History

// Pager support.
#ifndef FISH_PAGER_H
#define FISH_PAGER_H
2015-07-25 23:14:25 +08:00
#include <stddef.h>
#include <memory>
2015-07-25 23:14:25 +08:00
#include <string>
#include <vector>
2015-07-25 23:14:25 +08:00
#include "common.h"
2013-12-08 04:43:40 +08:00
#include "complete.h"
#include "reader.h"
#include "screen.h"
2013-12-08 04:43:40 +08:00
#define PAGER_SELECTION_NONE ((size_t)(-1))
/// Represents rendering from the pager.
class page_rendering_t {
public:
size_t term_width;
size_t term_height;
size_t rows;
size_t cols;
size_t row_start;
size_t row_end;
size_t selected_completion_idx;
2013-12-08 04:43:40 +08:00
screen_data_t screen_data;
2014-04-01 01:01:39 +08:00
size_t remaining_to_disclose;
2014-04-01 01:01:39 +08:00
bool search_field_shown;
editable_line_t search_field_line;
2014-04-01 01:01:39 +08:00
// Returns a rendering with invalid data, useful to indicate "no rendering".
page_rendering_t();
2013-12-08 04:43:40 +08:00
};
// The space between adjacent completions.
#define PAGER_SPACER_STRING L" "
#define PAGER_SPACER_STRING_WIDTH 2
// How many rows we will show in the "initial" pager.
#define PAGER_UNDISCLOSED_MAX_ROWS 4
2013-12-08 04:43:40 +08:00
typedef std::vector<completion_t> completion_list_t;
class pager_t {
size_t available_term_width;
size_t available_term_height;
2014-04-01 01:01:39 +08:00
size_t selected_completion_idx;
size_t suggested_row_start;
2014-04-01 01:01:39 +08:00
// Fully disclosed means that we show all completions.
bool fully_disclosed;
2014-04-01 01:01:39 +08:00
// Whether we show the search field.
bool search_field_shown;
2014-04-01 01:01:39 +08:00
// Returns the index of the completion that should draw selected, using the given number of
// columns.
size_t visual_selected_completion_index(size_t rows, size_t cols) const;
2014-04-01 01:01:39 +08:00
public:
/// Data structure describing one or a group of related completions.
struct comp_t {
/// The list of all completin strings this entry applies to.
wcstring_list_t comp;
/// The description.
wcstring desc;
/// The representative completion.
completion_t representative;
/// On-screen width of the completion string.
size_t comp_width;
/// On-screen width of the description information.
size_t desc_width;
/// Minimum acceptable width.
2016-12-04 12:12:53 +08:00
// size_t min_width;
2014-04-01 01:01:39 +08:00
2016-12-04 12:12:53 +08:00
comp_t() : comp(), desc(), representative(L""), comp_width(0), desc_width(0) {}
// Our text looks like this:
// completion (description)
// Two spaces separating, plus parens, yields 4 total extra space
// but only if we have a description of course
size_t description_punctuated_width() const {
return this->desc_width + (this->desc_width ? 4 : 0);
}
// Returns the preferred width, containing the sum of the
// width of the completion, separator, description
size_t preferred_width() const {
return this->comp_width + this->description_punctuated_width();
}
};
2014-04-01 01:01:39 +08:00
private:
typedef std::vector<comp_t> comp_info_list_t;
2014-04-01 01:01:39 +08:00
// The filtered list of completion infos.
comp_info_list_t completion_infos;
2014-04-01 01:01:39 +08:00
// The unfiltered list. Note there's a lot of duplication here.
comp_info_list_t unfiltered_completion_infos;
2014-04-01 01:01:39 +08:00
wcstring prefix;
2014-04-01 01:01:39 +08:00
bool completion_try_print(size_t cols, const wcstring &prefix, const comp_info_list_t &lst,
page_rendering_t *rendering, size_t suggested_start_row) const;
2014-04-01 01:01:39 +08:00
void recalc_min_widths(comp_info_list_t *lst) const;
void measure_completion_infos(std::vector<comp_t> *infos, const wcstring &prefix) const;
2014-04-01 01:01:39 +08:00
bool completion_info_passes_filter(const comp_t &info) const;
2014-04-01 01:01:39 +08:00
2016-12-04 12:12:53 +08:00
void completion_print(size_t cols, const size_t *width_per_column, size_t row_start,
size_t row_stop, const wcstring &prefix, const comp_info_list_t &lst,
page_rendering_t *rendering) const;
line_t completion_print_item(const wcstring &prefix, const comp_t *c, size_t row, size_t column,
size_t width, bool secondary, bool selected,
page_rendering_t *rendering) const;
2014-04-01 01:01:39 +08:00
public:
// The text of the search field.
editable_line_t search_field_line;
2014-04-01 01:01:39 +08:00
// Sets the set of completions.
void set_completions(const completion_list_t &comp);
2014-04-01 01:01:39 +08:00
// Sets the prefix.
void set_prefix(const wcstring &pref);
2014-04-01 01:01:39 +08:00
// Sets the terminal width and height.
void set_term_size(int w, int h);
2014-04-01 01:01:39 +08:00
// Changes the selected completion in the given direction according to the layout of the given
// rendering. Returns true if the selection changed.
bool select_next_completion_in_direction(selection_direction_t direction,
const page_rendering_t &rendering);
2014-04-01 01:01:39 +08:00
// Returns the currently selected completion for the given rendering.
const completion_t *selected_completion(const page_rendering_t &rendering) const;
2014-04-01 01:01:39 +08:00
// Indicates the row and column for the given rendering. Returns -1 if no selection.
size_t get_selected_row(const page_rendering_t &rendering) const;
size_t get_selected_column(const page_rendering_t &rendering) const;
2014-04-01 01:01:39 +08:00
// Produces a rendering of the completions, at the given term size.
page_rendering_t render() const;
2014-04-01 01:01:39 +08:00
// Updates the rendering if it's stale.
void update_rendering(page_rendering_t *rendering) const;
2014-04-01 01:01:39 +08:00
// Indicates if there are no completions, and therefore nothing to render.
bool empty() const;
2014-04-01 01:01:39 +08:00
// Clears all completions and the prefix.
void clear();
2014-04-01 01:01:39 +08:00
// Updates the completions list per the filter.
void refilter_completions();
2014-04-01 01:01:39 +08:00
// Sets whether the search field is shown.
void set_search_field_shown(bool flag);
// Gets whether the search field shown.
bool is_search_field_shown() const;
2014-04-01 01:01:39 +08:00
// Indicates if we are navigating our contents.
bool is_navigating_contents() const;
2014-04-01 01:01:39 +08:00
// Become fully disclosed.
void set_fully_disclosed(bool flag);
2014-04-01 01:01:39 +08:00
// Position of the cursor.
size_t cursor_position() const;
2014-04-01 01:01:39 +08:00
// Constructor
pager_t();
};
#endif