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`+`S` | Search forwards in history |
| `Ctrl`+`T` | Transpose characters | | `Ctrl`+`T` | Transpose characters |
| `Meta`+`T` | Transpose words (TODO) | | `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 | | `Ctrl`+`W` | Cut previous word |
| `Backspace` | Delete previous character | | `Backspace` | Delete previous character |
| `Meta`+`Backspace` | Cut previous word | | `Meta`+`Backspace` | Cut previous word |

View File

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

View File

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

View File

@ -60,20 +60,19 @@ func (r *RuneBuffer) Len() int {
} }
func (r *RuneBuffer) MoveToLineStart() { func (r *RuneBuffer) MoveToLineStart() {
if r.idx == 0 {
return
}
r.Refresh(func() { r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx = 0 r.idx = 0
}) })
} }
func (r *RuneBuffer) MoveBackward() { func (r *RuneBuffer) MoveBackward() {
if r.idx == 0 {
return
}
r.Refresh(func() { r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx-- r.idx--
}) })
} }
@ -132,26 +131,32 @@ func (r *RuneBuffer) DeleteWord() {
} }
func (r *RuneBuffer) MoveToPrevWord() { func (r *RuneBuffer) MoveToPrevWord() {
if r.idx == 0 { r.Refresh(func() {
return if r.idx == 0 {
}
for i := r.idx - 1; i > 0; i-- {
if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) {
r.Refresh(func() {
r.idx = i
})
return 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 r.idx = 0
}) })
} }
func (r *RuneBuffer) SetIdx(idx int) (change int) { func (r *RuneBuffer) KillFront() {
i := r.idx r.Refresh(func() {
r.idx = idx if r.idx == 0 {
return r.idx - i 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() { func (r *RuneBuffer) Kill() {
@ -161,15 +166,15 @@ func (r *RuneBuffer) Kill() {
} }
func (r *RuneBuffer) Transpose() { func (r *RuneBuffer) Transpose() {
if len(r.buf) < 2 {
if len(r.buf) == 1 {
r.Refresh(func() {
r.idx++
})
}
return
}
r.Refresh(func() { r.Refresh(func() {
if len(r.buf) == 1 {
r.idx++
}
if len(r.buf) < 2 {
return
}
if r.idx == 0 { if r.idx == 0 {
r.idx = 1 r.idx = 1
} else if r.idx >= len(r.buf) { } else if r.idx >= len(r.buf) {
@ -181,55 +186,53 @@ func (r *RuneBuffer) Transpose() {
} }
func (r *RuneBuffer) MoveToNextWord() { 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() { 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) r.idx = len(r.buf)
}) })
} }
func (r *RuneBuffer) BackEscapeWord() { func (r *RuneBuffer) BackEscapeWord() {
if r.idx == 0 { r.Refresh(func() {
return if r.idx == 0 {
}
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
})
return 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.buf = r.buf[:0]
r.idx = 0 r.idx = 0
}) })
} }
func (r *RuneBuffer) Backspace() { func (r *RuneBuffer) Backspace() {
if r.idx == 0 {
return
}
r.Refresh(func() { r.Refresh(func() {
if r.idx == 0 {
return
}
r.idx-- r.idx--
r.buf = append(r.buf[:r.idx], r.buf[r.idx+1:]...) r.buf = append(r.buf[:r.idx], r.buf[r.idx+1:]...)
}) })
} }
func (r *RuneBuffer) MoveToLineEnd() { func (r *RuneBuffer) MoveToLineEnd() {
if r.idx == len(r.buf) {
return
}
r.Refresh(func() { r.Refresh(func() {
if r.idx == len(r.buf) {
return
}
r.idx = len(r.buf) r.idx = len(r.buf)
}) })
} }
@ -242,9 +245,15 @@ func (r *RuneBuffer) IdxLine() int {
totalWidth := RunesWidth(r.buf[:r.idx]) + r.PromptLen() totalWidth := RunesWidth(r.buf[:r.idx]) + r.PromptLen()
w := getWidth() w := getWidth()
line := totalWidth / w 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-- line--
} }
return line return line
} }