diff --git a/internal/disk/sync.go b/internal/disk/sync.go index 1409100..e05e853 100644 --- a/internal/disk/sync.go +++ b/internal/disk/sync.go @@ -164,8 +164,11 @@ func syncFrontMatter(path, identifier string) error { }) } +// UpdateMetadataFunc is a function that updates metadata for a note +type UpdateMetadataFunc func(identifier, title, keywords, signature string) error + // GetAll reloads all notes from disk to 9P (discards uncommitted 9P changes) -func GetAll() error { +func GetAll(updateFunc UpdateMetadataFunc) error { return p9client.With9P(func(f *client.Fsys) error { // Read index to get all identifiers indexFid, err := f.Open("index", 0) @@ -247,15 +250,27 @@ func GetAll() error { } } - // Route to appropriate get function based on file type + // OPTIMIZATION: Circumvent 9P write operation overhead by directly manipulating in-memory data. + var title, keywords, signature string if SupportsFrontMatter(path) { - if err := getDenoteFile(f, path, identifier); err != nil { - log.Printf("get: failed to get denote file %s: %v", identifier, err) + fm, _, err := ExtractFrontMatter(path) + if err != nil { + log.Printf("get: failed to extract front matter for %s: %v", identifier, err) + continue } + title = fm.Title + keywords = strings.Join(fm.Tags, ",") + signature = fm.Signature } else { - if err := getNonDenoteFile(f, path, identifier); err != nil { - log.Printf("get: failed to get non-denote file %s: %v", identifier, err) - } + meta := metadata.ParseFilename(path) + title = meta.Title + keywords = strings.Join(meta.Tags, ",") + signature = meta.Signature + } + + // Update in-memory metadata directly + if err := updateFunc(identifier, title, keywords, signature); err != nil { + log.Printf("get: failed to update metadata for %s: %v", identifier, err) } } diff --git a/internal/p9/server/server.go b/internal/p9/server/server.go index c13d097..f923f3e 100644 --- a/internal/p9/server/server.go +++ b/internal/p9/server/server.go @@ -114,6 +114,35 @@ func findNote(identifier string) (*metadata.Metadata, error) { return nil, fmt.Errorf("note not found: %s", identifier) } +// UpdateMetadataFromDisk updates note metadata directly from disk without +// triggering callbacks or 9P protocol overhead. Used by GetAll() for bulk sync. +func UpdateMetadataFromDisk(identifier, title, keywords, signature string) error { + if srv == nil { + return fmt.Errorf("server not running") + } + + note, err := findNote(identifier) + if err != nil { + return err + } + + // Parse keywords into tags + var tags []string + if keywords != "" { + tags = strings.Split(keywords, ",") + for i := range tags { + tags[i] = strings.TrimSpace(tags[i]) + } + } + + // Update fields directly (note is a pointer, so this modifies the original) + note.Title = title + note.Tags = tags + note.Signature = signature + + return nil +} + // Getdir returns the denote directory // StartServer starts the 9P fileserver in the background with pre-loaded metadata. // initialData should contain all notes to be served - typically loaded by sync.LoadAll(). diff --git a/main.go b/main.go index 50f16c4..188b53d 100644 --- a/main.go +++ b/main.go @@ -341,7 +341,7 @@ func main() { w.Ctl("dot=addr") w.Ctl("show") case "Get": - if err := disk.GetAll(); err != nil { + if err := disk.GetAll(p9server.UpdateMetadataFromDisk); err != nil { log.Printf("get error: %v", err) } refreshWindowWithDefaults(w)