This repository has been archived by the owner on Nov 26, 2023. It is now read-only.
forked from simeji/jid
-
Notifications
You must be signed in to change notification settings - Fork 32
/
terminal.go
112 lines (92 loc) · 2.28 KB
/
terminal.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
package jiq
import (
"strings"
"github.com/nsf/termbox-go"
)
type Terminal struct {
defaultY int
prompt string
}
type TerminalDrawAttributes struct {
Query string
CursorOffsetX int
Contents []string
CandidateIndex int
ContentsOffsetY int
Complete string
Candidates []string
}
func NewTerminal(prompt string, defaultY int) *Terminal {
return &Terminal{
prompt: prompt,
defaultY: defaultY,
}
}
func (t *Terminal) draw(attr *TerminalDrawAttributes) {
query := attr.Query
complete := attr.Complete
rows := attr.Contents
candidates := attr.Candidates
candidateidx := attr.CandidateIndex
contentOffsetY := attr.ContentsOffsetY
termbox.Clear(termbox.ColorDefault, termbox.ColorDefault)
fs := t.prompt + query
cs := complete
y := t.defaultY
t.drawln(0, 0, fs+cs, []([]int){[]int{len(fs), len(fs) + len(cs)}})
if len(candidates) > 0 {
y = t.drawCandidates(0, t.defaultY, candidateidx, candidates)
}
for idx, row := range rows {
if i := idx - contentOffsetY; i >= 0 {
t.drawln(0, i+y, row, nil)
}
}
termbox.SetCursor(len(t.prompt)+attr.CursorOffsetX, 0)
termbox.Flush()
}
func (t *Terminal) drawln(x int, y int, str string, matches [][]int) {
color := termbox.ColorDefault
backgroundColor := termbox.ColorDefault
var c termbox.Attribute
for i, s := range str {
c = color
for _, match := range matches {
if i >= match[0]+1 && i < match[1] {
c = termbox.ColorGreen
}
}
termbox.SetCell(x+i, y, s, c, backgroundColor)
}
}
func (t *Terminal) drawCandidates(x int, y int, index int, candidates []string) int {
color := termbox.ColorBlack
backgroundColor := termbox.ColorWhite
w, _ := termbox.Size()
ss := candidates[index]
nss := len(ss)
var rows []string
var str string
for _, word := range candidates {
combine := " "
if l := len(str); l+len(word)+1 >= w {
rows = append(rows, str+" ")
str = ""
}
str += combine + word
}
rows = append(rows, str+" ")
for i, row := range rows {
match := strings.Index(row, ss)
var c termbox.Attribute
for ii, s := range row {
c = color
backgroundColor = termbox.ColorMagenta
if match != -1 && ii >= match && ii < match+nss {
backgroundColor = termbox.ColorWhite
}
termbox.SetCell(x+ii, y+i, s, c, backgroundColor)
}
}
return y + len(rows)
}