-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathrepaints.go
151 lines (137 loc) · 3.6 KB
/
repaints.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package readline
import (
"fmt"
"io"
"strings"
"github.com/nyaosorg/go-readline-ny/moji"
)
const (
CursorPositionDummyRune = '\uE000'
)
func (B *Buffer) refreshColor() ColorInterface {
var ci interface {
Init() ColorInterface
Next(rune) ColorInterface
}
if B.Coloring != nil {
ci = &colorBridge{base: B.Coloring}
} else {
str := B.String()
cursorPos := 0
for i := 0; i < B.Cursor; i++ {
cursorPos += B.Buffer[i].Moji.Len()
}
if B.memoHighlightSource == str && B.memoHighlightResult != nil {
ci = B.memoHighlightResult
} else {
result := HighlightToColorSequence(str, B.ResetColor, B.DefaultColor, B.Highlight, -1-cursorPos)
B.memoHighlightSource = str
B.memoHighlightResult = result
ci = result
}
}
var defaultColor ColorInterface = ci.Init()
position := int16(0)
var tmpbuf strings.Builder
for i, cell := range B.Buffer {
if i == B.Cursor {
ci.Next(CursorPositionDummyRune)
}
B.Buffer[i].position = position
if tab, ok := cell.Moji.(*moji.Tab); ok {
tab.SetPosition(position)
B.Buffer[i].color = ci.Next('\t')
} else if codepoint, ok := moji.MojiToRune(cell.Moji); ok {
B.Buffer[i].color = ci.Next(codepoint)
} else {
cell.Moji.PrintTo(&tmpbuf)
var cs ColorInterface
for _, c := range tmpbuf.String() {
cs = ci.Next(c)
}
B.Buffer[i].color = cs
tmpbuf.Reset()
}
position += int16(cell.Moji.Width())
}
if len(B.Buffer) == B.Cursor {
ci.Next(CursorPositionDummyRune)
}
return defaultColor
}
// InsertAndRepaint inserts str and repaint the editline.
func (B *Buffer) InsertAndRepaint(str string) {
B.ReplaceAndRepaint(B.Cursor, str)
}
// GotoHead move screen-cursor to the top of the viewarea.
// It should be called before text is changed.
func (B *Buffer) GotoHead() {
fmt.Fprintf(B.Out, "\x1B[%dG", B.topColumn+1)
}
func (B *Buffer) repaint() {
B.updateSuffix()
B.repaintWithoutUpdateSuffix()
}
func (B *Buffer) repaintWithoutUpdateSuffix() {
all, left, w := B.getView2()
B.GotoHead()
puts := B.newPrinter()
puts(all)
if B.PredictColor[0] != "" && len(B.suffix) > 0 {
io.WriteString(B.Out, B.PredictColor[0]) // "\x1B[3;22;39m"
for _, c := range B.getSuffix() {
w += c.Width()
if w >= B.ViewWidth() {
break
}
c.PrintTo(B.Out)
}
io.WriteString(B.Out, B.PredictColor[1]) // "\x1B[23m"
}
B.eraseline()
B.GotoHead()
puts(left)
}
// DrawFromHead draw all text in viewarea and
// move screen-cursor to the position where it should be.
func (B *Buffer) DrawFromHead() {
B.repaint()
}
// ReplaceAndRepaint replaces the string between `pos` and cursor's position to `str`
func (B *Buffer) ReplaceAndRepaint(pos int, str string) {
// Replace Buffer
B.Delete(pos, B.Cursor-pos)
// Define ViewStart , Cursor
B.Cursor = pos + B.InsertString(pos, str)
B.joinUndo() // merge delete and insert
B.ResetViewStart()
B.repaint()
}
// RepaintAfterPrompt repaints the all characters in the editline except for prompt.
func (B *Buffer) RepaintAfterPrompt() {
B.ResetViewStart()
B.repaint()
}
// RepaintAll repaints the all characters in the editline including prompt.
func (B *Buffer) RepaintAll() {
B.Out.Flush()
B.topColumn, _ = B.callPromptWriter()
B.repaint()
}
// RepaintLastLine repaints the last line of the prompt and input-line.
// IMPORTANT: This method requires setting valid Editor.PromptWriter
func (B *Buffer) RepaintLastLine() {
B.Out.Flush()
var prompt string
if B.PromptWriter == nil {
prompt = "\r> "
} else {
var buffer strings.Builder
buffer.WriteByte('\r')
B.PromptWriter(&buffer)
prompt = buffer.String()
prompt = strings.ReplaceAll(prompt, "\n", "\r")
}
B.Out.WriteString(prompt)
B.repaint()
}