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.) 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 :) 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 + - 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 :? 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>). 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" ... 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. Commented Apr 19, 2015 at 15:32

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.