Hacker News new | past | comments | ask | show | jobs | submit login
Bash One-Liners Explained, Part V: Navigating around (catonmat.net)
128 points by Anon84 on Nov 27, 2012 | hide | past | favorite | 32 comments

This is a great guide. Especially awesome for me was: 26. Change input mode to vi

$ set -o vi This command changes the key bindings to vi's. If vi's your favorite editor, you'll love this. I'll cover the vi mode in more details in the next part of the article.

I'd love to find a cheat sheet for vi bash usage (and also an indicator for which editing mode I'm in).

I'm a huge vi(m) fan, but still use Emacs-style readline. When editing code in vim, I tend to make several edits each time I'm in edit mode. When at the terminal, all I'll need is "go to front" or "search backwards". And which is easier: Esc+Shift-6+i or C-a? Esc+Shift-/ or C-r? I'm in no way an Emacs ninja, but it's not too hard to memorize the ten or so most common commands. Added bonus: they work in OS X and Qt textfields. Other added bonus: they work out of the box in terminals you haven't configured yourself.

I like vi-mode in my shell primarily for j/k to navigate through history (arrow keys just always suck imho, and C-r to search backwards in history is just overkill most of the time) and 'c[motion]', which is what I almost exclusively find myself using to correct things I messed up ('d[motion]' pops up less frequently). 99% of the time those are 99% of the things I use; for that set of features I think the vi sequences are definitely have the advantage.

The Emacs next-line and previous-line bindings C-n and C-p also work well for history navigation.

You can enjoy the best of both worlds with something like zsh's edit-command-line. I'm very happy with Emacs keys in the shell, unless I need to make a non-trivial edit or type in a multi-line command. In those cases, C-x C-e drops me right into Vim with the current command-line ready for editing.

Anybody know how to do the equivalent of C-x C-e in vim mode?

Try ESC-v.

uhh... try Esc-I and Esc-A. And Ctrl-R still works in vi mode.

You'll probably like this (includes cheat sheet): http://www.catonmat.net/blog/bash-vi-editing-mode-cheat-shee...

Many thanks for pointing this out! I hadn't read far enough to get to it myself. I kind of wish it was closer to the top because it rendered most of the other tips kind of pointless. Well, not C-r, but I already knew that one.

This has made me even happier than learning I could get vim key bindings in vim's own command-line mode[1]. Thanks again!

[1](C-f from command-line mode, or q: from normal)

I was excited when I found out about this a year ago and tried it out...I hated it, though. There's no indication as to what state you're in and it can get maddening at times!

Luckily, zsh actually allows you to change your prompt when the mode changes. I have mine set up to change the color of part of it whenever I'm in command mode. Definitely worth setting up.

| I'd love to find a cheat sheet for vi bash usage (and also an indicator for which editing mode I'm in).

In zsh, you can type: "bindkey" to get a listing. IIRC, in bash it is "bind -p".

Instead of searching through history, you can add this to your .inputrc

  "\e[B": history-search-forward
  "\e[A": history-search-backward
And this to your .bash_proflie

  export HISTCONTROL=erasedups
  export HISTSIZE=100000
  shopt -s histappend
Now the up/down arrow keys auto search and complete backwards/forwards based on what's written. If the line is empty, it behaves as normal.

This is also pretty neat, in your .bash_proflie:

  bind '"\t":menu-complete'
Enables cyclic tab completion

These are the first things I do when I'm on another terminal.

Cool, thanks for the cyclic tab. That was a new one for me.

I've been using the remap of the up/down arrow for a while too, and it is crazily useful indeed. It's the first thing I do on a new terminal. That, together with adjusting PS1 and setting up my common aliases.

Absolutely love both of these, thank you so much. My only nitpick would be that when you have text typed, say '$ vim' and go up, finding '$vim somefile', then going down again should bring you back to what you originally typed. This is also the behaviour in vim, I believe.

Any other tips? These two were brilliant!

Regarding HISTFILESIZE the man page for bash says:

> When this variable is assigned a value, the history file is truncated

Which I read as meaning if you export the following then you should get infinite entries:

I'm testing to see if it works for this also:

  export HISTSIZE=

My biggest complaint is that the semantics of CTRL-w and ALT-b are different. CTRL-w goes to the last space, and ALT-b goes to the nearest non-letter. Why did they define word in two different ways for the two different commands? I would kill for a non-deleting version of CTRL-w; if I have a long path in a command-line I want to be able to move to the previous parameter, not just the previous path element.

Alt+Backspace deletes to the last non-letter.

To go to the previous space, Ctrl+R SPACE works for me.

Ctrl+R SPACE seems like it's a bit iffy for some cases, especially since I use Ctrl+R so frequently for history searches. Using it instinctively (like I use Ctrl+W) wreaks all kinds of havoc; if I do something like Ctrl+R python to get a previously run command, then hit Ctrl+R SPACE, then it moves to the previous commandline that contains python instead of staying where I am and moving back a word. Still, something to explore -- I can probably find a way to use this.

"Bash uses the readline library for input editing. The readline library supports emacs style key bindings[...]"

Been using Emacs for a year and I didn't know this. O_o

Are you using a Mac? Because if you are, those Emacs motion key bindings work in almost all text input fields in all apps.

I'm on a Mac about once or twice a week at work. Thanks for the heads-up!

If you find yourself using these keyboard shortcuts frequently, you can save yourself some pinky fatigue by remapping caps lock to ctrl.

Doing this was a big part in saving my left hand from RSI. I can't emphasize enough how awesome it is to have ctrl bound to caps lock.

Yes! It's the first thing I do when I get a new system these days.

In OSX you can set it up in keyboard preferences and in Windows I use Autohotkey.

Working on a keyboard with a regular Caps Lock key feels very strange after all this time.

But then where is my ESC key?

The author notes that there is no meta key anymore [1], however you can often setup your terminal emulator to use another key as the meta key.

In iTerm [2] I have the left alt/option key setup as meta, so things like meta-b are much easier to type then Esc-b.

[1] "You'll often see Meta+b but there is no such key on the keyboards anymore." [2] Profiles -> Keys "Left option acts as meta"

I knew most of these, but I learned about Ctrl-# (for commenting a command), and Ctrl-x+Ctrl-u (or Ctrl-/) for undoing changes.

One shortcut that used often is Ctrl-o. When you have a few commands in your history that you want to repeat in that seqeunce, search for the first command in the group, optionally edit it if you want, and press Ctrl-o instead of the ENTER key.

After this command is executed, the next command in the history is presented to you. Press Ctrl-o again to continue the sequence, or press ENTER once you reached the last command in the sequence.

If you want skip a command in the sequence, instead of Ctrl-o just press Ctrl-n (or down-arrow) to get the next one in sequence.

Some awesome ones he did not mention:

Control-q: push-line-or-edit -- this saves the current command without executing it, allows you to run another command, then puts back the saved command for you to edit/run.

Esc-A: accept-and-hold -- execute command and maintain cursor position, so you can edit command and re-run.

Esc-' : quote-line -- escapes the single quotes in a line.

Old Vim user here, who has used emacs mode since moving from ksh to bash for about 8-10 years. Recently, switched back to vi mode, however, I have mapped Ctrl-A, Ctrl-E and a few more so i can use them in vi mode too. e.g.

    bindkey "^A" beginning-of-line

This seems to be written by someone who has no deep experience. For example, Ctrl-u does only delete the whole line, if the cursor stands at the end of that line, on my system (Ubuntu) this command generally deletes the characters left from the cursor. What's missing, is the complement to this command, which deletes the characters under and right from the cursor, namely Ctrl-k. Everybody who regularly uses Ctrl-u should know that.

The manual:



oh, this is the first time I've seen this: there is a vi mode for bash http://cnswww.cns.cwru.edu/php/chet/readline/rluserman.html#...

Mostly common (to me), but there's a few good ones in there! ^x^e could be my new favorite!

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