feat: add modal Vim editing to notes

This commit is contained in:
2026-10-22 11:25:41 +02:00
parent 665691ddee
commit 615cbd6eb6
7 changed files with 781 additions and 5 deletions
+20 -1
View File
@@ -3,7 +3,7 @@ import AppKit
private let literalTaskMarker = NSAttributedString.Key("Conjure.literalTaskMarker")
private let sourceTaskAttachment = NSAttributedString.Key("Conjure.sourceTaskAttachment")
private let sourceListParagraph = NSAttributedString.Key("Conjure.sourceListParagraph")
private let listWhitespace = NSAttributedString.Key("Conjure.listWhitespace")
let listWhitespace = NSAttributedString.Key("Conjure.listWhitespace")
private final class ListAttachment: NSTextAttachment {
let source: NSAttributedString
@@ -61,12 +61,18 @@ final class NotesTextView: NSTextView, @MainActor NSLayoutManagerDelegate {
private var tasks: [(range: NSRange, attachment: ListAttachment)] = []
private var checkboxes: [NSButton] = []
private var horizontalSelection: (anchor: Int, head: Int)?
var vimState = NotesVimState()
var vimModeChanged: (() -> Void)?
var vimEnabled = false {
didSet { resetVim() }
}
var markdownContents: NSAttributedString { Self.serialize(attributedString()) }
var markdownString: String { markdownContents.string }
func setMarkdownContents(_ contents: NSAttributedString) {
horizontalSelection = nil
resetVim()
textStorage?.setAttributedString(Self.render(contents))
refreshTasks()
}
@@ -232,6 +238,7 @@ final class NotesTextView: NSTextView, @MainActor NSLayoutManagerDelegate {
}
override func keyDown(with event: NSEvent) {
if handleVimKey(event) { return }
if event.keyCode == 48,
event.modifierFlags.intersection([.command, .control, .option, .shift]) == .shift,
delegate?.textView?(self, doCommandBy: #selector(NSResponder.insertBacktab(_:))) == true {
@@ -240,6 +247,18 @@ final class NotesTextView: NSTextView, @MainActor NSLayoutManagerDelegate {
super.keyDown(with: event)
}
override func resignFirstResponder() -> Bool {
let resigned = super.resignFirstResponder()
if resigned { clearVimCommand() }
return resigned
}
override func mouseDown(with event: NSEvent) {
if vimEnabled && vimMode != .insert { resetVim() }
else { clearVimCommand() }
super.mouseDown(with: event)
}
override func insertText(_ insertString: Any, replacementRange: NSRange) {
let replacement: NSAttributedString
if let attributed = insertString as? NSAttributedString {