diff --git a/src/EditorView.swift b/src/EditorView.swift index eb0fa6f..d7db798 100644 --- a/src/EditorView.swift +++ b/src/EditorView.swift @@ -908,6 +908,7 @@ struct EditorView: View { EditorTextView( text: bodyBinding, evalResults: offsetEvalResults(state.evalResults), + fileFormat: state.currentFileFormat, onEvaluate: { state.evaluate() }, onBackspaceAtStart: { NotificationCenter.default.post(name: .focusTitle, object: nil) @@ -928,6 +929,7 @@ struct EditorView: View { struct EditorTextView: NSViewRepresentable { @Binding var text: String var evalResults: [Int: String] + var fileFormat: FileFormat = .markdown var onEvaluate: () -> Void var onBackspaceAtStart: (() -> Void)? = nil @@ -983,7 +985,7 @@ struct EditorTextView: NSViewRepresentable { if let ts = textView.textStorage { ts.beginEditing() - applySyntaxHighlighting(to: ts) + applySyntaxHighlighting(to: ts, format: fileFormat) ts.endEditing() } textView.typingAttributes = [ @@ -1007,7 +1009,7 @@ struct EditorTextView: NSViewRepresentable { textView.string = text if let ts = textView.textStorage { ts.beginEditing() - applySyntaxHighlighting(to: ts) + applySyntaxHighlighting(to: ts, format: fileFormat) ts.endEditing() } textView.selectedRanges = selectedRanges @@ -1056,7 +1058,7 @@ struct EditorTextView: NSViewRepresentable { .foregroundColor: palette.text ] ts.beginEditing() - applySyntaxHighlighting(to: ts) + applySyntaxHighlighting(to: ts, format: parent.fileFormat) ts.endEditing() tv.needsDisplay = true } @@ -1077,7 +1079,7 @@ struct EditorTextView: NSViewRepresentable { parent.text = tv.string let sel = tv.selectedRanges ts.beginEditing() - applySyntaxHighlighting(to: ts) + applySyntaxHighlighting(to: ts, format: parent.fileFormat) ts.endEditing() tv.typingAttributes = [ .font: Theme.editorFont, @@ -1175,7 +1177,7 @@ struct EditorTextView: NSViewRepresentable { let sel = tv.selectedRanges ts.beginEditing() ts.replaceCharacters(in: range, with: newMarkdown) - applySyntaxHighlighting(to: ts) + applySyntaxHighlighting(to: ts, format: parent.fileFormat) ts.endEditing() tv.selectedRanges = sel parent.text = tv.string @@ -1396,7 +1398,7 @@ private let syntaxBooleans: Set = ["true", "false"] private let syntaxOperatorChars = CharacterSet(charactersIn: "+-*/=^<>!(){}[]:,.&|%") -func applySyntaxHighlighting(to textStorage: NSTextStorage) { +func applySyntaxHighlighting(to textStorage: NSTextStorage, format: FileFormat = .markdown) { let text = textStorage.string let fullRange = NSRange(location: 0, length: (text as NSString).length) let palette = Theme.current @@ -1409,6 +1411,11 @@ func applySyntaxHighlighting(to textStorage: NSTextStorage) { ] textStorage.setAttributes(baseAttrs, range: fullRange) + if format.isCode { + applyCodeFileHighlighting(to: textStorage, syn: syn, baseFont: baseFont) + return + } + let fencedRanges = highlightFencedCodeBlocks(textStorage: textStorage, palette: palette, baseFont: baseFont) let tableHeaderLines = findTableHeaderLines(textStorage: textStorage, fencedRanges: fencedRanges) @@ -1457,6 +1464,21 @@ func applySyntaxHighlighting(to textStorage: NSTextStorage) { highlightAutolinks(textStorage: textStorage, palette: palette, fencedRanges: fencedRanges) } +private func applyCodeFileHighlighting(to textStorage: NSTextStorage, syn: Theme.SyntaxColors, baseFont: NSFont) { + let text = textStorage.string + let nsText = text as NSString + var lineStart = 0 + + while lineStart < nsText.length { + let lineRange = nsText.lineRange(for: NSRange(location: lineStart, length: 0)) + let line = nsText.substring(with: lineRange) + highlightCodeLine(line, lineRange: lineRange, textStorage: textStorage, syn: syn) + lineStart = NSMaxRange(lineRange) + } + + highlightBlockComments(textStorage: textStorage, syn: syn, baseFont: baseFont) +} + private func highlightMarkdownLine(_ trimmed: String, line: String, lineRange: NSRange, textStorage: NSTextStorage, baseFont: NSFont, palette: CatppuccinPalette, isTableHeader: Bool = false) -> Bool { if trimmed.hasPrefix("### ") { let hashRange = (textStorage.string as NSString).range(of: "###", range: lineRange)