mirror of
https://github.com/fish-shell/fish-shell
synced 2025-01-13 21:44:16 +00:00
Rename cached_esc_sequences_t to layout_cache_t
Preparation for migrating the prompt cache into this struct.
This commit is contained in:
parent
634feac600
commit
d1436486e2
4 changed files with 54 additions and 45 deletions
|
@ -606,7 +606,7 @@ static void init_curses() {
|
|||
term_has_xn = tigetflag((char *)"xenl") == 1; // does terminal have the eat_newline_glitch
|
||||
update_fish_color_support();
|
||||
// Invalidate the cached escape sequences since they may no longer be valid.
|
||||
cached_esc_sequences.clear();
|
||||
cached_layouts.clear();
|
||||
curses_initialized = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -4333,27 +4333,27 @@ void test_maybe() {
|
|||
}
|
||||
|
||||
void test_cached_esc_sequences() {
|
||||
cached_esc_sequences_t seqs;
|
||||
do_test(seqs.find_entry(L"abc") == 0);
|
||||
seqs.add_entry(L"abc");
|
||||
seqs.add_entry(L"abc");
|
||||
do_test(seqs.size() == 1);
|
||||
do_test(seqs.find_entry(L"abc") == 3);
|
||||
do_test(seqs.find_entry(L"abcd") == 3);
|
||||
do_test(seqs.find_entry(L"abcde") == 3);
|
||||
do_test(seqs.find_entry(L"xabcde") == 0);
|
||||
seqs.add_entry(L"ac");
|
||||
do_test(seqs.find_entry(L"abcd") == 3);
|
||||
do_test(seqs.find_entry(L"acbd") == 2);
|
||||
seqs.add_entry(L"wxyz");
|
||||
do_test(seqs.find_entry(L"abc") == 3);
|
||||
do_test(seqs.find_entry(L"abcd") == 3);
|
||||
do_test(seqs.find_entry(L"wxyz123") == 4);
|
||||
do_test(seqs.find_entry(L"qwxyz123") == 0);
|
||||
do_test(seqs.size() == 3);
|
||||
layout_cache_t seqs;
|
||||
do_test(seqs.find_escape_code(L"abc") == 0);
|
||||
seqs.add_escape_code(L"abc");
|
||||
seqs.add_escape_code(L"abc");
|
||||
do_test(seqs.esc_cache_size() == 1);
|
||||
do_test(seqs.find_escape_code(L"abc") == 3);
|
||||
do_test(seqs.find_escape_code(L"abcd") == 3);
|
||||
do_test(seqs.find_escape_code(L"abcde") == 3);
|
||||
do_test(seqs.find_escape_code(L"xabcde") == 0);
|
||||
seqs.add_escape_code(L"ac");
|
||||
do_test(seqs.find_escape_code(L"abcd") == 3);
|
||||
do_test(seqs.find_escape_code(L"acbd") == 2);
|
||||
seqs.add_escape_code(L"wxyz");
|
||||
do_test(seqs.find_escape_code(L"abc") == 3);
|
||||
do_test(seqs.find_escape_code(L"abcd") == 3);
|
||||
do_test(seqs.find_escape_code(L"wxyz123") == 4);
|
||||
do_test(seqs.find_escape_code(L"qwxyz123") == 0);
|
||||
do_test(seqs.esc_cache_size() == 3);
|
||||
seqs.clear();
|
||||
do_test(seqs.size() == 0);
|
||||
do_test(seqs.find_entry(L"abcd") == 0);
|
||||
do_test(seqs.esc_cache_size() == 0);
|
||||
do_test(seqs.find_escape_code(L"abcd") == 0);
|
||||
}
|
||||
|
||||
/// Main test.
|
||||
|
|
|
@ -81,7 +81,7 @@ class scoped_buffer_t {
|
|||
|
||||
// Singleton of the cached escape sequences seen in prompts and similar strings.
|
||||
// Note this is deliberately exported so that init_curses can clear it.
|
||||
cached_esc_sequences_t cached_esc_sequences;
|
||||
layout_cache_t cached_layouts;
|
||||
|
||||
/// Tests if the specified narrow character sequence is present at the specified position of the
|
||||
/// specified wide character string. All of \c seq must match, but str may be longer than seq.
|
||||
|
@ -269,7 +269,7 @@ size_t escape_code_length(const wchar_t *code) {
|
|||
assert(code != NULL);
|
||||
if (*code != L'\e') return 0;
|
||||
|
||||
size_t esc_seq_len = cached_esc_sequences.find_entry(code);
|
||||
size_t esc_seq_len = cached_layouts.find_escape_code(code);
|
||||
if (esc_seq_len) return esc_seq_len;
|
||||
|
||||
bool found = is_color_escape_seq(code, &esc_seq_len);
|
||||
|
@ -279,17 +279,10 @@ size_t escape_code_length(const wchar_t *code) {
|
|||
if (!found) found = is_single_byte_escape_seq(code, &esc_seq_len);
|
||||
if (!found) found = is_csi_style_escape_seq(code, &esc_seq_len);
|
||||
if (!found) found = is_two_byte_escape_seq(code, &esc_seq_len);
|
||||
if (found) cached_esc_sequences.add_entry(wcstring(code, esc_seq_len));
|
||||
if (found) cached_layouts.add_escape_code(wcstring(code, esc_seq_len));
|
||||
return esc_seq_len;
|
||||
}
|
||||
|
||||
// Information about the layout of a prompt.
|
||||
struct prompt_layout_t {
|
||||
size_t line_count; // how many lines the prompt consumes
|
||||
size_t max_line_width; // width of the longest line
|
||||
size_t last_line_width; // width of the last line
|
||||
};
|
||||
|
||||
// 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"");
|
||||
|
|
44
src/screen.h
44
src/screen.h
|
@ -16,9 +16,10 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cstddef>
|
||||
#include <list>
|
||||
#include <memory>
|
||||
#include <unordered_set>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <vector>
|
||||
|
||||
#include "common.h"
|
||||
|
@ -199,45 +200,60 @@ bool screen_force_clear_to_end();
|
|||
/// Returns the length of an escape code. Exposed for testing purposes only.
|
||||
size_t escape_code_length(const wchar_t *code);
|
||||
|
||||
// Information about the layout of a prompt.
|
||||
struct prompt_layout_t {
|
||||
size_t line_count; // how many lines the prompt consumes
|
||||
size_t max_line_width; // width of the longest line
|
||||
size_t last_line_width; // width of the last line
|
||||
};
|
||||
|
||||
// Maintain a mapping of escape sequences to their length for fast lookup.
|
||||
class cached_esc_sequences_t {
|
||||
class layout_cache_t {
|
||||
private:
|
||||
// Cached escape sequences we've already detected in the prompt and similar strings, ordered
|
||||
// lexicographically.
|
||||
std::vector<wcstring> cache_;
|
||||
std::vector<wcstring> esc_cache_;
|
||||
|
||||
// LRU-list of prompts and their layouts.
|
||||
// Use a list so we can promote to the front on a cache hit.
|
||||
using prompt_layout_pair_t = std::pair<wcstring, prompt_layout_t>;
|
||||
std::list<prompt_layout_pair_t> prompt_cache_;
|
||||
|
||||
public:
|
||||
/// \return the size of the cache.
|
||||
size_t size() const { return cache_.size(); }
|
||||
/// \return the size of the escape code cache.
|
||||
size_t esc_cache_size() const { return esc_cache_.size(); }
|
||||
|
||||
/// Insert the entry \p str in its sorted position, if it is not already present in the cache.
|
||||
void add_entry(wcstring str) {
|
||||
auto where = std::upper_bound(cache_.begin(), cache_.end(), str);
|
||||
if (where == cache_.begin() || where[-1] != str) {
|
||||
cache_.emplace(where, std::move(str));
|
||||
void add_escape_code(wcstring str) {
|
||||
auto where = std::upper_bound(esc_cache_.begin(), esc_cache_.end(), str);
|
||||
if (where == esc_cache_.begin() || where[-1] != str) {
|
||||
esc_cache_.emplace(where, std::move(str));
|
||||
}
|
||||
}
|
||||
|
||||
/// \return the length of a string that matches a prefix of \p entry.
|
||||
size_t find_entry(const wchar_t *entry) const {
|
||||
size_t find_escape_code(const wchar_t *entry) const {
|
||||
// Do a binary search and see if the escape code right before our entry is a prefix of our
|
||||
// entry. Note this assumes that escape codes are prefix-free: no escape code is a prefix of
|
||||
// another one. This seems like a safe assumption.
|
||||
auto where = std::upper_bound(cache_.begin(), cache_.end(), entry);
|
||||
auto where = std::upper_bound(esc_cache_.begin(), esc_cache_.end(), entry);
|
||||
// 'where' is now the first element that is greater than entry. Thus where-1 is the last
|
||||
// element that is less than or equal to entry.
|
||||
if (where != cache_.begin()) {
|
||||
if (where != esc_cache_.begin()) {
|
||||
const wcstring &candidate = where[-1];
|
||||
if (string_prefixes_string(candidate.c_str(), entry)) return candidate.size();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void clear() { cache_.clear(); }
|
||||
void clear() {
|
||||
esc_cache_.clear();
|
||||
prompt_cache_.clear();
|
||||
}
|
||||
};
|
||||
|
||||
// Singleton that is exposed so that the cache can be invalidated when terminal related variables
|
||||
// change by calling `cached_esc_sequences.clear()`.
|
||||
extern cached_esc_sequences_t cached_esc_sequences;
|
||||
extern layout_cache_t cached_layouts;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue