aboutsummaryrefslogblamecommitdiffstats
path: root/vendor/github.com/awesome-gocui/gocui/keybinding.go
blob: d294e70de599fd9eb149b919cfe4cc073e111e2b (plain) (tree)
1
2
3
4
5
6





                                                         











                                                                        
 







                                                                      
 
































































                                                                               










                                                                                                                       
 






                                                                          


                                                             
         
                                    

 












































































                                            

























                                                      





                                                    
























































                                                              
// Copyright 2014 The gocui Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocui

import (
	"strings"

	"github.com/awesome-gocui/termbox-go"
)

// Key represents special keys or keys combinations.
type Key termbox.Key

// Modifier allows to define special keys combinations. They can be used
// in combination with Keys or Runes when a new keybinding is defined.
type Modifier termbox.Modifier

// Keybidings are used to link a given key-press event with a handler.
type keybinding struct {
	viewName string
	key      Key
	ch       rune
	mod      Modifier
	handler  func(*Gui, *View) error
}

// Parse takes the input string and extracts the keybinding.
// Returns a Key / rune, a Modifier and an error.
func Parse(input string) (interface{}, Modifier, error) {
	if len(input) == 1 {
		_, r, err := getKey(rune(input[0]))
		if err != nil {
			return nil, ModNone, err
		}
		return r, ModNone, nil
	}

	var modifier Modifier
	cleaned := make([]string, 0)

	tokens := strings.Split(input, "+")
	for _, t := range tokens {
		normalized := strings.Title(strings.ToLower(t))
		if t == "Alt" {
			modifier = ModAlt
			continue
		}
		cleaned = append(cleaned, normalized)
	}

	key, exist := translate[strings.Join(cleaned, "")]
	if !exist {
		return nil, ModNone, ErrNoSuchKeybind
	}

	return key, modifier, nil
}

// ParseAll takes an array of strings and returns a map of all keybindings.
func ParseAll(input []string) (map[interface{}]Modifier, error) {
	ret := make(map[interface{}]Modifier)
	for _, i := range input {
		k, m, err := Parse(i)
		if err != nil {
			return ret, err
		}
		ret[k] = m
	}
	return ret, nil
}

// MustParse takes the input string and returns a Key / rune and a Modifier.
// It will panic if any error occured.
func MustParse(input string) (interface{}, Modifier) {
	k, m, err := Parse(input)
	if err != nil {
		panic(err)
	}
	return k, m
}

// MustParseAll takes an array of strings and returns a map of all keybindings.
// It will panic if any error occured.
func MustParseAll(input []string) map[interface{}]Modifier {
	result, err := ParseAll(input)
	if err != nil {
		panic(err)
	}
	return result
}

// newKeybinding returns a new Keybinding object.
func newKeybinding(viewname string, key Key, ch rune, mod Modifier, handler func(*Gui, *View) error) (kb *keybinding) {
	kb = &keybinding{
		viewName: viewname,
		key:      key,
		ch:       ch,
		mod:      mod,
		handler:  handler,
	}
	return kb
}

// matchKeypress returns if the keybinding matches the keypress.
func (kb *keybinding) matchKeypress(key Key, ch rune, mod Modifier) bool {
	return kb.key == key && kb.ch == ch && kb.mod == mod
}

// matchView returns if the keybinding matches the current view.
func (kb *keybinding) matchView(v *View) bool {
	// if the user is typing in a field, ignore char keys
	if v == nil || (v.Editable && kb.ch != 0) {
		return false
	}
	return kb.viewName == v.name
}

// translations for strings to keys
var translate = map[string]Key{
	"F1":             KeyF1,
	"F2":             KeyF2,
	"F3":             KeyF3,
	"F4":             KeyF4,
	"F5":             KeyF5,
	"F6":             KeyF6,
	"F7":             KeyF7,
	"F8":             KeyF8,
	"F9":             KeyF9,
	"F10":            KeyF10,
	"F11":            KeyF11,
	"F12":            KeyF12,
	"Insert":         KeyInsert,
	"Delete":         KeyDelete,
	"Home":           KeyHome,
	"End":            KeyEnd,
	"Pgup":           KeyPgup,
	"Pgdn":           KeyPgdn,
	"ArrowUp":        KeyArrowUp,
	"ArrowDown":      KeyArrowDown,
	"ArrowLeft":      KeyArrowLeft,
	"ArrowRight":     KeyArrowRight,
	"CtrlTilde":      KeyCtrlTilde,
	"Ctrl2":          KeyCtrl2,
	"CtrlSpace":      KeyCtrlSpace,
	"CtrlA":          KeyCtrlA,
	"CtrlB":          KeyCtrlB,
	"CtrlC":          KeyCtrlC,
	"CtrlD":          KeyCtrlD,
	"CtrlE":          KeyCtrlE,
	"CtrlF":          KeyCtrlF,
	"CtrlG":          KeyCtrlG,
	"Backspace":      KeyBackspace,
	"CtrlH":          KeyCtrlH,
	"Tab":            KeyTab,
	"CtrlI":          KeyCtrlI,
	"CtrlJ":          KeyCtrlJ,
	"CtrlK":          KeyCtrlK,
	"CtrlL":          KeyCtrlL,
	"Enter":          KeyEnter,
	"CtrlM":          KeyCtrlM,
	"CtrlN":          KeyCtrlN,
	"CtrlO":          KeyCtrlO,
	"CtrlP":          KeyCtrlP,
	"CtrlQ":          KeyCtrlQ,
	"CtrlR":          KeyCtrlR,
	"CtrlS":          KeyCtrlS,
	"CtrlT":          KeyCtrlT,
	"CtrlU":          KeyCtrlU,
	"CtrlV":          KeyCtrlV,
	"CtrlW":          KeyCtrlW,
	"CtrlX":          KeyCtrlX,
	"CtrlY":          KeyCtrlY,
	"CtrlZ":          KeyCtrlZ,
	"Esc":            KeyEsc,
	"CtrlLsqBracket": KeyCtrlLsqBracket,
	"Ctrl3":          KeyCtrl3,
	"Ctrl4":          KeyCtrl4,
	"CtrlBackslash":  KeyCtrlBackslash,
	"Ctrl5":          KeyCtrl5,
	"CtrlRsqBracket": KeyCtrlRsqBracket,
	"Ctrl6":          KeyCtrl6,
	"Ctrl7":          KeyCtrl7,
	"CtrlSlash":      KeyCtrlSlash,
	"CtrlUnderscore": KeyCtrlUnderscore,
	"Space":          KeySpace,
	"Backspace2":     KeyBackspace2,
	"Ctrl8":          KeyCtrl8,
	"Mouseleft":      MouseLeft,
	"Mousemiddle":    MouseMiddle,
	"Mouseright":     MouseRight,
	"Mouserelease":   MouseRelease,
	"MousewheelUp":   MouseWheelUp,
	"MousewheelDown": MouseWheelDown,
}

// Special keys.
const (
	KeyF1         Key = Key(termbox.KeyF1)
	KeyF2             = Key(termbox.KeyF2)
	KeyF3             = Key(termbox.KeyF3)
	KeyF4             = Key(termbox.KeyF4)
	KeyF5             = Key(termbox.KeyF5)
	KeyF6             = Key(termbox.KeyF6)
	KeyF7             = Key(termbox.KeyF7)
	KeyF8             = Key(termbox.KeyF8)
	KeyF9             = Key(termbox.KeyF9)
	KeyF10            = Key(termbox.KeyF10)
	KeyF11            = Key(termbox.KeyF11)
	KeyF12            = Key(termbox.KeyF12)
	KeyInsert         = Key(termbox.KeyInsert)
	KeyDelete         = Key(termbox.KeyDelete)
	KeyHome           = Key(termbox.KeyHome)
	KeyEnd            = Key(termbox.KeyEnd)
	KeyPgup           = Key(termbox.KeyPgup)
	KeyPgdn           = Key(termbox.KeyPgdn)
	KeyArrowUp        = Key(termbox.KeyArrowUp)
	KeyArrowDown      = Key(termbox.KeyArrowDown)
	KeyArrowLeft      = Key(termbox.KeyArrowLeft)
	KeyArrowRight     = Key(termbox.KeyArrowRight)

	MouseLeft      = Key(termbox.MouseLeft)
	MouseMiddle    = Key(termbox.MouseMiddle)
	MouseRight     = Key(termbox.MouseRight)
	MouseRelease   = Key(termbox.MouseRelease)
	MouseWheelUp   = Key(termbox.MouseWheelUp)
	MouseWheelDown = Key(termbox.MouseWheelDown)
)

// Keys combinations.
const (
	KeyCtrlTilde      Key = Key(termbox.KeyCtrlTilde)
	KeyCtrl2              = Key(termbox.KeyCtrl2)
	KeyCtrlSpace          = Key(termbox.KeyCtrlSpace)
	KeyCtrlA              = Key(termbox.KeyCtrlA)
	KeyCtrlB              = Key(termbox.KeyCtrlB)
	KeyCtrlC              = Key(termbox.KeyCtrlC)
	KeyCtrlD              = Key(termbox.KeyCtrlD)
	KeyCtrlE              = Key(termbox.KeyCtrlE)
	KeyCtrlF              = Key(termbox.KeyCtrlF)
	KeyCtrlG              = Key(termbox.KeyCtrlG)
	KeyBackspace          = Key(termbox.KeyBackspace)
	KeyCtrlH              = Key(termbox.KeyCtrlH)
	KeyTab                = Key(termbox.KeyTab)
	KeyCtrlI              = Key(termbox.KeyCtrlI)
	KeyCtrlJ              = Key(termbox.KeyCtrlJ)
	KeyCtrlK              = Key(termbox.KeyCtrlK)
	KeyCtrlL              = Key(termbox.KeyCtrlL)
	KeyEnter              = Key(termbox.KeyEnter)
	KeyCtrlM              = Key(termbox.KeyCtrlM)
	KeyCtrlN              = Key(termbox.KeyCtrlN)
	KeyCtrlO              = Key(termbox.KeyCtrlO)
	KeyCtrlP              = Key(termbox.KeyCtrlP)
	KeyCtrlQ              = Key(termbox.KeyCtrlQ)
	KeyCtrlR              = Key(termbox.KeyCtrlR)
	KeyCtrlS              = Key(termbox.KeyCtrlS)
	KeyCtrlT              = Key(termbox.KeyCtrlT)
	KeyCtrlU              = Key(termbox.KeyCtrlU)
	KeyCtrlV              = Key(termbox.KeyCtrlV)
	KeyCtrlW              = Key(termbox.KeyCtrlW)
	KeyCtrlX              = Key(termbox.KeyCtrlX)
	KeyCtrlY              = Key(termbox.KeyCtrlY)
	KeyCtrlZ              = Key(termbox.KeyCtrlZ)
	KeyEsc                = Key(termbox.KeyEsc)
	KeyCtrlLsqBracket     = Key(termbox.KeyCtrlLsqBracket)
	KeyCtrl3              = Key(termbox.KeyCtrl3)
	KeyCtrl4              = Key(termbox.KeyCtrl4)
	KeyCtrlBackslash      = Key(termbox.KeyCtrlBackslash)
	KeyCtrl5              = Key(termbox.KeyCtrl5)
	KeyCtrlRsqBracket     = Key(termbox.KeyCtrlRsqBracket)
	KeyCtrl6              = Key(termbox.KeyCtrl6)
	KeyCtrl7              = Key(termbox.KeyCtrl7)
	KeyCtrlSlash          = Key(termbox.KeyCtrlSlash)
	KeyCtrlUnderscore     = Key(termbox.KeyCtrlUnderscore)
	KeySpace              = Key(termbox.KeySpace)
	KeyBackspace2         = Key(termbox.KeyBackspace2)
	KeyCtrl8              = Key(termbox.KeyCtrl8)
)

// Modifiers.
const (
	ModNone Modifier = Modifier(0)
	ModAlt           = Modifier(termbox.ModAlt)
)