mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Fix to add a generation count to threaded operations so they abort early
This commit is contained in:
parent
392232246e
commit
52dc415d0b
1 changed files with 43 additions and 32 deletions
75
reader.cpp
75
reader.cpp
|
@ -174,6 +174,9 @@ commence.
|
||||||
*/
|
*/
|
||||||
#define SEARCH_FORWARD 1
|
#define SEARCH_FORWARD 1
|
||||||
|
|
||||||
|
/* Any time the contents of a buffer changes, we update the generation count. This allows for our background highlighting thread to notice it and skip doing work that it would otherwise have to do. */
|
||||||
|
static unsigned int s_generation_count;
|
||||||
|
|
||||||
/* A color is an int */
|
/* A color is an int */
|
||||||
typedef int color_t;
|
typedef int color_t;
|
||||||
|
|
||||||
|
@ -215,7 +218,7 @@ class reader_data_t
|
||||||
int token_history_pos;
|
int token_history_pos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Saved search string for token history search. Not handled by check_size.
|
Saved search string for token history search. Not handled by command_line_changed.
|
||||||
*/
|
*/
|
||||||
wcstring token_history_buff;
|
wcstring token_history_buff;
|
||||||
|
|
||||||
|
@ -230,8 +233,8 @@ class reader_data_t
|
||||||
/** Length of the command */
|
/** Length of the command */
|
||||||
size_t command_length() const { return command_line.size(); }
|
size_t command_length() const { return command_line.size(); }
|
||||||
|
|
||||||
/** Ensures that our buffers are the right size */
|
/** Do what we need to do whenever our command line changes */
|
||||||
void check_size(void);
|
void command_line_changed(void);
|
||||||
|
|
||||||
/** The current position of the cursor in buff. */
|
/** The current position of the cursor in buff. */
|
||||||
size_t buff_pos;
|
size_t buff_pos;
|
||||||
|
@ -488,7 +491,7 @@ static void reader_kill( size_t begin_idx, int length, int mode, int newv )
|
||||||
}
|
}
|
||||||
|
|
||||||
data->command_line.erase(begin_idx, length);
|
data->command_line.erase(begin_idx, length);
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
|
|
||||||
reader_super_highlight_me_plenty( data->buff_pos );
|
reader_super_highlight_me_plenty( data->buff_pos );
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
|
@ -536,10 +539,14 @@ void reader_pop_current_filename()
|
||||||
|
|
||||||
|
|
||||||
/** Make sure buffers are large enough to hold the current string length */
|
/** Make sure buffers are large enough to hold the current string length */
|
||||||
void reader_data_t::check_size() {
|
void reader_data_t::command_line_changed() {
|
||||||
|
ASSERT_IS_MAIN_THREAD();
|
||||||
size_t len = command_length();
|
size_t len = command_length();
|
||||||
colors.resize(len);
|
colors.resize(len);
|
||||||
indents.resize(len);
|
indents.resize(len);
|
||||||
|
|
||||||
|
/* Update the gen count */
|
||||||
|
s_generation_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -720,7 +727,7 @@ static void remove_backward()
|
||||||
|
|
||||||
data->command_line.erase(data->buff_pos-1, 1);
|
data->command_line.erase(data->buff_pos-1, 1);
|
||||||
data->buff_pos--;
|
data->buff_pos--;
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
data->suppress_autosuggestion = true;
|
data->suppress_autosuggestion = true;
|
||||||
|
|
||||||
reader_super_highlight_me_plenty( data->buff_pos );
|
reader_super_highlight_me_plenty( data->buff_pos );
|
||||||
|
@ -737,9 +744,12 @@ static void remove_backward()
|
||||||
static int insert_string(const wcstring &str)
|
static int insert_string(const wcstring &str)
|
||||||
{
|
{
|
||||||
size_t len = str.size();
|
size_t len = str.size();
|
||||||
|
if (len == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
data->command_line.insert(data->buff_pos, str);
|
data->command_line.insert(data->buff_pos, str);
|
||||||
data->buff_pos += len;
|
data->buff_pos += len;
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
data->suppress_autosuggestion = false;
|
data->suppress_autosuggestion = false;
|
||||||
|
|
||||||
/* Syntax highlight */
|
/* Syntax highlight */
|
||||||
|
@ -1226,6 +1236,7 @@ struct autosuggestion_context_t {
|
||||||
const wcstring working_directory;
|
const wcstring working_directory;
|
||||||
const env_vars vars;
|
const env_vars vars;
|
||||||
wcstring_list_t commands_to_load;
|
wcstring_list_t commands_to_load;
|
||||||
|
const unsigned int generation_count;
|
||||||
|
|
||||||
// don't reload more than once
|
// don't reload more than once
|
||||||
bool has_tried_reloading;
|
bool has_tried_reloading;
|
||||||
|
@ -1236,13 +1247,18 @@ struct autosuggestion_context_t {
|
||||||
detector(history, term),
|
detector(history, term),
|
||||||
working_directory(get_working_directory()),
|
working_directory(get_working_directory()),
|
||||||
vars(env_vars::highlighting_keys),
|
vars(env_vars::highlighting_keys),
|
||||||
|
generation_count(s_generation_count),
|
||||||
has_tried_reloading(false)
|
has_tried_reloading(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
int threaded_autosuggest(void) {
|
int threaded_autosuggest(void) {
|
||||||
ASSERT_IS_BACKGROUND_THREAD();
|
ASSERT_IS_BACKGROUND_THREAD();
|
||||||
|
|
||||||
|
if (generation_count != s_generation_count) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (searcher.go_backwards()) {
|
while (searcher.go_backwards()) {
|
||||||
history_item_t item = searcher.current_item();
|
history_item_t item = searcher.current_item();
|
||||||
bool item_ok = false;
|
bool item_ok = false;
|
||||||
|
@ -1294,7 +1310,6 @@ static bool can_autosuggest(void) {
|
||||||
|
|
||||||
static void autosuggest_completed(autosuggestion_context_t *ctx, int result) {
|
static void autosuggest_completed(autosuggestion_context_t *ctx, int result) {
|
||||||
|
|
||||||
|
|
||||||
/* Extract the commands to load */
|
/* Extract the commands to load */
|
||||||
wcstring_list_t commands_to_load;
|
wcstring_list_t commands_to_load;
|
||||||
ctx->commands_to_load.swap(commands_to_load);
|
ctx->commands_to_load.swap(commands_to_load);
|
||||||
|
@ -1818,7 +1833,7 @@ void reader_replace_current_token( const wchar_t *new_token )
|
||||||
static void handle_history( const wcstring &new_str )
|
static void handle_history( const wcstring &new_str )
|
||||||
{
|
{
|
||||||
data->command_line = new_str;
|
data->command_line = new_str;
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
data->buff_pos=data->command_line.size();
|
data->buff_pos=data->command_line.size();
|
||||||
reader_super_highlight_me_plenty( data->buff_pos );
|
reader_super_highlight_me_plenty( data->buff_pos );
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
|
@ -2146,8 +2161,7 @@ void reader_set_buffer( const wcstring &b, int p )
|
||||||
/* Callers like to pass us pointers into ourselves, so be careful! I don't know if we can use operator= with a pointer to our interior, so use an intermediate. */
|
/* Callers like to pass us pointers into ourselves, so be careful! I don't know if we can use operator= with a pointer to our interior, so use an intermediate. */
|
||||||
size_t l = b.size();
|
size_t l = b.size();
|
||||||
data->command_line = b;
|
data->command_line = b;
|
||||||
|
data->command_line_changed();
|
||||||
data->check_size();
|
|
||||||
|
|
||||||
if( p>=0 )
|
if( p>=0 )
|
||||||
{
|
{
|
||||||
|
@ -2284,7 +2298,7 @@ void reader_push( const wchar_t *name )
|
||||||
|
|
||||||
data=n;
|
data=n;
|
||||||
|
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
|
|
||||||
if( data->next == 0 )
|
if( data->next == 0 )
|
||||||
{
|
{
|
||||||
|
@ -2351,45 +2365,43 @@ void reader_set_test_function( int (*f)( const wchar_t * ) )
|
||||||
/** A class as the context pointer for a background (threaded) highlight operation. */
|
/** A class as the context pointer for a background (threaded) highlight operation. */
|
||||||
class background_highlight_context_t {
|
class background_highlight_context_t {
|
||||||
public:
|
public:
|
||||||
/**
|
/** The string to highlight */
|
||||||
The string to highlight
|
|
||||||
*/
|
|
||||||
const wcstring string_to_highlight;
|
const wcstring string_to_highlight;
|
||||||
|
|
||||||
/** Color buffer */
|
/** Color buffer */
|
||||||
std::vector<color_t> colors;
|
std::vector<color_t> colors;
|
||||||
|
|
||||||
/**
|
/** The position to use for bracket matching */
|
||||||
The position to use for bracket matching
|
|
||||||
*/
|
|
||||||
const int match_highlight_pos;
|
const int match_highlight_pos;
|
||||||
|
|
||||||
/**
|
/** Function for syntax highlighting */
|
||||||
Function for syntax highlighting
|
|
||||||
*/
|
|
||||||
const highlight_function_t highlight_function;
|
const highlight_function_t highlight_function;
|
||||||
|
|
||||||
/**
|
/** Environment variables */
|
||||||
Environment variables
|
|
||||||
*/
|
|
||||||
const env_vars vars;
|
const env_vars vars;
|
||||||
|
|
||||||
/**
|
/** When the request was made */
|
||||||
When the request was made
|
|
||||||
*/
|
|
||||||
const double when;
|
const double when;
|
||||||
|
|
||||||
|
/** Gen count at the time the request was made */
|
||||||
|
const unsigned int generation_count;
|
||||||
|
|
||||||
background_highlight_context_t(const wcstring &pbuff, int phighlight_pos, highlight_function_t phighlight_func) :
|
background_highlight_context_t(const wcstring &pbuff, int phighlight_pos, highlight_function_t phighlight_func) :
|
||||||
string_to_highlight(pbuff),
|
string_to_highlight(pbuff),
|
||||||
match_highlight_pos(phighlight_pos),
|
match_highlight_pos(phighlight_pos),
|
||||||
highlight_function(phighlight_func),
|
highlight_function(phighlight_func),
|
||||||
vars(env_vars::highlighting_keys),
|
vars(env_vars::highlighting_keys),
|
||||||
when(timef())
|
when(timef()),
|
||||||
|
generation_count(s_generation_count)
|
||||||
{
|
{
|
||||||
colors.resize(string_to_highlight.size(), 0);
|
colors.resize(string_to_highlight.size(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int threaded_highlight() {
|
int threaded_highlight() {
|
||||||
|
if (generation_count != s_generation_count) {
|
||||||
|
// The gen count has changed, so don't do anything
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
const wchar_t *delayer = vars.get(L"HIGHLIGHT_DELAY");
|
const wchar_t *delayer = vars.get(L"HIGHLIGHT_DELAY");
|
||||||
double secDelay = 0;
|
double secDelay = 0;
|
||||||
if (delayer) {
|
if (delayer) {
|
||||||
|
@ -2596,7 +2608,7 @@ static int read_i()
|
||||||
|
|
||||||
data->buff_pos=0;
|
data->buff_pos=0;
|
||||||
data->command_line.clear();
|
data->command_line.clear();
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
reader_run_command( parser, tmp );
|
reader_run_command( parser, tmp );
|
||||||
free( (void *)tmp );
|
free( (void *)tmp );
|
||||||
if( data->end_loop)
|
if( data->end_loop)
|
||||||
|
@ -2671,7 +2683,6 @@ const wchar_t *reader_readline()
|
||||||
int finished=0;
|
int finished=0;
|
||||||
struct termios old_modes;
|
struct termios old_modes;
|
||||||
|
|
||||||
data->check_size();
|
|
||||||
data->search_buff.clear();
|
data->search_buff.clear();
|
||||||
data->search_mode = NO_SEARCH;
|
data->search_mode = NO_SEARCH;
|
||||||
|
|
||||||
|
@ -3199,7 +3210,7 @@ const wchar_t *reader_readline()
|
||||||
/* Accept the autosuggestion */
|
/* Accept the autosuggestion */
|
||||||
data->command_line = data->autosuggestion;
|
data->command_line = data->autosuggestion;
|
||||||
data->buff_pos = data->command_line.size();
|
data->buff_pos = data->command_line.size();
|
||||||
data->check_size();
|
data->command_line_changed();
|
||||||
reader_super_highlight_me_plenty(data->buff_pos);
|
reader_super_highlight_me_plenty(data->buff_pos);
|
||||||
reader_repaint();
|
reader_repaint();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue