krz/orgstar

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

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

2fa201330f61c801f777baa3f2943d49d8758cda
orgstar/docs/plans/2026-10-05-lists.md rendered · source · history · blame · raw

40 lines · 3112 bytes

 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".