From 9e69ce94ca3ba415f0e90dbcf765ef5b8e3f88bc Mon Sep 17 00:00:00 2001 From: Gokcehan Date: Sat, 15 Jul 2017 17:06:18 +0300 Subject: [PATCH] add globsearch option for wildcard searching Mentioned in #69. --- comp.go | 3 +++ doc.go | 33 +++++++++++++++++---------------- docstring.go | 33 +++++++++++++++++---------------- eval.go | 42 ++++++++++++++++++++++++++++++++++-------- nav.go | 46 ++++++++++++++++++++++++++++++++++++---------- opts.go | 40 +++++++++++++++++++++------------------- 6 files changed, 128 insertions(+), 69 deletions(-) diff --git a/comp.go b/comp.go index fc5c67c..538ab3c 100644 --- a/comp.go +++ b/comp.go @@ -53,6 +53,9 @@ var ( "dirfirst", "nodirfirst", "dirfirst!", + "globsearch", + "noglobsearch", + "globsearch!", "hidden", "nohidden", "hidden!", diff --git a/doc.go b/doc.go index 489d39c..2dacacb 100644 --- a/doc.go +++ b/doc.go @@ -68,22 +68,23 @@ keybindings: The following options can be used to customize the behavior of lf: - dircounts boolean (default off) - dirfirst boolean (default on) - hidden boolean (default off) - preview boolean (default on) - reverse boolean (default off) - wrapscan boolean (default on) - scrolloff integer (default 0) - tabstop integer (default 8) - filesep string (default ":") - ifs string (default "") (not exported if empty) - previewer string (default "") (not filtered if empty) - shell string (default "/bin/sh") - sortby string (default "natural") - timefmt string (default "Mon Jan _2 15:04:05 2006") - ratios string (default "1:2:3") - info string (default "") + dircounts boolean (default off) + dirfirst boolean (default on) + globsearch boolean (default off) + hidden boolean (default off) + preview boolean (default on) + reverse boolean (default off) + wrapscan boolean (default on) + scrolloff integer (default 0) + tabstop integer (default 8) + filesep string (default ":") + ifs string (default "") (not exported if empty) + previewer string (default "") (not filtered if empty) + shell string (default "/bin/sh") + sortby string (default "natural") + timefmt string (default "Mon Jan _2 15:04:05 2006") + ratios string (default "1:2:3") + info string (default "") The following variables are exported for shell commands: diff --git a/docstring.go b/docstring.go index e23c396..adfc0db 100644 --- a/docstring.go +++ b/docstring.go @@ -72,22 +72,23 @@ keybindings: The following options can be used to customize the behavior of lf: - dircounts boolean (default off) - dirfirst boolean (default on) - hidden boolean (default off) - preview boolean (default on) - reverse boolean (default off) - wrapscan boolean (default on) - scrolloff integer (default 0) - tabstop integer (default 8) - filesep string (default ":") - ifs string (default "") (not exported if empty) - previewer string (default "") (not filtered if empty) - shell string (default "/bin/sh") - sortby string (default "natural") - timefmt string (default "Mon Jan _2 15:04:05 2006") - ratios string (default "1:2:3") - info string (default "") + dircounts boolean (default off) + dirfirst boolean (default on) + globsearch boolean (default off) + hidden boolean (default off) + preview boolean (default on) + reverse boolean (default off) + wrapscan boolean (default on) + scrolloff integer (default 0) + tabstop integer (default 8) + filesep string (default ":") + ifs string (default "") (not exported if empty) + previewer string (default "") (not filtered if empty) + shell string (default "/bin/sh") + sortby string (default "natural") + timefmt string (default "Mon Jan _2 15:04:05 2006") + ratios string (default "1:2:3") + info string (default "") The following variables are exported for shell commands: diff --git a/eval.go b/eval.go index 11cc69b..34956a2 100644 --- a/eval.go +++ b/eval.go @@ -26,6 +26,12 @@ func (e *setExpr) eval(app *app, args []string) { case "dirfirst!": gOpts.dirfirst = !gOpts.dirfirst app.nav.renew(app.nav.height) + case "globsearch": + gOpts.globsearch = true + case "noglobsearch": + gOpts.globsearch = false + case "globsearch!": + gOpts.globsearch = !gOpts.globsearch case "hidden": gOpts.hidden = true app.nav.renew(app.nav.height) @@ -297,11 +303,21 @@ func (e *callExpr) eval(app *app, args []string) { case "search-back": app.ui.cmdpref = "?" case "search-next": - app.nav.searchNext() + if err := app.nav.searchNext(); err != nil { + msg := fmt.Sprintf("search: %s: %s", err, app.nav.search) + app.ui.message = msg + log.Printf(msg) + return + } app.ui.loadFile(app.nav) app.ui.loadFileInfo(app.nav) case "search-prev": - app.nav.searchPrev() + if err := app.nav.searchPrev(); err != nil { + msg := fmt.Sprintf("search: %s: %s", err, app.nav.search) + app.ui.message = msg + log.Printf(msg) + return + } app.ui.loadFile(app.nav) app.ui.loadFileInfo(app.nav) case "toggle": @@ -448,15 +464,25 @@ func (e *callExpr) eval(app *app, args []string) { case "/": log.Printf("search: %s", s) app.nav.search = s - app.nav.searchNext() - app.ui.loadFile(app.nav) - app.ui.loadFileInfo(app.nav) + if err := app.nav.searchNext(); err != nil { + msg := fmt.Sprintf("search: %s: %s", err, app.nav.search) + app.ui.message = msg + log.Printf(msg) + } else { + app.ui.loadFile(app.nav) + app.ui.loadFileInfo(app.nav) + } case "?": log.Printf("search-back: %s", s) app.nav.search = s - app.nav.searchPrev() - app.ui.loadFile(app.nav) - app.ui.loadFileInfo(app.nav) + if err := app.nav.searchPrev(); err != nil { + msg := fmt.Sprintf("search: %s: %s", err, app.nav.search) + app.ui.message = msg + log.Printf(msg) + } else { + app.ui.loadFile(app.nav) + app.ui.loadFileInfo(app.nav) + } default: log.Printf("entering unknown execution prefix: %q", app.ui.cmdpref) } diff --git a/nav.go b/nav.go index e0003ab..9573cc3 100644 --- a/nav.go +++ b/nav.go @@ -368,40 +368,66 @@ func (nav *nav) cd(wd string) error { return nil } -func (nav *nav) searchNext() { +func match(pattern, name string) (matched bool, err error) { + if gOpts.globsearch { + return filepath.Match(pattern, name) + } else { + return strings.Contains(name, pattern), nil + } +} + +func (nav *nav) searchNext() error { last := nav.currDir() for i := last.ind + 1; i < len(last.fi); i++ { - if strings.Contains(last.fi[i].Name(), nav.search) { + matched, err := match(nav.search, last.fi[i].Name()) + if err != nil { + return err + } + if matched { nav.down(i - last.ind) - return + return nil } } if gOpts.wrapscan { for i := 0; i < last.ind; i++ { - if strings.Contains(last.fi[i].Name(), nav.search) { + matched, err := match(nav.search, last.fi[i].Name()) + if err != nil { + return err + } + if matched { nav.up(last.ind - i) - return + return nil } } } + return nil } -func (nav *nav) searchPrev() { +func (nav *nav) searchPrev() error { last := nav.currDir() for i := last.ind - 1; i >= 0; i-- { - if strings.Contains(last.fi[i].Name(), nav.search) { + matched, err := match(nav.search, last.fi[i].Name()) + if err != nil { + return err + } + if matched { nav.up(last.ind - i) - return + return nil } } if gOpts.wrapscan { for i := len(last.fi) - 1; i > last.ind; i-- { - if strings.Contains(last.fi[i].Name(), nav.search) { + matched, err := match(nav.search, last.fi[i].Name()) + if err != nil { + return err + } + if matched { nav.down(i - last.ind) - return + return nil } } } + return nil } func (nav *nav) toggleMark(path string) { diff --git a/opts.go b/opts.go index c2397bb..43a4a45 100644 --- a/opts.go +++ b/opts.go @@ -3,30 +3,32 @@ package main import "time" var gOpts struct { - dircounts bool - dirfirst bool - hidden bool - preview bool - reverse bool - wrapscan bool - scrolloff int - tabstop int - filesep string - ifs string - previewer string - shell string - sortby string - timefmt string - ratios []int - info []string - keys map[string]expr - cmdkeys map[string]expr - cmds map[string]expr + dircounts bool + dirfirst bool + globsearch bool + hidden bool + preview bool + reverse bool + wrapscan bool + scrolloff int + tabstop int + filesep string + ifs string + previewer string + shell string + sortby string + timefmt string + ratios []int + info []string + keys map[string]expr + cmdkeys map[string]expr + cmds map[string]expr } func init() { gOpts.dircounts = false gOpts.dirfirst = true + gOpts.globsearch = false gOpts.hidden = false gOpts.preview = true gOpts.reverse = false