krz/orgstar

A native macOS editor for org-mode files. editor org-mode swift

Sources/OrgEditorAppKit/EditorCommands.swift

176fc78498d9ba962fa963bbeca0dd433d9e0bab
orgstar/Sources/OrgEditorAppKit/EditorCommands.swift history · blame · raw

103 lines · 5680 bytes

  1#if os(macOS)
  2import OrgCore
  3
  4/// Every command a key, menu or the palette can run, by id.
  5public struct EditorCommand: Sendable {
  6    public enum Action: Sendable {
  7        /// An `OrgCore` command, run through `OrgEditor.perform`.
  8        case text(any OrgCommand)
  9        /// Folding and other view changes the editor makes itself.
 10        case view
 11        /// A text-system action; `extending` is its variant that extends the selection, used
 12        /// while a mark is active.
 13        case edit(selector: String, extending: String? = nil)
 14        /// Mark handling in the editor.
 15        case mark
 16        /// Handled by the app (save, quick open, palette).
 17        case app
 18    }
 19
 20    public let id: String
 21    public let title: String
 22    public let action: Action
 23
 24    /// Shown in the palette; text-system movement and editing are left to keys.
 25    public var inPalette: Bool {
 26        switch action {
 27        case .edit, .mark: false
 28        default: true
 29        }
 30    }
 31}
 32
 33public enum EditorCommands {
 34    public static let all: [EditorCommand] = Commands.everything.map { EditorCommand(id: $0.id, title: $0.title, action: .text($0)) } + [
 35        EditorCommand(id: "org.cycle", title: "Cycle Visibility", action: .view),
 36        EditorCommand(id: "org.cycle-global", title: "Cycle Global Visibility", action: .view),
 37
 38        EditorCommand(id: "app.save", title: "Save", action: .app),
 39        EditorCommand(id: "app.quit", title: "Quit Orgstar", action: .app),
 40        EditorCommand(id: "app.quick-open", title: "Quick Open…", action: .app),
 41        EditorCommand(id: "app.palette", title: "Command Palette…", action: .app),
 42        EditorCommand(id: "app.search", title: "Search Notes", action: .app),
 43        EditorCommand(id: "app.reload-keymap", title: "Reload Keymap", action: .app),
 44        EditorCommand(id: "app.refile", title: "Refile…", action: .app),
 45        EditorCommand(id: "app.archive", title: "Archive Subtree", action: .app),
 46        EditorCommand(id: "app.agenda", title: "Agenda", action: .app),
 47        EditorCommand(id: "app.capture", title: "Capture…", action: .app),
 48        EditorCommand(id: "app.board", title: "Board", action: .app),
 49        EditorCommand(id: "app.clock.in", title: "Clock In", action: .app),
 50        EditorCommand(id: "app.clock.out", title: "Clock Out", action: .app),
 51        EditorCommand(id: "app.clock.cancel", title: "Cancel Clock", action: .app),
 52        EditorCommand(id: "app.clock.goto", title: "Go to Clocked Entry", action: .app),
 53        EditorCommand(id: "app.clock.report", title: "Clock Report", action: .app),
 54        EditorCommand(id: "app.export.html", title: "Export to HTML", action: .app),
 55        EditorCommand(id: "app.export.html-open", title: "Export to HTML and Open", action: .app),
 56        EditorCommand(id: "app.export.markdown", title: "Export to Markdown", action: .app),
 57        EditorCommand(id: "app.export.pdf", title: "Export to PDF with Emacs", action: .app),
 58        EditorCommand(id: "app.export.odt", title: "Export to ODT with Emacs", action: .app),
 59        EditorCommand(id: "app.export.latex", title: "Export to LaTeX with Emacs", action: .app),
 60        EditorCommand(id: "app.export.text", title: "Export to Plain Text with Emacs", action: .app),
 61
 62        movement("forward-char", "Forward Character", "moveForward:"),
 63        movement("backward-char", "Backward Character", "moveBackward:"),
 64        movement("next-line", "Next Line", "moveDown:"),
 65        movement("previous-line", "Previous Line", "moveUp:"),
 66        movement("beginning-of-line", "Beginning of Line", "moveToBeginningOfParagraph:"),
 67        movement("end-of-line", "End of Line", "moveToEndOfParagraph:"),
 68        movement("forward-word", "Forward Word", "moveWordForward:"),
 69        movement("backward-word", "Backward Word", "moveWordBackward:"),
 70        movement("beginning-of-buffer", "Beginning of Buffer", "moveToBeginningOfDocument:"),
 71        movement("end-of-buffer", "End of Buffer", "moveToEndOfDocument:"),
 72        movement("scroll-up", "Scroll Up", "pageDown:"),
 73        movement("scroll-down", "Scroll Down", "pageUp:"),
 74        edit("recenter", "Recenter", "centerSelectionInVisibleArea:"),
 75        edit("delete-char", "Delete Character", "deleteForward:"),
 76        edit("kill-word", "Kill Word", "deleteWordForward:"),
 77        edit("backward-kill-word", "Kill Word Backward", "deleteWordBackward:"),
 78        edit("kill-line", "Kill Line", "deleteToEndOfParagraph:"),
 79        edit("yank", "Yank", "yank:"),
 80        edit("select-all", "Select All", "selectAll:"),
 81        edit("kill-region", "Kill Region", "cut:"),
 82        edit("copy-region", "Copy Region", "copy:"),
 83        edit("undo", "Undo", "undo:"),
 84        edit("transpose-chars", "Transpose Characters", "transpose:"),
 85        edit("find", "Find", "performTextFinderAction:"),
 86        EditorCommand(id: "edit.set-mark", title: "Set Mark", action: .mark),
 87        EditorCommand(id: "edit.keyboard-quit", title: "Quit", action: .mark),
 88    ]
 89
 90    private static func movement(_ name: String, _ title: String, _ selector: String) -> EditorCommand {
 91        let extending = String(selector.dropLast()) + "AndModifySelection:"
 92        return EditorCommand(id: "edit.\(name)", title: title, action: .edit(selector: selector, extending: extending))
 93    }
 94
 95    private static func edit(_ name: String, _ title: String, _ selector: String) -> EditorCommand {
 96        EditorCommand(id: "edit.\(name)", title: title, action: .edit(selector: selector))
 97    }
 98
 99    private static let byID = Dictionary(uniqueKeysWithValues: all.map { ($0.id, $0) })
100
101    public static func command(_ id: String) -> EditorCommand? { byID[id] }
102}
103#endif