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",
"nodirfirst",
"dirfirst!",
"globsearch",
"noglobsearch",
"globsearch!",
"hidden",
"nohidden",
"hidden!",

33
doc.go
View File

@ -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:

View File

@ -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:

42
eval.go
View File

@ -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)
}

46
nav.go
View File

@ -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) {

40
opts.go
View File

@ -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