Commit 60d94beed4
Verified · cmc
Layout: unified · split
docs/plans/2026-10-05-lists.md added +40
| @@ -0,0 +1,40 @@ | ||
| 1 | # Lists and Checkboxes 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 plain list commands, byte- and caret-exact against Emacs: insert item (M-RET, M-S-RET with a checkbox), indent/outdent item and item tree (M-left/right, M-S-left/right), move item (M-up/down), toggle checkbox (C-c C-c on an item, C-c C-x C-b), with checkbox statistics cookies kept current. | |
| 6 | ||
| 7 | **Architecture:** `OrgList.swift` ports org-list.el's machinery onto `EmacsBuffer`: `org-list-context`, `org-in-item-p`, `org-list-struct` (items with indentation, bullet, counter, checkbox, tag, end), the prevs/parents alists, `org-list-insert-item`, `org-list-swap-items`, `org-list-send-item`, indent/outdent of structures, the repairs (`fix-bul`, `fix-ind`, `fix-box`, `fix-item-end`) and `org-list-struct-apply-struct`. `ListCommands.swift` holds the commands and `org-update-checkbox-count`, which finds cookies and their containers with the parser on the current section. | |
| 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: no alphabetical bullets, both `.` and `)` terminators, indent offset 0, items get blank lines `auto`, hierarchical statistics, spaces for indentation. | |
| 16 | - Not handled: the ORDERED property, radio lists, timer items, regions. | |
| 17 | ||
| 18 | ## What the oracle found | |
| 19 | ||
| 20 | - ICU's `^` doesn't match after a final newline; Emacs's does. `EmacsBuffer.regex` rewrites a leading `^` as a lookbehind. | |
| 21 | - Splitting an item that owns a sub-list (M-S-RET at its end) leaves org's structure with stale positions; org then reuses the previous match data when `looking-at` fails. The port tracks match data the way Emacs does (`looking-at-p`, `save-match-data` and `string-match` included) and gives the same result. | |
| 22 | - `indent-line-to` shrinking indentation inside a tab uses `move-to-column` with FORCE, which turns the tab into spaces. | |
| 23 | - `org-at-item-p` asks the element parser, so items in comment and verse blocks aren't items, though `org-list-context` allows those blocks. | |
| 24 | - The oracle set `indent-tabs-mode` only in the batch buffer; it now sets the default. | |
| 25 | ||
| 26 | ## Performance | |
| 27 | ||
| 28 | `EmacsBuffer` keeps an immutable `NSString` copy for regexps (rebuilt after a change) and records the span edits touched, so the final diff reads only that span. On a 1.5 MB file every list and structure command takes 1–8 ms. | |
| 29 | ||
| 30 | --- | |
| 31 | ||
| 32 | ### Task 1: List machinery and commands | |
| 33 | ||
| 34 | - [ ] Port the machinery and the nine commands; unit tests; oracle over 13 variants at every caret and over the corpus (`ORGSTAR_ORACLE_CORPUS`, item lines in files up to 20 KB). | |
| 35 | - [ ] Commit "Port plain list commands from org". | |
| 36 | ||
| 37 | ### Task 2: Keys | |
| 38 | ||
| 39 | - [ ] Emacs preset: item bindings on M-RET, M-S-RET, M-arrows, M-S-arrows with `when = "item"`; C-c C-c on items; C-c C-x C-b. Mac preset: the same on its chords, ⌃⌘C to toggle. | |
| 40 | - [ ] Commit "Bind list keys". | |