mirror of
https://github.com/fish-shell/fish-shell.git
synced 2025-02-21 05:25:54 +08:00
Consider cursor width when updating selection
This fixes the handling of the right end of the selection. Currently the right end is considered to be at the cursor position + 1. When using a `block` or `underline` cursor this is arguably correct, because the cursor has a width of 1 and spans from the current position to the next: ``` x x [x x x̲] x ``` This is incorrect though (or at least very unintuitive), when using a `line` cursor: ``` x x [x x|x] x ``` This commit changes the strategy for determining the end of the selection in the following way: * If the current cursor as determined by `$fish_cursor_<bind_mode>` is set to `line`, then a cursor width of `0` is assumed. * In all other cases, including `block` and `underscore` as well as when no value is set we retain the previous behavior of assuming a cursor width of `1`. ``` x x [x x x̲] x x x [x x|]x x ``` This change should not affect many users, because the selection is probably used most by vi-mode users, who are also likely to use a block cursor.
This commit is contained in:
parent
1edcd8ab29
commit
a7d943793e
@ -13,6 +13,9 @@
|
||||
#define FISH_BIND_MODE_VAR L"fish_bind_mode"
|
||||
#define DEFAULT_BIND_MODE L"default"
|
||||
|
||||
#define FISH_CURSOR_VAR_PREFIX L"fish_cursor_"
|
||||
#define FISH_CURSOR_LINE L"line"
|
||||
|
||||
class event_queue_peeker_t;
|
||||
class parser_t;
|
||||
|
||||
|
@ -780,6 +780,8 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
|
||||
inputter(*parser_ref, conf.in),
|
||||
history(std::move(hist)) {}
|
||||
|
||||
/// Returns the width of the current cursor in characters
|
||||
size_t cursor_width();
|
||||
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);
|
||||
@ -1046,6 +1048,18 @@ wcstring combine_command_and_autosuggestion(const wcstring &cmdline,
|
||||
return full_line;
|
||||
}
|
||||
|
||||
size_t reader_data_t::cursor_width() {
|
||||
auto bind_mode = vars().get(FISH_BIND_MODE_VAR);
|
||||
auto fish_cursor_var = FISH_CURSOR_VAR_PREFIX
|
||||
+ (bind_mode ? bind_mode->as_string() : DEFAULT_BIND_MODE);
|
||||
if (auto cursor = vars().get(fish_cursor_var)) {
|
||||
if (cursor->as_string() == FISH_CURSOR_LINE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/// Update the cursor position.
|
||||
void reader_data_t::update_buff_pos(editable_line_t *el, maybe_t<size_t> new_pos) {
|
||||
if (new_pos) {
|
||||
@ -1055,10 +1069,10 @@ 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 + 1;
|
||||
selection->stop = buff_pos + cursor_width();
|
||||
} else {
|
||||
selection->start = buff_pos;
|
||||
selection->stop = selection->begin + 1;
|
||||
selection->stop = selection->begin + cursor_width();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3964,7 +3978,7 @@ 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 + 1;
|
||||
selection->stop = pos + cursor_width();
|
||||
break;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user