From 91606a22231b044071ec43ba57a93fe7803fb817 Mon Sep 17 00:00:00 2001 From: Spencer Brower <6729162+sbrow@users.noreply.github.com> Date: Tue, 14 Jul 2026 12:48:38 -0400 Subject: [PATCH] feat: Added `-watch` flag. --- TODOS.md | 4 ++++ content.odin | 12 +++++++++--- main.odin | 20 +++++++++++++++----- site.odin | 4 ++++ 4 files changed, 32 insertions(+), 8 deletions(-) diff --git a/TODOS.md b/TODOS.md index 4683713..465843f 100644 --- a/TODOS.md +++ b/TODOS.md @@ -27,6 +27,10 @@ - [ ] `
` blocks need to set background to theme background,
regardless of prefers-dark. (or use a different theme)
- [ ] `-watch` flag
+ - [x] basic poll loop
+ - [ ] filesystem poll loop
+ - [ ] event based
+- [ ] Free cmark HTML output (`body_html`) — cmark allocates via C malloc, not the arena, so it leaks per iteration in watch mode
- [ ] commands
- [ ] Review every file in thor
- [ ] Review alerts.odin
diff --git a/content.odin b/content.odin
index 32b5b3a..d9479d3 100644
--- a/content.odin
+++ b/content.odin
@@ -32,8 +32,14 @@ Page :: struct {
// (or all pages if include_drafts is true).
//
// TODO: What is the lifetime of pages?
-walk_content :: proc(content_path: string, include_drafts: bool, sectionate: bool) -> []Page {
- pages: [dynamic]Page
+walk_content :: proc(site: ^Site) -> []Page {
+ content_path := site.content_dir
+ include_drafts := site.drafts
+ sectionate := site.sectionate
+
+ allocator := site_allocator(site)
+
+ pages := make([dynamic]Page, allocator)
collect_home(&pages, content_path, sectionate)
collect_standalone(&pages, content_path, sectionate)
@@ -46,7 +52,7 @@ walk_content :: proc(content_path: string, include_drafts: bool, sectionate: boo
if include_drafts {
return pages[:]
} else {
- filtered: [dynamic]Page
+ filtered := make([dynamic]Page, allocator)
for &page in pages {
if !page.draft {
append(&filtered, page)
diff --git a/main.odin b/main.odin
index 21193ee..f18f080 100644
--- a/main.odin
+++ b/main.odin
@@ -2,18 +2,28 @@ package main
import "core:log"
import "core:os"
+import "core:time"
main :: proc() {
console_logger := log.create_console_logger()
context.logger = console_logger
defer log.destroy_console_logger(console_logger)
- site: Site
- init_site(&site, os.args)
- defer destroy_site(&site)
+ for {
+ defer free_all(context.temp_allocator)
+ site: Site
+ init_site(&site, os.args)
+ defer destroy_site(&site)
+ // TODO: Make it so this isn't necessary
+ context.allocator = site_allocator(&site)
- pages := walk_content(site.content_dir, site.drafts, site.sectionate)
+ pages := walk_content(&site)
+ render_site(pages, site)
- render_site(pages, site)
+ if !site.watch {
+ break
+ }
+ time.sleep(5 * time.Second)
+ }
}
diff --git a/site.odin b/site.odin
index 9f11ce9..0aedefc 100644
--- a/site.odin
+++ b/site.odin
@@ -21,6 +21,7 @@ Site :: struct {
params: json.Value,
sectionate: bool,
drafts: bool `args:"name=drafts"`,
+ watch: bool
}
init_site :: proc(site: ^Site, args: []string) {
@@ -98,6 +99,9 @@ site_merge :: proc(config: ^Site, flags: Site) {
if flags.drafts {
config.drafts = true
}
+ if flags.watch {
+ config.watch = true
+ }
config.config_path = flags.config_path
}