6

When using bash's vi mode (set -o vi), is it possible to recover the last argument of the last executed command? This is done in emacs mode with ESC+., and I would like to do it in vi mode as well.

I know that bash provides !$ and $_, but they are not expanded and I find quite dangerous to use them directly.

I've tried (with no success) some solutions I found on Stack Overflow about editing the .inputrc and adding:

set editing-mode vi
set keymap vi-insert
"\e.": yank-last-arg
"\e_": yank-last-arg

I'm switching to vi mode in bash but I'm quite used to ESC+. and it would be nice to be able to use it, or to find a quick & easy replacement.

EDIT: This question has been marked as a duplicate of a similar one that asks about how to recover last argument with Alt+S. I was asking specifically about ESC+. (it's the shortcut I'm used to and it is not covered by the other answer).

EDIT: To complement @chaos' solution: the following binding makes ESC+. (well, really '.') paste the last argument, but you lose Vi's dot (.) functionality:

bind -m vi-command ".":insert-last-argument
1
  • There's regularly features that are not supported by bash, but by ksh. This one too; $_ is expanded in ksh. It might be worth a thought to switch to ksh; one gains not only many useful features but also a lot performance. And specifically bash's (vi-mode) history functions are not solved in an acceptable way, specifically if compared to ksh. Recent ksh versions have even a bash compatibility mode - not that I'd suggest to use it, though. (Just a suggestion. I'm aware that Linux users often just use what GNU provides.)
    – Janis
    Commented Apr 18, 2015 at 3:20

2 Answers 2

6

I've been using _ (in normal mode) to do that. I've found it documented here http://www.catonmat.net/download/bash-vi-editing-mode-cheat-sheet.txt .

It's easy to remember too:

  • $_ expands to the last argument
  • <Esc> + _ types it out
3
  • 1
    Thanks. ESC and then _ in an Spanish keyboard requires pressing Shift (Shift + - = _) but it's a good alternative :)
    – sromero
    Commented May 11, 2015 at 6:27
  • You're welcome. It's the same with the US keyboard layout. Commented May 11, 2015 at 6:57
  • Nice find. Looks like you can also use Shift + Alt + -
    – OdinX
    Commented Apr 27, 2018 at 14:31
5

For me it works when I add the following to my .inputrc:

$if mode=vi
"\e.":yank-last-arg
$endif

Then, when changing it in bash on the fly, the .inputrc must be read again:

set -o vi
bind -f .inputrc

Now, I can get the last argument with alt+..

4
  • It works,but it inserts a space character before the argument. Is there any way to enable ESC + dot too? (It works now with ALT+S). In the other hand, I don't understand why .inputrc is not being read on each login :?
    – sromero
    Commented Apr 17, 2015 at 14:36
  • 1. .inputrc IS read at each login, but mode is not set to vi, and however when switching to that mode (set -o vi) the binding are overwritten. 2. It work with <esc>+<dot> in my case, too (it's the same escape sequence as <alt>+<dot>).
    – chaos
    Commented Apr 17, 2015 at 14:47
  • In my case, ESC + dot repeats the last command that modified the buffer (as '.' does in vim), because ESC returns to command mode and dot repeats what I wrote. So "ls -l<ESC>." writes "ls -lls -l" ...
    – sromero
    Commented Apr 17, 2015 at 15:10
  • I've marked your answer as "the solution" as I don't see a way that ESC + . can work because they are not pressed at the same time and they both have a meaning under Vi (return to command mode and repeat last action that modified the buffer), so I'm starting to think that ESC+. cannot work like in Emacs mode without losing Vi's . (dot) functionality. Thanks.
    – sromero
    Commented Apr 19, 2015 at 15:32

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .