summaryrefslogtreecommitdiffstats
path: root/vendor
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2022-02-05 14:42:56 +1100
committerJesse Duffield <jessedduffield@gmail.com>2022-03-17 19:13:40 +1100
commit482bdc4f1ea5448c5e98697ae66221e544ea40dd (patch)
tree7df478f9870e3dddc85f77d7b77439bed16e3c7b /vendor
parent8e3484d8e98faf12f8395eaf5f9e8381f77a8e52 (diff)
more refactoring
Diffstat (limited to 'vendor')
-rw-r--r--vendor/github.com/jesseduffield/gocui/gui.go133
-rw-r--r--vendor/github.com/jesseduffield/gocui/keybinding.go24
-rw-r--r--vendor/github.com/jesseduffield/gocui/view.go2
3 files changed, 120 insertions, 39 deletions
diff --git a/vendor/github.com/jesseduffield/gocui/gui.go b/vendor/github.com/jesseduffield/gocui/gui.go
index 1c3b4a9cb..b374c82c0 100644
--- a/vendor/github.com/jesseduffield/gocui/gui.go
+++ b/vendor/github.com/jesseduffield/gocui/gui.go
@@ -69,6 +69,30 @@ type tabClickBinding struct {
handler tabClickHandler
}
+type ViewMouseBinding struct {
+ // the view that is clicked
+ ViewName string
+
+ // the context we are in when the click occurs. Not necessarily the context
+ // of the view we're clicking. If this is blank then it is a global binding.
+ FromContext string
+
+ Handler func(ViewMouseBindingOpts) error
+
+ // must be a mouse key
+ Key Key
+}
+
+type ViewMouseBindingOpts struct {
+ // cursor x/y
+ Cx int
+ Cy int
+
+ // origin x/y
+ Ox int
+ Oy int
+}
+
type GuiMutexes struct {
// tickingMutex ensures we don't have two loops ticking. The point of 'ticking'
// is to refresh the gui rapidly so that loader characters can be animated.
@@ -110,17 +134,18 @@ type Gui struct {
PlayMode PlayMode
StartTime time.Time
- tabClickBindings []*tabClickBinding
- gEvents chan GocuiEvent
- userEvents chan userEvent
- views []*View
- currentView *View
- managers []Manager
- keybindings []*keybinding
- maxX, maxY int
- outputMode OutputMode
- stop chan struct{}
- blacklist []Key
+ tabClickBindings []*tabClickBinding
+ viewMouseBindings []*ViewMouseBinding
+ gEvents chan GocuiEvent
+ userEvents chan userEvent
+ views []*View
+ currentView *View
+ managers []Manager
+ keybindings []*keybinding
+ maxX, maxY int
+ outputMode OutputMode
+ stop chan struct{}
+ blacklist []Key
// BgColor and FgColor allow to configure the background and foreground
// colors of the GUI.
@@ -162,6 +187,8 @@ type Gui struct {
screen tcell.Screen
suspendedMutex sync.Mutex
suspended bool
+
+ currentContext string
}
// NewGui returns a new Gui object with a given output mode.
@@ -237,6 +264,10 @@ func (g *Gui) Size() (x, y int) {
return g.maxX, g.maxY
}
+func (g *Gui) SetCurrentContext(context string) {
+ g.currentContext = context
+}
+
// SetRune writes a rune at the given point, relative to the top-left
// corner of the terminal. It checks if the position is valid and applies
// the given colors.
@@ -472,6 +503,7 @@ func (g *Gui) DeleteKeybinding(viewname string, key interface{}, mod Modifier) e
func (g *Gui) DeleteAllKeybindings() {
g.keybindings = []*keybinding{}
g.tabClickBindings = []*tabClickBinding{}
+ g.viewMouseBindings = []*ViewMouseBinding{}
}
// DeleteKeybindings deletes all keybindings of view.
@@ -495,6 +527,12 @@ func (g *Gui) SetTabClickBinding(viewName string, handler tabClickHandler) error
return nil
}
+func (g *Gui) SetViewClickBinding(binding *ViewMouseBinding) error {
+ g.viewMouseBindings = append(g.viewMouseBindings, binding)
+
+ return nil
+}
+
// BlackListKeybinding adds a keybinding to the blacklist
func (g *Gui) BlacklistKeybinding(k Key) error {
for _, j := range g.blacklist {
@@ -1098,6 +1136,17 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
return err
}
+ if ev.Mod == ModNone && IsMouseKey(ev.Key) {
+ opts := ViewMouseBindingOpts{Cx: newCx, Cy: newCy, Ox: v.ox, Oy: v.oy}
+ matched, err := g.execMouseKeybindings(v.Name(), ev, opts)
+ if err != nil {
+ return err
+ }
+ if matched {
+ return nil
+ }
+ }
+
if _, err := g.execKeybindings(v, ev); err != nil {
return err
}
@@ -1106,6 +1155,40 @@ func (g *Gui) onKey(ev *GocuiEvent) error {
return nil
}
+func (g *Gui) execMouseKeybindings(viewName string, ev *GocuiEvent, opts ViewMouseBindingOpts) (bool, error) {
+ // first pass looks for ones that match both the view and the current context
+ for _, binding := range g.viewMouseBindings {
+ if binding.ViewName == viewName && binding.FromContext == g.currentContext && ev.Key == binding.Key {
+ return true, binding.Handler(opts)
+ }
+ }
+
+ for _, binding := range g.viewMouseBindings {
+ if binding.ViewName == viewName && ev.Key == binding.Key {
+ return true, binding.Handler(opts)
+ }
+ }
+
+ return false, nil
+}
+
+func IsMouseKey(key interface{}) bool {
+ switch key {
+ case
+ MouseLeft,
+ MouseRight,
+ MouseMiddle,
+ MouseRelease,
+ MouseWheelUp,
+ MouseWheelDown,
+ MouseWheelLeft,
+ MouseWheelRight:
+ return true
+ default:
+ return false
+ }
+}
+
// execKeybindings executes the keybinding handlers that match the passed view
// and event. The value of matched is true if there is a match and no errors.
func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) (matched bool, err error) {
@@ -1136,10 +1219,10 @@ func (g *Gui) execKeybindings(v *View, ev *GocuiEvent) (matched bool, err error)
if !kb.matchKeypress(Key(ev.Key), ev.Ch, Modifier(ev.Mod)) {
continue
}
- if kb.matchView(v) {
+ if g.matchView(v, kb) {
return g.execKeybinding(v, kb)
}
- if v != nil && kb.matchView(v.ParentView) {
+ if v != nil && g.matchView(v.ParentView, kb) {
matchingParentViewKb = kb
}
if globalKb == nil && kb.viewName == "" && ((v != nil && !v.Editable) || (kb.ch == 0 && kb.key != KeyCtrlU && kb.key != KeyCtrlA && kb.key != KeyCtrlE)) {
@@ -1340,3 +1423,27 @@ func (g *Gui) Resume() error {
return g.screen.Resume()
}
+
+// matchView returns if the keybinding matches the current view (and the view's context)
+func (g *Gui) matchView(v *View, kb *keybinding) bool {
+ // if the user is typing in a field, ignore char keys
+ if v == nil {
+ return false
+ }
+ if v.Editable == true && kb.ch != 0 {
+ return false
+ }
+ if kb.viewName != v.name {
+ return false
+ }
+ // if the keybinding doesn't specify contexts, it applies for all contexts
+ if len(kb.contexts) == 0 {
+ return true
+ }
+ for _, context := range kb.contexts {
+ if context == g.currentContext {
+ return true
+ }
+ }
+ return false
+}
diff --git a/vendor/github.com/jesseduffield/gocui/keybinding.go b/vendor/github.com/jesseduffield/gocui/keybinding.go
index 95857656e..7a675d55b 100644
--- a/vendor/github.com/jesseduffield/gocui/keybinding.go
+++ b/vendor/github.com/jesseduffield/gocui/keybinding.go
@@ -124,30 +124,6 @@ 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 (and the view's context)
-func (kb *keybinding) matchView(v *View) bool {
- // if the user is typing in a field, ignore char keys
- if v == nil {
- return false
- }
- if v.Editable == true && kb.ch != 0 {
- return false
- }
- if kb.viewName != v.name {
- return false
- }
- // if the keybinding doesn't specify contexts, it applies for all contexts
- if len(kb.contexts) == 0 {
- return true
- }
- for _, context := range kb.contexts {
- if context == v.Context {
- return true
- }
- }
- return false
-}
-
// translations for strings to keys
var translate = map[string]Key{
"F1": KeyF1,
diff --git a/vendor/github.com/jesseduffield/gocui/view.go b/vendor/github.com/jesseduffield/gocui/view.go
index 1316ced2e..9783d7637 100644
--- a/vendor/github.com/jesseduffield/gocui/view.go
+++ b/vendor/github.com/jesseduffield/gocui/view.go
@@ -149,8 +149,6 @@ type View struct {
// ParentView is the view which catches events bubbled up from the given view if there's no matching handler
ParentView *View
- Context string // this is for assigning keybindings to a view only in certain contexts
-
searcher *searcher
// KeybindOnEdit should be set to true when you want to execute keybindings even when the view is editable