                 }
                 
                 // cache result if whole text was parsed
-                if highlightRange == wholeRange {
+                if highlightRange == string.nsRange {
                     self?.highlightCache = Cache(styleName: styleName, string: string, highlights: highlights)
                 }
                 
                 self?.textStorage.apply(highlights: highlights, range: highlightRange)
                 
                 progress.completedUnitCount += 1
+                
+                completionHandler()
             }
         }
         

    // MARK: Private Methods
    
    /// perform highlighting
    private func highlight(string: String, range highlightRange: NSRange, completionHandler: @escaping (() -> Void) = {}) -> Progress? {
        
        assert(Thread.isMainThread)
        assert(!(string as NSString).className.contains("MutableString"))
        
        guard !highlightRange.isEmpty, !self.style.isNone else { return nil }
        
        // just clear current highlight and return if no coloring needs
        guard self.style.hasHighlightDefinition else {
            self.textStorage.apply(highlights: [:], range: highlightRange)
            completionHandler()
            return nil
        }
        
        let wholeRange = string.nsRange
        let styleName = self.style.name
        
        let definition = SyntaxHighlightParseOperation.ParseDefinition(extractors: self.style.highlightExtractors,
                                                                       pairedQuoteTypes: self.style.pairedQuoteTypes,

            }
        }
        
        operation.completionBlock = { [weak self, weak operation, styleName = self.style.name] in
            guard
                let highlights = operation?.highlights,
                let progress = operation?.progress,
                !progress.isCancelled
                else {
                    if let observer = modificationObserver {
                        NotificationCenter.default.removeObserver(observer)
                    }
                    return
                }
            
            DispatchQueue.main.async {
                defer {
                    if let observer = modificationObserver {
                        NotificationCenter.default.removeObserver(observer)
                    }
                }
                
                guard !isModified.value else {
