Adventures in TTY

· berru's blog

First try as a TTY-only experience

Table of Contents

Contents #

This post was initially published on RTC.club in 2020.

~3700 words : ~28 minutes read

TL;RD: I challenged myself not to use a graphical environment for one month, and I talk about my setup.

adventures in TTY part 1 #

context #

So in early 2020 the country I live in was locked down and I found myself unemployed. A great occasion to focus on hobbies. I am a passionnate linux user I've been using it for more than a decade now, and I'm always amazed by the endless depth of its subculture.

In the last years I have been and more attracted by console-based programs. I found them more reliable, faster and simpler. No surprise for thoses already familiar with the UNIX philosophy and RTC members.

I challenged myself not to start a graphical environment for one month. No Xorg, no Wayland : plain TTY and nothing else. How hard could it be ? I was using CLI tools in terminals already !

Well the hardest part was the lack of documentation online. Most article assume you're using a terminal emulator, not a TTY. So I decided to share my journey to fix the lack of info online.

tty/linux console #

By TTY, you should understand the linux-console. The ArchWiki page on the topic is informative, as usual. So that's the console you see when your linux box boots. Linux distributions usually have several such consoles, accessible by pressing CTRL-ALT-FX, where X is a number between 1 and 9. I'll use the words 'console' and 'tty' interchangably in this series.

There are several differences with a terminal emulator such as alacritty, gnome-terminal or xterm. First it's running in the kernel, and not in userspace. If feels faster, but I suspect it has more to do with input latency. At any rate, it has no overhead, and is lighter than using a desktop environment. Second, there is nothing outside of it. There are no taskbar, no notifications popups, no launching menu. There is nothing else than ASCII characters on your screen. You can work around most of this limitations, and that's the topic of this series.

Your time is precious, so I'll start with the conclusion so you can decide if you want to read the detailed entries.

conclusion #

pros #

  1. Speed: CLI allows for "playing at the speed of thought"
  2. Decluttering: Helps focusing on long term tasks over noisy visual stimuli
  3. Load: Reduces the energy consumption/CPU usage by a lot !
  4. Fun: and rewarding
  5. Eye strain: the screen is mostly black, that's easier on the eyes

cons #

  1. No graphics: You can't have your cake and eat it
  2. Poor documentation: Most articles assume terminal emulators

takeaway #

Less procrastination and distraction. Sometimes I sit at the computer looking for a cooking recipe and the next thing I know, it's 5p.m. and I have spent my day browsing stuff so boring I didn't even remember them. How infuriating! Going 'full-tty' didn't completly solve the problem, but helped.

I can use my computer for days without charging it. Granted, I put it to sleep or shut it down when I don't use it. But the battery gain is tremendous. I managed to lower the energy consumption to about 2W. powertop reported a suspicious 15hrs of battery life. It might be optimistic, but I don't feel anxious about my battery draining fast.

There are things I still miss from the 'graphical' world. Better color handling, nicer font rendering. I like not having a pointer. Especially when using a laptop. Now I can rest my hands in a normal position without fear of touching the touchpad with my palms.

I keep using my computer in a TTY for my personnal use. Yet, I start my graphical environment (sway) on several occasions.

To do paid work: I'm in the video-game industry and have to see the game at some point. I also need to do video calls sometimes. To play games: Because most games I play can't run in a terminal. To procrastinate on purpose: sometimes I tired but not sleepy. I want to waste a few hours, and internet always have my back for that.

adventures in TTY part 2 : programming #

This part was actually the easiest to deal with. I was already using a majority text-based tools for programming. I was programming in Python & Rust at that time, which was convenient. My usual day to day job involves C# and Unity3d, that would've made the whole adventure impossible.

While I wasn't programming with the (un)famous vi, as my main IDE, I fell in love with the keymap and the modal system long ago. I was already using it for small editings and note taking though. It's, actually nvim but you get my point.

Making it my main IDE was a matter of installing the right plugins. By order of preference, I added :

  1. fzf.vim to find files, text, code buffers
  2. neoformat.vim to take care of the formatting
  3. deoplete for code autocompletion. I also tried syntastic and YouCompleteMe but preferred deoplete because it was easier to configure

I should mention I already had the following extensions :

  1. vimwiki to keep a journal/diary and personnal knowledge base
  2. vim-table-mode to create ascii tables
  3. vim-surround to deal with quotes and parenthesis

Tools like git and python or rustc were already first-class tty citizens, so I just went along. And carried on my usual business.

And that covers the programming part of computer usage.

Or so I though !

Not 5 minutes after my setup was finished I found myself wanting to read the documentation on an obscure Rust function, which is conveniently shipped in an HTML page. So I rapidly had to install a browser that could do a bit more than a simple curl.

After trying lynx, elinks and w3m I settled for the latter. Not only it has an option for vim-keybinding, but I found it managed pages layout better, overall. Also, it has the ability to display images in your tty. It feels kinda hacky but it can be really helpful sometimes. !example of my tmux session browsing a website with the image of a cat

For quick searches online, I really appreciate ddgr. It's basically a version of DuckDuckGo in a terminal. It allows me to enter a query, and see what I would've seen on DuckDuckGo itself : site address, title and a short extract. All of this without starting a browser, so it's even faster and better suited for my usage.

adventures in TTY part 3 : reading #

I like to read stuff online as much as anyone, but I don't like all the fancyness of 2020's web. Reading in a TTY removes all the bells and whistles I don't like, but also breaks quite a few websites.

For websites that have an RSS feed, I check on them with newsboat, a local and offline RSS reader. Of course, I found a way to configure some vim-keys binding as soon as I could ! As a bonus, the RSS feeds are stored locally, so I can read while commuting. When the author is kind enough to publish the whole article in the feed, that is. Otherwise, I use w3m to open the website and read.

I have two main issues with text-mode browser. They completly mess the layout, and they don't support javascript. I don't blame the browsers, given the mess that the web is today. But using them feels bad. I prefer to use a dedicated tool when I can.

I discovered the gemini protocol, and it's clearly a perfect fit for me. It's the web, but text-only. I have a routine of checking hackernews and/or lobste.rs in the morning. I added gemini's capcom to it. As I write this, there is a gemini proxy for lobste.rs and ddevault is working on one for hackernews. Maybe I'll be able to stick to gemini all the time sooner that I expected ! To connect to gemini I use av-98.py as my main 'browser'. It was the simplest and most intuitive I tried.

To read posts on reddit, I tried rtv. It's really good, but useless for image-based subreddits.

I also found wttr.in : a really nice way to check the weather. I type curl wttr.in or curl wttr.in/SomePlace and it prints a nicely formatted 3-days weather prediction.

I'm really fond of these little curl tools/sites. I whish there were more of them ! In the same vein, there is curl cht.sh/any_command that gives examples of a command. I use it all the time because I keep fogetting tar options and I'm too lazy to browse through the manpage.

I also used covid19cli.sh quite extensively too. I don't read 'news' and tend to focus on technical articles. So I prefer to access live numbers and forge my own opinion rather than reading alarming articles.

I discovered the epr program to read ebooks. Default 80 characters width and automatically open the last book where I left it are nice defaults. I still prefer to read them on my hardware e-ink reader though.

Now since my terminal supports a framebuffer, I can do stuff that I didn't expect. Display more than text-characters. For instance, fbgs can open pdf files in the tty. It's a bit aliased but I don't do that often anyway.

There is fbi to open images and I discovered that mpv can read videos in the tty too ! It's not hardware-accelerated, so it can have troubles when the definition is high. Since I have youtube-dl installed, typing mpv --vo=drm profile=sw-fast <my_youtube_url> allowed me to watch the occasional video.

adventures in TTY part 4 : writing #

I wrote about reading stuff in the last entry. Now, on to writing !

i/o #

I always have a IRC program running somewhere, at anytime. So far, I've been using weechat for that, so, no need to change it. I also added weecord and weeslack plugins to handle slack (for work) and discord (for friends) channels. Works great, and now I have the luxury of having all my instant messaging platforms in the same place without all the emojis, gifs, and link preview that distract me !

A limitation of the weecord plugin is that it doesn't handle audio. No surprise since weechat is an IRC client, but I would've loved a way to join an audio conversation from my TTY...

On the plus side, weechat running for hours (sometimes days), with 4 IRC servers, 1 slack workspace and 2 discord servers, averages about 80Mb of ram.

With weechat in a TTY, a few issues arised. English is not my main language, so reducing my character table to 'ASCII-only' was fine for programming, but out of question for discussion. The problem is two-fold :

  1. How do I display characters on screen ?
  2. How do I type non-ascii characters

The display part is unfortunately limited. There is no way to have full UTF-8 support in a TTY as far as I know. Some extended charactersets are available though, such as Latin, which is enough for me at the moment. So it's mostly a matter of setting a font that supports it using setfont. The terminus font has a variety of options in size and charactersets, so I settled on : setfont ter-p22n.psf.gz, but I'll talk about it in more detail in another post.

The input part has been a bit trickier, because of my setup. I like to have my keyboard in international QWERTY with 'CAPSLOCK' as my compose key. I had to create a new keymap and then load it with loadkeys my_keymap. Again, it'll be discussed in a later post too.

task management #

I expected it to block me sooner, but I stumbled on the 'background task management' issue at that point. If I have weechat running all the time, how do I do anything else ? Up to that point I was using CTRL-z and the jobs command to pause and resume several applications, but given the nature of weechat I can't really 'pause' the application. I need it to run in the background.

I tried several 'multiplexers' : gnu screen and tmux. They offer a set of similar features, and I finally settled for tmux. It's better, and it's easier to search info about it. Naming programs with very generic names is not usually a good idea for SEO. (I'm looking at you Rust!)

So using tmux has the following advantages : several program running at the same time in 'windows'. They work like I'd expect a workspace to work in a regular desktop environment. It also supports splitting the screen horizontally or vertically and I get a copy/pasting mechanism for free. So now I can open links that are sent to me. It's still more cumbersome than 'just clicking it', but I can copy the url and open it with my browser and that's already better than typing the URL myself !

mailing #

For classical mailing, I tried the venerable mutt and the new and shiny aerc. I preferred the later : it felt easier to use and configure. Ok, Vim-keys as a default was a huge selling point too. There is still room for improving my setup there : GPG management and calendar integration are not seamless. But I know GPG support is a work-in-progress in aerc so I don't want to spend time making a bunch of scripts to deal with it if I can wait for it to appear thanks to the devteam.

To manage my calendar, I use calcurse. Not much to say about it. It does its job well and can import ical files for meeting invitations I receive by mail. Running calcurse -a gives me a list of appointments for the day. Calcurse can also manage a todolist, but I prefer to keep that in my vimwiki.

To complete the mail setup, I use abook as my contact management app. Again, a simple one. I admit I didn't take the time to test any other alternative for that though, and kept the first I found. aerc can read from it to autocomplete mail addresses, but I didn't find an easy way to add new contacts to it from aerc.

I also use translate.sh extensively to check spelling and find words I know in a language but not in another.

adventures in TTY part 5 : playing #

Last part finished with the most boring corporate stuff. Let's discuss funnier topics.

music #

Music was a surprising and refreshing topic. Most programs I use in a TTY feel different than using them in a graphical environment. The colors, the shortcuts, the reactiveness contribute to a different feeling. Well not music. It's exactly the same. For the actual playing I use mpd. It stands for music player daemon. It works with your preffered soundsystem, either pulseaudio or alsa, and takes care of the 'playing' part of music playing. Then you're free to choose a 'client' to control it. Meaning starting the music, pausing it etc... I think of it as mpd being the hi-fi system and the client being the remote control. So far, it played any file format I thrown at it, with so little ram I don't even notice it. It was about 30Mb at its top. It even works for streaming radios & podcasts.

To control it I use a combination of mpc and ncmpcpp. I use mpc for small commands such as mpc stop and mpc pause. If I want to create a playlist, add a bunch of songs or search something in my music library, I open ncmpcpp. Apart from the name I can never remember right, it's a great piece of software. It does everything you'd expect from a music player, tagging, searching, playlisting, fetching lyrics. There even is a music visualizer.

Since I use pulseaudio, I can change the volume using pactl but I always forget the syntax somehow. I tend to use pulsemixer instead, it's an ncurse version of the kind of volume control application you find on every computer nowadays.

games #

No games I played during my TTY month had sound. A good opportunity to use programs from the above paragraph. It was a good opportunity to try 'real' roguelikes. Or 'Berlin definition' roguelikes. I already liked Dungeon Crawl Stone Soup, or dcss for short. But I had only played it with graphics. It's a great game and one of the easiest roguelikes to start with.

It has the basic heroic-fantasy roguelike universe : you, the hero has to go deep down the dungeon to get a McGuffin. The deeper the harder.

Gameplay-wise, it's a grid-based turn-by-turn game. Every action you take makes the game play an equal amount of time. So if I do a quick action, like drawing a sword, the monster might not even move. If I do a long action, like reading a scroll, monsters have enough time to travel from the other side of the room and gnaw at me. But from my player perspective, both outcomes are shown instantly.

It's a bit surprising at first, but it allows you to "play at the speed of thought".

dcss has lots of 'quality of life' features. Meaning it's one of the most accessible roguelikes for a beinner. Sure, you'll have to get used to ASCII characters representing the game and remember lots and lots of keys for different actions. But at least dcss provides easy and rememberable shortcuts consistent menus and functions such as 'autoexplore'. That's accessibility.

On the other end of the spectrum there is the other great game I spent hours on : 'Cataclysm : Dark Days Ahead'. Or cdda for short. It's the deepest game I ever played. It's a roguelike because you play your single character on a grid-based map and the time management is the same. That's where the similarities end. In cdda you play as a zombie apocalypse survivor, and it's really hard to convey how deep the game is. It goes to an insane level of simulation and customization. The learning curve is steep, but the possibilities endless. The game is open source and development has been very active for years.

I also tried a few interactive fiction games, but that isn't my type.

adventures in TTY part 6 : feeling at home #

Previous entries where about finding tty-applications to replace what I was doing in a graphical environment. But there are things to be done in the TTY too. Things that made me more confortable.

First changing the font. I don't like the default one, and it was too small anyway.

There aren't many fonts available in the 'psf' format a TTY expects. 'Terminus' was one of them. I like it and it's available in 16 and 20 pixels, which is way more confortable to read. The fonts are changed using the setfont command. You can find available fonts in /usr/share/kbd/consolefonts/. Changes are persisted by editing /etc/vconsole.conf. You can set your keymap using loadkeys, and it's persisted the same way. Existing keymaps can be found in /usr/share/kbd/keymaps/.

I mentionned editing my keymap in a previous entry, that's how. The way the keymap system works is not obvious. Each time you load a keymap, it doesn't replace the existing one. It adds the new mappings and if it already exists, it's replaced. As a consequence, a good way to start a keymap is using the output of dumpkeys as a starting point.

With bigger and cleaner fonts, it starts to look like home again, but that can be right without some color theming. You can actually tweak the TTY's default colors with escape codes. My favorite color scheme being the classic 'solarized', it was just a call to ddg away. I added it to my .rc file and here ! That's home now !

I had an unexpected issue with resolution. My laptop is 1920x1200, while my external monitor has the more classic 1920x1080. I discovered fbset -yres 1080 allows me to change the resolution of the screen. I always use a single monitor at any time, but I'm confident fbset could do some trickery with its virtual terminal settings to extend it on several monitor. Didn't test it though.

Now here is a random list of programs I could fit in no particular category, but were used at some point. To mount USB keys automatically, I used udiskie. I connected to new wifi networks using nmtui, and my password manager was already pass or (zx2c4 pass), which works in command-line. When I focused on power consumption powertop was an essential benchmark. Its --auto-tune paramater gets my baseline power consumption from ~20W to ~4W instantly.

Finally, I added some programs just to 'show off'. To nobody since I was still locked down, but I like silly programs.

I can see the matrix using cmatrix, and it can work as some sort of screensaver. No more secrets, or nms displays criptic symbols, and 'decrypts' them hollywood style at the press of a key. You can pipe anything to it. And genact simulates busy loading stuff : gcc compilation, php update, bitcoin mining. Looks like the real, but its all fake. So I can pretend I do important stuff and take endless coffee breaks.

I can't records gif of glitches on my desktop anymore, but I can record my terminal with asciinema. The program handles the recording, the uploading and the replaying. Handy !

Finally, my two favorite tools and best productivity improvers. Fish shell, and fzf. Fish shell is everything you find good in zsh plus oh-my-zsh only faster, with saner defaults. And fzf boosts it to insane level of usability. Autocompletion, syntaxic colorations, file search in arguments etc. The two combined feels like I unlocked the 'easy mode' for using a terminal.

Adventures in TTY part 8 : with a better TTY #

If you ever wondered what program handles your TTY and if you can change it, read on.

The default for the TTY, AKA the lines you might see before you are prompted with your login and password is handled by a program, most likely getty or agetty. You can switch to another one with a bit of configuration. It's obviously specific to your linux distribution.

Why would I change it ? Well some consoles offer a better experience with features such as :

All the modern stuff that one might want in a TTY without the hassle of a graphical environment.

Trivia : The default linux console is part of the linux kernel. It has to be compatible with an insane amount of devices, and did not include the above functionnalities for the sake of compatibility.

I tried 3 alternatives to the default console : fbterm, yaft and kmscon.

fbterm stands for 'Frame Buffer terminal'. While it offers the features I was looking for, I failed to make it work properly. I had issues with font rendering and couldn't fix it after a few hours so I just gave up.

yaft stands for 'yet another framebuffer terminal, it feels like a tech demo and a proof-of-concept rather than a fully-featured software. It was still good enough for most of my use-cases. Color scheme or theming can be customized by changing values in a file before compiling. Not very handy. I don't change my theme often anyway, so I could go with it.

kmscon stands for 'Kernel Mode Setting CONsole' and is the one I settled with. It has all the bells and whistles I listed above. It was easier to configure overall; a systemd service to start it instead of 'getty', a list of preset themes (including solarized !), and easily accessible pango rendered fonts !

My config file (stored in /etc/kmscon/kmscon.conf) is a simple as :

font-size=16
font-name=JetBrains Mono
font-engine=pango
palette=solarized
xkb-options=compose:caps
xkb-repeat-rate=25
xkb-layout=us
compose
drm
hwaccel

The font is as crips and smooth as in my graphical environment. I can resize it with ctrl +/ctrl -. Really feels like my regular terminal emulator.

offtopic #

As usual with the topic of TTY and using a computer without graphical environment, the documentation is quite scarce, and software is not moving a lot. Which isn't bad in itself. A good software is a finished software [1]. But in this particular case it proved inconvenient.

I had to do some internet digging to make the compose-key work, because the version I found online (both on freedesktop.org and on Aetf's github repo) didn't support them. The git repository looked untouched since 2018, so I had to find a patch proposed in 2014 by user 'Ran Benita ran234@gmail.com' to add support to it. Locally merged it, and everything now works !

And that concludes this series. If you think I forgot to mention something or you have an improvement to share ; Feel free to reach me at or berru at riseup dot net.

last updated: