diff --git a/complete.go b/complete.go index 5d57da4..2a282b8 100644 --- a/complete.go +++ b/complete.go @@ -58,6 +58,8 @@ var ( "echoerr", "cd", "select", + "glob-select", + "glob-unselect", "source", "push", } diff --git a/doc.go b/doc.go index 2dd16ed..2a4730c 100644 --- a/doc.go +++ b/doc.go @@ -62,6 +62,8 @@ The following commands are provided by lf without default keybindings: echoerr same as echomsg but red color cd change working directory to the argument select change current file selection to the argument + glob-select select files that match the given glob + glob-unselect unselect files that match the given glob source read the configuration file in the argument push simulate key pushes given in the argument delete remove the current file or selected file(s) diff --git a/docstring.go b/docstring.go index fa18283..522c813 100644 --- a/docstring.go +++ b/docstring.go @@ -65,6 +65,8 @@ The following commands are provided by lf without default keybindings: echoerr same as echomsg but red color cd change working directory to the argument select change current file selection to the argument + glob-select select files that match the given glob + glob-unselect unselect files that match the given glob source read the configuration file in the argument push simulate key pushes given in the argument delete remove the current file or selected file(s) diff --git a/eval.go b/eval.go index 1fd95d5..bdf781a 100644 --- a/eval.go +++ b/eval.go @@ -833,6 +833,27 @@ func (e *callExpr) eval(app *app, args []string) { if wd != path { app.nav.marks["'"] = wd } + case "glob-select": + if len(e.args) != 1 { + app.ui.echoerr("glob-select: requires a pattern to match") + return + } + + if err := app.nav.globSel(e.args[0], false); err != nil { + app.ui.echoerrf("%s", err) + return + } + case "glob-unselect": + if len(e.args) != 1 { + app.ui.echoerr("glob-unselect: requires a pattern to match") + return + } + + if err := app.nav.globSel(e.args[0], true); err != nil { + app.ui.echoerrf("%s", err) + return + } + case "source": if len(e.args) != 1 { app.ui.echoerr("source: requires an argument") diff --git a/lf.1 b/lf.1 index 941e98e..4690fe6 100644 --- a/lf.1 +++ b/lf.1 @@ -74,6 +74,8 @@ The following commands are provided by lf without default keybindings: echoerr same as echomsg but red color cd change working directory to the argument select change current file selection to the argument + glob-select select files that match the given glob + glob-unselect unselect files that match the given glob source read the configuration file in the argument push simulate key pushes given in the argument delete remove the current file or selected file(s) diff --git a/nav.go b/nav.go index 146e444..ed1e833 100644 --- a/nav.go +++ b/nav.go @@ -794,6 +794,30 @@ func (nav *nav) sel(path string) error { return nil } +func (nav *nav) globSel(pattern string, invert bool) error { + curDir := nav.currDir() + anyMatches := false + + for i := 0; i < len(curDir.files); i++ { + match, err := filepath.Match(pattern, curDir.files[i].Name()) + + if err != nil { + return fmt.Errorf("glob-select: %s", err) + } + if match { + anyMatches = true + fpath := filepath.Join(curDir.path, curDir.files[i].Name()) + if _, ok := nav.selections[fpath]; ok == invert { + nav.toggleSelection(fpath) + } + } + } + if !anyMatches { + return fmt.Errorf("glob-select: pattern not found: %s", pattern) + } + return nil +} + func findMatch(name, pattern string) bool { if gOpts.ignorecase { lpattern := strings.ToLower(pattern)