Add support for ctrl-alt-[a-z] key chords

Close #906
This commit is contained in:
Junegunn Choi 2017-04-28 02:36:36 +09:00
parent d5e72bf55d
commit 6b592137b9
No known key found for this signature in database
GPG Key ID: 254BC280FEF9C627
7 changed files with 52 additions and 39 deletions

View File

@ -21,7 +21,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE. THE SOFTWARE.
.. ..
.TH fzf 1 "Mar 2017" "fzf 0.16.6" "fzf - a command-line fuzzy finder" .TH fzf 1 "Apr 2017" "fzf 0.16.7" "fzf - a command-line fuzzy finder"
.SH NAME .SH NAME
fzf - a command-line fuzzy finder fzf - a command-line fuzzy finder
@ -439,6 +439,7 @@ e.g. \fBfzf --bind=ctrl-j:accept,ctrl-k:kill-line\fR
.B AVAILABLE KEYS: (SYNONYMS) .B AVAILABLE KEYS: (SYNONYMS)
\fIctrl-[a-z]\fR \fIctrl-[a-z]\fR
\fIctrl-space\fR \fIctrl-space\fR
\fIctrl-alt-[a-z]\fR
\fIalt-[a-z]\fR \fIalt-[a-z]\fR
\fIalt-[0-9]\fR \fIalt-[0-9]\fR
\fIf[1-12]\fR \fIf[1-12]\fR

View File

@ -401,7 +401,7 @@ func parseKeyChords(str string, message string) map[int]string {
case "ctrl-space": case "ctrl-space":
chord = tui.CtrlSpace chord = tui.CtrlSpace
case "alt-enter", "alt-return": case "alt-enter", "alt-return":
chord = tui.AltEnter chord = tui.CtrlAltM
case "alt-space": case "alt-space":
chord = tui.AltSpace chord = tui.AltSpace
case "alt-/": case "alt-/":
@ -437,7 +437,9 @@ func parseKeyChords(str string, message string) map[int]string {
case "f12": case "f12":
chord = tui.F12 chord = tui.F12
default: default:
if len(key) == 6 && strings.HasPrefix(lkey, "ctrl-") && isAlphabet(lkey[5]) { if len(key) == 10 && strings.HasPrefix(lkey, "ctrl-alt-") && isAlphabet(lkey[9]) {
chord = tui.CtrlAltA + int(lkey[9]) - 'a'
} else if len(key) == 6 && strings.HasPrefix(lkey, "ctrl-") && isAlphabet(lkey[5]) {
chord = tui.CtrlA + int(lkey[5]) - 'a' chord = tui.CtrlA + int(lkey[5]) - 'a'
} else if len(key) == 5 && strings.HasPrefix(lkey, "alt-") && isAlphabet(lkey[4]) { } else if len(key) == 5 && strings.HasPrefix(lkey, "alt-") && isAlphabet(lkey[4]) {
chord = tui.AltA + int(lkey[4]) - 'a' chord = tui.AltA + int(lkey[4]) - 'a'

View File

@ -125,14 +125,14 @@ func TestIrrelevantNth(t *testing.T) {
} }
func TestParseKeys(t *testing.T) { func TestParseKeys(t *testing.T) {
pairs := parseKeyChords("ctrl-z,alt-z,f2,@,Alt-a,!,ctrl-G,J,g,ALT-enter,alt-SPACE", "") pairs := parseKeyChords("ctrl-z,alt-z,f2,@,Alt-a,!,ctrl-G,J,g,ctrl-alt-a,ALT-enter,alt-SPACE", "")
check := func(i int, s string) { check := func(i int, s string) {
if pairs[i] != s { if pairs[i] != s {
t.Errorf("%s != %s", pairs[i], s) t.Errorf("%s != %s", pairs[i], s)
} }
} }
if len(pairs) != 11 { if len(pairs) != 12 {
t.Error(11) t.Error(12)
} }
check(tui.CtrlZ, "ctrl-z") check(tui.CtrlZ, "ctrl-z")
check(tui.AltZ, "alt-z") check(tui.AltZ, "alt-z")
@ -143,7 +143,8 @@ func TestParseKeys(t *testing.T) {
check(tui.CtrlA+'g'-'a', "ctrl-G") check(tui.CtrlA+'g'-'a', "ctrl-G")
check(tui.AltZ+'J', "J") check(tui.AltZ+'J', "J")
check(tui.AltZ+'g', "g") check(tui.AltZ+'g', "g")
check(tui.AltEnter, "ALT-enter") check(tui.CtrlAltA, "ctrl-alt-a")
check(tui.CtrlAltM, "ALT-enter")
check(tui.AltSpace, "alt-SPACE") check(tui.AltSpace, "alt-SPACE")
// Synonyms // Synonyms

View File

@ -344,9 +344,10 @@ func (r *LightRenderer) escSequence(sz *int) Event {
return Event{ESC, 0, nil} return Event{ESC, 0, nil}
} }
*sz = 2 *sz = 2
if r.buffer[1] >= 1 && r.buffer[1] <= 'z'-'a'+1 {
return Event{int(CtrlAltA + r.buffer[1] - 1), 0, nil}
}
switch r.buffer[1] { switch r.buffer[1] {
case 13:
return Event{AltEnter, 0, nil}
case 32: case 32:
return Event{AltSpace, 0, nil} return Event{AltSpace, 0, nil}
case 47: case 47:

View File

@ -353,7 +353,7 @@ func escSequence() Event {
case C.ERR: case C.ERR:
return Event{ESC, 0, nil} return Event{ESC, 0, nil}
case CtrlM: case CtrlM:
return Event{AltEnter, 0, nil} return Event{CtrlAltM, 0, nil}
case '/': case '/':
return Event{AltSlash, 0, nil} return Event{AltSlash, 0, nil}
case ' ': case ' ':

View File

@ -221,58 +221,65 @@ func (r *FullscreenRenderer) GetChar() Event {
// process keyboard: // process keyboard:
case *tcell.EventKey: case *tcell.EventKey:
alt := (ev.Modifiers() & tcell.ModAlt) > 0 alt := (ev.Modifiers() & tcell.ModAlt) > 0
keyfn := func(r rune) int {
if alt {
return CtrlAltA - 'a' + int(r)
}
return CtrlA - 'a' + int(r)
}
switch ev.Key() { switch ev.Key() {
case tcell.KeyCtrlA: case tcell.KeyCtrlA:
return Event{CtrlA, 0, nil} return Event{keyfn('a'), 0, nil}
case tcell.KeyCtrlB: case tcell.KeyCtrlB:
return Event{CtrlB, 0, nil} return Event{keyfn('b'), 0, nil}
case tcell.KeyCtrlC: case tcell.KeyCtrlC:
return Event{CtrlC, 0, nil} return Event{keyfn('c'), 0, nil}
case tcell.KeyCtrlD: case tcell.KeyCtrlD:
return Event{CtrlD, 0, nil} return Event{keyfn('d'), 0, nil}
case tcell.KeyCtrlE: case tcell.KeyCtrlE:
return Event{CtrlE, 0, nil} return Event{keyfn('e'), 0, nil}
case tcell.KeyCtrlF: case tcell.KeyCtrlF:
return Event{CtrlF, 0, nil} return Event{keyfn('f'), 0, nil}
case tcell.KeyCtrlG: case tcell.KeyCtrlG:
return Event{CtrlG, 0, nil} return Event{keyfn('g'), 0, nil}
case tcell.KeyCtrlH:
return Event{keyfn('h'), 0, nil}
case tcell.KeyCtrlI:
return Event{keyfn('i'), 0, nil}
case tcell.KeyCtrlJ: case tcell.KeyCtrlJ:
return Event{CtrlJ, 0, nil} return Event{keyfn('j'), 0, nil}
case tcell.KeyCtrlK: case tcell.KeyCtrlK:
return Event{CtrlK, 0, nil} return Event{keyfn('k'), 0, nil}
case tcell.KeyCtrlL: case tcell.KeyCtrlL:
return Event{CtrlL, 0, nil} return Event{keyfn('l'), 0, nil}
case tcell.KeyCtrlM: case tcell.KeyCtrlM:
if alt { return Event{keyfn('m'), 0, nil}
return Event{AltEnter, 0, nil}
}
return Event{CtrlM, 0, nil}
case tcell.KeyCtrlN: case tcell.KeyCtrlN:
return Event{CtrlN, 0, nil} return Event{keyfn('n'), 0, nil}
case tcell.KeyCtrlO: case tcell.KeyCtrlO:
return Event{CtrlO, 0, nil} return Event{keyfn('o'), 0, nil}
case tcell.KeyCtrlP: case tcell.KeyCtrlP:
return Event{CtrlP, 0, nil} return Event{keyfn('p'), 0, nil}
case tcell.KeyCtrlQ: case tcell.KeyCtrlQ:
return Event{CtrlQ, 0, nil} return Event{keyfn('q'), 0, nil}
case tcell.KeyCtrlR: case tcell.KeyCtrlR:
return Event{CtrlR, 0, nil} return Event{keyfn('r'), 0, nil}
case tcell.KeyCtrlS: case tcell.KeyCtrlS:
return Event{CtrlS, 0, nil} return Event{keyfn('s'), 0, nil}
case tcell.KeyCtrlT: case tcell.KeyCtrlT:
return Event{CtrlT, 0, nil} return Event{keyfn('t'), 0, nil}
case tcell.KeyCtrlU: case tcell.KeyCtrlU:
return Event{CtrlU, 0, nil} return Event{keyfn('u'), 0, nil}
case tcell.KeyCtrlV: case tcell.KeyCtrlV:
return Event{CtrlV, 0, nil} return Event{keyfn('v'), 0, nil}
case tcell.KeyCtrlW: case tcell.KeyCtrlW:
return Event{CtrlW, 0, nil} return Event{keyfn('w'), 0, nil}
case tcell.KeyCtrlX: case tcell.KeyCtrlX:
return Event{CtrlX, 0, nil} return Event{keyfn('x'), 0, nil}
case tcell.KeyCtrlY: case tcell.KeyCtrlY:
return Event{CtrlY, 0, nil} return Event{keyfn('y'), 0, nil}
case tcell.KeyCtrlZ: case tcell.KeyCtrlZ:
return Event{CtrlZ, 0, nil} return Event{keyfn('z'), 0, nil}
case tcell.KeyCtrlSpace: case tcell.KeyCtrlSpace:
return Event{CtrlSpace, 0, nil} return Event{CtrlSpace, 0, nil}
case tcell.KeyBackspace, tcell.KeyBackspace2: case tcell.KeyBackspace, tcell.KeyBackspace2:

View File

@ -75,7 +75,6 @@ const (
F11 F11
F12 F12
AltEnter
AltSpace AltSpace
AltSlash AltSlash
AltBS AltBS
@ -91,6 +90,8 @@ const ( // Reset iota
AltE AltE
AltF AltF
AltZ = AltA + 'z' - 'a' AltZ = AltA + 'z' - 'a'
CtrlAltA = AltZ + 1
CtrlAltM = CtrlAltA + 'm' - 'a'
) )
const ( const (