summaryrefslogtreecommitdiff
path: root/trees
diff options
context:
space:
mode:
Diffstat (limited to 'trees')
-rw-r--r--trees/index.typst4
-rw-r--r--trees/jj-log.typst105
2 files changed, 109 insertions, 0 deletions
diff --git a/trees/index.typst b/trees/index.typst
index 48570bd..ba426eb 100644
--- a/trees/index.typst
+++ b/trees/index.typst
@@ -30,3 +30,7 @@ My hobbies include, in no particular order:
== Blog posts
- #local("googlectf-2025")
+
+== Meta
+
+- #local("jj-log")
diff --git a/trees/jj-log.typst b/trees/jj-log.typst
new file mode 100644
index 0000000..814cedb
--- /dev/null
+++ b/trees/jj-log.typst
@@ -0,0 +1,105 @@
+#import "_lib/kodama.typ": *
+#show: kodama
+
+#let raw-text = read("_data/jj-log.json")
+#let lines = raw-text.split("\n").filter(l => l.trim() != "")
+#let commits = lines.map(l => json(bytes(l)))
+#let commits = commits.filter(c => not c.root)
+
+// Title is the shortest unique change id of the working copy (first commit)
+#let wc-short = commits.at(0).short_change
+#metadata(("title": wc-short))
+
+// --- Helpers ---
+
+#let body = raw(body)
+#let tag-pill(name, color: rgb("#4a6fa5")) = {
+ box(
+ fill: color.lighten(75%),
+ stroke: 0.5pt + color,
+ radius: 3pt,
+ inset: (x: 4pt, y: 2pt),
+ text(size: 0.8em, weight: "bold", raw(name)),
+ )
+}
+
+#let format-date(ts) = {
+ let date-part = ts.slice(0, 10)
+ let time-part = ts.slice(11, 16)
+ date-part + " " + time-part
+}
+
+#let all-bookmarks = (
+ commits
+ .map(c => {
+ c.bookmarks.map(b => (
+ name: b.name,
+ change: c.short_change,
+ commit: c.short_commit,
+ desc: c.commit.description.trim(),
+ ))
+ })
+ .flatten()
+)
+
+#text(size: 0.9em, fill: luma(120))[
+ #commits.len() commits #h(0.5em) | #h(0.5em)
+ #all-bookmarks.len() bookmarks #h(0.5em) | #h(0.5em)
+ newest #sym.arrow oldest
+]
+
+== Bookmarks
+
+#if all-bookmarks.len() > 0 [
+ #for bm in all-bookmarks [
+ - #tag-pill(bm.name) #h(0.3em) at #bm.change — #emph(bm.desc)
+ ]
+] else [
+ _No bookmarks in ancestor chain._
+]
+
+== Commit History
+
+#table(
+ columns: (auto, auto, 1fr, auto),
+ align: (center, center, left, right),
+ stroke: 0.4pt + luma(200),
+ inset: 6pt,
+
+ table.header(
+ text(weight: "bold")[Change],
+ text(weight: "bold")[Commit],
+ text(weight: "bold")[Description],
+ text(weight: "bold")[Date],
+ ),
+
+ ..commits
+ .map(c => {
+ let bookmarks = c.bookmarks.map(b => tag-pill(b.name))
+ let desc = c.commit.description.trim()
+ if desc == "" { desc = "(no description)" }
+
+ let badges = {
+ if c.empty { tag-pill("empty", color: rgb("#999")) }
+ if c.conflict { tag-pill("conflict", color: rgb("#c44")) }
+ }
+
+ (
+ c.short_change,
+ c.short_commit,
+ [
+ #desc
+ #if bookmarks.len() > 0 {
+ h(0.3em)
+ bookmarks.join(h(0.2em))
+ }
+ #badges
+ ],
+ text(size: 0.85em, fill: luma(100), format-date(
+ c.commit.author.timestamp,
+ )),
+ )
+ })
+ .flatten(),
+)
+