Use env_dispatch to update cursor selection mode

This commit is contained in:
Michael Forster 2022-07-02 17:08:59 +02:00 committed by ridiculousfish
parent 7d198fa404
commit f09d2c4e6e
3 changed files with 38 additions and 10 deletions

View File

@ -214,6 +214,13 @@ static void handle_fish_history_change(const env_stack_t &vars) {
reader_change_history(history_session_id(vars));
}
static void handle_fish_cursor_selection_mode_change(const env_stack_t &vars) {
auto mode = vars.get(L"fish_cursor_selection_mode");
reader_change_cursor_selection_mode(mode && mode->as_string() == L"inclusive"
? cursor_selection_mode_t::inclusive
: cursor_selection_mode_t::exclusive);
}
void handle_autosuggestion_change(const env_stack_t &vars) {
reader_set_autosuggestion_enabled(vars);
}
@ -327,6 +334,8 @@ static std::unique_ptr<const var_dispatch_table_t> create_dispatch_table() {
var_dispatch_table->add(L"TZ", handle_tz_change);
var_dispatch_table->add(L"fish_use_posix_spawn", handle_fish_use_posix_spawn_change);
var_dispatch_table->add(L"fish_trace", handle_fish_trace);
var_dispatch_table->add(L"fish_cursor_selection_mode",
handle_fish_cursor_selection_mode_change);
// This std::move is required to avoid a build error on old versions of libc++ (#5801),
// but it causes a different warning under newer versions of GCC (observed under GCC 9.3.0,

View File

@ -681,6 +681,9 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
/// The history search.
reader_history_search_t history_search{};
/// The cursor selection mode.
cursor_selection_mode_t cursor_selection_mode{cursor_selection_mode_t::exclusive};
/// The selection data. If this is not none, then we have an active selection.
maybe_t<selection_data_t> selection{};
@ -780,8 +783,6 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
inputter(*parser_ref, conf.in),
history(std::move(hist)) {}
/// Whether the selection should always include the character after the cursor.
bool select_char_after_cursor();
void update_buff_pos(editable_line_t *el, maybe_t<size_t> new_pos = none_t());
void kill(editable_line_t *el, size_t begin_idx, size_t length, int mode, int newv);
@ -1048,11 +1049,6 @@ wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
return full_line;
}
bool reader_data_t::select_char_after_cursor() {
auto val = vars().get(L"fish_cursor_selection_mode");
return !val || val->as_string() == L"inclusive";
}
/// Update the cursor position.
void reader_data_t::update_buff_pos(editable_line_t *el, maybe_t<size_t> new_pos) {
if (new_pos) {
@ -1062,10 +1058,12 @@ void reader_data_t::update_buff_pos(editable_line_t *el, maybe_t<size_t> new_pos
if (el == &command_line && selection.has_value()) {
if (selection->begin <= buff_pos) {
selection->start = selection->begin;
selection->stop = buff_pos + (select_char_after_cursor() ? 1 : 0);
selection->stop =
buff_pos + (cursor_selection_mode == cursor_selection_mode_t::inclusive ? 1 : 0);
} else {
selection->start = buff_pos;
selection->stop = selection->begin + (select_char_after_cursor() ? 1 : 0);
selection->stop = selection->begin +
(cursor_selection_mode == cursor_selection_mode_t::inclusive ? 1 : 0);
}
}
}
@ -2677,6 +2675,14 @@ void reader_change_history(const wcstring &name) {
}
}
void reader_change_cursor_selection_mode(cursor_selection_mode_t selection_mode) {
// We don't need to _change_ if we're not initialized yet.
reader_data_t *data = current_data_or_null();
if (data) {
data->cursor_selection_mode = selection_mode;
}
}
static bool check_autosuggestion_enabled(const env_stack_t &vars) {
if (auto val = vars.get(L"fish_autosuggestion_enabled")) {
return val->as_string() != L"0";
@ -3971,7 +3977,8 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
size_t pos = command_line.position();
selection->begin = pos;
selection->start = pos;
selection->stop = pos + (select_char_after_cursor() ? 1 : 0);
selection->stop =
pos + (cursor_selection_mode == cursor_selection_mode_t::inclusive ? 1 : 0);
break;
}

View File

@ -149,6 +149,18 @@ void restore_term_mode();
/// Change the history file for the current command reading context.
void reader_change_history(const wcstring &name);
/// Strategy for determining how the selection behaves.
enum class cursor_selection_mode_t : uint8_t {
/// The character at/after the cursor is excluded.
/// This is most useful with a line cursor shape.
exclusive,
/// The character at/after the cursor is included.
/// This is most useful with a block or underscore cursor shape.
inclusive,
};
void reader_change_cursor_selection_mode(cursor_selection_mode_t selection_mode);
/// Enable or disable autosuggestions based on the associated variable.
void reader_set_autosuggestion_enabled(const env_stack_t &vars);