Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
kardolus
GitHub Repository: kardolus/chatgpt-cli
Path: blob/main/vendor/github.com/chzyer/readline/vim.go
2875 views
1
package readline
2
3
const (
4
VIM_NORMAL = iota
5
VIM_INSERT
6
VIM_VISUAL
7
)
8
9
type opVim struct {
10
cfg *Config
11
op *Operation
12
vimMode int
13
}
14
15
func newVimMode(op *Operation) *opVim {
16
ov := &opVim{
17
cfg: op.cfg,
18
op: op,
19
}
20
ov.SetVimMode(ov.cfg.VimMode)
21
return ov
22
}
23
24
func (o *opVim) SetVimMode(on bool) {
25
if o.cfg.VimMode && !on { // turn off
26
o.ExitVimMode()
27
}
28
o.cfg.VimMode = on
29
o.vimMode = VIM_INSERT
30
}
31
32
func (o *opVim) ExitVimMode() {
33
o.vimMode = VIM_INSERT
34
}
35
36
func (o *opVim) IsEnableVimMode() bool {
37
return o.cfg.VimMode
38
}
39
40
func (o *opVim) handleVimNormalMovement(r rune, readNext func() rune) (t rune, handled bool) {
41
rb := o.op.buf
42
handled = true
43
switch r {
44
case 'h':
45
t = CharBackward
46
case 'j':
47
t = CharNext
48
case 'k':
49
t = CharPrev
50
case 'l':
51
t = CharForward
52
case '0', '^':
53
rb.MoveToLineStart()
54
case '$':
55
rb.MoveToLineEnd()
56
case 'x':
57
rb.Delete()
58
if rb.IsCursorInEnd() {
59
rb.MoveBackward()
60
}
61
case 'r':
62
rb.Replace(readNext())
63
case 'd':
64
next := readNext()
65
switch next {
66
case 'd':
67
rb.Erase()
68
case 'w':
69
rb.DeleteWord()
70
case 'h':
71
rb.Backspace()
72
case 'l':
73
rb.Delete()
74
}
75
case 'p':
76
rb.Yank()
77
case 'b', 'B':
78
rb.MoveToPrevWord()
79
case 'w', 'W':
80
rb.MoveToNextWord()
81
case 'e', 'E':
82
rb.MoveToEndWord()
83
case 'f', 'F', 't', 'T':
84
next := readNext()
85
prevChar := r == 't' || r == 'T'
86
reverse := r == 'F' || r == 'T'
87
switch next {
88
case CharEsc:
89
default:
90
rb.MoveTo(next, prevChar, reverse)
91
}
92
default:
93
return r, false
94
}
95
return t, true
96
}
97
98
func (o *opVim) handleVimNormalEnterInsert(r rune, readNext func() rune) (t rune, handled bool) {
99
rb := o.op.buf
100
handled = true
101
switch r {
102
case 'i':
103
case 'I':
104
rb.MoveToLineStart()
105
case 'a':
106
rb.MoveForward()
107
case 'A':
108
rb.MoveToLineEnd()
109
case 's':
110
rb.Delete()
111
case 'S':
112
rb.Erase()
113
case 'c':
114
next := readNext()
115
switch next {
116
case 'c':
117
rb.Erase()
118
case 'w':
119
rb.DeleteWord()
120
case 'h':
121
rb.Backspace()
122
case 'l':
123
rb.Delete()
124
}
125
default:
126
return r, false
127
}
128
129
o.EnterVimInsertMode()
130
return
131
}
132
133
func (o *opVim) HandleVimNormal(r rune, readNext func() rune) (t rune) {
134
switch r {
135
case CharEnter, CharInterrupt:
136
o.ExitVimMode()
137
return r
138
}
139
140
if r, handled := o.handleVimNormalMovement(r, readNext); handled {
141
return r
142
}
143
144
if r, handled := o.handleVimNormalEnterInsert(r, readNext); handled {
145
return r
146
}
147
148
// invalid operation
149
o.op.t.Bell()
150
return 0
151
}
152
153
func (o *opVim) EnterVimInsertMode() {
154
o.vimMode = VIM_INSERT
155
}
156
157
func (o *opVim) ExitVimInsertMode() {
158
o.vimMode = VIM_NORMAL
159
}
160
161
func (o *opVim) HandleVim(r rune, readNext func() rune) rune {
162
if o.vimMode == VIM_NORMAL {
163
return o.HandleVimNormal(r, readNext)
164
}
165
if r == CharEsc {
166
o.ExitVimInsertMode()
167
return 0
168
}
169
170
switch o.vimMode {
171
case VIM_INSERT:
172
return r
173
case VIM_VISUAL:
174
}
175
return r
176
}
177
178