Use the right kind of quotes
Build and (eventually) deploy / Check if website builds (pull_request) Successful in 49s Details
Build and (eventually) deploy / Deploy to Fly.io (pull_request) Has been skipped Details

https://practicaltypography.com/straight-and-curly-quotes.html
https://practicaltypography.com/apostrophes.html

Please pay for his book.
Tudor Roman 2024-04-05 20:50:08 +02:00
parent bfaa63acc3
commit 42403c25fe
Signed by: tudor
SSH Key Fingerprint: SHA256:3CwS9plgXBecpXImPGxDIaSktUXBejbV/zerZMqzzBk
8 changed files with 119 additions and 119 deletions

View File

@ -1,6 +1,6 @@
{
"site": {
"title": "tudor's website",
"title": "tudors website",
"description": "",
"siteName": "tudorr.ro",
"author": "Tudor Roman",

View File

@ -38,7 +38,7 @@
<header>
<h1 class="inline-block py-2 pt-5 text-4xl font-medium tracking-tight before:hidden">
<a class="no-underline hover:underline hover:decoration-4 hover:underline-offset-4"
href="/">tudor's website</a>
href="/">{{ site.title }}</a>
</h1>
<nav class="w-full pr-2 py-2 mb-3">
<ul class="flex flex-wrap divide-x-2 divide-current">

View File

@ -11,7 +11,7 @@ Welcome to my website! My name is Tudor, also known on some platforms as “tudo
<p class="mb-4">
This website is a collection of my thoughts and work, and I hope people can learn from it.
I learned so many things from the internet thanks to
other peoples' personal websites, not limited to software development, and I think that it would be nice of me to contribute back.
other peoples personal websites, not limited to software development, and I think that it would be nice of me to contribute back.
I think that keeping a blog is also a good exercise in writing and explaining your thoughts
to other people, which I find a very important skill that I want to improve.
</p>
@ -20,7 +20,7 @@ to other people, which I find a very important skill that I want to improve.
<p class="mb-2">
I think websites should be made with accessibility in mind,
and this one makes no exception. I want this website's content
and this one makes no exception. I want this websites content
to be easy to consume for everyone, to not cause dizziness
through unnecessary animations, and to allow assistive technologies to work properly.
Reader mode should also work properly in the major browsers, and the content
@ -28,8 +28,8 @@ should be easy to scrape, to be consumed in feed readers for example.
</p>
<p class="mb-4">
If you want to suggest ways to improve this site's accessibility,
please refer to the next section about contacting me. I'm open to improvement!
If you want to suggest ways to improve this sites accessibility,
please refer to the next section about contacting me. Im open to improvement!
</p>
<h2 class="text-2xl mb-4">Contact</h2>
@ -46,7 +46,7 @@ There are no analytics on this website. There are no cookies either.
</p>
<p class="mb-4">
The web server's access log saves your IP address and accessed URLs for each request,
The web servers access log saves your IP address and accessed URLs for each request,
for up to 26 weeks.
</p>
@ -58,9 +58,9 @@ for up to 26 weeks.
<p class="mb-2">
This website is a static website generated with <a href="https://lume.land/">Lume</a>.
It's running on <a href="https://fly.io">Fly.io</a>; it's simple, familiar technology:
Its running on <a href="https://fly.io">Fly.io</a>; its simple, familiar technology:
a container running <em>somewhere</em>.
You can find this website's code <a href="https://git.tudorr.ro/tudor/tudorr.ro">here</a>.
You can find this websites code <a href="https://git.tudorr.ro/tudor/tudorr.ro">here</a>.
</p>
<p class="mb-4">

View File

@ -9,63 +9,63 @@ tags:
url: "/blog/technical/2021/01/26/the-wayland-experience/"
---
[Wayland](https://wayland.freedesktop.org/) is the "new" (13 years old already) display server technology on Linux, which is supposed to replace
[Wayland](https://wayland.freedesktop.org/) is the “new” (13 years old already) display server technology on Linux, which is supposed to replace
the antiquated X11. It promises better security, performance, portability, everything, compared to X11, and
it sure does deliver, provided that you're not using [unsupported graphics cards](https://www.nvidia.com/).
it sure does deliver, provided that youre not using [unsupported graphics cards](https://www.nvidia.com/).
You can watch [this talk / rant about X11](https://www.youtube.com/watch?v=RIctzAQOe44) to get an idea about how bad it is.
Some power users also haven't switched to Wayland because their window manager doesn't have a
Wayland equivalent (XMonad, Awesome, Bspwm and the others, all having their unique feature-set). Some may wonder "hmm maybe I can port it myself". I wrote this post to make you (re)consider that.
Some power users also havent switched to Wayland because their window manager doesnt have a
Wayland equivalent (XMonad, Awesome, Bspwm and the others, all having their unique feature-set). Some may wonder “hmm maybe I can port it myself”. I wrote this post to make you (re)consider that.
One of the main ideas of Wayland is that it's merely a specialised IPC protocol, and the communication is
One of the main ideas of Wayland is that its merely a specialised IPC protocol, and the communication is
strictly between the clients (applications on your screen mainly) and the server.
The server is what we are interested in now. Unlike X11, where the server is X.Org and the window manager
is just an X11 client with special privileges, on Wayland the window manager is also a server and a compositor. In fact, the correct terminology is "Wayland compositor". This piece of software has the
is just an X11 client with special privileges, on Wayland the window manager is also a server and a compositor. In fact, the correct terminology is “Wayland compositor”. This piece of software has the
task of doing everything it wants with the clients, which is usually among the lines of showing them
on the screen and giving them inputs events from your keyboards, mice, touchscreens etc. In fact, [no one
stops you from leaving window management as an API](https://mir-server.io/).
On my laptop, I prefer using GNOME under Wayland, because it has the most stable, fully-featured and "just works"
On my laptop, I prefer using GNOME under Wayland, because it has the most stable, fully-featured and “just works”
experience there is. However, I wanted a better way of organising windows on my screen than leaving them
shuffled around. Tiling was also not good, because every time you launch a new window, the others get
shrunk to fit, which is not good on a small laptop display.
Luckily I discovered [PaperWM](https://github.com/paperwm/PaperWM). It's perfect for laptops, instead of
Luckily I discovered [PaperWM](https://github.com/paperwm/PaperWM). Its perfect for laptops, instead of
shrinking your windows, it just renders them off-screen. To switch between one or the other you can just
flick three fingers on the touchpad. It's great. It's also "glossy" and polished and has great UI and animations.
flick three fingers on the touchpad. Its great. Its also “glossy” and polished and has great UI and animations.
It has some disadvantages though, mainly concerning its speed. I find it sluggish, and it's no surprise that
like all other GNOME Shell extensions, it's a JavaScript behemoth. PaperWM still uses the GNOME Tweener
It has some disadvantages though, mainly concerning its speed. I find it sluggish, and its no surprise that
like all other GNOME Shell extensions, its a JavaScript behemoth. PaperWM still uses the GNOME Tweener
framework for its animations, which is entirely written in JS. Because of that, it needs to communicate with the main
GNOME compositor process on each operation. And because we're talking animations, said operations happen
for *every frame*. That means there is JS executed for every frame, 60 times a second. It's horrible!
GNOME compositor process on each operation. And because were talking animations, said operations happen
for *every frame*. That means there is JS executed for every frame, 60 times a second. Its horrible!
BTW nowadays GNOME uses animations implemented in C (since GNOME 3.34), the "GNOME runs JS on every frame" statement is for the most part false today.
BTW nowadays GNOME uses animations implemented in C (since GNOME 3.34), the “GNOME runs JS on every frame” statement is for the most part false today.
Because of the inefficiency of PaperWM, it also means that it drains my battery quickly, which is bad for a laptop!
So, because I am a student with a lot of free time, together with [Alex](https://alexge50.com/) we figured we shall develop a scrollable tiling (PaperWM-like) Wayland compositor. It's called [Cardboard](https://gitlab.com/cardboardwm/cardboard) (get it??). It also has the nicety of
So, because I am a student with a lot of free time, together with [Alex](https://alexge50.com/) we figured we shall develop a scrollable tiling (PaperWM-like) Wayland compositor. Its called [Cardboard](https://gitlab.com/cardboardwm/cardboard) (get it??). It also has the nicety of
being controlled and configured by a remote control program, like bspwm.
Neither Alex nor I had experience with any kind of Wayland development. However, I wrote [an X11 window manager](https://tudorr.ro/software/windowchef/),
[some XRandR querying utilities](https://github.com/tudurom/disputils/) and [a window rule daemon](https://github.com/tudurom/ruler). Alex has experience
with [graphics programming](https://git.alexge50.com/a/gie) and [C++ devilry](https://github.com/alexge50/libwatchpoint).
Our "tech stack" was [wlroots](https://github.com/swaywm/wlroots), which is an exceptional Wayland compositor library (apart from its lack of documentation). The description from the README is spot on:
Our “tech stack” was [wlroots](https://github.com/swaywm/wlroots), which is an exceptional Wayland compositor library (apart from its lack of documentation). The description from the README is spot on:
>About 50,000 lines of code you were going to write anyway.
I (because I wrote most of the Wayland-interfacing code) realised soon that there is still a lot of boilerplate involved in writing a compositor, much more than for an X11 window manager,
namely setting up your own rendering code, registering and storing input devices and screens in your own data structures, passing input events to windows, calculating bounds for bars
and other overlays (courtesy of [`layer-shell`](https://github.com/swaywm/wlr-protocols/blob/master/unstable/wlr-layer-shell-unstable-v1.xml)) and others. X11 handles all of this for you,
the window manager just reacts to events regarding window inputs to establish its behaviour. With Wayland, you handle everything, even with wlroots. The upside is that if you don't like the way X11 does something
the window manager just reacts to events regarding window inputs to establish its behaviour. With Wayland, you handle everything, even with wlroots. The upside is that if you dont like the way X11 does something
(which is a given), not only that you can do it in your own way on Wayland, you are required to do so.
Because we weren't really prepared for what writing a compositor involved, we thought that it must be approached like a "normal" program: split code into modules, each with their own responsibilities, call wlroots to do its thing, the usual stuff.
We are writing a program in our way and wlroots lets us "interface with Wayland". Or so we thought.
Because we werent really prepared for what writing a compositor involved, we thought that it must be approached like a “normal” program: split code into modules, each with their own responsibilities, call wlroots to do its thing, the usual stuff.
We are writing a program in our way and wlroots lets us “interface with Wayland”. Or so we thought.
We were as careful as possible to separate responsibilities into different structures / classes, yet we ended up with most functions taking a pointer to `Server` as their first parameter.
`Server` is a singleton holding all the other "sub-modules" in it. It represents the compositor itself. The reason most functions need `Server` is that everything is related to everything,
`Server` is a singleton holding all the other “sub-modules” in it. It represents the compositor itself. The reason most functions need `Server` is that everything is related to everything,
not because of a mistake in structuring the code, but by design. This is what a compositor requires, the problem of writing a compositor is somewhat complex because it has a great deal variables ranging
from input events, drawing on the screen, creating behaviours that the user leverages, reacting to application events. All of them can affect the other, you can not separate the thing into modules.
The best you can do is separate the code in different files and folders based on some criteria, like grouping data structures with related routines.
@ -119,7 +119,7 @@ OptionalRef<Workspace> get_focused_workspace(Server& server);
void focus(Server& server, Workspace& workspace); // TODO: yikes, passing Server*
```
As an example, let's take damage tracking. For starters, because the compositor is also tasked with rendering the content and displaying it on the screen, we have some rendering code that runs on every frame.
As an example, lets take damage tracking. For starters, because the compositor is also tasked with rendering the content and displaying it on the screen, we have some rendering code that runs on every frame.
Damage tracking is tracking which areas of the screen have changed in an amount of time. An example would
be typing a letter in the terminal. The place where the cursor is changes to the letter you typed, and the cursor advances.
If there is no change, the frame is not rendered, as it would look
@ -128,7 +128,7 @@ This way, instead of re-rendering everything 60 times a second (I assume that yo
You can read [an introduction to damage tracking](https://emersion.fr/blog/2019/intro-to-damage-tracking/) written by one of the main developers of wlroots.
I have just implemented the most basic form of damage tracking: do not render the frame if nothing on the screen changes.
It doesn't track the damage itself, just that it exists.
It doesnt track the damage itself, just that it exists.
To do this, I first added a `wlr_output_damage` object to my `Output` structure:
```diff
@ -153,8 +153,8 @@ void OutputManager::set_dirty()
This marks every output as entirely damaged, and as such triggers a render.
With this function set into place, I had to identify when does the "screen" change, namely when a window "commits" (changes its contents) and when a window is moved. The window move is one example
of the way everything is related to everything in the compositor. Before damage tracking, the `View::move()` (we call windows "views") method just changed the `x` and `y` fields of the `View` structures.
With this function set into place, I had to identify when does the “screen" change, namely when a window "commits” (changes its contents) and when a window is moved. The window move is one example
of the way everything is related to everything in the compositor. Before damage tracking, the `View::move()` (we call windows “views”) method just changed the `x` and `y` fields of the `View` structures.
Now, a move must call a method of `OutputManager`, so we need to give that as a parameter. This is almost like giving `Server` as a parameter, as `OutputManager` is a singleton inside `Server`.
```diff
@ -167,10 +167,10 @@ Now, a move must call a method of `OutputManager`, so we need to give that as a
}
```
That's when it hit me that wlroots is more of a framework and the compositor is one of its modules. Thinking that wlroots is an "interface to Wayland" is plain wrong, as the Wayland server is the
Thats when it hit me that wlroots is more of a framework and the compositor is one of its modules. Thinking that wlroots is an “interface to Wayland” is plain wrong, as the Wayland server is the
program that I am writing. The next refactor is going to make the `Server` instance global...
Now that we have a `wlr_output_damage` object in place and `set_dirty()` calls where they're needed, we only need to call the render function when `wlr_output_damage` tells us instead of
Now that we have a `wlr_output_damage` object in place and `set_dirty()` calls where theyre needed, we only need to call the render function when `wlr_output_damage` tells us instead of
every `1/60` seconds:
```diff
@ -192,20 +192,20 @@ every `1/60` seconds:
This is not complete code for a basic damage tracking implementation with wlroots. You can see [the whole commit here](https://gitlab.com/cardboardwm/cardboard/-/commit/f2ef2ff076ddbbd23994553b8eff131f9bd0207f).
This is an example of how wlroots provides yet another "module" that we can use in the grand scheme of the compositor. `wlr_output_damage` accumulates damaged rectangles in time and even turns these
numerous small rectangles into a big one as an optimisation. It also calls the frame handler when it's needed, and this is not only just when something on the screen changed, but also when the underlying "backend"
of the compositor changes. The simplest situation is when the compositor starts: it needs to render an initial frame so the screen isn't pitch black.
This is an example of how wlroots provides yet another “module” that we can use in the grand scheme of the compositor. `wlr_output_damage` accumulates damaged rectangles in time and even turns these
numerous small rectangles into a big one as an optimisation. It also calls the frame handler when its needed, and this is not only just when something on the screen changed, but also when the underlying “backend”
of the compositor changes. The simplest situation is when the compositor starts: it needs to render an initial frame so the screen isnt pitch black.
All in all, I do not recommend writing your own compositor if you only want some gimmicky user interface.
In the X world there is a WM for every single way of window tiling plus a couple more. It doesn't work like
In the X world there is a WM for every single way of window tiling plus a couple more. It doesnt work like
that with Wayland, you will spend more time implementing basic compositor duties than
on your compositor's unique features. Instead, if I were to rewrite Cardboard, I would rather do it
as a [Wayfire plugin](https://github.com/WayfireWM/wayfire/wiki/Plugin-architecture) or maybe as a KWin script. However, I think Wayfire is more "enthusiast-friendly", as it uses [protocols from
on your compositors unique features. Instead, if I were to rewrite Cardboard, I would rather do it
as a [Wayfire plugin](https://github.com/WayfireWM/wayfire/wiki/Plugin-architecture) or maybe as a KWin script. However, I think Wayfire is more “enthusiast-friendly”, as it uses [protocols from
wlroots](https://github.com/swaywm/wlr-protocols) such as `layer-shell` (for panels, overlays and backgrounds), `gamma-control` (for Redshift), `screencopy` (for screenshots) and others,
allowing people to write tools that are not specific to the compositor.
Nevertheless, if you want to do it for the learning experience, I definitely recommend writing
a "full-fledged" compositor with wlroots, learning from other compositors ([Sway][sway],
a “full-fledged” compositor with wlroots, learning from other compositors ([Sway][sway],
[cage][cage], [Wayfire][wayfire], [hikari][hikari] and others; cage is the simplest, hikari second simplest) and from their creators on
IRC (`#sway-devel` on Freenode), they are very kind and knowledgeable.
@ -220,12 +220,12 @@ Recommended lectures:
* [Writing a Wayland Compositor](https://drewdevault.com/2018/02/17/Writing-a-Wayland-compositor-1.html), by Drew DeVault, the author of Sway and wlroots
* [The Wayland Protocol Book](https://wayland-book.com/), also by Drew DeVault
* [The Wayland Protocol](https://wayland.freedesktop.org/docs/html/), the actual protocol (larger than the book)
* Posts from Simon Ser's blog, maintainer of Sway and wlroots:
* Posts from Simon Sers blog, maintainer of Sway and wlroots:
* [Writing a Wayland rendering loop](https://emersion.fr/blog/2018/wayland-rendering-loop/)
* [Introduction to damage tracking](https://emersion.fr/blog/2019/intro-to-damage-tracking/)
* [Wayland clipboard and drag & drop](https://emersion.fr/blog/2020/wayland-clipboard-drag-and-drop/)
* [The init routine of Wayfire](https://github.com/WayfireWM/wayfire/blob/cb7920187d2546ca375f00e7ef0a71d7a4995ba6/src/core/core.cpp#L173). GTK is rather picky when it comes to the order of advertised Wayland protocols.
Don't waste hours of your life trying to figure out whether you did something wrong, it's GTK...
Dont waste hours of your life trying to figure out whether you did something wrong, its GTK...
Also, I suggest you write the compositor in either C, C++ or Zig (with [zig-wlroots](https://github.com/swaywm/zig-wlroots) or just doing your thing, Zig is C compatible).
See this article on why the [Rust bindings failed](http://way-cooler.org/blog/2019/04/29/rewriting-way-cooler-in-c.html).

View File

@ -9,12 +9,12 @@ url: "/blog/technical/2023/10/12/modern-shell-tools/"
---
The standard UNIX command line tools are still enjoying a multi-decade-long reign,
whether we're talking about the bare-bones `echo` and `cat`, the familiar `ls`,
`date` and `cal` (I can't be the only one who's still using `cal`, right?),
whether were talking about the bare-bones `echo` and `cat`, the familiar `ls`,
`date` and `cal` (I cant be the only one whos still using `cal`, right?),
the weirdly-named text processing utilities `tr`, `sed`, `cut`, `grep` and
their main nemesis, `awk`, or the ubiquitous text editors, `vi` and the 30+ year old Vi IMproved.
Here are a couple "postmodern" CLI and TUI tools I like to use. They are mainly
Here are a couple “postmodern” CLI and TUI tools I like to use. They are mainly
alternatives to the well-established tools that try to take on trivial problems,
like string processing, finding files, looking for strings in files and so on.
@ -27,20 +27,20 @@ yet allowing for easy integration with other tools.
## fd
[fd's webpage](https://github.com/sharkdp/fd).
[fds webpage](https://github.com/sharkdp/fd).
I don't know about you but I cannot remember for the love of what's holy `find`'s flags.
It also grinds my gears heavily that it doesn't automatically ignore files declared in `.gitignore`,
although `find` was made when `git`'s creator was a toddler.
I dont know about you but I cannot remember for the love of whats holy `find`s flags.
It also grinds my gears heavily that it doesnt automatically ignore files declared in `.gitignore`,
although `find` was made when `git`s creator was a toddler.
`fd`, when supplied with an argument, does what you probably want to do most of the time
when looking for files in a directory: look for any files that contain a pattern in the filename.
And it does that with pretty colours! It respects `LS_COLORS` even, so the colours have meaning!
Another nicety is that it uses [Rust's regex library][regex-crate].
Another nicety is that it uses [Rusts regex library][regex-crate].
GNU Find offers many regex types, which can be quite confusing. Run `find -regextype help` to see them all.
Example usage, finding all Markdown files in the blog's source code repo:
Example usage, finding all Markdown files in the blogs source code repo:
```shell
$ fd .md$
@ -63,7 +63,7 @@ You can find it in your package manager probably: `rust-fd-find` in Fedora, Ubun
## sd
[sd's webpage](https://github.com/chmln/sd).
[sds webpage](https://github.com/chmln/sd).
`sd` is a lesser-known postmodern alternative to `sed`. It simplifies greatly the most common
use case for `sed` (to replace and extract data), and also uses Rust regexes (no more `sed -E`).
@ -72,13 +72,13 @@ The examples also show nice ways to use it together with `fd`.
Example usage:
```shell
# -f i stands for `flags: case insensitive'
# -f i stands for `flags: case insensitive
$ sd -f i emacs VIM file.txt
# sd does by default in-place substitution, so this will print nothing.
# we can do, however, the following
$ sd -f i -p emacs VIM file.txt
The original VIM did not have Lisp in it. The lower level language, the non-interpreted language—was PDP-10 Assembler.
The interpreter we wrote in that actually wasn't written for VIM, it was written for TECO.
The interpreter we wrote in that actually wasnt written for VIM, it was written for TECO.
```
_Text fragment taken from [here](https://www.gnu.org/gnu/rms-lisp.html)._
@ -90,9 +90,9 @@ This one is also available in the repositories of some popular distros: `rust-sd
## Helix
[Helix's webpage](https://github.com/helix-editor/helix).
[Helixs webpage](https://github.com/helix-editor/helix).
Currently my text editor of choice. It's a modal text editor, like {"{neo,}"}vim,
Currently my text editor of choice. Its a modal text editor, like {"{neo,}"}vim,
but it sacrificies extensibility (no plugin support!) for natively implementing
various niceties, such as:
@ -101,11 +101,11 @@ various niceties, such as:
* Nice command navigation: press space and see what other keys you can hit to do various things. Press, for example, `w` and you are presented window manipulation functions,
* Fuzzy file and buffer selector, and more.
It's also heavily inspired by [Kakoune][kak] in the way commands are used:
Its also heavily inspired by [Kakoune][kak] in the way commands are used:
first you press the key that selects the text object you operate on, and then the action (unlike Vim that does it in reverse).
So, if I want to change the next word, I'd press `wc`. After pressing `w`, the selection is also highlighted.
So, if I want to change the next word, Id press `wc`. After pressing `w`, the selection is also highlighted.
This one is not as widely-available in distro repositories (yet), but it's easy to install
This one is not as widely-available in distro repositories (yet), but its easy to install
if you happen to have the Rust toolset installed. [Repology][repology-helix].
[kak]: https://github.com/mawww/kakoune
@ -113,10 +113,10 @@ if you happen to have the Rust toolset installed. [Repology][repology-helix].
## Nushell
[Nushell's webpage](https://www.nushell.sh/).
[Nushells webpage](https://www.nushell.sh/).
I like to describe Nushell as "what if you take Powershell's object oriented everything approach, but you apply it to UNIX".
Instead of using objects, Nushell operates on tables made of records reminescent of JSON's data types.
I like to describe Nushell as “what if you take Powershells object oriented everything approach, but you apply it to UNIX”.
Instead of using objects, Nushell operates on tables made of records reminescent of JSONs data types.
You have mostly lists, key-value hash tables, numbers, strings, and booleans, plus a couple specific data types like
date, filesize, durations, but also ranges and closures.
@ -129,7 +129,7 @@ such as a help system that has syntax highlighted examples and example outputs (
a command search mode (after typing a pipe, you can press <kbd>F1</kbd> and a menu pops up with a command search and small help overview),
syntax highlighted commands as you type, and quite decent completion.
There aren't many completion definitions for all the other "normal" commands you may use,
There arent many completion definitions for all the other “normal” commands you may use,
but you can easily declare completers in your config, such as [using Fish as a completer][fish-as-completer].
Fish comes with stellar completion support, so now Nu does too!

View File

@ -20,7 +20,7 @@ which should allow me to use [LT<sub>E</sub>X][ltex] as an
a pretty decent spell and grammar checker.
Jens Getreu [wrote an article about it][helix-lt], among a couple other things.
But that's too much work, and I'm very prone to [yak shaving][xkcd-success]!
But thats too much work, and Im very prone to [yak shaving][xkcd-success]!
## The actual hack

View File

@ -2,7 +2,7 @@
title: "Zoomer Tries RSS: In Praise of Yarr"
excerpt: >-
Yarr is, according to its GitHub page, “yet another rss reader”.
But I think this description doesn't do it justice.
But I think this description doesnt do it justice.
date: 2024-04-04 14:22:58+02:00
category: technical
tags:
@ -15,15 +15,15 @@ tags:
[yarr]: https://github.com/nkanaev/yarr
[Yarr][yarr] is, according to its GitHub page, <q>yet another rss reader</q>.
But I think this description doesn't do it justice.
But I think this description doesnt do it justice.
I started using a feed reader less than half a year ago, to easily keep track
of new content I enjoy on the internet without depending on social media.
Web feeds are, in 2024 terms, old technology: according to the [RSS Advisory Board][rss-board],
RSS, one of the main web feed formats available, has been published in 1999, and it's not
RSS, one of the main web feed formats available, has been published in 1999, and its not
even the first web syndication format ever made.
I'm a [Gen Z-er][gen-z]: I was a toddler when RSS reached its 2.0 milestone,
Im a [Gen Z-er][gen-z]: I was a toddler when RSS reached its 2.0 milestone,
and when Apple popularised RSS for podcasts [by adding support in iTunes][itunes-rss].
I was in middle school when Google Reader was shut down. When I started using the internet
by myself, it was already dominated by social media, which is still the dominant
@ -34,7 +34,7 @@ source of information for many people around me, younger and older alike.
[itunes-rss]: https://www.macworld.com/article/176125/podcastingfirstlook.html
Getting all my information from social media got really tiring; I was using Reddit mostly,
and a carefully curated set of information-oriented Instagram profiles &mdash; so nice to read pictures of text! I didn't really like wasting my time doom-scrolling
and a carefully curated set of information-oriented Instagram profiles &mdash; so nice to read pictures of text! I didnt really like wasting my time doom-scrolling
instead of doing other things that could generate some creative output &mdash; like
writing on this blog, maybe &mdash; or
doing some fun coding. Or maybe I could tidy up my kitchen, read a book and actually learn
@ -47,68 +47,68 @@ the subreddit I want to read, scroll a bit, and then become very frustrated wit
which is totally not intentionally bad to make you download the mobile app.
Not only that, but I also change the URL to `old.reddit.com` when needed (even harder when doing it on my phone&hellip;).
And then I only read without ever logging in, which is why using Old Reddit is a requirement.
You can easily see that it's not the best reading experience for the web.
You can easily see that its not the best reading experience for the web.
With this in mind, I remembered RSS and feeds are a thing, so I figured I should set up a reader.
I've never used one before, but the concept sounded promising: I can subscribe to blogs and news outlets, directly!
Ive never used one before, but the concept sounded promising: I can subscribe to blogs and news outlets, directly!
I had three requirements for choosing one:
* Simple, non-distracting UI.
* Has some kind of feature to extract relevant content from web pages &mdash; many feeds truncate the content.
* Doesn't require me to do any kind of syncing when using multiple devices to read (laptop and phone). A self-hosted web app should be fine.
* Doesnt require me to do any kind of syncing when using multiple devices to read (laptop and phone). A self-hosted web app should be fine.
## First try: Feeder
[Feeder][feeder] is a pretty Android app, it implements the newest [Material 3][material-3] design language, and it's generally very pleasant to use.
[Feeder][feeder] is a pretty Android app, it implements the newest [Material 3][material-3] design language, and its generally very pleasant to use.
It definitely satisfies the first requirement. And it knows how to extract the content from a web page, very nice!
Unfortunately, it's only for your phone. If you want to change your reader app, it does support importing and exporting OPML files; that is pretty sweet,
but I don't want to be tied to my phone to read the news and the blogs I want to follow.
Unfortunately, its only for your phone. If you want to change your reader app, it does support importing and exporting OPML files; that is pretty sweet,
but I dont want to be tied to my phone to read the news and the blogs I want to follow.
[feeder]: https://f-droid.org/packages/com.nononsenseapps.feeder/
[material-3]: https://m3.material.io/
## Second try: Miniflux
[Miniflux][miniflux] is what I've been using up until I discovered Yarr, actually. It's wonderful software: it's a web application, very easy to self-host, and it's [quite featureful][miniflux-features].
It has a very simple UI (some might say “arcane”), stays out of your way, no useless spacing, readable, accessible, it's just great.
[Miniflux][miniflux] is what Ive been using up until I discovered Yarr, actually. Its wonderful software: its a web application, very easy to self-host, and its [quite featureful][miniflux-features].
It has a very simple UI (some might say “arcane”), stays out of your way, no useless spacing, readable, accessible, its just great.
Looks similar to [Lobsters][lobsters] and [sourcehut][sourcehut], I really like this style. It even has the required manifests to make it a Progressive Web App,
making it look like an app on your phone. It's just an all-around pleasant experience to use Miniflux.
making it look like an app on your phone. Its just an all-around pleasant experience to use Miniflux.
[miniflux]: https://miniflux.app/
[miniflux-features]: https://miniflux.app/features.html
[lobsters]: https://lobste.rs/
[sourcehut]: https://sourcehut.org/
Being written in Go, it's very easy to self-host: the program is just a single statically-linked executable. I run [NixOS][nixos] on my server, and I was very delighted to see
Being written in Go, its very easy to self-host: the program is just a single statically-linked executable. I run [NixOS][nixos] on my server, and I was very delighted to see
that [there is a module for Miniflux in Nixpkgs][nixpkgs-miniflux]. Very easy to set it up and integrate it in my setup.
[nixos]: https://nixos.org/
[nixpkgs-miniflux]: https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/web-apps/miniflux.nix
I have one big gripe with Miniflux, though: it only supports PostgreSQL, though [very understandably so][miniflux-postgres].
It's much easier to support a single configuration, a very respectable one in this case.
Miniflux also has a commercial offering, so it shouldn't come as a surprise that it's in its best interest to have a well-tested and reliable storage layer.
Its much easier to support a single configuration, a very respectable one in this case.
Miniflux also has a commercial offering, so it shouldnt come as a surprise that its in its best interest to have a well-tested and reliable storage layer.
[miniflux-postgres]: https://miniflux.app/opinionated.html#postgresql
It's just that I prefer having as many services as possible use SQLite when it comes to my self-hosted services. One of the main downsides
of self-hosting is that you have to take care of your own services &mdash; who would've thought! I really, really don't want to take care of a PostgreSQL
cluster, even if it's a single-node one. You might argue that it's just one node, what's to be taken care of? Identity maps, backups, authentication&hellip;
I can just use SQLite, have all my data in one file (per service), you cannot access it remotely, so that's covered,
Its just that I prefer having as many services as possible use SQLite when it comes to my self-hosted services. One of the main downsides
of self-hosting is that you have to take care of your own services &mdash; who wouldve thought! I really, really dont want to take care of a PostgreSQL
cluster, even if its a single-node one. You might argue that its just one node, whats to be taken care of? Identity maps, backups, authentication&hellip;
I can just use SQLite, have all my data in one file (per service), you cannot access it remotely, so thats covered,
backups are a one-line command (`sqlite3 db.sqlite ".backup db.sqlite.bak"`), and the only authentication and authorisation is in the file system permissions.
I don't even have to think about *what needs to be taken care of*, there isn't really anything I need to worry about!
Of course, serious usage should make me worried about the throughput, write blocking, cache sizes, journal modes and so on. But at my scale, that's not really an issue.
It reduces the cognitive complexity, let's put it this way.
I dont even have to think about *what needs to be taken care of*, there isnt really anything I need to worry about!
Of course, serious usage should make me worried about the throughput, write blocking, cache sizes, journal modes and so on. But at my scale, thats not really an issue.
It reduces the cognitive complexity, lets put it this way.
The less I need to think about things when self-hosting<br/>
&rarr; The easier it is to self-host<br/>
&rarr; The more satisfied I am<br/>
&rarr; The more I am encouraged to keep on doing it!
It's the same as: the cleaner and well-stocked my kitchen is, the more I am encouraged to cook and eat healthy.
Its the same as: the cleaner and well-stocked my kitchen is, the more I am encouraged to cook and eat healthy.
The sharper my knives, the more I enjoy cutting onions.
Hence, sorry PostgreSQL, but I don't want you here. If this is not a problem for you, then I strongly encourage you to give Miniflux a try.
Hence, sorry PostgreSQL, but I dont want you here. If this is not a problem for you, then I strongly encourage you to give Miniflux a try.
Which brings me to&hellip;
@ -118,8 +118,8 @@ Which brings me to&hellip;
desc="A screenshot of my Yarr instance, showing some websites I follow and some posts from samwho.dev" />
[Yarr][yarr] is, in some regards, even more minimalistic than Miniflux.
It doesn't provide fancy integrations, it doesn't support multiple users (it does support authentication, though).
It doesn't do much, really.
It doesnt provide fancy integrations, it doesnt support multiple users (it does support authentication, though).
It doesnt do much, really.
But what it does, it does well. And it has a couple of niceties, such as the possibility to change
the auto-refresh interval &mdash; or disable it altogether &mdash;
@ -127,7 +127,7 @@ or to switch between the predefined colour palettes.
There are also some keyboard shortcuts, and the ability to save (star ⭐️) articles for later.
It has a small search box, too.
What I find to be the best feature, though, is the UI: it's simple, yet it looks good.
What I find to be the best feature, though, is the UI: its simple, yet it looks good.
And on a large enough screen, it has this three-column layout, with the feeds, articles, and
article view columns, really nice for reading the news. Yet, if your screen &mdash; or browser window &mdash; is smaller, it
will switch to a one-column layout. I find it clean and practical, and I like its choice of
@ -135,15 +135,15 @@ icons. It also has a couple dynamic elements, just enough to enhance it and not
For example, when you manually refresh the feeds, it shows the progress in the bottom-left corner,
together with a little animated spinner. And when you add a new feed, in the event that it finds multiple
feeds for the same websites, it will present the choices in the same “Add feed” modal.
It's completely a single-page application, unlike Miniflux, which is the opposite: Miniflux
is a completely server-side application. And I'm usually against that, but in the case of Yarr,
there isn't any “routing”, there aren't different screens, it's just one large feed-reading window,
Its completely a single-page application, unlike Miniflux, which is the opposite: Miniflux
is a completely server-side application. And Im usually against that, but in the case of Yarr,
there isnt any “routing”, there arent different screens, its just one large feed-reading window,
and the dynamic elements only enhance the interaction.
I have even more appreciation for the developer for publishing [this text file][yarr-rationale]
in the repo with the rationale behind Yarr and the sources of inspiration for the user interface.
It would be great if more people did this, to get a small glimpse of what they were thinking
of when they started a project. The message of the commit that added this file is <q>let's be honest</q>, nice touch.
of when they started a project. The message of the commit that added this file is <q>lets be honest</q>, nice touch.
[yarr-rationale]: https://github.com/nkanaev/yarr/blob/master/doc/rationale.txt
@ -151,7 +151,7 @@ Yarr is a bit stuck in time: the author claims that the software is complete,
that it fulfils all their expectations, and that no pull requests with new features will be merged.
I think this is good for a feed reader: it does what it says on the tin, without burdening
anyone with maintaining the program, and without burdening users with upgrades, config changes and the like.
There isn't much to be done, it just works; I applaud the lack of feature creep.
There isnt much to be done, it just works; I applaud the lack of feature creep.
Contrast this to Miniflux, which is an actively maintained and updated project, with many features (not a bad thing!).
Yarr can also be used as a desktop application: it supports being launched from the system tray, of all things.
@ -163,20 +163,20 @@ And when it comes to storage, everything is stored in a single SQLite database.
There are no other data folders kept around, just that sole database file containing all the state. (This might be a con if you care about cross-compiling the binary, or if anything else breaks because of cgo. Use of cgo is required,
because SQLite is written in C, and is embedded in programs directly by linking to its shared library. Read: [cgo is not Go](https://dave.cheney.net/2016/01/18/cgo-is-not-go).)
I love it so much, it's one of my favourite programs I use on a daily basis.
Open-source, useful, easy to self-host, easy to use, works with a mouse, works with a keyboard, works with a touchscreen. I don't have to think about it.
I love it so much, its one of my favourite programs I use on a daily basis.
Open-source, useful, easy to self-host, easy to use, works with a mouse, works with a keyboard, works with a touchscreen. I dont have to think about it.
And whenever I'm thinking of it, it's always out of gratefulness. This is the most I can wish
And whenever Im thinking of it, its always out of gratefulness. This is the most I can wish
from software, in my opinion.
It's not as well-known, if judging by the number of stars on GitHub, which might be part of the reason for why there isn't already a ready-made module for NixOS.
Its not as well-known, if judging by the number of stars on GitHub, which might be part of the reason for why there isnt already a ready-made module for NixOS.
Luckily, I made my own, [which is available on Codeberg][yarr-nix].
[yarr-nix]: https://codeberg.org/tudor/yarr-nix
All in all, I think switching to feed readers has brought a net improvement in my quality of life, when it
comes to consuming information. If Yarr sounds compelling to you, I suggest you give it a try.
You don't have to self-host it, you can just grab a binary release from GitHub and run it locally.
You dont have to self-host it, you can just grab a binary release from GitHub and run it locally.
## Appendix: The Feeds I Follow
@ -185,7 +185,7 @@ You don't have to self-host it, you can just grab a binary release from GitHub a
[Hacker News Daily][hn-daily]: This is a feed containing the ten highest-rating articles on Hacker News which have not appeared on previous daily digests. I read HN from time to time, but the volume of submissions it receives is too high for me,
thus I prefer visiting the website directly.
My favourite link aggregator is [Lobsters][lobsters], yet I don't have it in my feed reader, because I prefer just browsing
My favourite link aggregator is [Lobsters][lobsters], yet I dont have it in my feed reader, because I prefer just browsing
the website directly.
[hn-daily]: http://www.daemonology.net/hn-daily/
@ -207,21 +207,21 @@ Various blogs I enjoy reading. At the time of writing this article, in no partic
* **samwho.dev**: https://samwho.dev
* **The Copetti site**: https://www.copetti.org
* **tonsky.me**: https://tonsky.me
* **Winny's Blog**: https://blog.winny.tech
* **Winnys Blog**: https://blog.winny.tech
* **Xesite**: https://xeiaso.net
### Comics
I only follow [xkcd](https://xkcd.com). I haven't found other comics I would enjoy reading, yet.
I only follow [xkcd](https://xkcd.com). I havent found other comics I would enjoy reading, yet.
### The News
I use my feed reader to read both Dutch news &mdash; I live here, and it's very good language immersion &mdash;
and Romanian news, to keep an eye on what's going on there.
I use my feed reader to read both Dutch news &mdash; I live here, and its very good language immersion &mdash;
and Romanian news, to keep an eye on whats going on there.
Dutch:
* [AT5 Achtergrond][at5-achtergrond]: AT5 is a local news outlet. I'm glad that they offer separate RSS feeds for each category on their website, so that I can only follow the investigations.
* [AT5 Achtergrond][at5-achtergrond]: AT5 is a local news outlet. Im glad that they offer separate RSS feeds for each category on their website, so that I can only follow the investigations.
* [NOS][nos] Algemeen: General news from the public broadcasting system. The [online Teletext][nos-teletekst] (“Teletekst”) is the best, in my opinion, for getting a quick look at the news.
* [NOS op 3][nos-op3]: Mostly targeted at younger people, the NOS also makes nice explainer videos for various events happening in and out the country. They also make explainer apps, [such as this one about the electricity network][nos-stroomnet].
@ -233,16 +233,16 @@ Dutch:
As you can see, I mostly read news from the public service.
For investigative journalism and more detailed stories,
I prefer purchasing magazines and newspapers. It's always nice to read from paper!
I prefer purchasing magazines and newspapers. Its always nice to read from paper!
Romanian:
* [PressOne][pressone]: Investigative journalism
* [Rise Project][rise] (link in English): Investigative journalism, focused on organised crime and corruption.
I had to be careful when adding this one into Yarr, because the meta tags on the website's front page lead to the feed for their blog. To get the investigations feed, I fed Yarr with the web page containing all articles categorised with “investigation”.
I had to be careful when adding this one into Yarr, because the meta tags on the websites front page lead to the feed for their blog. To get the investigations feed, I fed Yarr with the web page containing all articles categorised with “investigation”.
* [Recorder][recorder-english] (link in English): Investigative journalism, again&hellip; They have really nice videos on their website and YouTube channel.
I am a bit of the opinion that they have a slight tendency to be negativistic and pessimstic, but their materials generally tend to be quite good.
* [Buletin de București][buletin]: The Bucharest Bulletin. Local publication, I like seeing what's going on there.
* [Buletin de București][buletin]: The Bucharest Bulletin. Local publication, I like seeing whats going on there.
The website has a funny address.
[rise]: https://riseproject.ro/en/
@ -260,8 +260,8 @@ You should be able to just paste a YouTube channel in any reader, and it should
Currently, I only follow [Ars Technica][ars] and [Teletext][tltxt] (not to be confused with the NOS Teletext).
Teletext is, according to their website, <q>the newest platform dedicated to pop culture in Romania</q>.
I'm more of a technical person, I don't have all the cultural knowledge Teletext's authors do,
yet I really love reading their articles, precisely because it's all new and different to me.
Im more of a technical person, I dont have all the cultural knowledge Teletexts authors do,
yet I really love reading their articles, precisely because its all new and different to me.
[ars]: https://arstechnica.com
[tltxt]: https://tltxt.ro
@ -275,7 +275,7 @@ I personally use dedicated apps for podcasts like [GNOME Podcasts][gnome-podcast
[antennapod]: https://antennapod.org/
I also have a recipe website in there which I really like, [RecipeTin Eats][recipetin].
Of course the best way to cook is to train your intuition and just make something you'd fancy with the ingredients you have,
but it's always good to get some inspiration from time to time, which is the reason why I have it in my feed reader.
Of course the best way to cook is to train your intuition and just make something youd fancy with the ingredients you have,
but its always good to get some inspiration from time to time, which is the reason why I have it in my feed reader.
[recipetin]: https://recipetineats.com

View File

@ -103,7 +103,7 @@ export default () => {
I was part of the judging committee for the most important software development competition
for high school students in Romania. Together with the other members of the judging team,
I evaluated the participants' software projects, and helped them with constructive feedback
I evaluated the participants software projects, and helped them with constructive feedback
and tips for their future projects.
</DtEvent>