diff --git a/go.mod b/go.mod index 76276e27025cac6c280f9c7f1fb64153dda1272e..cdb1e1659d728c33e3f85d0cea217234400d8a89 100755 --- a/go.mod +++ b/go.mod @@ -22,6 +22,7 @@ require ( ) require ( + github.com/aymanbagabas/go-osc52 v1.0.0 github.com/charmbracelet/keygen v0.3.0 github.com/gobwas/glob v0.2.3 github.com/gogs/git-module v1.6.0 diff --git a/go.sum b/go.sum index 698185837e619e01b8771b068a06d1c7514bef08..805fc0b23db5c6a947ce3a6a6098b6801a27c3fe 100644 --- a/go.sum +++ b/go.sum @@ -17,6 +17,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52 v1.0.0 h1:yjRSILSEUSIhuRcyOJ55tbSKtvBLmJDgbPErH8pXcxM= +github.com/aymanbagabas/go-osc52 v1.0.0/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= diff --git a/server/session.go b/server/session.go index fc5bfb797e354d1bbdc74df99e850721d1264ec2..bbec7217512b15039e57e1341b05e0f1adeed8c0 100644 --- a/server/session.go +++ b/server/session.go @@ -16,8 +16,8 @@ import ( type Session struct { tea.Model *tea.Program - ssh.Session - Cfg *appCfg.Config + session ssh.Session + Cfg *appCfg.Config } func (s *Session) Config() *appCfg.Config { @@ -29,8 +29,13 @@ func (s *Session) Send(msg tea.Msg) { } func (s *Session) PublicKey() ssh.PublicKey { - return s.Session.PublicKey() + return s.session.PublicKey() } + +func (s *Session) Session() ssh.Session { + return s.session +} + func SessionHandler(ac *appCfg.Config) bm.ProgramHandler { return func(s ssh.Session) *tea.Program { pty, _, active := s.Pty() @@ -39,7 +44,7 @@ func SessionHandler(ac *appCfg.Config) bm.ProgramHandler { return nil } sess := &Session{ - Session: s, + session: s, Cfg: ac, } cmd := s.Command() diff --git a/ui/components/yankable/yankable.go b/ui/components/yankable/yankable.go index 862ebb0342d82f33154a80bd742cce594c8a48d6..acdf915d7a064aae44d008d8c71e2f0734c7958a 100644 --- a/ui/components/yankable/yankable.go +++ b/ui/components/yankable/yankable.go @@ -1,8 +1,14 @@ package yankable import ( + "fmt" + "log" + "strings" + + "github.com/aymanbagabas/go-osc52" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/gliderlabs/ssh" ) type Yankable struct { @@ -10,14 +16,29 @@ type Yankable struct { style lipgloss.Style text string clicked bool + osc52 *osc52.Output } -func New(style, yankStyle lipgloss.Style, text string) *Yankable { +func New(s ssh.Session, style, yankStyle lipgloss.Style, text string) *Yankable { + environ := s.Environ() + termExists := false + for _, env := range environ { + if strings.HasPrefix(env, "TERM=") { + termExists = true + break + } + } + if !termExists { + pty, _, _ := s.Pty() + environ = append(environ, fmt.Sprintf("TERM=%s", pty.Term)) + } + log.Print(environ) return &Yankable{ yankStyle: yankStyle, style: style, text: text, clicked: false, + osc52: osc52.NewOutput(s, environ), } } @@ -30,18 +51,17 @@ func (y *Yankable) Init() tea.Cmd { } func (y *Yankable) Update(msg tea.Msg) (tea.Model, tea.Cmd) { - cmds := make([]tea.Cmd, 0) switch msg := msg.(type) { case tea.MouseMsg: switch msg.Type { case tea.MouseRight: y.clicked = true - return y, nil + return y, y.copy() } default: y.clicked = false } - return y, tea.Batch(cmds...) + return y, nil } func (y *Yankable) View() string { @@ -50,3 +70,8 @@ func (y *Yankable) View() string { } return y.style.Render(y.text) } + +func (y *Yankable) copy() tea.Cmd { + y.osc52.Copy(y.text) + return nil +} diff --git a/ui/pages/selection/item.go b/ui/pages/selection/item.go index 6bf66247394437199542d1c0d1f5cab850316076..63eb095aa762c0b9cece2c0845052389320d3833 100644 --- a/ui/pages/selection/item.go +++ b/ui/pages/selection/item.go @@ -55,9 +55,9 @@ func (d ItemDelegate) Spacing() int { return 1 } // Update implements list.ItemDelegate. func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { cmds := make([]tea.Cmd, 0) - if d.activeBox == nil || *d.activeBox != selectorBox { - return nil - } + // if d.activeBox == nil || *d.activeBox != selectorBox { + // return nil + // } for i, item := range m.VisibleItems() { itm, ok := item.(Item) if !ok { @@ -66,14 +66,14 @@ func (d ItemDelegate) Update(msg tea.Msg, m *list.Model) tea.Cmd { // FIXME check if X & Y are within the item box switch msg := msg.(type) { case tea.MouseMsg: - x := msg.X + // x := msg.X y := msg.Y - minX := (i * d.Width()) - maxX := minX + d.Width() + // minX := (i * d.Width()) + // maxX := minX + d.Width() minY := (i * d.Height()) maxY := minY + d.Height() // log.Printf("i: %d, x: %d, y: %d", i, x, y) - if y < minY || y > maxY || x < minX || x > maxX { + if y < minY || y > maxY { continue } } diff --git a/ui/pages/selection/selection.go b/ui/pages/selection/selection.go index c1ce0195bc83fa7445c3b327e9a539c0429ceb93..8c1b3864379ebe236dfdd36ef4f047b63374f715 100644 --- a/ui/pages/selection/selection.go +++ b/ui/pages/selection/selection.go @@ -106,9 +106,10 @@ func (s *Selection) FullHelp() [][]key.Binding { func (s *Selection) Init() tea.Cmd { items := make([]list.Item, 0) cfg := s.s.Config() - // TODO fix yankable component + // TODO clean up this yank := func(text string) *yankable.Yankable { return yankable.New( + s.s.Session(), lipgloss.NewStyle().Foreground(lipgloss.Color("168")), lipgloss.NewStyle().Foreground(lipgloss.Color("168")).SetString("Copied!"), text, diff --git a/ui/session/session.go b/ui/session/session.go index 43ef7ec86698ac47857d83f99c61b2dee1da3af6..cb9bc29436f8b26b7db982ab33b11441729886fe 100644 --- a/ui/session/session.go +++ b/ui/session/session.go @@ -14,4 +14,5 @@ type Session interface { Config() *appCfg.Config // PublicKey returns the public key of the user. PublicKey() ssh.PublicKey + Session() ssh.Session }