Path: blob/main/vendor/github.com/chzyer/readline/vim.go
2875 views
package readline12const (3VIM_NORMAL = iota4VIM_INSERT5VIM_VISUAL6)78type opVim struct {9cfg *Config10op *Operation11vimMode int12}1314func newVimMode(op *Operation) *opVim {15ov := &opVim{16cfg: op.cfg,17op: op,18}19ov.SetVimMode(ov.cfg.VimMode)20return ov21}2223func (o *opVim) SetVimMode(on bool) {24if o.cfg.VimMode && !on { // turn off25o.ExitVimMode()26}27o.cfg.VimMode = on28o.vimMode = VIM_INSERT29}3031func (o *opVim) ExitVimMode() {32o.vimMode = VIM_INSERT33}3435func (o *opVim) IsEnableVimMode() bool {36return o.cfg.VimMode37}3839func (o *opVim) handleVimNormalMovement(r rune, readNext func() rune) (t rune, handled bool) {40rb := o.op.buf41handled = true42switch r {43case 'h':44t = CharBackward45case 'j':46t = CharNext47case 'k':48t = CharPrev49case 'l':50t = CharForward51case '0', '^':52rb.MoveToLineStart()53case '$':54rb.MoveToLineEnd()55case 'x':56rb.Delete()57if rb.IsCursorInEnd() {58rb.MoveBackward()59}60case 'r':61rb.Replace(readNext())62case 'd':63next := readNext()64switch next {65case 'd':66rb.Erase()67case 'w':68rb.DeleteWord()69case 'h':70rb.Backspace()71case 'l':72rb.Delete()73}74case 'p':75rb.Yank()76case 'b', 'B':77rb.MoveToPrevWord()78case 'w', 'W':79rb.MoveToNextWord()80case 'e', 'E':81rb.MoveToEndWord()82case 'f', 'F', 't', 'T':83next := readNext()84prevChar := r == 't' || r == 'T'85reverse := r == 'F' || r == 'T'86switch next {87case CharEsc:88default:89rb.MoveTo(next, prevChar, reverse)90}91default:92return r, false93}94return t, true95}9697func (o *opVim) handleVimNormalEnterInsert(r rune, readNext func() rune) (t rune, handled bool) {98rb := o.op.buf99handled = true100switch r {101case 'i':102case 'I':103rb.MoveToLineStart()104case 'a':105rb.MoveForward()106case 'A':107rb.MoveToLineEnd()108case 's':109rb.Delete()110case 'S':111rb.Erase()112case 'c':113next := readNext()114switch next {115case 'c':116rb.Erase()117case 'w':118rb.DeleteWord()119case 'h':120rb.Backspace()121case 'l':122rb.Delete()123}124default:125return r, false126}127128o.EnterVimInsertMode()129return130}131132func (o *opVim) HandleVimNormal(r rune, readNext func() rune) (t rune) {133switch r {134case CharEnter, CharInterrupt:135o.ExitVimMode()136return r137}138139if r, handled := o.handleVimNormalMovement(r, readNext); handled {140return r141}142143if r, handled := o.handleVimNormalEnterInsert(r, readNext); handled {144return r145}146147// invalid operation148o.op.t.Bell()149return 0150}151152func (o *opVim) EnterVimInsertMode() {153o.vimMode = VIM_INSERT154}155156func (o *opVim) ExitVimInsertMode() {157o.vimMode = VIM_NORMAL158}159160func (o *opVim) HandleVim(r rune, readNext func() rune) rune {161if o.vimMode == VIM_NORMAL {162return o.HandleVimNormal(r, readNext)163}164if r == CharEsc {165o.ExitVimInsertMode()166return 0167}168169switch o.vimMode {170case VIM_INSERT:171return r172case VIM_VISUAL:173}174return r175}176177178