add globsearch option for wildcard searching

Mentioned in #69.
This commit is contained in:
Gokcehan 2017-07-15 17:06:18 +03:00
parent fe05105c88
commit 9e69ce94ca
6 changed files with 128 additions and 69 deletions

View File

@ -53,6 +53,9 @@ var (
"dirfirst", "dirfirst",
"nodirfirst", "nodirfirst",
"dirfirst!", "dirfirst!",
"globsearch",
"noglobsearch",
"globsearch!",
"hidden", "hidden",
"nohidden", "nohidden",
"hidden!", "hidden!",

1
doc.go
View File

@ -70,6 +70,7 @@ The following options can be used to customize the behavior of lf:
dircounts boolean (default off) dircounts boolean (default off)
dirfirst boolean (default on) dirfirst boolean (default on)
globsearch boolean (default off)
hidden boolean (default off) hidden boolean (default off)
preview boolean (default on) preview boolean (default on)
reverse boolean (default off) reverse boolean (default off)

View File

@ -74,6 +74,7 @@ The following options can be used to customize the behavior of lf:
dircounts boolean (default off) dircounts boolean (default off)
dirfirst boolean (default on) dirfirst boolean (default on)
globsearch boolean (default off)
hidden boolean (default off) hidden boolean (default off)
preview boolean (default on) preview boolean (default on)
reverse boolean (default off) reverse boolean (default off)

34
eval.go
View File

@ -26,6 +26,12 @@ func (e *setExpr) eval(app *app, args []string) {
case "dirfirst!": case "dirfirst!":
gOpts.dirfirst = !gOpts.dirfirst gOpts.dirfirst = !gOpts.dirfirst
app.nav.renew(app.nav.height) app.nav.renew(app.nav.height)
case "globsearch":
gOpts.globsearch = true
case "noglobsearch":
gOpts.globsearch = false
case "globsearch!":
gOpts.globsearch = !gOpts.globsearch
case "hidden": case "hidden":
gOpts.hidden = true gOpts.hidden = true
app.nav.renew(app.nav.height) app.nav.renew(app.nav.height)
@ -297,11 +303,21 @@ func (e *callExpr) eval(app *app, args []string) {
case "search-back": case "search-back":
app.ui.cmdpref = "?" app.ui.cmdpref = "?"
case "search-next": 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.loadFile(app.nav)
app.ui.loadFileInfo(app.nav) app.ui.loadFileInfo(app.nav)
case "search-prev": 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.loadFile(app.nav)
app.ui.loadFileInfo(app.nav) app.ui.loadFileInfo(app.nav)
case "toggle": case "toggle":
@ -448,15 +464,25 @@ func (e *callExpr) eval(app *app, args []string) {
case "/": case "/":
log.Printf("search: %s", s) log.Printf("search: %s", s)
app.nav.search = s app.nav.search = s
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)
} else {
app.ui.loadFile(app.nav) app.ui.loadFile(app.nav)
app.ui.loadFileInfo(app.nav) app.ui.loadFileInfo(app.nav)
}
case "?": case "?":
log.Printf("search-back: %s", s) log.Printf("search-back: %s", s)
app.nav.search = s app.nav.search = s
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)
} else {
app.ui.loadFile(app.nav) app.ui.loadFile(app.nav)
app.ui.loadFileInfo(app.nav) app.ui.loadFileInfo(app.nav)
}
default: default:
log.Printf("entering unknown execution prefix: %q", app.ui.cmdpref) log.Printf("entering unknown execution prefix: %q", app.ui.cmdpref)
} }

46
nav.go
View File

@ -368,40 +368,66 @@ func (nav *nav) cd(wd string) error {
return nil 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() last := nav.currDir()
for i := last.ind + 1; i < len(last.fi); i++ { 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) nav.down(i - last.ind)
return return nil
} }
} }
if gOpts.wrapscan { if gOpts.wrapscan {
for i := 0; i < last.ind; i++ { 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) nav.up(last.ind - i)
return return nil
} }
} }
} }
return nil
} }
func (nav *nav) searchPrev() { func (nav *nav) searchPrev() error {
last := nav.currDir() last := nav.currDir()
for i := last.ind - 1; i >= 0; i-- { 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) nav.up(last.ind - i)
return return nil
} }
} }
if gOpts.wrapscan { if gOpts.wrapscan {
for i := len(last.fi) - 1; i > last.ind; i-- { 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) nav.down(i - last.ind)
return return nil
} }
} }
} }
return nil
} }
func (nav *nav) toggleMark(path string) { func (nav *nav) toggleMark(path string) {

View File

@ -5,6 +5,7 @@ import "time"
var gOpts struct { var gOpts struct {
dircounts bool dircounts bool
dirfirst bool dirfirst bool
globsearch bool
hidden bool hidden bool
preview bool preview bool
reverse bool reverse bool
@ -27,6 +28,7 @@ var gOpts struct {
func init() { func init() {
gOpts.dircounts = false gOpts.dircounts = false
gOpts.dirfirst = true gOpts.dirfirst = true
gOpts.globsearch = false
gOpts.hidden = false gOpts.hidden = false
gOpts.preview = true gOpts.preview = true
gOpts.reverse = false gOpts.reverse = false