-
Notifications
You must be signed in to change notification settings - Fork 1
/
screen.go
159 lines (146 loc) · 4.08 KB
/
screen.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
152
153
154
155
156
157
158
159
package ziti
import (
"fmt"
"time"
termbox "github.com/nsf/termbox-go"
)
/* ============================= Terminal update ============================ */
/* This function writes the whole screen using termbox-go */
func (e *editor) editorRefreshScreen(drawCursor bool) {
termbox.Clear(termbox.ColorBlack, termbox.ColorDefault)
// lastSelCol := -1
// Draw the runes on the screen
for y := 0; y < e.screenrows; y++ {
filerow := e.cb.point.ro + y
if filerow >= e.cb.numrows {
e.drawline(y, e.fgcolor, e.bgcolor, "~")
} else {
r := e.cb.rows[filerow]
len := r.rsize - e.cb.point.co
if len > 0 {
if len > e.screencols {
len = e.screencols
}
for j := 0; j < len; j++ {
runeToPrint := r.render[j]
if r.render[j] == Tab {
runeToPrint = ' '
}
if e.inSelectedRegion(j, filerow) {
termbox.SetCell(j, y, runeToPrint, e.fgcolor|termbox.AttrUnderline, e.bgcolor)
// lastSelCol = j
} else {
termbox.SetCell(j, y, runeToPrint, e.fgcolor, e.bgcolor)
}
}
}
}
}
/* Create a two rows for status. First row: */
dirtyflag := ""
if e.cb.dirty {
dirtyflag = "(modified)"
}
status := fmt.Sprintf("-- %s - %d lines - %d/%d - %s",
e.cb.filename, e.cb.numrows, e.cb.point.ro+e.cb.point.r+1, e.cb.point.co+e.cb.point.c+1, dirtyflag) //e.cb.dirty ? "(modified)" : "")
slen := len(status)
if slen > e.screencols {
slen = e.screencols
}
for slen < e.screencols { // blank the rest of the line
status = status + " "
slen++
}
e.drawline(e.screenrows, e.fgcolor|termbox.AttrReverse, e.bgcolor|termbox.AttrReverse, status) //termbox.ColorWhite, termbox.ColorBlack, status)
/* Second row: depends on e.statusmsg and the status message update time. */
if len(e.statusmsg) > 0 && time.Since(e.statusmsgTime).Seconds() < 3 {
e.drawline(e.screenrows+1, e.fgcolor, e.bgcolor, e.statusmsg)
} else {
e.drawline(e.screenrows+1, e.fgcolor, e.bgcolor, " ")
}
/* Put cursor at its currentLine position. Note that the horizontal position
* at which the cursor is displayed may be different compared to 'e.cb.point.c'
* because of Tabs. */
cx := e.adjustCursor()
filerow := e.cb.point.ro + e.cb.point.r
for j := e.cb.point.co + e.cb.point.c; j < cx; j++ {
if e.cb.markSet == true {
termbox.SetCell(j, e.cb.point.r, e.cb.rows[filerow].render[j], e.fgcolor|termbox.AttrUnderline, e.bgcolor)
}
}
if drawCursor {
termbox.SetCursor(cx, e.cb.point.r)
}
termbox.Flush()
}
func (e *editor) inSelectedRegion(c, r int) bool {
if e.cb.markSet == false {
return false
}
sr, sc, er, ec, _ := swapCursorsMaybe(e.cb.mark.r+e.cb.mark.ro, e.cb.mark.c+e.cb.mark.co, e.cb.point.ro+e.cb.point.r, e.cb.point.co+e.cb.point.c)
if r < sr || r > er {
return false
}
if r == sr && r == er && c >= ec {
return false
}
if r == sr && c >= sc {
return true
}
if r == sr && c < sc {
return false
}
if r > sr && r < er {
return true
}
if r == er && c < ec {
return true
}
return false
}
func (e *editor) adjustCursor() int {
cx := 0
filerow := e.cb.point.ro + e.cb.point.r
var row *erow // := nil
if filerow < e.cb.numrows {
row = e.cb.rows[filerow]
}
if row != nil {
for j := e.cb.point.co; j < (e.cb.point.c + e.cb.point.co); j++ {
if j < row.size && row.runes[j] == Tab {
cx = cx + 3 //7 - ((cx) % 8)
}
cx = cx + 1
}
}
return cx
}
func (e *editor) drawline(y int, fg, bg termbox.Attribute, msg string) {
x := 0
for _, c := range msg {
termbox.SetCell(x, y, c, fg, bg)
x++
}
for k := x; k < (e.screencols - 1); k++ {
termbox.SetCell(k, y, ' ', fg, bg)
}
}
/* Set an editor status message for the second line of the status, at the
* end of the screen. */
func (e *editor) editorSetStatusMessage(fm string, args ...interface{}) {
e.statusmsg = fmt.Sprintf(fm, args...)
e.statusmsgTime = time.Now()
return
}
func (e *editor) moveToBufferStart() {
e.cb.point.c = 0
e.cb.point.co = 0
e.cb.point.r = 0
e.cb.point.ro = 0
}
func (e *editor) moveToBufferEnd() {
e.cb.point.c = e.cb.rows[e.cb.numrows-1].size
e.cb.point.co = 0
e.cb.point.r = e.screenrows - 1
e.cb.point.ro = (e.cb.numrows - 1) - (e.screenrows - 1)
}