fuzzy searching stuff for cmd suggestions

This commit is contained in:
Felix Angell 2018-04-29 01:31:41 +01:00
parent d44801de76
commit 8c27c35353
3 changed files with 69 additions and 17 deletions

View File

@ -2,17 +2,27 @@ package gui
import "os" import "os"
type BufferAction func(*Buffer) bool type BufferAction struct {
name string
proc func(*Buffer) bool
}
func NewBufferAction(name string, proc func(*Buffer) bool) BufferAction {
return BufferAction{
name: name,
proc: proc,
}
}
var actions = map[string]BufferAction{ var actions = map[string]BufferAction{
"save": Save, "save": NewBufferAction("save", Save),
"delete_line": DeleteLine, "delete_line": NewBufferAction("delete_ine", DeleteLine),
"close_buffer": CloseBuffer, "close_buffer": NewBufferAction("close_buffer", CloseBuffer),
"paste": Paste, "paste": NewBufferAction("paste", Paste),
"show_palette": ShowPalette, "show_palette": NewBufferAction("show_palette", ShowPalette),
"exit": func(*Buffer) bool { "exit": NewBufferAction("exit", func(*Buffer) bool {
// TODO do this properly lol // TODO do this properly lol
os.Exit(0) os.Exit(0)
return false return false
}, }),
} }

View File

@ -236,9 +236,9 @@ func (b *Buffer) processTextInput(r rune) bool {
if CONTROL_DOWN { if CONTROL_DOWN {
actionName, actionExists := cfg.Shortcuts.Controls[string(unicode.ToLower(r))] actionName, actionExists := cfg.Shortcuts.Controls[string(unicode.ToLower(r))]
if actionExists { if actionExists {
if proc, ok := actions[actionName]; ok { if action, ok := actions[actionName]; ok {
log.Println("Executing action '" + actionName + "'") log.Println("Executing action '" + actionName + "'")
return proc(b) return action.proc(b)
} }
} else { } else {
log.Println("warning, unimplemented shortcut ctrl +", string(unicode.ToLower(r)), actionName) log.Println("warning, unimplemented shortcut ctrl +", string(unicode.ToLower(r)), actionName)
@ -248,8 +248,8 @@ func (b *Buffer) processTextInput(r rune) bool {
if SUPER_DOWN { if SUPER_DOWN {
actionName, actionExists := cfg.Shortcuts.Supers[string(unicode.ToLower(r))] actionName, actionExists := cfg.Shortcuts.Supers[string(unicode.ToLower(r))]
if actionExists { if actionExists {
if proc, ok := actions[actionName]; ok { if action, ok := actions[actionName]; ok {
return proc(b) return action.proc(b)
} }
} else { } else {
log.Println("warning, unimplemented shortcut ctrl+", unicode.ToLower(r), actionName) log.Println("warning, unimplemented shortcut ctrl+", unicode.ToLower(r), actionName)

View File

@ -1,6 +1,7 @@
package gui package gui
import ( import (
"github.com/felixangell/fuzzysearch/fuzzy"
"github.com/felixangell/phi/cfg" "github.com/felixangell/phi/cfg"
"github.com/felixangell/strife" "github.com/felixangell/strife"
"github.com/veandco/go-sdl2/sdl" "github.com/veandco/go-sdl2/sdl"
@ -8,10 +9,30 @@ import (
"strings" "strings"
) )
var commandSet []string
func init() {
commandSet = make([]string, len(actions))
for _, action := range actions {
commandSet = append(commandSet, action.name)
}
}
type CommandPalette struct { type CommandPalette struct {
BaseComponent BaseComponent
buff *Buffer buff *Buffer
parentBuff *Buffer parentBuff *Buffer
recentSuggestions *[]suggestion
}
const suggestionBoxHeight = 128
type suggestion struct {
name string
}
func (s *suggestion) render(x, y int, ctx *strife.Renderer) {
ctx.String(s.name, x, y)
} }
func NewCommandPalette(conf cfg.TomlConfig, view *View) *CommandPalette { func NewCommandPalette(conf cfg.TomlConfig, view *View) *CommandPalette {
@ -39,7 +60,6 @@ func (b *CommandPalette) OnInit() {
func (b *CommandPalette) processCommand() { func (b *CommandPalette) processCommand() {
tokenizedLine := strings.Split(b.buff.contents[0].String(), " ") tokenizedLine := strings.Split(b.buff.contents[0].String(), " ")
command := tokenizedLine[0] command := tokenizedLine[0]
action, exists := actions[command] action, exists := actions[command]
@ -47,11 +67,26 @@ func (b *CommandPalette) processCommand() {
return return
} }
action(b.parentBuff) action.proc(b.parentBuff)
}
func (b *CommandPalette) calculateSuggestions() {
tokenizedLine := strings.Split(b.buff.contents[0].String(), " ")
command := tokenizedLine[0]
ranks := fuzzy.RankFind(command, commandSet)
suggestions := make([]suggestion, len(ranks))
for _, r := range ranks {
cmdName := commandSet[r.Index]
suggestions = append(suggestions, suggestion{cmdName})
}
b.recentSuggestions = &suggestions
} }
func (b *CommandPalette) clearInput() { func (b *CommandPalette) clearInput() {
actions["delete_line"](b.buff) actions["delete_line"].proc(b.buff)
} }
func (b *CommandPalette) OnUpdate() bool { func (b *CommandPalette) OnUpdate() bool {
@ -61,6 +96,7 @@ func (b *CommandPalette) OnUpdate() bool {
override := func(k int) bool { override := func(k int) bool {
if k != sdl.K_RETURN && k != sdl.K_ESCAPE { if k != sdl.K_RETURN && k != sdl.K_ESCAPE {
b.calculateSuggestions()
return false return false
} }
@ -82,6 +118,12 @@ func (b *CommandPalette) OnRender(ctx *strife.Renderer) {
ctx.Rect(b.x-border, b.y-border, b.w+(border*2), b.h+(border*2), strife.Fill) ctx.Rect(b.x-border, b.y-border, b.w+(border*2), b.h+(border*2), strife.Fill)
b.buff.OnRender(ctx) b.buff.OnRender(ctx)
if b.recentSuggestions != nil {
for i, sugg := range *b.recentSuggestions {
sugg.render(b.x, b.y+(i*suggestionBoxHeight), ctx)
}
}
} }
func (b *CommandPalette) OnDispose() { func (b *CommandPalette) OnDispose() {