A couple of days ago, I did maybe the weirdest and also most amazing thing on a remote machine thus far (with Emacs) and wanted to share the story. So there’s this EmulationStation software that organizes roms with XML lists for metadata. I needed to change the <name> field of about 100 entries there to drop a numeric prefix. That’d be easy on my local computer with tools I know well, but I was accessing the device remotely via SSH and wanted to see what I could do.
SwiftUI very likely is the future of app development. But it cannot, on its own replace UIKit or AppKit. Not yet, maybe not next year, either. Eventually you will have to drop down a level to implement a custom view, custom navigation, animation, window, or what have you. So for the time being, the two worlds of UIKit and SwiftUI co-exist and complement each other.
In short: Image file drag and drop does only produce file URLs, either with security scope-able bookmarks or plain file paths. Dragging an image file from Finder onto an NSTextView will trigger performDragOperation(_:). You get access to NSDraggingInfo there and can inspect available content. Its draggingPasteboard (shortened to pb here) contains the following data when executed on macOS 12 Monterey:
An old code base was still using Sparkler v1.27.0. To test the transition to the latest 2.x branch, the one that allows Sandboxing and uses XPC services under the hood, I migrated that project. Carthage builds of Sparkle’s v2.x branch don’t work well, though. You would need to do a lot of manual re-signing, otherwise the code signing stage of your build will fails. It does with a simple test project that embeds and signs the framework.
The Apple’s Human Interface Guidelines have a list of named system colors for macOS. These color names can be used for Emacs “faces”, i.e. color-and-font settings of text. Recently, this came in handy when Protesilaos Stavrou published his LIN package source code – it’s basically an extension of the built-in hl-mode, read: highlight-line-mode. The default highlights the current line. That’s kind of useful to find your insertion point more quickly. But it’s also used in selection interfaces to highlight the currently selected line: email modes like message-mode, notmuch, mu4e, and feed reader elfeed use this to show that the actions you can perform pertains to the currently focused or highlighted line. That’s where Prot’s LIN package comes into play: it helps distinguish between highlighting the line in text editing modes and highlighting the line in selection interfaces, so you can use different colors.
Today’s WTF moment with Swift is related to switch-case and the pattern matching operator, ~=. Defining operator overloads for special cases can help to keep case statements readable. And I thought it’d be simple enough to quickly check the setup, but I was in for a surprise!
Today, I had trouble getting NSColor to work with colors from Asset catalogues when asking for its .cgColor. Since NSColor is appearance-aware, i.e. it switches light and dark mode appropriately when used directly in your views, I wondered why asking for .cgColor always returned the initial value. Say we start the app in light mode, then this is always going to be the light mode color, never dark mode. Yes, not even if you initialize the color anew using NSColor(named: ...).cgColor.
I was profiling performance bottlenecks in the The Archive and noticed that no matter how much highlighting functionality I removed/commented-out, the apparent slowness was all due to … Touch Bar API?! I have been “pruning” the Touch Bar related calls from the profiling stack to focus on what I though would be the real bottlenecks. But, as often, it turns out this was stupid and the instruments did point out the true problem. Something indeed was causing trouble here, it turned out.
In The Archive, people relying on character composition to enter their text noticed that the auto-saving routing got in the way and aborted the composable editing mode. This affects e.g. Chinese or Japanese character input on macOS, but also when you hit a composable accent like ´ after which the text editor waits for another character to put underneath the accent.
Recently, FastSpring announced what they call “Multi-Discount Coupons”. These are coupon codes that: This is different from regular coupon codes that would only apply to one product. To implement a coupon-based discount for a combination of products, the best bet so far was to create a (temporary) product bundle and apply a re-usable coupon to that.
I was preparing a test build to check if linking against a new library worked fine in production. Trying to distribute the app using my Developer ID (but this would also have happened in a step before uploading to the App Store), I got this: Found an unexpected Mach-O header code: 0x72613c21 Oops? Like probably most developers, I have absolutely no clue about many crucial steps in the app making process. Especially stuff like code signing and most build settings elude me – I pick up pieces over the years, but not with the same speed with which I’m getting better at writing apps. So I didn’t understand what’s going on at all here. The search results I got weren’t that useful, so this post is meant to fill the vacuum for the next person running into this.
I’m having all my project in git repositories. And since I discovered the magic of Magit in Emacs, I sometimes want to have a familiar, interactive interface to select hunks for a commit without having to fire up a proper GUI app for stuff that I don’t already edit in Emacs.
In my previous post, I shared a function to fetch macOS Finder’s frontmost window path using AppleScript. The result was then opened in dired so you can import your Finder session into Emacs, so to speak.
Quite often I have a directory open in macOS Finder that I want to open in Emacs dired, e.g. to mass-rename files, copy stuff to a remote machine via SSH, or what have you. In my last post, for example, I used Gifox to create a GIF and then viewed the result in Finder. To add the GIF to my blog post, I needed to copy it over into the appropriate website project directory. Since I was writing that post in Emacs already, I wanted to quickly copy the file from my Downloads folder (my default scratchpad for output like screenshots and screen recordings, including GIFs) over to the blog post’s location.
Today I found that NSTextView has a bug where it won’t automatically scroll to keep the insertion point visible when you hit Enter or Return to insert a line break. Update 2022-04-26: This bug is resolved on macOS 12 Monterey! So I’d suggest something like:
I’ve just watched the TextKit 2 WWDC video. Without hands-on experience, I cannot say much about the tech, but judging from the presentation, all of the changes sound like an amazing step forward to make rich text-based interfaces nicer to work with. I didn’t particularly enjoy implementing some things in TextKit 1.
I’ve enabled using the macOS system trash in Emacs to feel safer experimenting with dired and other file manipulation functions in Emacs. This enables using the trash by default: When this is enabled, move-file-to-trash is used to delete files. The manual reveals what’s affected, but only the function API docs from within Emacs tell the whole story (and are super hard to search online for whatever reason):
In the past couple of months, I’ve been thinking about the Gemini Protocol on and off. As a protocol, it’s a SSL/TLS-enabled text transfer protocol. The stuff it’s supposed to transfer is text files sorta similar to Markdown. And the client is supposed to render the result. It sits somewhere between Gopher and HTTP.
So a client of mine recently asked how he could customize his app’s printing. The app’s main window there mostly showed tabular data, so when you’re inside the NSTableView and hit ⌘P to print, the table view will redirect its draw(_:) output to the print dialog. That’s how you get printing for free.
Fellow Emacs-user Göktuğ Kayaalp condensed my frame centering stuff into one function as I mentioned one could do, and then improved it by adding a condition for full-screen frames. This is probably the last post on this topic, ever, because what else could be said. Right?! It’s so nice, I want to share the code, reformatted a bit. And Göktuğ didn’t add the binding of frame to selected-frame as a fallback, so I added that back in, plus longer docs.
When centering my Emacs windows (aka ‘frames’) on my monitors, I noticed that with 2 monitors active, the computation doesn’t work: It doesn’t center in the main monitor; it centers in the area of both monitors combined. That’s not what I want.
When I open a new GUI window of Emacs on macOS (which Emacs calls frame) it’s positioned in the top-left corner. Since I have an ultrawide monitor at my desk, that’s pretty annoying. Unlike regular macOS apps, Emacs doesn’t remember where I dragged the last NSWindow to, so it doesn’t spawn new windows next to that. It also doesn’t stagger them like NSDocument-type apps usually do.
I was in a chat with Xah Lee and we ended up talking about “open source” for a short while. The trigger was that he shared quotes by Richard Stallman, one of which boiled down to: packages outside of GNU’s own package repository are not really part of Emacs.
In some modes in Emacs, the hl-line (‘hl’ for ‘highlight’) is used. That’s not intended to highlight the current line when you edit text; it’s used for things like feed readers and email, where you operate on items that are represented on lines. This highlight is way too subtle for my taste.
This week, I seem to have a lucky streak in terms on Emacs customizations. I use Emacs to read and compose most of my email, using the excellent notmuchCLI tool and its accompanying Emacs package. I also really like Protesilaos Stavrou’s modus-themes in both light and dark mode.
I know that #IndieSupportWeeks were supposedly a thing that ended in early 2020, but I don’t see why we shouldn’t continue shouting-out to the devs of apps we use everyday. Late in 2020, @Splattack on the Zettelkasten Forum brought up Monodraw – think OmniGraffle, but with ASCII box art!
In 2015, I sang praises for the guard statement to unwrap optional values in tests. But since then, we were blessed with XCUnwrap, which makes things even better in my book. I received a comment on the 2015 piece a couple weeks ago, so I figured I might as well document that things have changed in the meantime!
I’ve updated the open source FloatingFilter package to finally have rounded corners. The old corners looked especially out of place on Big Sur, but fit Catalina and older macOS versions, too. I believe I never announced the development of this library in the past. It’s used in The Archive to show a floating selector for external editors, and will also be a prominent feature of stuff I’m working on. It’s a general purpose “select with fuzzy matching from a list of things” tool.
Some things on the blog are supposed to have a longer shelf-life. But the nature of a blog is to present things in a timeline. I employ cross-links from older posts to newer posts to encourage exploration with the introduction of the “linked posts” part at the bottom of each post. And I have a structured overview to help with discovery. Even then I branched out into other topical pages, like the TextKit overview, or the even larger FastSpring/Distribute outside the MAS page. To make sense of the timeline, I introduce what’s basically a ‘garden’ to my ‘stream’. It’s not a new idea, but I find not having these overview pages to hamper my writing. Some things need systematic overviews, and I enjoy making these, but there’s no good place for them.
In a Discord chat, we’ve recently talked about how well funding for Blender turned out. At the time of writing, they get $137k per month for development. I cannot say if that’s enough or too little. But it’s not nothing. Being crowd-funded comes with its perils. Especially with free open-source software like Blender, developers tell that it’s not easy to know which user base to focus on, which UI/UX compromises to make, and how to figure out if the project backers are satisfied with the result.
Our note-taking app for macOS, The Archive, turns 3 years old this week. To celebrate, we wanted to do something nice to all the people who supported us during that time.
The thing we came up with is a giveaway. But every customer of the past 3 years wins automatically. The price is 1 free license to freely gift to someone else.
The only condition is that you purchased the app before I uploaded everything today, and that’s it. And that you enter before April rolls around, because then we’ll take down the Claim-O-Matic.
Go to the give-away page and enter your email, then you get a link you can share with the ultimate recipient!
It was really fun to create the website for this giveaway. I also find myself staring at the confetti because it’s so soothing to see how it travels downward. I hope you enjoy the experience, too, and that you know someone who would benefit from a tasteful note-taking app in 2021 with no strings attached.
I found it weird to form the union of two CharacterSet instances by calling the union method on one element: This chains nicely, but what pops out to me looking at the line of code is the CharacterSet, then something about URLs, and then I scan the line to see what kind of statement this is – some lengthy stuff that looks like chained method calls at first glance due to the length and the many dots.
I am not good at reading crash logs of my apps. Some errors are obvious, like index out of bounds exceptions. Others require actual symbolication of the crash log to reveal the symbol aka function name in the stack trace. You can do this in the command line and interactively explore the crash reasons like a caveperson.
I asked Xah Lee for feedback on my case changing functions. He’s fluent in Emacs Lisp, so I figured if he wanted to, he would’ve used my approach years ago. So there must be something I miss. The factoring of the small helper functions don’t seem to be bad, but there are other reasons to design the text editor you use every day in one way or another:
At the moment, I’m proof-reading and editing the book manuscript of my pal Sascha for the new edition of the Zettelkasten Method book. As with most things text these days, I’m doing that with Emacs. Something that continually drives me bonkers is how Emacs handles upcasing, downcasing, and capitalization of words by default. The functions that are called for the default key bindings are upcase-word, downcase-word, and capitalize-word. These sounds super useful to fix typos. The default behavior is odd, though: They only change the case of the whole word when you select the word first. Otherwise they change the case of the remainder of the word beginning at the character at the insertion point. The docstrings say as much: “Capitalize from point to the end of word, moving over.” Why?
If you’re using hashtags on Twitter, Instagram, or in your Zettelkasten – consider CamelCasing the hashtags if there’s more than one word involved. That acually seems to help screen-readers with pronunciation.
Since I’ve added backlinks to the bottom of posts today, I figured I might as well share the code. I’m using static site generator nanoc. It has a preprocessing section in the compilation step where you can add new items and modify items that are read from disk further. I got the basis for this code from Denis Defreyne, creator of nanoc. (Check out his code.)
Everytime I mention, think of, and link to Andy Matuschak’s public notes, I really like how each note displays a list of backlinks at the bottom. In my note-taking, I don’t want backlinks to be added automatically into the content. I can get by with other means just fine to figure out what links to the current note.
In Emacs org-mode, you start with two states for your outline headings by default to manage tasks: TODO and DONE. I recently introduced a new state in between: DOING. That helped me come back to stuff I had to let lie for a while. In code, that means at least: I actually have multiple sequences, but these don’t matter for this demonstrations.
This tip is a bit out of context, but will make sense once I write more about the NAS I did set up. The NAS I have runs Unraid. It’s a Slackware-based Linux operating system that provides a bit of redundancy/recovery from drive failures without the RAID setup overhead and performance penalties. More details will follow later.
Back in December, I whipped up a test project to demonstrate why distributing a Mac app with RxSwift using Carthage failed. Building and running worked well, but I couldn’t upload the app for notarization at all. The signing step just failed.
Update 2021-02-16: I accidentally solved the problem myself, with help by Docker specialist @cwrau using a IPv6 NAT container I need help with a NAS (running the Unraid operating system) and Docker containers (Docker v19.03.5 at the moment) for various services.
By default, NSTextView will show the NSSharingServicePicker button when you hover over an image inside the text view. That’s true even for custom image-based NSTextAttachments in the attributed string. The default menu item is limited to “Markup” and a “Services” submenu, I believe. Apps can register to be shown in this menu, and users can customize the menu in System Preferences.
I’m a fan of linking into my Zettelkasten. I usually do this via a convention: when a 12-number digit is used to signify a timestamp with accuracy to the minute, like 202102101025 for 2021-02-10 10:25, then I expect this to be a note identifier in my note archive. When the timestamp is accurate to the second, I expect this to be something else outside my note archive, like invoices I filed away. To utilize this information, in the worst case, I have to copy the ID and paste it into Spotlight to get to the note.
My grandmother is 91 years old and, for about 2 years now, her sight degraded to almost-blindness. She barely sees milky shapes in her central field of vision. It’s supposedly better in the corners of her eyes, but I couldn’t get any reliable confirmation out of her regarding that. So using a telephone is a problem.
You and I are probably pretty familiar with the XCTestExpectations helper expectation(description:) that we can .fulfill() in an async callback, and then wait in the test case for that to happen. When you have neither async callbacks or notifications handy from which you can create test expectations, then there’s a NSPredicate-based version, too. Like all NSPredicates, it works with key–value-coding, or with block-based checks. These run periodically to check if the predicate resolves to “true”.
WordCounter v1.6.4 is just released and comes with mostly Big Sur compatibility fixes and a fix for the calendar view: January 2021 in Gregorian calendars was displayed oddly, because the maths for the week calculations accidentally produced January 2022 and not 2021. Calendar arithmetics are still hard.
Was working on an export sheet today and during testing on Big Sur, I noticed that the button that would bring up the save panel would produce a beachball for a while, and then I’d get an error dialog telling me that the panel crashed. I changed the NSSavePanel.allowedFileTypes property to ["public.csv"] during this update, and that trips up the save panel on Big Sur. Note that ["csv"] works just fine.
Over at the Zettelkasten Forum, we are using a PHP forum software called Vanilla Forum”. (Vanilla is free and open source if you host it yourself, but the creators also offer managed hosting with some additional features. I like it, it works well, and is pretty well-worn by communities all over the web.)