177 lines
8.1 KiB
Markdown
177 lines
8.1 KiB
Markdown
# Orkmode Vision
|
|
|
|
## The Problem
|
|
|
|
Org-mode is exceptional for structured thinking, task management, and knowledge work. But it's trapped in Emacs.
|
|
|
|
Existing alternatives fall short:
|
|
- **Organice** (web): Clunky, slow, limited offline
|
|
- **Orgzly** (Android): Mobile-only, sync issues
|
|
- **VS Code extensions**: No proper AST, just syntax highlighting
|
|
- **Logseq/Obsidian**: Nice editing UX, but their own formats — not org-mode
|
|
|
|
None of these integrate with the Linux desktop. None feel native.
|
|
|
|
## The Goal
|
|
|
|
A native KDE application for org-mode that:
|
|
- Parses org files correctly (tree-sitter AST, not regex)
|
|
- Renders beautifully (Qt/QML, not web views)
|
|
- Edits efficiently (keyboard-driven, Emacs-inspired bindings)
|
|
- Syncs reliably (file-based, works with Syncthing/git)
|
|
- Integrates with KDE (notifications, calendar, search)
|
|
|
|
## Non-Goals
|
|
|
|
- Replace Emacs for power users
|
|
- Support every org-mode feature on day one
|
|
- Build a "second brain" or "PKM" system
|
|
- Cloud/SaaS anything
|
|
|
|
## Design Principles
|
|
|
|
**1. Files are truth**
|
|
Org files on disk are the source of truth. No database. No proprietary format. Edit with Emacs, vim, or orkmode interchangeably.
|
|
|
|
**2. Parse properly**
|
|
Use tree-sitter for a real AST. No regex hacks. Handle malformed files gracefully with error recovery.
|
|
|
|
**3. The document is the control surface**
|
|
Actions live on the objects, not in menus. A TODO keyword, a priority cookie, a tag, a timestamp, a headline — each is manipulable in place. Cycle a keyword by clicking it or by pressing a key on it; refile a subtree by dragging it or by a command. Mouse and keyboard are equal citizens; neither is primary. No nested menu trees, no walls of buttons — the affordances are in the rendered document itself.
|
|
|
|
**4. Structure and text, one view**
|
|
The document renders as structure but is never a read-only render. Content is edited as raw org text in place (see the editing model below); structure is edited by direct manipulation of the rendered objects. Both paths issue the same operations against the same files.
|
|
|
|
**5. Desktop-native**
|
|
Use Qt/QML. Respect system themes. Integrate with KDE services (KRunner, Akonadi calendar, notifications).
|
|
|
|
**6. One path to the data**
|
|
The GUI, the CLI, and any other client all reach org files through the same `ork-server` 9P interface. No client has a privileged path; a mouse gesture and a CLI command produce the identical write. This also makes the `ork` CLI a first-class tool for scripting, agent integration, and headless workflows.
|
|
|
|
## Editing Model
|
|
|
|
The document is rendered as styled structure (Logseq-like), not plain text and not a read-only view.
|
|
|
|
**Content editing.** Clicking into a section's headline or body turns *that region* into an editable raw-org-text buffer. Everything else stays rendered. On leaving the region (blur/commit), only that section is reparsed and re-rendered — parsing work is bounded to what you touched, and happens on commit, never per keystroke. A commit is one 9P write to that section's file (`headline`, `body`, ...).
|
|
|
|
**Structural editing.** Structure is manipulated directly on the rendered objects, without entering text-edit mode. Each gesture is exactly one 9P operation:
|
|
|
|
| Gesture | Operation |
|
|
|---|---|
|
|
| Drag headline up/down among siblings | `move up` / `move down` |
|
|
| Drag headline onto another | `refile --parent` |
|
|
| Drag to indent / outdent | `demote` / `promote` |
|
|
| Click a TODO keyword | `set keyword` (cycles via `/keywords`) |
|
|
| Click a priority cookie | `set priority` |
|
|
| Click a tag or the tag area | `tag` (add/remove) |
|
|
| Click a timestamp | `set scheduled` / `set deadline` |
|
|
| Toggle a `[ ]` checkbox | body edit |
|
|
|
|
The GUI holds no org logic of its own — it is a direct-manipulation and in-place-editing surface over the operations the server already exposes.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────┐
|
|
│ Qt/QML UI │
|
|
│ (document view, agenda, capture, search) │
|
|
└─────────────────────────────────────────────────┘
|
|
│ ▲
|
|
│ 9P (unix socket) │ same protocol
|
|
▼ │
|
|
┌─────────────────────────────────────────────────┐
|
|
│ ork-server (Rust) │
|
|
│ 9P namespace: docs, sections, fields, agenda, │
|
|
│ query, ctl (rm/move/promote/demote/refile/...) │
|
|
├─────────────────────────────────────────────────┤
|
|
│ org-parser (Rust) │
|
|
│ (tree-sitter AST, incremental parsing) │
|
|
├─────────────────────────────────────────────────┤
|
|
│ org-ast (Rust) │
|
|
│ (type definitions, spans, serialization) │
|
|
└─────────────────────────────────────────────────┘
|
|
▲
|
|
│ 9P (unix socket / tcp)
|
|
│
|
|
ork CLI · Emacs/vim (edit files directly) · agents
|
|
```
|
|
|
|
Every client — GUI, CLI, automation — speaks 9P to `ork-server`. The server owns all org logic and reads/writes the real `.org` files, so external editors (Emacs, vim) stay interchangeable.
|
|
|
|
## Milestones
|
|
|
|
### v0.1 — Parser & CLI ✅
|
|
- [x] Tree-sitter parser integration
|
|
- [x] Core AST types
|
|
- [x] CLI for querying and basic mutations
|
|
- [x] JSON output for tooling
|
|
|
|
### v0.2 — 9P server & client ✅
|
|
- [x] `ork-server`: org files exposed as a 9P namespace (docs, sections, fields)
|
|
- [x] Read/write section fields (keyword, priority, tags, planning, properties, body)
|
|
- [x] `ork` reworked as a pure 9P client
|
|
- [x] Structural ops via `ctl` (rm, move, promote, demote, refile, archive, lint)
|
|
- [x] `query` and agenda views (todos, today, week)
|
|
|
|
### v0.3 — Read-only UI ✅
|
|
- [x] Qt/QML document view rendering the 9P namespace
|
|
- [x] Headline folding/cycling
|
|
- [x] Structural styling (keywords, priorities, tags, timestamps as distinct objects)
|
|
- [x] Navigation (link following, section reveal with segment-precise scroll)
|
|
|
|
### v0.4 — Editing (the editing model)
|
|
- [x] In-place raw-text editing per section, reparse-on-commit
|
|
- [x] Direct manipulation: click keyword/priority/tag/timestamp → 9P op
|
|
(keyword, priority, tags, and SCHEDULED/DEADLINE timestamps)
|
|
- [ ] Drag to move / refile / promote / demote
|
|
- [x] Checkbox toggling
|
|
- [x] Code block execution (brought forward from Future)
|
|
- [ ] Undo/redo
|
|
|
|
### v0.5 — Agenda & search UI
|
|
- [ ] Agenda view (day/week) over `/agenda`
|
|
- [ ] TODO list and `query`-backed filtering
|
|
- [ ] Scheduled/deadline display
|
|
|
|
### v0.6 — KDE Integration
|
|
- [ ] KRunner plugin (search headlines)
|
|
- [ ] System notifications for deadlines
|
|
- [ ] Akonadi calendar integration
|
|
- [ ] Global capture hotkey
|
|
|
|
### Future
|
|
- Clock/time tracking (`clock` ctl verbs + LOGBOOK)
|
|
- Code block execution
|
|
- Diagram rendering (mermaid, plantuml)
|
|
- Table formula evaluation
|
|
- Capture templates
|
|
- Mobile companion (Kirigami)
|
|
|
|
## Why Rust + Qt + 9P?
|
|
|
|
**Rust** for the parser, AST, and server:
|
|
- Memory safety without GC
|
|
- Excellent tree-sitter bindings
|
|
- Fast parsing
|
|
|
|
**9P** as the interface between server and clients:
|
|
- Language-agnostic — the GUI need not be Rust
|
|
- Process isolation — a GUI crash never corrupts the core
|
|
- One uniform path for GUI, CLI, and agents
|
|
- Trivially inspectable and scriptable
|
|
|
|
**Qt/QML** for the UI:
|
|
- Native KDE integration
|
|
- Powerful text rendering (QTextDocument)
|
|
- Declarative UI with QML
|
|
- Cross-platform if needed later
|
|
|
|
## Contributing
|
|
|
|
See AGENTS.md for AI-assisted development workflow.
|
|
|
|
The codebase is designed for agent collaboration:
|
|
- CLI with JSON output for programmatic access
|
|
- Clear module boundaries
|
|
- Comprehensive type definitions
|