Custom NSTextContentManager? #79
Replies: 3 comments 3 replies
-
to some degree. I was working toward this goal, then at one point I realized I needed some thing akin to if you have |
Beta Was this translation helpful? Give feedback.
-
Thanks for the fast reply. Your talks and work here have been a big help. My use case involves a SQLite table in which each row could map directly to an NSTextElement (paragraph, heading, list item, figure, etc.) in documents that may have hundreds of pages. The rows do not have plain text. Each needs to be parsed. This “word processor” usage looks more like @danielsaidi’s RichTextKit, I think, than STTextView. I’d love to contribute a PR to STTextView with alternate storage support but I think the smart move is first to evaluate what the performance really looks like to fetch, parse and concatenate all the rows to NSAttributedString and the effort of mapping changes back to the rows. If that gets stupid then I’ll try harder with custom storage, based on STTextView. |
Beta Was this translation helpful? Give feedback.
-
Oh as someone who's been down this road, good luck. I've been experimenting with building a custom backing store for an AST like data model and subclassing For instance in TextKit 2 everything begins with the NSTextElementProvider interface and e.g. given this signature: func enumerateTextElements(
from textLocation: (any NSTextLocation)?,
options: NSTextContentManager.EnumerationOptions = [],
using block: (NSTextElement) -> Bool
) -> (any NSTextLocation)? The docs say:
Maybe it's just me, but what exactly is meant by the "edge" with respect to either forward or backward enumeration? Also I suppose it's not that big of a deal but why is a returned Personally I think NSTextElementProvider is the worst part of TextKit 2. For one it assumes that all implementors want such an API that also encompasses document modifications which IMO should be specific to a given backing store and should overall be outside the scope of a generalized text rendering interface (especially since some use cases may only require read-only functionality). Personally I think a lazy iterator like API would be far better. Something like: public protocol ForwardElementIterator<Element> {
associatedtype Element
mutating func next() -> Self.Element?
}
public protocol BackwardElementIterator<Element> {
associatedtype Element
mutating func next() -> Self.Element?
}
public protocol ElementIteratorProvider<Element> {
associatedtype Element:
SSDocumentRange
associatedtype ForwardIterator:
ForwardElementIterator<Element>
associatedtype BackwardIterator:
BackwardElementIterator<Element>
func makeForwardIterator(
startingFrom startIndex: Element.Index
) -> ForwardIterator
func makeBackwardIterator(
startingFrom startIndex: Element.Index
) -> BackwardIterator
} Or use a zipper like API for more uniform forward/backward traversal: public protocol SSElementZipper<Element> {
associatedtype Element: SSDocumentRange
mutating func seek(to position: Element.Index)
mutating func forward() -> Self.Element?
mutating func backward() -> Self.Element?
var currentElement: Element? { get }
var firstElement: Element? { get }
var lastElement: Element? { get }
} Where each element records its logical range in the parent document (via SSDocumentRange) and its index with respect to other top-level elements (i.e. Perhaps TextKit shouldn't even need to know the whole document range in favor of just fetching and rendering content via some iterator or zipper like API. But I digress... (I've been trying to figure out how to build a higher level interface upon TextKit 2 for more custom document data models.) Anyway I apologize for the rant. Perhaps there were some helpful tidbits with regard to your problem... IMO learn from my mistakes and just figure out how to make TextKit 2 work with the preexisting |
Beta Was this translation helpful? Give feedback.
-
Does STTextView allow use of a NSTextContantManager subclass that does not use NSTextStorage?
That seems to be implied in the old Apple Developer thread but I don’t see that explicit option here.
Beta Was this translation helpful? Give feedback.
All reactions