diff options
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 115 |
1 files changed, 115 insertions, 0 deletions
@@ -0,0 +1,115 @@ +package main + +// #cgo linux LDFLAGS: -lX11 -lXtst -lXi +// #include "keyboard_writer.h" +// #include "keyboard_reader.h" +import "C" + +import ( + "errors" + "fmt" + "github.com/BurntSushi/toml" + "github.com/sirupsen/logrus" + "reflect" + "strings" + "time" +) + +type tomlConfig struct { + Bindings map[string]binding +} + +type binding struct { + Keypress string + Text string +} + +func main() { + // Startup Load the config + config, err := get_config() + if err != nil { + logrus.Println(err) + return + } + for { + expansion := wait_for_autocomplete(config) + logrus.Println(fmt.Sprintf("executing: %s", expansion)) + time.Sleep(100 * time.Millisecond) + for _, v := range expansion { + cs := C.CString(char_to_x11(string(v))) + if stringInSlice(string(v), needsShift) { + C.x11_key_shift(cs) + } else { + C.x11_key(cs) + } + } + } +} + +func get_config() (tomlConfig, error) { + var config tomlConfig + if _, err := toml.DecodeFile("incantation.toml", &config); err != nil { + return config, errors.New("Can't load config file") + } + return config, nil +} + +func wait_for_autocomplete(config tomlConfig) string { + max_length := 10 + buffer := make([]string, max_length) + for { + key_press := x11_to_char(C.GoString(C.get_key())) + // Cut down length + if len(buffer) == max_length { + buffer = buffer[1:] + } + buffer = append(buffer, key_press) + logrus.Println(strings.Join(buffer, ", ")) + // Check for expansion matches, windowing through buffer + for _, binding := range config.Bindings { + // Build kepress string into slice for slice comparison + keypress_slice := make([]string, 0) + for _, v := range binding.Keypress { + keypress_slice = append(keypress_slice, string(v)) + } + for i := 0; i < len(buffer)-len(keypress_slice)+1; i++ { + tmp_buf := buffer[i : i+len(keypress_slice)] + if reflect.DeepEqual(tmp_buf, keypress_slice) { + // Erase the keypresses + for range binding.Keypress { + cs := C.CString("BackSpace") + C.x11_key(cs) + } + return binding.Text + } + } + } + } +} + +func char_to_x11(code string) string { + for k, v := range x11Map { + if k == code { + return v + } + } + return code +} + +func x11_to_char(code string) string { + for k, v := range x11Map { + if v == code { + return k + } + } + return code +} + +func stringInSlice(a string, list []string) bool { + for _, b := range list { + if b == a { + return true + } + } + return false +} |