From b3b101a89cd4a9431d98293e63e349367e83ac65 Mon Sep 17 00:00:00 2001 From: Junegunn Choi Date: Fri, 1 Dec 2017 02:11:20 +0900 Subject: [PATCH] Support binding of left-click and right-click left-click and right-click are respectively bound to "ignore" and "toggle" (after implicitly moving the cursor) by default. Close #1130 --- man/man1/fzf.1 | 4 +++- src/options.go | 4 ++++ src/terminal.go | 6 ++++++ src/tui/light.go | 11 +++++++---- src/tui/tcell.go | 13 ++++++++----- src/tui/tui.go | 3 +++ 6 files changed, 31 insertions(+), 10 deletions(-) diff --git a/man/man1/fzf.1 b/man/man1/fzf.1 index 3cc6c7a..aea5fea 100644 --- a/man/man1/fzf.1 +++ b/man/man1/fzf.1 @@ -476,6 +476,8 @@ e.g. \fBfzf --bind=ctrl-j:accept,ctrl-k:kill-line\fR \fIpgdn\fR (\fIpage-down\fR) \fIshift-left\fR \fIshift-right\fR + \fIleft-click\fR + \fIright-click\fR \fIdouble-click\fR or any single character @@ -521,7 +523,7 @@ triggered whenever the query string is changed. \fBprevious-history\fR (\fIctrl-p\fR on \fB--history\fR) \fBprint-query\fR (print query and exit) \fBselect-all\fR - \fBtoggle\fR + \fBtoggle\fR (\fIright-click\fR) \fBtoggle-all\fR \fBtoggle+down\fR \fIctrl-i (tab)\fR \fBtoggle-in\fR (\fB--reverse\fR ? \fBtoggle+up\fR : \fBtoggle+down\fR) diff --git a/src/options.go b/src/options.go index 00b2afd..11a5021 100644 --- a/src/options.go +++ b/src/options.go @@ -430,6 +430,10 @@ func parseKeyChords(str string, message string) map[int]string { chord = tui.SLeft case "shift-right": chord = tui.SRight + case "left-click": + chord = tui.LeftClick + case "right-click": + chord = tui.RightClick case "double-click": chord = tui.DoubleClick case "f10": diff --git a/src/terminal.go b/src/terminal.go index 7dbdb6e..bc1c2ae 100644 --- a/src/terminal.go +++ b/src/terminal.go @@ -278,6 +278,8 @@ func defaultKeymap() map[int][]action { keymap[tui.Rune] = toActions(actRune) keymap[tui.Mouse] = toActions(actMouse) keymap[tui.DoubleClick] = toActions(actAccept) + keymap[tui.LeftClick] = toActions(actIgnore) + keymap[tui.RightClick] = toActions(actToggle) return keymap } @@ -1766,6 +1768,10 @@ func (t *Terminal) Loop() { toggle() } req(reqList) + if me.Left { + return doActions(t.keymap[tui.LeftClick], tui.LeftClick) + } + return doActions(t.keymap[tui.RightClick], tui.RightClick) } } } diff --git a/src/tui/light.go b/src/tui/light.go index 52e26ed..578961e 100644 --- a/src/tui/light.go +++ b/src/tui/light.go @@ -495,16 +495,19 @@ func (r *LightRenderer) mouseSequence(sz *int) Event { } *sz = 6 switch r.buffer[3] { - case 32, 36, 40, 48, // mouse-down / shift / cmd / ctrl + case 32, 34, 36, 40, 48, // mouse-down / shift / cmd / ctrl 35, 39, 43, 51: // mouse-up / shift / cmd / ctrl mod := r.buffer[3] >= 36 + left := r.buffer[3] == 32 down := r.buffer[3]%2 == 0 x := int(r.buffer[4] - 33) y := int(r.buffer[5]-33) - r.yoffset double := false if down { now := time.Now() - if now.Sub(r.prevDownTime) < doubleClickDuration { + if !left { // Right double click is not allowed + r.clickY = []int{} + } else if now.Sub(r.prevDownTime) < doubleClickDuration { r.clickY = append(r.clickY, y) } else { r.clickY = []int{y} @@ -517,14 +520,14 @@ func (r *LightRenderer) mouseSequence(sz *int) Event { } } - return Event{Mouse, 0, &MouseEvent{y, x, 0, down, double, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, 0, left, down, double, mod}} case 96, 100, 104, 112, // scroll-up / shift / cmd / ctrl 97, 101, 105, 113: // scroll-down / shift / cmd / ctrl mod := r.buffer[3] >= 100 s := 1 - int(r.buffer[3]%2)*2 x := int(r.buffer[4] - 33) y := int(r.buffer[5]-33) - r.yoffset - return Event{Mouse, 0, &MouseEvent{y, x, s, false, false, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, s, false, false, false, mod}} } return Event{Invalid, 0, nil} } diff --git a/src/tui/tcell.go b/src/tui/tcell.go index 7db37c4..8e5524a 100644 --- a/src/tui/tcell.go +++ b/src/tui/tcell.go @@ -193,19 +193,22 @@ func (r *FullscreenRenderer) GetChar() Event { button := ev.Buttons() mod := ev.Modifiers() != 0 if button&tcell.WheelDown != 0 { - return Event{Mouse, 0, &MouseEvent{y, x, -1, false, false, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, -1, false, false, false, mod}} } else if button&tcell.WheelUp != 0 { - return Event{Mouse, 0, &MouseEvent{y, x, +1, false, false, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, +1, false, false, false, mod}} } else if runtime.GOOS != "windows" { // double and single taps on Windows don't quite work due to // the console acting on the events and not allowing us // to consume them. - down := button&tcell.Button1 != 0 // left + left := button&tcell.Button1 != 0 + down := left || button&tcell.Button3 != 0 double := false if down { now := time.Now() - if now.Sub(r.prevDownTime) < doubleClickDuration { + if !left { + r.clickY = []int{} + } else if now.Sub(r.prevDownTime) < doubleClickDuration { r.clickY = append(r.clickY, x) } else { r.clickY = []int{x} @@ -218,7 +221,7 @@ func (r *FullscreenRenderer) GetChar() Event { } } - return Event{Mouse, 0, &MouseEvent{y, x, 0, down, double, mod}} + return Event{Mouse, 0, &MouseEvent{y, x, 0, left, down, double, mod}} } // process keyboard: diff --git a/src/tui/tui.go b/src/tui/tui.go index 244e0b0..fff3572 100644 --- a/src/tui/tui.go +++ b/src/tui/tui.go @@ -44,6 +44,8 @@ const ( Resize Mouse DoubleClick + LeftClick + RightClick BTab BSpace @@ -185,6 +187,7 @@ type MouseEvent struct { Y int X int S int + Left bool Down bool Double bool Mod bool