mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-23 18:30:20 +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.
|
/// The number of characters to indent new blocks.
|
||||||
#define INDENT_STEP 4u
|
#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);
|
static void invalidate_soft_wrap(screen_t *scr);
|
||||||
|
|
||||||
/// RAII class to begin and end buffering around stdoutput().
|
/// 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
|
/// Stat stdout and stderr and save result. This should be done before calling a function that may
|
||||||
/// cause output.
|
/// cause output.
|
||||||
void s_save_status(screen_t *s) {
|
void s_save_status(screen_t *s) {
|
||||||
fstat(1, &s->prev_buff_1);
|
fstat(STDOUT_FILENO, &s->prev_buff_1);
|
||||||
fstat(2, &s->prev_buff_2);
|
fstat(STDERR_FILENO, &s->prev_buff_2);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stat stdout and stderr and compare result to previous result in reader_save_status. Repaint if
|
/// 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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fstat(1, &s->post_buff_1);
|
struct stat post_buff_1 {};
|
||||||
fstat(2, &s->post_buff_2);
|
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) ||
|
bool changed = (s->prev_buff_1.st_mtime != post_buff_1.st_mtime) ||
|
||||||
(s->prev_buff_2.st_mtime != s->post_buff_2.st_mtime);
|
(s->prev_buff_2.st_mtime != post_buff_2.st_mtime);
|
||||||
|
|
||||||
#if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
#if defined HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
|
||||||
changed = changed ||
|
changed = changed || s->prev_buff_1.st_mtimespec.tv_nsec != post_buff_1.st_mtimespec.tv_nsec ||
|
||||||
s->prev_buff_1.st_mtimespec.tv_nsec != s->post_buff_1.st_mtimespec.tv_nsec ||
|
s->prev_buff_2.st_mtimespec.tv_nsec != post_buff_2.st_mtimespec.tv_nsec;
|
||||||
s->prev_buff_2.st_mtimespec.tv_nsec != s->post_buff_2.st_mtimespec.tv_nsec;
|
|
||||||
#elif defined HAVE_STRUCT_STAT_ST_MTIM_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 ||
|
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 != s->post_buff_2.st_mtim.tv_nsec;
|
s->prev_buff_2.st_mtim.tv_nsec != post_buff_2.st_mtim.tv_nsec;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (changed) {
|
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->actual.cursor.x += width;
|
||||||
s->outp().writech(c);
|
s->outp().writech(c);
|
||||||
if (s->actual.cursor.x == s->actual_width && allow_soft_wrap()) {
|
if (s->actual.cursor.x == s->actual_width && allow_soft_wrap()) {
|
||||||
s->soft_wrap_location.x = 0;
|
s->soft_wrap_location = screen_data_t::cursor_t{0, s->actual.cursor.y + 1};
|
||||||
s->soft_wrap_location.y = s->actual.cursor.y + 1;
|
|
||||||
|
|
||||||
// Note that our cursor position may be a lie: Apple Terminal makes the right cursor stick
|
// 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
|
// 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,
|
// 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.
|
// 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) {
|
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?
|
// We can soft wrap; but do we want to?
|
||||||
if (scr->desired.line(y - 1).is_soft_wrapped && allow_soft_wrap()) {
|
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
|
// 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
|
// to move here, so we will just output on "one big line" (which the terminal soft
|
||||||
// wraps.
|
// wraps.
|
||||||
scr->actual.cursor = scr->soft_wrap_location;
|
scr->actual.cursor = scr->soft_wrap_location.value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make sure we don't soft wrap.
|
/// 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.
|
/// Update the screen to match the desired output.
|
||||||
static void s_update(screen_t *scr, const wcstring &left_prompt, const wcstring &right_prompt) {
|
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) {
|
if (scr->actual_width != screen_width) {
|
||||||
// Ensure we don't issue a clear screen for the very first output, to avoid issue #402.
|
// 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;
|
need_clear_screen = true;
|
||||||
s_move(scr, 0, 0);
|
s_move(scr, 0, 0);
|
||||||
s_reset(scr, screen_reset_mode_t::current_line_contents);
|
s_reset(scr, screen_reset_mode_t::current_line_contents);
|
||||||
|
@ -1226,16 +1221,4 @@ void screen_force_clear_to_end() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen_t::screen_t()
|
screen_t::screen_t() : outp_(outputter_t::stdoutput()) {}
|
||||||
: 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() {}
|
|
||||||
|
|
33
src/screen.h
33
src/screen.h
|
@ -74,9 +74,9 @@ class screen_data_t {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct cursor_t {
|
struct cursor_t {
|
||||||
int x;
|
int x{0};
|
||||||
int y;
|
int y{0};
|
||||||
cursor_t() : x(0), y(0) {}
|
cursor_t() = default;
|
||||||
cursor_t(int a, int b) : x(a), y(b) {}
|
cursor_t(int a, int b) : x(a), y(b) {}
|
||||||
} cursor;
|
} cursor;
|
||||||
|
|
||||||
|
@ -119,37 +119,38 @@ class screen_t {
|
||||||
outputter_t &outp_;
|
outputter_t &outp_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constructor.
|
|
||||||
screen_t();
|
screen_t();
|
||||||
|
|
||||||
/// The internal representation of the desired screen contents.
|
/// The internal representation of the desired screen contents.
|
||||||
screen_data_t desired;
|
screen_data_t desired{};
|
||||||
/// The internal representation of the actual screen contents.
|
/// 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.
|
/// A string containing the prompt which was last printed to the screen.
|
||||||
wcstring actual_left_prompt;
|
wcstring actual_left_prompt{};
|
||||||
/// Last right prompt width.
|
/// Last right prompt width.
|
||||||
size_t last_right_prompt_width;
|
size_t last_right_prompt_width{0};
|
||||||
/// The actual width of the screen at the time of the last screen write.
|
/// The actual width of the screen at the time of the last screen write, or negative if not yet
|
||||||
int actual_width;
|
/// set.
|
||||||
|
int actual_width{-1};
|
||||||
/// If we support soft wrapping, we can output to this location without any cursor motion.
|
/// 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.
|
/// 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
|
/// 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
|
/// 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
|
/// command has to be sent to the terminal at the end of each line, including
|
||||||
/// actual_lines_before_reset.
|
/// 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.
|
/// 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
|
/// 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
|
/// is used when resizing the window larger: if the cursor jumps to the line above, we need to
|
||||||
/// remember to clear the subsequent lines.
|
/// 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
|
/// 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.
|
/// 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.
|
/// \return the outputter for this screen.
|
||||||
outputter_t &outp() { return outp_; }
|
outputter_t &outp() { return outp_; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user