/
main.go
130 lines (114 loc) Β· 3.89 KB
/
main.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
125
126
127
128
129
130
package main
import (
"fmt"
"log"
"os"
"strings"
"github.com/charmbracelet/lipgloss"
"github.com/charmbracelet/wish"
lm "github.com/charmbracelet/wish/logging"
"github.com/gliderlabs/ssh"
"github.com/kr/pty"
"github.com/muesli/termenv"
)
type sshOutput struct {
ssh.Session
tty *os.File
}
func (s *sshOutput) Write(p []byte) (int, error) {
return s.Session.Write(p)
}
func (s *sshOutput) Fd() uintptr {
return s.tty.Fd()
}
type sshEnviron struct {
environ []string
}
func (s *sshEnviron) Getenv(key string) string {
for _, v := range s.environ {
if strings.HasPrefix(v, key+"=") {
return v[len(key)+1:]
}
}
return ""
}
func (s *sshEnviron) Environ() []string {
return s.environ
}
func outputFromSession(s ssh.Session) *termenv.Output {
sshPty, _, _ := s.Pty()
_, tty, err := pty.Open()
if err != nil {
panic(err)
}
o := &sshOutput{
Session: s,
tty: tty,
}
environ := s.Environ()
environ = append(environ, fmt.Sprintf("TERM=%s", sshPty.Term))
e := &sshEnviron{
environ: environ,
}
return termenv.NewOutput(o, termenv.WithEnvironment(e))
}
func main() {
addr := ":3456"
s, err := wish.NewServer(
wish.WithAddress(addr),
wish.WithHostKeyPath("ssh_example"),
wish.WithMiddleware(
func(sh ssh.Handler) ssh.Handler {
return func(s ssh.Session) {
output := outputFromSession(s)
pty, _, active := s.Pty()
if !active {
sh(s)
return
}
w, _ := pty.Window.Width, pty.Window.Height
renderer := lipgloss.NewRenderer(lipgloss.WithTermenvOutput(output),
lipgloss.WithColorProfile(termenv.TrueColor))
str := strings.Builder{}
fmt.Fprintf(&str, "\n%s %s %s %s %s",
renderer.NewStyle().SetString("bold").Bold(true),
renderer.NewStyle().SetString("faint").Faint(true),
renderer.NewStyle().SetString("italic").Italic(true),
renderer.NewStyle().SetString("underline").Underline(true),
renderer.NewStyle().SetString("crossout").Strikethrough(true),
)
fmt.Fprintf(&str, "\n%s %s %s %s %s %s %s",
renderer.NewStyle().SetString("red").Foreground(lipgloss.Color("#E88388")),
renderer.NewStyle().SetString("green").Foreground(lipgloss.Color("#A8CC8C")),
renderer.NewStyle().SetString("yellow").Foreground(lipgloss.Color("#DBAB79")),
renderer.NewStyle().SetString("blue").Foreground(lipgloss.Color("#71BEF2")),
renderer.NewStyle().SetString("magenta").Foreground(lipgloss.Color("#D290E4")),
renderer.NewStyle().SetString("cyan").Foreground(lipgloss.Color("#66C2CD")),
renderer.NewStyle().SetString("gray").Foreground(lipgloss.Color("#B9BFCA")),
)
fmt.Fprintf(&str, "\n%s %s %s %s %s %s %s\n\n",
renderer.NewStyle().SetString("red").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#E88388")),
renderer.NewStyle().SetString("green").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#A8CC8C")),
renderer.NewStyle().SetString("yellow").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#DBAB79")),
renderer.NewStyle().SetString("blue").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#71BEF2")),
renderer.NewStyle().SetString("magenta").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#D290E4")),
renderer.NewStyle().SetString("cyan").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#66C2CD")),
renderer.NewStyle().SetString("gray").Foreground(lipgloss.Color("0")).Background(lipgloss.Color("#B9BFCA")),
)
fmt.Fprintf(&str, "%s %t\n", renderer.NewStyle().SetString("Has dark background?").Bold(true), renderer.HasDarkBackground())
fmt.Fprintln(&str)
wish.WriteString(s, renderer.Place(w, lipgloss.Height(str.String()), lipgloss.Center, lipgloss.Center, str.String()))
sh(s)
}
},
lm.Middleware(),
),
)
if err != nil {
log.Fatal(err)
}
log.Printf("Listening on %s", addr)
if err := s.ListenAndServe(); err != nil {
log.Fatal(err)
}
}