Hi all,
Recently, with the help of claude code, I had a crack at trying to separate Leo's model from its Qt front end. This led to the [decouple-model-gui](
https://github.com/shakfu/leo-editor/tree/decouple-model-gui) branch of my leo fork and the creation of something called `leolib` which includes the model but not the view. It has reached a point where I thought it may be useful to others to look at it if they liked.
`leolib` can open, create, edit and save `.leo` files, including every `@file` kind, with no commander, no frame and no gui:
```python
from leo import leolib
doc = leolib.Document.open('myfile.leo')
child = doc.insert_child(doc.outline.rootPosition())
doc.set_headline(child, 'written with no window in sight')
doc.undo()
doc.save()
```
**Where it stands**
- The model lives in `leo/leolib/` and no longer imports `leoGlobals` or any view module. `leoNodes`, `leoOutline`, `leoFileCommands`, `leoAtFile`, `leoShadow`, `leoImport`, `leoUndo` and friends moved there. The old `leo.core.*` paths are aliases for the new modules (the same module objects, not copies), so no plugin needs to change.
- Opening `LeoPyRef.leo` and reading all its external files imports 13 `leo.*` modules through `leolib`, against about 105 through `leoBridge`. The outlines are identical, node for node.
- A Document class holds an outline and its undo history, and has the structural commands: insert, delete, clone, cut, copy, paste, moves, demote, promote, unmark-all. It records the same undo beads Leo's own commands do.
- `leo/leotui` is a small terminal front end written against `leolib` alone. What a front end has to supply is about ten members, listed in `leolib`'s `HeadlessView`.
- 999 tests pass, and ruff, ty and `check_leo_sync` are clean. Qt Leo runs as before; single-window editing and saving are confirmed by hand.
**A Rust port, and a shared test corpus**
As a proof-of-concept, I ported `leolib` -- again with the help of claude code -- to rust. This became [leo-rs](
https://github.com/shakfu/leo-rs) which includes two crates: the rust `leolib` port and `leotui`, a terminal front end (vim-style editing, tree-sitter highlighting). It reads `LeoPyRef.leo` and its external files identically to the Python `leolib`, rewrites the `.leo` file byte for byte, and tangles the external files it has checked back to the bytes on disk.
As things happens, the rust port has evolved into a workable vim-like editor.
The two implementations now share a conformance 'corpus' test: a bunch of outlines covering every `@<file>` kind, clones, CRLF, latin-1, lines that look like sentinels, and `@auto` in four languages.
**Discovery of leo-cub**
After developing the rust port to some extent, I ran a 'rust leo' search in the leo-editor group and found the cool [leo-cub](
https://github.com/vivainio/leo-cub) project that Ville Vainio is developing (also in rust).
I haven't really compared features, but it looks like `leo-cub` is lot more mature and is likely more compatible with leo with more features than the rust leotui implementation but the latter has some nice 'editor' features like vim-like modal editing / search and tree-sitter-based helix-style themes for syntax highlighting.
**Hope this is useful**
I would be pleased if any of the code which came out of this experiment proved useful for the leo-editor project or to other related projects.
S