How to skip words in OS X terminal?

11

10

Let's say I wrote a long command in the Mac OSX terminal, i.e

say "Hello, how are you? I am good thank you. How is it going with you? Fine, thanks"

and now I want to change the word Hello to Hi.

To do that, right now I have to keep pressing (or hold down) the left keyboard key until the "cursor" gets to the end of the word Hello, and then delete it. The usual 'holding down option' technique doesn't work as it does in most other OS X applications.

Is there a way to skip a word at a time instead (or any other shorter way of getting the cursor there)?

Yuval

Posted 2010-04-17T03:51:50.090

Reputation: 2 088

Answers

19

Command line editing is a function of your shell, not of Terminal. Probably your shell is bash and probably its command line editing style is set to “emacs”.

Here are a few of the Emacs-style key combinations that you might find handy:

  • C-a: beginning-of-line
  • C-e: end-of-line
  • M-f: forward-word
  • M-b: backward-word
  • C-d: delete-char
  • M-d: kill-word (delete the next ‘word’)
  • M-DEL: backward-kill-word

C-x means Control+x, so C-a is Control+a.

M-x means Meta+x, but there probably is no Meta key on your keyboard. So instead, you can use ESC x (i.e. Escape then x). Terminal has an setting to automatically send ESC before keys pressed with Option held down. Using this feature disables the extended character handling that Mac OS X usually provides when using the Option modifier. So, if you use few extended characters and want to have Option+x send ESC x, then you can enable this Terminal option.

There are lots of ways of moving to “Hello” in your example:

  • Search for “Hello”: C-r H e l l o C-j (or ESC)
    • In normal Emacs, you would just use RET (Return) to end the search at the current location and return to editing. But in bash, the default bindings cause RET (i.e. C-m) to always execute the current line, even if an incremental search is active. So the C-j/ESC part is a deviation from normal Emacs.
  • Jump to the beginning of the line and move forward: C-a M-f C-f (or )
  • Jump to the beginning of the line, then move by words: C-a M-f M-f M-b
  • Use M-b a lot (only really feasible if you map Option to Meta).

There are also several ways of accomplishing your desired replacement:

  • delete the word and replace it: M-d H i
  • delete characters and replace them: C-d C-d C-d C-d C-d H i
  • move past “H” and delete the following work, replace it: C-f M-d i
  • move past “H” and delete the remaining characters, replace them: C-f C-d C-d C-d C-d i

If you stopped at the end of the word (maybe via C-a M-f M-f), you could use M-DEL H i.

You might do something like bind -P | less to find other interesting bindings. Consult the readline section of the bash man page (or the readline parts of the bash info pages) for details.

Chris Johnsen

Posted 2010-04-17T03:51:50.090

Reputation: 31 786

Ok, this doesn't really pertain to the question, but how do you put the words that look like keyboard keys in there? – Wuffers – 2010-04-17T22:46:55.083

1

@Mr. Man: Use <kbd> elements. A subset of HTML is allowed in the markup here. The appearance is due to site-local styling of the tag (background, border-color, border-style, border-width, etc.). You can review the source markup of my post (“view source” on this page). See http://meta.stackexchange.com/questions/5527 even though the fancy style is disabled on MSO: http://meta.stackexchange.com/questions/1939/#23571

– Chris Johnsen – 2010-04-18T04:42:09.003

1

You can also use vi bindings by adding set -o vi in your .bashrc! https://www.gnu.org/software/bash/manual/html_node/Command-Line-Editing.html

– Will Munn – 2017-05-10T19:55:32.093

Is there a way to change the environment or shell so that I can do ctrl or fn + arrow keys to match my IDE? – codecowboy – 2011-05-06T12:44:26.790

@codecowboy: It is technically possible (depending on which exact behavior you want), but it would not be trivial. You can configure Terminal to send additional codes for Control-modified keys (but not fn; it usually just replaces one key with another instead of adding a modifier “bit”). Then you would have to extend a terminfo entry and set the TERM environment variable to the new entry to let programs (e.g. your shell) know about the extra codes. Finally, you might need to redefine the bindings in individual programs (e.g. your shell) to trigger some behavior based on your new keys. – Chris Johnsen – 2011-05-06T17:29:33.277

I'm not sure if this is obvious or not, it took me a minute to figure it out, but I'm on a MBP without a meta key and I'm using a default Terminal configuration. To move forward and backward on words I can press Esc and then F, or Esc and then B. Just wanted to mention that because the way it was explained above was making me try and press Esc + x and then f or b... – cwd – 2011-01-23T22:06:26.653

@cwd That's why the x is in italics, to indicate it's a placeholder for any key. Thats explained in the following sentence: C- x means Control+ x, so C-a is Control+a. It goes on to explain that you can get C-*x* by pressing "ESC x (i.e. Escape then x)." – Daniel Beck – 2011-06-12T09:37:29.260

2

The default readline binding for forward-word is Meta-F (bash(1) man page, READLINE section, Commands for Moving subsection). I'm not sure what Meta translates to in OS X though. Option, perhaps.

Ignacio Vazquez-Abrams

Posted 2010-04-17T03:51:50.090

Reputation: 100 516

+1 - you're actually right. this works in bash on OSX – Yuval – 2010-06-02T06:50:55.853