/
terminal_state.go
96 lines (83 loc) · 2.67 KB
/
terminal_state.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
package buffer
type TerminalState struct {
scrollLinesFromBottom uint
cursorX uint16
cursorY uint16
cursorAttr CellAttributes
defaultCell Cell
viewHeight uint16
viewWidth uint16
topMargin uint // see DECSTBM docs - this is for scrollable regions
bottomMargin uint // see DECSTBM docs - this is for scrollable regions
ReplaceMode bool // overwrite character at cursor or insert new
OriginMode bool // see DECOM docs - whether cursor is positioned within the margins or not
LineFeedMode bool
AutoWrap bool
maxLines uint64
tabStops map[uint16]struct{}
}
// NewTerminalMode creates a new terminal state
func NewTerminalState(viewCols uint16, viewLines uint16, attr CellAttributes, maxLines uint64) *TerminalState {
b := &TerminalState{
cursorX: 0,
cursorY: 0,
cursorAttr: attr,
AutoWrap: true,
defaultCell: Cell{attr: attr},
maxLines: maxLines,
viewWidth: viewCols,
viewHeight: viewLines,
topMargin: 0,
bottomMargin: uint(viewLines - 1),
}
b.TabReset()
return b
}
func (terminalState *TerminalState) SetVerticalMargins(top uint, bottom uint) {
terminalState.topMargin = top
terminalState.bottomMargin = bottom
}
// ResetVerticalMargins resets margins to extreme positions
func (terminalState *TerminalState) ResetVerticalMargins() {
terminalState.SetVerticalMargins(0, uint(terminalState.viewHeight-1))
}
func (terminalState *TerminalState) IsNewLineMode() bool {
return terminalState.LineFeedMode == false
}
func (terminalState *TerminalState) TabZonk() {
terminalState.tabStops = make(map[uint16]struct{})
}
func (terminalState *TerminalState) TabSet(index uint16) {
terminalState.tabStops[index] = struct{}{}
}
func (terminalState *TerminalState) TabClear(index uint16) {
delete(terminalState.tabStops, index)
}
func (terminalState *TerminalState) getTabIndexFromCursor() uint16 {
index := terminalState.cursorX
if index == terminalState.viewWidth {
index = 0
}
return index
}
func (terminalState *TerminalState) IsTabSetAtCursor() bool {
index := terminalState.getTabIndexFromCursor()
_, ok := terminalState.tabStops[index]
return ok
}
func (terminalState *TerminalState) TabClearAtCursor() {
terminalState.TabClear(terminalState.getTabIndexFromCursor())
}
func (terminalState *TerminalState) TabSetAtCursor() {
terminalState.TabSet(terminalState.getTabIndexFromCursor())
}
func (terminalState *TerminalState) TabReset() {
terminalState.TabZonk()
const MaxTabs uint16 = 1024
const TabStep = 4
var i uint16
for i < MaxTabs {
terminalState.TabSet(i)
i += TabStep
}
}