-
Notifications
You must be signed in to change notification settings - Fork 411
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
A widget to translate specific keys into key sequences
This package provides a widget that can map one keypress to a sequence of keypresses. If the user pnovides as input a key that is mapped, the sequence of resulting keypresses is played to the subwidget before control returns. If the key is not mapped, it is passed through as normal. I'm going to use this to provide a vim-like macro feature in termshark.
- Loading branch information
Showing
1 changed file
with
75 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2019-2020 Graham Clark. All rights reserved. Use of this source | ||
// code is governed by the MIT license that can be found in the LICENSE | ||
// file. | ||
|
||
// Package mapkeys provides a widget that can map one keypress to a sequence of | ||
// keypresses. If the user pnovides as input a key that is mapped, the sequence of | ||
// resulting keypresses is played to the subwidget before control returns. If the key is | ||
// not mapped, it is passed through as normal. I'm going to use this to provide a vim-like | ||
// macro feature in termshark. | ||
package mapkeys | ||
|
||
import ( | ||
"github.com/gcla/gowid" | ||
"github.com/gcla/gowid/vim" | ||
"github.com/gdamore/tcell" | ||
) | ||
|
||
//====================================================================== | ||
|
||
type Widget struct { | ||
gowid.IWidget | ||
kmap map[vim.KeyPress]vim.KeySequence | ||
} | ||
|
||
var _ gowid.IWidget = (*Widget)(nil) | ||
|
||
func New(w gowid.IWidget) *Widget { | ||
res := &Widget{ | ||
IWidget: w, | ||
kmap: make(map[vim.KeyPress]vim.KeySequence), | ||
} | ||
return res | ||
} | ||
|
||
func (w *Widget) UserInput(ev interface{}, size gowid.IRenderSize, focus gowid.Selector, app gowid.IApp) bool { | ||
switch ev := ev.(type) { | ||
case *tcell.EventKey: | ||
kp := vim.KeyPressFromTcell(ev) | ||
if seq, ok := w.kmap[kp]; ok { | ||
var res bool | ||
for _, k := range seq { | ||
// What should the handled value be?? | ||
res = w.IWidget.UserInput(tcell.NewEventKey(k.Key, k.Ch, k.Mod), size, focus, app) | ||
} | ||
return res | ||
} else { | ||
return w.IWidget.UserInput(ev, size, focus, app) | ||
} | ||
default: | ||
return w.IWidget.UserInput(ev, size, focus, app) | ||
} | ||
} | ||
|
||
func (w *Widget) AddMapping(from vim.KeyPress, to vim.KeySequence, app gowid.IApp) { | ||
w.kmap[from] = to | ||
} | ||
|
||
func (w *Widget) RemoveMapping(from vim.KeyPress, app gowid.IApp) { | ||
delete(w.kmap, from) | ||
} | ||
|
||
// ClearMappings will remove all mappings. I deliberately preserve the same dictionary, | ||
// though in case I decide in the future it's useful to let clients have direct access to | ||
// the map (and so maybe store it somewhere). | ||
func (w *Widget) ClearMappings(app gowid.IApp) { | ||
for k := range w.kmap { | ||
delete(w.kmap, k) | ||
} | ||
} | ||
|
||
//====================================================================== | ||
// Local Variables: | ||
// mode: Go | ||
// fill-column: 90 | ||
// End: |