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

migrated from serverfault.com Apr 18 '15 at 3:03

This question came from our site for system and network administrators.

  • 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 3:20
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+..

  • 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 <esc>+<dot> in my case, too (it's the same escape sequence as <alt>+<dot>). – 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<ESC>." 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
5

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
  • 1
    Thanks. ESC and then _ in an Spanish keyboard requires pressing Shift (Shift + - = _) but it's a good alternative :) – sromero May 11 '15 at 6:27
  • You're welcome. It's the same with the US keyboard layout. – PSkocik May 11 '15 at 6:57
  • Nice find. Looks like you can also use Shift + Alt + - – vimist Apr 27 '18 at 14:31

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.