diff --git a/operation.go b/operation.go index 2c93561..9d050ec 100644 --- a/operation.go +++ b/operation.go @@ -226,6 +226,8 @@ func (o *Operation) ioloop() { o.Refresh() case MetaBackspace, CharCtrlW: o.buf.BackEscapeWord() + case CharCtrlY: + o.buf.Yank() case CharEnter, CharCtrlJ: if o.IsSearchMode() { o.ExitSearchMode(false) diff --git a/runebuf.go b/runebuf.go index 1b2a5d0..d101aab 100644 --- a/runebuf.go +++ b/runebuf.go @@ -29,9 +29,15 @@ type RuneBuffer struct { offset string + lastKill []rune + sync.Mutex } +func (r* RuneBuffer) pushKill(text []rune) { + r.lastKill = append([]rune{}, text...) +} + func (r *RuneBuffer) OnWidthChange(newWidth int) { r.Lock() r.width = newWidth @@ -187,6 +193,7 @@ func (r *RuneBuffer) Replace(ch rune) { func (r *RuneBuffer) Erase() { r.Refresh(func() { r.idx = 0 + r.pushKill(r.buf[:]) r.buf = r.buf[:0] }) } @@ -196,6 +203,7 @@ func (r *RuneBuffer) Delete() (success bool) { if r.idx == len(r.buf) { return } + r.pushKill(r.buf[r.idx : r.idx+1]) r.buf = append(r.buf[:r.idx], r.buf[r.idx+1:]...) success = true }) @@ -212,6 +220,7 @@ func (r *RuneBuffer) DeleteWord() { } for i := init + 1; i < len(r.buf); i++ { if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) { + r.pushKill(r.buf[r.idx:i-1]) r.Refresh(func() { r.buf = append(r.buf[:r.idx], r.buf[i-1:]...) }) @@ -247,6 +256,7 @@ func (r *RuneBuffer) KillFront() { } length := len(r.buf) - r.idx + r.pushKill(r.buf[:r.idx]) copy(r.buf[:length], r.buf[r.idx:]) r.idx = 0 r.buf = r.buf[:length] @@ -255,6 +265,7 @@ func (r *RuneBuffer) KillFront() { func (r *RuneBuffer) Kill() { r.Refresh(func() { + r.pushKill(r.buf[r.idx:]) r.buf = r.buf[:r.idx] }) } @@ -321,6 +332,7 @@ func (r *RuneBuffer) BackEscapeWord() { } for i := r.idx - 1; i > 0; i-- { if !IsWordBreak(r.buf[i]) && IsWordBreak(r.buf[i-1]) { + r.pushKill(r.buf[i:r.idx]) r.buf = append(r.buf[:i], r.buf[r.idx:]...) r.idx = i return @@ -332,6 +344,20 @@ func (r *RuneBuffer) BackEscapeWord() { }) } +func (r *RuneBuffer) Yank() { + if len(r.lastKill) == 0 { + return + } + r.Refresh(func() { + buf := make([]rune, 0, len(r.buf) + len(r.lastKill)) + buf = append(buf, r.buf[:r.idx]...) + buf = append(buf, r.lastKill...) + buf = append(buf, r.buf[r.idx:]...) + r.buf = buf + r.idx += len(r.lastKill) + }) +} + func (r *RuneBuffer) Backspace() { r.Refresh(func() { if r.idx == 0 { diff --git a/utils.go b/utils.go index 670736b..af4e005 100644 --- a/utils.go +++ b/utils.go @@ -38,6 +38,7 @@ const ( CharTranspose = 20 CharCtrlU = 21 CharCtrlW = 23 + CharCtrlY = 25 CharCtrlZ = 26 CharEsc = 27 CharEscapeEx = 91 diff --git a/vim.go b/vim.go index 641b22b..bedf2c1 100644 --- a/vim.go +++ b/vim.go @@ -72,6 +72,8 @@ func (o *opVim) handleVimNormalMovement(r rune, readNext func() rune) (t rune, h case 'l': rb.Delete() } + case 'p': + rb.Yank() case 'b', 'B': rb.MoveToPrevWord() case 'w', 'W':