list() returns files AND directories. Section entries are directories only.
Files like 'title', 'keyword', 'body' were being incorrectly treated as
child sections. Using listDirs() filters to directories only.
TreeView (inherits TableView) is designed for file browsers with fixed row
heights, not structured document editing. ListView gives us:
- Full control over row heights (implicitHeight just works)
- Simpler delegate without TreeViewDelegate quirks
- Manual indentation via leftMargin based on level
- Expansion state tracked in model with hasChildren/expanded roles
- Click-to-expand triangles for sections with children
DocumentModel changed from QAbstractItemModel (tree) to QAbstractListModel
(flat list) with sections ordered depth-first. Tree structure preserved via
level, parentId, childIds fields. Expansion state controls visibility.
TreeView (inherits TableView) defaults to fixed row heights. Setting
rowHeightProvider to return -1 tells it to use each delegate's
implicitHeight, enabling variable-height rows.
- In system mode, read palette from QGuiApplication::palette() rather
than parsing kdeglobals (platform plugin already handles this)
- Don't call setPalette() in system mode — let Qt handle it
- Add isOverriding property for QML to check mode
- Use Fusion style by default for consistent palette respect
- Improved fallback logic in systemSchemePath() for dark/light detection
- Added /etc/xdg/kdeglobals as fallback for system-wide defaults
ThemeManager now supports:
- fontFamily, fontSize, fontStyle with full QFontDatabase access
- uiScale (0.5x to 4.0x) saved to theme.conf
- resetFont() to return to system defaults
SettingsDialog provides UI for:
- Color scheme selection (all installed KDE schemes)
- Font family/style/size with live preview
- UI scale slider with percentage display
OutlineView uses pointSize (scalable) instead of pixelSize (fixed).
All font sizes derived from theme.fontSize or baseFontSize.
- Add ork-server and orkmode (GUI) to install target
- Make UI build optional (only if Qt6 Qml available)
- Add ui target for explicit GUI build
- Clean ui/build directory on 'make clean'
- Update help text with requirements
- Replace manual Item+anchoring with ColumnLayout for proper height calc
- Remove redundant bodyMeasure Text and bodyWidth property
- Add proper top/bottom margins using rowPad constant
- Body row now uses RowLayout with Layout.fillWidth
A standalone Qt6/QML app in ui/ that speaks 9P to ork-server; no FFI,
no privileged path. All org logic stays in the server.
- p9client: minimal synchronous 9P2000 client over QTcp/QLocalSocket
- orkclient: QML-facing facade (read/list/listDirs/write/rdwr/docs)
- documentmodel: lazy QAbstractItemModel of the section tree, with a
BodyRole that reads /<doc>/<id>/body (planning line + :PROPERTIES:
drawer stripped, since those are shown as structural objects)
- Main.qml: document sidebar + outline; OutlineView.qml: folding
TreeView rendering keyword/priority/title/tags/timestamps as distinct
objects, with section body shown inline beneath each headline
- main.cpp: --addr/$ORK_ADDR, --selftest (headless outline dump),
--shot (headless window grab for debugging)
- CMake build; binary emitted to bin/ to avoid the QML-module-URI vs
target-name directory clash
Known issue: inline body layout still needs work (row sizing/overlap
when bodies wrap); to be iterated.
Dropping the C FFI layer left orkmode-core unused: nothing in the
workspace depends on it, and the GUI will speak 9P instead. Delete the
crate, drop it from the workspace, and scrub FFI references from the
docs (README structure/usage, AGENTS structure/FFI/next-steps).
The vision predated the 9P pivot and the GUI direction. Correct it:
- Architecture: clients (GUI, CLI, Emacs/vim, agents) speak 9P to
ork-server; drop the C FFI layer entirely.
- Replace "keyboard-first, mouse optional" with "the document is the
control surface": actions live on objects, mouse and keyboard equal,
no menu trees or button walls.
- Add an explicit Editing Model: structured render, per-section
raw-text editing with reparse-on-commit, and direct-manipulation
structural edits that each map to one 9P operation.
- Refresh milestones (v0.1 parser/CLI and v0.2 9P server/client done;
GUI is next) and the rationale (add the "Why 9P" section).
Client verbs for the new server capabilities, each a thin wrapper over
the base 9P operations: the structural verbs write to /ctl, and query
writes to /query and prints the matches.
Rework /ctl into a self-describing dispatch table (name, desc, fn),
inspired by the ollie 9P server: an empty write or "help" lists the
verbs, and unknown verbs report the valid set.
New control verbs, each operating on a section subtree:
- rm: delete a section and its subtree
- move up|down: reorder among siblings
- promote/demote: shift the subtree's outline level
- refile <to-doc> [parent]: move a subtree across or within documents,
re-leveling to the target depth
- archive: move a subtree to the companion <doc>.org_archive file
- lint [doc]: reparse and report per document
Add a root /query file (rdwr): write a tag:X+todo:Y+priority:Z match
expression, read back matching sections.
Implement the previously stubbed agenda today/week views with real date
filtering, using a dependency-free civil-date day-number calculation.
Subtree edits share span-based helpers (subtree_range, sibling_ranges,
shift_headline_levels, insert_at). Covered by unit tests.
Four more friendly verbs, all pure compositions of the base 9P
operations against the existing namespace (no server change):
- tag <doc> <id> <tag> [--remove]: toggle a single tag, mirroring
org-toggle-tag, instead of rewriting the whole tag list.
- prop <doc> <id> <key> [value] [--delete]: get, set, or delete one
property, mirroring org-set-property, instead of the whole drawer.
- todo <doc> <id> [state]: set the keyword, or with no argument cycle
to the next state following the /keywords sequence, like org-todo.
- tree <doc>: print the recursive section outline.
Each edit reads the relevant namespace file, modifies it, and writes it
back; all validate the section exists first for a clear error.
ork now operates solely as a 9P client against ork-server; all org
intelligence lives in the server. Remove the local file-parsing command
layer (commands.rs) and its org-ast/org-parser/orkmode-core/serde deps.
Base verbs speak raw 9P: ls, read, write, rdwr. Address resolves from
--addr, then $ORK_ADDR, then tcp://localhost:5640.
Add friendly commands, all thin compositions of the base 9P operations:
docs, sections, todos, agenda, get, set, add (--parent), mkdoc, reload.
Fix the directory-listing parser in client.rs: the stat-entry name offset
double-counted the size field (pos + 2 + 41 instead of pos + 41), so ls
returned nothing. Handle a downstream reader closing early (e.g. | head)
by treating BrokenPipe as a clean exit instead of panicking.
Dynamic child resolvers returned Some for any name, fabricating phantom
document and section directories so walks to nonexistent paths appeared
to succeed. Validate existence and return None instead:
- root resolver checks get_doc
- document resolver checks new OrkState::section_exists
- section resolver checks child_ids
Also fix create_child_section, which corrupted the org file:
- find_section_end used the parent's headline-end offset, inserting the
child before the parent's PROPERTIES/ID drawer and detaching its ID.
Use section.span.end, which covers planning, drawer, body, children.
- The child headline was written verbatim; demote it to parent.level + 1
via the new restar helper.
Add regression tests for restar and child section nesting.
- set_section_keyword/priority/title/tags
- set_section_scheduled/deadline/closed
- set_section_properties/body
- rebuild_headline helper for atomic headline updates
- Fixed replace_headline to preserve DEADLINE/:PROPERTIES: lines
- Clear read cache on write in 9P server
All writes tested working via 9p client.
Simple 9P2000 client supporting:
- Connect via Unix socket or TCP
- read/write/rdwr operations
- Directory listing
Preparation for reworking CLI to use 9P server.
- new file at root: create org file
- new file at doc level: create top-level section
- new file at section level: create child section
- All created sections get UUID in :ID: property
- body file added to doc (alias for raw)
- Test for section creation via 9P namespace
- Sections nest as directories mirroring org structure
- One file per property (title, keyword, tags, etc.)
- ID from CUSTOM_ID > ID > slug+hash
- EDSL pattern from ollie's virtfs for declarative namespace