         
         self.textStorage = textStorage
         self.style = style
+        
+        // give up if the string is changed while parsing
+        self.textEditingObserver = NotificationCenter.default.publisher(for: NSTextStorage.willProcessEditingNotification, object: textStorage)
+            .map { $0.object as! NSTextStorage }
+            .filter { $0.editedMask.contains(.editedCharacters) }
+            .sink { [weak self] _ in self?.syntaxHighlightParseOperationQueue.cancelAllOperations() }
     }
     
     

    
    private var highlightCache: Cache?  // results cache of the last whole string highlights
    
    
    
    // MARK: -

        
        let operation = SyntaxHighlightParseOperation(definition: definition, string: string, range: highlightRange)
        
        operation.completionBlock = { [weak self, weak operation, styleName = self.style.name] in
            guard
                let highlights = operation?.highlights,
                let progress = operation?.progress,
                !progress.isCancelled
                else { return }
            
            DispatchQueue.main.async {
                guard !progress.isCancelled else { return }
                
                if highlightRange == string.nsRange {
                    self?.highlightCache = Cache(styleName: styleName, string: string, highlights: highlights)
                }
