23 December 2019

terminal emulators

by mo


is a computer program that emulates a video terminal within some other display architecture.

I haven been playing with different terminal emulators recently because I was curious. This is what I learned:

Kitty

Kitty is a terminal emulator created by the author of calibre. It takes advantage of rendering via the GPU to free up your CPU. It can display images, true-color and open type ligatures. It has a host of additional features such as tiling, and can be configured via a kitty.conf configuration file and runs on Unix-like platforms.

It’s included in the updates repo in Fedora 31 an can be installed easily.

モ yum info kitty
Installed Packages
Name         : kitty
Version      : 0.15.0
Release      : 1.fc31
Architecture : x86_64
Size         : 6.9 M
Source       : kitty-0.15.0-1.fc31.src.rpm
Repository   : @System
From repo    : updates
Summary      : Cross-platform, fast, feature full, GPU based terminal emulator
URL          : https://sw.kovidgoyal.net/kitty
License      : GPLv3 and zlib and BSD
Description  : - Offloads rendering to the GPU for lower system load and buttery smooth
             :   scrolling. Uses threaded rendering to minimize input latency.
             :
             : - Supports all modern terminal features: graphics (images), unicode, true-color,
             :   OpenType ligatures, mouse protocol, focus tracking, bracketed paste and
             :   several new terminal protocol extensions.
             :
             : - Supports tiling multiple terminal windows side by side in different layouts
             :   without needing to use an extra program like tmux.
             :
             : - Can be controlled from scripts or the shell prompt, even over SSH.
             :
             : - Has a framework for Kittens, small terminal programs that can be used to
             :   extend kitty's functionality. For example, they are used for Unicode input,
             :   Hints and Side-by-side diff.
             :
             : - Supports startup sessions which allow you to specify the window/tab layout,
             :   working directories and programs to run on startup.
             :
             : - Cross-platform: kitty works on Linux and macOS, but because it uses only
             :   OpenGL for rendering, it should be trivial to port to other Unix-like
             :   platforms.
             :
             : - Allows you to open the scrollback buffer in a separate window using arbitrary
             :   programs of your choice. This is useful for browsing the history comfortably
             :   in a pager or editor.
             :
             : - Has multiple copy/paste buffers, like vim.

There’s also an additional kitty-terminfo package that can be used to add a terminfo entry for kitty.

It just works and is packed with features for someone that wants a terminal that works across MacOS and Linux with little setup. Configuring the terminal to work across operating systems is easy and well documented.

rxvt-unicode aka urxvt

urxvt is a fork of rxvt with added support for Unicode.

The source code for rxvt-unicode is in CVS but there are some folks running mirrors to GitHub.

The default repos on Fedora 31 include several different types of rxvt-unicode versions.

モ yum search rxvt-unicode
Last metadata expiration check: 0:07:13 ago on Mon 23 Dec 2019 12:44:46 PM MST.
============================= Name Exactly Matched: rxvt-unicode ==============================
rxvt-unicode.x86_64 : Unicode version of rxvt
============================ Name & Summary Matched: rxvt-unicode =============================
rxvt-unicode-ml.x86_64 : Multi-language version of rxvt-unicode
rxvt-unicode-256color.x86_64 : 256 color version of rxvt-unicode
rxvt-unicode-256color-ml.x86_64 : 256 color multi-language version of rxvt-unicode

None of them seemed to be compiled with the options that I wanted like unicode3 and frills. I found it easier to pull from a mirror and recompile the urxvt binary with the --enable-everything option to get what I wanted.

モ urxvt --help 2>&1 | grep 'options:'
options: perl,xft,styles,combining,blink,iso14755,unicode3,encodings=eu+vn+jp+jp-ext+kr+zh+zh-ext,fade,transparent,tint,XIM,frills,selectionscrolling,wheel,slipwheel,cursorBlink,pointerBlank,scrollbars=plain+rxvt+NeXT+xterm

Once, I had a version of urxvt installed with the options that I wanted, then I could configure it via $HOME/.Xresources. This took several rounds of tweaking to get right. Each round of tweaking required xrdb -load ~/.Xresources or xrdb -merge ~/.Xresources depending on what I was trying to accomplish. In some cases it was easier to restart the display manager via sudo systemctl restart display-manager.

history | grep display-manager | wc -l
50

To tweak .Xresources you’re going to need to get comfortable with:

  • fc-list: List installed fonts
  • xrdb -query: Query the X resources db to see what the current settings are
  • xrdb -load ~/.Xresources: Load and reset X resources from a file.
  • xrdb -merge ~/.Xresources: Merge settings for X resources from a file.

This requires patience. urxvt supports fallback font rendering and xft. However, rendering colour fonts via xft through rxvt-unicode never seemed to work for me. I settled on Symbola as my fallback font for rendering emoji. 😥

My current ~/.Xresources:

! xdpyinfo  | grep dots
Xft.dpi: 94
Xft.antialias: true
Xft.rgba: rgb
Xft.hinting: true
Xft.hintstyle: hintslight

URxvt.font: xft:monospace:pixelsize=14,xft:Symbola:pixelsize=12:antialias=true:autohint=true
URxvt.letterSpace: -1
URxvt.cursorBlink: true
URxvt*skipBuiltinGlyphs: true
URxvt.depth: 32
URxvt.geometry: 1920x1080
URxvt.internalBorder: 0
URxvt.lineSpace: -1
URxvt.saveLines: 0
URxvt.loginShell: true
URxvt.scrollBar: false
URxvt.scrollWithBuffer: true
URxvt.url-launcher: firefox-dev

URxvt.perl-ext-common: default,matcher,clipboard-osc
URxvt.url-select.launcher: firefox-dev
URxvt.url-select.underline: true
URxvt.matcher.button: 1

! Copyright (c) 2016-present Arctic Ice Studio <development@arcticicestudio.com>
! Copyright (c) 2016-present Sven Greb <code@svengreb.de>

! Project:    Nord XResources
! Version:    0.1.0
! Repository: https://github.com/arcticicestudio/nord-xresources
! License:    MIT

#define nord0 #2E3440
#define nord1 #3B4252
#define nord2 #434C5E
#define nord3 #4C566A
#define nord4 #D8DEE9
#define nord5 #E5E9F0
#define nord6 #ECEFF4
#define nord7 #8FBCBB
#define nord8 #88C0D0
#define nord9 #81A1C1
#define nord10 #5E81AC
#define nord11 #BF616A
#define nord12 #D08770
#define nord13 #EBCB8B
#define nord14 #A3BE8C
#define nord15 #B48EAD

*.foreground:   nord4
*.background:   nord0
*.cursorColor:  nord4
*fading: 35
*fadeColor: nord3

*.color0: nord1
*.color1: nord11
*.color2: nord14
*.color3: nord13
*.color4: nord9
*.color5: nord15
*.color6: nord8
*.color7: nord5
*.color8: nord3
*.color9: nord11
*.color10: nord14
*.color11: nord13
*.color12: nord9
*.color13: nord15
*.color14: nord7
*.color15: nord6

This worked pretty good. Memory usage was slow and the terminal seemed pretty snappy. I did miss my colour emoji and the images seemed to flicker when viewing a page via w3m.

I installed a .desktop entry that starts tmux immediately.

cat ~/.local/share/applications/urxvt.desktop
[Desktop Entry]
Type=Application
Encoding=UTF-8
Name=urxvt
Exec=/usr/local/bin/urxvt -e tmux
Icon=urxvt
Terminal=false

I liked the minimal features that rxvt-unicode offered. I don’t need scroll back or window tiling because I use tmux. I’m almost embarrassed to say it but, I do miss colour emoji.

alacritty

alacritty claims to be:

the fastest terminal emulator in existence.

It uses GPU rendering and defaults to Wayland on systems that support it. Also, this project is written in Rust.

Configuring, alacritty is done via a alacritty.yml file and supports an auto reload option. The auto reload option made it very easy to configure and tweak the terminal. One of my favourite settings is window.decorations.none. This removes the window title bar and maximizes the amount of space that my terminal occupies on my screen. Some of the settings are platform specific and I found that some settings that worked on Linux ended up causing a crash on MacOs. It took a bit of debugging to figure out which settings those were but in the end I was able to get a similar experience across MacOS and Linux. The settings that I ended up commenting out because it worked on Linux but caused a crash on MacOS were:

  • shell.program: /usr/bin/tmux # /usr/local/bin/tmux on MacOS but still crashed.
  • window.startup_mode: Maximized # I’m not sure why this only worked on Linux.

There appears to be a proposal to support fallback fonts which looks nice and will mean I can use my preferred monospace font and fallback to a color emoji font for missing items. Until then, if you want colour emoji you will need to choose a font that supports it.

The latest release includes an example config file with all the available options.

This project is still pre 1.0 so it’s not quite stable yet. I like this terminal emulator and I’m excited to see where the project goes.

simple terminal - st by suckless.org

st is a minimal terminal that supports UTF-8, wide-characters, 256 and true colors. This program is available via package managers but to customize it you need to edit a config.h file so you’re better off compiling it from scratch. Additional features come in the form of .patch files submitted by the community. The core is minimal and you can apply whatever patch files that you like.

A minimal Dockerfile with a few patches to build an rpm:

Dockerfile

FROM fedora:latest
RUN yum update -y
RUN yum install -y git wget tree man which ruby-devel rpm-build libffi-devel
RUN yum group install -y "Development Tools"
RUN yum group install -y "X Software Development"
RUN gem install --no-document fpm
RUN git clone https://git.suckless.org/st /root/st
WORKDIR /root/st
COPY patch.sh patch.sh
COPY config.h config.h
RUN sh patch.sh
RUN make clean install
WORKDIR /root/
RUN fpm -s dir -t rpm -n mokha-st -v '0.8.2' /usr/local/bin/st /usr/local/share/man/man1/st.1 /usr/share/applications/st.desktop

patch.sh

#!/bin/sh

set -e

apply_patch() {
  url=$1
  wget "$url"
  file="$(basename "$url")"
  git apply "$file"
  rm "$file"
}

apply_patch https://st.suckless.org/patches/font2/st-font2-20190416-ba72400.diff
apply_patch https://st.suckless.org/patches/boxdraw/st-boxdraw_v2-0.8.2.diff
apply_patch https://st.suckless.org/patches/newterm/st-newterm-0.8.2.diff
apply_patch https://st.suckless.org/patches/nordtheme/st-nordtheme-0.8.2.diff
apply_patch https://st.suckless.org/patches/desktopentry/st-desktopentry-0.8.2.diff
apply_patch https://st.suckless.org/patches/clipboard/st-clipboard-20180309-c5ba9c0.diff
apply_patch https://gist.githubusercontent.com/mokhan/62bba469937d0114778af4e08ab5f53b/raw/f386b4f738585e90564e457c9795a681333b54e8/st-exec-tmux.diff

This terminal has the same issue as rxvt-unicode with rendering colour emoji due to it’s dependence on xft but it has the advantage of true color support, easy to compile, and no need to mess with .Xresources.

github

Conclusion

alacritty works quite well and is a consistent experience across Linux and MacOS. st is minimal and easy to read. For now, I will keep an eye on alacritty and use it when I’m on my MacOS laptop and probably stick with st when working from my Linux host.

Also, I would like to thank the nord theme project for making it easy on my eyes across terminals and editors. Also, it doesn’t hurt to stick with the defaults as I was surprised to see the results from Terminal latency.

unix