summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGalen Abell <galen@galenabell.com>2019-07-30 15:10:57 -0400
committerDrew DeVault <sir@cmpwn.com>2019-08-02 09:22:39 -0400
commitc4b57aaad8a48a1347a0404001fdcb13532c7620 (patch)
tree4f276e2b6c0792f37649b37aaf5f015be62b33ae
parentb73fcaae32a0de7e070638620927d148064330f5 (diff)
downloadaerc-c4b57aaad8a48a1347a0404001fdcb13532c7620.zip
Add CompletePath method
CompletePath takes an existing path and returns possible filesystem completions based on that path.
-rw-r--r--commands/util.go91
1 files changed, 91 insertions, 0 deletions
diff --git a/commands/util.go b/commands/util.go
index e9fd205..81d2da6 100644
--- a/commands/util.go
+++ b/commands/util.go
@@ -1,12 +1,17 @@
package commands
import (
+ "fmt"
"io"
+ "os"
"os/exec"
+ "path/filepath"
+ "strings"
"time"
"git.sr.ht/~sircmpwn/aerc/widgets"
"github.com/gdamore/tcell"
+ "github.com/mitchellh/go-homedir"
)
// QuickTerm is an ephemeral terminal for running a single command and quiting.
@@ -54,3 +59,89 @@ func QuickTerm(aerc *widgets.Aerc, args []string, stdin io.Reader) (*widgets.Ter
return term, nil
}
+
+// CompletePath provides filesystem completions given a starting path.
+func CompletePath(path string) []string {
+ if path == "" {
+ // default to cwd
+ cwd, err := os.Getwd()
+ if err != nil {
+ return nil
+ }
+ path = cwd
+ }
+
+ path, err := homedir.Expand(path)
+ if err != nil {
+ return nil
+ }
+
+ // strip trailing slashes, etc.
+ path = filepath.Clean(path)
+
+ if _, err := os.Stat(path); os.IsNotExist(err) {
+ // if the path doesn't exist, it is likely due to it being a partial path
+ // in this case, we want to return possible matches (ie /hom* should match
+ // /home)
+ matches, err := filepath.Glob(fmt.Sprintf("%s*", path))
+ if err != nil {
+ return nil
+ }
+
+ for i, m := range matches {
+ if isDir(m) {
+ matches[i] = m + "/"
+ }
+ }
+
+ return matches
+ }
+
+ files := listDir(path, false)
+
+ for i, f := range files {
+ f = filepath.Join(path, f)
+ if isDir(f) {
+ f += "/"
+ }
+
+ files[i] = f
+ }
+
+ return files
+}
+
+func isDir(path string) bool {
+ info, err := os.Stat(path)
+ if err != nil {
+ return false
+ }
+
+ return info.IsDir()
+}
+
+// return all filenames in a directory, optionally including hidden files
+func listDir(path string, hidden bool) []string {
+ f, err := os.Open(path)
+ if err != nil {
+ return []string{}
+ }
+
+ files, err := f.Readdirnames(-1) // read all dir names
+ if err != nil {
+ return []string{}
+ }
+
+ if hidden {
+ return files
+ }
+
+ var filtered []string
+ for _, g := range files {
+ if !strings.HasPrefix(g, ".") {
+ filtered = append(filtered, g)
+ }
+ }
+
+ return filtered
+}