0.99.0: say code as classified runs, and a diff line as a change
quasicoherent 19d7602d, option (d), and the last certain gap in the vocabulary.
`Node::Code { runs, language, inline }` carries `Lexeme`s and never a bare
string. That is the whole ruling: an app that browses source already has a
lexer, a renderer does not and should not grow one, and three renderers each
growing their own would disagree about the same file. The alternatives were a
highlighter inside quasi-webview that goingson and audiofiles would pay for
although neither browses source, or a `Node::Diff` putting git's data model in a
vocabulary shared by a task manager and a sample browser.
`inline` is a flag rather than a second member because the distinction is
containment: a clone URL in a sentence and a file in a source browser are the
same claim about the same text, and `Node::containment` reads the flag, so an
inline literal is a leaf that may sit in a Row or a Cell and a block is not.
`Lexeme` carries its own text rather than a range into a source string. A range
would allocate less and would hand every renderer a byte offset that may not
land on a character boundary; two of the three would get it wrong on the first
file with a multi-byte character in it. The run carrying its text cannot express
that bug.
`Cells::change` is the diff half, so file, blame and a diff are all
`Node::Table` and nothing here learns what a hunk is. `None` is not
`Change::Context`: one says this table is not a diff, the other says this line
did not change, and without the distinction every ordinary table in the tree
would read as a diff whose lines are all context.
All three renderers have an arm, and none took a dependency:
- quasi-webview writes a span per classified run, `lex-<class>` off
`Syntax::name`, and nothing at all for a plain run, which is most of a file.
A diff row gets `data-change` beside `data-tone`, so a host that has never
heard of a diff still gets the success and danger it already styles.
- quasi-tui maps the classes onto the theme's status colours, following base16
Tomorrow, and puts the diff's sign in front of the row rather than a tint
behind it: the sign survives a monochrome terminal and a colour does not.
- quasi-immediate does the same in egui, monospaced.
The two terminal-shaped choices are documented where they are made rather than
here: a terminal spending status colours on syntax is deliberate, because the
palette has no syntax colours and is not going to grow any.
- Co-Authored-By
- Claude Opus 5 (1M context) <noreply@anthropic.com>
- Claude-Session
- https://claude.ai/code/session_01MptwXZ8k65v19rFmdGAyki
19 files changed,
+533 insertions,
-66 deletions
| 2656 |
2656 |
|
|
| 2657 |
2657 |
|
[[package]]
|
| 2658 |
2658 |
|
name = "makeover-immediate"
|
| 2659 |
|
- |
version = "0.44.0"
|
| 2660 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2661 |
|
- |
checksum = "d34f96a7b5b7c26c79ea94b243e911b006e4899270bac418d215ff39f111cda9"
|
|
2659 |
+ |
version = "0.45.0"
|
| 2662 |
2660 |
|
dependencies = [
|
| 2663 |
2661 |
|
"egui",
|
| 2664 |
2662 |
|
"egui_extras",
|
| 2668 |
2666 |
|
|
| 2669 |
2667 |
|
[[package]]
|
| 2670 |
2668 |
|
name = "makeover-layout"
|
| 2671 |
|
- |
version = "0.43.0"
|
| 2672 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2673 |
|
- |
checksum = "c0a9124f65373683ae4320b00bf4a6198b2554ef3ad3af2806b413ac164545fa"
|
|
2669 |
+ |
version = "0.44.0"
|
| 2674 |
2670 |
|
|
| 2675 |
2671 |
|
[[package]]
|
| 2676 |
2672 |
|
name = "makeover-timing"
|
| 2683 |
2679 |
|
|
| 2684 |
2680 |
|
[[package]]
|
| 2685 |
2681 |
|
name = "makeover-touch"
|
| 2686 |
|
- |
version = "0.33.0"
|
| 2687 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2688 |
|
- |
checksum = "6281006f62d84f15c8c88662056e32f2027717bdd61f29d36f7917b9a694d64a"
|
|
2682 |
+ |
version = "0.34.0"
|
| 2689 |
2683 |
|
dependencies = [
|
| 2690 |
2684 |
|
"makeover-geometry",
|
| 2691 |
2685 |
|
"makeover-layout",
|
| 2693 |
2687 |
|
|
| 2694 |
2688 |
|
[[package]]
|
| 2695 |
2689 |
|
name = "makeover-tui"
|
| 2696 |
|
- |
version = "0.43.0"
|
| 2697 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2698 |
|
- |
checksum = "39fc9343435bdcbaef8a5f5e2910254b841b08171919c19795dc50be7b1910ba"
|
|
2690 |
+ |
version = "0.44.0"
|
| 2699 |
2691 |
|
dependencies = [
|
| 2700 |
2692 |
|
"makeover",
|
| 2701 |
2693 |
|
"makeover-layout",
|
| 2705 |
2697 |
|
|
| 2706 |
2698 |
|
[[package]]
|
| 2707 |
2699 |
|
name = "makeover-webview"
|
| 2708 |
|
- |
version = "0.72.0"
|
| 2709 |
|
- |
source = "registry+https://github.com/rust-lang/crates.io-index"
|
| 2710 |
|
- |
checksum = "ae1993234ce8b39b26b326b40cf92f455dfe0656b79d96cbe012c09c982df96d"
|
|
2700 |
+ |
version = "0.73.0"
|
| 2711 |
2701 |
|
dependencies = [
|
| 2712 |
2702 |
|
"makeover-geometry",
|
| 2713 |
2703 |
|
"makeover-layout",
|
| 3476 |
3466 |
|
|
| 3477 |
3467 |
|
[[package]]
|
| 3478 |
3468 |
|
name = "quasi"
|
| 3479 |
|
- |
version = "0.98.0"
|
|
3469 |
+ |
version = "0.99.0"
|
| 3480 |
3470 |
|
|
| 3481 |
3471 |
|
[[package]]
|
| 3482 |
3472 |
|
name = "quasi-axum"
|
| 3483 |
|
- |
version = "0.98.0"
|
|
3473 |
+ |
version = "0.99.0"
|
| 3484 |
3474 |
|
dependencies = [
|
| 3485 |
3475 |
|
"axum",
|
| 3486 |
3476 |
|
"http",
|
| 3494 |
3484 |
|
|
| 3495 |
3485 |
|
[[package]]
|
| 3496 |
3486 |
|
name = "quasi-basics"
|
| 3497 |
|
- |
version = "0.98.0"
|
|
3487 |
+ |
version = "0.99.0"
|
| 3498 |
3488 |
|
dependencies = [
|
| 3499 |
3489 |
|
"makeover-layout",
|
| 3500 |
3490 |
|
"quasi-http",
|
| 3504 |
3494 |
|
|
| 3505 |
3495 |
|
[[package]]
|
| 3506 |
3496 |
|
name = "quasi-bench"
|
| 3507 |
|
- |
version = "0.98.0"
|
|
3497 |
+ |
version = "0.99.0"
|
| 3508 |
3498 |
|
dependencies = [
|
| 3509 |
3499 |
|
"askama",
|
| 3510 |
3500 |
|
"dhat",
|
| 3521 |
3511 |
|
|
| 3522 |
3512 |
|
[[package]]
|
| 3523 |
3513 |
|
name = "quasi-http"
|
| 3524 |
|
- |
version = "0.98.0"
|
|
3514 |
+ |
version = "0.99.0"
|
| 3525 |
3515 |
|
dependencies = [
|
| 3526 |
3516 |
|
"form_urlencoded",
|
| 3527 |
3517 |
|
"http",
|
| 3530 |
3520 |
|
|
| 3531 |
3521 |
|
[[package]]
|
| 3532 |
3522 |
|
name = "quasi-immediate"
|
| 3533 |
|
- |
version = "0.98.0"
|
|
3523 |
+ |
version = "0.99.0"
|
| 3534 |
3524 |
|
dependencies = [
|
| 3535 |
3525 |
|
"docengine",
|
| 3536 |
3526 |
|
"egui",
|
| 3541 |
3531 |
|
|
| 3542 |
3532 |
|
[[package]]
|
| 3543 |
3533 |
|
name = "quasi-notifs"
|
| 3544 |
|
- |
version = "0.98.0"
|
|
3534 |
+ |
version = "0.99.0"
|
| 3545 |
3535 |
|
dependencies = [
|
| 3546 |
3536 |
|
"quasi-router",
|
| 3547 |
3537 |
|
"synckit-config",
|
| 3551 |
3541 |
|
|
| 3552 |
3542 |
|
[[package]]
|
| 3553 |
3543 |
|
name = "quasi-router"
|
| 3554 |
|
- |
version = "0.98.0"
|
|
3544 |
+ |
version = "0.99.0"
|
| 3555 |
3545 |
|
dependencies = [
|
| 3556 |
3546 |
|
"makeover-layout",
|
| 3557 |
3547 |
|
]
|
| 3568 |
3558 |
|
|
| 3569 |
3559 |
|
[[package]]
|
| 3570 |
3560 |
|
name = "quasi-tauri"
|
| 3571 |
|
- |
version = "0.98.0"
|
|
3561 |
+ |
version = "0.99.0"
|
| 3572 |
3562 |
|
dependencies = [
|
| 3573 |
3563 |
|
"http",
|
| 3574 |
3564 |
|
"quasi-http",
|
| 3579 |
3569 |
|
|
| 3580 |
3570 |
|
[[package]]
|
| 3581 |
3571 |
|
name = "quasi-tui"
|
| 3582 |
|
- |
version = "0.98.0"
|
|
3572 |
+ |
version = "0.99.0"
|
| 3583 |
3573 |
|
dependencies = [
|
| 3584 |
3574 |
|
"docengine",
|
| 3585 |
3575 |
|
"makeover",
|
| 3592 |
3582 |
|
|
| 3593 |
3583 |
|
[[package]]
|
| 3594 |
3584 |
|
name = "quasi-webview"
|
| 3595 |
|
- |
version = "0.98.0"
|
|
3585 |
+ |
version = "0.99.0"
|
| 3596 |
3586 |
|
dependencies = [
|
| 3597 |
3587 |
|
"docengine",
|
| 3598 |
3588 |
|
"makeover-layout",
|
| 6290 |
6280 |
|
[[patch.unused]]
|
| 6291 |
6281 |
|
name = "tagtree"
|
| 6292 |
6282 |
|
version = "0.4.1"
|
|
6283 |
+ |
|
|
6284 |
+ |
[[patch.unused]]
|
|
6285 |
+ |
name = "makeover-build"
|
|
6286 |
+ |
version = "0.66.0"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-axum"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
description = "The axum host adapter for quasi-router: an HTTP request in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0" }
|
| 17 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.98.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0" }
|
|
17 |
+ |
quasi-http = { path = "../quasi-http", version = "0.99.0" }
|
| 18 |
18 |
|
axum = "0.8.8"
|
| 19 |
19 |
|
http = "1.3.1"
|
| 20 |
20 |
|
tokio = { version = "1.50.0", features = ["rt"] }
|
| 21 |
21 |
|
|
| 22 |
22 |
|
[dev-dependencies]
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.99.0" }
|
| 24 |
24 |
|
tokio = { version = "1.50.0", features = ["macros", "rt-multi-thread"] }
|
| 25 |
25 |
|
tower = { version = "0.5.3", features = ["util"] }
|
| 26 |
26 |
|
http-body-util = "0.1.3"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-basics"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
description = "The first-party widget set: named assemblies of primitives, shared across our apps"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0" }
|
| 17 |
|
- |
makeover-layout = "0.43"
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0" }
|
|
17 |
+ |
makeover-layout = "0.44"
|
| 18 |
18 |
|
|
| 19 |
19 |
|
[dev-dependencies]
|
| 20 |
20 |
|
# A widget's guarantees are claims about what a renderer draws, so they are
|
| 21 |
21 |
|
# tested against a real one rather than by walking the tree the assembly just
|
| 22 |
22 |
|
# built. The webview is the renderer that recognises names today.
|
| 23 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
|
| 24 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.98.0" }
|
|
23 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.99.0" }
|
|
24 |
+ |
quasi-http = { path = "../quasi-http", version = "0.99.0" }
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-bench"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
description = "What a described screen costs to render, in time and in allocations"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 26 |
26 |
|
askama = ["dep:askama"]
|
| 27 |
27 |
|
|
| 28 |
28 |
|
[dependencies]
|
| 29 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0" }
|
| 30 |
|
- |
quasi-webview = { path = "../quasi-webview", version = "0.98.0" }
|
| 31 |
|
- |
quasi-tui = { path = "../quasi-tui", version = "0.98.0" }
|
|
29 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0" }
|
|
30 |
+ |
quasi-webview = { path = "../quasi-webview", version = "0.99.0" }
|
|
31 |
+ |
quasi-tui = { path = "../quasi-tui", version = "0.99.0" }
|
| 32 |
32 |
|
# `Serves` is the trait carrying `screen` and `fragment`, which is what the
|
| 33 |
33 |
|
# webview is measured through. Taken directly rather than through quasi-webview
|
| 34 |
34 |
|
# because a bench calling a trait method should name the trait it calls.
|
| 35 |
|
- |
quasi-http = { path = "../quasi-http", version = "0.98.0" }
|
| 36 |
|
- |
makeover-layout = "0.43"
|
|
35 |
+ |
quasi-http = { path = "../quasi-http", version = "0.99.0" }
|
|
36 |
+ |
makeover-layout = "0.44"
|
| 37 |
37 |
|
# The renderer's own escaper, so the staged path fills a hole exactly the way
|
| 38 |
38 |
|
# `Node::Text` does and the guarantee is not quietly reimplemented.
|
| 39 |
|
- |
makeover-webview = "0.72"
|
| 40 |
|
- |
makeover-tui = { version = "0.43", features = ["theme"] }
|
|
39 |
+ |
makeover-webview = "0.73"
|
|
40 |
+ |
makeover-tui = { version = "0.44", features = ["theme"] }
|
| 41 |
41 |
|
# Only to load a bundled theme file. `makeover_tui::Theme` is `#[non_exhaustive]`,
|
| 42 |
42 |
|
# so `Theme::from_theme` is the one way to get one, the same reason quasi-tui's
|
| 43 |
43 |
|
# tests take this.
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-http"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
description = "The http-shaped seam quasi's webview host adapters share: decoding in, a rendered description out"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 13 |
13 |
|
workspace = true
|
| 14 |
14 |
|
|
| 15 |
15 |
|
[dependencies]
|
| 16 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0" }
|
|
16 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0" }
|
| 17 |
17 |
|
http = "1.3.1"
|
| 18 |
18 |
|
form_urlencoded = "1.2.2"
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-immediate"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
edition = "2024"
|
| 5 |
5 |
|
description = "The immediate-mode renderer for quasi-router: a described screen in, an egui frame out. Immediate mode is the constraint that matters, not the library."
|
| 6 |
6 |
|
license = "MIT"
|
| 12 |
12 |
|
categories = ["gui"]
|
| 13 |
13 |
|
|
| 14 |
14 |
|
[dependencies]
|
| 15 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0" }
|
|
15 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0" }
|
| 16 |
16 |
|
# The node drawing, which is the makeover layer's and not this crate's. Every
|
| 17 |
17 |
|
# widget here that is not a container comes from it: a screen walk that painted
|
| 18 |
18 |
|
# its own meter would be the divergence the suite exists to end, one copy per
|
| 19 |
19 |
|
# renderer instead of one copy per app.
|
| 20 |
|
- |
makeover-immediate = "0.44"
|
|
20 |
+ |
makeover-immediate = "0.45"
|
| 21 |
21 |
|
# The one place a duration is named rather than numbered. `Intent::Dismiss` is
|
| 22 |
22 |
|
# how long a transient notice lives, and `notice_lifetime` is the seam: the
|
| 23 |
23 |
|
# description says a toast goes away on its own and declines to say when, so
|
| 1 |
1 |
|
[package]
|
| 2 |
2 |
|
name = "quasi-notifs"
|
| 3 |
|
- |
version = "0.98.0"
|
|
3 |
+ |
version = "0.99.0"
|
| 4 |
4 |
|
description = "Declared notification kinds and the registry that holds them: what a notification says and what it is for, apart from how it reaches a person"
|
| 5 |
5 |
|
edition.workspace = true
|
| 6 |
6 |
|
rust-version.workspace = true
|
| 28 |
28 |
|
tauri = ["dep:tauri", "dep:tauri-plugin-notification"]
|
| 29 |
29 |
|
|
| 30 |
30 |
|
[dependencies]
|
| 31 |
|
- |
quasi-router = { path = "../quasi-router", version = "0.98.0", optional = true }
|
|
31 |
+ |
quasi-router = { path = "../quasi-router", version = "0.99.0", optional = true }
|
| 32 |
32 |
|
synckit-config = { git = "https://makenot.work/git/max/synckit.git", version = "0.2", optional = true }
|
| 33 |
33 |
|
tauri-plugin-notification = { version = "2.3.3", optional = true }
|
| 34 |
34 |
|
# Default features off, for `quasi-tauri`'s reason: this takes an `AppHandle`
|