Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Show file location when querying bindings with bind#12221

Open
ritoban23 wants to merge 4 commits intofish-shell:masterfrom
ritoban23:bind-show-file-location
Open

Show file location when querying bindings with bind#12221
ritoban23 wants to merge 4 commits intofish-shell:masterfrom
ritoban23:bind-show-file-location

Conversation

@ritoban23
Copy link

Description

This PR enhances the bind builtin to display the file in which a key binding was defined when querying existing bindings, similar to how functions -q and type show the definition location.

  • Adds a definition_file field to the InputMapping struct to track the source file for each binding.
  • Updates the bind output to append # defined in <filename> when a binding was created from a file.
  • Bindings created interactively or from stdin do not show a file location.

Fixes issue #12215

TODOs:

  • Changes to fish usage are reflected in user documentation/manpages.
  • Tests have been added for regressions fixed
  • User-visible changes noted in CHANGELOG.rst


// Show where the binding was defined
if let Some(def_file) = definition_file {
out.push_str(" # defined in ");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should be push_utfstr(wgettext!(...)) so it's translated

};
self.input_mappings
.add(key_seq, key_name_style, cmds, mode, sets_mode, user);
let definition_file = parser.current_filename();
Copy link
Contributor

@krobelus krobelus Jan 3, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at some example output

	bind --preset \; self-insert expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	bind --preset \| self-insert expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	bind --preset \& self-insert expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	bind --preset \> self-insert expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	bind --preset \< self-insert expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	...
	bind --preset shift-enter 'commandline -i \\n (commandline --search-field >/dev/null && echo --search-field)' expand-abbr # defined in embedded:functions/__fish_shared_key_bindings.fish
	...
	bind --preset alt-backspace 'if fish_in_macos_terminal; commandline -f backward-kill-word; else commandline -f backward-kill-token; end' # defined in embedded:functions/__fish_per_os_bind.fish

I notice that

  1. there's a lot of noisy repetition
  2. the file names are private implementation files (denoted by the leading __),
    which we should avoid exposing to the user.
  3. the __fish_per_os_bind.fish is a helper file that's called from default/shared key bindings

I'm not sure yet what we should do, but

  • to address 1, we could group bindings by filename, and on
	# Defined in embedded:functions/fish_default_key_bindings.fish
	bind --preset \; self-insert expand-abbr
	bind --preset \| self-insert expand-abbr
	bind --preset \& self-insert expand-abbr
	bind --preset \> self-insert expand-abbr
	bind --preset \< self-insert expand-abbr
	# Defined in ~/.config/fish/config.fish
	bind ...

i'm not yet sure if that messes with semantics;
historically we list bindings in definition order but
IIRC that order is not used to determine priority at all.
So that should be fine..

  • to address 2 and 3, we could maybe rework the way our default bindings work.
    For example we could have __fish_shared_key_bindings only output bind commands,
    and then have fish_default_key_bindings.fish and fish_vi_key_bindings.fish call eval "$(__fish_shared_key_bindings)".

self.opts.sets_bind_mode.to_owned(),
self.opts.user,
parser,
streams,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(unrelated: parser and streams should be the first two arguments like for the top-level builtin functions)

}

// Like add(), but takes a single command.
#[allow(clippy::too_many_arguments)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FWIW every commit should ideally pass all tests & lints, so squash these commits if possible

bind | string match -v '*\e\\[*' # Hide raw bindings.
bind --user --preset | string match -v '*\e\\[*'
bind | string match -v '*\e\\[*' | string replace -r ' # defined in .*' '' # Hide raw bindings.
bind --user --preset | string match -v '*\e\\[*' | string replace -r ' # defined in .*' ''
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

rather than repeating the same string replace command everywhere,
how about extracting a function to
tests/test_functions/test-bind.fish or tests/test_functions/bind-list.fish
that does it by default, for brevity?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants