11

Shells (at least what I know) have really bad command editing capabilities.

For example:

  • I can't point the cursor to any point of the command.
  • I can't select and backspace/delete/replace text in the command.

Currently these are so distracting, I use gedit to edit commands before pasting them to the terminal.

Is there any solution that's good for these?

  • 2
    You are conflating a terminal with a shell. – JdeBP Dec 6 '15 at 11:25
13

Bash is actually quite good at this. You just need to learn its shortcuts. For example (in the default emacs mode):

  • Ctrl + A : move to the beginning of the line.
  • Ctrl + E : move to the end of the line.
  • Ctrl + B : move one character backwards.
  • Ctrl + F : move one character forwards.
  • Alt + B : move one word backwards.
  • Alt + F : move one word forwards.
  • Ctrl + K : delete (cut) everything until the end of the line.
  • Alt + D : delete (cut) the word after the cursor.
  • Ctrl + W : delete (cut) the word before the cursor.
  • Ctrl + Y : yank (paste) what is in the buffer (what you cut with Ctrl+K or Alt + D for example)

And there are many more. Read man readline to see what else is available. You can assign different shortcuts by placing them in ~/.inputrc. For example, to make Ctrl + Left go back one word and Ctrl + Right go forward one word, add this to your ~/.inputrc:

"\e[1;5D": backward-word 
"\e[1;5C": forward-word

To find out what those strange codes mean, press Ctrl + V and then press the key you would like to use. If you try with Ctrl + Right, you will see ^[[1;5C. Replace ^[ with \e in ~/.inputrc.


You might also want to look into other shells. Popular "modern", feature-rich shells include:

  • With gnome-terminal you have to use ESC button instead of ALT to navigate one word forwards and backwards . . .. or switch to a terminal which doesn't use Alt for it's application menu . . . like xterm or sakura – Sergiy Kolodyazhnyy Dec 7 '15 at 11:19
  • @Serg not on my system, thanks. I don't know if you have set it up that way or if it is some default tweaked by Ubuntu. Esc is often used as a synonym of Alt though. – terdon Dec 7 '15 at 11:47
  • No sharing cut buffers between terminal though. – Craig Hicks Feb 5 at 4:19
7

You can edit an empty or partially typed command into the editor of your choice by setting EDITOR to the editor of your choice and by hitting CTRL+X+E or CTRL+X/CTRL+E, which open the currently being edited line in EDITOR;

For example, setting EDITOR to gedit will make CTRL+X+E and CTRL+X/CTRL+E open the current line in Gedit.

To make this a permanent solution, you can set EDITOR in ~/.bashrc.

This allows to use even a fully-fleged graphical text editor to edit the command; to run the edited command, simply save and close the document.


The same feature can be enabled in Zsh by adding the following to ~/.zshrc:

autoload -U edit-command-line
zle -N edit-command-line
bindkey '^xe' edit-command-line
bindkey '^x^e' edit-command-line
  • 2
    This can also be invoked with the fc command if the FCEDIT variable is set. Good answer ! – Sergiy Kolodyazhnyy Dec 7 '15 at 11:17
  • 1
    @Serg Thanks, however fc opens the previous command (which is even neater in a certain way). I didn't know about that, thanks! – kos Dec 7 '15 at 11:28
6

Terminals have no text editing abilities themselves. Terminals provide an area of text and connect the keyboard to something. But the something that you run inside the terminal determines what it can do.

Shells such as bash are typically the first thing that you will find to run inside of a terminal. Because shells work based on commands you are only able to edit the current command. provides excellent command editing compared to the Bourne shell or csh or ksh yet it is hardly something you would want to edit even a short story with.

Text editors are one of the commands you can invoke in the shell. The leading examples are and . vim or emacs will give you the ability to edit almost anything. Both include built-in programming environments for extending their abilities to whatever problem you face.

So the solution is to understand better what these tools are doing and meant to do and pick the right one for the job.

  • I know the difference, but can something be done to improve the command editing of bash? – UniversallyUniqueID Dec 6 '15 at 14:51
  • 1
    put it in a script? – chicks Dec 6 '15 at 17:22
0

Usually terminals allow text selection with the mouse, but the shell is not made aware of this. So unfortunately neither bash, zsh, fish nor es can support mouse-based editing. I think to do so, they would need to take greater control over the terminal.

However (and this is a bit of a stretch) if you open Vim or GVim, and then enter shell commands using:

:!...

then you can click your mouse to jump to anywhere in the line. (You will need to :set mouse=a first if that is not already enabled.) The editing keys in this mode can be seen with :help cmdline-editing

Vim also has quite a powerful command history mode, which can be reached by hitting q:. From there you can yank, delete and paste using Vim's normal-mode commands. In this mode, you can get the select-with-mouse and then delete feature you desire (by hitting d).

A significant caveat here is that Vim does not actually keep a live shell session running. Each command you execute will be run in a child process. So any changes made to environment variables or shell options by the child process will be lost.

That said, you can modify environment variables from within the Vim process, and use these from Vim's command line, and they will even be exported to child processes:

:let $FOO="bar"        " the $ and the quotes are mandatory here

:echo $FOO             " Vim's own echo command
bar

:!echo "$FOO"          " Passing the variable to a shell command
bar

:!bash                 " Opening a child shell
$ echo "$FOO"
bar

So if you are willing to pretend that Vim is actually some kind of weird shell, then you can enjoy its advanced editing features! Probably the biggest drawback is that you will have to start every command by typing either :! or q:

Oh and by the way, if you want to get the output of the shell command into your current Vim buffer, you can do that like this (but beware it will clobber your current line):

:,!ls

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.