keybinding.go

  1// Copyright 2014 The gocui Authors. All rights reserved.
  2// Use of this source code is governed by a BSD-style
  3// license that can be found in the LICENSE file.
  4
  5package gocui
  6
  7import (
  8	"strings"
  9
 10	"github.com/awesome-gocui/termbox-go"
 11)
 12
 13// Key represents special keys or keys combinations.
 14type Key termbox.Key
 15
 16// Modifier allows to define special keys combinations. They can be used
 17// in combination with Keys or Runes when a new keybinding is defined.
 18type Modifier termbox.Modifier
 19
 20// Keybidings are used to link a given key-press event with a handler.
 21type keybinding struct {
 22	viewName string
 23	key      Key
 24	ch       rune
 25	mod      Modifier
 26	handler  func(*Gui, *View) error
 27}
 28
 29// Parse takes the input string and extracts the keybinding.
 30// Returns a Key / rune, a Modifier and an error.
 31func Parse(input string) (interface{}, Modifier, error) {
 32	if len(input) == 1 {
 33		_, r, err := getKey(rune(input[0]))
 34		if err != nil {
 35			return nil, ModNone, err
 36		}
 37		return r, ModNone, nil
 38	}
 39
 40	var modifier Modifier
 41	cleaned := make([]string, 0)
 42
 43	tokens := strings.Split(input, "+")
 44	for _, t := range tokens {
 45		normalized := strings.Title(strings.ToLower(t))
 46		if t == "Alt" {
 47			modifier = ModAlt
 48			continue
 49		}
 50		cleaned = append(cleaned, normalized)
 51	}
 52
 53	key, exist := translate[strings.Join(cleaned, "")]
 54	if !exist {
 55		return nil, ModNone, ErrNoSuchKeybind
 56	}
 57
 58	return key, modifier, nil
 59}
 60
 61// ParseAll takes an array of strings and returns a map of all keybindings.
 62func ParseAll(input []string) (map[interface{}]Modifier, error) {
 63	ret := make(map[interface{}]Modifier)
 64	for _, i := range input {
 65		k, m, err := Parse(i)
 66		if err != nil {
 67			return ret, err
 68		}
 69		ret[k] = m
 70	}
 71	return ret, nil
 72}
 73
 74// MustParse takes the input string and returns a Key / rune and a Modifier.
 75// It will panic if any error occured.
 76func MustParse(input string) (interface{}, Modifier) {
 77	k, m, err := Parse(input)
 78	if err != nil {
 79		panic(err)
 80	}
 81	return k, m
 82}
 83
 84// MustParseAll takes an array of strings and returns a map of all keybindings.
 85// It will panic if any error occured.
 86func MustParseAll(input []string) map[interface{}]Modifier {
 87	result, err := ParseAll(input)
 88	if err != nil {
 89		panic(err)
 90	}
 91	return result
 92}
 93
 94// newKeybinding returns a new Keybinding object.
 95func newKeybinding(viewname string, key Key, ch rune, mod Modifier, handler func(*Gui, *View) error) (kb *keybinding) {
 96	kb = &keybinding{
 97		viewName: viewname,
 98		key:      key,
 99		ch:       ch,
100		mod:      mod,
101		handler:  handler,
102	}
103	return kb
104}
105
106// matchKeypress returns if the keybinding matches the keypress.
107func (kb *keybinding) matchKeypress(key Key, ch rune, mod Modifier) bool {
108	return kb.key == key && kb.ch == ch && kb.mod == mod
109}
110
111// matchView returns if the keybinding matches the current view.
112func (kb *keybinding) matchView(v *View) bool {
113	// if the user is typing in a field, ignore char keys
114	if v == nil || (v.Editable && kb.ch != 0) {
115		return false
116	}
117	return kb.viewName == v.name
118}
119
120// translations for strings to keys
121var translate = map[string]Key{
122	"F1":             KeyF1,
123	"F2":             KeyF2,
124	"F3":             KeyF3,
125	"F4":             KeyF4,
126	"F5":             KeyF5,
127	"F6":             KeyF6,
128	"F7":             KeyF7,
129	"F8":             KeyF8,
130	"F9":             KeyF9,
131	"F10":            KeyF10,
132	"F11":            KeyF11,
133	"F12":            KeyF12,
134	"Insert":         KeyInsert,
135	"Delete":         KeyDelete,
136	"Home":           KeyHome,
137	"End":            KeyEnd,
138	"Pgup":           KeyPgup,
139	"Pgdn":           KeyPgdn,
140	"ArrowUp":        KeyArrowUp,
141	"ArrowDown":      KeyArrowDown,
142	"ArrowLeft":      KeyArrowLeft,
143	"ArrowRight":     KeyArrowRight,
144	"CtrlTilde":      KeyCtrlTilde,
145	"Ctrl2":          KeyCtrl2,
146	"CtrlSpace":      KeyCtrlSpace,
147	"CtrlA":          KeyCtrlA,
148	"CtrlB":          KeyCtrlB,
149	"CtrlC":          KeyCtrlC,
150	"CtrlD":          KeyCtrlD,
151	"CtrlE":          KeyCtrlE,
152	"CtrlF":          KeyCtrlF,
153	"CtrlG":          KeyCtrlG,
154	"Backspace":      KeyBackspace,
155	"CtrlH":          KeyCtrlH,
156	"Tab":            KeyTab,
157	"CtrlI":          KeyCtrlI,
158	"CtrlJ":          KeyCtrlJ,
159	"CtrlK":          KeyCtrlK,
160	"CtrlL":          KeyCtrlL,
161	"Enter":          KeyEnter,
162	"CtrlM":          KeyCtrlM,
163	"CtrlN":          KeyCtrlN,
164	"CtrlO":          KeyCtrlO,
165	"CtrlP":          KeyCtrlP,
166	"CtrlQ":          KeyCtrlQ,
167	"CtrlR":          KeyCtrlR,
168	"CtrlS":          KeyCtrlS,
169	"CtrlT":          KeyCtrlT,
170	"CtrlU":          KeyCtrlU,
171	"CtrlV":          KeyCtrlV,
172	"CtrlW":          KeyCtrlW,
173	"CtrlX":          KeyCtrlX,
174	"CtrlY":          KeyCtrlY,
175	"CtrlZ":          KeyCtrlZ,
176	"Esc":            KeyEsc,
177	"CtrlLsqBracket": KeyCtrlLsqBracket,
178	"Ctrl3":          KeyCtrl3,
179	"Ctrl4":          KeyCtrl4,
180	"CtrlBackslash":  KeyCtrlBackslash,
181	"Ctrl5":          KeyCtrl5,
182	"CtrlRsqBracket": KeyCtrlRsqBracket,
183	"Ctrl6":          KeyCtrl6,
184	"Ctrl7":          KeyCtrl7,
185	"CtrlSlash":      KeyCtrlSlash,
186	"CtrlUnderscore": KeyCtrlUnderscore,
187	"Space":          KeySpace,
188	"Backspace2":     KeyBackspace2,
189	"Ctrl8":          KeyCtrl8,
190	"Mouseleft":      MouseLeft,
191	"Mousemiddle":    MouseMiddle,
192	"Mouseright":     MouseRight,
193	"Mouserelease":   MouseRelease,
194	"MousewheelUp":   MouseWheelUp,
195	"MousewheelDown": MouseWheelDown,
196}
197
198// Special keys.
199const (
200	KeyF1         Key = Key(termbox.KeyF1)
201	KeyF2             = Key(termbox.KeyF2)
202	KeyF3             = Key(termbox.KeyF3)
203	KeyF4             = Key(termbox.KeyF4)
204	KeyF5             = Key(termbox.KeyF5)
205	KeyF6             = Key(termbox.KeyF6)
206	KeyF7             = Key(termbox.KeyF7)
207	KeyF8             = Key(termbox.KeyF8)
208	KeyF9             = Key(termbox.KeyF9)
209	KeyF10            = Key(termbox.KeyF10)
210	KeyF11            = Key(termbox.KeyF11)
211	KeyF12            = Key(termbox.KeyF12)
212	KeyInsert         = Key(termbox.KeyInsert)
213	KeyDelete         = Key(termbox.KeyDelete)
214	KeyHome           = Key(termbox.KeyHome)
215	KeyEnd            = Key(termbox.KeyEnd)
216	KeyPgup           = Key(termbox.KeyPgup)
217	KeyPgdn           = Key(termbox.KeyPgdn)
218	KeyArrowUp        = Key(termbox.KeyArrowUp)
219	KeyArrowDown      = Key(termbox.KeyArrowDown)
220	KeyArrowLeft      = Key(termbox.KeyArrowLeft)
221	KeyArrowRight     = Key(termbox.KeyArrowRight)
222
223	MouseLeft      = Key(termbox.MouseLeft)
224	MouseMiddle    = Key(termbox.MouseMiddle)
225	MouseRight     = Key(termbox.MouseRight)
226	MouseRelease   = Key(termbox.MouseRelease)
227	MouseWheelUp   = Key(termbox.MouseWheelUp)
228	MouseWheelDown = Key(termbox.MouseWheelDown)
229)
230
231// Keys combinations.
232const (
233	KeyCtrlTilde      Key = Key(termbox.KeyCtrlTilde)
234	KeyCtrl2              = Key(termbox.KeyCtrl2)
235	KeyCtrlSpace          = Key(termbox.KeyCtrlSpace)
236	KeyCtrlA              = Key(termbox.KeyCtrlA)
237	KeyCtrlB              = Key(termbox.KeyCtrlB)
238	KeyCtrlC              = Key(termbox.KeyCtrlC)
239	KeyCtrlD              = Key(termbox.KeyCtrlD)
240	KeyCtrlE              = Key(termbox.KeyCtrlE)
241	KeyCtrlF              = Key(termbox.KeyCtrlF)
242	KeyCtrlG              = Key(termbox.KeyCtrlG)
243	KeyBackspace          = Key(termbox.KeyBackspace)
244	KeyCtrlH              = Key(termbox.KeyCtrlH)
245	KeyTab                = Key(termbox.KeyTab)
246	KeyCtrlI              = Key(termbox.KeyCtrlI)
247	KeyCtrlJ              = Key(termbox.KeyCtrlJ)
248	KeyCtrlK              = Key(termbox.KeyCtrlK)
249	KeyCtrlL              = Key(termbox.KeyCtrlL)
250	KeyEnter              = Key(termbox.KeyEnter)
251	KeyCtrlM              = Key(termbox.KeyCtrlM)
252	KeyCtrlN              = Key(termbox.KeyCtrlN)
253	KeyCtrlO              = Key(termbox.KeyCtrlO)
254	KeyCtrlP              = Key(termbox.KeyCtrlP)
255	KeyCtrlQ              = Key(termbox.KeyCtrlQ)
256	KeyCtrlR              = Key(termbox.KeyCtrlR)
257	KeyCtrlS              = Key(termbox.KeyCtrlS)
258	KeyCtrlT              = Key(termbox.KeyCtrlT)
259	KeyCtrlU              = Key(termbox.KeyCtrlU)
260	KeyCtrlV              = Key(termbox.KeyCtrlV)
261	KeyCtrlW              = Key(termbox.KeyCtrlW)
262	KeyCtrlX              = Key(termbox.KeyCtrlX)
263	KeyCtrlY              = Key(termbox.KeyCtrlY)
264	KeyCtrlZ              = Key(termbox.KeyCtrlZ)
265	KeyEsc                = Key(termbox.KeyEsc)
266	KeyCtrlLsqBracket     = Key(termbox.KeyCtrlLsqBracket)
267	KeyCtrl3              = Key(termbox.KeyCtrl3)
268	KeyCtrl4              = Key(termbox.KeyCtrl4)
269	KeyCtrlBackslash      = Key(termbox.KeyCtrlBackslash)
270	KeyCtrl5              = Key(termbox.KeyCtrl5)
271	KeyCtrlRsqBracket     = Key(termbox.KeyCtrlRsqBracket)
272	KeyCtrl6              = Key(termbox.KeyCtrl6)
273	KeyCtrl7              = Key(termbox.KeyCtrl7)
274	KeyCtrlSlash          = Key(termbox.KeyCtrlSlash)
275	KeyCtrlUnderscore     = Key(termbox.KeyCtrlUnderscore)
276	KeySpace              = Key(termbox.KeySpace)
277	KeyBackspace2         = Key(termbox.KeyBackspace2)
278	KeyCtrl8              = Key(termbox.KeyCtrl8)
279)
280
281// Modifiers.
282const (
283	ModNone Modifier = Modifier(0)
284	ModAlt           = Modifier(termbox.ModAlt)
285)