Hacker News new | past | comments | ask | show | jobs | submit login
A look at terminal emulators, part 1 (lwn.net)
213 points by eddieh on April 22, 2018 | hide | past | favorite | 42 comments



I like that the test started with Unicode support, but there is a lot more that could be tested. See http://www.madore.org/~david/misc/unitest/ for some more challenges, in particular http://www.madore.org/~david/misc/unitest/#combining

Last time I compared terminals re:Unicode, I settled on sakura (over xterm, urxvt, st, xfce4-terminal at least). I should probably try mlterm too, but since I don't understand any RTL languages myself, I actually find it less confusing if they are "backwards", especially when they occur in the middle of non-RTL strings. https://opensource.com/life/16/3/twisted-road-right-left-lan... is a scary look at the possibilities for misinterpretation – keeping everything in byte order at least makes it predictable and unambiguous, though "wrong".

-----

By the way, `set enable-bracketed-paste on` really should be default, that's an instant productivity enhancer! I used to think it was impossible to paste tabs into the terminal …


A lot of these RTL issues seem to properly belong to the application generating the output and not the terminal. A terminal displays what an application tells it to. It should be up to the application to properly tell the terminal to display the text RTL and left or right aligned and not up to the terminal to try to decipher what the application wants.

The article itself has an example of this. It contains RTL language which should not be right aligned because it properly belongs in line with the rest of the text. How is a terminal suppose to know this without the application telling it. The application is the one with knowledge of the context.


For what it's worth, here is how I deal with that pasting problem in my terminal emulator.

I took a leaf out of the book of dealing with octal escapes in string literals in the C language. One of the simplest ways of avoiding the problem of the octal number in the escape being followed by an actual intended digit character is to terminate the string literal and start a new one. Hence:

    "abcde\001""23"
I took the same idea and applied it to pasted content. When console-terminal-emulator receives ESC or CSI characters from its input FIFO that are marked as pasted text, immediately after sending them on it sends an end-of-paste sequence (DECFNK 201) followed by a start-of-paste (DECFNK 200). Thus any potential DECFNK control sequence in the pasted text, that would otherwise itself turn pasting on and off, is broken up.

* http://jdebp.eu./Softwares/nosh/guide/console-terminal-emula...

For example: Generating the sequence ESC [ 2 0 1 ~ l s LF as pasted input directly to the terminal emulator's input, in the way that a realizer program would send pasted input events, with

    # printf '%c\x00\x00\x09' $'\x1B' '[' 2 0 1 '~' 'l' 's' $'\n' >> /run/dev/vc2/input
results in user virtual terminal #2 receiving the following

    % printf "\x1b[?2004h" ; cat -v
    ^[[200~^[^[[201~^[[200~[201~ls
Breaking that down, those are:

1. DECFNK 200 (start pasted text mode)

2. ESC (as pasted character)

3. DECFNK 201 (end pasted text mode)

4. DECFNK 200 (start pasted text mode)

5. [ (as pasted character)

6. 2 (as pasted character)

7. 0 (as pasted character)

8. 1 (as pasted character)

9. ~ (as pasted character)

A. l (as pasted character)

B. s (as pasted character)

C. LF (as pasted character)

A Z shell running in that terminal does indeed receive this as the pasted text ESC [ 2 0 1 ~ l s LF, exactly as sent, and does not enact the embedded end-of-paste or Line Feed.


I have now tried several terminals, but most lack one feature: I use zsh's [autocompletion plugin], and I'd like to call the suggestion with Ctrl+Enter. On the other hand, sometimes I want to execute only what I typed in, with Enter. However, almost all terminals cannot differentiate between Enter and Ctrl+Enter. The one that could is Terminator, but that depends on gconf and I don't need the tiling. Sakura, urxvt and Alacritty cannot. Does anybody have a suggestion for me, or a better mapping?

[autocompletion plugin] https://github.com/zsh-users/zsh-autosuggestions


> almost all terminals cannot differentiate between Enter and Ctrl+Enter

On the contrary, many (perhaps even most) of them can. This is a matter of having a keyboard map that makes these into two distinguishable actions. For many terminal (emulators, at least) this is indeed entirely within the remit of the keyboard map and not limited by the terminal emulator itself at all.

Easy to find example: The us.kbd keyboard map on FreeBSD, used by the terminal emulator that is built in to the kernel and that provides the kernel virtual terminals, distinguishes between these two chords, mapping the former to CR and the latter to LF.

    /usr/share/vt/keymaps % sed -n -e '3,5p;/089/p' us.kbd
    # scan                       cntrl          alt    alt   cntrl lock
    # code  base   shift  cntrl  shift  alt    shift  cntrl  shift state
    # ------------------------------------------------------------------
      089   cr     cr     nl     nl     cr     cr     nl     nl      O
    /usr/share/vt/keymaps %
Note that to take advantage of a mapping like this, one has to turn off the crnl input mode in the terminal line discipline. Again, though, the kernel line discipline is a separate thing to the terminal emulator and this is not a mechanism of the terminal emulator.


I recently did a similar overview of terminals since I needed to pass all keypresses to the terminal, I ended up with something like this in xterm, but I hear it works in urxvt as well:

     .Xdefaults-localhost
     *VT100.Translations: #override \
              	Shift<Key>Return: string("shift return")\n\
              	Ctrl<Key>Return: string("ctrl return")\n\
              	Alt<Key>Return: string("alt return")\n\
              	Super<Key>Return: string("super return")

Here are the escape sequences used by Kitty for sending modifiers to the shell from the terminal: https://github.com/kovidgoyal/kitty/blob/master/protocol-ext... (thanks aumerle)


Simply remap Ctrl+Enter to send some other key combination and bind that in zsh. You can do the remapping either in X or using the terminals native remapping features many terminals have them, for instance kitty.


>However, almost all terminals cannot differentiate between Enter and Ctrl+Enter.

Don't let them do the differentiation them.

Hook a script/something between the keyboard and the terminal that does it for them.


I recently discovered kitty[1], and I love it. It certainly doesn't have all the fancy nice-to-haves, but it is butter smooth, 256 color okay, and renders emojis nicely.

[1]: https://github.com/kovidgoyal/kitty


Emojis are great for things like Vim Dev Icons: https://github.com/ryanoasis/vim-devicons


Thanks for sharing this. Looks like it's had a lot of work done and is actively developed. I'll give it a shot!


Thank god it renders emojis.


I had never heard of that paste attack before.

I tried it out and it doesn't work in zsh, because pasted lines of code always get expanded for you to inspect before they're executed.


Well, "doesn't work" automatically.

Most people will instinctively just press Enter after pasting though, which will defeat the expansion's utility.


I'm going to post just to say a quick word about QTerminal (https://github.com/lxqt/qterminal). It's part of the LXQT project but you don't need to use LXQT for it; in fact, I think its only runtime dependency that's not part of the Qt project is QTerminalWidget.

It deals fine with Unicode. It's not as functional or fully-featured as Konsole, but it's good enough. It has real tab support (urxvt supports tabs through a Perl extension but in a somewhat convoluted way) and doesn't use GTK3.


This is a nice addition I seemed to have missed before, but that might be due to the "project-prefix" thing, I tend to avoid those because they often pull in the entire project as a dependency (but not in this case as you noted).

I currently use sakura (a lighter fork of gnome-terminal less the gnome stuff). I'm mostly just after something that's minimal, the first thing I do when trying out a new terminal emulator is turn off all of the GUI fluff (I use a tiling window manager), then it's all down to font rendering, speed and small binary footprint. I can at least get qterminal down to the actual text console so far which is a good start :) (many terminals you can't)


I switched to qterminal from konsole after becoming frustrated at how long it took to load (order of seconds) in my non-KDE system.

Another nice feature of Qterm is support for font ligatures, like the ones provided in Fira Code.


Does it write all terminal contents to disk like libvte? :-)


Does libvte does this all the time? I was under the impression that, since the dawn of unlimited scrollback in terminal emulators, you only write terminal contents to disk if you need to store an unlimited amount of scrollback content. If you configure a finite amount of scrollback lines, they're stored in memory.

Konsole does this, and I'd be fairly surprised if qterminal didn't, either -- but if you're concerned about this, you should definitely check the source code.


Good thing someone finally pointed out to the poor Unicode and bidirectional text in terminals.


> I haven't found another terminal with such definitive protection against the attack described by Horn.

It's not available on Linux, but iTerm2 does this!


macOS's built-in Terminal.app protects against this attack too. If I try and paste the text containing the bracketed end mode character, Terminal.app beeps and presents a sheet telling me that I cannot send the text to the terminal because it contains invalid content for Bracketed Paste Mode (along with a more detailed description).

Incidentally, when you say iTerm2 "does this" do you mean the simple "confirm paste" behavior, or does it actually explicitly protect against the bracketed paste mode attack?


I also do this in MacTerm (with the option to join the text to a single line, keep as-is or cancel).

Though there is still lots of trickery that can sneak into text, e.g. zero-width characters, and I’m trying to come up with better filters.


elementary's terminal does too with sudo commands: https://github.com/elementary/terminal


Does what?


Asks you whether you want to execute a command ending in a newline that you pasted.


As I pointed out in comments in the original article, warning against newlines is not a sufficient protection against malicious pastes.


A note on urxvt and colors. Many distros do not compile it with 256 color support enabled by default which may be why the author had issues.


The author mentions testing the terminals on Debian as well as Fedora, and since I use urxvt on Fedora it should be fairly easy to verify the authors results. The package with colour support on Fedora is called rxvt-unicode-256color, and the binary is urxvt256c unlike some other systems where colour support may be enabled on the regular urxvt binary. Using the gist the author mentions [0] I end up getting the same results that the author gets, along with the incorrect blinking characters [1].

I even tried 'rxvt-unicode-with-perl-with-unicode3-with-plugins-9.22' from Nix, which includes colour support, to the same results.

[0] https://gist.github.com/XVilka/8346728

[1] https://i.imgur.com/zvBp5oi.png


Same results on gentoo compiled as I stated. I stand corrected.


Looks like my favourite is missing: Sakura.

http://www.pleyades.net/david/projects/sakura

One of many that wraps libvte - but it's pretty small, and does everything I need.


I wish he added Terminator (https://github.com/software-jessies-org/jessies/wiki/Termina...), different from Gnome Terminator, to the panel...


I really didn’t see anything there that would make me give up xterm. Sure it’s kind of big but nearly all the others are bigger and the actual application is very light weight.


Yeah, I still like xterm the most, even if it's not the 'best'.

I use it with the font size set larger.

xtermfont: -fixed----20-

Some of the fancier terminals I have tried had key bindings that interfere with applications I use. It was enough of a hassle I prefer to just stick with plain old xterm.


The xterm default font, "fixed", is also my favourite font in general, so much that I use it on non-Linux systems too.


Me too, at least before wayland being the standard.


Going from OSX to Linux, I still think iTerm2 still takes the cake (though it's OSX only). Disappointed Alacritty was not in the comparison.

I use terminator for the iTerm2 like splits on Linux.


> Disappointed Alacritty was not in the comparison.

It does appear to be included though?


What about commercial terminal emulators like Ericom PowerTerm?


Is there an actual use case for a commercial terminal emulator? Termite and Deepin Terminal both work splendidly for about every use case I can come up with.


My understanding is that these commercial terminals tend to be focused on emulating non-standard terminals used by by systems like IBM mainframes, etc. which are in no way VT100 compatible.

I believe that these products are also optimized for allowing non-technical staff to use old 'greenscreen' terminal UI applications. These products usually have features like macros for commonly-used sequences of key-combos, and they also do things like figuring out if the screen is showing a menu, and turning the menu entries into something that can be clicked by a mouse so it isn't entirely keyboard driven.

For a dev and/or ops person on a modern Linux system, there's almost certainly no reason to look into this stuff.


> My understanding is that these commercial terminals tend to be focused on emulating non-standard terminals used by by systems like IBM mainframes, etc. which are in no way VT100 compatible.

x3270 (http://x3270.bgp.nu/) handles one of the most popular of those.




Join us for AI Startup School this June 16-17 in San Francisco!

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

Search: