@@ -164,12 +164,23 @@ private extension Highlighter {
164164 treeSitterClient? . queryColorsFor ( range: nsRange) { [ weak self] highlightRanges in
165165 guard let attributeProvider = self ? . attributeProvider,
166166 let textView = self ? . textView else { return }
167+
168+ // Mark these indices as not pending and valid
167169 self ? . pendingSet. remove ( integersIn: range)
168170 self ? . validSet. formUnion ( IndexSet ( integersIn: range) )
171+
172+ // If this range does not exist in the visible set, we can exit.
169173 if !( self ? . visibleSet ?? . init( ) ) . contains ( integersIn: range) {
170174 return
171175 }
172176
177+ // Try to create a text range for invalidating. If this fails we fail silently
178+ guard let textContentManager = textView. textLayoutManager. textContentManager,
179+ let textRange = NSTextRange ( nsRange, provider: textContentManager) else {
180+ return
181+ }
182+
183+ // Loop through each highlight and modify the textStorage accordingly.
173184 textView. textContentStorage. textStorage? . beginEditing ( )
174185 for highlight in highlightRanges {
175186 textView. textContentStorage. textStorage? . setAttributes (
@@ -178,6 +189,10 @@ private extension Highlighter {
178189 )
179190 }
180191 textView. textContentStorage. textStorage? . endEditing ( )
192+
193+ // After applying edits to the text storage we need to invalidate the layout
194+ // of the highlighted text.
195+ textView. textLayoutManager. invalidateLayout ( for: textRange)
181196 }
182197 }
183198
@@ -211,7 +226,6 @@ private extension Highlighter {
211226 for range in newlyInvalidSet. rangeView. map ( { NSRange ( $0) } ) {
212227 invalidate ( range: range)
213228 }
214-
215229 }
216230}
217231
0 commit comments