krz/orgstar

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

docs/plans/2026-10-05-structure.md

main
orgstar/docs/plans/2026-10-05-structure.md rendered · source · history · blame · raw

47 lines · 3494 bytes

6 symbols in this file
 1# Heading Structure Commands Implementation Plan
 2
 3> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
 4
 5**Goal:** Org's heading structure commands, byte- and caret-exact against Emacs: insert heading (M-RET, C-RET, M-S-RET), move subtree (M-up/down), promote/demote subtree (M-S-left/right), heading motion (C-c C-n/p/f/b/u) and set tags (C-c C-q) through a prompt answered in the echo area.
 6
 7**Architecture:** Multi-line commands are ported from Org 9.8.7's Lisp onto `EmacsBuffer`, a whole-text buffer with Emacs's point and marker rules (`insert`, `insert-before-markers`, `delete-region`, `replace-match`, `save-excursion`) and org's regexp-based outline primitives. `commitBuffer` turns the result into one minimal edit and the caret. Motion commands skip headings inside `EditContext.hidden` (folded text). Prompts go from `CommandStep.prompt` through `OrgEditor.onPrompt` to a minibuffer field in the echo area; the answer reruns the command.
 8
 9**Tech Stack:** Swift 6.2 tools, Swift Testing, Emacs 31.1 / Org 9.8.7 oracle.
10
11**Spec:** `docs/design.md`, "Commands and keymaps".
12
13## Global Constraints
14
15- Org defaults: `org-blank-before-new-entry` heading `auto`, `org-M-RET-may-split-line` t, `org-auto-align-tags` t, tags column -77.
16- The oracle unfolds the buffer after `org-mode` (`#+STARTUP` may fold it); cases run with everything visible.
17- In plain lists, M-RET and M-S-RET insert items in org; list commands come in the next plan.
18
19## Defaults chosen (user may change)
20
21- Mac preset: ⌘↩ insert heading, ⌃⌘↩ after subtree, ⇧⌘↩ TODO heading, ⌃⌥⌘ arrows move/promote/demote subtree, ⌥⌘↑/↓ previous/next heading, ⌃⌘Q tags.
22- The tags prompt has no completion yet.
23
24## File structure
25
26| File | Responsibility |
27| --- | --- |
28| `Sources/OrgCore/Commands/EmacsBuffer.swift` | Buffer with point and markers, outline primitives, regexps, `commitBuffer` |
29| `Sources/OrgCore/Commands/StructureCommands.swift` | Insert, move, promote/demote subtree, motion |
30| `Sources/OrgCore/Commands/TagCommands.swift` | `SetTags` |
31| `Sources/OrgCore/Commands/Command.swift` | `EditContext.hidden`, `Prompt.initial` |
32| `Sources/OrgEditorAppKit/OrgEditor.swift` | Hidden ranges in the context, `onPrompt` |
33| `Sources/Orgstar/*.swift` | Prompt in the echo area |
34
35---
36
37### Task 1: Buffer and structure commands
38
39- [ ] Port `org-insert-heading` (with `org--blank-before-heading-p`, `org-N-empty-lines-before-current`), `org-insert-todo-heading`, `org-move-subtree-down`, `org-promote-subtree`/`org-demote-subtree` (`org-map-tree`, `org-promote`, `org-demote`, `org-fix-position-after-promote`), `org-next-visible-heading`, `org-forward-heading-same-level`, `outline-up-heading`.
40- [ ] Oracle: every command at every caret of ten variants (levels, blank lines, tags, text before the first heading, no final newline, non-BMP) and over the corpus (`ORGSTAR_ORACLE_CORPUS`, files up to 20 KB).
41- [ ] Commit "Port heading structure commands from org".
42
43### Task 2: Tags and prompts
44
45- [ ] `SetTags`: prompt with the current tags, then `org-set-tags` semantics (realign even when unchanged). Oracle with `completing-read-multiple` stubbed to the answer.
46- [ ] Editor `onPrompt`; app minibuffer field (Return answers, Escape cancels); key bindings in both presets.
47- [ ] Commit "Set tags through a prompt".