From bfd01e5ed86292be6df21a778268c0ace800b1e6 Mon Sep 17 00:00:00 2001 From: Juris Arturs Majors <32071671+JurisMajors@users.noreply.github.com> Date: Sat, 20 Jul 2019 18:31:19 +0200 Subject: [PATCH] draft rename (#197) * basic structure * working rename, without making dir's and selection change * mkdirAll if necessary * updated TODO's * rename with replace prompting * path prompt and moved functionality to nav.rename() * renewing now (no set period is needed) * documentation, keybidning change, load file info after renaming * go generate --- complete.go | 1 + doc.go | 1 + docstring.go | 1 + eval.go | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- lf.1 | 1 + nav.go | 26 ++++++++++++++++++++++++++ opts.go | 1 + 7 files changed, 82 insertions(+), 1 deletion(-) diff --git a/complete.go b/complete.go index 068c964..3f742e8 100644 --- a/complete.go +++ b/complete.go @@ -53,6 +53,7 @@ var ( "mark-save", "mark-remove", "mark-load", + "rename", "sync", "echo", "echomsg", diff --git a/doc.go b/doc.go index c077fe9..acde39c 100644 --- a/doc.go +++ b/doc.go @@ -37,6 +37,7 @@ The following commands are provided by lf with default keybindings: redraw (default '') reload (default '') read (default ':') + rename (default 'r') shell (default '$') shell-pipe (default '%') shell-wait (default '!') diff --git a/docstring.go b/docstring.go index 7b7f067..29339d8 100644 --- a/docstring.go +++ b/docstring.go @@ -40,6 +40,7 @@ The following commands are provided by lf with default keybindings: redraw (default '') reload (default '') read (default ':') + rename (default 'r') shell (default '$') shell-pipe (default '%') shell-wait (default '!') diff --git a/eval.go b/eval.go index eb28a4b..253d7b7 100644 --- a/eval.go +++ b/eval.go @@ -472,6 +472,17 @@ func insert(app *app, arg string) { app.ui.echoerrf("delete: %s", err) } } + case strings.HasPrefix(app.ui.cmdPrefix, "replace") || + strings.HasPrefix(app.ui.cmdPrefix, "create path"): + normal(app) + + if arg == "y" { + if err := app.nav.rename(app.ui); err != nil { + app.ui.echoerrf("rename: %s", err) + return + } + } + case app.ui.cmdPrefix == "mark-save: ": normal(app) @@ -523,7 +534,6 @@ func insert(app *app, arg string) { if err := remote("send sync"); err != nil { app.ui.echoerrf("mark-remove: %s", err) } - default: app.ui.cmdAccLeft = append(app.ui.cmdAccLeft, []rune(arg)...) } @@ -818,6 +828,15 @@ func (e *callExpr) eval(app *app, args []string) { case "mark-remove": app.ui.menuBuf = listMarks(app.nav.marks) app.ui.cmdPrefix = "mark-remove: " + case "rename": + if curr, err := app.nav.currFile(); err != nil { + app.ui.echoerrf("rename: %s:", err) + return + } else { + app.ui.cmdPrefix = "rename: " + app.ui.cmdAccLeft = append(app.ui.cmdAccLeft, []rune(curr.Name())...) + } + case "sync": if err := app.nav.sync(); err != nil { app.ui.echoerrf("sync: %s", err) @@ -1029,6 +1048,37 @@ func (e *callExpr) eval(app *app, args []string) { app.ui.loadFile(app.nav) app.ui.loadFileInfo(app.nav) } + case "rename: ": + app.ui.cmdPrefix = "" + if curr, err := app.nav.currFile(); err != nil { + app.ui.echoerrf("rename: %s", err) + } else { + wd, err := os.Getwd() + if err != nil { + log.Printf("getting current directory: %s", err) + return + } + oldPathTo := filepath.Join(wd, curr.Name()) + newPathTo := filepath.Join(wd, s) + app.nav.renameCache = []string{oldPathTo, newPathTo} + + if dir, _ := filepath.Split(s); dir != "" { + if _, err := os.Stat(filepath.Join(wd, dir)); err != nil { + app.ui.cmdPrefix = "create path " + dir + "?[y/N]" + return + } + } + + if _, err := os.Stat(newPathTo); err == nil { // file exists + app.ui.cmdPrefix = "replace " + s + "?[y/N]" + return + } + + if err := app.nav.rename(app.ui); err != nil { + app.ui.echoerrf("rename: %s", err) + } + + } default: log.Printf("entering unknown execution prefix: %q", app.ui.cmdPrefix) } diff --git a/lf.1 b/lf.1 index 2e4a3c9..25f6df1 100644 --- a/lf.1 +++ b/lf.1 @@ -47,6 +47,7 @@ The following commands are provided by lf with default keybindings: redraw (default '') reload (default '') read (default ':') + rename (default 'r') shell (default '$') shell-pipe (default '%') shell-wait (default '!') diff --git a/nav.go b/nav.go index 9e0b58d..fa6bc37 100644 --- a/nav.go +++ b/nav.go @@ -207,6 +207,7 @@ type nav struct { regCache map[string]*reg saves map[string]bool marks map[string]string + renameCache []string selections map[string]int selectionInd int height int @@ -293,6 +294,7 @@ func newNav(height int) *nav { regCache: make(map[string]*reg), saves: make(map[string]bool), marks: make(map[string]string), + renameCache: make([]string, 2), selections: make(map[string]int), selectionInd: 0, height: height, @@ -738,6 +740,30 @@ func (nav *nav) del() error { return nil } +func (nav *nav) rename(ui *ui) error { + oldPath := nav.renameCache[0] + newPath := nav.renameCache[1] + dir, _ := filepath.Split(newPath) + os.MkdirAll(dir, os.ModePerm) + + if _, err := os.Stat(newPath); err == nil { // file exists + if err := os.Remove(newPath); err != nil { + return err + } + } + if err := os.Rename(oldPath, newPath); err != nil { + return err + } + nav.renew() + // TODO: change selection + if err := nav.sel(newPath); err != nil { + return err + } + ui.loadFile(nav) + ui.loadFileInfo(nav) + return nil +} + func (nav *nav) sync() error { list, cp, err := loadFiles() if err != nil { diff --git a/opts.go b/opts.go index a130e84..5bf9bda 100644 --- a/opts.go +++ b/opts.go @@ -140,6 +140,7 @@ func init() { gOpts.keys["m"] = &callExpr{"mark-save", nil, 1} gOpts.keys["'"] = &callExpr{"mark-load", nil, 1} gOpts.keys[`"`] = &callExpr{"mark-remove", nil, 1} + gOpts.keys[`r`] = &callExpr{"rename", nil, 1} gOpts.keys[""] = &callExpr{"cmd-history-next", nil, 1} gOpts.keys[""] = &callExpr{"cmd-history-prev", nil, 1}