package main import ( "citrons.xyz/talk/proto" ) func isCommand(text string) (bool, string) { if text[0] == '/' { if len(text) > 1 && text[1] == '/' { text = text[1:] return false, text } return true, text } return false, text } func (a *application) processCommand(text string) { text = text[1:] args := []string {""} escaped := false quoted := false for _, c := range text { if escaped { args[len(args) - 1] += string(c) continue } switch c { case '\\': escaped = true case '"': quoted = !quoted case ' ': if !quoted { if args[len(args) - 1] != "" { args = append(args, "") } break } fallthrough default: args[len(args) - 1] += string(c) } } if len(text) > len(args[0]) { text = text[len(args[0]) + 1:] } else { text = "" } a.doCommand(args[0], args[1:], text) } func (a *application) doCommand(command string, args []string, text string) { argN := func(n int) bool { if len(args) != n { a.cmdWindow.err( "%s: expected %d arguments, was %d", command, n, len(args), ) return false } return true } switch command { case "quit": a.quit = true return case "help": var ( hm helpMsg ok bool cmd string ) if len(args) == 0 { hm, ok = getHelp("") } else { if !argN(1) { break } cmd = args[0] if cmd[0] == '/' { if len(cmd) > 1 { cmd = cmd[1:] } else { cmd = "" } } hm, ok = getHelp(cmd) } if !ok { a.cmdWindow.err("unknown command: /" + cmd) } else { a.cmdWindow.Buffer().Add(hm) } return } if !a.connected { return } switch command { case "nick": a.setNick(text) return case "join": if a.authenticated { a.join(text) } return case "leave": if !argN(0) { break } win := a.windowCache.Get(a.currentWindow) switch win.(type) { case *channelWindow: win.(*channelWindow).leaveChannel() } a.currentWindow = cmdWindowLocation {} return case "rename": win := a.windowCache.Get(a.currentWindow) switch win.(type) { case *channelWindow: win.(*channelWindow).renameChannel(text) } return case "list": if !argN(0) { break } win := a.windowCache.Get(a.currentWindow) switch win.(type) { case *channelWindow: win.(*channelWindow).userList(func(msg userListMsg) { a.cmdWindow.Buffer().Add(msg) }) } return case "status": if !a.authenticated { break } cb := func(response proto.Command) { if response.Kind == "fail" && len(response.Args) > 0 { a.cmdWindow.fail(response.Args[0]) } } a.sendUpdate(proto.Object { "u", a.uid, map[string]string {"status": text}, }, cb) return case "who": a.lookup(text, "u", func(u *proto.Object, fail *proto.Fail) { if fail != nil { a.cmdWindow.fail(proto.Object(*fail)) } else { a.cmdWindow.who(u.Id) } }) return case "msg": a.lookup(text, "u", func(u *proto.Object, fail *proto.Fail) { if fail != nil { a.cmdWindow.fail(proto.Object(*fail)) } else { a.joinDirect([]proto.Object {*u}) } }) return case "msgall": a.lookupAll(args, "u", func(us []proto.Object, fail *proto.Fail) { if fail != nil { a.cmdWindow.fail(proto.Object(*fail)) } else { a.joinDirect(us) } }) return case "create": a.createChannel(text) return case "password": if text == "" { a.cmdWindow.err("password cannot be empty") return } a.pushPrompt(&passwordChangePrompt {password: text}) return case "debug": a.goTo(debugWindowLocation{}) return } a.cmdWindow.err("unknown command: /" + command) }