Hacker News new | comments | show | ask | jobs | submit login

Bash, running in your terminal, understands both the Emacs and the Vi commands. By default is Emacs, so you can C-a (control-a) for beginning of line, C-p to go back in command line history, or C-r to search it.

I prefer the Vi mode, though. Add to your .bashrc

set -o vi

Then you can press escape to go from input mode to normal mode; there k will take you to the previous line in command line history, j to the next line, ^ and $ to the beginning and end of the line, /something will search something back.

Editing is really fast; move by words with w (forward) and b (backward), do cw to replace a word, r to replace a letter, i to go back to input. It will remember the last editing command, just as Vi, and repeat it when you press . in normal mode.




I use these settings in my .inputrc. The get me a few more commands and even the ability to escape using jj.

    set completion-ignore-case On
    set bell-style none
    set editing-mode vi

    $if mode=vi
      set keymap vi-command
      "gg": beginning-of-history
      "G": end-of-history
      set keymap vi-insert
      "jj": vi-movement-mode
      "\C-p": history-search-backward


>set completion-ignore-case On

Thanks. Keeping track of whether certain directories were capitalized or not has been unnecessarily occupying my mental bandwidth for years.


Is there a functional difference between putting...

    set editing-mode vi
... in one's inputrc and...

    set -o vi
... in one's .bashrc?

I realize that .inputrc is the config file for Readline, and .bashrc is essentially a start-up file for Bash. But is it ever necessary to use both snippets?


I would imagine that .inputrc would serve as a superset in that all programs (for instance gdb) whiich use readline would now default to vi mode.


This is the most useful thing I've heard this (short) year. I've always been looking for a way to make readline globally default to vi mode. Thanks for that.


Indeed. It also works in things like irb, for example.


Thanks for this. I switched my input mode to VI and was greatly missing using Ctrl-L to clear the screen when in input mode. I hadn't known about the inputrc before. Adding this line below your "\C-p" line fixed that for me:

    "\C-l": clear-screen


Signs you have to revert to Emacs mode. Unless it's an assemblage, it's always a smell if you replace a unit of a body with that of a "competitor."


Oh wow, I didn't even think about that. I've been making do with Cmd+K on OSX and aliasing c to clear to get around the problem.


Command-K also does the trick


Command-K won't play nicely with tmux panes though.


I've been wanting to use 'jj' to enter normal mode on the command line for some time. This solution actually didn't work for me, but adding the following to my .zshrc did:

  bindkey -M viins 'jj' vi-cmd-mode


That is because zsh does not make use of readline. I ran into this issue myself recently, since I use bash on my personal machines and zsh on my work ones.


Super off-topic, but I bet you'd be far happier if you used only one.


Very cool, does anyone know a way to set a visual indicator (diff cursor?) when in edit mode?


> set completion-ignore-case

works well with "\t": menu-complete

But I had to delete this entry. I need the case to differentiate between which path I really wanted :(


C-a : beginning line, C-e end line, alt+f forward word (unless system shortcut for file menu), alt+b back word, C-k kill line, C-b back char, C-f forward char.

At least in my current setup, C-w yank and C-y paste works as well.

Immensely helpful. Sometimes at+left/right does forward/ back word depending on the terminal emu.

Note most of these keystrokes are valid in nano as well.


More:

- C-u to kill (cut) from current location to beginning of the line

- C-k to kill (cut) from current location to end of line

- C-w to kill (cut) from current location to beginning of word

- C-y to paste (copied / cut) lines

- C-l to clear screen (I use the shit out of this)

- Ctrl + shift + '-' (holding ctrl, shift, minus at the same time), for undo.

That is it.

EDIT: Damn it, I didn't realize I was saying a bunch of the same things as you did.

EDIT2 Thanks oinksoft for clearing up C-u and C-w.


Also, most emacs keybindings (C-u and C-w don't, but C-k, e, a and y do, at the very least) work in all Cocoa text fields. This (in general) means you have two copy buffers: the normal, system wide Cmd-C (or X), Cmd-V and the "Cocoa wide" C-k C-y buffer


The basic emacs shortcuts even work on iOS, if you're using a Bluetooth keyboard. Now the muscle memory works everywhere.


Right! Weirdly enough, C-k kills a word in (at least) the Editorial writing app in iOS7 (only writing app where I have tried since upgrading my iPad)


My favorite undocumented keybinding: C-t (transpose) for sloppy typers like me.


Didn't know C-t worked in Cocoa's. Thanks for pointing it out, always useful!


Just wanted to note:

C-u kills from cursor to start of line.

C-w kills from cursor to start of previous word. M-d is its friendly forward sibling.


Note: Ctrl-U and Ctrl-W are not from Emacs. They are instead from the same group as Ctrl-C for interrupt, Ctrl-D for End-of-File, etc; i.e. traditional Unix TTY driver keys. Run “stty -a” to see them all; the stty command can also be used to change them.


Thanks! fixed.

I never noticed C-u was from cursor. I tend to use it mostly from the end of the line.


And that's why C-e C-u is burned into my hands :^)


Is it any different from C-a C-k ? Both seem to stuff things into the kill ring (or whatever it's called in bash).

I guess lots of people leave C-a as the default escape key for screen.


Yea, there's the GNU Screen mapping conflict, and also I rarely use C-k so it's not in my muscle memory.


Makes sense; I use emacs in addition to just the emacs-like readline bindings, so C-u conflicts with "prefix argument". I also nest screen sessions using ^Z as the outer one's escape key and ^O as the inner one's, partly so I can use C-a / ^A.


Pressing ESC and then _ will insert the last argument of the last line. Repeat to go up in the history.

If you go through the command history and press CTRL-o on a line it will be executed and the command on the commandline will be replaced by the next line in the history.


Also M-. (meta-period). Keep banging on M-. to pull in the last argument of preceding commands.

With a numeric prefix argument N, it grabs the Nth-from-the-end argument of the previous command, so M-3 M-. grabs the 3rd-from-last argument from the previous command.


In Bash, you also can use the $_ variable which is the last argument of the previous command:

  $ stat /tmp/foobar
    File: `/tmp/foobar'
    Size: 0         	Blocks: 0          IO Block: 4096
    ...
  
  $ rm -v $_
  removed `/tmp/foobar'


You can also use `!$`.


!$ runs the last command. it's bad if the last command is of the form command arg... because it'd run command without every other argument passed in the command line


also alt + backspace, works similar to ctrl + w, but word is defined as only alphanumerics. Very useful when deleting parts of the long file paths because it will stop on / character (unlike C-w that deletes the whole path)


It's worth noting that that the C-w/C-k/C-y yank ring is a distinct buffer from the system Cmd+X/C/V pasteboard.

That way, you can have two different things on your clipboard without having to use a fancy clipboard manager. (Or, alternatively, you can be confused why the thing you're pasting isn't the thing you thought you copied last.)


http://tiswww.case.edu/php/chet/readline/readline.html

These work in most GUI inputs as well.


Mac OS X uses libedit (http://thrysoee.dk/editline/, http://www.opensource.apple.com/source/libedit/libedit-39/), not GNU readline.

But yes, the keybindings work in Cocoa text controls, too, for example in TextEdit, in the Safari URL/search control, etc.


you can also go into visual mode (at least in vi mode).. pressing esc then v will launch your default editor with the current command in the buffer; saving an exiting runs the command; very useful for long commands and/or iterating


bash/emacs has C-x C-e to open up the command in a editor.


Agreed, this was the reason for me to learn my first emacs shortcuts. Also, the option+click thing doesn't work in iTerm, so unfortunately it doesn't help me but -side note- it's amazing that after years of using OS X I can still discover small productivity features like this, and I think it stands for the thoughtfulness of the people behind it.


you sure? it works for me in iterm2


To get

  [NORMAL]
on the right side of the terminal like in Vim, I put this in my .zshrc file:

  function zle-line-init zle-keymap-select {
      VIM_PROMPT="%{$fg_bold[yellow]%} [% %{$reset_color%}NORMAL%{$fg_bold[yellow]%}]%  %{$reset_color%}"
      RPS1="${${KEYMAP/vicmd/$VIM_PROMPT}/(main|viins)/} $EPS1"
      zle reset-prompt
  }


Is there a bash version of that? I don't care about where it is too much.


I started using vi mode recently. The only thing that I really miss are ci and di commands.


ci and di aren't commands. c and d are operators and the i is part of the motion--specifically, text objects.


> Then you can press escape [..]

Don't forget Ctrl-[ instead of Esc. I find that more quick, especially with Ctrl in place of CapsLk. :)


I you tried Evil-mode, i actually using Emacs with this, now i got the power of emacs with the efficiency of Vi in one place.


Depends on how much of Vi/Vim you use. IIRC, Evil-mode doesn't implement everything.


Pretty much 90%, but that is enough at least for me.


I just realized you can use some of these Emacs commands in the Chrome browser address bar (not sure about others).


Most text inputs in Mac OS support at least C-a and C-e too.


great tip. on my system i added it to .bash_profile.


zsh also has these modes.




Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact

Search: