Skip to content

Commit

Permalink
Add FileSystemCompleter and example
Browse files Browse the repository at this point in the history
  • Loading branch information
c-bata committed Jun 23, 2018
1 parent 7a24f16 commit a537115
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
30 changes: 30 additions & 0 deletions _tools/complete_file/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package main

import (
"fmt"
"os"
"strings"

"github.com/c-bata/go-prompt"
"github.com/c-bata/go-prompt/completer"
)

func executor(in string) {
fmt.Println("Your input: " + in)
}

func main() {
c := completer.FilePathCompleter{
IgnoreCase: true,
Filter: func(fi os.FileInfo, filename string) bool {
return fi.IsDir() || strings.HasSuffix(fi.Name(), ".go")
},
}
p := prompt.New(
executor,
c.Complete,
prompt.OptionPrefix(">>> "),
prompt.OptionCompletionWordSeparator(completer.FilePathCompletionSeparator),
)
p.Run()
}
56 changes: 56 additions & 0 deletions completer/file.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package completer

import (
"io/ioutil"
"log"
"os"
"path/filepath"

"github.com/c-bata/go-prompt"
)

var (
FilePathCompletionSeparator = string([]byte{' ', os.PathSeparator})
)

// FilePathCompleter is a completer for your local file system.
type FilePathCompleter struct {
Filter func(fi os.FileInfo, filename string) bool
IgnoreCase bool
fileListCache map[string][]prompt.Suggest
}

// Complete returns suggestions from your local file system.
func (c *FilePathCompleter) Complete(d prompt.Document) []prompt.Suggest {
if c.fileListCache == nil {
c.fileListCache = make(map[string][]prompt.Suggest, 4)
}
path := d.GetWordBeforeCursor()
base := filepath.Base(path)
if len(path) == 0 || path[len(path)-1] == os.PathSeparator {
base = ""
}

dir := filepath.Dir(path)
if cached, ok := c.fileListCache[dir]; ok {
return prompt.FilterHasPrefix(cached, base, c.IgnoreCase)
}

files, err := ioutil.ReadDir(dir)
if err != nil && os.IsNotExist(err) {
return nil
} else if err != nil {
log.Print("[ERROR] completer: cannot read directory items " + err.Error())
return nil
}

suggests := make([]prompt.Suggest, 0, len(files))
for _, f := range files {
if c.Filter != nil && !c.Filter(f, f.Name()) {
continue
}
suggests = append(suggests, prompt.Suggest{Text: f.Name()})
}
c.fileListCache[dir] = suggests
return prompt.FilterHasPrefix(suggests, base, c.IgnoreCase)
}

0 comments on commit a537115

Please sign in to comment.