Currently leaning towards having separate implementations of TextView for UIKit and AppKit with shared logic moved into separate types. The alternative is a single implementation with lots of if-else-endif macros.
It makes for some duplicated logic but also means that the two implementations can easily be maintained and implemented in isolation.
@simonbs Sound idea. In practice, text views always ends up being a mess with all the different types, delegates, etc.
If you try to manage the different APIs within that code you end up breaking the iOS version while working on the macOS version, etc..
I’d just have completely separate technical implementations with platform independent code shared in platform neutral classes.
I’ve found testing and re-testing changes to be a much bigger time killer than writing separate implementations.
@simonbs I really dislike maintaining macro “if” based multiplatform code. I always try to structure my way out of it, like what you describe.
Much easier to read and reason about I think.
Yay! Runestone now works with... *Checks notes*... UIKit?? 🤨
In order to prepare for AppKit support, I had to rip the internals of Runestone apart and put it together again. For the first time in 36 hours, Runestone now works with UIKit again.
So I now have an NSWindow with an NSView that receives keystrokes. That's like step 0 in building a text editor, right?
There's such a long way to go still before Runestone is rewritten in AppKit. I hope I'll eventually turn a corner where all my work from UIKit can be reused and I ✨magically✨ have an AppKit implementation.
The AppKit version of Runestone now supports scrolling the content.
This involves a bit more than just wrapping everything in an NSScrollView because Runestone only renders the lines within the viewport.
Baby steps, y'all.
I need to implement all moving within lines myself 😑
In the screenshot I'm logging the selectors that I don't handle but that AppKit expects me to handle. This is something we get (almost) for free in UIKit. Honestly, I really don't want to write this logic.
Got navigation with the arrow keys working in Runestone for AppKit.
I figured out how to reuse some of the code from the UIKit implementation so this turned out to be much easier than anticipated.
Next up is adding support for jumping between words with Option+Left/Right arrow keys.
Baby steps, y'all.
While working on moving between words in Runestone for AppKit I found that the UIKit version had an incorrect behavior when moving between words followed by an emoji. The caret would always jump all the way to the end of the document which isn't correct, obviously. Fortunately, that was easy to fix and the fix works in both UIKit and AppKit.
And yes, it is supposed to jump all the way from the word "emoji" to the word "cool". That's how TextEdit does it too. Baby steps, y'all.
And now Runestone for AppKit supports moving to the line and document boundaries as well as clicking with the mouse to move to the closest location.
Maybe the next step is to support text selection. Or something more fun like line numbers.
Baby steps, y'all.

Performant and reusable text view component (TextKit 2), with line numbers and more. UITextView / NSTextView replacement. - krzyzanowskim/STTextView
@terhechte That's what's scaring me the most: the uncertainty of which bugs I'll have to deal with now.
Working around crazy issues with UITextInput has probably been the most exhausting challenge I've faced when building software.
@simonbs Looks great, can’t wait!
Maybe more yarn? 🧶