Infobar history

This commit is contained in:
Zachary Yedidia
2019-01-03 17:07:28 -05:00
parent 6fdf275b8a
commit e29cae4f7f
6 changed files with 100 additions and 63 deletions

View File

@@ -560,7 +560,7 @@ func (h *BufHandler) SaveAs() bool {
// Find opens a prompt and searches forward for the input
func (h *BufHandler) Find() bool {
InfoBar.Prompt("Find: ", "", func(resp string) {
InfoBar.Prompt("Find: ", "", "Find", func(resp string) {
// Event callback
match, found, _ := h.Buf.FindNext(resp, h.Cursor.Loc, true)
if found {
@@ -802,7 +802,7 @@ func (h *BufHandler) SelectAll() bool {
// OpenFile opens a new file in the buffer
func (h *BufHandler) OpenFile() bool {
InfoBar.Prompt("> ", "open ", nil, func(resp string, canceled bool) {
InfoBar.Prompt("> ", "open ", "Open", nil, func(resp string, canceled bool) {
if !canceled {
HandleCommand(resp)
}
@@ -966,7 +966,7 @@ func (h *BufHandler) ShellMode() bool {
// CommandMode lets the user enter a command
func (h *BufHandler) CommandMode() bool {
InfoBar.Prompt("> ", "", nil, func(resp string, canceled bool) {
InfoBar.Prompt("> ", "", "Command", nil, func(resp string, canceled bool) {
if !canceled {
HandleCommand(resp)
}

View File

@@ -3,7 +3,6 @@ package action
import (
"os"
"github.com/zyedidia/micro/cmd/micro/info"
"github.com/zyedidia/micro/cmd/micro/shellwords"
"github.com/zyedidia/micro/cmd/micro/util"
)
@@ -11,13 +10,13 @@ import (
// A Command contains an action (a function to call) as well as information about how to autocomplete the command
type Command struct {
action func([]string)
completions []info.Completion
completions []Completion
}
// A StrCommand is similar to a command but keeps the name of the action
type StrCommand struct {
action string
completions []info.Completion
completions []Completion
}
var commands map[string]Command
@@ -71,7 +70,7 @@ func parseCommands(userCommands map[string]StrCommand) {
// MakeCommand is a function to easily create new commands
// This can be called by plugins in Lua so that plugins can define their own commands
func MakeCommand(name, function string, completions ...info.Completion) {
func MakeCommand(name, function string, completions ...Completion) {
action := commandActions[function]
// if _, ok := commandActions[function]; !ok {
// If the user seems to be binding a function that doesn't exist
@@ -85,32 +84,32 @@ func MakeCommand(name, function string, completions ...info.Completion) {
// DefaultCommands returns a map containing micro's default commands
func DefaultCommands() map[string]StrCommand {
return map[string]StrCommand{
"set": {"Set", []info.Completion{info.OptionCompletion, info.OptionValueCompletion}},
"setlocal": {"SetLocal", []info.Completion{info.OptionCompletion, info.OptionValueCompletion}},
"show": {"Show", []info.Completion{info.OptionCompletion, info.NoCompletion}},
"showkey": {"ShowKey", []info.Completion{info.NoCompletion}},
"bind": {"Bind", []info.Completion{info.NoCompletion}},
"run": {"Run", []info.Completion{info.NoCompletion}},
"quit": {"Quit", []info.Completion{info.NoCompletion}},
"save": {"Save", []info.Completion{info.NoCompletion}},
"replace": {"Replace", []info.Completion{info.NoCompletion}},
"replaceall": {"ReplaceAll", []info.Completion{info.NoCompletion}},
"vsplit": {"VSplit", []info.Completion{info.FileCompletion, info.NoCompletion}},
"hsplit": {"HSplit", []info.Completion{info.FileCompletion, info.NoCompletion}},
"tab": {"Tab", []info.Completion{info.FileCompletion, info.NoCompletion}},
"help": {"Help", []info.Completion{info.HelpCompletion, info.NoCompletion}},
"eval": {"Eval", []info.Completion{info.NoCompletion}},
"log": {"ToggleLog", []info.Completion{info.NoCompletion}},
"plugin": {"Plugin", []info.Completion{info.PluginCmdCompletion, info.PluginNameCompletion}},
"reload": {"Reload", []info.Completion{info.NoCompletion}},
"cd": {"Cd", []info.Completion{info.FileCompletion}},
"pwd": {"Pwd", []info.Completion{info.NoCompletion}},
"open": {"Open", []info.Completion{info.FileCompletion}},
"tabswitch": {"TabSwitch", []info.Completion{info.NoCompletion}},
"term": {"Term", []info.Completion{info.NoCompletion}},
"memusage": {"MemUsage", []info.Completion{info.NoCompletion}},
"retab": {"Retab", []info.Completion{info.NoCompletion}},
"raw": {"Raw", []info.Completion{info.NoCompletion}},
"set": {"Set", []Completion{OptionCompletion, OptionValueCompletion}},
"setlocal": {"SetLocal", []Completion{OptionCompletion, OptionValueCompletion}},
"show": {"Show", []Completion{OptionCompletion, NoCompletion}},
"showkey": {"ShowKey", []Completion{NoCompletion}},
"bind": {"Bind", []Completion{NoCompletion}},
"run": {"Run", []Completion{NoCompletion}},
"quit": {"Quit", []Completion{NoCompletion}},
"save": {"Save", []Completion{NoCompletion}},
"replace": {"Replace", []Completion{NoCompletion}},
"replaceall": {"ReplaceAll", []Completion{NoCompletion}},
"vsplit": {"VSplit", []Completion{FileCompletion, NoCompletion}},
"hsplit": {"HSplit", []Completion{FileCompletion, NoCompletion}},
"tab": {"Tab", []Completion{FileCompletion, NoCompletion}},
"help": {"Help", []Completion{HelpCompletion, NoCompletion}},
"eval": {"Eval", []Completion{NoCompletion}},
"log": {"ToggleLog", []Completion{NoCompletion}},
"plugin": {"Plugin", []Completion{PluginCmdCompletion, PluginNameCompletion}},
"reload": {"Reload", []Completion{NoCompletion}},
"cd": {"Cd", []Completion{FileCompletion}},
"pwd": {"Pwd", []Completion{NoCompletion}},
"open": {"Open", []Completion{FileCompletion}},
"tabswitch": {"TabSwitch", []Completion{NoCompletion}},
"term": {"Term", []Completion{NoCompletion}},
"memusage": {"MemUsage", []Completion{NoCompletion}},
"retab": {"Retab", []Completion{NoCompletion}},
"raw": {"Raw", []Completion{NoCompletion}},
}
}
@@ -119,7 +118,7 @@ func DefaultCommands() map[string]StrCommand {
// enter
func CommandEditAction(prompt string) BufKeyAction {
return func(h *BufHandler) bool {
InfoBar.Prompt("> ", prompt, nil, func(resp string, canceled bool) {
InfoBar.Prompt("> ", prompt, "Command", nil, func(resp string, canceled bool) {
if !canceled {
HandleCommand(resp)
}

View File

@@ -1,4 +1,4 @@
package info
package action
import (
"io/ioutil"
@@ -76,20 +76,20 @@ func FileComplete(input string) (string, []string) {
}
// CommandComplete autocompletes commands
// func CommandComplete(input string) (string, []string) {
// var suggestions []string
// for cmd := range commands {
// if strings.HasPrefix(cmd, input) {
// suggestions = append(suggestions, cmd)
// }
// }
//
// var chosen string
// if len(suggestions) == 1 {
// chosen = suggestions[0]
// }
// return chosen, suggestions
// }
func CommandComplete(input string) (string, []string) {
var suggestions []string
for cmd := range commands {
if strings.HasPrefix(cmd, input) {
suggestions = append(suggestions, cmd)
}
}
var chosen string
if len(suggestions) == 1 {
chosen = suggestions[0]
}
return chosen, suggestions
}
// HelpComplete autocompletes help topics
func HelpComplete(input string) (string, []string) {

View File

@@ -35,6 +35,15 @@ func (h *InfoHandler) HandleEvent(event tcell.Event) {
done := h.DoKeyEvent(ke)
if !done && e.Key() == tcell.KeyRune {
h.DoRuneInsert(e.Rune())
done = true
}
if done && h.HasPrompt {
resp := strings.TrimSpace(string(h.LineBytes(0)))
hist := h.History[h.PromptType]
hist[h.HistoryNum] = resp
if h.EventCallback != nil {
h.EventCallback(resp)
}
}
case *tcell.EventMouse:
h.BufHandler.HandleEvent(event)
@@ -61,19 +70,9 @@ func (h *InfoHandler) DoKeyEvent(e KeyEvent) bool {
done = action(h.BufHandler)
}
}
if done && h.EventCallback != nil {
h.EventCallback(strings.TrimSpace(string(h.LineBytes(0))))
}
return done
}
func (h *InfoHandler) DoRuneInsert(r rune) {
h.BufHandler.DoRuneInsert(r)
if h.EventCallback != nil {
h.EventCallback(strings.TrimSpace(string(h.LineBytes(0))))
}
}
// InfoNones is a list of actions that should have no effect when executed
// by an infohandler
var InfoNones = []string{
@@ -136,10 +135,10 @@ var InfoOverrides = map[string]InfoKeyAction{
}
func (h *InfoHandler) CursorUp() {
// TODO: history
h.UpHistory(h.History[h.PromptType])
}
func (h *InfoHandler) CursorDown() {
// TODO: history
h.DownHistory(h.History[h.PromptType])
}
func (h *InfoHandler) InsertTab() {
// TODO: autocomplete

View File

@@ -59,3 +59,21 @@ func (i *InfoBuf) SaveHistory() {
}
}
}
// UpHistory fetches the previous item in the history
func (i *InfoBuf) UpHistory(history []string) {
if i.HistoryNum > 0 {
i.HistoryNum--
i.Replace(i.Start(), i.End(), history[i.HistoryNum])
i.Buffer.GetActiveCursor().GotoLoc(i.End())
}
}
// DownHistory fetches the next item in the history
func (i *InfoBuf) DownHistory(history []string) {
if i.HistoryNum < len(history)-1 {
i.HistoryNum++
i.Replace(i.Start(), i.End(), history[i.HistoryNum])
i.Buffer.GetActiveCursor().GotoLoc(i.End())
}
}

View File

@@ -16,6 +16,8 @@ type InfoBuf struct {
HasMessage bool
HasError bool
PromptType string
Msg string
// This map stores the history for all the different kinds of uses Prompt has
@@ -36,10 +38,16 @@ func NewBuffer() *InfoBuf {
ib.History = make(map[string][]string)
ib.Buffer = buffer.NewBufferFromString("", "infobar", buffer.BTInfo)
ib.LoadHistory()
return ib
}
// Close performs any cleanup necessary when shutting down the infobuffer
func (i *InfoBuf) Close() {
i.SaveHistory()
}
// Message sends a message to the user
func (i *InfoBuf) Message(msg ...interface{}) {
// only display a new message if there isn't an active prompt
@@ -68,12 +76,20 @@ func (i *InfoBuf) Error(msg ...interface{}) {
// and callbacks executed when the user executes an event and when the user finishes the prompt
// The eventcb passes the current user response as the argument and donecb passes the user's message
// and a boolean indicating if the prompt was canceled
func (i *InfoBuf) Prompt(prompt string, msg string, eventcb func(string), donecb func(string, bool)) {
func (i *InfoBuf) Prompt(prompt string, msg string, ptype string, eventcb func(string), donecb func(string, bool)) {
// If we get another prompt mid-prompt we cancel the one getting overwritten
if i.HasPrompt {
i.DonePrompt(true)
}
if _, ok := i.History[ptype]; !ok {
i.History[ptype] = []string{""}
} else {
i.History[ptype] = append(i.History[ptype], "")
}
i.HistoryNum = len(i.History[ptype]) - 1
i.PromptType = ptype
i.Msg = prompt
i.HasPrompt = true
i.HasMessage, i.HasError = false, false
@@ -88,8 +104,13 @@ func (i *InfoBuf) DonePrompt(canceled bool) {
if i.PromptCallback != nil {
if canceled {
i.PromptCallback("", true)
h := i.History[i.PromptType]
i.History[i.PromptType] = h[:len(h)-1]
} else {
i.PromptCallback(strings.TrimSpace(string(i.LineBytes(0))), false)
resp := strings.TrimSpace(string(i.LineBytes(0)))
i.PromptCallback(resp, false)
h := i.History[i.PromptType]
h[len(h)-1] = resp
}
}
i.PromptCallback = nil