diff --git a/cmd/pttodo-cli/cli.go b/cmd/pttodo-cli/cli.go index 9aebb67..b240b6e 100644 --- a/cmd/pttodo-cli/cli.go +++ b/cmd/pttodo-cli/cli.go @@ -109,6 +109,55 @@ func verifyFile(path string) error { } func edit(dry bool, filepaths []string) error { + tempDir, err := ioutil.TempDir(os.TempDir(), "edit-pttodo-*") + if err != nil { + return err + } + for _, target := range filepaths { + if b, err := ioutil.ReadFile(target); err != nil && !os.IsNotExist(err) { + return err + } else if err := ioutil.WriteFile(path.Join(tempDir, path.Base(target)), b, os.ModePerm); err != nil { + return err + } + } + if err := vimd(tempDir); err != nil { + return err + } + for _, target := range filepaths { + for { + err := verifyFile(path.Join(tempDir, path.Base(target))) + if err == nil { + break + } + log.Printf("%v, press to resume editing", err) + b := make([]byte, 1) + if _, err := os.Stdin.Read(b); err != nil { + break + } + if err := vimd(tempDir); err != nil { + return err + } + } + } + if dry { + return nil + } + for _, target := range filepaths { + var todo pttodo.Root + if b, err := ioutil.ReadFile(path.Join(tempDir, path.Base(target))); err != nil { + return err + } else if err := yaml.Unmarshal(b, &todo); err != nil { + return err + } else if c, err := yaml.Marshal(todo); err != nil { + return err + } else if err := ioutil.WriteFile(target, c, os.ModePerm); err != nil { + return err + } + } + return nil +} + +func _edit(dry bool, filepaths []string) error { tempDir, err := ioutil.TempDir(os.TempDir(), "edit-pttodo") if err != nil { return err @@ -140,45 +189,7 @@ func edit(dry bool, filepaths []string) error { return nil } vi := func() error { - bin := "vim" - editorbin, err := exec.LookPath(bin) - if err != nil { - editorbin, err = exec.LookPath("vi") - } - if err != nil { - return err - } - args := []string{editorbin, "-p"} - tempfiles, err := listDir(tempDir) - if err != nil { - return err - } - args = append(args, tempfiles...) - cpid, err := syscall.ForkExec( - editorbin, - args, - &syscall.ProcAttr{ - Dir: tempDir, - Env: os.Environ(), - Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}, - Sys: nil, - }, - ) - if err != nil { - return err - } - proc, err := os.FindProcess(cpid) - if err != nil { - return err - } - state, err := proc.Wait() - if err != nil { - return err - } - if exitCode := state.ExitCode(); exitCode != 0 { - return fmt.Errorf("bad exit code on vim: %d, state: %+v", exitCode, state) - } - return nil + return vimd(tempDir) } verifyOne := func(tempFile string) error { for { @@ -248,6 +259,48 @@ func edit(dry bool, filepaths []string) error { return nil } +func vimd(d string) error { + bin := "vim" + editorbin, err := exec.LookPath(bin) + if err != nil { + editorbin, err = exec.LookPath("vi") + } + if err != nil { + return err + } + args := []string{editorbin, "-p"} + files, err := listDir(d) + if err != nil { + return err + } + args = append(args, files...) + cpid, err := syscall.ForkExec( + editorbin, + args, + &syscall.ProcAttr{ + Dir: d, + Env: os.Environ(), + Files: []uintptr{os.Stdin.Fd(), os.Stdout.Fd(), os.Stderr.Fd()}, + Sys: nil, + }, + ) + if err != nil { + return err + } + proc, err := os.FindProcess(cpid) + if err != nil { + return err + } + state, err := proc.Wait() + if err != nil { + return err + } + if exitCode := state.ExitCode(); exitCode != 0 { + return fmt.Errorf("bad exit code on vim: %d, state: %+v", exitCode, state) + } + return nil +} + func merge(dry bool, filepath string, mergeTargetFilePath string) error { baseReader, err := filePathReader(filepath) if err != nil { diff --git a/cmd/pttodo-cli/pttodo-cli b/cmd/pttodo-cli/pttodo-cli index 24e8ce3..60e0a22 100755 Binary files a/cmd/pttodo-cli/pttodo-cli and b/cmd/pttodo-cli/pttodo-cli differ diff --git a/cmd/pttodo-cli/testdata/test.yaml b/cmd/pttodo-cli/testdata/test.yaml new file mode 100755 index 0000000..783b309 --- /dev/null +++ b/cmd/pttodo-cli/testdata/test.yaml @@ -0,0 +1,5 @@ +todo: +- a +- a +scheduled: [] +done: []