feat: improve note formatting shortcuts and code styling

This commit is contained in:
2026-10-22 09:35:51 +02:00
parent 5065ba59bd
commit 665691ddee
5 changed files with 87 additions and 22 deletions
+56 -4
View File
@@ -7,7 +7,7 @@ import Testing
func noteFormattingHidesSyntaxButPreservesMarkdownAndLiteralCode() throws {
_ = NSApplication.shared
let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 600, height: 800))
let source = "# Heading\n## Subheading\n*italic* **bold** _emphasis_ __strong__ ~~gone~~ `*literal*`\n> Quote\n[Label](https://example.com)\n```text\n# Code *literal*\n```\nUnmatched * and \\*escaped*"
let source = "# Heading\n## Subheading\n*italic* **bold** _emphasis_ __strong__ ~~gone~~ <u>underlined</u> `*literal*`\n> Quote\n[Label](https://example.com)\n```text\n# Code *literal*\n```\nUnmatched * and \\*escaped*"
editor.setMarkdownContents(NSAttributedString(string: source))
MarkdownHighlighting.apply(to: editor)
editor.refreshTasks()
@@ -25,7 +25,7 @@ func noteFormattingHidesSyntaxButPreservesMarkdownAndLiteralCode() throws {
}
return result
}
#expect(visibleText() == "Heading\nSubheading\nitalic bold emphasis strong gone *literal*\nQuote\nLabel\n\n# Code *literal*\n\nUnmatched * and \\*escaped*")
#expect(visibleText() == "Heading\nSubheading\nitalic bold emphasis strong gone underlined *literal*\nQuote\nLabel\n```text\n# Code *literal*\n```\nUnmatched * and \\*escaped*")
#expect(editor.markdownString == source)
editor.setSelectedRange(NSRange(location: 0, length: editor.string.utf16.count))
let pasteboard = NSPasteboard.withUniqueName()
@@ -247,9 +247,32 @@ func notesFormattingShortcutsToggleCombinedStylesAndRespectPopupFocus() throws {
#expect(try shortcut("b"))
#expect(editor.markdownString == "fox 🦊")
#expect(try shortcut("x", shift: true))
#expect(try shortcut("s", shift: true))
#expect(editor.markdownString == "~~fox 🦊~~")
#expect(try shortcut("x", shift: true))
#expect(editor.textStorage?.attribute(.strikethroughStyle, at: editor.selectedRange().location,
effectiveRange: nil) as? Int == NSUnderlineStyle.single.rawValue)
#expect(try shortcut("s", shift: true))
#expect(editor.markdownString == "fox 🦊")
editor.breakUndoCoalescing()
editor.undoManager?.removeAllActions()
editor.undoManager?.beginUndoGrouping()
#expect(try shortcut("u", shift: true))
editor.undoManager?.endUndoGrouping()
#expect(editor.markdownString == "<u>fox 🦊</u>")
#expect(editor.textStorage?.attribute(.underlineStyle, at: editor.selectedRange().location,
effectiveRange: nil) as? Int == NSUnderlineStyle.single.rawValue)
#expect(controller.save())
#expect(try NotesStore(directory: directory).notes.first?.contents.string == "<u>fox 🦊</u>")
#expect(try NoteMarkdownExport(contents: editor.markdownContents).clipboardText == "<u>fox 🦊</u>")
editor.undoManager?.undo()
#expect(editor.markdownString == "fox 🦊")
#expect(try shortcut("u", shift: true))
#expect(try shortcut("u", shift: true))
#expect(editor.markdownString == "fox 🦊")
#expect(editor.textStorage?.attribute(.underlineStyle, at: 0, effectiveRange: nil) == nil)
#expect(try shortcut("l", shift: true))
#expect(editor.markdownString == "- fox 🦊")
#expect(try shortcut("l", shift: true))
#expect(editor.markdownString == "fox 🦊")
#expect(!(try shortcut("b", option: true)))
#expect(editor.markdownString == "fox 🦊")
@@ -272,3 +295,32 @@ func notesFormattingShortcutsToggleCombinedStylesAndRespectPopupFocus() throws {
#expect(controller.save())
#expect(try NotesStore(directory: directory).notes.first?.contents.string == "fox 🦊")
}
@Test @MainActor
func inlineCodeContainerStaysWithinCodeAndDisappearsWhenDelimitersAreRemoved() throws {
_ = NSApplication.shared
let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 200, height: 300))
let source = "Before `some *literal* code 🦊` after\n```text\n`not inline` <u>literal</u>\n```"
editor.setMarkdownContents(NSAttributedString(string: source))
let storage = try #require(editor.textStorage)
let layout = try #require(editor.layoutManager)
layout.ensureLayout(for: try #require(editor.textContainer))
let body = (source as NSString).range(of: "some *literal* code 🦊")
for index in body.location..<NSMaxRange(body) {
#expect(storage.attribute(.foregroundColor, at: index, effectiveRange: nil) as? NSColor == SunsetPalette.accent)
#expect(storage.attribute(.backgroundColor, at: index, effectiveRange: nil) as? NSColor == SunsetPalette.selectionFill)
}
for token in ["Before", "after", "not inline"] {
let index = (source as NSString).range(of: token).location
#expect(storage.attribute(.backgroundColor, at: index, effectiveRange: nil) == nil)
}
let literalUnderline = (source as NSString).range(of: "<u>literal</u>")
#expect(storage.attribute(.underlineStyle, at: literalUnderline.location, effectiveRange: nil) == nil)
#expect(editor.markdownString == source)
#expect(editor.markdownContents.attribute(.backgroundColor, at: body.location, effectiveRange: nil) == nil)
editor.replaceMarkdown("some *literal* code 🦊",
range: NSRange(location: body.location - 1, length: body.length + 2))
let plain = (editor.string as NSString).range(of: "some")
#expect(storage.attribute(.backgroundColor, at: plain.location, effectiveRange: nil) == nil)
#expect(storage.attribute(.foregroundColor, at: plain.location, effectiveRange: nil) as? NSColor == SunsetPalette.text)
}