aboutsummaryrefslogtreecommitdiff
path: root/content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md
diff options
context:
space:
mode:
Diffstat (limited to 'content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md')
-rw-r--r--content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md184
1 files changed, 95 insertions, 89 deletions
diff --git a/content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md b/content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md
index 4ec307f..a03a2a4 100644
--- a/content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md
+++ b/content/posts/2023-01-26-trying-to-build-a-new-kind-of-terminal-emulator.md
@@ -5,32 +5,33 @@ date: 2023-01-26T12:00:00+02:00
5draft: false 5draft: false
6--- 6---
7 7
8Over the past few weeks, I have been really thinking about terminal emulators, 8Over the past few weeks, I have been really thinking about terminal emulators,
9how we interact with computers, the separation of text-based programs and GUI 9how we interact with computers, the separation of text-based programs and GUI
10ones. To be perfectly honest, I got pissed off one evening when I was cleaning 10ones. To be perfectly honest, I got pissed off one evening when I was cleaning
11up files on my computer. Normally, I go into console and do `ncdu` and check 11up files on my computer. Normally, I go into console and do `ncdu` and check
12where the junk is. Then I start deleting stuff. Without any discrimination, 12where the junk is. Then I start deleting stuff. Without any discrimination,
13usually. But when it comes to screenshots, I have learned that it's good to 13usually. But when it comes to screenshots, I have learned that it's good to keep
14keep them somewhere near if I need to refer to something that I was doing. I 14them somewhere near if I need to refer to something that I was doing. I am an
15am an avid screenshot taker. So at that point I checked Pictures folder and 15avid screenshot taker. So at that point I checked Pictures folder and also did a
16also did a basic search `find . -type f -name "*.jpg"` for all the JPEG files 16basic search `find . -type f -name "*.jpg"` for all the JPEG files in my home
17in my home directory and immediately got pissed off. Why can’t I see thumbnails 17directory and immediately got pissed off. Why can’t I see thumbnails in my
18in my terminal? I know why, but why in the year of 2022 this is still a 18terminal? I know why, but why in the year of 2022 this is still a problem. I am
19problem. I am used to traversing my disk via terminal. I am faster, and I am 19used to traversing my disk via terminal. I am faster, and I am more comfortable
20more comfortable this way. But when it comes to visualization, I then need to 20this way. But when it comes to visualization, I then need to revert to GUI
21revert to GUI applications and again find the same file to see it. I know that 21applications and again find the same file to see it. I know that programs like
22programs like `feh` and `sxiv` are available, but I would just like to see the 22`feh` and `sxiv` are available, but I would just like to see the preview. Like
23preview. Like [Jupyter notebook](https://jupyter.org/) or something similar. 23[Jupyter notebook](https://jupyter.org/) or something similar. Just having it
24Just having it inline. Part of a result. 24inline. Part of a result.
25 25
26It also didn’t help that I was spending some time with the [Plan 9](https://plan9.io/plan9/) 26It also didn’t help that I was spending some time with the [Plan
27Operating system. More specifically [9FRONT](http://9front.org/). The way 279](https://plan9.io/plan9/) Operating system. More specifically
28that [ACME editor](http://acme.cat-v.org/) handles text editing is just 28[9FRONT](http://9front.org/). The way that [ACME editor](http://acme.cat-v.org/)
29wonderful. Different and fresh somehow, even though it’s super old. 29handles text editing is just wonderful. Different and fresh somehow, even though
30 30it’s super old.
31So, I went on a lookout for an interesting way of visualizing results of some 31
32query. I found these applications to be outstanding examples of how not to be 32So, I went on a lookout for an interesting way of visualizing results of some
33a captive of a predetermined way of doing things. 33query. I found these applications to be outstanding examples of how not to be a
34captive of a predetermined way of doing things.
34 35
35- [Wolfram Mathematica](https://www.wolfram.com/mathematica/) 36- [Wolfram Mathematica](https://www.wolfram.com/mathematica/)
36- [Jupyter notebooks](https://jupyter.org/) 37- [Jupyter notebooks](https://jupyter.org/)
@@ -38,56 +39,56 @@ a captive of a predetermined way of doing things.
38- [Temple OS](https://templeos.org/) 39- [Temple OS](https://templeos.org/)
39- [Emacs](https://www.gnu.org/software/emacs/) 40- [Emacs](https://www.gnu.org/software/emacs/)
40 41
41My idea is not as out there as ACME is, but it is a spin on the terminal 42My idea is not as out there as ACME is, but it is a spin on the terminal
42emulators. I like the modes that Vi/Vim provides you with. I like the way 43emulators. I like the modes that Vi/Vim provides you with. I like the way the
43the Emacs does its own `M-x` `M-c`. Furthermore, I really like how Mathematica 44Emacs does its own `M-x` `M-c`. Furthermore, I really like how Mathematica and
44and Jupyter present the data in a free flowing form. And I love how Temple OS 45Jupyter present the data in a free flowing form. And I love how Temple OS is
45is basically a C interpreter on some level. 46basically a C interpreter on some level.
46 47
47> **Note:** This is part 1 of the journey. Nowhere finished yet. I am just 48> **Note:** This is part 1 of the journey. Nowhere finished yet. I am just
48> tinkering with this at the moment. This whole thing can easily spectacularly 49> tinkering with this at the moment. This whole thing can easily spectacularly
49> fail. 50> fail.
50 51
51So I started. I knew that I wanted to have the couple of modes, but I didn’t 52So I started. I knew that I wanted to have the couple of modes, but I didn’t
52like the repetition of keystrokes, so the only option was to have some sort of 53like the repetition of keystrokes, so the only option was to have some sort of
53toggle and indicate to the user that they are in a special mode. Like Vi does 54toggle and indicate to the user that they are in a special mode. Like Vi does
54for Normal and Visual mode. 55for Normal and Visual mode.
55 56
56These modes would for the first version be: 57These modes would for the first version be:
57 58
58- *Preview mode* (toggle with Ctrl + P) 59- *Preview mode* (toggle with Ctrl + P)
59 - When this mode would be enabled, the `ls` command would try to find images 60 - When this mode would be enabled, the `ls` command would try to find images
60 from the results and display thumbnails from them in the terminal itself. 61 from the results and display thumbnails from them in the terminal itself.
61 No ASCII art. Proper images. In a grid! 62 No ASCII art. Proper images. In a grid!
62- *Detach mode* (toggle with Ctrl + D) 63- *Detach mode* (toggle with Ctrl + D)
63 - When this mode would be enabled, every command would open a new window 64 - When this mode would be enabled, every command would open a new window
64 and execute that command in it. This would be useful for starting `htop` 65 and execute that command in it. This would be useful for starting `htop`
65 in a separate window. 66 in a separate window.
66 67
67The reason for having these modes togglable is to not ask for previews every 68The reason for having these modes togglable is to not ask for previews every
68time. You enable a mode and until you disable it, it behaves that way. 69time. You enable a mode and until you disable it, it behaves that way. Purely
69Purely out of ergonomic reasons. 70out of ergonomic reasons.
70 71
71I would like to treat every terminal I open as a session mentally. When I start 72I would like to treat every terminal I open as a session mentally. When I start
72using the terminal, I start digging deeper into the issue I am trying to resolve. 73using the terminal, I start digging deeper into the issue I am trying to
73And while I am doing this, I would like to open detached windows etc. A lot of 74resolve. And while I am doing this, I would like to open detached windows
74these things can be done easily with something like [i3](https://i3wm.org/), 75etc. A lot of these things can be done easily with something like
75but also that pull you out of the context of what you were doing. I would 76[i3](https://i3wm.org/), but also that pull you out of the context of what you
76like to orchestrate everything from one single point. 77were doing. I would like to orchestrate everything from one single point.
77 78
78In planning for this project, I knew that I would need to use a language like 79In planning for this project, I knew that I would need to use a language like C
79C and a library such as [SDL2](https://www.libsdl.org/) in order to achieve 80and a library such as [SDL2](https://www.libsdl.org/) in order to achieve the
80the desired results. I had considered other options, but ultimately determined 81desired results. I had considered other options, but ultimately determined that
81that [SDL2](https://www.libsdl.org/) was the best fit based on its capabilities 82[SDL2](https://www.libsdl.org/) was the best fit based on its capabilities and
82and reputation in the programming community. 83reputation in the programming community.
83 84
84At first, I thought the idea of a hardware accelerated terminal was a bit of 85At first, I thought the idea of a hardware accelerated terminal was a bit of a
85a joke. It seemed like such a niche and unnecessary feature, especially given 86joke. It seemed like such a niche and unnecessary feature, especially given the
86the fact that terminal emulators have been around for decades and have always 87fact that terminal emulators have been around for decades and have always relied
87relied on software rendering. But to be fair, [Alacritty](https://alacritty.org/) 88on software rendering. But to be fair, [Alacritty](https://alacritty.org/) is
88is doing the same thing. Well, they are doing a remarkable job at it. 89doing the same thing. Well, they are doing a remarkable job at it.
89 90
90So, I embarked on a journey. Everything has to start somewhere. For me, it 91So, I embarked on a journey. Everything has to start somewhere. For me, it
91started with creating a window! It has to start somewhere. 🙂 92started with creating a window! It has to start somewhere. 🙂
92 93
93```c 94```c
@@ -101,28 +102,31 @@ SDL_Window *window = SDL_CreateWindow(
101 102
102I continued like this to get some text displayed on the screen. 103I continued like this to get some text displayed on the screen.
103 104
104I noted that [`TTF_RenderText_Solid`](https://wiki.libsdl.org/SDL_ttf/TTF_RenderText_Solid) 105I noted that
105rendered text really poorly. There were no antialiasing at all. In my wisdom, 106[`TTF_RenderText_Solid`](https://wiki.libsdl.org/SDL_ttf/TTF_RenderText_Solid)
106I never checked the documentation. Well, that was a fail. To uneducated like 107rendered text really poorly. There were no antialiasing at all. In my wisdom, I
107me: `TTF_RenderText_Solid` renders Latin1 text at fast quality to a new 8-bit 108never checked the documentation. Well, that was a fail. To uneducated like me:
109`TTF_RenderText_Solid` renders Latin1 text at fast quality to a new 8-bit
108surface. So, that's why the texts looked like shit. No wonder. 110surface. So, that's why the texts looked like shit. No wonder.
109 111
110Remarks on `TTF_RenderText_Solid`: This function will allocate a new 8-bit, 112Remarks on `TTF_RenderText_Solid`: This function will allocate a new 8-bit,
111palettized surface. The surface's 0 pixel will be the colorkey, giving a 113palettized surface. The surface's 0 pixel will be the colorkey, giving a
112transparent background. The 1 pixel will be set to the text color. 114transparent background. The 1 pixel will be set to the text color.
113 115
114After I replaced it with [`TTF_RenderText_LCD`](https://wiki.libsdl.org/SDL_ttf/TTF_RenderText_LCD) 116After I replaced it with
115which renders Latin1 text at LCD subpixel quality to a new ARGB surface, the 117[`TTF_RenderText_LCD`](https://wiki.libsdl.org/SDL_ttf/TTF_RenderText_LCD) which
116text started looking good. Really make sure you read the documentation. It’s 118renders Latin1 text at LCD subpixel quality to a new ARGB surface, the text
117actually good. As a side note, you can find all the documentation regarding 119started looking good. Really make sure you read the documentation. It’s actually
118[SDL2 on their Wiki](https://wiki.libsdl.org/). 120good. As a side note, you can find all the documentation regarding [SDL2 on
119 121their Wiki](https://wiki.libsdl.org/).
120After that was done, I started working on displaying other things like 122
121`Preview` and `Detach` modes. This wasn’t really that hard. In SDL2 you can 123After that was done, I started working on displaying other things like `Preview`
122check all the available events with `while (SDL_PollEvent(&event) > 0)` and 124and `Detach` modes. This wasn’t really that hard. In SDL2 you can check all the
123have a bunch of switch statements to determine which key is currently being 125available events with `while (SDL_PollEvent(&event) > 0)` and have a bunch of
124pressed. More about keys, [SDLKey](https://documentation.help/SDL/sdlkey.html) 126switch statements to determine which key is currently being pressed. More about
125and mroe about pooling the events on [SDL_PollEvent](https://documentation.help/SDL/sdlpollevent.html). 127keys, [SDLKey](https://documentation.help/SDL/sdlkey.html) and mroe about
128pooling the events on
129[SDL_PollEvent](https://documentation.help/SDL/sdlpollevent.html).
126 130
127```c 131```c
128while (SDL_PollEvent(&event) > 0) 132while (SDL_PollEvent(&event) > 0)
@@ -144,9 +148,9 @@ while (SDL_PollEvent(&event) > 0)
144} 148}
145``` 149```
146 150
147After that was somewhat working correctly, I started creating a struct that 151After that was somewhat working correctly, I started creating a struct that
148would hold all the commands and results and I call them Cells. Yes, I stole 152would hold all the commands and results and I call them Cells. Yes, I stole that
149that naming idea from Jupyter. 153naming idea from Jupyter.
150 154
151```c 155```c
152typedef struct 156typedef struct
@@ -159,13 +163,15 @@ typedef struct
159} Cell; 163} Cell;
160``` 164```
161 165
162I am at a place now where I am starting to implement scrolling. This will for 166I am at a place now where I am starting to implement scrolling. This will for
163sure be fun to code. Memory management in C is super easy. 😂 167sure be fun to code. Memory management in C is super easy. 😂
164 168
165I have also added a simple [INI file like configuration](https://en.wikipedia.org/wiki/INI_file) 169I have also added a simple [INI file like
166support. It is done in an [STB style of header](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) 170configuration](https://en.wikipedia.org/wiki/INI_file) support. It is done in an
167and maps to specific options supported by the terminal. It is not universal, 171[STB style of
168and the code below demonstrates how I will use it in the future. 172header](https://github.com/nothings/stb/blob/master/docs/stb_howto.txt) and maps
173to specific options supported by the terminal. It is not universal, and the code
174below demonstrates how I will use it in the future.
169 175
170```c 176```c
171#ifndef CONFIG_H 177#ifndef CONFIG_H
@@ -239,8 +245,8 @@ extern Config read_config_file(const char *filename)
239#endif 245#endif
240``` 246```
241 247
242This is as far as I managed to get for now. I have a daily job and this 248This is as far as I managed to get for now. I have a daily job and this
243prohibits me to work on these things full time. But I should probably get 249prohibits me to work on these things full time. But I should probably get back
244back and finish this. At least have a simple version working out, so I can 250and finish this. At least have a simple version working out, so I can start
245start testing it on my machines. Fingers crossed. 🕵️‍♂️ 251testing it on my machines. Fingers crossed. 🕵️‍♂️
246 252