Add OptionKeyBindMode

This commit is contained in:
c-bata 2017-08-13 13:33:51 +09:00
parent c98ec2f0d6
commit 691d64f6f1
4 changed files with 73 additions and 10 deletions

View File

@ -1,5 +1,50 @@
package prompt
/*
========
PROGRESS
========
Moving the cursor
-----------------
* [x] Ctrl + a Go to the beginning of the line (Home)
* [x] Ctrl + e Go to the End of the line (End)
* [x] Ctrl + p Previous command (Up arrow)
* [x] Ctrl + n Next command (Down arrow)
* [ ] Alt + b Back (left) one word
* [ ] Alt + f Forward (right) one word
* [x] Ctrl + f Forward one character
* [x] Ctrl + b Backward one character
* [x] Ctrl + xx Toggle between the start of line and current cursor position
Editing
-------
* [ ] Ctrl + L Clear the Screen, similar to the clear command
* [ ] Alt + Del Delete the Word before the cursor.
* [ ] Alt + d Delete the Word after the cursor.
* [x] Ctrl + d Delete character under the cursor
* [x] Ctrl + h Delete character before the cursor (Backspace)
* [x] Ctrl + w Cut the Word before the cursor to the clipboard.
* [x] Ctrl + k Cut the Line after the cursor to the clipboard.
* [x] Ctrl + u Cut/delete the Line before the cursor to the clipboard.
* [ ] Alt + t Swap current word with previous
* [ ] Ctrl + t Swap the last two characters before the cursor (typo).
* [ ] Esc + t Swap the last two words before the cursor.
* [ ] ctrl + y Paste the last thing to be cut (yank)
* [ ] Alt + u UPPER capitalize every character from the cursor to the end of the current word.
* [ ] Alt + l Lower the case of every character from the cursor to the end of the current word.
* [ ] Alt + c Capitalize the character under the cursor and move to the end of the word.
* [ ] Alt + r Cancel the changes and put back the line as it was in the history (revert).
* [ ] ctrl + _ Undo
*/
var emacsKeyBindings = []KeyBind {
// Go to the End of the line
{

View File

@ -7,6 +7,13 @@ type KeyBind struct {
Fn KeyBindFunc
}
type KeyBindMode string
const (
CommonKeyBind KeyBindMode = "common"
EmacsKeyBind KeyBindMode = "emacs"
)
var commonKeyBindings = []KeyBind {
// Go to the End of the line
{

View File

@ -145,6 +145,13 @@ func OptionHistory(x []string) option {
}
}
func SwitchKeyBindMode(m KeyBindMode) option {
return func(p *Prompt) error {
p.keyBindMode = m
return nil
}
}
func OptionAddKeyBind(b ...KeyBind) option {
return func(p *Prompt) error {
p.keyBindings = append(p.keyBindings, b...)
@ -173,10 +180,11 @@ func New(executor Executor, completer Completer, opts ...option) *Prompt {
selectedDescriptionTextColor: White,
selectedDescriptionBGColor: Cyan,
},
buf: NewBuffer(),
executor: executor,
history: NewHistory(),
completion: NewCompletionManager(completer, 6),
buf: NewBuffer(),
executor: executor,
history: NewHistory(),
completion: NewCompletionManager(completer, 6),
keyBindMode: EmacsKeyBind, // All the above assume that bash is running in the default Emacs setting
}
for _, opt := range opts {

View File

@ -25,6 +25,7 @@ type Prompt struct {
history *History
completion *CompletionManager
keyBindings []KeyBind
keyBindMode KeyBindMode
}
type Exec struct {
@ -159,6 +160,7 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
p.buf.InsertText(string(b), false, true)
}
// Key bindings
for i := range commonKeyBindings {
kb := commonKeyBindings[i]
if kb.Key == key {
@ -166,15 +168,16 @@ func (p *Prompt) feed(b []byte) (shouldExit bool, exec *Exec) {
}
}
// All the above assume that bash is running in the default Emacs setting
for i := range emacsKeyBindings {
kb := emacsKeyBindings[i]
if kb.Key == key {
p.buf = kb.Fn(p.buf)
if p.keyBindMode == EmacsKeyBind {
for i := range emacsKeyBindings {
kb := emacsKeyBindings[i]
if kb.Key == key {
p.buf = kb.Fn(p.buf)
}
}
}
// Custom keybindings
// Custom key bindings
for i := range p.keyBindings {
kb := p.keyBindings[i]
if kb.Key == key {