/reply command with autocomplete.

This commit is contained in:
Andrey Petrov 2015-01-18 18:11:30 -08:00
parent 12402c2338
commit 544c9789c0
3 changed files with 81 additions and 39 deletions

View File

@ -201,7 +201,7 @@ func InitCommands(c *Commands) {
c.Add(Command{
Prefix: "/quiet",
Help: "Silence announcement-type messages (join, part, rename, etc).",
Help: "Silence room announcements.",
Handler: func(room *Room, msg CommandMsg) error {
u := msg.From()
u.ToggleQuietMode()

View File

@ -64,6 +64,16 @@ func (u *User) SetId(id Id) {
u.SetColorIdx(rand.Int())
}
// ReplyTo returns the last user that messaged this user.
func (u *User) ReplyTo() *User {
return u.replyTo
}
// SetReplyTo sets the last user to message this user.
func (u *User) SetReplyTo(user *User) {
u.replyTo = user
}
// ToggleQuietMode will toggle whether or not quiet mode is enabled
func (u *User) ToggleQuietMode() {
u.Config.Quiet = !u.Config.Quiet
@ -113,10 +123,13 @@ func (u *User) SetHighlight(s string) error {
return nil
}
func (u User) render(m Message) string {
func (u *User) render(m Message) string {
switch m := m.(type) {
case *PublicMsg:
return m.RenderFor(u.Config) + Newline
case *PrivateMsg:
u.SetReplyTo(m.From())
return m.Render(u.Config.Theme) + Newline
default:
return m.Render(u.Config.Theme) + Newline
}

37
host.go
View File

@ -68,8 +68,6 @@ func (h Host) isOp(conn sshd.Connection) bool {
// Connect a specific Terminal to this host and its room.
func (h *Host) Connect(term *sshd.Terminal) {
id := NewIdentity(term.Conn)
term.AutoCompleteCallback = h.AutoCompleteFunction
user := chat.NewUserScreen(id, term)
user.Config.Theme = h.theme
go func() {
@ -92,6 +90,7 @@ func (h *Host) Connect(term *sshd.Terminal) {
// Successfully joined.
term.SetPrompt(GetPrompt(user))
term.AutoCompleteCallback = h.AutoCompleteFunction(user)
user.SetHighlight(user.Name())
h.count++
@ -159,8 +158,9 @@ func (h Host) completeCommand(partial string) string {
return ""
}
// AutoCompleteFunction is a callback for terminal autocompletion
func (h *Host) AutoCompleteFunction(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
// AutoCompleteFunction returns a callback for terminal autocompletion
func (h *Host) AutoCompleteFunction(u *chat.User) func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
return func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
if key != 9 {
return
}
@ -179,6 +179,12 @@ func (h *Host) AutoCompleteFunction(line string, pos int, key rune) (newLine str
if isFirst && strings.HasPrefix(partial, "/") {
// Command
completed = h.completeCommand(partial)
if completed == "/reply" {
replyTo := u.ReplyTo()
if replyTo != nil {
completed = "/msg " + replyTo.Name()
}
}
} else {
// Name
completed = h.completeName(partial)
@ -198,6 +204,7 @@ func (h *Host) AutoCompleteFunction(line string, pos int, key rune) (newLine str
ok = true
return
}
}
// GetUser returns a chat.User based on a name.
func (h *Host) GetUser(name string) (*chat.User, bool) {
@ -235,6 +242,28 @@ func (h *Host) InitCommands(c *chat.Commands) {
},
})
c.Add(chat.Command{
Prefix: "/reply",
PrefixHelp: "MESSAGE",
Help: "Reply with MESSAGE to the previous private message.",
Handler: func(room *chat.Room, msg chat.CommandMsg) error {
args := msg.Args()
switch len(args) {
case 0:
return errors.New("must specify message")
}
target := msg.From().ReplyTo()
if target == nil {
return errors.New("no message to reply to")
}
m := chat.NewPrivateMsg(strings.Join(args, " "), msg.From(), target)
room.Send(m)
return nil
},
})
// Op commands
c.Add(chat.Command{
Op: true,