add Ctrl+U

This commit is contained in:
Cheney 2015-09-28 11:13:39 +08:00
parent c814ccae9a
commit 03d201ab65
4 changed files with 70 additions and 57 deletions

View File

@ -162,7 +162,7 @@ Users can change that in terminal simulator(i.e. iTerm2) to `Alt`+`B`
| `Ctrl`+`S` | Search forwards in history |
| `Ctrl`+`T` | Transpose characters |
| `Meta`+`T` | Transpose words (TODO) |
| `Ctrl`+`U` | Cut text to the beginning of line (TODO) |
| `Ctrl`+`U` | Cut text to the beginning of line |
| `Ctrl`+`W` | Cut previous word |
| `Backspace` | Delete previous character |
| `Meta`+`Backspace` | Cut previous word |

View File

@ -18,6 +18,7 @@ const (
CharBckSearch = 18
CharFwdSearch = 19
CharTranspose = 20
CharCtrlU = 21
CharCtrlW = 23
CharEsc = 27
CharEscapeEx = 91

View File

@ -97,6 +97,8 @@ func (o *Operation) ioloop() {
case CharBckSearch:
o.SearchMode(S_DIR_BCK)
keepInSearchMode = true
case CharCtrlU:
o.buf.KillFront()
case CharFwdSearch:
o.SearchMode(S_DIR_FWD)
keepInSearchMode = true
@ -185,6 +187,7 @@ func (o *Operation) ioloop() {
keepInCompleteMode = true
}
}
if !keepInSearchMode && o.IsSearchMode() {
o.ExitSearchMode(false)
o.buf.Refresh(nil)

View File

@ -60,20 +60,19 @@ func (r *RuneBuffer) Len() int {
}
func (r *RuneBuffer) MoveToLineStart() {
if r.idx == 0 {
return
}
r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx = 0
})
}
func (r *RuneBuffer) MoveBackward() {
if r.idx == 0 {
return
}
r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx--
})
}
@ -132,26 +131,32 @@ func (r *RuneBuffer) DeleteWord() {
}
func (r *RuneBuffer) MoveToPrevWord() {
if r.idx == 0 {
return
}
for i := r.idx - 1; i > 0; i-- {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.Refresh(func() {
r.idx = i
})
r.Refresh(func() {
if r.idx == 0 {
return
}
}
r.Refresh(func() {
for i := r.idx - 1; i > 0; i-- {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.idx = i
return
}
}
r.idx = 0
})
}
func (r *RuneBuffer) SetIdx(idx int) (change int) {
i := r.idx
r.idx = idx
return r.idx - i
func (r *RuneBuffer) KillFront() {
r.Refresh(func() {
if r.idx == 0 {
return
}
length := len(r.buf) - r.idx
copy(r.buf[:length], r.buf[r.idx:])
r.idx = 0
r.buf = r.buf[:length]
})
}
func (r *RuneBuffer) Kill() {
@ -161,15 +166,15 @@ func (r *RuneBuffer) Kill() {
}
func (r *RuneBuffer) Transpose() {
if len(r.buf) < 2 {
if len(r.buf) == 1 {
r.Refresh(func() {
r.idx++
})
}
return
}
r.Refresh(func() {
if len(r.buf) == 1 {
r.idx++
}
if len(r.buf) < 2 {
return
}
if r.idx == 0 {
r.idx = 1
} else if r.idx >= len(r.buf) {
@ -181,55 +186,53 @@ func (r *RuneBuffer) Transpose() {
}
func (r *RuneBuffer) MoveToNextWord() {
for i := r.idx + 1; i < len(r.buf); i++ {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.Refresh(func() {
r.idx = i
})
return
}
}
r.Refresh(func() {
for i := r.idx + 1; i < len(r.buf); i++ {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.idx = i
return
}
}
r.idx = len(r.buf)
})
}
func (r *RuneBuffer) BackEscapeWord() {
if r.idx == 0 {
return
}
for i := r.idx - 1; i > 0; i-- {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.Refresh(func() {
r.buf = append(r.buf[:i], r.buf[r.idx:]...)
r.idx = i
})
r.Refresh(func() {
if r.idx == 0 {
return
}
}
for i := r.idx - 1; i > 0; i-- {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.buf = append(r.buf[:i], r.buf[r.idx:]...)
r.idx = i
return
}
}
r.Refresh(func() {
r.buf = r.buf[:0]
r.idx = 0
})
}
func (r *RuneBuffer) Backspace() {
if r.idx == 0 {
return
}
r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx--
r.buf = append(r.buf[:r.idx], r.buf[r.idx+1:]...)
})
}
func (r *RuneBuffer) MoveToLineEnd() {
if r.idx == len(r.buf) {
return
}
r.Refresh(func() {
if r.idx == len(r.buf) {
return
}
r.idx = len(r.buf)
})
}
@ -242,9 +245,15 @@ func (r *RuneBuffer) IdxLine() int {
totalWidth := RunesWidth(r.buf[:r.idx]) + r.PromptLen()
w := getWidth()
line := totalWidth / w
if totalWidth%w == 0 {
// if cursor is in last colmun and not any character behind it
// the cursor will in the first line, otherwise will in the second line
// this situation only occurs in golang's Stdout
// TODO: figure out why
if totalWidth%w == 0 && len(r.buf) == r.idx {
line--
}
return line
}