mirror of
https://github.com/shazow/ssh-chat.git
synced 2025-04-13 07:37:17 +03:00
/reply command with autocomplete.
This commit is contained in:
parent
12402c2338
commit
544c9789c0
@ -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()
|
||||
|
15
chat/user.go
15
chat/user.go
@ -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
|
||||
}
|
||||
|
103
host.go
103
host.go
@ -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,44 +158,52 @@ 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) {
|
||||
if key != 9 {
|
||||
return
|
||||
}
|
||||
|
||||
if strings.HasSuffix(line[:pos], " ") {
|
||||
// Don't autocomplete spaces.
|
||||
return
|
||||
}
|
||||
|
||||
fields := strings.Fields(line[:pos])
|
||||
isFirst := len(fields) < 2
|
||||
partial := fields[len(fields)-1]
|
||||
posPartial := pos - len(partial)
|
||||
|
||||
var completed string
|
||||
if isFirst && strings.HasPrefix(partial, "/") {
|
||||
// Command
|
||||
completed = h.completeCommand(partial)
|
||||
} else {
|
||||
// Name
|
||||
completed = h.completeName(partial)
|
||||
if completed == "" {
|
||||
// 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
|
||||
}
|
||||
if isFirst {
|
||||
completed += ":"
|
||||
}
|
||||
}
|
||||
completed += " "
|
||||
|
||||
// Reposition the cursor
|
||||
newLine = strings.Replace(line[posPartial:], partial, completed, 1)
|
||||
newLine = line[:posPartial] + newLine
|
||||
newPos = pos + (len(completed) - len(partial))
|
||||
ok = true
|
||||
return
|
||||
if strings.HasSuffix(line[:pos], " ") {
|
||||
// Don't autocomplete spaces.
|
||||
return
|
||||
}
|
||||
|
||||
fields := strings.Fields(line[:pos])
|
||||
isFirst := len(fields) < 2
|
||||
partial := fields[len(fields)-1]
|
||||
posPartial := pos - len(partial)
|
||||
|
||||
var completed string
|
||||
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)
|
||||
if completed == "" {
|
||||
return
|
||||
}
|
||||
if isFirst {
|
||||
completed += ":"
|
||||
}
|
||||
}
|
||||
completed += " "
|
||||
|
||||
// Reposition the cursor
|
||||
newLine = strings.Replace(line[posPartial:], partial, completed, 1)
|
||||
newLine = line[:posPartial] + newLine
|
||||
newPos = pos + (len(completed) - len(partial))
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// GetUser returns a chat.User based on a name.
|
||||
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user