-
Notifications
You must be signed in to change notification settings - Fork 1
/
manualctl.go
115 lines (99 loc) · 2.61 KB
/
manualctl.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
package csvi
import (
"context"
"fmt"
"io"
"os"
"path/filepath"
"sync"
"github.com/mattn/go-runewidth"
"github.com/mattn/go-tty"
"github.com/nyaosorg/go-readline-ny"
"github.com/nyaosorg/go-readline-ny/completion"
"github.com/nyaosorg/go-readline-ny/keys"
"github.com/nyaosorg/go-readline-skk"
"github.com/hymkor/go-cursorposition"
)
type _ManualCtl struct {
*tty.TTY
}
func newManualCtl() (_ManualCtl, error) {
var rc _ManualCtl
var err error
rc.TTY, err = tty.Open()
return rc, err
}
func (m _ManualCtl) Calibrate() error {
// Measure how far the cursor moves while the `▽` is printed
w, err := cursorposition.AmbiguousWidthGoTty(m.TTY, os.Stderr)
if err != nil {
return err
}
runewidth.DefaultCondition.EastAsianWidth = w >= 2
return nil
}
func (m _ManualCtl) Close() error {
return m.TTY.Close()
}
func (m _ManualCtl) Size() (int, int, error) {
return m.TTY.Size()
}
func (m _ManualCtl) GetKey() (string, error) {
return readline.GetKey(m.TTY)
}
var skkInit = sync.OnceFunc(func() {
env := os.Getenv("GOREADLINESKK")
if env != "" {
_, err := skk.Config{
MiniBuffer: skk.MiniBufferOnCurrentLine{},
}.SetupWithString(env)
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
}
}
})
func (m _ManualCtl) ReadLine(out io.Writer, prompt, defaultStr string, c Candidate) (string, error) {
skkInit()
editor := &readline.Editor{
Writer: out,
Default: defaultStr,
History: c,
Cursor: 65535,
PromptWriter: func(w io.Writer) (int, error) {
return fmt.Fprintf(w, "\r\x1B[0;33;40;1m%s%s", prompt, _ANSI_ERASE_LINE)
},
LineFeedWriter: func(readline.Result, io.Writer) (int, error) {
return 0, nil
},
Coloring: &skk.Coloring{},
}
if len(c) > 0 {
editor.BindKey(keys.CtrlI, completion.CmdCompletion{
Completion: c,
})
}
defer io.WriteString(out, _ANSI_CURSOR_OFF)
editor.BindKey(keys.Escape, readline.CmdInterrupt)
return editor.ReadLine(context.Background())
}
func (m _ManualCtl) GetFilename(out io.Writer, prompt, defaultStr string) (string, error) {
skkInit()
editor := &readline.Editor{
Writer: out,
Default: defaultStr,
Cursor: len(defaultStr) - len(filepath.Ext(defaultStr)),
PromptWriter: func(w io.Writer) (int, error) {
return fmt.Fprintf(w, "\r\x1B[0;33;40;1m%s%s", prompt, _ANSI_ERASE_LINE)
},
LineFeedWriter: func(readline.Result, io.Writer) (int, error) {
return 0, nil
},
Coloring: &skk.Coloring{},
}
editor.BindKey(keys.CtrlI, completion.CmdCompletionOrList{
Completion: completion.File{},
})
defer io.WriteString(out, _ANSI_CURSOR_OFF)
editor.BindKey(keys.Escape, readline.CmdInterrupt)
return editor.ReadLine(context.Background())
}