Keep It Simple Stupid

OSX: Close notification with keyboard

| comments

OS X’s UI looks nice, but isn’t very keyboard-friendly. For example, there is no standard shortcut to expand or minimize a window (yes, Cmd+M typically works, but it depends on the Window > Minimize menu command, which is sometimes not present). The same is true for the notification center, specifically calendar invitations/reminders that display a notification popup by default with two buttons: Close and Accept/Remind later. How do you dismiss it with the keyboard alone?

Backups, TimeMachine, HFS and pain

| comments

Disk doesn’t mount

A recent Saturday evening my external 4TB SSD for TimeMachine backups and some other data has failed to mount when connected. Strange, but it’d happened once before, and an OS restart had helped then. This time, it didn’t… While I was thinking that my SSD has suddenly started dying (it happens with hardware) and what to do about it, about 10 minutes have passed and a message popped up that said something like there is a problem with the drive, but you can still copy your data, and the volume was mounted read-only!

I tried to repair the volume in Disk Utility, but it would fail after several minutes. It wasn’t clear to me if it’s really a disk failure or a filesystem error.

Automate saving Glacier webcam pictures

| comments

Glacier National Park is really beautiful! The website has a dozen of webcams in different parts of the park and winter views are amazing (from the working cameras). All the webcams with their descriptions are on this page, but I like the current thumbnails page more because it provides a compact view of the current webcam images. Sometimes I want to save a picture, but I have to manually change the filename or append a suffix so that previous images from the same webcam aren’t overwritten — this is annoying. How could we automate this?

Cleaning swift build products clarifies errors

| comments

This is a quick note about the fact that if you get surprising or unexpected build errors in a swift project, cleaning the build products directory may clarify them. In AppCode, the fastest way by default is to press Cmd+Shift+A to open the action fuzzy search and type “Clean build folder”; in Xcode, the shortcut is Cmd+Opt+Shift+K.

There are two kinds of errors I’ve seen that are improved in this way:

Enabling locate on OSX

| comments

locate is a nice tool to quickly find files by name because it builds a database of all files and searches it instead of the filesystem. I know OSX has Spotlight, but it’s graphical, has some indexing issues sometimes, and the command-line client is clumsy. I prefer simpler UNIX tools. Some more info in the Arch wiki.

I’m mostly interested in locating my own files, so the database will be stored in the home directory and updated from my user, not root.

Lightweight validation in swift from scratch

| comments

A program that takes any input from the outside world must validate it. In a project I worked on, I encountered a problem with the code that validates a received response and I didn’t know why validation failed because the logs only said “Rejected response X because it’s invalid”. The problem is that the validation function just returned a Bool, which doesn’t carry any extra information as I show in this post.

This article is about a general idea of how to get more information from various processes in your program, in this case, from validation. It describes only the first steps and can be extended further.

The repository with the sample code is at

Disable desktop images usage in XScreenSaver on OSX

| comments

I have previously written about XScreenSaver and selecting a random screensaver among the dozens of the great ones in the package: “OS X: flexible random screensavers”.

Some of the screensavers can display images and the default there is to use the screenshot of the current desktop; it is a sensible default, however I don’t like this mini-leakage of information. Each screensaver has a settings dialog (at least, on OS X) and you can disable the “Grab desktop images” option, enable the “Choose random images” option instead and pick a directory, such as /Library/Desktop Pictures. The problem here is that there are more than a dozen of such screensavers, I don’t know which ones, and I don’t feel like going through a hundred settings dialogs manually at all. We’ll use the terminal instead!

TIL: sudoedit

| comments

The command-line interface in Linux/UNIX is extremely powerful due to the combinable features of a shell and a vast number of different programs. You can discover new tools all the time. For example, I recently discovered that the sudo package has the sudoedit command to edit files as root.

So instead of

$ sudo vim /etc/hosts

you can

$ sudoedit /etc/hosts

The advantage of this is that the editor is run as your user, not as root, increasing security. Works in Linux and OS X.

There is a bit more information here:

My week in Haskell: monad transformers

| comments

This will likely be a less coherent post than usual. I’ll try to describe my investigations and new experience in Haskell this week. I’m only the beginner in this field, but these thoughts might be helpful to other beginners too. You can ask questions in the comments.

I have a tiny program logdl that downloads log files from an iOS text editor via HTTP using the http-client package. I was thinking about extending it to support FTP downloads from an Android device as well and of course there is a Haskell library for an FTP client, for example ftp-client. There is a caveat with that library: all FTP operations must be done within the withFTP scope, bracket-style, which is different from creating and using a manager in the HTTP library — so this difference needs to be dealt with.

The current code in my program looks like an imperative mess in Main.hs, I admit that it’s far from perfect; to support a different transport I shouldn’t need to change the business logic, but right now those two parts aren’t separate. The solution I see here is “depend on the abstraction, not on the concrete implementation” a.k.a. dependency injection. I know how I’d do it in swift, but what about Haskell?