KISS 🇺🇦

Stop the war!

Stop the war in Ukraine! Fuck putin!

More information is at: https://war.ukraine.ua/.

There is a fund to support the Ukrainian Army: https://savelife.in.ua/en/donate/, and there is a special bank account that accepts funds in multiple currencies: https://bank.gov.ua/en/about/support-the-armed-forces. I donated to them. Please donate if you can!

Killer putin

Killer putin. Source: politico.eu.

Arrested putin

"It hasn't happened yet, but it will happen sooner or later. Beautiful photo, isn't it?" Source: twitter.

Useful global shortcuts

| comments

This is a short post of appreciation of computer keyboards, and shortcuts specifically. Global one key combination shortcuts (such as Cmd+c) are quick and incredibly useful; they are much faster to press when you need a program than for example moving your hand to the touchpad/mouse and fishing out the program from Dock or another place. They are global so they work anywhere in the system (as long as the program handling them is running).

Improving vCard parsing with megaparsec

| comments

Last time I wrote about nested parsing of birthdays in vCards using megaparsec. That solution worked fine as far as I could tell, but there must’ve been a better way. And indeed there was! I’ll explore it and also refactor the vCard parser in this article. The changes (still based on the proof of concept) are at https://github.com/eunikolsky/b2c/tree/poc/full; there are individual commits for every distinct change described here.

Inner parsing with megaparsec

| comments

For a small project, I need to parse the contact information from vcf files, which contain vCards (contact information). Specifically, the vCard 3.0 format defined by RFC 2426. And I only need contact’s name and birthday if any.

It’s a good project for me to learn more about parser combinators in Haskell. I’ve implemented a proof of concept using megaparsec because it has a great tutorial and produces good error messages. The code in this post is truncated and somewhat edited for (hopefully) easier understanding, but may not always make total sense, so you can take a look at the full working code in the PoC repository at https://github.com/eunikolsky/b2c/tree/poc/full.

A story of recovering files

| comments

One day I wanted to move a couple of files into the directory with the sources for this blog. It’s an often used directory, meaning fasd could help me with its path, but I used the wrong command, which resulted in this output and a bunch of missing files:

1
2
3
4
5
6
7
8
9
10
11
$ mv /Volumes/files/file{1,2} `fasd -d`
mv: rename 1 to /Users/user/Documents/var/1: No such file or directory
mv: rename 1.01117 to /Users/user/Documents/var/1.01117: No such file or directory
mv: rename 1.01117 to /Users/user/Documents/var/1.01117: No such file or directory
mv: rename /Volumes/disk/var/podcasts/backups/kazakh_v_kanade to /Users/user/Documents/var/kazakh_v_kanade: Permission denied
mv: rename 1.06288 to /Users/user/Documents/var/1.06288: No such file or directory
mv: rename 1.06288 to /Users/user/Documents/var/1.06288: No such file or directory
mv: rename 1.8225 to /Users/user/Documents/var/1.8225: No such file or directory
mv: rename 1.88823 to /Users/user/Documents/var/1.88823: No such file or directory
^C

Communicate UIKit to SwiftUI

| comments

I needed to do a quick proof-of-concept for a project and instead of dealing with UITableViews (whose API looks so archaic now, you need both a datasource and a delegate, and a separate piece of state to hold the items for rows) and UIKit in general, I decided to try out SwiftUI for the first time to build a small piece of the PoC UI. Specifically, I needed to embed a SwiftUI view in a storyboard and be able to update its state. I’ve found a working solution after a lot of searching online because there were different pieces in different places. Here’s a short post and a sample repository on how to do that.

Fast swift rebuilds with fswatch

| comments

I normally use AppCode rather than Xcode for iOS development because it’s so much more configurable and keyboard-friendly, which is even better with its ideavim plugin. Its biggest downside for me is that it eats a lot of CPU, especially while indexing when a project has been opened. High CPU usage means fast battery drain (and higher laptop temperature, and audible fans). One time I needed to “survive” on the MBP’s battery for several hours, so I couldn’t use AppCode.

Coincidentally, I had a task of importing data from some tables in a PDF file into swift models. That means pasting the table data in whatever format it got to be copied into the swift file, cleaning it up, adding regular structure to it (inserting commas, wrapping lines in function calls). An excellent usage of vim because of macros, registers, regexps. I wanted to have regular feedback though because the model types kept becoming more specific as I was adding more data. The solution was to use fswatch to automatically rebuild the project.

Aligning complex ways in JOSM

| comments

OpenStreetMaps is an outstanding project to create free and open maps of the entire world, created and updated by people. I’ve been improving OSM for several years, mostly doing small edits in the default editor iD. It’s a good and easy choice for the beginners. Recently I tried JOSM and it blew my mind! There is so much functionality there to make mapping faster, more correct and even more fun, including the support for plugins, presets and themes!

Today I’d like to share a guide on how I aligned a part of a polygon with another polyline consisting of a bunch of nodes. To help with the explanations, several screenshots and one screen recording are provided.

Using fzf to pick an iOS Simulator

| comments

I love using UNIX’s/Linux’s command line (aka shell, aka terminal) because it has excellent options for customizations and extensions. There are dozens of standard coreutils as well as hundreds (thousands?) of extra CLI utilities. Some tools can increase your productivity significantly once you get used to them; one of those is fzf — a fuzzy finder, which allows you to pick an item/a set of items from a list quickly. It has a number of useful commands and key bindings out of the box and of course you can write your own! That’s what I wanted to do to start using it more frequently and help with frequent actions.

My use case is to pick a booted iOS Simulator for a command. Most of the time I use one simulator, so a typical command for me would be xcrun simctl uninstall booted org.example.app to uninstall an application from the booted simulator. However that command fails when I have 2+ open simulators, in which case I need to provide a UDID of the simulator I want to target. Do you easily remember the UDIDs of the simulators that you use often? I don’t, so the tiny task here is to get the UDID of a simulator by its name. That’s where fzf comes in. (Granted, in this case I’m unlikely to have dozens of simulators open at the same time to justify using a fuzzy finder, but I needed to start somewhere.)

Playing any video from firefox with mpv and youtube-dl

| comments

Modern browsers are very complicated programs, especially because they also need to be secure to protect users from countless threats on the interwebs. That means that the plugins functionality is necessarily quite limited. Firefox used to have XUL extensions, allowing to have the powerful vimperator; but from Firefox 57, only WebExtensions API is supported. There is a replacement for vimperator written with the WebExtensions API: tridactyl, however it’s more limited.

Lots of websites now provide video content. But sometimes videos have ads, sometimes the player’s interface is inconvenient, or the video is blocked on the page even though it can be loaded if you know the link. youtube-dl is an amazing program that can download videos from dozens of websites. How do you make it work with your current tab in Firefox?

Result builder example for validation in swift

| comments

My recent (2020?!) post introduced an idea for lightweight validation in swift that can gather all the errors that failed the validation.

This post is a continuation where I implement a result builder for this validation so that it would look a bit cleaner:

1
2
3
4
all {
    foo == bar <?> "Incompatible operations"
    baz == 42 <?> "Unexpected baz"
}