New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modularize user key bindings #5191

Closed
jorgebucaran opened this Issue Sep 17, 2018 · 8 comments

Comments

Projects
None yet
2 participants
@jorgebucaran
Copy link

jorgebucaran commented Sep 17, 2018

Would you consider making fish aware of a new keybindings directory inside $__fish_datadir, XDG_CONFIG_HOME, etc.?

Then, during startup, copy the user's fish_user_key_bindings function (if there is one) and create a new fish_user_key_bindings function that when invoked, will source every file in each keybindings/ directory in $__fish_datadir and XDG_CONFIG_HOME.

Basically this:

if functions -q fish_user_key_bindings
  functions -c fish_user_key_bindings __fish_user_key_bindings
end

function fish_user_key_bindings
  for file in ~/.config/fish/keybindings/*.fish
    source $file
  end
  if functions -q __fish_user_key_bindings
    __fish_user_key_bindings
  end
end

I can emulate this behavior using conf.d and distribute that script as a plugin, but it would be nice to have this out of the box.

In fisher v2.x (since I depend exclusively on fish autoloading feature) I go to great lengths to generate a fish_user_key_bindings function on the fly that concatenates the keybindings exported by each plugin with the user's key bindings defined inside their fish_user_key_bindings, but it's highly impractical (and buggy). In fisher v3.x I'll work around this more cleanly with a plugin as suggested above, but it would be nice if I didn't need to.

Oh-my-fish (here) and fundle (here) emulate this behavior through the user's config.fish using the same (or similar) technique described above.

@faho

This comment has been minimized.

Copy link
Member

faho commented Sep 17, 2018

I've actually been thinking about doing away with the need for fish_user_key_bindings entirely.

Really, the only reason that function is needed is because, when the user switches binding sets (e.g. from emacs to vi) we want to erase everything belonging to the old set. So what we do now is to erase everything and rerun that function.

What I've been thinking about is to add a "--default" or "--system" switch to bind. Any binding set would then always call bind --default, and the user wouldn't, so we could then just erase bindings defined with that switch (bind --erase --all --default).

So what fisher/omf/fundle would then do is simply call bind - I'm just not quite sure if with --default or not, yet.

@faho faho added the enhancement label Sep 17, 2018

@faho faho added this to the fish-future milestone Sep 17, 2018

@jorgebucaran

This comment has been minimized.

Copy link

jorgebucaran commented Sep 17, 2018

@faho Do you mean that it would work similarly to complete?

So, with complete we can already complete -ec $funcname which makes uninstalling completions easy. Installing them is easy as well, just put them in the $fish_complete_path, and if you want them in the current shell, just source the $path/completions/$funcname.fish file.

@faho

This comment has been minimized.

Copy link
Member

faho commented Sep 17, 2018

Do you mean that it would work similarly to complete?

Not really, no. Just if you call bind, we keep that binding, even if you switch from vi to emacs or the other way around. In fish_vi_key_bindings and such we'd use bind --default, and we'd do bind --erase --all --default to clear all previously defined default bindings, but not bindings defined without --default.

If you do bind \t something-else, we still keep the default (bind --default \t complete) in the background, so if you then delete yours, that becomes active again.

I don't think we would need any special files to support this - you'd do bind statements in conf.d files as part of your setup.

@jorgebucaran

This comment has been minimized.

Copy link

jorgebucaran commented Sep 17, 2018

@faho I don't think we would need any special files to support this - you'd do bind statements in conf.d files as part of your setup.

Wouldn't that run into the same problem of using bind in config.fish (you can't). 🤔

@jorgebucaran

This comment has been minimized.

Copy link

jorgebucaran commented Sep 18, 2018

@faho ...you'd do bind statements in conf.d files as part of your setup.

I haven't run any benchmarks, but I suspect this wouldn't be scalable as it would force every script that wants to add its own bindings to copy any existing fish_user_key_bindings.

echo "...initializing my script"

if functions -q fish_user_key_bindings
    functions --copy fish_user_key_bindings _my_script_fish_user_key_bindings
end

function fish_user_key_bindings
    bind ...
    bind ...
    bind ...

    if functions -q _my_script_fish_user_key_bindings
        _my_script_fish_user_key_bindings
    end
end

If I have 10 my_script-like files in conf.d, because that's the point of this issue—to be able to modularize key bindings—then the most recently defined fish_user_key_bindings function would be copied over 10 times.

A more sensible approach would be to copy the function only once and source a bunch of files with the bind statements as described above.

Now, perhaps I still don't understand what "doing away with the need for fish_user_key_bindings entirely" means. Do you mean removing this feature?

That would be a breaking change, and IMO, a less optimal plan of action, as it would force plugin manager authors to go to great lengths if they intend to support at least fish >=2.3, as I intend to do.

@jorgebucaran

This comment has been minimized.

Copy link

jorgebucaran commented Sep 18, 2018

I used fish -p to measure the startup time impact of 4 plugins that set key bindings using the copy method through conf.d versus using the approach I suggested of a single conf.d script that copies fish_user_key_bindings once and the results indicate that my suggestion is actually slower.

I suspect that my suggestion is slower because of the fact the conf.d script iterates over each file in the proposed keybindings directory and then sources them. This touches the filesystem, whereas copying fish_user_key_bindings N times over (once per plugin) doesn't.

Taking into account this and the drawback of introducing a new feature (feature bloat) I have mixed feelings about this feature request now. The obvious win of this feature is that it makes it very easy to define key bindings on a per-plugin basis, but the alternative doesn't make it impossible, just a bit more difficult. I am leaning towards the slightly more difficult process, in exchange for a simpler plugin architecture and less nosey shell (existing behavior).

PROFILING RESULTS
NO PLUGINS
fish -c exit -p profile
Time	Sum	Command
721	4640	> builtin source /usr/local/share/fish/config.fish 2>/dev/null
56	56	-> set -g IFS \n\ \t
19	19	-> function __fish_default_command_not_found_handler...
14	14	-> function __fish_command_not_found_handler --on-event fish_command_not_found...
60	60	-> set -l configdir ~/.config
6	23	-> if set -q XDG_CONFIG_HOME...
17	17	--> set -q XDG_CONFIG_HOME
38	38	-> set -l userdatadir ~/.local/share
6	20	-> if set -q XDG_DATA_HOME...
14	14	--> set -q XDG_DATA_HOME
8	69	-> if not set -q fish_function_path...
15	15	--> not set -q fish_function_path
46	46	--> set fish_function_path $configdir/fish/functions    $__fish_sysconfdir/functions    $__fish_datadir/functions
6	98	-> if not contains $__fish_datadir/functions $fish_function_path...
92	92	--> not contains $__fish_datadir/functions $fish_function_path
10	108	-> if not set -q fish_complete_path...
34	34	--> not set -q fish_complete_path
64	64	--> set fish_complete_path $configdir/fish/completions  $__fish_sysconfdir/completions  $__fish_datadir/vendor_completions.d  $__fish_datadir/completions $userdatadir/fish/generated_completions
6	54	-> if not contains $__fish_datadir/completions $fish_complete_path...
48	48	--> not contains $__fish_datadir/completions $fish_complete_path
6	51	-> if test -d /usr/xpg4/bin...
45	45	--> test -d /usr/xpg4/bin
58	58	-> set -g __fish_tmp_path $PATH
9	9	-> function __fish_load_path_helper_paths...
37	37	-> test -r /etc/paths
99	1688	-> and __fish_load_path_helper_paths < /etc/paths
88	88	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
68	1444	--> while read -l new_path_comp...
103	103	---> read -l new_path_comp
91	157	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
66	66	----> contains -i $new_path_comp $__fish_tmp_path
35	35	---> and set -e __fish_tmp_path[$where]
58	58	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
52	52	---> read -l new_path_comp
58	116	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
58	58	----> contains -i $new_path_comp $__fish_tmp_path
32	32	---> and set -e __fish_tmp_path[$where]
58	58	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
37	37	---> read -l new_path_comp
57	112	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
55	55	----> contains -i $new_path_comp $__fish_tmp_path
32	32	---> and set -e __fish_tmp_path[$where]
57	57	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
53	53	---> read -l new_path_comp
56	117	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
61	61	----> contains -i $new_path_comp $__fish_tmp_path
31	31	---> and set -e __fish_tmp_path[$where]
56	56	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
41	41	---> read -l new_path_comp
55	111	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
56	56	----> contains -i $new_path_comp $__fish_tmp_path
31	31	---> and set -e __fish_tmp_path[$where]
67	67	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
20	20	---> read -l new_path_comp
57	57	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
92	648	-> for pathfile in /etc/paths.d/* ...
93	556	--> __fish_load_path_helper_paths < $pathfile
62	62	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
20	343	---> while read -l new_path_comp...
100	100	----> read -l new_path_comp
57	118	----> set -l where (contains -i $new_path_comp $__fish_tmp_path)
61	61	-----> contains -i $new_path_comp $__fish_tmp_path
31	31	----> and set -e __fish_tmp_path[$where]
54	54	----> set __fish_tmp_path $new_path_comp $__fish_tmp_path
20	20	----> read -l new_path_comp
58	58	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
57	57	-> set -xg PATH $__fish_tmp_path
19	19	-> set -e __fish_tmp_path
45	45	-> functions -e __fish_load_path_helper_paths
22	22	-> function __fish_reconstruct_path -d "Update PATH when fish_user_paths changes" --on-variable fish_user_paths...
99	667	-> __fish_reconstruct_path
55	55	--> set -l local_path $PATH
15	15	--> set -l x
8	8	--> for x in $__fish_added_user_paths...
16	16	--> set -e __fish_added_user_paths
28	421	--> for x in $fish_user_paths[-1..1]...
9	146	---> if set -l idx (contains --index $x $local_path)...
53	107	----> set -l idx (contains --index $x $local_path)
54	54	-----> contains --index $x $local_path
30	30	----> set -e local_path[$idx]
52	52	---> set local_path $x $local_path
9	145	---> if set -l idx (contains --index $x $local_path)...
49	107	----> set -l idx (contains --index $x $local_path)
58	58	-----> contains --index $x $local_path
29	29	----> set -e local_path[$idx]
50	50	---> set local_path $x $local_path
53	53	--> set -xg PATH $local_path
34	34	-> function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Launches a debug prompt."...
11	11	-> function __fish_on_interactive --on-event fish_prompt...
14	14	-> function . --description 'Evaluate contents of file (deprecated, see "source")' --no-scope-shadowing...
139	185	> builtin source /usr/local/etc/fish/config.fish 2>/dev/null
6	46	-> if status --is-login...
40	40	--> status --is-login
158	257	> builtin source /Users/x/.config/fish/config.fish 2>/dev/null
57	57	-> for file in ~/.config/fish/conf.d/*.fish...
6	24	-> if status --is-interactive...
18	18	--> status --is-interactive
10	10	-> function __gh_migrate...
8	8	-> function __gh_push_force...
29	29	> exit
MANUAL BIND VIA CONF.D
fish -c exit -p profile
Time	Sum	Command
720	4622	> builtin source /usr/local/share/fish/config.fish 2>/dev/null
56	56	-> set -g IFS \n\ \t
19	19	-> function __fish_default_command_not_found_handler...
13	13	-> function __fish_command_not_found_handler --on-event fish_command_not_found...
60	60	-> set -l configdir ~/.config
7	23	-> if set -q XDG_CONFIG_HOME...
16	16	--> set -q XDG_CONFIG_HOME
38	38	-> set -l userdatadir ~/.local/share
5	20	-> if set -q XDG_DATA_HOME...
15	15	--> set -q XDG_DATA_HOME
9	67	-> if not set -q fish_function_path...
14	14	--> not set -q fish_function_path
44	44	--> set fish_function_path $configdir/fish/functions    $__fish_sysconfdir/functions    $__fish_datadir/functions
6	104	-> if not contains $__fish_datadir/functions $fish_function_path...
98	98	--> not contains $__fish_datadir/functions $fish_function_path
10	112	-> if not set -q fish_complete_path...
38	38	--> not set -q fish_complete_path
64	64	--> set fish_complete_path $configdir/fish/completions  $__fish_sysconfdir/completions  $__fish_datadir/vendor_completions.d  $__fish_datadir/completions $userdatadir/fish/generated_completions
5	54	-> if not contains $__fish_datadir/completions $fish_complete_path...
49	49	--> not contains $__fish_datadir/completions $fish_complete_path
6	52	-> if test -d /usr/xpg4/bin...
46	46	--> test -d /usr/xpg4/bin
58	58	-> set -g __fish_tmp_path $PATH
10	10	-> function __fish_load_path_helper_paths...
39	39	-> test -r /etc/paths
99	1641	-> and __fish_load_path_helper_paths < /etc/paths
87	87	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
68	1398	--> while read -l new_path_comp...
103	103	---> read -l new_path_comp
91	157	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
66	66	----> contains -i $new_path_comp $__fish_tmp_path
34	34	---> and set -e __fish_tmp_path[$where]
70	70	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
49	49	---> read -l new_path_comp
55	112	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
57	57	----> contains -i $new_path_comp $__fish_tmp_path
31	31	---> and set -e __fish_tmp_path[$where]
55	55	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
36	36	---> read -l new_path_comp
53	107	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
54	54	----> contains -i $new_path_comp $__fish_tmp_path
30	30	---> and set -e __fish_tmp_path[$where]
54	54	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
51	51	---> read -l new_path_comp
53	112	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
59	59	----> contains -i $new_path_comp $__fish_tmp_path
30	30	---> and set -e __fish_tmp_path[$where]
53	53	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
39	39	---> read -l new_path_comp
51	106	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
55	55	----> contains -i $new_path_comp $__fish_tmp_path
29	29	---> and set -e __fish_tmp_path[$where]
53	53	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
19	19	---> read -l new_path_comp
57	57	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
91	651	-> for pathfile in /etc/paths.d/* ...
96	560	--> __fish_load_path_helper_paths < $pathfile
63	63	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
19	343	---> while read -l new_path_comp...
101	101	----> read -l new_path_comp
56	117	----> set -l where (contains -i $new_path_comp $__fish_tmp_path)
61	61	-----> contains -i $new_path_comp $__fish_tmp_path
32	32	----> and set -e __fish_tmp_path[$where]
54	54	----> set __fish_tmp_path $new_path_comp $__fish_tmp_path
20	20	----> read -l new_path_comp
58	58	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
57	57	-> set -xg PATH $__fish_tmp_path
19	19	-> set -e __fish_tmp_path
45	45	-> functions -e __fish_load_path_helper_paths
21	21	-> function __fish_reconstruct_path -d "Update PATH when fish_user_paths changes" --on-variable fish_user_paths...
88	680	-> __fish_reconstruct_path
56	56	--> set -l local_path $PATH
16	16	--> set -l x
8	8	--> for x in $__fish_added_user_paths...
16	16	--> set -e __fish_added_user_paths
28	442	--> for x in $fish_user_paths[-1..1]...
8	156	---> if set -l idx (contains --index $x $local_path)...
58	115	----> set -l idx (contains --index $x $local_path)
57	57	-----> contains --index $x $local_path
33	33	----> set -e local_path[$idx]
54	54	---> set local_path $x $local_path
10	151	---> if set -l idx (contains --index $x $local_path)...
52	112	----> set -l idx (contains --index $x $local_path)
60	60	-----> contains --index $x $local_path
29	29	----> set -e local_path[$idx]
53	53	---> set local_path $x $local_path
54	54	--> set -xg PATH $local_path
36	36	-> function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Launches a debug prompt."...
12	12	-> function __fish_on_interactive --on-event fish_prompt...
15	15	-> function . --description 'Evaluate contents of file (deprecated, see "source")' --no-scope-shadowing...
148	196	> builtin source /usr/local/etc/fish/config.fish 2>/dev/null
6	48	-> if status --is-login...
42	42	--> status --is-login
218	1582	> builtin source /Users/x/.config/fish/config.fish 2>/dev/null
115	1321	-> for file in ~/.config/fish/conf.d/*.fish...
143	383	--> source $file
9	217	---> if functions -q fish_user_key_bindings...
72	160	----> functions -q fish_user_key_bindings
79	88	-----> source /Users/x/.config/fish/functions/fish_user_key_bindings.fish
9	9	------> function fish_user_key_bindings...
48	48	----> functions -c fish_user_key_bindings _salute_fish_user_key_bindings
11	11	---> function fish_user_key_bindings...
12	12	---> function _salute_erase_key_bindings --on-event uninstall_key_bindings_salute...
142	294	--> source $file
11	125	---> if functions -q fish_user_key_bindings...
64	64	----> functions -q fish_user_key_bindings
50	50	----> functions -c fish_user_key_bindings _salute_green_fish_user_key_bindings
14	14	---> function fish_user_key_bindings...
13	13	---> function _salute_green_erase_key_bindings --on-event uninstall_key_bindings_salute_green...
212	311	--> source $file
9	78	---> if functions -q fish_user_key_bindings...
22	22	----> functions -q fish_user_key_bindings
47	47	----> functions -c fish_user_key_bindings _salute_magenta_fish_user_key_bindings
10	10	---> function fish_user_key_bindings...
11	11	---> function _salute_magenta_erase_key_bindings --on-event uninstall_key_bindings_salute_magenta...
123	218	--> source $file
9	75	---> if functions -q fish_user_key_bindings...
20	20	----> functions -q fish_user_key_bindings
46	46	----> functions -c fish_user_key_bindings _salute_red_fish_user_key_bindings
9	9	---> function fish_user_key_bindings...
11	11	---> function _salute_red_erase_key_bindings --on-event uninstall_key_bindings_salute_red...
5	21	-> if status --is-interactive...
16	16	--> status --is-interactive
14	14	-> function __gh_migrate...
8	8	-> function __gh_push_force...
48	48	> exit
SUGGESTED METHOD
fish -c exit -p profile
Time	Sum	Command
801	5081	> builtin source /usr/local/share/fish/config.fish 2>/dev/null
56	56	-> set -g IFS \n\ \t
19	19	-> function __fish_default_command_not_found_handler...
14	14	-> function __fish_command_not_found_handler --on-event fish_command_not_found...
64	64	-> set -l configdir ~/.config
7	23	-> if set -q XDG_CONFIG_HOME...
16	16	--> set -q XDG_CONFIG_HOME
43	43	-> set -l userdatadir ~/.local/share
6	21	-> if set -q XDG_DATA_HOME...
15	15	--> set -q XDG_DATA_HOME
9	69	-> if not set -q fish_function_path...
14	14	--> not set -q fish_function_path
46	46	--> set fish_function_path $configdir/fish/functions    $__fish_sysconfdir/functions    $__fish_datadir/functions
7	99	-> if not contains $__fish_datadir/functions $fish_function_path...
92	92	--> not contains $__fish_datadir/functions $fish_function_path
10	112	-> if not set -q fish_complete_path...
35	35	--> not set -q fish_complete_path
67	67	--> set fish_complete_path $configdir/fish/completions  $__fish_sysconfdir/completions  $__fish_datadir/vendor_completions.d  $__fish_datadir/completions $userdatadir/fish/generated_completions
5	54	-> if not contains $__fish_datadir/completions $fish_complete_path...
49	49	--> not contains $__fish_datadir/completions $fish_complete_path
6	52	-> if test -d /usr/xpg4/bin...
46	46	--> test -d /usr/xpg4/bin
57	57	-> set -g __fish_tmp_path $PATH
9	9	-> function __fish_load_path_helper_paths...
39	39	-> test -r /etc/paths
115	1710	-> and __fish_load_path_helper_paths < /etc/paths
88	88	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
65	1446	--> while read -l new_path_comp...
105	105	---> read -l new_path_comp
93	159	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
66	66	----> contains -i $new_path_comp $__fish_tmp_path
35	35	---> and set -e __fish_tmp_path[$where]
57	57	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
52	52	---> read -l new_path_comp
58	117	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
59	59	----> contains -i $new_path_comp $__fish_tmp_path
32	32	---> and set -e __fish_tmp_path[$where]
58	58	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
36	36	---> read -l new_path_comp
56	113	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
57	57	----> contains -i $new_path_comp $__fish_tmp_path
33	33	---> and set -e __fish_tmp_path[$where]
56	56	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
57	57	---> read -l new_path_comp
57	119	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
62	62	----> contains -i $new_path_comp $__fish_tmp_path
32	32	---> and set -e __fish_tmp_path[$where]
56	56	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
41	41	---> read -l new_path_comp
56	113	---> set -l where (contains -i $new_path_comp $__fish_tmp_path)
57	57	----> contains -i $new_path_comp $__fish_tmp_path
32	32	---> and set -e __fish_tmp_path[$where]
58	58	---> set __fish_tmp_path $new_path_comp $__fish_tmp_path
20	20	---> read -l new_path_comp
61	61	--> set __fish_tmp_path $__fish_tmp_path[-1..1]
92	653	-> for pathfile in /etc/paths.d/* ...
94	561	--> __fish_load_path_helper_paths < $pathfile
64	64	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
20	345	---> while read -l new_path_comp...
100	100	----> read -l new_path_comp
57	118	----> set -l where (contains -i $new_path_comp $__fish_tmp_path)
61	61	-----> contains -i $new_path_comp $__fish_tmp_path
32	32	----> and set -e __fish_tmp_path[$where]
55	55	----> set __fish_tmp_path $new_path_comp $__fish_tmp_path
20	20	----> read -l new_path_comp
58	58	---> set __fish_tmp_path $__fish_tmp_path[-1..1]
59	59	-> set -xg PATH $__fish_tmp_path
19	19	-> set -e __fish_tmp_path
46	46	-> functions -e __fish_load_path_helper_paths
22	22	-> function __fish_reconstruct_path -d "Update PATH when fish_user_paths changes" --on-variable fish_user_paths...
97	977	-> __fish_reconstruct_path
57	57	--> set -l local_path $PATH
16	16	--> set -l x
8	8	--> for x in $__fish_added_user_paths...
17	17	--> set -e __fish_added_user_paths
45	728	--> for x in $fish_user_paths[-1..1]...
13	326	---> if set -l idx (contains --index $x $local_path)...
178	263	----> set -l idx (contains --index $x $local_path)
85	85	-----> contains --index $x $local_path
50	50	----> set -e local_path[$idx]
97	97	---> set local_path $x $local_path
10	206	---> if set -l idx (contains --index $x $local_path)...
66	162	----> set -l idx (contains --index $x $local_path)
96	96	-----> contains --index $x $local_path
34	34	----> set -e local_path[$idx]
54	54	---> set local_path $x $local_path
54	54	--> set -xg PATH $local_path
36	36	-> function fish_sigtrap_handler --on-signal TRAP --no-scope-shadowing --description "Signal handler for the TRAP signal. Launches a debug prompt."...
12	12	-> function __fish_on_interactive --on-event fish_prompt...
15	15	-> function . --description 'Evaluate contents of file (deprecated, see "source")' --no-scope-shadowing...
145	194	> builtin source /usr/local/etc/fish/config.fish 2>/dev/null
6	49	-> if status --is-login...
43	43	--> status --is-login
158	728	> builtin source /Users/x/.config/fish/config.fish 2>/dev/null
73	531	-> for file in ~/.config/fish/conf.d/*.fish...
156	458	--> source $file
8	219	---> if functions -q fish_user_key_bindings...
77	163	----> functions -q fish_user_key_bindings
78	86	-----> source /Users/x/.config/fish/functions/fish_user_key_bindings.fish
8	8	------> function fish_user_key_bindings...
48	48	----> functions -c fish_user_key_bindings _keybinder_fish_user_key_bindings
30	30	---> test -z "$XDG_CONFIG_HOME"
42	42	---> and set XDG_CONFIG_HOME ~/.config
11	11	---> function fish_user_key_bindings...
5	22	-> if status --is-interactive...
17	17	--> status --is-interactive
9	9	-> function __gh_migrate...
8	8	-> function __gh_push_force...
41	41	> exit
@faho

This comment has been minimized.

Copy link
Member

faho commented Sep 18, 2018

Now, perhaps I still don't understand what "doing away with the need for fish_user_key_bindings entirely" means.

Correct.

Do you mean removing this feature?

What I mean, in short, is this: Making bind statements in config.fish work.

Wouldn't that run into the same problem of using bind in config.fish (you can't). thinking

Ever wondered why that is?

It's because we only set up your bindings after config.fish has run (via a function triggered --on-event fish_prompt), because your config.fish might contain changes to $fish_key_bindings. So we run the binding function which, as we've established, erases all bindings to get back to a clean slate [0], and that kills any bindings you've set up previously. Then we run fish_user_key_bindings.

What I want is to erase all bindings that have been set up as part of a binding set (which won't include any bindings you've set up previously). Then we can still run fish_user_key_bindings for backwards-compatibility and nice grouping. It just won't be necessary anymore.

Which means:

this wouldn't be scalable as it would force every script that wants to add its own bindings to copy any existing fish_user_key_bindings.

You wouldn't have to! You'd just do bind in your script.

And also:

That would be a breaking change

It wouldn't, because we'd still run fish_user_key_bindings. Only if you had bind statements in config.fish, they'd suddenly start to work!


[0]: Of course we could also stop erasing all bindings the first time the bindings are set up. That would make bind calls in config.fish work, unless you switched bindings later. Which is a bit dirty.

@jorgebucaran

This comment has been minimized.

Copy link

jorgebucaran commented Sep 18, 2018

@faho Making bind statements in config.fish work.

Yes, please, this would be amazing. Plugins that export key bindings would become easier to make, install and uninstall without much meddling from the plugin manager too.

@faho faho referenced this issue Sep 19, 2018

Closed

Add notion of "default" bindings #5195

3 of 3 tasks complete

@faho faho closed this in 444f9f8 Sep 30, 2018

@faho faho modified the milestones: fish-future, fish-3.0 Sep 30, 2018

ridiculousfish added a commit to ridiculousfish/fish-shell that referenced this issue Nov 24, 2018

Add separation of "preset" bindings
This allows for marking certain bindings as part of a preset, which allows us to

- only erase those when switching presets
- go back to the preset binding when erasing a user binding
- only show user customization if requested
- make bare bind statements in config.fish work (!!!11elf!!!)

Fixes fish-shell#5191.
Fixes fish-shell#3699.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment