docs/plans/2026-10-05-lists.md
40 lines · 3112 bytes
6 symbols in this file
Lists and Checkboxes Implementation Plan
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.
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.
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.
Tech Stack: Swift 6.2 tools, Swift Testing, Emacs 31.1 / Org 9.8.7 oracle.
Spec: docs/design.md, "Commands and keymaps".
Global Constraints
- Org defaults: no alphabetical bullets, both
.and)terminators, indent offset 0, items get blank linesauto, hierarchical statistics, spaces for indentation. - Not handled: the ORDERED property, radio lists, timer items, regions.
What the oracle found
- ICU's
^doesn't match after a final newline; Emacs's does.EmacsBuffer.regexrewrites a leading^as a lookbehind. - 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-atfails. The port tracks match data the way Emacs does (looking-at-p,save-match-dataandstring-matchincluded) and gives the same result. indent-line-toshrinking indentation inside a tab usesmove-to-columnwith FORCE, which turns the tab into spaces.org-at-item-pasks the element parser, so items in comment and verse blocks aren't items, thoughorg-list-contextallows those blocks.- The oracle set
indent-tabs-modeonly in the batch buffer; it now sets the default.
Performance
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.
Task 1: List machinery and commands
- 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). - Commit "Port plain list commands from org".
Task 2: Keys
- 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. - Commit "Bind list keys".