format-aware highlighting: code files get code mode, others fall back to Cordial/markdown
This commit is contained in:
parent
3d20668edc
commit
977874cd22
|
|
@ -908,6 +908,7 @@ struct EditorView: View {
|
||||||
EditorTextView(
|
EditorTextView(
|
||||||
text: bodyBinding,
|
text: bodyBinding,
|
||||||
evalResults: offsetEvalResults(state.evalResults),
|
evalResults: offsetEvalResults(state.evalResults),
|
||||||
|
fileFormat: state.currentFileFormat,
|
||||||
onEvaluate: { state.evaluate() },
|
onEvaluate: { state.evaluate() },
|
||||||
onBackspaceAtStart: {
|
onBackspaceAtStart: {
|
||||||
NotificationCenter.default.post(name: .focusTitle, object: nil)
|
NotificationCenter.default.post(name: .focusTitle, object: nil)
|
||||||
|
|
@ -928,6 +929,7 @@ struct EditorView: View {
|
||||||
struct EditorTextView: NSViewRepresentable {
|
struct EditorTextView: NSViewRepresentable {
|
||||||
@Binding var text: String
|
@Binding var text: String
|
||||||
var evalResults: [Int: String]
|
var evalResults: [Int: String]
|
||||||
|
var fileFormat: FileFormat = .markdown
|
||||||
var onEvaluate: () -> Void
|
var onEvaluate: () -> Void
|
||||||
var onBackspaceAtStart: (() -> Void)? = nil
|
var onBackspaceAtStart: (() -> Void)? = nil
|
||||||
|
|
||||||
|
|
@ -983,7 +985,7 @@ struct EditorTextView: NSViewRepresentable {
|
||||||
|
|
||||||
if let ts = textView.textStorage {
|
if let ts = textView.textStorage {
|
||||||
ts.beginEditing()
|
ts.beginEditing()
|
||||||
applySyntaxHighlighting(to: ts)
|
applySyntaxHighlighting(to: ts, format: fileFormat)
|
||||||
ts.endEditing()
|
ts.endEditing()
|
||||||
}
|
}
|
||||||
textView.typingAttributes = [
|
textView.typingAttributes = [
|
||||||
|
|
@ -1007,7 +1009,7 @@ struct EditorTextView: NSViewRepresentable {
|
||||||
textView.string = text
|
textView.string = text
|
||||||
if let ts = textView.textStorage {
|
if let ts = textView.textStorage {
|
||||||
ts.beginEditing()
|
ts.beginEditing()
|
||||||
applySyntaxHighlighting(to: ts)
|
applySyntaxHighlighting(to: ts, format: fileFormat)
|
||||||
ts.endEditing()
|
ts.endEditing()
|
||||||
}
|
}
|
||||||
textView.selectedRanges = selectedRanges
|
textView.selectedRanges = selectedRanges
|
||||||
|
|
@ -1056,7 +1058,7 @@ struct EditorTextView: NSViewRepresentable {
|
||||||
.foregroundColor: palette.text
|
.foregroundColor: palette.text
|
||||||
]
|
]
|
||||||
ts.beginEditing()
|
ts.beginEditing()
|
||||||
applySyntaxHighlighting(to: ts)
|
applySyntaxHighlighting(to: ts, format: parent.fileFormat)
|
||||||
ts.endEditing()
|
ts.endEditing()
|
||||||
tv.needsDisplay = true
|
tv.needsDisplay = true
|
||||||
}
|
}
|
||||||
|
|
@ -1077,7 +1079,7 @@ struct EditorTextView: NSViewRepresentable {
|
||||||
parent.text = tv.string
|
parent.text = tv.string
|
||||||
let sel = tv.selectedRanges
|
let sel = tv.selectedRanges
|
||||||
ts.beginEditing()
|
ts.beginEditing()
|
||||||
applySyntaxHighlighting(to: ts)
|
applySyntaxHighlighting(to: ts, format: parent.fileFormat)
|
||||||
ts.endEditing()
|
ts.endEditing()
|
||||||
tv.typingAttributes = [
|
tv.typingAttributes = [
|
||||||
.font: Theme.editorFont,
|
.font: Theme.editorFont,
|
||||||
|
|
@ -1175,7 +1177,7 @@ struct EditorTextView: NSViewRepresentable {
|
||||||
let sel = tv.selectedRanges
|
let sel = tv.selectedRanges
|
||||||
ts.beginEditing()
|
ts.beginEditing()
|
||||||
ts.replaceCharacters(in: range, with: newMarkdown)
|
ts.replaceCharacters(in: range, with: newMarkdown)
|
||||||
applySyntaxHighlighting(to: ts)
|
applySyntaxHighlighting(to: ts, format: parent.fileFormat)
|
||||||
ts.endEditing()
|
ts.endEditing()
|
||||||
tv.selectedRanges = sel
|
tv.selectedRanges = sel
|
||||||
parent.text = tv.string
|
parent.text = tv.string
|
||||||
|
|
@ -1396,7 +1398,7 @@ private let syntaxBooleans: Set<String> = ["true", "false"]
|
||||||
|
|
||||||
private let syntaxOperatorChars = CharacterSet(charactersIn: "+-*/=^<>!(){}[]:,.&|%")
|
private let syntaxOperatorChars = CharacterSet(charactersIn: "+-*/=^<>!(){}[]:,.&|%")
|
||||||
|
|
||||||
func applySyntaxHighlighting(to textStorage: NSTextStorage) {
|
func applySyntaxHighlighting(to textStorage: NSTextStorage, format: FileFormat = .markdown) {
|
||||||
let text = textStorage.string
|
let text = textStorage.string
|
||||||
let fullRange = NSRange(location: 0, length: (text as NSString).length)
|
let fullRange = NSRange(location: 0, length: (text as NSString).length)
|
||||||
let palette = Theme.current
|
let palette = Theme.current
|
||||||
|
|
@ -1409,6 +1411,11 @@ func applySyntaxHighlighting(to textStorage: NSTextStorage) {
|
||||||
]
|
]
|
||||||
textStorage.setAttributes(baseAttrs, range: fullRange)
|
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 fencedRanges = highlightFencedCodeBlocks(textStorage: textStorage, palette: palette, baseFont: baseFont)
|
||||||
let tableHeaderLines = findTableHeaderLines(textStorage: textStorage, fencedRanges: fencedRanges)
|
let tableHeaderLines = findTableHeaderLines(textStorage: textStorage, fencedRanges: fencedRanges)
|
||||||
|
|
||||||
|
|
@ -1457,6 +1464,21 @@ func applySyntaxHighlighting(to textStorage: NSTextStorage) {
|
||||||
highlightAutolinks(textStorage: textStorage, palette: palette, fencedRanges: fencedRanges)
|
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 {
|
private func highlightMarkdownLine(_ trimmed: String, line: String, lineRange: NSRange, textStorage: NSTextStorage, baseFont: NSFont, palette: CatppuccinPalette, isTableHeader: Bool = false) -> Bool {
|
||||||
if trimmed.hasPrefix("### ") {
|
if trimmed.hasPrefix("### ") {
|
||||||
let hashRange = (textStorage.string as NSString).range(of: "###", range: lineRange)
|
let hashRange = (textStorage.string as NSString).range(of: "###", range: lineRange)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue