iconoclast
iconoclast

Reputation: 22610

Can zsh or bash expand history expressions referring to directories?

For example, let's suppose I just copied something:

mv foo_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype

and I'd like to use history substitution like so:

mv bar_file.txt !!:2

I'm surprised that zsh is not expanding the !!:2 for me when I hit [tab]. In a more complex reference to a historical argument I might really want the expansion before I hit return, just so I know with certainty that I referred to the correct argument. Is there any way to make it do that? (I would expect that to be the default behavior. Is it the default behavior, that I have somehow inadvertently disabled or broken?)

If zsh can't do it, can bash?

UPDATE: zsh will expand the history expression if it refers to a file, but not a directory:

mv foo_file.txt foo_bar_file.txt
mv bar_file.txt !!:2[TAB]

It will expand it if it is just an arbitrary string:

echo one two three four
echo !!:1[TAB]

But not if you're trying to move something to a directory. It looks more and more like this must be a bug.

Upvotes: 2

Views: 546

Answers (5)

Adam Spiers
Adam Spiers

Reputation: 17916

Works perfectly for me with zsh 4.3.17. Sounds like you probably have a bug which might be worth reporting on the zsh-user mailing list. However there are at least five other keybindings which should accomplish what you want: C-x * which is by default bound to expand-word, and Esc Space or Meta-Space or Esc ! or Meta-! which are all bound to expand-history by default. (Meta means the Alt key for many people, although it depends on your terminal setup.)

Having said that, Esc . (or Meta-. or Alt-.) is a nicer way of retrieving the last word from the previous line in the history, since it provides instant visual feedback. You can also choose the last word from older lines by repeatedly pressing the keyboard shortcut, or even the n th last word on a previous line by prefixing the shortcut with Alt-n (or Meta-n or Esc n). So for example to retrieve the penultimate word from the 3rd newest line of history, the sequence would be:

  • Meta-. (goes back one line of history, selecting the last word from that line)
  • Meta-. (goes back another, again selecting the last word)
  • Meta-2 Meta-. (goes back another, but this time selects the penultimate word from that line)

Upvotes: 1

Nicholas Sushkin
Nicholas Sushkin

Reputation: 13780

In bash, Alt-. is typically bound to yank-last-arg, which will give you what you want.

Here is a link to the whole list of history related commands that can be bound to keystrokes http://www.gnu.org/software/bash/manual/bashref.html#Commands-For-History

For example,

ls /etc/passwd /etc/group
cat 
# press Alt+. (Alt dot) here, bash adds /etc/group
cat /etc/group
# press space, then press Alt+1 Alt+.
# bash adds the first argument of the previous command /etc/passwd
cat /etc/group /etc/passwd

Upvotes: 0

Dario Buttari
Dario Buttari

Reputation: 119

I am using zsh in cygwin:

$ zsh --version
zsh 4.3.12 (i686-pc-cygwin)

$ setopt
interactive
monitor
shinstdin
zle

I just tried the following:

$ touch foo_file.txt bar_file.txt
$ mkdir -p ~/to/some/long/path/that/i/do/not/want/to/retype
$ mv foo_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype

I then tried the tab completion mentioned above:

$ mv bar_file.txt !!:2[TAB]

and it worked fine, the last argument being expanded as follows:

$ mv bar_file.txt ~/to/some/long/path/that/i/do/not/want/to/retype

Upvotes: 2

Foo Bah
Foo Bah

Reputation: 26271

You can pseudo-hack it in bash:

$ shopt -s histreedit
$ shopt -s histverify

Then, to actually try an expansion:

$ echo !!:2 [now hit enter]
$ echo histverify

Now you can't do tab expansion in bash. Unequivocally no. That's because of the order in which bash expansion is processed.

Upvotes: 1

Delan Azabani
Delan Azabani

Reputation: 81384

I've tried what you've described, and I don't think bash supports this either.

Upvotes: 0

Related Questions