-
Notifications
You must be signed in to change notification settings - Fork 0
/
content_box.go
109 lines (88 loc) · 2.46 KB
/
content_box.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
package nve
import (
"log"
"time"
"unicode"
"unicode/utf8"
"github.com/bep/debounce"
"github.com/gdamore/tcell/v2"
"github.com/rivo/tview"
)
type ContentBox struct {
*tview.TextArea
debounce func(func())
currentFile *FileRef
}
func NewContentBox() *ContentBox {
textArea := ContentBox{
TextArea: tview.NewTextArea(),
debounce: debounce.New(300 * time.Millisecond),
}
textArea.SetBorder(true).
SetTitle("Content").
SetTitleColor(tcell.ColorDarkOrange).
SetBorderStyle(tcell.StyleDefault.Dim(true)).
SetBorderPadding(1, 0, 1, 1).
SetTitleAlign(tview.AlignLeft)
textArea.SetFocusFunc(func() {
// ignore edits if there is no current file
if textArea.currentFile == nil {
textArea.Blur()
}
})
return &textArea
}
func (b *ContentBox) Clear() {
b.currentFile = nil
b.SetText("", true)
}
func (b *ContentBox) SetFile(f *FileRef) {
b.currentFile = f
b.SetText(GetContent(f.Filename), false)
}
// InputHandler overrides default handling to switch focus away from search box when necessary.
func (b *ContentBox) InputHandler() func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
return b.WrapInputHandler(func(event *tcell.EventKey, setFocus func(p tview.Primitive)) {
event = b.mapSpecialKeys(event)
before := b.GetText()
if handler := b.TextArea.InputHandler(); handler != nil {
handler(event, setFocus)
}
if after := b.GetText(); before != after {
b.queueSave(after)
}
})
}
func (b *ContentBox) mapSpecialKeys(event *tcell.EventKey) *tcell.EventKey {
switch event.Key() {
// navigate up
case tcell.KeyCtrlP:
event = tcell.NewEventKey(tcell.KeyUp, event.Rune(), event.Modifiers())
// navigate down
case tcell.KeyCtrlN:
event = tcell.NewEventKey(tcell.KeyDown, event.Rune(), event.Modifiers())
// navigate forward
case tcell.KeyCtrlF:
event = tcell.NewEventKey(tcell.KeyRight, event.Rune(), event.Modifiers())
// delete empty line
case tcell.KeyCtrlK:
fromRow, fromCol, toRow, toCol := b.GetCursor()
if fromRow == toRow && fromCol == toCol && fromCol == 0 {
if _, start, end := b.GetSelection(); start == end {
r, _ := utf8.DecodeRuneInString(b.GetText()[start:])
if !unicode.IsLetter(r) {
event = tcell.NewEventKey(tcell.KeyDelete, event.Rune(), event.Modifiers())
}
}
}
}
return event
}
func (b *ContentBox) queueSave(content string) {
b.debounce(func() {
err := SaveContent(b.currentFile.Filename, content)
if err != nil {
log.Println("Error saving content:", err)
}
})
}