diff --git a/README.md b/README.md index 676858e..d8a9e05 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Quality of life feature: you may edit metadata directly in the Denote window. ``` ------------------------------------------------------- -/Denote/ Del Snarf | Look New Put Remove Sync +/Denote/ Del Snarf | Look New Put Remove Get ------------------------------------------------------- 20251112T221141 | my dummy file 7 | dummy 20251112T221140 | my dummy file 6 | dummy @@ -86,7 +86,7 @@ Quality of life feature: you may edit metadata directly in the Denote window. ``` ------------------------------------------------------- -/Denote/ Del Snarf | Look New Put Remove Sync +/Denote/ Del Snarf | Look New Put Remove Get ------------------------------------------------------- 20251112T221141 | you can edit | dummy 20251112T221140 | the titles | dummy @@ -99,9 +99,9 @@ Quality of life feature: you may edit metadata directly in the Denote window. Middle-click `Put` to write all metadata changes. This will rename files and, when possible, update front matter. -### Sync +### Get -Sometimes it's necessary to update the Denote metadata from the filesystem. Middle-click `Sync` to do this. +Reload all notes from disk, discarding any uncommitted changes in the 9P metadata. Middle-click `Get` to do this. This is useful when notes are modified outside of Acme or when you want to discard metadata changes. ## File Format diff --git a/internal/disk/events.go b/internal/disk/events.go index ea35ecd..d73de20 100644 --- a/internal/disk/events.go +++ b/internal/disk/events.go @@ -9,6 +9,7 @@ import ( "path/filepath" "strings" + "9fans.net/go/acme" "9fans.net/go/plan9/client" ) @@ -144,6 +145,15 @@ func HandleRenameEvent(f *client.Fsys, identifier, denoteDir string) error { if err := os.Rename(oldPath, newPath); err != nil { return fmt.Errorf("failed to rename file from %s to %s: %w", oldPath, newPath, err) } + + // Update window tag for renamed file + if wins, err := acme.Windows(); err == nil { + for _, w := range wins { + if err := updateWindowName(w.ID, oldPath, newPath); err != nil { + log.Printf("failed to update window %d: %v", w.ID, err) + } + } + } } return nil @@ -185,3 +195,27 @@ func HandleDeleteEvent(f *client.Fsys, identifier, denoteDir string) error { return nil } + +// updateWindowName updates the window tag name from oldPath to newPath +func updateWindowName(id int, oldPath, newPath string) error { + win, err := acme.Open(id, nil) + if err != nil { + return err + } + defer win.CloseFiles() + + tag, err := win.ReadAll("tag") + if err != nil { + return err + } + + if !strings.Contains(string(tag), oldPath) { + return nil // Window doesn't have this path, skip + } + + if err := win.Ctl("name " + newPath); err != nil { + return fmt.Errorf("failed to rename window: %w", err) + } + + return nil +} diff --git a/internal/disk/sync.go b/internal/disk/sync.go index 1133d85..18157e2 100644 --- a/internal/disk/sync.go +++ b/internal/disk/sync.go @@ -164,8 +164,8 @@ func syncFrontMatter(path, identifier string) error { }) } -// SyncAll syncs all notes in the denote directory -func SyncAll() error { +// GetAll reloads all notes from disk to 9P (discards uncommitted 9P changes) +func GetAll() error { return p9client.With9P(func(f *client.Fsys) error { // Read index to get all identifiers indexFid, err := f.Open("index", 0) @@ -247,14 +247,14 @@ func SyncAll() error { } } - // Route to appropriate sync function based on file type + // Route to appropriate get function based on file type if SupportsFrontMatter(path) { - if err := syncDenoteFile(f, path, identifier); err != nil { - log.Printf("sync: failed to sync denote file %s: %v", identifier, err) + if err := getDenoteFile(f, path, identifier); err != nil { + log.Printf("get: failed to get denote file %s: %v", identifier, err) } } else { - if err := syncNonDenoteFile(f, path, identifier); err != nil { - log.Printf("sync: failed to sync non-denote file %s: %v", identifier, err) + if err := getNonDenoteFile(f, path, identifier); err != nil { + log.Printf("get: failed to get non-denote file %s: %v", identifier, err) } } } @@ -263,8 +263,8 @@ func SyncAll() error { }) } -// syncDenoteFile syncs a text file with front matter -func syncDenoteFile(f *client.Fsys, path, identifier string) error { +// getDenoteFile reloads a text file with front matter from disk to 9P +func getDenoteFile(f *client.Fsys, path, identifier string) error { // Extract front matter from file fm, err := ExtractFrontMatter(path) if err != nil { @@ -290,17 +290,11 @@ func syncDenoteFile(f *client.Fsys, path, identifier string) error { return err } - // Trigger rename event - ctlPath := "n/" + identifier + "/ctl" - if err := p9client.WriteFile(f, ctlPath, "r"); err != nil { - return err - } - return nil } -// syncNonDenoteFile syncs a binary file (metadata from filename) -func syncNonDenoteFile(f *client.Fsys, path, identifier string) error { +// getNonDenoteFile reloads a binary file from disk to 9P (metadata from filename) +func getNonDenoteFile(f *client.Fsys, path, identifier string) error { // Extract metadata from filename meta := metadata.ParseFilename(path) @@ -323,7 +317,5 @@ func syncNonDenoteFile(f *client.Fsys, path, identifier string) error { return err } - // Don't trigger rename - filename is already correct - return nil } diff --git a/main.go b/main.go index feaa0bb..ff7cb46 100644 --- a/main.go +++ b/main.go @@ -258,7 +258,7 @@ func main() { } defer w.CloseFiles() - if _, err = w.Write("tag", []byte("New Put Remove Sync")); err != nil { + if _, err = w.Write("tag", []byte("New Put Remove Get")); err != nil { w.Del(true) log.Fatal(fmt.Errorf("failed to set tag: %w", err)) } @@ -337,9 +337,9 @@ func main() { w.Addr("#0") w.Ctl("dot=addr") w.Ctl("show") - case "Sync": - if err := disk.SyncAll(); err != nil { - log.Printf("sync error: %v", err) + case "Get": + if err := disk.GetAll(); err != nil { + log.Printf("get error: %v", err) } refreshWindowWithDefaults(w) w.Addr("#0")