@@ -4,17 +4,17 @@ import (
4
4
"fmt"
5
5
"os"
6
6
7
- "github.com/emirpasic/gods/lists/arraylist"
7
+ "github.com/emirpasic/gods/v2/ lists/arraylist"
8
8
"github.com/mattn/go-runewidth"
9
9
"golang.org/x/term"
10
10
)
11
11
12
12
type Buffer struct {
13
13
DisplayPos int
14
14
Pos int
15
- Buf * arraylist.List
15
+ Buf * arraylist.List [ rune ]
16
16
// LineHasSpace is an arraylist of bools to keep track of whether a line has a space at the end
17
- LineHasSpace * arraylist.List
17
+ LineHasSpace * arraylist.List [ bool ]
18
18
Prompt * Prompt
19
19
LineWidth int
20
20
Width int
@@ -33,8 +33,8 @@ func NewBuffer(prompt *Prompt) (*Buffer, error) {
33
33
b := & Buffer {
34
34
DisplayPos : 0 ,
35
35
Pos : 0 ,
36
- Buf : arraylist .New (),
37
- LineHasSpace : arraylist .New (),
36
+ Buf : arraylist .New [ rune ] (),
37
+ LineHasSpace : arraylist .New [ bool ] (),
38
38
Prompt : prompt ,
39
39
Width : width ,
40
40
Height : height ,
@@ -46,40 +46,33 @@ func NewBuffer(prompt *Prompt) (*Buffer, error) {
46
46
47
47
func (b * Buffer ) GetLineSpacing (line int ) bool {
48
48
hasSpace , _ := b .LineHasSpace .Get (line )
49
-
50
- if hasSpace == nil {
51
- return false
52
- }
53
-
54
- return hasSpace .(bool )
49
+ return hasSpace
55
50
}
56
51
57
52
func (b * Buffer ) MoveLeft () {
58
53
if b .Pos > 0 {
59
54
// asserts that we retrieve a rune
60
- if e , ok := b .Buf .Get (b .Pos - 1 ); ok {
61
- if r , ok := e .(rune ); ok {
62
- rLength := runewidth .RuneWidth (r )
63
-
64
- if b .DisplayPos % b .LineWidth == 0 {
65
- fmt .Print (CursorUp + CursorBOL + CursorRightN (b .Width ))
66
- if rLength == 2 {
67
- fmt .Print (CursorLeft )
68
- }
55
+ if r , ok := b .Buf .Get (b .Pos - 1 ); ok {
56
+ rLength := runewidth .RuneWidth (r )
69
57
70
- line := b .DisplayPos / b .LineWidth - 1
71
- hasSpace := b .GetLineSpacing (line )
72
- if hasSpace {
73
- b .DisplayPos -= 1
74
- fmt .Print (CursorLeft )
75
- }
76
- } else {
77
- fmt .Print (CursorLeftN (rLength ))
58
+ if b .DisplayPos % b .LineWidth == 0 {
59
+ fmt .Print (CursorUp + CursorBOL + CursorRightN (b .Width ))
60
+ if rLength == 2 {
61
+ fmt .Print (CursorLeft )
78
62
}
79
63
80
- b .Pos -= 1
81
- b .DisplayPos -= rLength
64
+ line := b .DisplayPos / b .LineWidth - 1
65
+ hasSpace := b .GetLineSpacing (line )
66
+ if hasSpace {
67
+ b .DisplayPos -= 1
68
+ fmt .Print (CursorLeft )
69
+ }
70
+ } else {
71
+ fmt .Print (CursorLeftN (rLength ))
82
72
}
73
+
74
+ b .Pos -= 1
75
+ b .DisplayPos -= rLength
83
76
}
84
77
}
85
78
}
@@ -107,24 +100,22 @@ func (b *Buffer) MoveLeftWord() {
107
100
108
101
func (b * Buffer ) MoveRight () {
109
102
if b .Pos < b .Buf .Size () {
110
- if e , ok := b .Buf .Get (b .Pos ); ok {
111
- if r , ok := e .(rune ); ok {
112
- rLength := runewidth .RuneWidth (r )
113
- b .Pos += 1
114
- hasSpace := b .GetLineSpacing (b .DisplayPos / b .LineWidth )
115
- b .DisplayPos += rLength
116
-
117
- if b .DisplayPos % b .LineWidth == 0 {
118
- fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())))
119
- } else if (b .DisplayPos - rLength )% b .LineWidth == b .LineWidth - 1 && hasSpace {
120
- fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())+ rLength ))
121
- b .DisplayPos += 1
122
- } else if b .LineHasSpace .Size () > 0 && b .DisplayPos % b .LineWidth == b .LineWidth - 1 && hasSpace {
123
- fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())))
124
- b .DisplayPos += 1
125
- } else {
126
- fmt .Print (CursorRightN (rLength ))
127
- }
103
+ if r , ok := b .Buf .Get (b .Pos ); ok {
104
+ rLength := runewidth .RuneWidth (r )
105
+ b .Pos += 1
106
+ hasSpace := b .GetLineSpacing (b .DisplayPos / b .LineWidth )
107
+ b .DisplayPos += rLength
108
+
109
+ if b .DisplayPos % b .LineWidth == 0 {
110
+ fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())))
111
+ } else if (b .DisplayPos - rLength )% b .LineWidth == b .LineWidth - 1 && hasSpace {
112
+ fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())+ rLength ))
113
+ b .DisplayPos += 1
114
+ } else if b .LineHasSpace .Size () > 0 && b .DisplayPos % b .LineWidth == b .LineWidth - 1 && hasSpace {
115
+ fmt .Print (CursorDown + CursorBOL + CursorRightN (len (b .Prompt .prompt ())))
116
+ b .DisplayPos += 1
117
+ } else {
118
+ fmt .Print (CursorRightN (rLength ))
128
119
}
129
120
}
130
121
}
@@ -182,10 +173,8 @@ func (b *Buffer) MoveToEnd() {
182
173
func (b * Buffer ) DisplaySize () int {
183
174
sum := 0
184
175
for i := range b .Buf .Size () {
185
- if e , ok := b .Buf .Get (i ); ok {
186
- if r , ok := e .(rune ); ok {
187
- sum += runewidth .RuneWidth (r )
188
- }
176
+ if r , ok := b .Buf .Get (i ); ok {
177
+ sum += runewidth .RuneWidth (r )
189
178
}
190
179
}
191
180
@@ -257,11 +246,9 @@ func (b *Buffer) countRemainingLineWidth(place int) int {
257
246
for place <= b .LineWidth {
258
247
counter += 1
259
248
sum += prevLen
260
- if e , ok := b .Buf .Get (b .Pos + counter ); ok {
261
- if r , ok := e .(rune ); ok {
262
- place += runewidth .RuneWidth (r )
263
- prevLen = len (string (r ))
264
- }
249
+ if r , ok := b .Buf .Get (b .Pos + counter ); ok {
250
+ place += runewidth .RuneWidth (r )
251
+ prevLen = len (string (r ))
265
252
} else {
266
253
break
267
254
}
@@ -346,64 +333,62 @@ func (b *Buffer) drawRemaining() {
346
333
347
334
func (b * Buffer ) Remove () {
348
335
if b .Buf .Size () > 0 && b .Pos > 0 {
349
- if e , ok := b .Buf .Get (b .Pos - 1 ); ok {
350
- if r , ok := e .(rune ); ok {
351
- rLength := runewidth .RuneWidth (r )
352
- hasSpace := b .GetLineSpacing (b .DisplayPos / b .LineWidth - 1 )
353
-
354
- if b .DisplayPos % b .LineWidth == 0 {
355
- // if the user backspaces over the word boundary, do this magic to clear the line
356
- // and move to the end of the previous line
357
- fmt .Print (CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN (b .Width ))
358
-
359
- if b .DisplaySize ()% b .LineWidth < (b .DisplaySize ()- rLength )% b .LineWidth {
360
- b .LineHasSpace .Remove (b .DisplayPos / b .LineWidth - 1 )
361
- }
336
+ if r , ok := b .Buf .Get (b .Pos - 1 ); ok {
337
+ rLength := runewidth .RuneWidth (r )
338
+ hasSpace := b .GetLineSpacing (b .DisplayPos / b .LineWidth - 1 )
362
339
363
- if hasSpace {
364
- b . DisplayPos -= 1
365
- fmt . Print ( CursorLeft )
366
- }
340
+ if b . DisplayPos % b . LineWidth == 0 {
341
+ // if the user backspaces over the word boundary, do this magic to clear the line
342
+ // and move to the end of the previous line
343
+ fmt . Print ( CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN ( b . Width ))
367
344
368
- if rLength == 2 {
369
- fmt .Print (CursorLeft + " " + CursorLeftN (2 ))
370
- } else {
371
- fmt .Print (" " + CursorLeft )
372
- }
373
- } else if (b .DisplayPos - rLength )% b .LineWidth == 0 && hasSpace {
374
- fmt .Print (CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN (b .Width ))
345
+ if b .DisplaySize ()% b .LineWidth < (b .DisplaySize ()- rLength )% b .LineWidth {
346
+ b .LineHasSpace .Remove (b .DisplayPos / b .LineWidth - 1 )
347
+ }
375
348
376
- if b .Pos == b .Buf .Size () {
377
- b .LineHasSpace .Remove (b .DisplayPos / b .LineWidth - 1 )
378
- }
349
+ if hasSpace {
379
350
b .DisplayPos -= 1
351
+ fmt .Print (CursorLeft )
352
+ }
353
+
354
+ if rLength == 2 {
355
+ fmt .Print (CursorLeft + " " + CursorLeftN (2 ))
380
356
} else {
381
- fmt .Print (CursorLeftN (rLength ))
382
- for range rLength {
383
- fmt .Print (" " )
384
- }
385
- fmt .Print (CursorLeftN (rLength ))
357
+ fmt .Print (" " + CursorLeft )
386
358
}
359
+ } else if (b .DisplayPos - rLength )% b .LineWidth == 0 && hasSpace {
360
+ fmt .Print (CursorBOL + ClearToEOL + CursorUp + CursorBOL + CursorRightN (b .Width ))
387
361
388
- var eraseExtraLine bool
389
- if (b .DisplaySize ()- 1 )% b .LineWidth == 0 || (rLength == 2 && ((b .DisplaySize ()- 2 )% b .LineWidth == 0 )) || b .DisplaySize ()% b .LineWidth == 0 {
390
- eraseExtraLine = true
362
+ if b .Pos == b .Buf .Size () {
363
+ b .LineHasSpace .Remove (b .DisplayPos / b .LineWidth - 1 )
364
+ }
365
+ b .DisplayPos -= 1
366
+ } else {
367
+ fmt .Print (CursorLeftN (rLength ))
368
+ for range rLength {
369
+ fmt .Print (" " )
391
370
}
371
+ fmt .Print (CursorLeftN (rLength ))
372
+ }
392
373
393
- b .Pos -= 1
394
- b .DisplayPos -= rLength
395
- b .Buf .Remove (b .Pos )
396
-
397
- if b .Pos < b .Buf .Size () {
398
- b .drawRemaining ()
399
- // this erases a line which is left over when backspacing in the middle of a line and there
400
- // are trailing characters which go over the line width boundary
401
- if eraseExtraLine {
402
- remainingLines := (b .DisplaySize () - b .DisplayPos ) / b .LineWidth
403
- fmt .Print (CursorDownN (remainingLines + 1 ) + CursorBOL + ClearToEOL )
404
- place := b .DisplayPos % b .LineWidth
405
- fmt .Print (CursorUpN (remainingLines + 1 ) + CursorRightN (place + len (b .Prompt .prompt ())))
406
- }
374
+ var eraseExtraLine bool
375
+ if (b .DisplaySize ()- 1 )% b .LineWidth == 0 || (rLength == 2 && ((b .DisplaySize ()- 2 )% b .LineWidth == 0 )) || b .DisplaySize ()% b .LineWidth == 0 {
376
+ eraseExtraLine = true
377
+ }
378
+
379
+ b .Pos -= 1
380
+ b .DisplayPos -= rLength
381
+ b .Buf .Remove (b .Pos )
382
+
383
+ if b .Pos < b .Buf .Size () {
384
+ b .drawRemaining ()
385
+ // this erases a line which is left over when backspacing in the middle of a line and there
386
+ // are trailing characters which go over the line width boundary
387
+ if eraseExtraLine {
388
+ remainingLines := (b .DisplaySize () - b .DisplayPos ) / b .LineWidth
389
+ fmt .Print (CursorDownN (remainingLines + 1 ) + CursorBOL + ClearToEOL )
390
+ place := b .DisplayPos % b .LineWidth
391
+ fmt .Print (CursorUpN (remainingLines + 1 ) + CursorRightN (place + len (b .Prompt .prompt ())))
407
392
}
408
393
}
409
394
}
@@ -536,7 +521,7 @@ func (b *Buffer) StringNM(n, m int) string {
536
521
}
537
522
for cnt := n ; cnt < m ; cnt ++ {
538
523
c , _ := b .Buf .Get (cnt )
539
- s += string (c .( rune ) )
524
+ s += string (c )
540
525
}
541
526
return s
542
527
}
0 commit comments