9

How can I configure Bash, Zsh or Tmux to complete the last matching identifier on the screen? Consider this common scenario:

$ git fetch
remote: Counting objects: 16, done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 9 (delta 4), reused 0 (delta 0)
Unpacking objects: 100% (9/9), done.
From /opt/git/thunder
 * [new branch]      issue540   -> origin/issue547314
   e9204cf..4d42c3f  v2.1       -> origin/v2.1

How can I get Bash / Zsh/ Tmux to complete issue547 on the CLI easily? When I press Tab after $ git checkout is Git helpfully completes to issue, but I must complete the digits by myself because all the previous digits do in fact match existent Git branches.

In VIM, pressing Ctrl+P for omnicomplete will complete as the previous match, so in this case issue547314 will in fact be completed. How can I get this behaviour in Bash, in Zsh or in Tmux?

I'm currently using Bash 4.2 and Tmux 1.10 on Ubuntu Server (usually 12.04 LTS). I can update to the latest Ubuntu Server LTS (14.04) if needed.

EDIT: I would not mind any solution that uses Bash, Zsh, or Tmux as long as it is not difficult to use. So Tab or Ctrl+P or some other such shortcut would be fine, but not Alt+Meta+Super+Shift+א.

  • Pretty sure this would take a fairly large revision of the bash source. – Kevin Jun 24 '14 at 19:15
  • @Kevin: I figured as much, but hopefully either the amazing zsh can handle it, or perhaps tmux. – dotancohen Jun 24 '14 at 20:25
3
+50

I think that feature that OP is looking for is called dabbrev-expand in Emacs world:

Expand the word in the buffer before point as a dynamic abbrev, by searching in the buffer for words starting with that abbreviation (v-expand).

xterm also has dabbrev-expand feature but it's a bit less smart than Emacs counterpart but it's very useful to me and one was one of the reasons for which I switched to xterm. Inside xterm window one can use a custom keybinding specified in ~/.Xresources to invoke dabbrev-expand on a given string. For example, I have the following entry in my ~/.Xresources (I use uxterm, an Unicode version of xterm):

UXTerm*VT100.Translations: #override \n\
     Meta <Key>/:dabbrev-expand() \n\

Inside xterm window I can use M-/ (ALT + /) to invoke dabbrev-expand. xterm will look for all strings visible on the screen that start with letters I typed. Example:

$ echo a_very_long_string bye by
$ a_v

If I pressed M-/ now xterm would expand a_v to a_very_long_string. Unfortunately, as I said xterm is not so smart and its dabbrev-expand feature will only work on full strings. So, in your case is would be expanded to issue540 and not issue547314 because issue547314 is a part of origin/issue547314 (think about it as \b in regular expressions, it's a bit similar although most regular expressions engines would catch both occurrences of issue strings in \bissue.+\b). But, you can type or and then pres M-/. xterm will first expand or to origin/v2.1, this is not what we want so press M-/ again and xterm will expand it to origin/issue547314. Now, if you use Bash you can do M-b, C-w and C-e to remove origin/ part. To sum up, dabbrev-expand inside xterm is not as good as in Emacs (and Vim I guess) but it's still faster than rewriting long strings by hand and less typo-prone. And in most cases it will expand directly to the desired string without need to remove redundant parts. You just need to get used to it - look at string you want to have at cursor and see if it's not preceded by something else, and if it is type a preceding part and remove it after expansion.

Note that xterm is not compiled with dabbrev-expand feature by default and you have to enable it explicitly. However, version of xterm in Ubuntu repositories is compiled with dabbrev-expand and you can use it right away.

  • Thank you Arkadiusz, this seems to be close enough to what I need. Note that I cannot get it to work! Perhaps my xterm and uxterm are not compiled for dabbrev-expand, I could find no mention of the feature in -help. How can I see the compile flags (like with vim --version)? Note that I also tried the config line in ~/.Xresources as Meta <KeyPress> /: dabbrev-expand() \n\ as found here but that did not help, either. – dotancohen Jul 1 '14 at 5:59
  • It may be your xterm has been compiled without dabbrev-expand. How did you install xterm? After modifying ~/.Xresources do xrdb -merge .Xresources in xterm. – Arkadiusz Drabczyk Jul 1 '14 at 10:52
  • That most certainly did it, Arkadiusz! Thank you! – dotancohen Jul 1 '14 at 11:24
  • I'm going to give the question a few more hours until the bounty period ends, but I'm pretty sure that you are a shoe-in. The only problem is the requirement for xterm, which is terrible! But now that I know the proper name for the feature I can google it for other applications. Thanks! – dotancohen Jul 1 '14 at 11:36
  • Thank you Arkadiusz! Though I won't be using the xterm solution, you have certainly pointed me in the right direction. Apparantly zsh does have this facility. – dotancohen Jul 1 '14 at 18:31
1

Bash as a similar facility called bash completetion. You can make use of it by hitting the Tab key when providing arguments to commands when you're typing them.

Example

If I start by typing ls and then hitting Tab twice you'll get Bash to provide a list of matching files (and command line switches) to whatever command you're attempting to use:

$ ls <---- hit Tab x 2
Display all 232 possibilities? (y or n)

And here's the example with switches:

$ ls -- <---- hit Tab x 2
--all                 --format=                                  --quote-name
--almost-all          --group-directories-first
....
....

Setup?

My installation already included a rule for git:

/etc/bash_completion.d/git

The installation of this file was done when I installed the git package. I'm on Fedora 19, but other distros should be doing this as well.

$ rpm -qf /etc/bash_completion.d/git
git-1.8.3.1-1.fc19.x86_64

Looking at the rules file it explains that it will facilitate auto-completion in the following situations:

# The contained completion routines provide support for completing:
#
#    *) local and remote branch names
#    *) local and remote tag names
#    *) .git/remotes file names
#    *) git 'subcommands'
#    *) tree paths within 'ref:path/to/file' expressions
#    *) file paths within current working directory and index
#    *) common --long-options
#

So this should "just work" for you.

  • 2
    Bash completion and Git completion work (as I mention in the OP). The change that I would like to perform is to have it complete on the first Tab press the last legal value shown on the screen. This is how VIM Omnicompletion works. – dotancohen Mar 14 '14 at 14:04
  • @dotancohen - I don't see now that would be possible beyond what I've described. – slm Mar 14 '14 at 14:06
1

You can do something like this with extrakto:

  • press tmux prefix + tab to start extrakto
  • fuzzy find the text/path/url
  • press
    • tab to insert it to the current pane,
    • enter to copy it to the clipboard,
    • ctrl-o to open the path/url or
    • ctrl-e to edit with $EDITOR

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.