diff --git a/cmd/edit.go b/cmd/edit.go index aac06c4..6781893 100644 --- a/cmd/edit.go +++ b/cmd/edit.go @@ -12,7 +12,6 @@ import ( "syscall" "time" - "github.com/google/uuid" "gogs.inhome.blapointe.com/bel/pttodo/pttodo" "gopkg.in/yaml.v2" ) @@ -50,50 +49,67 @@ func _edit(filepaths func() []string) error { return err } - // remove original files - // merge original files - // move new files in - for _, target := range editedFiles { - r, err := filePathReader(path.Join(editableDir, path.Base(target))) + edits := map[string]string{} + for _, editedFile := range editedFiles { + edits[path.Base(editedFile)] = editedFile + originalFile := func() string { + for _, f := range filepaths() { + if path.Base(f) == path.Base(editedFile) { + return f + } + } + panic("how?") + }() + + edited, err := pttodo.NewTodosFromFile(editedFile) if err != nil { return err } - var newTodos []pttodo.Todo - if err := yaml.NewDecoder(r).Decode(&newTodos); err != nil { + original, err := pttodo.NewRootFromFile(originalFile) + if err != nil { return err } - original := originals[target] - newTodoIDs := map[string]struct{}{} - for i := range newTodos { - newTodoIDs[newTodos[i].ID()] = struct{}{} + editedIDs := map[string]int{} + for i := range edited { + editedIDs[edited[i].ID()] = 1 } - for i := range original.Todo { - if _, ok := newTodoIDs[original.Todo[i].ID()]; !ok { - original.Todo[i].TS = pttodo.TS(time.Now().Unix()) - if string(original.Todo[i].Schedule) != "" && !original.Todo[i].Triggered() { - original.Scheduled = append(original.Scheduled, original.Todo[i]) - } - original.Done = append(original.Done, original.Todo[i]) + if _, ok := editedIDs[original.Todo[i].ID()]; ok { + continue } + original.Todo[i].TS = pttodo.TS(time.Now().Unix()) + if string(original.Todo[i].Schedule) != "" && !original.Todo[i].Triggered() { + original.Scheduled = append(original.Scheduled, original.Todo[i]) + } + original.Done = append(original.Done, original.Todo[i]) } - original.Todo = newTodos - + original.Todo = edited original.AutoMove() - c, err := yaml.Marshal(original) - if err != nil { - return err - } - outputPath := target - if info, _ := os.Stat(target); info != nil && info.ModTime() != lastModified[target] { - outputPath = fmt.Sprintf("%s.%s.%s", outputPath, uuid.New().String(), path.Ext(outputPath)) - } - if err := ioutil.WriteFile(outputPath, c, os.ModePerm); err != nil { + if err := func() error { + f, err := os.Create(editedFile) + if err != nil { + return err + } + defer f.Close() + + return yaml.NewEncoder(f).Encode(original) + }(); err != nil { return err } } + + for _, f := range filepaths() { + if edited, ok := edits[path.Base(f)]; ok { + if err := os.Rename(edited, f); err != nil { + return err + } + } else if err := os.Remove(f); err != nil { + return err + } + } + return nil }