mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-12 23:27:17 +03:00
sshchat: Echo command messages with the new timestamp code.
This commit is contained in:
parent
8282fad7dc
commit
9c3db55c83
@ -170,6 +170,8 @@ func (u *User) render(m Message) string {
|
||||
if cfg.Bell {
|
||||
out += Bel
|
||||
}
|
||||
case *CommandMsg:
|
||||
out += m.RenderSelf(cfg)
|
||||
default:
|
||||
out += m.Render(cfg.Theme)
|
||||
}
|
||||
|
23
host.go
23
host.go
@ -162,6 +162,20 @@ func (h *Host) Connect(term *sshd.Terminal) {
|
||||
|
||||
m := message.ParseInput(line, user)
|
||||
|
||||
// Gross hack to override line echo in golang.org/x/crypto/ssh/terminal
|
||||
// It needs to live before we render the resulting message.
|
||||
term.Write([]byte{
|
||||
27, '[', 'A', // Up
|
||||
27, '[', '2', 'K', // Clear line
|
||||
})
|
||||
// May the gods have mercy on our souls.
|
||||
|
||||
if m, ok := m.(*message.CommandMsg); ok {
|
||||
// Other messages render themselves by the room, commands we'll
|
||||
// have to re-echo ourselves manually.
|
||||
user.HandleMsg(m)
|
||||
}
|
||||
|
||||
// FIXME: Any reason to use h.room.Send(m) instead?
|
||||
h.HandleMsg(m)
|
||||
|
||||
@ -175,15 +189,6 @@ func (h *Host) Connect(term *sshd.Terminal) {
|
||||
term.SetPrompt(GetPrompt(user))
|
||||
user.SetHighlight(user.Name())
|
||||
}
|
||||
|
||||
// Gross hack to override line echo in golang.org/x/crypto/ssh/terminal
|
||||
term.Write([]byte{
|
||||
27, // keyEscape
|
||||
'[', 'A', // Up
|
||||
27, // keyEscape
|
||||
'[', '2', 'K', // Clear line
|
||||
})
|
||||
// May the gods have mercy on our souls.
|
||||
}
|
||||
|
||||
err = h.Leave(user)
|
||||
|
55
host_test.go
55
host_test.go
@ -6,6 +6,7 @@ import (
|
||||
"crypto/rsa"
|
||||
"errors"
|
||||
"io"
|
||||
mathRand "math/rand"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
@ -15,22 +16,53 @@ import (
|
||||
)
|
||||
|
||||
func stripPrompt(s string) string {
|
||||
pos := strings.LastIndex(s, "\033[K")
|
||||
if pos < 0 {
|
||||
return s
|
||||
// FIXME: Is there a better way to do this?
|
||||
if endPos := strings.Index(s, "\x1b[K "); endPos > 0 {
|
||||
return s[endPos+3:]
|
||||
}
|
||||
if endPos := strings.Index(s, "\x1b[2K "); endPos > 0 {
|
||||
return s[endPos+4:]
|
||||
}
|
||||
if endPos := strings.Index(s, "] "); endPos > 0 {
|
||||
return s[endPos+2:]
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
func TestStripPrompt(t *testing.T) {
|
||||
tests := []struct {
|
||||
Input string
|
||||
Want string
|
||||
}{
|
||||
{
|
||||
Input: "\x1b[A\x1b[2K[quux] hello",
|
||||
Want: "hello",
|
||||
},
|
||||
{
|
||||
Input: "[foo] \x1b[D\x1b[D\x1b[D\x1b[D\x1b[D\x1b[D\x1b[K * Guest1 joined. (Connected: 2)\r",
|
||||
Want: " * Guest1 joined. (Connected: 2)\r",
|
||||
},
|
||||
}
|
||||
|
||||
for i, tc := range tests {
|
||||
if got, want := stripPrompt(tc.Input), tc.Want; got != want {
|
||||
t.Errorf("case #%d:\n got: %q\nwant: %q", i, got, want)
|
||||
}
|
||||
}
|
||||
return s[pos+3:]
|
||||
}
|
||||
|
||||
func TestHostGetPrompt(t *testing.T) {
|
||||
var expected, actual string
|
||||
|
||||
// Make the random colors consistent across tests
|
||||
mathRand.Seed(1)
|
||||
|
||||
u := message.NewUser(&Identity{id: "foo"})
|
||||
|
||||
actual = GetPrompt(u)
|
||||
expected = "[foo] "
|
||||
if actual != expected {
|
||||
t.Errorf("Got: %q; Expected: %q", actual, expected)
|
||||
t.Errorf("Invalid host prompt:\n Got: %q;\nWant: %q", actual, expected)
|
||||
}
|
||||
|
||||
u.SetConfig(message.UserConfig{
|
||||
@ -39,7 +71,7 @@ func TestHostGetPrompt(t *testing.T) {
|
||||
actual = GetPrompt(u)
|
||||
expected = "[\033[38;05;88mfoo\033[0m] "
|
||||
if actual != expected {
|
||||
t.Errorf("Got: %q; Expected: %q", actual, expected)
|
||||
t.Errorf("Invalid host prompt:\n Got: %q;\nWant: %q", actual, expected)
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,18 +237,23 @@ func TestHostKick(t *testing.T) {
|
||||
// Change nicks, make sure op sticks
|
||||
w.Write([]byte("/nick quux\r\n"))
|
||||
scanner.Scan() // Prompt
|
||||
scanner.Scan() // Prompt echo
|
||||
scanner.Scan() // Nick change response
|
||||
|
||||
// Signal for the second client to connect
|
||||
connected <- struct{}{}
|
||||
|
||||
// Block until second client is here
|
||||
connected <- struct{}{}
|
||||
scanner.Scan() // Connected message
|
||||
|
||||
w.Write([]byte("/kick bar\r\n"))
|
||||
scanner.Scan() // Prompt
|
||||
scanner.Scan() // Prompt echo
|
||||
|
||||
scanner.Scan()
|
||||
scanner.Scan() // Kick result
|
||||
if actual, expected := stripPrompt(scanner.Text()), " * bar was kicked by quux.\r"; actual != expected {
|
||||
t.Errorf("Got %q; expected %q", actual, expected)
|
||||
t.Errorf("Failed to detect kick:\n Got: %q;\nWant: %q", actual, expected)
|
||||
}
|
||||
|
||||
kicked <- struct{}{}
|
||||
@ -231,6 +268,8 @@ func TestHostKick(t *testing.T) {
|
||||
}()
|
||||
|
||||
go func() {
|
||||
<-connected
|
||||
|
||||
// Second client
|
||||
err := sshd.ConnectShell(addr, "bar", func(r io.Reader, w io.WriteCloser) error {
|
||||
scanner := bufio.NewScanner(r)
|
||||
|
Loading…
x
Reference in New Issue
Block a user