Skip to content
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

Allow for alternate key bindings #546

Closed
3 of 14 tasks
kopischke opened this issue Apr 21, 2016 · 12 comments
Closed
3 of 14 tasks

Allow for alternate key bindings #546

kopischke opened this issue Apr 21, 2016 · 12 comments

Comments

@kopischke
Copy link

kopischke commented Apr 21, 2016

  • Category
    • fzf binary
    • fzf-tmux script
    • Key bindings
    • Completion
    • Vim
    • Neovim
    • Etc.
  • OS
    • Linux
    • Mac OS X
    • Windows
    • Etc.
  • Shell
    • bash
    • zsh
    • fish

Two out of three of fzf’s key bindings conflict with OS X features:

  • Ctrl-T clobbers the “transpose” function of the Cocoa text system ordinarily bound to that key; too useful a feature to simply lose for fzf usage.
  • Alt-C does not work at all, as Alt+letter combinations insert special characters (“ç” on a German keyboard); disabling that is not even an option for anybody writing in a language other than English on OS X.

Providing either a way to configure these bindings (not just opt out on install – the hotkeys are useful after all), or saner defaults on OS X would be much appreciated.

@junegunn
Copy link
Owner

junegunn commented Apr 22, 2016

Technically CTRL-T is not an OS X feature, but a default key binding of bash that is mapped to "transpose-chars" (see bind -p to confirm). I was well aware of the feature but as I hardly used it – and I figure not many others use it judging from the fact you're the first one to mention it – I decided to override the key. But I guess that it makes sense to provide an option or suggest a way to configure the key without too much hassle.

Excerpt from https://www.iterm2.com/faq.html:

Q: How do I make the option/alt key act like Meta or send escape codes?

A: Go to Preferences->Profiles tab. Select your profile on the left, and then open the Keyboard tab. At the bottom is a set of buttons that lets you select the behavior of the Option key. For most users, Esc+ will be the best choice.

I use Esc+ setting as suggested above so it works for me, but since you said it's not an option, ESC-C should do the trick. If you weren't aware of this, I can say you are missing out. ALT-B (backward-word), ALT-F (forward-word), ALT-Backspace (backward-kill-word), ALT-D (kill-word), and ALT-. (insert-last-argument) are just indispensable. Likewise, they are available to you via ESC-B, ESC-F, etc. Note that iTerm allows you to choose the option for left option key and right option key separately, so it's something you can consider.

@kopischke
Copy link
Author

kopischke commented Apr 22, 2016

Well, if we want to get all technical, these are Emacs-style readline bindings, but the Cocoa text system makes a slightly modified subset of them available in all Cocoa text fields (no Meta combinations, but Ctrl-W is backward-kill-word, for instance), which is where I first encountered Ctrl-T. For me, that one has become essential, and having to decide between it and fzf’s hotkey functionality is a rather unpleasant dilemma. Thanks in advance for looking into a solution for that.

As to the meta key configuration, I’m not using iTerm (and don’t intend to – there are only so many configuration time sinks I am willing to invest into ;)), but I think Terminal.app allows for usage of Escape as Meta too. Thanks for the hint!

@junegunn
Copy link
Owner

junegunn commented Apr 22, 2016

You use bash so you currently can do this:

[ -f ~/.fzf.bash ] && source ~/.fzf.bash

# Remap CTRL-T to CTRL-X CTRL-T
bind "$(bind -s | grep __fzf_select | sed 's/\\C-t/\\C-x\\C-t/')"
bind '"\C-t": transpose-chars'

@kopischke
Copy link
Author

Yeah, I can hack my way around this (in fact, the first thing I did before posting this issue was looking into key-bindings.bash), but this is both brittle (it depends on internal implementation details) and non-portable (I’ll have to redo it should I switch shells, say to zsh), hence me posting this issue.

I’m wondering if a possible way to address this might be introducing an intermediary binding (e.g. C-xC-t) which could be unconditionally rebound by the user with a more straightforward bind command than what we have now. The current default bindings could still be installed, but opting out and re-configuring would be a much mot painless process. I could submit a PR if you are willing to entertain this?

@junegunn
Copy link
Owner

junegunn commented Apr 22, 2016

Interesting idea but the suggested approach does not completely solve the problem of portability you mentioned. bash, zsh, and fish all use different syntaxes for binding keys. Changing the binding is much more pleasant on zsh:

bindkey '^X^T' fzf-file-widget
bindkey '^T' transpose-chars

on bash 4 (I'm stuck with bash 3)

bind -x '"\C-x\C-t": "__fzf_select_tmux_auto__"'
bind '"\C-t": transpose-chars'

and on fish

bind \cx\ct __fzf_ctrl_t
bind \ct transpose-chars

Looking at the above snippets, it looks like what we can do is to use the consistent name fzf-file-widget (no underscore prefix, already known by zsh users so we should be using this) across all three shells. Explicit names are better than some obscure key bindings that we hope no one uses.

@kopischke
Copy link
Author

Looking at the above snippets, it looks like what we can do is to use the consistent name fzf-file-widget (no underscore prefix, already known by zsh users so we should be using this) across all three shells. Explicit names are better than some obscure key bindings that we hope no one uses.

Sounds good; I’ll take straightforward, stable configurability over portability if I have to choose.

junegunn added a commit that referenced this issue Apr 24, 2016
- fzf-file-widget
- fzf-history-widget
- fzf-cd-widget
junegunn added a commit that referenced this issue Apr 24, 2016
e.g. Remapping fzf-file-widget to CTRL-X CTRL-T intead of CTRL-T

    bind -x '"\C-x\C-t": fzf-file-widget'
    bind '"\C-t": transpose-chars'
@junegunn
Copy link
Owner

Updated the code. Now on bash 4+ you can

bind -x '"\C-x\C-t": fzf-file-widget'
bind '"\C-t": transpose-chars'

However, unfortunately, CTRL-R and ALT-C are left untouched for the following reasons

  • CTRL-R: Couldn't find a way to trigger history-expand-line
  • ALT-C: The prompt is not updated when we change the directory within the function

I'll close the issue for now as we still have workarounds. But pull requests are appreciated.

@nico
Copy link

nico commented Aug 8, 2019

FWIW, I too found it a bit annoying that fzf clobbered ctrl-t. Having to recreate the mapping after fzf clobbered it seems a bit roundabout.

Maybe there could be some env var that when set prevents fzf from overwriting ctrl-t in the first place?

@juanMarinero
Copy link

FYI, to bind (aka shortcut or remap) keystrokes in bash follow: https://stackoverflow.com/questions/4200800/in-bash-how-do-i-bind-a-function-key-to-a-command/4201274#4201274

@mskar
Copy link

mskar commented Sep 10, 2020

These bindings work great for me:

bindkey -v
bindkey -M viins '^r' fzf-history-widget # r for reverse history search
bindkey -M viins '^x^f' fzf-file-widget # f for file
bindkey -M viins '^x^j' fzf-cd-widget # j for jump
bindkey -M viins '^t' transpose-chars # t for transpose
bindkey -M viins '\ec' capitalize-word # c for capitalizae

I have the best of vim and emacs/readline in my terminal!
My .zshrc: https://github.com/mskar/setup/blob/master/macos/.zshrc#L408

@cjolowicz
Copy link

cjolowicz commented Nov 25, 2021

For those using bash with vi bindings, and who don't like it that ESC c now triggers fzf.

You can disable the binding like this in your .bashrc after setting up fzf:

bind -r '\ec'

@in-plaintext
Copy link

Does fzf currently override any stock Bash functionality, aside from transpose-chars (Fedora 39, fzf 0.44.1, release 1.fc39)?

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

No branches or pull requests

7 participants