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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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?
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.
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.
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.
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.
92 comments
[ 0.32 ms ] story [ 192 ms ] threadhttps://news.ycombinator.com/item?id=38866170
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.
For multi-megabyte files I always use Sublime.
The MarkEdit team uses WebView and have strong opinions about why.
The average user does not care.
https://github.com/simonbs/Runestone
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.
Yep, it's a win-win. A good resource plus a bit of marketing for the product.
Great post btw!
The state is saved to local storage. Just delete the key from DevTools and they will come back. :D
"paper writing app" is a good keyword to search by.
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.
I want to migrate Paper to it this or next year.
Incredible article btw
With attributes strings it’s trivial, you just need to move attributes accordingly and to normalize stuff at the end.
The document-based app template gets you a lot for “free” too, including tabs and conversion of windows into tabs and vice versa.
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.
I'll be sure to prioritize this work then. :D
Comments are now hidden in the Preview Mode.
I've also added the comment block feature (%%) like in Ulysses:
https://help.ulysses.app/en_US/guides/comments-notes-annotat...
Shortcuts:
- Comment: Command+T
- Comment Block: Shift+Command+T
Adjusting the preferred comment syntax:
- Mac: Go to the Format menu, hold the Option key, then under More Formatting below Comment you can pick either ++ or /**/
- iOS: Go to the Settings app, then under Paper > Markdown pick either ++ or /**/
It's a shame because otherwise the presentation is really good.
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…
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.
Ideally, I would have expected it to behave like you have described.
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.
I am offloading all the storage to NSDocument, so I don't have to deal with stuff like this. :)
How did you glean the information needed to write this? Other people’s code? Painful experience? developer.apple.com?
I've been working on Paper for 9 years. I've had a lot of time to study how everything works. :D
Just to repeat my years-long crusade of yelling at clouds, we need a cross platform, Rich Text HTML Document standard.
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.