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
sromero
  • 757
  • 5
  • 11
  • 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 Apr 18 '15 at 03:20

2 Answers2

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
Petr Skocik
  • 28,176
  • 14
  • 81
  • 141
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+..

Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
chaos
  • 47,463
  • 11
  • 118
  • 144
  • 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 Apr 17 '15 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 + in my case, too (it's the same escape sequence as +). – chaos Apr 17 '15 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." writes "ls -lls -l" ... – sromero Apr 17 '15 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 Apr 19 '15 at 15:32