mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 15:16:40 +08:00
Modernize screen_t
Use inline initializers rather than the constructor, and adopt some maybe_t. Also move post_buff_1 and post_buff_2 to local variables instead of member variables.
This commit is contained in:
parent
520c83cbbf
commit
81af389258
|
@ -46,12 +46,6 @@
|
|||
/// The number of characters to indent new blocks.
|
||||
#define INDENT_STEP 4u
|
||||
|
||||
/// The initial screen width.
|
||||
#define SCREEN_WIDTH_UNINITIALIZED (-1)
|
||||
|
||||
/// A helper value for an invalid location.
|
||||
#define INVALID_LOCATION (screen_data_t::cursor_t(-1, -1))
|
||||
|
||||
static void invalidate_soft_wrap(screen_t *scr);
|
||||
|
||||
/// RAII class to begin and end buffering around stdoutput().
|
||||
|
@ -337,8 +331,8 @@ static size_t calc_prompt_lines(const wcstring &prompt) {
|
|||
/// Stat stdout and stderr and save result. This should be done before calling a function that may
|
||||
/// cause output.
|
||||
void s_save_status(screen_t *s) {
|
||||
fstat(1, &s->prev_buff_1);
|
||||
fstat(2, &s->prev_buff_2);
|
||||
fstat(STDOUT_FILENO, &s->prev_buff_1);
|
||||
fstat(STDERR_FILENO, &s->prev_buff_2);
|
||||
}
|
||||
|
||||
/// Stat stdout and stderr and compare result to previous result in reader_save_status. Repaint if
|
||||
|
@ -356,19 +350,20 @@ static void s_check_status(screen_t *s) {
|
|||
return;
|
||||
}
|
||||
|
||||
fstat(1, &s->post_buff_1);
|
||||
fstat(2, &s->post_buff_2);
|
||||
struct stat post_buff_1 {};
|
||||
struct stat post_buff_2 {};
|
||||
fstat(STDOUT_FILENO, &post_buff_1);
|
||||
fstat(STDERR_FILENO, &post_buff_2);
|
||||
|
||||
bool changed = (s->prev_buff_1.st_mtime != s->post_buff_1.st_mtime) ||
|
||||
(s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime);
|
||||
bool changed = (s->prev_buff_1.st_mtime != post_buff_1.st_mtime) ||
|
||||
(s->prev_buff_2.st_mtime != post_buff_2.st_mtime);
|
||||
|
||||
#if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||
changed = changed ||
|
||||
s->prev_buff_1.st_mtimespec.tv_nsec != s->post_buff_1.st_mtimespec.tv_nsec ||
|
||||
s->prev_buff_2.st_mtimespec.tv_nsec != s->post_buff_2.st_mtimespec.tv_nsec;
|
||||
changed = changed || s->prev_buff_1.st_mtimespec.tv_nsec != post_buff_1.st_mtimespec.tv_nsec ||
|
||||
s->prev_buff_2.st_mtimespec.tv_nsec != post_buff_2.st_mtimespec.tv_nsec;
|
||||
#elif defined HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
|
||||
changed = changed || s->prev_buff_1.st_mtim.tv_nsec != s->post_buff_1.st_mtim.tv_nsec ||
|
||||
s->prev_buff_2.st_mtim.tv_nsec != s->post_buff_2.st_mtim.tv_nsec;
|
||||
changed = changed || s->prev_buff_1.st_mtim.tv_nsec != post_buff_1.st_mtim.tv_nsec ||
|
||||
s->prev_buff_2.st_mtim.tv_nsec != post_buff_2.st_mtim.tv_nsec;
|
||||
#endif
|
||||
|
||||
if (changed) {
|
||||
|
@ -537,8 +532,7 @@ static void s_write_char(screen_t *s, wchar_t c, size_t width) {
|
|||
s->actual.cursor.x += width;
|
||||
s->outp().writech(c);
|
||||
if (s->actual.cursor.x == s->actual_width && allow_soft_wrap()) {
|
||||
s->soft_wrap_location.x = 0;
|
||||
s->soft_wrap_location.y = s->actual.cursor.y + 1;
|
||||
s->soft_wrap_location = screen_data_t::cursor_t{0, s->actual.cursor.y + 1};
|
||||
|
||||
// Note that our cursor position may be a lie: Apple Terminal makes the right cursor stick
|
||||
// to the margin, while Ubuntu makes it "go off the end" (but still doesn't wrap). We rely
|
||||
|
@ -592,20 +586,21 @@ static size_t line_shared_prefix(const line_t &a, const line_t &b) {
|
|||
// we believe we are already in the target position. This lets the terminal take care of wrapping,
|
||||
// which means that if you copy and paste the text, it won't have an embedded newline.
|
||||
static bool perform_any_impending_soft_wrap(screen_t *scr, int x, int y) {
|
||||
if (x == scr->soft_wrap_location.x && y == scr->soft_wrap_location.y) { //!OCLINT
|
||||
if (scr->soft_wrap_location && x == scr->soft_wrap_location->x &&
|
||||
y == scr->soft_wrap_location->y) { //!OCLINT
|
||||
// We can soft wrap; but do we want to?
|
||||
if (scr->desired.line(y - 1).is_soft_wrapped && allow_soft_wrap()) {
|
||||
// Yes. Just update the actual cursor; that will cause us to elide emitting the commands
|
||||
// to move here, so we will just output on "one big line" (which the terminal soft
|
||||
// wraps.
|
||||
scr->actual.cursor = scr->soft_wrap_location;
|
||||
scr->actual.cursor = scr->soft_wrap_location.value();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Make sure we don't soft wrap.
|
||||
static void invalidate_soft_wrap(screen_t *scr) { scr->soft_wrap_location = INVALID_LOCATION; }
|
||||
static void invalidate_soft_wrap(screen_t *scr) { scr->soft_wrap_location = none(); }
|
||||
|
||||
/// Update the screen to match the desired output.
|
||||
static void s_update(screen_t *scr, const wcstring &left_prompt, const wcstring &right_prompt) {
|
||||
|
@ -628,7 +623,7 @@ static void s_update(screen_t *scr, const wcstring &left_prompt, const wcstring
|
|||
|
||||
if (scr->actual_width != screen_width) {
|
||||
// Ensure we don't issue a clear screen for the very first output, to avoid issue #402.
|
||||
if (scr->actual_width != SCREEN_WIDTH_UNINITIALIZED) {
|
||||
if (scr->actual_width > 0) {
|
||||
need_clear_screen = true;
|
||||
s_move(scr, 0, 0);
|
||||
s_reset(scr, screen_reset_mode_t::current_line_contents);
|
||||
|
@ -1226,16 +1221,4 @@ void screen_force_clear_to_end() {
|
|||
}
|
||||
}
|
||||
|
||||
screen_t::screen_t()
|
||||
: outp_(outputter_t::stdoutput()),
|
||||
last_right_prompt_width(),
|
||||
actual_width(SCREEN_WIDTH_UNINITIALIZED),
|
||||
soft_wrap_location(INVALID_LOCATION),
|
||||
autosuggestion_is_truncated(false),
|
||||
need_clear_lines(false),
|
||||
need_clear_screen(false),
|
||||
actual_lines_before_reset(0),
|
||||
prev_buff_1(),
|
||||
prev_buff_2(),
|
||||
post_buff_1(),
|
||||
post_buff_2() {}
|
||||
screen_t::screen_t() : outp_(outputter_t::stdoutput()) {}
|
||||
|
|
33
src/screen.h
33
src/screen.h
|
@ -74,9 +74,9 @@ class screen_data_t {
|
|||
|
||||
public:
|
||||
struct cursor_t {
|
||||
int x;
|
||||
int y;
|
||||
cursor_t() : x(0), y(0) {}
|
||||
int x{0};
|
||||
int y{0};
|
||||
cursor_t() = default;
|
||||
cursor_t(int a, int b) : x(a), y(b) {}
|
||||
} cursor;
|
||||
|
||||
|
@ -119,37 +119,38 @@ class screen_t {
|
|||
outputter_t &outp_;
|
||||
|
||||
public:
|
||||
/// Constructor.
|
||||
screen_t();
|
||||
|
||||
/// The internal representation of the desired screen contents.
|
||||
screen_data_t desired;
|
||||
screen_data_t desired{};
|
||||
/// The internal representation of the actual screen contents.
|
||||
screen_data_t actual;
|
||||
screen_data_t actual{};
|
||||
/// A string containing the prompt which was last printed to the screen.
|
||||
wcstring actual_left_prompt;
|
||||
wcstring actual_left_prompt{};
|
||||
/// Last right prompt width.
|
||||
size_t last_right_prompt_width;
|
||||
/// The actual width of the screen at the time of the last screen write.
|
||||
int actual_width;
|
||||
size_t last_right_prompt_width{0};
|
||||
/// The actual width of the screen at the time of the last screen write, or negative if not yet
|
||||
/// set.
|
||||
int actual_width{-1};
|
||||
/// If we support soft wrapping, we can output to this location without any cursor motion.
|
||||
screen_data_t::cursor_t soft_wrap_location;
|
||||
maybe_t<screen_data_t::cursor_t> soft_wrap_location{};
|
||||
/// Whether the last-drawn autosuggestion (if any) is truncated, or hidden entirely.
|
||||
bool autosuggestion_is_truncated;
|
||||
bool autosuggestion_is_truncated{false};
|
||||
/// This flag is set to true when there is reason to suspect that the parts of the screen lines
|
||||
/// where the actual content is not filled in may be non-empty. This means that a clr_eol
|
||||
/// command has to be sent to the terminal at the end of each line, including
|
||||
/// actual_lines_before_reset.
|
||||
bool need_clear_lines;
|
||||
bool need_clear_lines{false};
|
||||
/// Whether there may be yet more content after the lines, and we issue a clr_eos if possible.
|
||||
bool need_clear_screen;
|
||||
bool need_clear_screen{false};
|
||||
/// If we need to clear, this is how many lines the actual screen had, before we reset it. This
|
||||
/// is used when resizing the window larger: if the cursor jumps to the line above, we need to
|
||||
/// remember to clear the subsequent lines.
|
||||
size_t actual_lines_before_reset;
|
||||
size_t actual_lines_before_reset{0};
|
||||
/// These status buffers are used to check if any output has occurred other than from fish's
|
||||
/// main loop, in which case we need to redraw.
|
||||
struct stat prev_buff_1, prev_buff_2, post_buff_1, post_buff_2;
|
||||
struct stat prev_buff_1 {};
|
||||
struct stat prev_buff_2 {};
|
||||
|
||||
/// \return the outputter for this screen.
|
||||
outputter_t &outp() { return outp_; }
|
||||
|
|
Loading…
Reference in New Issue
Block a user