mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 04:22:40 +08:00
Use the layout cache instead of static variables for caching prompts
This correctly reacts to changes in TERM (which might affect prompt width due to escape code differences), and eliminates some ugly static variables.
This commit is contained in:
parent
1bd5946d23
commit
72208a9438
@ -50,8 +50,6 @@
|
||||
/// A helper value for an invalid location.
|
||||
#define INVALID_LOCATION (screen_data_t::cursor_t(-1, -1))
|
||||
|
||||
enum prompt_type_t { UNKNOWN_PROMPT, LEFT_PROMPT, RIGHT_PROMPT };
|
||||
|
||||
static void invalidate_soft_wrap(screen_t *scr);
|
||||
|
||||
/// Ugly kludge. The internal buffer used to store output of tputs. Since tputs external function
|
||||
@ -304,20 +302,11 @@ void layout_cache_t::add_prompt_layout(wcstring input, prompt_layout_t layout) {
|
||||
}
|
||||
}
|
||||
|
||||
// These are used by `calc_prompt_layout()` to avoid redundant calculations.
|
||||
static const wchar_t *cached_left_prompt = wcsdup(L"");
|
||||
static const wchar_t *cached_right_prompt = wcsdup(L"");
|
||||
static prompt_layout_t cached_left_prompt_layout = {1, 0, 0};
|
||||
static prompt_layout_t cached_right_prompt_layout = {1, 0, 0};
|
||||
|
||||
/// Calculate layout information for the given prompt. Does some clever magic to detect common
|
||||
/// escape sequences that may be embeded in a prompt, such as those to set visual attributes.
|
||||
static prompt_layout_t calc_prompt_layout(const wchar_t *prompt, prompt_type_t which_prompt) {
|
||||
if (which_prompt == LEFT_PROMPT && wcscmp(cached_left_prompt, prompt) == 0) {
|
||||
return cached_left_prompt_layout;
|
||||
}
|
||||
if (which_prompt == RIGHT_PROMPT && wcscmp(cached_right_prompt, prompt) == 0) {
|
||||
return cached_right_prompt_layout;
|
||||
static prompt_layout_t calc_prompt_layout(const wcstring &prompt, layout_cache_t &cache) {
|
||||
if (auto cached_layout = cache.find_prompt_layout(prompt)) {
|
||||
return *cached_layout;
|
||||
}
|
||||
|
||||
prompt_layout_t prompt_layout = {1, 0, 0};
|
||||
@ -345,18 +334,8 @@ static prompt_layout_t calc_prompt_layout(const wchar_t *prompt, prompt_type_t w
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
prompt_layout.last_line_width = current_line_width;
|
||||
if (which_prompt == LEFT_PROMPT) {
|
||||
free((void *)cached_left_prompt);
|
||||
cached_left_prompt = wcsdup(prompt);
|
||||
cached_left_prompt_layout = prompt_layout;
|
||||
}
|
||||
if (which_prompt == RIGHT_PROMPT) {
|
||||
free((void *)cached_right_prompt);
|
||||
cached_right_prompt = wcsdup(prompt);
|
||||
cached_right_prompt_layout = prompt_layout;
|
||||
}
|
||||
cache.add_prompt_layout(prompt, prompt_layout);
|
||||
return prompt_layout;
|
||||
}
|
||||
|
||||
@ -366,7 +345,7 @@ static size_t calc_prompt_lines(const wcstring &prompt) {
|
||||
// calc_prompt_width_and_lines.
|
||||
size_t result = 1;
|
||||
if (prompt.find(L'\n') != wcstring::npos || prompt.find(L'\f') != wcstring::npos) {
|
||||
result = calc_prompt_layout(prompt.c_str(), UNKNOWN_PROMPT).line_count;
|
||||
result = calc_prompt_layout(prompt, cached_layouts).line_count;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -638,11 +617,12 @@ static bool perform_any_impending_soft_wrap(screen_t *scr, int x, int y) {
|
||||
static void invalidate_soft_wrap(screen_t *scr) { scr->soft_wrap_location = INVALID_LOCATION; }
|
||||
|
||||
/// Update the screen to match the desired output.
|
||||
static void s_update(screen_t *scr, const wchar_t *left_prompt, const wchar_t *right_prompt) {
|
||||
static void s_update(screen_t *scr, const wcstring &left_prompt, const wcstring &right_prompt) {
|
||||
// if (test_stuff(scr)) return;
|
||||
const size_t left_prompt_width = calc_prompt_layout(left_prompt, LEFT_PROMPT).last_line_width;
|
||||
const size_t left_prompt_width =
|
||||
calc_prompt_layout(left_prompt, cached_layouts).last_line_width;
|
||||
const size_t right_prompt_width =
|
||||
calc_prompt_layout(right_prompt, RIGHT_PROMPT).last_line_width;
|
||||
calc_prompt_layout(right_prompt, cached_layouts).last_line_width;
|
||||
|
||||
int screen_width = common_get_width();
|
||||
|
||||
@ -676,9 +656,9 @@ static void s_update(screen_t *scr, const wchar_t *left_prompt, const wchar_t *r
|
||||
// want.
|
||||
const size_t lines_with_stuff = maxi(actual_lines_before_reset, scr->actual.line_count());
|
||||
|
||||
if (wcscmp(left_prompt, scr->actual_left_prompt.c_str())) {
|
||||
if (left_prompt != scr->actual_left_prompt) {
|
||||
s_move(scr, &output, 0, 0);
|
||||
s_write_str(&output, left_prompt);
|
||||
s_write_str(&output, left_prompt.c_str());
|
||||
scr->actual_left_prompt = left_prompt;
|
||||
scr->actual.cursor.x = (int)left_prompt_width;
|
||||
}
|
||||
@ -789,7 +769,7 @@ static void s_update(screen_t *scr, const wchar_t *left_prompt, const wchar_t *r
|
||||
if (i == 0 && right_prompt_width > 0) { //!OCLINT(Use early exit/continue)
|
||||
s_move(scr, &output, (int)(screen_width - right_prompt_width), (int)i);
|
||||
s_set_color(scr, &output, 0xffffffff);
|
||||
s_write_str(&output, right_prompt);
|
||||
s_write_str(&output, right_prompt.c_str());
|
||||
scr->actual.cursor.x += right_prompt_width;
|
||||
|
||||
// We output in the last column. Some terms (Linux) push the cursor further right, past
|
||||
@ -875,8 +855,8 @@ static screen_layout_t compute_layout(screen_t *s, size_t screen_width,
|
||||
const wchar_t *right_prompt = right_prompt_str.c_str();
|
||||
const wchar_t *autosuggestion = autosuggestion_str.c_str();
|
||||
|
||||
prompt_layout_t left_prompt_layout = calc_prompt_layout(left_prompt, LEFT_PROMPT);
|
||||
prompt_layout_t right_prompt_layout = calc_prompt_layout(right_prompt, RIGHT_PROMPT);
|
||||
prompt_layout_t left_prompt_layout = calc_prompt_layout(left_prompt_str, cached_layouts);
|
||||
prompt_layout_t right_prompt_layout = calc_prompt_layout(right_prompt_str, cached_layouts);
|
||||
|
||||
size_t left_prompt_width = left_prompt_layout.last_line_width;
|
||||
size_t right_prompt_width = right_prompt_layout.last_line_width;
|
||||
@ -1102,7 +1082,7 @@ void s_write(screen_t *s, const wcstring &left_prompt, const wcstring &right_pro
|
||||
// Append pager_data (none if empty).
|
||||
s->desired.append_lines(pager.screen_data);
|
||||
|
||||
s_update(s, layout.left_prompt.c_str(), layout.right_prompt.c_str());
|
||||
s_update(s, layout.left_prompt, layout.right_prompt);
|
||||
s_save_status(s);
|
||||
}
|
||||
void s_reset(screen_t *s, screen_reset_mode_t mode) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user