Log in
Seblog.nl

Alles

Vandaag is er een reünie op de plek waar ik mijn eerste biertje dronk. Nu drink ik 0.0, want ik moet nog rijden. Mijn gebruikelijke autoschaamte wordt hier verdrongen door autotrots, want sinds kort kan ik ook rijden. Ik ben niet langer die ene die op een ov-fiets aan komt zetten, die sowieso niet de bob is want ja, geen rijbewijs.

De trots wordt beantwoord met kinderen, kinderen die kunnen lopen en praten en ‘papa’ en ‘mama’ zeggen tegen hen die ik nog als kind ken. De mensen van wie ik wist dat ze ouders waren geworden hebben hun kinderen niet eens mee: te oud, waarschijnlijk, hadden wel betere dingen te doen.

‘Een witte Volkswagen Up,’ vertel ik tegen een papa. ‘Ah,’ zegt hij, ‘wij twijfelen nog. Onze tweede auto is kapot, maar zo’n kleine is toch wel fijn om erbij te hebben.’ De Chinees na afloop sla ik over, maar zonder goed excuus, thuis zit er niemand op me te wachten. ‘Nee sorry,’ zeg ik, ‘het is een lange reis.’

The day before yesterday I posted about how to divide up posts into various 'post topics', to aid readers in finding something interesting.

Just now I came across an interesting read (in Dutch) by NRC, how they put articles on their homepage. The gist of it: they have some automation, but most of it is actually hand picked by a team.

I don't know if I want to hand pick something like that for my own site, but I like the idea of hand-picked content over algorithms. Or even 'assisted hand-picking', something like that might work.

Another perspective I wanted to add to my own post: by creating these three to five main categories, one is also creating three to five 'personas' to write for. It is like writing a letter to a friend, but then have three friends with different interests, so you write them different stories. What I mean is that these main topics can also aid the writing process itself.

When @hacdias.com posted about our conversation about post topics I couldn’t stay behind to also formulate my part of it in a blogpost.

Currently I have various feeds for various post types. I don’t want to link them all here, in case I want to change them around, but I have different feeds that only show my likes, my photos, my replies, etc (you can probably guess the URLs).

These feeds are relatively easy to set up: does it have a photo? Then it’s a photo. Does it have a title? Then it’s an article. This post doesn’t have any, so it’s a note. I have a few of those rules set up and they fill these pages.

But when you scroll through my photo feed, you will also see drawings. When you scroll through my notes, there are various topics represented. It is not that bad right now, but that is mainly because I don’t post as much as I could, because I don’t want to bore my readers with topics they don’t want to follow.

On social media, we live a siloed life, and the people on the IndieWeb are trying to bring that all back to their own site. But, in the siloed life, we can pick the silo for the post. ‘Insta is for friends, Twitter is more business, Reddit is shitposting’, something like that. Sometimes the silo is aimed at a certain kind of post, sometimes it is just the kind of bubble you created for yourself on that silo that makes you post a certain way.

On the IndieWeb, I have only one site. Of course I can get multiple – I have – but I like having all my posts in one place. But I also want to give people options for how to follow me, different persona to share posts with.

I do have tags but most are not that useful. Most of them only contain one post, and also, most of them are very specific. I like the indieweb and vim tags, for they are quite topical, but those are exceptions.

At one point (not now) I would like to divide posts up into probably five rough categories. The homepage might still show a selection of all, and there will also be a place to actually see everything, but I think these categories make sense to me:

  • professional / helpful for all those posts in which I share something about IndieWeb, Vim, something about programming, something I learned
  • personal for stories about what happened in my life, maybe also some tweets, the more human connection
  • too personal for checkins, books I’ve read, food I’ve eaten, movies I’ve watched, still about life but without commentary
  • art for those good pictures, occasional drawings, fiction stories, the things I post too little

I said five and I posted four, because I don’t think this is final. I might also want to add a ‘current obsession’ category, to blog about those things I am deeply into. (There has been posts about keyboards here, you missed Getting Things Done, currently I am into the game of Go again.)

A last category I might also need is ‘thinking out loud’, as this is a post that would fall into that. For what is worth, I’ll post it anyway.

Kleine follow-up op mijn toepassing van NFC-stickers: ik heb zojuist een sticker op mijn wasmachine geplakt. Hoe meer je gaat leven met een app waar je al je todo's in bewaart, hoe meer je ook andere todo's daar in wil stoppen. Zo heb ik dus een herhalende herinnering om de was te doen, dat is, de inhoud van de wasmand in de wasmachine te stoppen. De vraag is, wie haalt het er dan weer uit?

Daarnet bleek ik dat dus vergeten te zijn. De was zat nog in de machine terwijl die al een tijd klaar was. De nieuwe sticker op de wasmachine lost dat op: zodra ik 'm scan maakt mijn iPhone een taak aan genaamd 'was ophangen', in de context 'thuis' en met de datum van vandaag. De nieuwe taak opent direct zodat ik een specifiekere herinnering kan instellen als dat nodig is. Na het aanzetten even scannen en klaar. Kind kan de was doen.

WorkOutDoors hardloop app

Om maar gewoon met de deur in huis te vallen: de beste hardloop-app voor Apple Watch heet WorkOutDoors. Ik ben helemaal blij.

Voorheen nam ik mijn hardlooprondjes op via de standaard Workouts app van Apple. Dit is een prima app: het meet wat het moet meten. Ik gebruik een app genaamd HealthFit om mijn rondjes naar Strava te syncen (en ooit, ooit ook naar dit weblog). Op Strava heb ik vervolgens allemaal analyses.

Kleine pro-tip tussendoor: je kan tijdens een workout dubbeltappen op je Apple Watch, dat neemt een nieuwe lap/interval op. Hiermee hak je je workout op in stukjes, die je later kan analyseren. Eerst vier minuten snel, dan drie langzaam? Twee tapjes tussendoor en je ziet later precies statistiekjes over de twee losse stukken.

En dat brengt me bij mijn grootste probleem met de Workout app: het geeft me allerlei gegevens tijdens het lopen, maar niet de verstreken tijd sinds het begin van de huidige interval. Eerst vier minuten snel, dan drie langzaam? Dan mag je dus zelf heen en weer naar de stopwatch-app, om een timertje te zetten. Ik vind dat niet echt lekker werken.

Nou, dan niet WorkOutDoors. Mis je in deze app een bepaald cijfertje? Binnen no-time heb je het toegevoegd op een van de vele schermen die je kan instellen. En dan echt élk soort cijfertje wat je maar kan verzinnen, op elk soort scherm dat je maar wil. Mijn enige kritiekpunt is dat de app té nerdy is, te veel is aan te passen. Maar tegelijkertijd vind ik het dikke prima: het is precies wat ik wil, zelfs als ik straks misschien wat anders wil.

Toen ik van de week bij Cifla trainde had ik het er met iemand over. Zij miste juist een andere feature: van te voren een set aan intervals en tijden instellen en dan dat programma laten afdraaien tijdens het rennen. Die feature zit hier ook gewoon in; ik heb ‘m net gebruikt voor een rondje, en achteraf gezien is dat inderdaad een feature die ik ook gemist heb. Eerst vier minuten snel, dan drie minuten langzaam? Stel het van te voren in en alles komt goed.

Ik grapte toen nog dat het een gat in de markt was dat dit nog niet bestond, dat ik zelf die app maar moest gaan maken. Maar hij bestaat dus wél, voor 6 euro. Shut up and take my money.

De twee vormen van privacy

In discussies over privacy merk ik vaak dat mensen het over verschillende dingen hebben. Van het woord ‘bank’ is vaak uit de context wel duidelijk of het om een financiële instelling of om een zitmeubel gaat, maar bij ‘privacy’ lopen de concepten een beetje door elkaar heen.

Er zijn naar mijn idee twee vormen van privacy: mens-mens-privacy en mens-bedrijf-privacy. Waar ‘bedrijf’ staat kan ook ‘instantie’ staan of iets anders dat op een onpersoonlijk rechtspersoon duidt. In beide vormen is het volgens mij belangrijk om privacy te hebben, en de reden ervoor brengt ze uiteindelijk weer bij elkaar tot één begrip van privacy.

De meest begrijpelijke vorm van privacy is denk ik de mens-mens-privacy. Persoonlijk ben ik liever alleen als ik naar het toilet ga. Sommige dingen vertel je wel aan je moeder maar niet aan collega’s en andere dingen juist niet aan je moeder maar wel aan je collega’s.

Privacy gaat over relaties, over hoe ik mij verhoud tot collega’s en mijn moeder. Het is gezond om dingen achter te houden voor bepaalde mensen, niet omdat het echt geheim is, maar gewoon omdat de omgang prettiger is zonder die informatie. Ze doen het zelf ook naar mij toe.

De andere vorm, mens-bedrijf-privacy, gaat over data. Als ik een vriend vertel over mijn weekend is dat een verhaal, als mijn telefoon verbinding maakt met de wifi van de Albert Heijn is dat een data-punt. In deze vorm van privacy gaat het nog steeds om een relatie, namelijk die van mij tegenover de instantie die mijn data interpreteert, maar de relatie is uit balans.

Bedrijven en instanties hebben veel data, en kunnen daarmee komen tot voor hen nuttige inzichten over mij. Die inzichten geven de relatie vorm die ze met mij willen hebben, maar zelf heb ik niet zo’n concreet beeld van hen. In veel gevallen weet ik niet eens wie mijn data interpreteert en met welk doel.

Ook vergeten instanties dingen niet snel meer. Dankzij regelgeving horen ze gegevens periodiek te verwijderen, gelukkig, maar als ze niet op de knop drukken hebben ze nog altijd een even scherp beeld van mij als dat ze hadden toen ze de data vergaarden. Een anekdote van een bekende in de kroeg zakt na een paar maanden wel weg.

Het belang van de mens-mens-vorm van privacy wordt ook onderschat, denk ik. Voor beide moet aandacht zijn. In beide vormen gaat het om de noodzaak om zelf controle te houden over de relaties die anderen met je op proberen te bouwen.

Neem me mee met NFC

Een tijd terug kreeg ik tijdens een IndieWebCamp van Sven een set aan NFC-stickers. ‘Jij hebt er vast creatievere ideeën voor,’ zei hij toen. Ik moet bekennen dat het even op zich heeft laten wachten voor ik er een idee mee had.

Het idee van een NFC-sticker is dat je de tag draadloos kan scannen met je smartphone, die daar dan iets mee kan. Het is exact hetzelfde als je ov-chipkaart, alleen dan is de sticker de kaart en je telefoon het poortje. Als je mijn ov-chipkaart scant met mijn telefoon opent die de NS app op ‘actuele vertrektijden’.

Het is op iOS heel simpel in te stellen: open of installeer de Apple app ‘Opdrachten’ (Siri Shortcuts), ga naar het tabje ‘Automatisering’ en voeg een ‘Persoonlijke automatisering’ toe. Als trigger kies je NFC, scan je ov-chipkaart, en klik ‘volgende’. Daarna kan je een actie kiezen die moet worden uitgevoerd.

Een paar weken geleden ben ik weer begonnen met Getting Things Done te implementeren en daar ben ik momenteel best tevreden over. Voor wie het niet kent: schrijf al je taken op, zodat je kan doordenken wat ze voor je betekenen, en hou de eerstvolgende acties bij in een systeem dat je vertrouwt en vaak raadpleegt. (En dan nog wat reviews, een paar nuances en veel oefenen.)

Eén van de lijsten die ik nu bijhoudt is een lijst van dingen die momenteel thuis liggen maar ‘ergens’ naar toe moeten. Punt is: ik vertrek wel vaker van huis, maar steeds naar andere bestemmingen, en eenmaal op die bestemming denk je pas: o ja, dat moest mee! Vandaar de lijst.

Nu hangt er dus een NFC-sticker in de hal. Als ik die scan, opent mijn telefoon de Things-app op de ‘Anytime’ view, met daarin de ‘Mee naar...’ tag voorgeselecteerd. Het is een soort snelkoppeling, maar dan in de fysieke wereld. Heel erg blij mee.

Op de plek waar in ‘s nachts altijd mijn telefoon neerleg ligt er nu ook een. Als ik die scan gaat ‘Welterusten’ aan: alle lampen in mijn huis gaan uit, behalve heel zacht het licht in mijn slaapkamer. Na één minuut gaat die ook uit. Die is ook fijn, maar het zou kunnen dat ik in dit geval gewoon hardop ‘Welterusten’ tegen Siri blijf zeggen.

Ik zie veel zoveel-jaar-geledens vandaag, dus ik dacht ik doe ook mee: vandaag is het 16 jaar geleden dat ik een weblog lanceerde op Seblog.nl en aangezien ik toen 16 was ben heb ik vanaf vandaag langer wel een weblog dan niet.

De maan schijnt recht mijn kamer in, ik heb hem nog nooit zo vol gezien, zo veel licht. Ergens bang om nu een wolf te worden maar vooralsnog voel ik me prima.

Faster copy to clipboard in Vim

tl;dr: I just mapped Y to "+y and I am very pleased with it.

A coworker saw me copying some text out of Vim and humored me: everything seemed to happen like magic in my editor, but for a simple thing as copy and paste I needed a lot of keys.

It is true: in order to copy text within Vim, you can use the y command, combined with the motion of what you want to yank. So: yiw will yank inside a word, ggyG will go to the top of the file and then yank until the bottom (so, the whole file), yy will yank a full line. But these yanks are only pastable (with p) within Vim itself.

In order to get text out of Vim, you need to use a special register. Registers are a sort of named boxes, letters a to z, in which you can put snippets of text. To use it, you prefix your yank (or delete) with a quote: "ayi( will select register a and then yank the text within parentheses. To get to your system clipboard (the one all other programs use), you select the special register with "+.

Thus: my coworker saw me hunting for the "+y combination, probably. I almost always look at my keyboard when I do that, so awkward is the combination. But I just found a solution: Y.

nmap Y "+y
vmap Y "+y

By default, Y does a yy, which I never use, because it's inconsistent with other commands. D, for example is equivalent to d$, delete until the end of the line, same for C as c$. I guess it makes Y play along with V (line-wise visual select) and S (subsitute full line), but I always use yy anyway, so Y is free to use. When I now want to yank to my system clipboard, I just use Y instead of y and that's it.

You can also consider adding this as gy, which does not have a meaning, but g combines with various commands to activate variation of their meaning, so it's not a bad choice either. I mapped it to both and will see which one sticks.

Adding a prefix to TailwindCSS classes with VIM

Today we needed to add a TailwindCSS prefix to a small project we are building, to prevent clashes with other TailwindCSS classes on the same page. The setting in the tailwind.config.js was straightforward, we added this:

module.exports = {
  prefix: 'sf-',

... and now TailwindCSS will generate classes like .font-bold and .border-none as .sf-font-bold and .sf-border-none. Next up, we needed to replace all the classes in the project with their prefixed counterpart.

There were some plugins available to do this automagically in Webpack, but we decided we wanted to add them manually. A few of the classnames are dynamically set, and we doubted the plugins would find all those cases. Also: the plugins seemed to be old.

My co-worker started writing a regex for a search-and-replace, but soon stranded. You need to find the proper locations, and then within those locations, add the prefix. The prefix, however, is sometimes more of an infix, since there are other prefixes that are added before the prefix itself. See the class with md: for example:

<div className="bg-gray-100 px-4 md:px-0">
// Becomes:
<div className="sf-bg-gray-100 sf-px-4 md:sf-px-0">

While he worked on the regex and subsequently went to get coffee, I thought: I should be able to solve this in VIM in some way. I know I can make a visual selection and then type :! to get the selection as input into some shell command. If I pipe the lines to some script, I can then just split strings all I want.

One problem I ran into was that, if I make a visual selection within quotes (vi") and I then use the colon-exclamation to pipe it to some script (:'<,'>! php transform.php), I will receive the full line, as if I was using the line-wise V selection.

While searching the internet I thought: can I use a register here? And the internet had a solution for that. I ended up running the following command:

:vmap m "ay:call setreg('a', system('php transform.php', getreg('a')))<cr>gv"ap

This sets up a mapping for visual mode, and binds the m to do a series of things. It first selects the 'a' register and yanks ("ay). Since we are already in visual mode here, y is a direct yank of that selection. We are now in normal mode, so we continue to type out a command that calls a function to set register 'a' again with the output of a system call to php transform, taking in the current contents of register 'a'. We execute this command by pressing enter (<cr>). Register 'a' now contains the scripts output. We then re-select the last visual selection (gv in normal mode) and then paste from register 'a' ("ap). This effectively runs the script over the visually selected area.

I then just opened the alphabetically first file of the project and manually made visual selections that selected all the classnames. For this, I also temporary mapped m to vi", so I could just do mm once my cursor was in a className="..." (for which mouse mode is nice too: click + mm, very fast). Then, to get to each next file, just press ]f.

The project was small enough to do this last part so manually, but this at least saved me a lot of stops in between all the classnames, and also saved me the headache to scan for md: prefixes and pick the right spot. Even when the classnames were actually in a backtick-string it was no problem: as long as I defined a correct visual selection, m would replace things.

For completeness, here is transform.php:

<?php

$input = file_get_contents('php://stdin');

$classes = array_filter(explode(' ', $input));

$classes = array_map(function ($class) {
    $parts = explode(':', $class);
    $parts[count($parts)-1] = 'sf-'.$parts[count($parts)-1];
    return implode(':', $parts);
}, $classes);

echo implode(' ', $classes);
Meer laden