mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-06 00:41:15 -03:00
Show file location when querying bindings with bind
Closes #12215 Closes #12504 Closes #12221
This commit is contained in:
committed by
Johannes Altmanninger
parent
eb535322d0
commit
11d6e92cb5
@@ -11,6 +11,7 @@ Interactive improvements
|
|||||||
This means that on systems where fish version 3.x was installed originally, the update will avoid creating that file (:issue:`12725`).
|
This means that on systems where fish version 3.x was installed originally, the update will avoid creating that file (:issue:`12725`).
|
||||||
- ``fish_hg_prompt``, ``fish_git_prompt`` and ``fish_fossil_prompt`` now strip control characters from VCS state read off disk, matching ``prompt_pwd``.
|
- ``fish_hg_prompt``, ``fish_git_prompt`` and ``fish_fossil_prompt`` now strip control characters from VCS state read off disk, matching ``prompt_pwd``.
|
||||||
- The sample informative and minimalist prompts now use ``prompt_pwd`` instead of printing ``$PWD`` directly.
|
- The sample informative and minimalist prompts now use ``prompt_pwd`` instead of printing ``$PWD`` directly.
|
||||||
|
- ``bind`` shows the file where bindings were defined (:issue:`12504`).
|
||||||
|
|
||||||
For distributors and developers
|
For distributors and developers
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
# localization: skip(private)
|
|
||||||
function __fish_per_os_bind
|
|
||||||
set -l macos $argv[-2]
|
|
||||||
set -l non_macos $argv[-1]
|
|
||||||
set -e argv[-2..-1]
|
|
||||||
for varname in macos non_macos
|
|
||||||
if contains -- $$varname (bind --function-names)
|
|
||||||
set $varname 'commandline -f '$$varname
|
|
||||||
end
|
|
||||||
end
|
|
||||||
bind $argv "if fish_in_macos_terminal; $macos; else $non_macos; end"
|
|
||||||
end
|
|
||||||
14
share/functions/__fish_per_os_bind_body.fish
Normal file
14
share/functions/__fish_per_os_bind_body.fish
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# localization: skip(private)
|
||||||
|
function __fish_per_os_bind_body
|
||||||
|
printf %s '
|
||||||
|
set -l macos $argv[-2]
|
||||||
|
set -l non_macos $argv[-1]
|
||||||
|
set -e argv[-2..-1]
|
||||||
|
for varname in macos non_macos
|
||||||
|
if contains -- $$varname (bind --function-names)
|
||||||
|
set $varname \'commandline -f \'$$varname
|
||||||
|
end
|
||||||
|
end
|
||||||
|
bind $argv "if fish_in_macos_terminal; $macos; else $non_macos; end"
|
||||||
|
'
|
||||||
|
end
|
||||||
@@ -1,132 +1,131 @@
|
|||||||
# localization: skip(private)
|
# localization: skip(private)
|
||||||
function __fish_shared_key_bindings -d "Bindings shared between emacs and vi mode"
|
function __fish_shared_key_bindings -d "Prints function body for bindings shared between emacs and vi mode"
|
||||||
# These are some bindings that are supposed to be shared between vi mode and default mode.
|
# These are some bindings that are supposed to be shared between vi mode and default mode.
|
||||||
# They are supposed to be unrelated to text-editing (or movement).
|
# They are supposed to be unrelated to text-editing (or movement).
|
||||||
# This takes $argv so the vi-bindings can pass the mode they are valid in.
|
# This takes $argv so the vi-bindings can pass the mode they are valid in.
|
||||||
|
printf %s '
|
||||||
if contains -- -h $argv
|
if contains -- -h $argv
|
||||||
or contains -- --help $argv
|
or contains -- --help $argv
|
||||||
echo "Sorry but this function doesn't support -h or --help" >&2
|
echo "Sorry but this function doesn\'t support -h or --help" >&2
|
||||||
return 1
|
return 1
|
||||||
end
|
end
|
||||||
|
bind --preset $argv ctrl-y yank
|
||||||
bind --preset $argv ctrl-y yank
|
or return # protect against invalid $argv
|
||||||
or return # protect against invalid $argv
|
bind --preset $argv alt-y yank-pop
|
||||||
bind --preset $argv alt-y yank-pop
|
|
||||||
|
# Left/Right arrow
|
||||||
# Left/Right arrow
|
bind --preset $argv right forward-char
|
||||||
bind --preset $argv right forward-char
|
bind --preset $argv left backward-char
|
||||||
bind --preset $argv left backward-char
|
|
||||||
|
# Ctrl-left/right - these also work in vim.
|
||||||
# Ctrl-left/right - these also work in vim.
|
__fish_per_os_bind --preset $argv ctrl-right forward-token forward-word
|
||||||
__fish_per_os_bind --preset $argv ctrl-right forward-token forward-word
|
__fish_per_os_bind --preset $argv ctrl-left backward-token backward-word
|
||||||
__fish_per_os_bind --preset $argv ctrl-left backward-token backward-word
|
|
||||||
|
bind --preset $argv pageup beginning-of-history
|
||||||
bind --preset $argv pageup beginning-of-history
|
bind --preset $argv pagedown end-of-history
|
||||||
bind --preset $argv pagedown end-of-history
|
|
||||||
|
# Interaction with the system clipboard.
|
||||||
# Interaction with the system clipboard.
|
bind --preset $argv ctrl-x fish_clipboard_copy
|
||||||
bind --preset $argv ctrl-x fish_clipboard_copy
|
bind --preset $argv ctrl-v fish_clipboard_paste
|
||||||
bind --preset $argv ctrl-v fish_clipboard_paste
|
|
||||||
|
bind --preset $argv escape cancel
|
||||||
bind --preset $argv escape cancel
|
bind --preset $argv ctrl-\[ cancel
|
||||||
bind --preset $argv ctrl-\[ cancel
|
bind --preset $argv tab complete
|
||||||
bind --preset $argv tab complete
|
bind --preset $argv ctrl-i complete
|
||||||
bind --preset $argv ctrl-i complete
|
bind --preset $argv ctrl-s pager-toggle-search
|
||||||
bind --preset $argv ctrl-s pager-toggle-search
|
# shift-tab does a tab complete followed by a search.
|
||||||
# shift-tab does a tab complete followed by a search.
|
bind --preset $argv shift-tab complete-and-search
|
||||||
bind --preset $argv shift-tab complete-and-search
|
bind --preset $argv shift-delete history-delete or backward-delete-char
|
||||||
bind --preset $argv shift-delete history-delete or backward-delete-char
|
|
||||||
|
bind --preset $argv down down-or-search
|
||||||
bind --preset $argv down down-or-search
|
bind --preset $argv up up-or-search
|
||||||
bind --preset $argv up up-or-search
|
|
||||||
|
bind --preset $argv shift-right forward-bigword
|
||||||
bind --preset $argv shift-right forward-bigword
|
bind --preset $argv shift-left backward-bigword
|
||||||
bind --preset $argv shift-left backward-bigword
|
|
||||||
|
bind --preset $argv alt-b prevd-or-backward-word
|
||||||
bind --preset $argv alt-b prevd-or-backward-word
|
bind --preset $argv alt-f nextd-or-forward-word
|
||||||
bind --preset $argv alt-f nextd-or-forward-word
|
|
||||||
|
for alt_right in alt-right \e\[1\;9C # TODO(terminal-workaround) iTerm2 < 3.5.12
|
||||||
for alt_right in alt-right \e\[1\;9C # TODO(terminal-workaround) iTerm2 < 3.5.12
|
__fish_per_os_bind --preset $argv $alt_right \
|
||||||
__fish_per_os_bind --preset $argv $alt_right \
|
nextd-or-forward-word nextd-or-forward-token
|
||||||
nextd-or-forward-word nextd-or-forward-token
|
end
|
||||||
end
|
for alt_left in alt-left \e\[1\;9D # TODO(terminal-workaround) iTerm2 < 3.5.12
|
||||||
for alt_left in alt-left \e\[1\;9D # TODO(terminal-workaround) iTerm2 < 3.5.12
|
__fish_per_os_bind --preset $argv $alt_left \
|
||||||
__fish_per_os_bind --preset $argv $alt_left \
|
prevd-or-backward-word prevd-or-backward-token
|
||||||
prevd-or-backward-word prevd-or-backward-token
|
end
|
||||||
end
|
|
||||||
|
bind --preset $argv alt-up history-token-search-backward
|
||||||
bind --preset $argv alt-up history-token-search-backward
|
bind --preset $argv alt-down history-token-search-forward
|
||||||
bind --preset $argv alt-down history-token-search-forward
|
# TODO(terminal-workaround)
|
||||||
# TODO(terminal-workaround)
|
bind --preset $argv \e\[1\;9A history-token-search-backward # iTerm2 < 3.5.12
|
||||||
bind --preset $argv \e\[1\;9A history-token-search-backward # iTerm2 < 3.5.12
|
bind --preset $argv \e\[1\;9B history-token-search-forward # iTerm2 < 3.5.12
|
||||||
bind --preset $argv \e\[1\;9B history-token-search-forward # iTerm2 < 3.5.12
|
# Bash compatibility
|
||||||
# Bash compatibility
|
# https://github.com/fish-shell/fish-shell/issues/89
|
||||||
# https://github.com/fish-shell/fish-shell/issues/89
|
bind --preset $argv alt-. history-token-search-backward
|
||||||
bind --preset $argv alt-. history-token-search-backward
|
|
||||||
|
bind --preset $argv alt-l __fish_list_current_token
|
||||||
bind --preset $argv alt-l __fish_list_current_token
|
bind --preset $argv alt-o __fish_preview_current_file
|
||||||
bind --preset $argv alt-o __fish_preview_current_file
|
bind --preset $argv alt-w __fish_whatis_current_token
|
||||||
bind --preset $argv alt-w __fish_whatis_current_token
|
bind --preset $argv ctrl-l \
|
||||||
bind --preset $argv ctrl-l \
|
"status test-terminal-feature scroll-content-up && commandline -f scrollback-push" \
|
||||||
'status test-terminal-feature scroll-content-up && commandline -f scrollback-push' \
|
clear-screen
|
||||||
clear-screen
|
bind --preset $argv ctrl-c clear-commandline
|
||||||
bind --preset $argv ctrl-c clear-commandline
|
bind --preset $argv ctrl-u backward-kill-line
|
||||||
bind --preset $argv ctrl-u backward-kill-line
|
bind --preset $argv ctrl-k kill-line
|
||||||
bind --preset $argv ctrl-k kill-line
|
bind --preset $argv ctrl-w backward-kill-path-component
|
||||||
bind --preset $argv ctrl-w backward-kill-path-component
|
bind --preset $argv end end-of-line
|
||||||
bind --preset $argv end end-of-line
|
bind --preset $argv home beginning-of-line
|
||||||
bind --preset $argv home beginning-of-line
|
|
||||||
|
bind --preset $argv alt-d \'if test "$(commandline; printf .)" = \n.; __fish_echo dirh; else; commandline -f kill-word; end\'
|
||||||
bind --preset $argv alt-d 'if test "$(commandline; printf .)" = \n.; __fish_echo dirh; else; commandline -f kill-word; end'
|
bind --preset $argv ctrl-d delete-or-exit
|
||||||
bind --preset $argv ctrl-d delete-or-exit
|
|
||||||
|
bind --preset $argv alt-s \'for cmd in sudo doas please run0; if command -q $cmd; fish_commandline_prepend $cmd; break; end; end\'
|
||||||
bind --preset $argv alt-s 'for cmd in sudo doas please run0; if command -q $cmd; fish_commandline_prepend $cmd; break; end; end'
|
|
||||||
|
# Allow reading manpages by pressing f1 (many GUI applications) or Alt+h (like in zsh).
|
||||||
# Allow reading manpages by pressing f1 (many GUI applications) or Alt+h (like in zsh).
|
bind --preset $argv f1 __fish_man_page
|
||||||
bind --preset $argv f1 __fish_man_page
|
bind --preset $argv alt-h __fish_man_page
|
||||||
bind --preset $argv alt-h __fish_man_page
|
|
||||||
|
# This will make sure the output of the current command is paged using the default pager when
|
||||||
# This will make sure the output of the current command is paged using the default pager when
|
# you press Meta-p.
|
||||||
# you press Meta-p.
|
# If none is set, less will be used.
|
||||||
# If none is set, less will be used.
|
bind --preset $argv alt-p __fish_paginate
|
||||||
bind --preset $argv alt-p __fish_paginate
|
|
||||||
|
# Make it easy to turn an unexecuted command into a comment in the shell history. Also,
|
||||||
# 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.
|
||||||
# remove the commenting chars so the command can be further edited then executed.
|
bind --preset $argv alt-# __fish_toggle_comment_commandline
|
||||||
bind --preset $argv alt-# __fish_toggle_comment_commandline
|
|
||||||
|
# These keystrokes invoke an external editor on the command buffer.
|
||||||
# These keystrokes invoke an external editor on the command buffer.
|
bind --preset $argv alt-e edit_command_buffer
|
||||||
bind --preset $argv alt-e edit_command_buffer
|
bind --preset $argv alt-v edit_command_buffer
|
||||||
bind --preset $argv alt-v edit_command_buffer
|
|
||||||
|
# Bindings that are shared in text-insertion modes.
|
||||||
# Bindings that are shared in text-insertion modes.
|
if not set -l index (contains --index -- -M $argv)
|
||||||
if not set -l index (contains --index -- -M $argv)
|
or test $argv[(math $index + 1)] = insert
|
||||||
or test $argv[(math $index + 1)] = insert
|
|
||||||
|
# This is the default binding, i.e. the one used if no other binding matches
|
||||||
# This is the default binding, i.e. the one used if no other binding matches
|
bind --preset $argv "" self-insert
|
||||||
bind --preset $argv "" self-insert
|
or exit # protect against invalid $argv
|
||||||
or exit # protect against invalid $argv
|
|
||||||
|
# Space and other command terminators expands abbrs _and_ inserts itself.
|
||||||
# Space and other command terminators expands abbrs _and_ inserts itself.
|
bind --preset $argv space self-insert expand-abbr
|
||||||
bind --preset $argv space self-insert expand-abbr
|
bind --preset $argv ";" self-insert expand-abbr
|
||||||
bind --preset $argv ";" self-insert expand-abbr
|
bind --preset $argv "|" self-insert expand-abbr
|
||||||
bind --preset $argv "|" self-insert expand-abbr
|
bind --preset $argv "&" self-insert expand-abbr
|
||||||
bind --preset $argv "&" self-insert expand-abbr
|
bind --preset $argv ">" self-insert expand-abbr
|
||||||
bind --preset $argv ">" self-insert expand-abbr
|
bind --preset $argv "<" self-insert expand-abbr
|
||||||
bind --preset $argv "<" self-insert expand-abbr
|
set -l maybe_search_field "(commandline --search-field >/dev/null && echo --search-field)"
|
||||||
set -l maybe_search_field '(commandline --search-field >/dev/null && echo --search-field)'
|
bind --preset $argv shift-enter "commandline -i \n $maybe_search_field" expand-abbr
|
||||||
bind --preset $argv shift-enter "commandline -i \n $maybe_search_field" expand-abbr
|
bind --preset $argv alt-enter "commandline -i \n $maybe_search_field" expand-abbr
|
||||||
bind --preset $argv alt-enter "commandline -i \n $maybe_search_field" expand-abbr
|
bind --preset $argv ")" self-insert expand-abbr # Closing a command substitution.
|
||||||
bind --preset $argv ")" self-insert expand-abbr # Closing a command substitution.
|
bind --preset $argv ctrl-space \'test -n "$(commandline)" && commandline -i " " \'$maybe_search_field
|
||||||
bind --preset $argv ctrl-space 'test -n "$(commandline)" && commandline -i " " '$maybe_search_field
|
# Shift-space behaves like space because it\'s easy to mistype.
|
||||||
# Shift-space behaves like space because it's easy to mistype.
|
bind --preset $argv shift-space \'commandline -i " " \'$maybe_search_field expand-abbr
|
||||||
bind --preset $argv shift-space 'commandline -i " " '$maybe_search_field expand-abbr
|
|
||||||
|
bind --preset $argv enter execute
|
||||||
bind --preset $argv enter execute
|
bind --preset $argv ctrl-j execute
|
||||||
bind --preset $argv ctrl-j execute
|
bind --preset $argv ctrl-m execute
|
||||||
bind --preset $argv ctrl-m execute
|
# Make Control+Return behave like Return because it\'s easy to mistype after accepting an autosuggestion.
|
||||||
# Make Control+Return behave like Return because it's easy to mistype after accepting an autosuggestion.
|
bind --preset $argv ctrl-enter execute
|
||||||
bind --preset $argv ctrl-enter execute
|
end'
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -13,13 +13,12 @@ function fish_default_key_bindings -d "emacs-like key binds"
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Silence warnings about unavailable keys. See #4431, 4188
|
function __fish_per_os_bind
|
||||||
if not contains -- -s $argv
|
eval "$(__fish_per_os_bind_body)"
|
||||||
set argv -s $argv
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# These are shell-specific bindings that we share with vi mode.
|
# These are shell-specific bindings that we share with vi mode.
|
||||||
__fish_shared_key_bindings $argv
|
eval "$(__fish_shared_key_bindings)" $argv
|
||||||
or return # protect against invalid $argv
|
or return # protect against invalid $argv
|
||||||
|
|
||||||
bind --preset $argv right forward-char
|
bind --preset $argv right forward-char
|
||||||
@@ -50,11 +49,13 @@ function fish_default_key_bindings -d "emacs-like key binds"
|
|||||||
bind --preset $argv alt-u upcase-word
|
bind --preset $argv alt-u upcase-word
|
||||||
|
|
||||||
bind --preset $argv alt-c capitalize-word
|
bind --preset $argv alt-c capitalize-word
|
||||||
|
|
||||||
__fish_per_os_bind --preset $argv alt-backspace backward-kill-word backward-kill-token
|
__fish_per_os_bind --preset $argv alt-backspace backward-kill-word backward-kill-token
|
||||||
__fish_per_os_bind --preset $argv ctrl-alt-h backward-kill-word backward-kill-token
|
__fish_per_os_bind --preset $argv ctrl-alt-h backward-kill-word backward-kill-token
|
||||||
__fish_per_os_bind --preset $argv ctrl-backspace backward-kill-token backward-kill-word
|
__fish_per_os_bind --preset $argv ctrl-backspace backward-kill-token backward-kill-word
|
||||||
__fish_per_os_bind --preset $argv alt-delete kill-word kill-token
|
__fish_per_os_bind --preset $argv alt-delete kill-word kill-token
|
||||||
__fish_per_os_bind --preset $argv ctrl-delete kill-token kill-word
|
__fish_per_os_bind --preset $argv ctrl-delete kill-token kill-word
|
||||||
|
functions --erase __fish_per_os_bind
|
||||||
|
|
||||||
bind --preset $argv alt-\< beginning-of-buffer
|
bind --preset $argv alt-\< beginning-of-buffer
|
||||||
bind --preset $argv alt-\> end-of-buffer
|
bind --preset $argv alt-\> end-of-buffer
|
||||||
|
|||||||
@@ -324,13 +324,22 @@ function fish_vi_key_bindings --description 'vi-like key bindings for fish'
|
|||||||
echo "Unknown argument $argv" >&2
|
echo "Unknown argument $argv" >&2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __fish_vi_key_bindings_shared
|
||||||
|
eval "$(__fish_shared_key_bindings)"
|
||||||
|
end
|
||||||
|
function __fish_per_os_bind
|
||||||
|
eval "$(__fish_per_os_bind_body)"
|
||||||
|
end
|
||||||
|
|
||||||
# Inherit shared key bindings.
|
# Inherit shared key bindings.
|
||||||
# Do this first so vi-bindings win over default.
|
# Do this first so vi-bindings win over default.
|
||||||
for mode in insert default visual
|
for mode in insert default visual
|
||||||
__fish_shared_key_bindings -M $mode
|
__fish_vi_key_bindings_shared -M $mode
|
||||||
__fish_per_os_bind --preset -M $mode ctrl-right forward-token forward-word-vi
|
__fish_per_os_bind --preset -M $mode ctrl-right forward-token forward-word-vi
|
||||||
# ctrl-left is same as emacs mode
|
# ctrl-left is same as emacs mode
|
||||||
end
|
end
|
||||||
|
functions -e __fish_vi_key_bindings_shared
|
||||||
|
functions -e __fish_per_os_bind
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
builtins::error::Error,
|
builtins::error::Error,
|
||||||
common::valid_var_name,
|
common::valid_var_name,
|
||||||
err_fmt, err_raw, err_str,
|
err_fmt, err_raw, err_str,
|
||||||
highlight::highlight_and_colorize,
|
highlight::{colorize, highlight_and_colorize, highlight_shell},
|
||||||
input::{
|
input::{
|
||||||
InputMapping, InputMappingSet, KeyNameStyle, input_function_get_names, input_mappings,
|
InputMapping, InputMappingSet, KeyNameStyle, input_function_get_names, input_mappings,
|
||||||
},
|
},
|
||||||
@@ -137,6 +137,7 @@ fn generate_output_string(seq: &[Key], user: bool, bind: &InputMapping) -> WStri
|
|||||||
out.push(' ');
|
out.push(' ');
|
||||||
out.push_utfstr(&escape(ecmd));
|
out.push_utfstr(&escape(ecmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
out.push('\n');
|
out.push('\n');
|
||||||
|
|
||||||
out
|
out
|
||||||
@@ -209,11 +210,32 @@ fn list(
|
|||||||
streams: &mut IoStreams,
|
streams: &mut IoStreams,
|
||||||
) {
|
) {
|
||||||
let lst = self.input_mappings.get_names(user);
|
let lst = self.input_mappings.get_names(user);
|
||||||
|
let mut cur_file = None;
|
||||||
|
|
||||||
for binding in lst {
|
for binding in lst {
|
||||||
|
let mut out = WString::new();
|
||||||
|
let definition_file =
|
||||||
|
&self.input_mappings.get(&binding.seq, bind_mode, user)[0].definition_file;
|
||||||
|
|
||||||
|
if let Some(def_file) = definition_file {
|
||||||
|
if Some(def_file) != cur_file {
|
||||||
|
out.push_utfstr(&L!("# Defined in "));
|
||||||
|
out.push_utfstr(&**def_file);
|
||||||
|
out.push_utfstr(&L!(":\n"));
|
||||||
|
streams.out.append(&if streams.out_is_redirected {
|
||||||
|
out
|
||||||
|
} else {
|
||||||
|
let mut colors = Vec::new();
|
||||||
|
highlight_shell(&out, &mut colors, &mut parser.context(), false, None);
|
||||||
|
let colored = colorize(&out, &colors, parser.vars());
|
||||||
|
bytes2wcstring(&colored)
|
||||||
|
});
|
||||||
|
cur_file = Some(def_file);
|
||||||
|
}
|
||||||
|
}
|
||||||
if bind_mode.is_some_and(|m| m != binding.mode) {
|
if bind_mode.is_some_and(|m| m != binding.mode) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.list_one(&binding.seq, Some(&binding.mode), user, parser, streams);
|
self.list_one(&binding.seq, Some(&binding.mode), user, parser, streams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,6 +265,7 @@ fn function_names(&self, streams: &mut IoStreams) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Add specified key binding.
|
/// Add specified key binding.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn add(
|
fn add(
|
||||||
&mut self,
|
&mut self,
|
||||||
seq: &wstr,
|
seq: &wstr,
|
||||||
@@ -250,6 +273,7 @@ fn add(
|
|||||||
mode: WString,
|
mode: WString,
|
||||||
sets_mode: Option<WString>,
|
sets_mode: Option<WString>,
|
||||||
user: bool,
|
user: bool,
|
||||||
|
parser: &Parser,
|
||||||
streams: &mut IoStreams,
|
streams: &mut IoStreams,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let cmds = cmds.iter().map(|&s| s.to_owned()).collect();
|
let cmds = cmds.iter().map(|&s| s.to_owned()).collect();
|
||||||
@@ -262,8 +286,16 @@ fn add(
|
|||||||
} else {
|
} else {
|
||||||
KeyNameStyle::Plain
|
KeyNameStyle::Plain
|
||||||
};
|
};
|
||||||
self.input_mappings
|
let definition_file = parser.current_filename();
|
||||||
.add(key_seq, key_name_style, cmds, mode, sets_mode, user);
|
self.input_mappings.add(
|
||||||
|
key_seq,
|
||||||
|
key_name_style,
|
||||||
|
cmds,
|
||||||
|
mode,
|
||||||
|
sets_mode,
|
||||||
|
user,
|
||||||
|
definition_file,
|
||||||
|
);
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -383,6 +415,7 @@ fn insert(
|
|||||||
.unwrap_or(DEFAULT_BIND_MODE.to_owned()),
|
.unwrap_or(DEFAULT_BIND_MODE.to_owned()),
|
||||||
self.opts.sets_bind_mode.clone(),
|
self.opts.sets_bind_mode.clone(),
|
||||||
self.opts.user,
|
self.opts.user,
|
||||||
|
parser,
|
||||||
streams,
|
streams,
|
||||||
) {
|
) {
|
||||||
return true;
|
return true;
|
||||||
@@ -410,11 +443,11 @@ fn list_modes(&mut self, streams: &mut IoStreams) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_cmd_opts(
|
fn parse_cmd_opts(
|
||||||
|
parser: &Parser,
|
||||||
|
streams: &mut IoStreams,
|
||||||
opts: &mut Options,
|
opts: &mut Options,
|
||||||
optind: &mut usize,
|
optind: &mut usize,
|
||||||
argv: &mut [&wstr],
|
argv: &mut [&wstr],
|
||||||
parser: &mut Parser,
|
|
||||||
streams: &mut IoStreams,
|
|
||||||
) -> BuiltinResult {
|
) -> BuiltinResult {
|
||||||
let cmd = argv[0];
|
let cmd = argv[0];
|
||||||
let short_options = L!("aehkKfM:Lm:s");
|
let short_options = L!("aehkKfM:Lm:s");
|
||||||
@@ -521,7 +554,7 @@ pub fn bind(
|
|||||||
) -> BuiltinResult {
|
) -> BuiltinResult {
|
||||||
let cmd = argv[0];
|
let cmd = argv[0];
|
||||||
let mut optind = 0;
|
let mut optind = 0;
|
||||||
parse_cmd_opts(&mut self.opts, &mut optind, argv, parser, streams)?;
|
parse_cmd_opts(parser, streams, &mut self.opts, &mut optind, argv)?;
|
||||||
|
|
||||||
if self.opts.list_modes {
|
if self.opts.list_modes {
|
||||||
self.list_modes(streams);
|
self.list_modes(streams);
|
||||||
|
|||||||
34
src/input.rs
34
src/input.rs
@@ -11,7 +11,7 @@
|
|||||||
reader::{Reader, reader_reset_interrupted},
|
reader::{Reader, reader_reset_interrupted},
|
||||||
threads::assert_is_main_thread,
|
threads::assert_is_main_thread,
|
||||||
};
|
};
|
||||||
use fish_common::{Named, assert_sorted_by_name, escape, get_by_sorted_name};
|
use fish_common::{FilenameRef, Named, assert_sorted_by_name, escape, get_by_sorted_name};
|
||||||
use std::{
|
use std::{
|
||||||
mem,
|
mem,
|
||||||
sync::{
|
sync::{
|
||||||
@@ -53,6 +53,8 @@ pub struct InputMapping {
|
|||||||
pub sets_mode: Option<WString>,
|
pub sets_mode: Option<WString>,
|
||||||
/// Perhaps this binding was created using a raw escape sequence.
|
/// Perhaps this binding was created using a raw escape sequence.
|
||||||
pub key_name_style: KeyNameStyle,
|
pub key_name_style: KeyNameStyle,
|
||||||
|
/// The file from which the binding was created, or None if not from a file.
|
||||||
|
pub definition_file: Option<FilenameRef>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InputMapping {
|
impl InputMapping {
|
||||||
@@ -63,6 +65,7 @@ fn new(
|
|||||||
mode: WString,
|
mode: WString,
|
||||||
sets_mode: Option<WString>,
|
sets_mode: Option<WString>,
|
||||||
key_name_style: KeyNameStyle,
|
key_name_style: KeyNameStyle,
|
||||||
|
definition_file: Option<FilenameRef>,
|
||||||
) -> InputMapping {
|
) -> InputMapping {
|
||||||
static LAST_INPUT_MAP_SPEC_ORDER: AtomicU32 = AtomicU32::new(0);
|
static LAST_INPUT_MAP_SPEC_ORDER: AtomicU32 = AtomicU32::new(0);
|
||||||
let specification_order = 1 + LAST_INPUT_MAP_SPEC_ORDER.fetch_add(1, Ordering::Relaxed);
|
let specification_order = 1 + LAST_INPUT_MAP_SPEC_ORDER.fetch_add(1, Ordering::Relaxed);
|
||||||
@@ -77,6 +80,7 @@ fn new(
|
|||||||
mode,
|
mode,
|
||||||
sets_mode,
|
sets_mode,
|
||||||
key_name_style,
|
key_name_style,
|
||||||
|
definition_file,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -289,6 +293,7 @@ fn input_mapping_insert_sorted(ml: &mut Vec<InputMapping>, new_mapping: InputMap
|
|||||||
|
|
||||||
impl InputMappingSet {
|
impl InputMappingSet {
|
||||||
/// Adds an input mapping.
|
/// Adds an input mapping.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn add(
|
pub fn add(
|
||||||
&mut self,
|
&mut self,
|
||||||
sequence: Vec<Key>,
|
sequence: Vec<Key>,
|
||||||
@@ -297,6 +302,7 @@ pub fn add(
|
|||||||
mode: WString,
|
mode: WString,
|
||||||
sets_mode: Option<WString>,
|
sets_mode: Option<WString>,
|
||||||
user: bool,
|
user: bool,
|
||||||
|
definition_file: Option<FilenameRef>,
|
||||||
) {
|
) {
|
||||||
// Update any existing mapping with this sequence.
|
// Update any existing mapping with this sequence.
|
||||||
// FIXME: this makes adding multiple bindings quadratic.
|
// FIXME: this makes adding multiple bindings quadratic.
|
||||||
@@ -309,16 +315,25 @@ pub fn add(
|
|||||||
if m.seq == sequence && m.mode == mode {
|
if m.seq == sequence && m.mode == mode {
|
||||||
m.commands = commands;
|
m.commands = commands;
|
||||||
m.sets_mode = sets_mode;
|
m.sets_mode = sets_mode;
|
||||||
|
m.definition_file = definition_file;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add a new mapping, using the next order.
|
// Add a new mapping, using the next order.
|
||||||
let new_mapping = InputMapping::new(sequence, commands, mode, sets_mode, key_name_style);
|
let new_mapping = InputMapping::new(
|
||||||
|
sequence,
|
||||||
|
commands,
|
||||||
|
mode,
|
||||||
|
sets_mode,
|
||||||
|
key_name_style,
|
||||||
|
definition_file,
|
||||||
|
);
|
||||||
input_mapping_insert_sorted(ml, new_mapping);
|
input_mapping_insert_sorted(ml, new_mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like add(), but takes a single command.
|
// Like add(), but takes a single command.
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
pub fn add1(
|
pub fn add1(
|
||||||
&mut self,
|
&mut self,
|
||||||
sequence: Vec<Key>,
|
sequence: Vec<Key>,
|
||||||
@@ -327,6 +342,7 @@ pub fn add1(
|
|||||||
mode: WString,
|
mode: WString,
|
||||||
sets_mode: Option<WString>,
|
sets_mode: Option<WString>,
|
||||||
user: bool,
|
user: bool,
|
||||||
|
definition_file: Option<FilenameRef>,
|
||||||
) {
|
) {
|
||||||
self.add(
|
self.add(
|
||||||
sequence,
|
sequence,
|
||||||
@@ -335,6 +351,7 @@ pub fn add1(
|
|||||||
mode,
|
mode,
|
||||||
sets_mode,
|
sets_mode,
|
||||||
user,
|
user,
|
||||||
|
definition_file,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,7 +374,15 @@ pub fn init_input() {
|
|||||||
let mut add = |key: Vec<Key>, cmd: &str| {
|
let mut add = |key: Vec<Key>, cmd: &str| {
|
||||||
let mode = DEFAULT_BIND_MODE.to_owned();
|
let mode = DEFAULT_BIND_MODE.to_owned();
|
||||||
let sets_mode = Some(DEFAULT_BIND_MODE.to_owned());
|
let sets_mode = Some(DEFAULT_BIND_MODE.to_owned());
|
||||||
input_mapping.add1(key, KeyNameStyle::Plain, cmd.into(), mode, sets_mode, false);
|
input_mapping.add1(
|
||||||
|
key,
|
||||||
|
KeyNameStyle::Plain,
|
||||||
|
cmd.into(),
|
||||||
|
mode,
|
||||||
|
sets_mode,
|
||||||
|
false,
|
||||||
|
None,
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
add(vec![], "self-insert");
|
add(vec![], "self-insert");
|
||||||
@@ -390,6 +415,7 @@ pub fn init_input() {
|
|||||||
mode,
|
mode,
|
||||||
sets_mode,
|
sets_mode,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
add_raw("\x1B[A", "up-line");
|
add_raw("\x1B[A", "up-line");
|
||||||
@@ -1044,6 +1070,7 @@ fn test_input() {
|
|||||||
bind_mode(),
|
bind_mode(),
|
||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
input_mappings.add1(
|
input_mappings.add1(
|
||||||
desired_binding.clone(),
|
desired_binding.clone(),
|
||||||
@@ -1052,6 +1079,7 @@ fn test_input() {
|
|||||||
bind_mode(),
|
bind_mode(),
|
||||||
None,
|
None,
|
||||||
true,
|
true,
|
||||||
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Push the desired binding to the queue.
|
// Push the desired binding to the queue.
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ for bindings in true fish_default_key_bindings fish_vi_key_bindings
|
|||||||
$fish -c "
|
$fish -c "
|
||||||
$bindings
|
$bindings
|
||||||
or echo >&2 error setting bindings: status=\$status
|
or echo >&2 error setting bindings: status=\$status
|
||||||
bind > $tmpdir/old
|
bind | string match -r -v '^# Defined in' > $tmpdir/old
|
||||||
bind --erase --all --preset
|
bind --erase --all --preset
|
||||||
bind --erase --all
|
bind --erase --all
|
||||||
source $tmpdir/old
|
source $tmpdir/old
|
||||||
bind >$tmpdir/new
|
bind | string match -r -v '^# Defined in' >$tmpdir/new
|
||||||
diff -u $tmpdir/{old,new}
|
diff -u $tmpdir/{old,new}
|
||||||
"
|
"
|
||||||
end
|
end
|
||||||
@@ -35,8 +35,12 @@ bind -M bind-mode \cX true
|
|||||||
bind -M bind_mode \cX true
|
bind -M bind_mode \cX true
|
||||||
|
|
||||||
# Listing bindings
|
# Listing bindings
|
||||||
bind | string match -v '*\e\\[*' # Hide raw bindings.
|
{
|
||||||
bind --user --preset | string match -v '*\e\\[*'
|
bind
|
||||||
|
bind --user --preset
|
||||||
|
} |
|
||||||
|
string match -v '*\e\\[*' | # Hide raw bindings.
|
||||||
|
string match -r -v '^# Defined in'
|
||||||
# CHECK: bind --preset '' self-insert
|
# CHECK: bind --preset '' self-insert
|
||||||
# CHECK: bind --preset enter execute
|
# CHECK: bind --preset enter execute
|
||||||
# CHECK: bind --preset tab complete
|
# CHECK: bind --preset tab complete
|
||||||
@@ -75,7 +79,7 @@ bind --user --preset | string match -v '*\e\\[*'
|
|||||||
# CHECK: bind -M bind_mode ctrl-x true
|
# CHECK: bind -M bind_mode ctrl-x true
|
||||||
|
|
||||||
# Preset only
|
# Preset only
|
||||||
bind --preset | string match -v '*\e\\[*'
|
bind --preset | string match -v '*\e\\[*' | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind --preset '' self-insert
|
# CHECK: bind --preset '' self-insert
|
||||||
# CHECK: bind --preset enter execute
|
# CHECK: bind --preset enter execute
|
||||||
# CHECK: bind --preset tab complete
|
# CHECK: bind --preset tab complete
|
||||||
@@ -95,12 +99,12 @@ bind --preset | string match -v '*\e\\[*'
|
|||||||
# CHECK: bind --preset ctrl-f forward-char
|
# CHECK: bind --preset ctrl-f forward-char
|
||||||
|
|
||||||
# User only
|
# User only
|
||||||
bind --user | string match -v '*\e\\[*'
|
bind --user | string match -v '*\e\\[*' | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind -M bind_mode ctrl-x true
|
# CHECK: bind -M bind_mode ctrl-x true
|
||||||
|
|
||||||
# Adding bindings
|
# Adding bindings
|
||||||
bind tab 'echo banana'
|
bind tab 'echo banana'
|
||||||
bind | string match -v '*\e\\[*'
|
bind | string match -v '*\e\\[*' | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind --preset '' self-insert
|
# CHECK: bind --preset '' self-insert
|
||||||
# CHECK: bind --preset enter execute
|
# CHECK: bind --preset enter execute
|
||||||
# CHECK: bind --preset tab complete
|
# CHECK: bind --preset tab complete
|
||||||
@@ -132,15 +136,15 @@ bind super-alt-\~
|
|||||||
|
|
||||||
# Legacy
|
# Legacy
|
||||||
bind \cx\cax 'echo foo'
|
bind \cx\cax 'echo foo'
|
||||||
bind \cx\cax
|
bind \cx\cax | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind ctrl-x,ctrl-a,x 'echo foo'
|
# CHECK: bind ctrl-x,ctrl-a,x 'echo foo'
|
||||||
bind \ef forward-word
|
bind \ef forward-word
|
||||||
bind \ef
|
bind \ef | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind alt-f forward-word
|
# CHECK: bind alt-f forward-word
|
||||||
|
|
||||||
# Erasing bindings
|
# Erasing bindings
|
||||||
bind --erase tab
|
bind --erase tab
|
||||||
bind tab
|
bind tab | string match -r -v '^# Defined in'
|
||||||
bind tab 'echo wurst'
|
bind tab 'echo wurst'
|
||||||
# CHECK: bind --preset tab complete
|
# CHECK: bind --preset tab complete
|
||||||
bind --erase --user --preset tab
|
bind --erase --user --preset tab
|
||||||
@@ -154,7 +158,7 @@ bind -k nul 'echo foo'
|
|||||||
# CHECKERR: bind: the -k/--key syntax is no longer supported. See `bind --help` and `bind --key-names`
|
# CHECKERR: bind: the -k/--key syntax is no longer supported. See `bind --help` and `bind --key-names`
|
||||||
|
|
||||||
# Either Return or ctrl-m.
|
# Either Return or ctrl-m.
|
||||||
bind \r
|
bind \r | string match -r -v '^# Defined in'
|
||||||
# CHECK: bind --preset enter execute
|
# CHECK: bind --preset enter execute
|
||||||
# Never Return, probably always ctrl-j.
|
# Never Return, probably always ctrl-j.
|
||||||
bind \n 2>&1
|
bind \n 2>&1
|
||||||
|
|||||||
Reference in New Issue
Block a user