Refactor emacs keybind
This commit is contained in:
parent
ba4f3458b5
commit
b5d7d9eae3
43
emacs.go
43
emacs.go
@ -13,8 +13,6 @@ Moving the cursor
|
|||||||
* [x] Ctrl + e Go to the End of the line (End)
|
* [x] Ctrl + e Go to the End of the line (End)
|
||||||
* [x] Ctrl + p Previous command (Up arrow)
|
* [x] Ctrl + p Previous command (Up arrow)
|
||||||
* [x] Ctrl + n Next command (Down 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 + f Forward one character
|
||||||
* [x] Ctrl + b Backward one character
|
* [x] Ctrl + b Backward one character
|
||||||
* [x] Ctrl + xx Toggle between the start of line and current cursor position
|
* [x] Ctrl + xx Toggle between the start of line and current cursor position
|
||||||
@ -23,8 +21,6 @@ Editing
|
|||||||
-------
|
-------
|
||||||
|
|
||||||
* [ ] Ctrl + L Clear the Screen, similar to the clear command
|
* [ ] 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 + d Delete character under the cursor
|
||||||
* [x] Ctrl + h Delete character before the cursor (Backspace)
|
* [x] Ctrl + h Delete character before the cursor (Backspace)
|
||||||
|
|
||||||
@ -32,97 +28,82 @@ Editing
|
|||||||
* [x] Ctrl + k Cut the Line after 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.
|
* [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).
|
* [ ] Ctrl + t Swap the last two characters before the cursor (typo).
|
||||||
* [ ] Esc + t Swap the last two words before the cursor.
|
* [ ] Esc + t Swap the last two words before the cursor.
|
||||||
|
|
||||||
* [ ] ctrl + y Paste the last thing to be cut (yank)
|
* [ ] 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
|
* [ ] ctrl + _ Undo
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var emacsKeyBindings = []KeyBind {
|
var emacsKeyBindings = []KeyBind{
|
||||||
// Go to the End of the line
|
// Go to the End of the line
|
||||||
{
|
{
|
||||||
Key: ControlE,
|
Key: ControlE,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextAfterCursor())
|
x := []rune(buf.Document().TextAfterCursor())
|
||||||
buf.CursorRight(len(x))
|
buf.CursorRight(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Go to the beginning of the line
|
// Go to the beginning of the line
|
||||||
{
|
{
|
||||||
Key: ControlA,
|
Key: ControlA,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextBeforeCursor())
|
x := []rune(buf.Document().TextBeforeCursor())
|
||||||
buf.CursorLeft(len(x))
|
buf.CursorLeft(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Cut the Line after the cursor
|
// Cut the Line after the cursor
|
||||||
{
|
{
|
||||||
Key: ControlK,
|
Key: ControlK,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextAfterCursor())
|
x := []rune(buf.Document().TextAfterCursor())
|
||||||
buf.Delete(len(x))
|
buf.Delete(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Cut/delete the Line before the cursor
|
// Cut/delete the Line before the cursor
|
||||||
{
|
{
|
||||||
Key: ControlU,
|
Key: ControlU,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextBeforeCursor())
|
x := []rune(buf.Document().TextBeforeCursor())
|
||||||
buf.DeleteBeforeCursor(len(x))
|
buf.DeleteBeforeCursor(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Delete character under the cursor
|
// Delete character under the cursor
|
||||||
{
|
{
|
||||||
Key: ControlD,
|
Key: ControlD,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
if buf.Text() == "" {
|
if buf.Text() != "" {
|
||||||
return buf // This means just exit.
|
buf.Delete(1)
|
||||||
}
|
}
|
||||||
buf.Delete(1)
|
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Backspace
|
// Backspace
|
||||||
{
|
{
|
||||||
Key: ControlH,
|
Key: ControlH,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.DeleteBeforeCursor(1)
|
buf.DeleteBeforeCursor(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Right allow: Forward one character
|
// Right allow: Forward one character
|
||||||
{
|
{
|
||||||
Key: ControlF,
|
Key: ControlF,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.CursorRight(1)
|
buf.CursorRight(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Left allow: Backward one character
|
// Left allow: Backward one character
|
||||||
{
|
{
|
||||||
Key: ControlB,
|
Key: ControlB,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.CursorLeft(1)
|
buf.CursorLeft(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Cut the Word before the cursor.
|
// Cut the Word before the cursor.
|
||||||
{
|
{
|
||||||
Key: ControlW,
|
Key: ControlW,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.DeleteBeforeCursor(len([]rune(buf.Document().GetWordBeforeCursor())))
|
buf.DeleteBeforeCursor(len([]rune(buf.Document().GetWordBeforeCursor())))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
32
emacs_test.go
Normal file
32
emacs_test.go
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package prompt
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestEmacsKeyBindings(t *testing.T) {
|
||||||
|
buf := NewBuffer()
|
||||||
|
buf.InsertText("abcde", false, true)
|
||||||
|
if buf.CursorPosition != len("abcde") {
|
||||||
|
t.Errorf("Want %d, but got %d", len("abcde"), buf.CursorPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the beginning of the line
|
||||||
|
applyEmacsKeyBind(buf, ControlA)
|
||||||
|
if buf.CursorPosition != 0 {
|
||||||
|
t.Errorf("Want %d, but got %d", 0, buf.CursorPosition)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Go to the end of the line
|
||||||
|
applyEmacsKeyBind(buf, ControlE)
|
||||||
|
if buf.CursorPosition != len("abcde") {
|
||||||
|
t.Errorf("Want %d, but got %d", len("abcde"), buf.CursorPosition)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyEmacsKeyBind(buf *Buffer, key Key) {
|
||||||
|
for i := range emacsKeyBindings {
|
||||||
|
kb := emacsKeyBindings[i]
|
||||||
|
if kb.Key == key {
|
||||||
|
kb.Fn(buf)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
25
key_bind.go
25
key_bind.go
@ -1,6 +1,6 @@
|
|||||||
package prompt
|
package prompt
|
||||||
|
|
||||||
type KeyBindFunc func(*Buffer) *Buffer
|
type KeyBindFunc func(*Buffer)
|
||||||
|
|
||||||
type KeyBind struct {
|
type KeyBind struct {
|
||||||
Key Key
|
Key Key
|
||||||
@ -11,59 +11,52 @@ type KeyBindMode string
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
CommonKeyBind KeyBindMode = "common"
|
CommonKeyBind KeyBindMode = "common"
|
||||||
EmacsKeyBind KeyBindMode = "emacs"
|
EmacsKeyBind KeyBindMode = "emacs"
|
||||||
)
|
)
|
||||||
|
|
||||||
var commonKeyBindings = []KeyBind {
|
var commonKeyBindings = []KeyBind{
|
||||||
// Go to the End of the line
|
// Go to the End of the line
|
||||||
{
|
{
|
||||||
Key: End,
|
Key: End,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextAfterCursor())
|
x := []rune(buf.Document().TextAfterCursor())
|
||||||
buf.CursorRight(len(x))
|
buf.CursorRight(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Go to the beginning of the line
|
// Go to the beginning of the line
|
||||||
{
|
{
|
||||||
Key: Home,
|
Key: Home,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
x := []rune(buf.Document().TextBeforeCursor())
|
x := []rune(buf.Document().TextBeforeCursor())
|
||||||
buf.CursorLeft(len(x))
|
buf.CursorLeft(len(x))
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Delete character under the cursor
|
// Delete character under the cursor
|
||||||
{
|
{
|
||||||
Key: Delete,
|
Key: Delete,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.Delete(1)
|
buf.Delete(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Backspace
|
// Backspace
|
||||||
{
|
{
|
||||||
Key: Backspace,
|
Key: Backspace,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.DeleteBeforeCursor(1)
|
buf.DeleteBeforeCursor(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Right allow: Forward one character
|
// Right allow: Forward one character
|
||||||
{
|
{
|
||||||
Key: Right,
|
Key: Right,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.CursorRight(1)
|
buf.CursorRight(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
// Left allow: Backward one character
|
// Left allow: Backward one character
|
||||||
{
|
{
|
||||||
Key: Left,
|
Key: Left,
|
||||||
Fn: func(buf *Buffer) *Buffer {
|
Fn: func(buf *Buffer) {
|
||||||
buf.CursorLeft(1)
|
buf.CursorLeft(1)
|
||||||
return buf
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user