Skip to content

Commit

Permalink
A widget to translate specific keys into key sequences
Browse files Browse the repository at this point in the history
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
gcla committed Jul 27, 2020
1 parent 9d8bba6 commit 66c7cdc
Showing 1 changed file with 75 additions and 0 deletions.
75 changes: 75 additions & 0 deletions widgets/mapkeys/mapkeys.go
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:

0 comments on commit 66c7cdc

Please sign in to comment.