Loading dclish/completer.go 0 → 100644 +81 −0 Original line number Diff line number Diff line package dclish import ( "strings" "unicode" ) // Completer command completer type. type Completer struct { commands []string flags map[string][]string } // NewCompleter creates a new completer. func NewCompleter(commands Commands) Completer { comps := []string{} flags := map[string][]string{} for c := range commands { comps = append(comps, c) if len(commands[c].Commands) > 0 { subcommands := commands[c].Commands for subc := range subcommands { fullc := c + " " + subc comps = append(comps, fullc) flags[fullc] = []string{} if subcommands[subc].Flags != nil { for f := range subcommands[subc].Flags { flags[fullc] = append(flags[fullc], f) } } } } flags[c] = []string{} if commands[c].Flags != nil { for f := range commands[c].Flags { flags[c] = append(flags[c], f) } } } return Completer{ commands: comps, flags: flags, } } // Do return a list of possible completions. func (c Completer) Do(line []rune, pos int) ([][]rune, int) { // Nothing typed in. if pos == 0 { newline := make([][]rune, len(c.commands)) for i := range c.commands { newline[i] = []rune(c.commands[i]) } return newline, pos } // Command partially typed in. newline := [][]rune{} cmd := strings.ToUpper(string(line[0:pos])) lower := false if unicode.IsLower(line[0]) { lower = true } for i := range c.commands { if strings.HasPrefix(c.commands[i], cmd) { rest := strings.Replace(c.commands[i], cmd, "", 1) if lower { newline = append(newline, []rune(strings.ToLower(rest))) } else { newline = append(newline, []rune(rest)) } } } if len(newline) > 0 { return newline, pos } // Command completely typed in. // TODO: figure out flags. return newline, pos } dclish/dclish.go +5 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,10 @@ import ( // ActionFunc is the function that a command runs. type ActionFunc func(*Command) error // CompleterFunc is a function to provide completions for arguments for // a given command. type CompleterFunc func() []string // Flag is a flag for a command. type Flag struct { OptArg bool Loading @@ -30,6 +34,7 @@ type Command struct { MinArgs int Commands Commands Action ActionFunc Completer CompleterFunc Description string } Loading repl/repl.go +5 −3 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import ( "strings" "unicode" "git.lyda.ie/kevin/bulletin/dclish" "git.lyda.ie/kevin/bulletin/this" "github.com/adrg/xdg" "github.com/chzyer/readline" Loading @@ -15,6 +16,7 @@ import ( // Loop is the main event loop. func Loop() error { completer := dclish.NewCompleter(commands) histdir := path.Join(xdg.ConfigHome, "BULLETIN") os.MkdirAll(histdir, 0700) histfile := path.Join(histdir, fmt.Sprintf("%s.history", this.User.Login)) Loading @@ -22,7 +24,7 @@ func Loop() error { &readline.Config{ Prompt: "BULLETIN> ", HistoryFile: histfile, // TODO: AutoComplete: completer, AutoComplete: completer, InterruptPrompt: "^C", EOFPrompt: "EXIT", HistorySearchFold: true, Loading Loading
dclish/completer.go 0 → 100644 +81 −0 Original line number Diff line number Diff line package dclish import ( "strings" "unicode" ) // Completer command completer type. type Completer struct { commands []string flags map[string][]string } // NewCompleter creates a new completer. func NewCompleter(commands Commands) Completer { comps := []string{} flags := map[string][]string{} for c := range commands { comps = append(comps, c) if len(commands[c].Commands) > 0 { subcommands := commands[c].Commands for subc := range subcommands { fullc := c + " " + subc comps = append(comps, fullc) flags[fullc] = []string{} if subcommands[subc].Flags != nil { for f := range subcommands[subc].Flags { flags[fullc] = append(flags[fullc], f) } } } } flags[c] = []string{} if commands[c].Flags != nil { for f := range commands[c].Flags { flags[c] = append(flags[c], f) } } } return Completer{ commands: comps, flags: flags, } } // Do return a list of possible completions. func (c Completer) Do(line []rune, pos int) ([][]rune, int) { // Nothing typed in. if pos == 0 { newline := make([][]rune, len(c.commands)) for i := range c.commands { newline[i] = []rune(c.commands[i]) } return newline, pos } // Command partially typed in. newline := [][]rune{} cmd := strings.ToUpper(string(line[0:pos])) lower := false if unicode.IsLower(line[0]) { lower = true } for i := range c.commands { if strings.HasPrefix(c.commands[i], cmd) { rest := strings.Replace(c.commands[i], cmd, "", 1) if lower { newline = append(newline, []rune(strings.ToLower(rest))) } else { newline = append(newline, []rune(rest)) } } } if len(newline) > 0 { return newline, pos } // Command completely typed in. // TODO: figure out flags. return newline, pos }
dclish/dclish.go +5 −0 Original line number Diff line number Diff line Loading @@ -10,6 +10,10 @@ import ( // ActionFunc is the function that a command runs. type ActionFunc func(*Command) error // CompleterFunc is a function to provide completions for arguments for // a given command. type CompleterFunc func() []string // Flag is a flag for a command. type Flag struct { OptArg bool Loading @@ -30,6 +34,7 @@ type Command struct { MinArgs int Commands Commands Action ActionFunc Completer CompleterFunc Description string } Loading
repl/repl.go +5 −3 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ import ( "strings" "unicode" "git.lyda.ie/kevin/bulletin/dclish" "git.lyda.ie/kevin/bulletin/this" "github.com/adrg/xdg" "github.com/chzyer/readline" Loading @@ -15,6 +16,7 @@ import ( // Loop is the main event loop. func Loop() error { completer := dclish.NewCompleter(commands) histdir := path.Join(xdg.ConfigHome, "BULLETIN") os.MkdirAll(histdir, 0700) histfile := path.Join(histdir, fmt.Sprintf("%s.history", this.User.Login)) Loading @@ -22,7 +24,7 @@ func Loop() error { &readline.Config{ Prompt: "BULLETIN> ", HistoryFile: histfile, // TODO: AutoComplete: completer, AutoComplete: completer, InterruptPrompt: "^C", EOFPrompt: "EXIT", HistorySearchFold: true, Loading