Go to file
Levi Neely 33173bcc29 Remove dead orkmode-core (FFI) crate
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).
2026-09-30 22:27:50 +02:00
crates Remove dead orkmode-core (FFI) crate 2026-09-30 22:27:50 +02:00
doc Add complete section properties to 9P namespace 2026-09-30 14:16:18 +02:00
.gitignore Initial commit: org-mode parser and CLI 2026-09-30 09:43:21 +02:00
.gitmodules Initial commit: org-mode parser and CLI 2026-09-30 09:43:21 +02:00
AGENTS.md Remove dead orkmode-core (FFI) crate 2026-09-30 22:27:50 +02:00
Cargo.lock Remove dead orkmode-core (FFI) crate 2026-09-30 22:27:50 +02:00
Cargo.toml Remove dead orkmode-core (FFI) crate 2026-09-30 22:27:50 +02:00
LICENSE Initial commit: org-mode parser and CLI 2026-09-30 09:43:21 +02:00
Makefile Add Makefile 2026-09-30 09:46:41 +02:00
README.md Remove dead orkmode-core (FFI) crate 2026-09-30 22:27:50 +02:00
VISION.md Update VISION to the 9P architecture and editing model 2026-09-30 22:21:10 +02:00
test.org Initial commit: org-mode parser and CLI 2026-09-30 09:43:21 +02:00

README.md

Orkmode

A standalone org-mode implementation for KDE, built with Rust (parser/core) and C++ (Qt UI).

Project Structure

orkmode/
├── Cargo.toml                    # Workspace root
├── crates/
│   ├── org-ast/                  # AST type definitions
│   │   └── src/
│   │       ├── lib.rs           # Module exports
│   │       ├── document.rs      # Document, settings
│   │       ├── headline.rs      # Section, Headline, Planning
│   │       ├── elements.rs      # Block elements (paragraph, list, table, etc.)
│   │       ├── objects.rs       # Inline objects (markup, links, etc.)
│   │       ├── timestamp.rs     # Timestamp types
│   │       └── span.rs          # Source location tracking
│   ├── org-parser/              # Tree-sitter based parser
│   │   ├── build.rs            # Compiles tree-sitter-org grammar
│   │   ├── tree-sitter-org/    # Git submodule: nvim-orgmode/tree-sitter-org
│   │   └── src/
│   │       ├── lib.rs          # Parser API
│   │       ├── convert.rs      # Tree-sitter → AST conversion
│   │       ├── ts.rs           # Tree-sitter language bindings
│   │       └── error.rs        # Error types
│   ├── ork-cli/                 # Command-line interface (9P client)
│   │   └── src/
│   │       ├── main.rs         # CLI commands (base + friendly verbs)
│   │       └── client.rs       # 9P2000 client
│   └── ork-server/             # 9P server exposing org files
│       └── src/
│           ├── bin/ork-server.rs  # Server entry point
│           ├── state.rs        # Document state, section ops, ctl verbs
│           ├── namespace.rs    # 9P namespace (docs, sections, agenda, query)
│           ├── p9.rs           # 9P protocol handling
│           └── virtfs.rs       # Virtual filesystem tree
└── ui/                          # (future) Qt/QML UI

Features

Supported Org Syntax

  • Headlines with nesting levels
  • TODO keywords (customizable via #+TODO:)
  • Priority cookies ([#A], [#B], [#C])
  • Tags
  • Property drawers
  • Planning lines (SCHEDULED, DEADLINE, CLOSED)
  • Timestamps (active, inactive, ranges, repeaters)
  • Paragraphs
  • Plain lists (unordered, ordered, checkboxes)
  • Source blocks
  • Tables
  • Drawers
  • Keywords/directives
  • Comments
  • LaTeX environments
  • Inline markup (bold, italic, etc.) - AST types ready, parsing TODO
  • Links - AST types ready, parsing TODO
  • Footnotes
  • Citations

Document Settings

Parses common #+KEYWORD directives:

  • TITLE, AUTHOR, EMAIL, DATE
  • TODO, SEQ_TODO, TYP_TODO
  • PROPERTY, STARTUP, OPTIONS
  • FILETAGS, CATEGORY, ARCHIVE

Building

Prerequisites

  • Rust 1.70+
  • C compiler (for tree-sitter grammar)

Build

# Build all crates
cargo build

# Run tests
cargo test

# Build release
cargo build --release

Usage

CLI (ork)

The ork command operates on org directories or individual files. All commands default to the current directory (.) when no path is specified. Use -R for recursive subdirectory scanning.

# List org files
ork files                     # Current directory
ork files ~/org               # Specific directory
ork files -R .                # Recursive

# Document info (aggregated across all files)
ork info                      # Current directory
ork info ~/org -R             # Recursive
ork info file.org             # Single file
ork info --json               # JSON output

# List sections
ork sections                  # All sections in cwd
ork sections --todos-only     # Only TODOs
ork sections --tag work       # Filter by tag
ork sections --depth 2        # Max depth
ork sections -R -j            # Recursive, JSON

# Query sections
ork query "tag:work"          # By tag
ork query "todo:TODO"         # By TODO state
ork query "priority:A"        # By priority
ork query "title:pattern"     # By title
ork query "file:notes"        # By filename
ork query "done:false" -j     # JSON output

# Get specific section by ID or title
ork get "my-task-id"          # Searches all files
ork get "My Task" -j          # JSON output
ork get "intro" ~/org -R      # In specific path

# List tags with counts
ork tags                      # All tags in cwd
ork tags -R --json            # Recursive, JSON

# Export as JSON
ork export --pretty           # All documents
ork export --section my-id    # Specific section

# Add section
ork add "New Task" file.org                           # To specific file
ork add "New Task" --file notes.org                   # When path is directory
ork add "New Task" file.org --todo TODO --priority A --tags "work,urgent"
ork add "New Task" file.org -n                        # Dry run

# Toggle TODO state
ork toggle "task-id"          # Searches all files
ork toggle "task-id" -n       # Dry run

# Agenda view
ork agenda                    # Current directory
ork agenda ~/org -R           # Recursive
ork agenda --days 14 --json   # 14 days, JSON

# Validate syntax
ork check                     # Current directory
ork check -R --json           # Recursive, JSON

Rust API

use org_parser::Parser;

let mut parser = Parser::new();
let doc = parser.parse(r#"
#+TITLE: My Document
#+TODO: TODO WAITING | DONE

* TODO [#A] First Task :work:
DEADLINE: <2025-01-15 Wed 14:00>

Some description.

** Subtask
- [ ] Item 1
- [X] Item 2
"#).unwrap();

// Access document properties
println!("Title: {:?}", doc.title());
println!("Sections: {}", doc.sections.len());
println!("TODOs: {}", doc.todos().count());

// Iterate sections
for section in doc.all_sections() {
    println!("{} {}", 
        "*".repeat(section.level() as usize),
        section.headline.title_text()
    );
}

9P server & client

Serve a directory of org files over 9P, then act on it with ork:

# Start the server (unix socket or tcp)
ork-server -a unix:///tmp/ork.sock -d ~/org &

# Point the client at it (or pass -a on each call)
export ORK_ADDR=unix:///tmp/ork.sock

ork docs                       # list documents
ork tree work                  # outline of work.org
ork todos                      # TODO items across all docs
ork set work my-task keyword DONE
ork refile work my-task archive --parent done-items
ork query 'tag:work+todo:TODO'

Any 9P client works too (e.g. plan9port 9p); the server owns all org logic and reads/writes the real .org files.

Architecture

Parser Design

The parser uses tree-sitter with the nvim-orgmode/tree-sitter-org grammar.

Benefits:

  • Incremental parsing: Only re-parses changed regions
  • Error recovery: Produces partial AST even with syntax errors
  • Performance: O(n) parsing, minimal memory allocation
  • Battle-tested: Used by Neovim's org-mode plugin

AST Design

The AST follows the org-element specification:

  • Document: Root node with settings and sections
  • Section: Headline + content + children
  • Elements: Block-level constructs (paragraphs, lists, blocks)
  • Objects: Inline constructs (markup, links, timestamps)

All nodes include source span information for editor integration.

Roadmap

Phase 1: Parser (Current)

  • Tree-sitter integration
  • Core AST types
  • Headline/section parsing
  • Block element parsing
  • Complete inline object parsing

Phase 2: Qt UI

  • Document rendering (read-only)
  • Syntax highlighting
  • Folding/cycling
  • Navigation

Phase 3: Editing

  • Inline editing
  • TODO state cycling
  • Tag editing
  • Property editing

Phase 4: Agenda

  • Basic agenda view
  • Day/week/month views
  • Filtering
  • Custom views

Phase 5: Advanced Features

  • Code block execution
  • Diagram rendering (mermaid, plantuml)
  • Capture templates
  • Clock/time tracking

License

GPL-3.0-or-later