[HN Gopher] Nerdy internals of an Apple text editor
       ___________________________________________________________________
        
       Nerdy internals of an Apple text editor
        
       Author : papereditor
       Score  : 439 points
       Date   : 2024-03-05 13:28 UTC (1 days ago)
        
 (HTM) web link (papereditor.app)
 (TXT) w3m dump (papereditor.app)
        
       | papereditor wrote:
       | Discussion for the first article:
       | 
       | https://news.ycombinator.com/item?id=38866170
        
       | soapdog wrote:
       | I love articles like this.
        
         | papereditor wrote:
         | Thanks!
        
         | whartung wrote:
         | I'd like to see a similar treatise on the Apple Document
         | system. I love that thing, it's a favorite part of all the
         | Apple apps.
        
           | jitl wrote:
           | That makes me super curious about it. I've only had some
           | small interaction while learning SwiftUI and I was confused
           | in passing, and sort of just smashed things until it worked.
        
       | kccqzy wrote:
       | Are the internals of other Mac-native text editors like TextMate
       | similar to this as well?
        
         | pvg wrote:
         | That depends on the extent on which they rely on the system-
         | provided frameworks. When the needs of the editor get
         | specialized enough, all sorts of hackery happens.
        
         | ladberg wrote:
         | A quick glance at https://github.com/textmate/textmate says
         | they don't but someone correct me if I'm wrong
        
         | Someone wrote:
         | Depends on what you call "similar". They'll have storage,
         | layout, a part of the layout that's visible, etc, but they may
         | not separate them that clearly, and won't have that rich an
         | API. TextView is way more flexible than what the typical _text_
         | editor needs. Text editors typically don't need multiple fonts,
         | multiple font sizes, varying line spacing, paragraph indents,
         | proportional fonts, right-aligning or decimal tabs, images
         | inside text, etc.
         | 
         | All those features make TextView relatively slow and memory
         | hungry. Because of that, I don't think _text_ editors that
         | handle multi-megabyte files will use a single
         | NSAttributedString to store the entire document's text.
        
           | papereditor wrote:
           | Yep. TextView is a beast.
           | 
           | For multi-megabyte files I always use Sublime.
        
             | kccqzy wrote:
             | And for multi-gigabyte files I use HexFiend.
        
             | KerrAvon wrote:
             | BBEdit is more Mac-like than Sublime and handles multi-gig
             | files with ease.
        
               | papereditor wrote:
               | Indeed, there are a handful of those dev-oriented editors
               | that crunch through mega files with ease. No idea why I
               | prefer Sublime. :D
        
         | confd wrote:
         | https://github.com/MarkEdit-app/MarkEdit/wiki/Why-MarkEdit
         | 
         | The MarkEdit team uses WebView and have strong opinions about
         | why.
        
           | Ezhik wrote:
           | Using CodeMirror in a desktop app seems like an interesting
           | choice. I'd love to hear more about why they took this
           | approach.
        
             | papereditor wrote:
             | Web tech is an obvious pragmatic choice. Cross-platform by
             | default, amazing libraries with great support.
             | 
             | The average user does not care.
        
         | sharkjacobs wrote:
         | A great example of a very different approach to this is
         | Runestone
         | 
         | https://github.com/simonbs/Runestone
        
       | dbalatero wrote:
       | The author did a great job using images to convey the various
       | concerns each piece of code in the API is responsible for. Also
       | super great detail in the writing. Nice work!
       | 
       | This feels like a technical-first article that also happens to
       | generate goodwill for the product, as opposed to a marketing-
       | first technical article that serves up the bare minimum of
       | insights.
        
         | papereditor wrote:
         | Thanks!
         | 
         | Yep, it's a win-win. A good resource plus a bit of marketing
         | for the product.
        
       | Nijikokun wrote:
       | I clicked "hide these widgets" from the three dot dropdown menu
       | on your animations and now I can't figure out how to bring them
       | back. heh.
       | 
       | Great post btw!
        
         | papereditor wrote:
         | Thanks!
         | 
         | The state is saved to local storage. Just delete the key from
         | DevTools and they will come back. :D
        
       | foxandmouse wrote:
       | I've been loving this app, It's replaced all other markdown apps
       | for me including obsidian and ia Writer!
        
         | mk12 wrote:
         | Interesting, those are the two main apps I use for writing.
         | Maybe I should check this out.
        
         | caycep wrote:
         | granted, I know Paper is an apt name, but there's at least 2
         | other iOS apps called "Paper" IIRc...
        
           | papereditor wrote:
           | Yep...
           | 
           | "paper writing app" is a good keyword to search by.
        
       | sharkjacobs wrote:
       | This is great, I think it supplants
       | https://www.objc.io/issues/5-ios7/getting-to-know-textkit/ as my
       | go to introduction to TextKit.
        
         | papereditor wrote:
         | That looks like a good article, indeed. I have not seen it
         | before. Thanks!
        
         | Someone wrote:
         | For iOS 15.0 or later/MacOS Monterey or later, you want to look
         | at TextKit 2. See
         | https://developer.apple.com/documentation/appkit/textkit/usi...
         | 
         | That's a new layout engine that currently is the default for
         | text fields and on iOS and MacOS, but likely will be the only
         | option some time in the future.
        
           | papereditor wrote:
           | Indeed!
           | 
           | I want to migrate Paper to it this or next year.
        
       | yuchi wrote:
       | In the era of DOM documents (see notion, gitbook) I very often
       | resort to attributed strings to do magic stuff with text parsing
       | and manipulation. It's such an elegant structure and I don't
       | understand why is so unknown.
       | 
       | Incredible article btw
        
         | papereditor wrote:
         | Thank you!
        
         | LikeAnElephant wrote:
         | Do you have an example? I'd love to learn more!
        
           | yuchi wrote:
           | Let's say you have a rich text where you want to highlight
           | all occurrences of some token or syntax. When you have tree
           | data structures you cannot use regexps or a simple parsers,
           | since the full text may be split in different nodes.
           | 
           | With attributes strings it's trivial, you just need to move
           | attributes accordingly and to normalize stuff at the end.
        
         | Ezhik wrote:
         | I wonder if there are any web rich text editor components that
         | use attributed strings? Tired of the DOM.
        
       | dkjaudyeqooe wrote:
       | It's a real shame that Apple doesn't release the source to a
       | recent version of TextEdit. Given its structure (more or less
       | just a stock objects from the API) it would be super educational
       | for anyone who wants to use NSTextView et al.
        
         | krzyzanowskim wrote:
         | For the educational purpose of modern TextKit and NSTextView-
         | like implementation, you can check out
         | https://github.com/krzyzanowskim/STTextView that is modern re-
         | implementation of the text view.
        
         | jwells89 wrote:
         | Yeah, you can get pretty close to TextEdit by just dropping an
         | NSTextView into the document window XIB of a document-based Mac
         | app, hooking up the data methods in your Document class to it,
         | and doing a little bit of wiring of menu items to the textview.
         | Text formatting bar, rulers, Find in Page, font panel, etc.
         | There's a few things missing but not a ton.
         | 
         | The document-based app template gets you a lot for "free" too,
         | including tabs and conversion of windows into tabs and vice
         | versa.
        
       | jrvarela56 wrote:
       | This is amazing content marketing. Developers are an obvious
       | target niche for such a product. Exposing internals of the
       | software in a way HNers enjoy sounds like a great idea, would
       | love to see if it worked as a traction experiment.
        
         | papereditor wrote:
         | Last time (https://news.ycombinator.com/item?id=38866170) there
         | was a small spike in sales, but no lasting effect.
         | 
         | I would not say that developers are the target niche. The best
         | customers are professional writers who use a ton of writing
         | apps for different occasions.
        
           | glorioushubris wrote:
           | Professional writer who uses different writing apps for
           | different occasions is me exactly. I'm also the (or at least
           | a) guy who messaged you about inline comments. As soon as all
           | the details of that feature are implemented, I'm buying it.
        
             | papereditor wrote:
             | Nice!
             | 
             | I'll be sure to prioritize this work then. :D
        
       | brcmthrowaway wrote:
       | Is openGl used here at all for rendering?
        
         | papereditor wrote:
         | I don't use any low-level rendering code.
        
       | jakey_bakey wrote:
       | The UI of this doc is absolutely beautiful
        
         | troupo wrote:
         | There are several elements that are practically invisible
         | though: play/pause buttons on the sides, comments in
         | parentheses, explanatory text on graphics.
         | 
         | It's a shame because otherwise the presentation is really good.
        
           | papereditor wrote:
           | Thanks!
           | 
           | The play/pause buttons are meant to not disturb the reading.
           | They are only for the rare occasions when you want to pause
           | the video to examine it closer.
           | 
           | Comments can be hovered over to make them fully visible.
           | 
           | The text, yes, should have been more prominent...
        
         | Eggs-n-Jakey wrote:
         | I like your handle, Jake.
        
         | papereditor wrote:
         | Thanks!
        
       | lilyball wrote:
       | I'm a little confused at the part about decorative attributes
       | being done outside of the editing transaction, saying "And they
       | are not even aware of the transaction since they live in the
       | NSLayoutManager itself, not in NSTextStorage". Decorative
       | attributes like color do normally live in the NSTextStorage! Is
       | the author implying that the colors applied to markdown
       | characters are being done with NSLayoutManager's temporary
       | attributes support (typically used to color misspelled words)?
       | What would be the purpose of that?
        
         | papereditor wrote:
         | Yes. NSTextStorage can also contain the same attributes as the
         | temporary attributes (rendering attributes in TextKit 2).
         | 
         | The benefit of using temporary attributes is that changing them
         | is very fast compared to invoking the full transaction on
         | NSTextStorage. For example, switching between Light/Dark modes
         | is very fast in Paper.
        
           | lilyball wrote:
           | I would have expected a transaction to track whether any
           | changes affect layout and avoid invalidating layout if only
           | changing rendering attributes. I assume you've actually
           | measured this though, and so I have to infer that this
           | optimization does not in fact happen.
        
             | papereditor wrote:
             | Things might have changed already, but yes, when I measured
             | it there was a noticeable difference.
             | 
             | Ideally, I would have expected it to behave like you have
             | described.
        
       | CaesarA wrote:
       | As someone who has attempted to write their own text editor
       | completely from scratch before, this would've been a tremendous
       | resource to have.
        
         | papereditor wrote:
         | Thank you!
        
       | anonymouse008 wrote:
       | Haha! Love this so much.
       | 
       | Did you ever have to store custom metadata in NSAS to file?
       | Before chatGPT, I had to write NSSecureCoding classes by hand,
       | and that agony will remain in my soul next incarnation.
        
         | papereditor wrote:
         | Thanks!
         | 
         | I am offloading all the storage to NSDocument, so I don't have
         | to deal with stuff like this. :)
        
       | personjerry wrote:
       | I wish there was documentation like this for more ios components!
        
         | papereditor wrote:
         | Thanks!
        
       | justinzollars wrote:
       | Awesome description! Thank you!
        
         | papereditor wrote:
         | Thanks!
        
       | xenodium wrote:
       | Anyone know of a similarly well crafted app for Android?
        
         | papereditor wrote:
         | iA Writer (https://ia.net/writer) is on Android as well.
        
           | xenodium wrote:
           | Thank you!
        
       | indemnity wrote:
       | What a great article (and personally timely, wrangling
       | NSTextViews at the moment).
       | 
       | How did you glean the information needed to write this? Other
       | people's code? Painful experience? developer.apple.com?
        
         | papereditor wrote:
         | Thanks!
         | 
         | I've been working on Paper for 9 years. I've had a lot of time
         | to study how everything works. :D
        
       | russellbeattie wrote:
       | Imagine going through all that effort, and then saving the output
       | in Markdown. It's like finishing your astrophysics PhD and then
       | getting a lobotomy.
       | 
       | Just to repeat my years-long crusade of yelling at clouds, _we
       | need a cross platform, Rich Text HTML Document standard_.
        
         | jitl wrote:
         | Isn't that "just" HTML? What should be added to HTML?
        
           | russellbeattie wrote:
           | Sorry, a little late with my reply.
           | 
           | It's mostly about _removing_ stuff from HTML - JavaScript,
           | forms, and various CSS features - to make it focus on simple
           | formatting. Then requiring the appropriate CSP security
           | constraints to ensure privacy /security. Finally,
           | standardizing on a way to include binary files (images, etc.)
           | in the format using a JSON blob at the end of the text which
           | can be referenced above.
           | 
           | Self contained, document focused, cross platform, secure and
           | private, while still being standard HTML. Would replace ePub,
           | .docx, Markdown, and provide a standard file format for
           | Google Docs to export to.
        
       | userbinator wrote:
       | _The TextEdit app consists almost entirely of a single TextView_
       | 
       | I believe WordPad is the Windows equivalent, based on the
       | RichEdit control.
       | 
       |  _Another fun fact is that RTF is basically the serialized form
       | of NSAttributedString._
       | 
       | The same is true of Windows' RichEdit control. In fact, it looks
       | like Windows' implementation came first:
       | https://en.wikipedia.org/wiki/Rich_Text_Format
        
         | papereditor wrote:
         | Interesting facts!
        
       | kaichanvong wrote:
       | casual opinion; To the App developer (Mihhail L/@_mihhail?)
       | themselves, to say: Loved just how it keeps itself, everything-
       | from-the emoji of engineering, engi-peeping, mechanical heading-
       | towards focus on screen/container mixed with data storage.
       | 
       | Never certain how it keeps for scrolling; the issue lies in drag,
       | doomscrolls, scrollbar versus tap-for-scrolling... now, on topic
       | of moving on: "a good OS citizen, you should provide many
       | formats", not keen on everything/too-many Media Formats keeping
       | it sweet, simple; some of these Apps can become almost utility
       | goto. Some of my favourites, include emoji meets paste formatting
       | issues in export. How do they render correctly the almost,
       | "interstitial flickering" change.
       | 
       | My expectations paused at Themes/Theming (not really happening?
       | different looks) no simple mention of light Vs. dark; willow
       | filter adjustment tones? Okay! Still, amazement. I believe, we
       | choose our (kind of) Paper whenever possible.
       | 
       | ...Thanks!
       | 
       | All the kindest of regards, from reading nerdy happenings! Kai V
       | (@kaichanvong)
        
       | grishka wrote:
       | For me, as a long-time Android app developer, it was interesting
       | to see how Apple approaches things somewhat differently and more
       | thoughtfully.
       | 
       | On Android, you basically have the Layout class (and its
       | subclasses) that does _everything_ related to both layout and
       | rendering, and TextView which implements some of the editing
       | /selection logic. The only difference between EditText and
       | TextView is that EditText _enables_ that editing functionality
       | already present in TextView. The problem with this rather
       | monolithic approach (and poor APIs) is that if you need more
       | control over how your app renders text, you 're out of luck. Want
       | to get at the individual glyphs after they've been laid out for
       | example? Nope, sorry.
        
       | Ezhik wrote:
       | Oh thank god at least somebody is doing Cocoa in 2024.
        
       ___________________________________________________________________
       (page generated 2024-03-06 23:02 UTC)