-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheditor.go
124 lines (98 loc) · 2.25 KB
/
editor.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
// pago - a command-line password manager.
//
// License: MIT.
// See the file LICENSE.
package main
import (
"fmt"
"strings"
"github.com/charmbracelet/bubbles/textarea"
tea "github.com/charmbracelet/bubbletea"
style "github.com/charmbracelet/lipgloss"
"golang.org/x/term"
)
type editor struct {
err error
save bool
textarea textarea.Model
}
type cancelError struct{}
const (
bannerNoSave = "[ Ctrl+V: Paste ] [ Esc: Cancel ]"
bannerSave = "[ Ctrl+D: Save ] [ Ctrl+V: Paste ] [ Esc: Cancel ]"
defaultHeight = 15
defaultWidth = 80
editorCharLimit = 1 << 16
)
var CancelError = &cancelError{}
func (e *cancelError) Error() string {
return "editor canceled"
}
func (e editor) Init() tea.Cmd {
return nil
}
func (e editor) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.Type {
case tea.KeyEsc, tea.KeyCtrlC:
e.err = CancelError
return e, tea.Quit
case tea.KeyCtrlD:
if !e.save {
return e, nil
}
return e, tea.Quit
}
}
e.textarea, cmd = e.textarea.Update(msg)
return e, cmd
}
func (e editor) View() string {
banner := bannerNoSave
if e.save {
banner = bannerSave
}
return fmt.Sprintf("%s\n\n%s\n", banner, e.textarea.View())
}
// Edit presents an editor with the given initial content and returns the edited text.
func Edit(initial string, save bool) (string, error) {
if len(initial) > editorCharLimit {
return "", fmt.Errorf("initial text too long")
}
ta := textarea.New()
ta.CharLimit = editorCharLimit
ta.ShowLineNumbers = false
ta.SetValue(initial)
ta.Focus()
// Remove cursor line highlighting.
ta.FocusedStyle.CursorLine = style.Style{}
// Remove base styling.
ta.FocusedStyle.Base = style.Style{}
// Match blurred and focused styles.
ta.BlurredStyle = ta.FocusedStyle
width, height, err := term.GetSize(0)
if err == nil {
height /= 2
} else {
width = defaultWidth
height = defaultHeight
}
ta.SetWidth(width)
ta.SetHeight(height)
e := editor{
save: save,
textarea: ta,
}
p := tea.NewProgram(e)
m, err := p.Run()
if err != nil {
return "", fmt.Errorf("editor failed: %v", err)
}
ed := m.(editor)
if ed.err != nil {
return "", ed.err
}
return strings.TrimSpace(ed.textarea.Value()), nil
}