Skip to content

Commit

Permalink
Improve command bar keybindings
Browse files Browse the repository at this point in the history
The command bar now supports better keybindings:

CtrlA, CtrlLeft: start of line
CtrlE, CtrlRight: end of line
CtrlF, AltRight: next word
CtrlB, AltLeft: previous word
CtrlW, AltBackspace: delete previous word
CtrlV: Paste
Arrow keys as usual

These keybindings are not rebindable (maybe support will be added
in the future).
  • Loading branch information
zyedidia committed Nov 24, 2017
1 parent af6ef4f commit 5fc8f84
Showing 1 changed file with 128 additions and 51 deletions.
179 changes: 128 additions & 51 deletions cmd/micro/messenger.go
Expand Up @@ -348,62 +348,139 @@ func (m *Messenger) Prompt(prompt, placeholder, historyType string, completionTy
return response, canceled
}

func (m *Messenger) UpHistory(history []string) {
if m.historyNum > 0 {
m.historyNum--
m.response = history[m.historyNum]
m.cursorx = Count(m.response)
}
}
func (m *Messenger) DownHistory(history []string) {
if m.historyNum < len(history)-1 {
m.historyNum++
m.response = history[m.historyNum]
m.cursorx = Count(m.response)
}
}
func (m *Messenger) CursorLeft() {
if m.cursorx > 0 {
m.cursorx--
}
}
func (m *Messenger) CursorRight() {
if m.cursorx < Count(m.response) {
m.cursorx++
}
}
func (m *Messenger) Start() {
m.cursorx = 0
}
func (m *Messenger) End() {
m.cursorx = Count(m.response)
}
func (m *Messenger) Backspace() {
if m.cursorx > 0 {
m.response = string([]rune(m.response)[:m.cursorx-1]) + string([]rune(m.response)[m.cursorx:])
m.cursorx--
}
}
func (m *Messenger) Paste() {
clip, _ := clipboard.ReadAll("clipboard")
m.response = Insert(m.response, m.cursorx, clip)
m.cursorx += Count(clip)
}
func (m *Messenger) WordLeft() {
response := []rune(m.response)
m.CursorLeft()
if m.cursorx <= 0 {
return
}
for IsWhitespace(response[m.cursorx]) {
if m.cursorx <= 0 {
return
}
m.CursorLeft()
}
m.CursorLeft()
for IsWordChar(string(response[m.cursorx])) {
if m.cursorx <= 0 {
return
}
m.CursorLeft()
}
m.CursorRight()
}
func (m *Messenger) WordRight() {
response := []rune(m.response)
if m.cursorx >= len(response) {
return
}
for IsWhitespace(response[m.cursorx]) {
m.CursorRight()
if m.cursorx >= len(response) {
m.CursorRight()
return
}
}
m.CursorRight()
if m.cursorx >= len(response) {
return
}
for IsWordChar(string(response[m.cursorx])) {
m.CursorRight()
if m.cursorx >= len(response) {
return
}
}
}
func (m *Messenger) DeleteWordLeft() {
m.WordLeft()
m.response = string([]rune(m.response)[:m.cursorx])
}

// HandleEvent handles an event for the prompter
func (m *Messenger) HandleEvent(event tcell.Event, history []string) {
switch e := event.(type) {
case *tcell.EventKey:
if e.Key() != tcell.KeyRune || e.Modifiers() != 0 {
for key, actions := range bindings {
if e.Key() == key.keyCode {
if e.Key() == tcell.KeyRune {
if e.Rune() != key.r {
continue
}
}
if e.Modifiers() == key.modifiers {
for _, action := range actions {
funcName := FuncName(action)
switch funcName {
case "main.(*View).CursorUp":
if m.historyNum > 0 {
m.historyNum--
m.response = history[m.historyNum]
m.cursorx = Count(m.response)
}
case "main.(*View).CursorDown":
if m.historyNum < len(history)-1 {
m.historyNum++
m.response = history[m.historyNum]
m.cursorx = Count(m.response)
}
case "main.(*View).CursorLeft":
if m.cursorx > 0 {
m.cursorx--
}
case "main.(*View).CursorRight":
if m.cursorx < Count(m.response) {
m.cursorx++
}
case "main.(*View).CursorStart", "main.(*View).StartOfLine":
m.cursorx = 0
case "main.(*View).CursorEnd", "main.(*View).EndOfLine":
m.cursorx = Count(m.response)
case "main.(*View).Backspace":
if m.cursorx > 0 {
m.response = string([]rune(m.response)[:m.cursorx-1]) + string([]rune(m.response)[m.cursorx:])
m.cursorx--
}
case "main.(*View).Paste":
clip, _ := clipboard.ReadAll("clipboard")
m.response = Insert(m.response, m.cursorx, clip)
m.cursorx += Count(clip)
}
}
}
}
}
}
switch e.Key() {
case tcell.KeyCtrlA:
m.Start()
case tcell.KeyCtrlE:
m.End()
case tcell.KeyUp:
m.UpHistory(history)
case tcell.KeyDown:
m.DownHistory(history)
case tcell.KeyLeft:
if e.Modifiers() == tcell.ModCtrl {
m.Start()
} else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
m.WordLeft()
} else {
m.CursorLeft()
}
case tcell.KeyRight:
if e.Modifiers() == tcell.ModCtrl {
m.End()
} else if e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
m.WordRight()
} else {
m.CursorRight()
}
case tcell.KeyBackspace2, tcell.KeyBackspace:
if e.Modifiers() == tcell.ModCtrl || e.Modifiers() == tcell.ModAlt || e.Modifiers() == tcell.ModMeta {
m.DeleteWordLeft()
} else {
m.Backspace()
}
case tcell.KeyCtrlW:
m.DeleteWordLeft()
case tcell.KeyCtrlV:
m.Paste()
case tcell.KeyCtrlF:
m.WordRight()
case tcell.KeyCtrlB:
m.WordLeft()
case tcell.KeyRune:
m.response = Insert(m.response, m.cursorx, string(e.Rune()))
m.cursorx++
Expand Down

0 comments on commit 5fc8f84

Please sign in to comment.