diff --git a/src/EditorView.swift b/src/EditorView.swift index b67d738..03bb068 100644 --- a/src/EditorView.swift +++ b/src/EditorView.swift @@ -1191,7 +1191,9 @@ func applySyntaxHighlighting(to textStorage: NSTextStorage) { continue } - highlightCodeLine(line, lineRange: lineRange, textStorage: textStorage, syn: syn) + if isCordialLine(trimmed) { + highlightCodeLine(line, lineRange: lineRange, textStorage: textStorage, syn: syn) + } highlightInlineCode(textStorage: textStorage, lineRange: lineRange, palette: palette, baseFont: baseFont) highlightStrikethrough(textStorage: textStorage, lineRange: lineRange, palette: palette) highlightFootnoteRefs(textStorage: textStorage, lineRange: lineRange, palette: palette) @@ -1266,6 +1268,7 @@ private func highlightMarkdownLine(_ trimmed: String, line: String, lineRange: N if isHorizontalRule(trimmed) { textStorage.addAttribute(.foregroundColor, value: palette.base, range: lineRange) + textStorage.addAttribute(.font, value: NSFont.systemFont(ofSize: 0.01), range: lineRange) return true } @@ -1446,15 +1449,37 @@ private func highlightBlockComments(textStorage: NSTextStorage, syn: Theme.Synta let text = textStorage.string let nsText = text as NSString let italicFont = NSFontManager.shared.convert(baseFont, toHaveTrait: .italicFontMask) + let len = nsText.length + guard len >= 4 else { return } - guard let regex = try? NSRegularExpression(pattern: "/\\*.*?\\*/", options: .dotMatchesLineSeparators) else { return } - let fullRange = NSRange(location: 0, length: nsText.length) - let matches = regex.matches(in: text, range: fullRange) - for match in matches { - textStorage.addAttributes([ - .foregroundColor: syn.comment, - .font: italicFont - ], range: match.range) + var i = 0 + while i < len - 1 { + if nsText.character(at: i) == 0x2F && nsText.character(at: i + 1) == 0x2A { // /* + let start = i + var depth = 1 + i += 2 + while i < len - 1 && depth > 0 { + let c = nsText.character(at: i) + let n = nsText.character(at: i + 1) + if c == 0x2F && n == 0x2A { // /* + depth += 1 + i += 2 + } else if c == 0x2A && n == 0x2F { // */ + depth -= 1 + i += 2 + } else { + i += 1 + } + } + if i > len { i = len } + let range = NSRange(location: start, length: i - start) + textStorage.addAttributes([ + .foregroundColor: syn.comment, + .font: italicFont + ], range: range) + } else { + i += 1 + } } } @@ -1686,6 +1711,23 @@ private func applyListIndent(line: String, lineRange: NSRange, textStorage: NSTe } } +private func isCordialLine(_ trimmed: String) -> Bool { + if trimmed.isEmpty { return false } + if trimmed.hasPrefix("/=") { return true } + if trimmed.hasPrefix("//") { return true } + if trimmed.hasPrefix("/*") { return true } + if trimmed.hasPrefix("let ") { + return trimmed.contains("=") + } + guard let eqIdx = trimmed.firstIndex(of: "=") else { return false } + if eqIdx == trimmed.startIndex { return false } + let after = trimmed.index(after: eqIdx) + if after < trimmed.endIndex && trimmed[after] == "=" { return false } + let before = trimmed[trimmed.index(before: eqIdx)] + if before == "!" || before == "<" || before == ">" { return false } + return true +} + private func isHorizontalRule(_ trimmed: String) -> Bool { if trimmed.isEmpty { return false } let stripped = trimmed.replacingOccurrences(of: " ", with: "")