fix metadata management model

This commit is contained in:
Levi Neely 2025-11-26 12:55:49 +01:00
parent 77a1db71e3
commit f19fff72e5
4 changed files with 53 additions and 27 deletions

View File

@ -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

View File

@ -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
}

View File

@ -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
}

View File

@ -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")