mirror of
https://github.com/fish-shell/fish-shell
synced 2024-12-26 12:53:13 +00:00
Add repaint-mode bind function
If we switch the bind mode, we add a "force-repaint" there just to redraw the mode indicator. That's quite wasteful and annoying, considering that sometimes the prompt can take half a second. So we add a "repaint-mode" function that just reexecutes the mode-prompt and uses the cached values for the others. Fixes #5783.
This commit is contained in:
parent
da1b32f0ad
commit
8ff866b26b
5 changed files with 73 additions and 50 deletions
|
@ -63,7 +63,7 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
# Add a way to switch from insert to normal (command) mode.
|
# Add a way to switch from insert to normal (command) mode.
|
||||||
# Note if we are paging, we want to stay in insert mode
|
# Note if we are paging, we want to stay in insert mode
|
||||||
# See #2871
|
# See #2871
|
||||||
bind -s --preset -M insert \e "if commandline -P; commandline -f cancel; else; set fish_bind_mode default; commandline -f backward-char force-repaint; end"
|
bind -s --preset -M insert \e "if commandline -P; commandline -f cancel; else; set fish_bind_mode default; commandline -f backward-char repaint-mode; end"
|
||||||
|
|
||||||
# Default (command) mode
|
# Default (command) mode
|
||||||
bind -s --preset :q exit
|
bind -s --preset :q exit
|
||||||
|
@ -72,14 +72,14 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
bind -s --preset -M default l forward-char
|
bind -s --preset -M default l forward-char
|
||||||
bind -s --preset -m insert \n execute
|
bind -s --preset -m insert \n execute
|
||||||
bind -s --preset -m insert \r execute
|
bind -s --preset -m insert \r execute
|
||||||
bind -s --preset -m insert i force-repaint
|
bind -s --preset -m insert i repaint-mode
|
||||||
bind -s --preset -m insert I beginning-of-line force-repaint
|
bind -s --preset -m insert I beginning-of-line repaint-mode
|
||||||
bind -s --preset -m insert a forward-char force-repaint
|
bind -s --preset -m insert a forward-char repaint-mode
|
||||||
bind -s --preset -m insert A end-of-line force-repaint
|
bind -s --preset -m insert A end-of-line repaint-mode
|
||||||
bind -s --preset -m visual v begin-selection force-repaint
|
bind -s --preset -m visual v begin-selection repaint-mode
|
||||||
|
|
||||||
#bind -s --preset -m insert o "commandline -a \n" down-line force-repaint
|
#bind -s --preset -m insert o "commandline -a \n" down-line repaint-mode
|
||||||
#bind -s --preset -m insert O beginning-of-line "commandline -i \n" up-line force-repaint # doesn't work
|
#bind -s --preset -m insert O beginning-of-line "commandline -i \n" up-line repaint-mode # doesn't work
|
||||||
|
|
||||||
bind -s --preset gg beginning-of-buffer
|
bind -s --preset gg beginning-of-buffer
|
||||||
bind -s --preset G end-of-buffer
|
bind -s --preset G end-of-buffer
|
||||||
|
@ -154,24 +154,24 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
bind -s --preset dF begin-selection backward-jump kill-selection end-selection
|
bind -s --preset dF begin-selection backward-jump kill-selection end-selection
|
||||||
bind -s --preset dT begin-selection backward-jump forward-char kill-selection end-selection
|
bind -s --preset dT begin-selection backward-jump forward-char kill-selection end-selection
|
||||||
|
|
||||||
bind -s --preset -m insert s delete-char force-repaint
|
bind -s --preset -m insert s delete-char repaint-mode
|
||||||
bind -s --preset -m insert S kill-whole-line force-repaint
|
bind -s --preset -m insert S kill-whole-line repaint-mode
|
||||||
bind -s --preset -m insert cc kill-whole-line force-repaint
|
bind -s --preset -m insert cc kill-whole-line repaint-mode
|
||||||
bind -s --preset -m insert C kill-line force-repaint
|
bind -s --preset -m insert C kill-line repaint-mode
|
||||||
bind -s --preset -m insert c\$ kill-line force-repaint
|
bind -s --preset -m insert c\$ kill-line repaint-mode
|
||||||
bind -s --preset -m insert c\^ backward-kill-line force-repaint
|
bind -s --preset -m insert c\^ backward-kill-line repaint-mode
|
||||||
bind -s --preset -m insert cw kill-word force-repaint
|
bind -s --preset -m insert cw kill-word repaint-mode
|
||||||
bind -s --preset -m insert cW kill-bigword force-repaint
|
bind -s --preset -m insert cW kill-bigword repaint-mode
|
||||||
bind -s --preset -m insert ciw forward-char forward-char backward-word kill-word force-repaint
|
bind -s --preset -m insert ciw forward-char forward-char backward-word kill-word repaint-mode
|
||||||
bind -s --preset -m insert ciW forward-char forward-char backward-bigword kill-bigword force-repaint
|
bind -s --preset -m insert ciW forward-char forward-char backward-bigword kill-bigword repaint-mode
|
||||||
bind -s --preset -m insert caw forward-char forward-char backward-word kill-word force-repaint
|
bind -s --preset -m insert caw forward-char forward-char backward-word kill-word repaint-mode
|
||||||
bind -s --preset -m insert caW forward-char forward-char backward-bigword kill-bigword force-repaint
|
bind -s --preset -m insert caW forward-char forward-char backward-bigword kill-bigword repaint-mode
|
||||||
bind -s --preset -m insert ce kill-word force-repaint
|
bind -s --preset -m insert ce kill-word repaint-mode
|
||||||
bind -s --preset -m insert cE kill-bigword force-repaint
|
bind -s --preset -m insert cE kill-bigword repaint-mode
|
||||||
bind -s --preset -m insert cb backward-kill-word force-repaint
|
bind -s --preset -m insert cb backward-kill-word repaint-mode
|
||||||
bind -s --preset -m insert cB backward-kill-bigword force-repaint
|
bind -s --preset -m insert cB backward-kill-bigword repaint-mode
|
||||||
bind -s --preset -m insert cge backward-kill-word force-repaint
|
bind -s --preset -m insert cge backward-kill-word repaint-mode
|
||||||
bind -s --preset -m insert cgE backward-kill-bigword force-repaint
|
bind -s --preset -m insert cgE backward-kill-bigword repaint-mode
|
||||||
|
|
||||||
bind -s --preset '~' capitalize-word
|
bind -s --preset '~' capitalize-word
|
||||||
bind -s --preset gu downcase-word
|
bind -s --preset gu downcase-word
|
||||||
|
@ -215,9 +215,9 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
#
|
#
|
||||||
# Lowercase r, enters replace_one mode
|
# Lowercase r, enters replace_one mode
|
||||||
#
|
#
|
||||||
bind -s --preset -m replace_one r force-repaint
|
bind -s --preset -m replace_one r repaint-mode
|
||||||
bind -s --preset -M replace_one -m default '' delete-char self-insert backward-char force-repaint
|
bind -s --preset -M replace_one -m default '' delete-char self-insert backward-char repaint-mode
|
||||||
bind -s --preset -M replace_one -m default \e cancel force-repaint
|
bind -s --preset -M replace_one -m default \e cancel repaint-mode
|
||||||
|
|
||||||
#
|
#
|
||||||
# visual mode
|
# visual mode
|
||||||
|
@ -236,7 +236,7 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
bind -s --preset -M visual W forward-bigword
|
bind -s --preset -M visual W forward-bigword
|
||||||
bind -s --preset -M visual e forward-word
|
bind -s --preset -M visual e forward-word
|
||||||
bind -s --preset -M visual E forward-bigword
|
bind -s --preset -M visual E forward-bigword
|
||||||
bind -s --preset -M visual o swap-selection-start-stop force-repaint
|
bind -s --preset -M visual o swap-selection-start-stop repaint-mode
|
||||||
|
|
||||||
bind -s --preset -M visual f forward-jump
|
bind -s --preset -M visual f forward-jump
|
||||||
bind -s --preset -M visual t forward-jump-till
|
bind -s --preset -M visual t forward-jump-till
|
||||||
|
@ -250,15 +250,15 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
||||||
bind -s --preset -M visual $key beginning-of-line
|
bind -s --preset -M visual $key beginning-of-line
|
||||||
end
|
end
|
||||||
|
|
||||||
bind -s --preset -M visual -m insert c kill-selection end-selection force-repaint
|
bind -s --preset -M visual -m insert c kill-selection end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default d kill-selection end-selection force-repaint
|
bind -s --preset -M visual -m default d kill-selection end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default x kill-selection end-selection force-repaint
|
bind -s --preset -M visual -m default x kill-selection end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default X kill-whole-line end-selection force-repaint
|
bind -s --preset -M visual -m default X kill-whole-line end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default y kill-selection yank end-selection force-repaint
|
bind -s --preset -M visual -m default y kill-selection yank end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default '"*y' "commandline -s | xsel -p; commandline -f end-selection force-repaint"
|
bind -s --preset -M visual -m default '"*y' "commandline -s | xsel -p; commandline -f end-selection repaint-mode"
|
||||||
|
|
||||||
bind -s --preset -M visual -m default \cc end-selection force-repaint
|
bind -s --preset -M visual -m default \cc end-selection repaint-mode
|
||||||
bind -s --preset -M visual -m default \e end-selection force-repaint
|
bind -s --preset -M visual -m default \e end-selection repaint-mode
|
||||||
|
|
||||||
# Make it easy to turn an unexecuted command into a comment in the shell history. Also, remove
|
# Make it easy to turn an unexecuted command into a comment in the shell history. Also, remove
|
||||||
# the commenting chars so the command can be further edited then executed.
|
# the commenting chars so the command can be further edited then executed.
|
||||||
|
|
|
@ -136,6 +136,10 @@ The following special input functions are available:
|
||||||
|
|
||||||
- ``pager-toggle-search``, toggles the search field if the completions pager is visible.
|
- ``pager-toggle-search``, toggles the search field if the completions pager is visible.
|
||||||
|
|
||||||
|
- ``repaint`` reexecutes the prompt functions and redraws the prompt. Multiple successive repaints are coalesced.
|
||||||
|
|
||||||
|
- ``repaint-mode`` reexecutes the fish_mode_prompt function and redraws the prompt. This is useful for vi-mode.
|
||||||
|
|
||||||
- ``suppress-autosuggestion``, remove the current autosuggestion
|
- ``suppress-autosuggestion``, remove the current autosuggestion
|
||||||
|
|
||||||
- ``swap-selection-start-stop``, go to the other end of the highlighted text without changing the selection
|
- ``swap-selection-start-stop``, go to the other end of the highlighted text without changing the selection
|
||||||
|
|
|
@ -112,6 +112,7 @@ static const input_function_metadata_t input_function_metadata[] = {
|
||||||
{readline_cmd_t::execute, L"execute"},
|
{readline_cmd_t::execute, L"execute"},
|
||||||
{readline_cmd_t::beginning_of_buffer, L"beginning-of-buffer"},
|
{readline_cmd_t::beginning_of_buffer, L"beginning-of-buffer"},
|
||||||
{readline_cmd_t::end_of_buffer, L"end-of-buffer"},
|
{readline_cmd_t::end_of_buffer, L"end-of-buffer"},
|
||||||
|
{readline_cmd_t::repaint_mode, L"repaint-mode"},
|
||||||
{readline_cmd_t::repaint, L"repaint"},
|
{readline_cmd_t::repaint, L"repaint"},
|
||||||
{readline_cmd_t::force_repaint, L"force-repaint"},
|
{readline_cmd_t::force_repaint, L"force-repaint"},
|
||||||
{readline_cmd_t::up_line, L"up-line"},
|
{readline_cmd_t::up_line, L"up-line"},
|
||||||
|
|
|
@ -50,6 +50,7 @@ enum class readline_cmd_t {
|
||||||
execute,
|
execute,
|
||||||
beginning_of_buffer,
|
beginning_of_buffer,
|
||||||
end_of_buffer,
|
end_of_buffer,
|
||||||
|
repaint_mode,
|
||||||
repaint,
|
repaint,
|
||||||
force_repaint,
|
force_repaint,
|
||||||
up_line,
|
up_line,
|
||||||
|
|
|
@ -357,6 +357,7 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
|
||||||
wcstring right_prompt;
|
wcstring right_prompt;
|
||||||
/// The output of the last evaluation of the prompt command.
|
/// The output of the last evaluation of the prompt command.
|
||||||
wcstring left_prompt_buff;
|
wcstring left_prompt_buff;
|
||||||
|
wcstring mode_prompt_buff;
|
||||||
/// The output of the last evaluation of the right prompt command.
|
/// The output of the last evaluation of the right prompt command.
|
||||||
wcstring right_prompt_buff;
|
wcstring right_prompt_buff;
|
||||||
/// Completion support.
|
/// Completion support.
|
||||||
|
@ -461,6 +462,7 @@ class reader_data_t : public std::enable_shared_from_this<reader_data_t> {
|
||||||
|
|
||||||
void highlight_search();
|
void highlight_search();
|
||||||
void highlight_complete(highlight_result_t result);
|
void highlight_complete(highlight_result_t result);
|
||||||
|
void exec_mode_prompt();
|
||||||
void exec_prompt();
|
void exec_prompt();
|
||||||
|
|
||||||
bool jump(jump_direction_t dir, jump_precision_t precision, editable_line_t *el,
|
bool jump(jump_direction_t dir, jump_precision_t precision, editable_line_t *el,
|
||||||
|
@ -641,7 +643,8 @@ void reader_data_t::repaint() {
|
||||||
bool focused_on_pager = active_edit_line() == &pager.search_field_line;
|
bool focused_on_pager = active_edit_line() == &pager.search_field_line;
|
||||||
size_t cursor_position = focused_on_pager ? pager.cursor_position() : cmd_line->position;
|
size_t cursor_position = focused_on_pager ? pager.cursor_position() : cmd_line->position;
|
||||||
|
|
||||||
s_write(&screen, left_prompt_buff, right_prompt_buff, full_line, cmd_line->size(), colors,
|
// Prepend the mode prompt to the left prompt.
|
||||||
|
s_write(&screen, mode_prompt_buff + left_prompt_buff, right_prompt_buff, full_line, cmd_line->size(), colors,
|
||||||
indents, cursor_position, current_page_rendering, focused_on_pager);
|
indents, cursor_position, current_page_rendering, focused_on_pager);
|
||||||
|
|
||||||
repaint_needed = false;
|
repaint_needed = false;
|
||||||
|
@ -904,6 +907,20 @@ void reader_write_title(const wcstring &cmd, bool reset_cursor_position) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reader_data_t::exec_mode_prompt() {
|
||||||
|
mode_prompt_buff.clear();
|
||||||
|
if (function_exists(MODE_PROMPT_FUNCTION_NAME)) {
|
||||||
|
wcstring_list_t mode_indicator_list;
|
||||||
|
exec_subshell(MODE_PROMPT_FUNCTION_NAME, parser(), mode_indicator_list,
|
||||||
|
false);
|
||||||
|
// We do not support multiple lines in the mode indicator, so just concatenate all of
|
||||||
|
// them.
|
||||||
|
for (size_t i = 0; i < mode_indicator_list.size(); i++) {
|
||||||
|
mode_prompt_buff += mode_indicator_list.at(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Reexecute the prompt command. The output is inserted into prompt_buff.
|
/// Reexecute the prompt command. The output is inserted into prompt_buff.
|
||||||
void reader_data_t::exec_prompt() {
|
void reader_data_t::exec_prompt() {
|
||||||
// Clear existing prompts.
|
// Clear existing prompts.
|
||||||
|
@ -921,17 +938,7 @@ void reader_data_t::exec_prompt() {
|
||||||
if (left_prompt.size() || right_prompt.size()) {
|
if (left_prompt.size() || right_prompt.size()) {
|
||||||
proc_push_interactive(0);
|
proc_push_interactive(0);
|
||||||
|
|
||||||
// Prepend any mode indicator to the left prompt (issue #1988).
|
exec_mode_prompt();
|
||||||
if (function_exists(MODE_PROMPT_FUNCTION_NAME)) {
|
|
||||||
wcstring_list_t mode_indicator_list;
|
|
||||||
exec_subshell(MODE_PROMPT_FUNCTION_NAME, parser(), mode_indicator_list,
|
|
||||||
apply_exit_status);
|
|
||||||
// We do not support multiple lines in the mode indicator, so just concatenate all of
|
|
||||||
// them.
|
|
||||||
for (size_t i = 0; i < mode_indicator_list.size(); i++) {
|
|
||||||
left_prompt_buff += mode_indicator_list.at(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!left_prompt.empty()) {
|
if (!left_prompt.empty()) {
|
||||||
wcstring_list_t prompt_list;
|
wcstring_list_t prompt_list;
|
||||||
|
@ -2503,6 +2510,16 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat
|
||||||
// The only thing we can cancel right now is paging, which we handled up above.
|
// The only thing we can cancel right now is paging, which we handled up above.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case rl::repaint_mode: {
|
||||||
|
// Repaint the mode-prompt only if it exists.
|
||||||
|
// This is an optimization basically exclusively for vi-mode, since the prompt
|
||||||
|
// may sometimes take a while but when switching the mode all we care about is the mode-prompt.
|
||||||
|
exec_mode_prompt();
|
||||||
|
s_reset(&screen, screen_reset_current_line_and_prompt);
|
||||||
|
screen_reset_needed = false;
|
||||||
|
repaint();
|
||||||
|
break;
|
||||||
|
}
|
||||||
case rl::force_repaint:
|
case rl::force_repaint:
|
||||||
case rl::repaint: {
|
case rl::repaint: {
|
||||||
if (!rls.coalescing_repaints) {
|
if (!rls.coalescing_repaints) {
|
||||||
|
|
Loading…
Reference in a new issue