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

                    highlightRange.length = effectiveRange.upperBound - highlightRange.location
                }
            }
        }
        
        // use cache if the content of the whole document is the same as the last

        guard UserDefaults.standard[.enableSyntaxHighlight] else { return nil }
        guard !self.textStorage.string.isEmpty else { return nil }
        
        // in case that wholeRange length is changed from editedRange
        guard editedRange.flatMap({ $0.upperBound > self.textStorage.length }) != true else {
            assertionFailure("Invalid range is passed in to \(#function)")
            return nil
        }
        
        let wholeRange = self.textStorage.range
        let highlightRange: NSRange = {
            guard let editedRange = editedRange, editedRange != wholeRange else { return wholeRange }
            
            // highlight whole if string is enough short
            let bufferLength = UserDefaults.standard[.coloringRangeBufferLength]
            if wholeRange.length <= bufferLength {
                return wholeRange
            }
            
            // highlight whole visible area if edited point is visible
            var highlightRange = self.textStorage.layoutManagers
                .compactMap(\.textViewForBeginningOfSelection?.visibleRange)
                .filter { $0.intersects(editedRange) }
                .reduce(into: editedRange) { $0.formUnion($1) }
            
            highlightRange = (self.textStorage.string as NSString).lineRange(for: highlightRange)
            
