Why can't I highlight text in a linux terminal emulator with shift+arrow keys?

20

8

These are the standard text editing keyboard shortcuts that I use constantly whenever editing text in, literally, any linux application other than terminal emulators:

  • left+right arrows to move left+right
  • ctrl+arrow to move an entire word
  • home/end to move to start/end of line
  • ctrl+c/ctrl+v to copy/paste [some terminals can use shift-ctrl-C/shift-ctrl-V; this is a good substitute]
  • shift+arrow to highlight text
  • shift+ctrl+arrow to highlight an entire word

I have never found a combination of shell plus terminal emulator that allows the last two items on this list, and it drives me nuts. Obviously terminal emulators support highlighting (the mouse can do it), and they support the use of the ctrl and shift keys as modifiers (they can be used to move the cursor an entire word, and to capitalize letters, respectively; [edit:] they can even be used together to copy/paste with shift-ctrl-C and shift-ctrl-V), so what is the issue preventing this functionality? I have several questions:

  • Is this an issue with my terminal emulator, or with my shell (bash, though I'm willing to change)?
  • Why do terminal emulators/shells not conform to this otherwise universal standard?
  • If there is an actual reason, is it ancient and obsolete, or is it still relevant to a significant number of desktop linux users?
  • Is there any kind of workaround?
  • Is there some obscure program I can use that supports this?
  • Is it feasible to modify the source of, say, gnome-terminal to support this?

I know text can be copied/pasted with the mouse, that's not what I'm asking about. I'm asking why I can't do these things with the keyboard in a terminal emulator.

monguin

Posted 2013-02-22T17:22:58.480

Reputation: 371

Note that selecting text with the mouse does not change the cursor position. If you'd mix in text selection with entering regular commands on the keyboard, it'd just be really confusing beyond the boundaries of the command you just typed and not yet executed. Are you able to select text beyond the boundaries of the text box on a web page with the keyboard? Please also note that there are programs like screen that allow entering a different mode that has text selection for the entire terminal, but of course does no longer allow entering commands. – Daniel Beck – 2013-02-22T17:25:57.473

1Daniel: the Matlab console, for example, is a CLI that allows text highlighting with the keyboard. It works perfectly in my experience; it allows selection beyond the current not-yet-executed command if desired, personally I have little use for that. – monguin – 2013-02-22T17:38:14.020

and here as well http://stackoverflow.com/q/312213/1172302

– Nikos Alexandris – 2013-07-05T08:03:00.370

Answers

5

I think it'd be most useful if I took this a piece at a time. The general problem is: who is the key press intended for? The terminal, or the program running inside the terminal?

As an example, "screen", which is kindof a terminal, uses Ctrl+A as a prefix for its commands, to distinguish them from things going to the running program itself. (And provides a way to send Ctrl+A.)

gnome-terminal has several keys that it captures to do various things, including some of the ones you ask about.

Also keep in mind that a terminal's "highlighting" is separate from the terminal's cursor position. Some terminals have no ability to highlight at all.

Now, taking this key combinations at a time:

left+right arrows to move left+right ctrl+arrow to move an entire word home/end to move to start/end of line

Move what left and right? Bash can be configured to do this, and typically is by default. Typically, these move the cursor position.

ctrl+c/ctrl+v to copy/paste

First: does copy/paste even make sense? If you're at a VT, you don't really have a clipboard, especially if X isn't running.

Some terminals can copy text in the output, and some will also "paste" by simulating you typing the contents of the clipboard. Ctrl+Shift+V, for example, is paste in gnome-terminal, which may help. (And Ctrl+Shift+C is copy.) As discussed earlier, the big problem with Ctrl+C and Ctrl+V is they overlap with common terminal/program commands. (Ctrl+C is send interrupt (SIGINT) and Ctrl+V is verbatim.)

Some terminals also support two modes of copying data: a more normal "just copy", and what's known as "block select" or "block copy". (Hold Ctrl, and then drag while in gnome-terminal for example.)

Additionally, xsel -b can be used to pipe clipboard contents around. Depends on the exact situtation whether xsel or the terminal's version of paste is more useful. See man xsel.

shift+arrow to highlight text shift+ctrl+arrow to highlight an entire word

Your terminal's highlight (if it has this capability) is separate from cursor position. Again, lack of available key combos is probably a factor. Keep in mind a highlight has two positions: either the start and end, or the upper left and lower right corners. How do you manage both?

Finally, note that many GUI terminals, double-clicking a word will highlight it. (And in X, copy to the primary selection.)

screen, as an example, has keys to switch into a mode for moving around the buffer (previous output) and copy/pasting.

I think if you make adequate use of xsel and the primary selection, you will find clipboard operations are both rare enough and complex enough to merit using the mouse.

Thanatos

Posted 2013-02-22T17:22:58.480

Reputation: 1 924

@monguin Well, even though the information in the answers to this Q appears extraordinarily messy and unordered to me, I've finally found my solution. Even though I too would prefer a way to select text in xterm in a cursor-block-by-cursor-block fashion (going 1 character right/left), it occurs to me that this is simply not available. However, I could work around it a bit (albeit a bit clumsy, but what can you do!) Hack in a $ echo -n "looong_path" | xsel, then press middle mouse button to paste the path (2x in my case, as i only wanted to rename a file with minimal change in filename) – syntaxerror – 2014-12-08T22:35:23.943

Addendum: This goes even sneakier. Supposing you fire away with your (comprehensive) history in bash. In one of the first lines displayed on screen, you see a command which is complex and which you don't want to retype. So you do a $ echo -n "!1234" | xsel and you will have your command from history in the primary buffer, ready to get edited! No, this is not the same as simply invoking $ !1234 on the shell, as the latter will execute the command (which you don't intend until the line has been altered). Lastly I'm wondering why I had to post-install xsel on Lubuntu... – syntaxerror – 2014-12-09T16:39:00.743

@syntaxerror That's a good partial solution for me, I can probably make use of it in the future. My main use case is in editing an existing line, though - modifying parts of a long path, for example. Ctrl+shift+arrow would be really convenient in that context. – monguin – 2014-12-10T04:34:20.903

Hmmm.The only thing left ot consider would be fc (fix command), a bash built-in. It has editing abilities indeed. At least it won't hurt if you just read yourself through this, no matter whether it takes you further in your "quest" or not: http://www.gnu.org/software/bash/manual/html_node/Bash-History-Builtins.html#Bash-History-Builtins

– syntaxerror – 2014-12-10T13:13:27.247

5I appreciate the time you took to write out your answer, but somehow I don't feel like I have any greater understanding of why this is not an available feature in terminal emulators. You pointed out a new idea to me - that a terminal emulator is unique in that it can run other programs - but I don't understand why only a select subset of key combinations are impossible to make available to the user. – monguin – 2013-02-25T16:35:07.073

Don't think about it in terms of the user, but in terms of the destination program. If you type Ctrl+C, is that Ctrl+C intended for the terminal (to copy highlighted text) or for the program running in the terminal (to send an interrupt)? – Thanatos – 2013-02-26T20:55:23.487

The problem with ctrl-C is clear to me, and I assume that's why gnome-terminal uses shift-ctrl-C. Less clear is why the other combinations are not available - ctrl-V, shift-arrow, ctrl-shift-arrow. Do these have some obscure meaning? They don't seem to do anything, other than inserting seemingly random letters, which has no value that I can see. What prevents those from being used in the now-standard way? – monguin – 2013-02-27T21:37:02.030

Ctrl+V is verbatim: try typing, say, "gnome-", Ctrl+V, Tab in your shell. You'll get "gnome-", and then an actual tab, as opposed to tab-completion. Shift-arrow and Ctrl-shift-arrow, are not, AFAIK, used by the shell, but other programs could in theory use them. You'd also need keys to manipulate which end of the selection you're capturing, and (optionally) whether you want a block select or not. I think you'd find it'd be more trouble than its worth for such a minor task. – Thanatos – 2013-02-28T20:43:47.500

2Terminal emulators emulate physical terminals. They were not created from scratch to provide a command-line interface. Things like Control-C had established meanings long before Microsoft decided to co-opt them as keyboard shortcuts, and terminal emulators must adhere to them. – chepner – 2013-02-28T20:53:54.997

Thanatos - why would you need "keys to manipulate which end of the selection you're capturing" ? One end is determined by the cursor location when you press shift, then you move the cursor, and the other end is determined by the current cursor location. This is exactly how shift-highlighting works in every other context, why would that not work in a terminal emulator? I don't know what you mean by "block select". I agree it's more trouble than it's worth, I am just trying to discover a single actual reason that this functionality is not already available. – monguin – 2013-03-01T21:46:11.010

chepner - what meaning did shift-arrow have back then? If it did not have a meaning, then why can it not be used in the now-standard way? Terminal emulators emulate terminals, but that doesn't mean we can't add new, useful, simple features, like colors, scrolling, tabs, profiles... Shift-highlighting seems like it would take a fraction of the code, and memory footprint, necessary for all those things, but it is still not available? I have yet to hear a good reason why it isn't. – monguin – 2013-03-01T21:53:29.187

2I think the devil is in the details here. It's not impossible: screen has a mode to do what you want, I think. But to accomplish it, you have to switch into a "I want to select things" mode. gnome-terminal would have similar issues: they probably didn't implement it because it isn't exactly something you're doing. Keep in mind the shell isn't the only program running: any program could be running, and it could want to use any key sequence that you might use for copy/paste for it's own purposes. screen has ways to send the keys it overrides, and gnome-terminal tries to not step on toes. – Thanatos – 2013-03-01T21:58:25.237

1Block select is a means of selecting a rectangle: Hold control and drag in gnome-terminal, and you should immediately see how it's different. Most GUI terminal emulators have this capability, and most advanced text editors to as well. (See Visual block in vim, for example.) – Thanatos – 2013-03-01T21:59:55.640

1Ah, then I'm familiar with block select, but wasn't aware of the name. I'm also not aware of a GUI keyboard shortcut for that action, so it seems unnecessary to invent one for the sake of answering my question. I appreciate everyone's comments here, but as I'm still unsatisfied, I suppose all I can do now is dig into the source myself... – monguin – 2013-03-01T22:07:58.037

1

The answers are given are good explanations of why doing this is hard. Here is something you can do in gnome-terminal to setup ctrl-c and ctrl-v to copy and paste, while rebinding other keys in the terminal discipline with stty to send SIGINT and insert a character verbatim. This is not a complete solution because some programs disable the terminal discipline, and you won't be able to send them '^C' and '^V'. More info here.

In your shell startup script (e.g. ~/.bashrc, ~/.zshrc, ~/.rcrc), do

stty intr '^Q' 2>/dev/null  # To send SIGINT I will use ctrl-q
stty lnext '^A' 2>/dev/null # To insert a character verbatim I will use ctrl-a

Then in gnome-terminal Edit > Preferences > Shortcuts you can bind Copy and Paste to ctrl-c and ctrl-v. Note that the terminal will get the key events before anything is sent to the terminal device, so from then on you wont be able to send '^C' and '^V' to any process running on the terminal.

I just did this and I will see how it goes, and what problems it causes. I did the stty's conditionally to apply them only when I am running X.

spelufo

Posted 2013-02-22T17:22:58.480

Reputation: 141

1Thanks for the response. In the mean time I've become accustomed to OSX and Emacs bindings, and also just given up on the dream of ctrl+shift+arrow in a terminal... – monguin – 2016-10-28T02:50:56.247

1

As Thanatos mentioned, there is a distinction to be made between the terminal emulator (running on X Windows or Wayland) and programs running within the terminal (let's call that the "shell", though it might not be); these two things are isolated from each other (see technical details).

The first items on your list (arrow keys, Home/End, etc.) are handled directly by the program inside the terminal, and so the cursor position is controlled by the program inside the terminal.

The copy and paste shortcuts (Ctrl+Shift+C and Ctrl+Shift+V), on the other hand, are handled by the terminal emulator, which understands the mouse (so you can select text with the mouse), it knows what is on the screen (so it can copy), and can send keypresses to the program inside (so it can paste).

In order to support Shift+Left and Shift+Right, either the terminal emulator or the shell would have to handle the keystroke. Either way we have a problem:

  1. The shell can't easily handle these keys because eventually you'll want to copy the selected text to the clipboard, and the clipboard is an X Windows concept that the shell doesn't necessarily have access to (but see xclip). And as far as I know, if the shell supported text selection, Linux does not define any mechanism to notify the terminal emulator about what is selected.
  2. Meanwhile, the terminal emulator isn't in charge of the cursor's location. Even if the terminal emulator could change the cursor's location, it probably doesn't know where the current line of text begins and ends. For example, the terminal might contain text like ~ $ ls -l and the terminal emulator is unaware that only the ls -l part belongs to the user.

It's not hard to imagine a terminal emulator that supports selection with Shift+Arrows, but I guess it would have to hide the shell's cursor and introduce its own "fake cursor" that exists temporarily to help you select something, and then you could press Ctrl+C / Ctrl+Shift+C / Ctrl+Ins to copy (or Esc to cancel) and show the real cursor once again. This wouldn't have all the capabilities of a normal selection of course - notably cut and delete wouldn't exist.

Qwertie

Posted 2013-02-22T17:22:58.480

Reputation: 151

Thanks, I will read that TTY article, but haven't yet. That might explain the gap in my understanding of the difference between "terminal emulators" and "desktop applications that handle text programs". My earlier example, the Matlab console, behaves exactly how I want. I don't understand why there can't be a desktop application with that behavior, where the text program running within it is something besides Matlab. Say I wanted to use only the most basic shell commands - ls, cd, cp, mv - then I don't see any conflict. Programs like screen or tmux, I understand might make things trickier. – monguin – 2018-11-09T16:22:11.350

1

These are CUA keyboard bindings you describe, a standard from IBM in the mid 80s:

https://en.wikipedia.org/wiki/IBM_Common_User_Access

They are typically implemented in all desktop environments created since. DOS, Windows, Motif, even Netware tools all converged on this standard. One exception is the Mac, which uses a quite similar but different set (Cmd instead of Ctrl) from the same time period.

Unix terminals far predate this standard however and mostly ignored it. Also, if they did implement these key bindings, it might interfere with TUI programs that already use them for other functionality. So while technically doable, problematic too.

Apps:

The micro text editor is the best I've seen at emulating a GUI text editor, similar to DOS edit but with more modern features a la Sublime Text. ne is an older one in Debian repos, and even nano can be configured with sane keybindings. But the bare terminal/shell, no.

With libvte it might be easy to build a rudimentary virtual terminal that handles these keybindings yourself. A lot of work for a tiny gain however.

Gringo Suave

Posted 2013-02-22T17:22:58.480

Reputation: 932

1

I'm not an expert of terminal emulators but...

applications like bash (readline) running into a terminal emulator know nothing about the running X window system and the X window they are within, they know stdin and stdout on a terminal device (ttyS/ttyUSB/tty/pts on linux).

The problem isn't show some highlighted text but how to let know the X window application (the terminal emulator) that text been selected, through these terminal devices.

I guess the X terminal application open one of those devices in input and output and then translate X key events to properly output (from X side) input (from bash side). Viceversa the bash output stream to the X terminal as input, here the X terminal process this input to move the cursor, fill the backround with some color, according with the bash application output.

For my knowledge escape codes may be used to control special behaviors, like clear, fill the background, move the cursor, and maybe some custom escape code could be added to let know the X terminal that a text from row,col to row,col has been selected, just an example, maybe instead the selected text could just be returned (an implementation detail).

I guess not being a standard definition you'll have to patch every application you want to support it to know about the key combination has pressed and output the appropriate escape code, the readline if you want it in the bash, the X terminal emulator on the other side to process properly the escape code (and finally send the information to the clipboard). Probably implementing this as a terminal capability would save you from patch every single application. I hope (and guess) the terminal device drivers in the kernel want to know less as possible about escape codes, so if you are lucky no patch will be required.

The X terminal draw the output, so it easily know, when you use the mouse, what text/characters are you selecting.

A graphic text widget know everything about its X window that why it is so easy to implement select&copy.

EDIT

Here this urxvt-9.16-image-display patch could be a good start point to understand what is needed to support new escape codes. http://lists.schmorp.de/pipermail/rxvt-unicode/2013q1/001736.html

Alex

Posted 2013-02-22T17:22:58.480

Reputation: 87

0

I just helped a buddy through a similar issue to this and found out that the clipboard manager clipit was the culprit.

sudo apt-get remove clipit

was able to get everything back up and running just fine for him. Hope that might help someone else out there.

Mandela Affected

Posted 2013-02-22T17:22:58.480

Reputation: 1

Did you answer the wrong question? This was a general question about the capabilities of all terminal emulators. It is pretty clear there is no "solution". I don't now, nor have I ever had clipit installed on any machine. – monguin – 2018-09-09T02:35:36.793