aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTulir Asokan <tulir@maunium.net>2018-05-27 14:54:07 +0300
committerTulir Asokan <tulir@maunium.net>2018-05-27 14:54:07 +0300
commit094a566189a29568a1b7a49510602aecfbcb7bdd (patch)
treeaeb3c8ec18c8376a3c6c54da83b5d177fa728b70
parentb63c451706ab2cec003689e2e8047af737fb1b1c (diff)
Split command system from main view
-rw-r--r--ui/command-processor.go128
-rw-r--r--ui/commands.go99
-rw-r--r--ui/view-main.go81
3 files changed, 234 insertions, 74 deletions
diff --git a/ui/command-processor.go b/ui/command-processor.go
new file mode 100644
index 0000000..9d646ff
--- /dev/null
+++ b/ui/command-processor.go
@@ -0,0 +1,128 @@
+// gomuks - A terminal Matrix client written in Go.
+// Copyright (C) 2018 Tulir Asokan
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package ui
+
+import (
+ "maunium.net/go/gomuks/interface"
+ "strings"
+ "maunium.net/go/gomuks/config"
+ "maunium.net/go/gomuks/debug"
+ "fmt"
+)
+
+type gomuksPointerContainer struct {
+ MainView *MainView
+ UI *GomuksUI
+ Matrix ifc.MatrixContainer
+ Config *config.Config
+ Gomuks ifc.Gomuks
+}
+
+type Command struct {
+ gomuksPointerContainer
+ Handler *CommandProcessor
+
+ Room *RoomView
+ Command string
+ Args []string
+ OrigText string
+}
+
+func (cmd *Command) Reply(message string, args ...interface{}) {
+ cmd.Room.AddServiceMessage(fmt.Sprintf(message, args...))
+}
+
+type Alias struct {
+ NewCommand string
+}
+
+func (alias *Alias) Process(cmd *Command) *Command {
+ cmd.Command = alias.NewCommand
+ return cmd
+}
+
+type CommandHandler func(cmd *Command)
+
+type CommandProcessor struct {
+ gomuksPointerContainer
+
+ aliases map[string]*Alias
+ commands map[string]CommandHandler
+}
+
+func NewCommandProcessor(parent *MainView) *CommandProcessor {
+ return &CommandProcessor{
+ gomuksPointerContainer: gomuksPointerContainer{
+ MainView: parent,
+ UI: parent.parent,
+ Matrix: parent.matrix,
+ Config: parent.config,
+ Gomuks: parent.gmx,
+ },
+ aliases: map[string]*Alias{
+ "part": {"leave"},
+ },
+ commands: map[string]CommandHandler{
+ "unknown-command": cmdUnknownCommand,
+ "help": cmdHelp,
+ "me": cmdMe,
+ "quit": cmdQuit,
+ "clearcache": cmdClearCache,
+ "leave": cmdLeave,
+ "join": cmdJoin,
+ "uitoggle": cmdUIToggle,
+ "logout": cmdLogout,
+ },
+ }
+}
+
+func (ch *CommandProcessor) ParseCommand(roomView *RoomView, text string) *Command {
+ if text[0] != '/' || len(text) < 2 {
+ return nil
+ }
+ text = text[1:]
+ args := strings.SplitN(text, " ", 2)
+ command := strings.ToLower(args[0])
+ args = args[1:]
+ return &Command{
+ gomuksPointerContainer: ch.gomuksPointerContainer,
+ Handler: ch,
+
+ Room: roomView,
+ Command: command,
+ Args: args,
+ OrigText: text,
+ }
+}
+
+func (ch *CommandProcessor) HandleCommand(cmd *Command) {
+ defer debug.Recover()
+ if cmd == nil {
+ return
+ }
+ if alias, ok := ch.aliases[cmd.Command]; ok {
+ cmd = alias.Process(cmd)
+ }
+ if cmd == nil {
+ return
+ }
+ if handler, ok := ch.commands[cmd.Command]; ok {
+ handler(cmd)
+ return
+ }
+ cmdUnknownCommand(cmd)
+}
diff --git a/ui/commands.go b/ui/commands.go
new file mode 100644
index 0000000..38694a5
--- /dev/null
+++ b/ui/commands.go
@@ -0,0 +1,99 @@
+// gomuks - A terminal Matrix client written in Go.
+// Copyright (C) 2018 Tulir Asokan
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+package ui
+
+import (
+ "maunium.net/go/gomuks/debug"
+ "strings"
+)
+
+func cmdMe(cmd *Command) {
+ text := strings.Join(cmd.Args, " ")
+ tempMessage := cmd.Room.NewTempMessage("m.emote", text)
+ go cmd.MainView.sendTempMessage(cmd.Room, tempMessage, text)
+ cmd.UI.Render()
+}
+
+func cmdQuit(cmd *Command) {
+ cmd.Gomuks.Stop()
+}
+
+func cmdClearCache(cmd *Command) {
+ cmd.Config.Clear()
+ cmd.Gomuks.Stop()
+}
+
+func cmdUnknownCommand(cmd *Command) {
+ cmd.Reply("Unknown command \"%s\". Try \"/help\" for help.", cmd.Command)
+}
+
+func cmdHelp(cmd *Command) {
+ cmd.Reply("Known command. Don't try \"/help\" for help.")
+}
+
+func cmdLeave(cmd *Command) {
+ err := cmd.Matrix.LeaveRoom(cmd.Room.MxRoom().ID)
+ debug.Print("Leave room error:", err)
+ if err == nil {
+ cmd.MainView.RemoveRoom(cmd.Room.MxRoom())
+ }
+}
+
+func cmdJoin(cmd *Command) {
+ if len(cmd.Args) == 0 {
+ cmd.Reply("Usage: /join <room>")
+ return
+ }
+ identifer := cmd.Args[0]
+ server := ""
+ if len(cmd.Args) > 1 {
+ server = cmd.Args[1]
+ }
+ room, err := cmd.Matrix.JoinRoom(identifer, server)
+ debug.Print("Join room error:", err)
+ if err == nil {
+ cmd.MainView.AddRoom(room)
+ }
+}
+
+func cmdUIToggle(cmd *Command) {
+ if len(cmd.Args) == 0 {
+ cmd.Reply("Usage: /uitoggle <rooms/users/baremessages>")
+ return
+ }
+ switch cmd.Args[0] {
+ case "rooms":
+ cmd.MainView.hideRoomList = !cmd.MainView.hideRoomList
+ cmd.Config.Preferences.HideRoomList = cmd.MainView.hideRoomList
+ case "users":
+ cmd.MainView.hideUserList = !cmd.MainView.hideUserList
+ cmd.Config.Preferences.HideUserList = cmd.MainView.hideUserList
+ case "baremessages":
+ cmd.MainView.bareMessages = !cmd.MainView.bareMessages
+ cmd.Config.Preferences.BareMessageView = cmd.MainView.bareMessages
+ default:
+ cmd.Reply("Usage: /uitoggle <rooms/users/baremessages>")
+ return
+ }
+ cmd.UI.Render()
+ cmd.UI.Render()
+ go cmd.Matrix.SendPreferencesToMatrix()
+}
+
+func cmdLogout(cmd *Command) {
+ cmd.Matrix.Logout()
+}
diff --git a/ui/view-main.go b/ui/view-main.go
index 9f4f247..785fb44 100644
--- a/ui/view-main.go
+++ b/ui/view-main.go
@@ -18,7 +18,6 @@ package ui
import (
"fmt"
- "strings"
"time"
"unicode"
@@ -40,9 +39,10 @@ import (
type MainView struct {
*tview.Flex
- roomList *RoomList
- roomView *tview.Pages
- rooms map[string]*RoomView
+ roomList *RoomList
+ roomView *tview.Pages
+ rooms map[string]*RoomView
+ cmdProcessor *CommandProcessor
lastFocusTime time.Time
@@ -73,6 +73,7 @@ func (ui *GomuksUI) NewMainView() tview.Primitive {
hideRoomList: prefs.HideRoomList,
bareMessages: prefs.BareMessageView,
}
+ mainView.cmdProcessor = NewCommandProcessor(mainView)
mainView.
SetDirection(tview.FlexColumn).
@@ -133,10 +134,8 @@ func (view *MainView) InputSubmit(roomView *RoomView, text string) {
if len(text) == 0 {
return
} else if text[0] == '/' {
- args := strings.SplitN(text, " ", 2)
- command := strings.ToLower(args[0])
- args = args[1:]
- go view.HandleCommand(roomView, command, args)
+ cmd := view.cmdProcessor.ParseCommand(roomView, text)
+ go view.cmdProcessor.HandleCommand(cmd)
} else {
view.SendMessage(roomView, text)
}
@@ -168,72 +167,6 @@ func (view *MainView) sendTempMessage(roomView *RoomView, tempMessage ifc.Messag
}
}
-func (view *MainView) HandleCommand(roomView *RoomView, command string, args []string) {
- defer debug.Recover()
- debug.Print("Handling command", command, args)
- switch command {
- case "/me":
- text := strings.Join(args, " ")
- tempMessage := roomView.NewTempMessage("m.emote", text)
- go view.sendTempMessage(roomView, tempMessage, text)
- view.parent.Render()
- case "/quit":
- view.gmx.Stop()
- case "/clearcache":
- view.config.Clear()
- view.gmx.Stop()
- case "/panic":
- panic("This is a test panic.")
- case "/part", "/leave":
- err := view.matrix.LeaveRoom(roomView.Room.ID)
- debug.Print("Leave room error:", err)
- if err == nil {
- view.RemoveRoom(roomView.Room)
- }
- case "/uitoggle":
- if len(args) == 0 {
- roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
- break
- }
- switch args[0] {
- case "rooms":
- view.hideRoomList = !view.hideRoomList
- view.config.Preferences.HideRoomList = view.hideRoomList
- case "users":
- view.hideUserList = !view.hideUserList
- view.config.Preferences.HideUserList = view.hideUserList
- case "baremessages":
- view.bareMessages = !view.bareMessages
- view.config.Preferences.BareMessageView = view.bareMessages
- default:
- roomView.AddServiceMessage("Usage: /uitoggle <rooms/users/baremessages>")
- return
- }
- view.parent.Render()
- view.parent.Render()
- go view.matrix.SendPreferencesToMatrix()
- case "/join":
- if len(args) == 0 {
- roomView.AddServiceMessage("Usage: /join <room>")
- break
- }
- identifer := args[0]
- server := ""
- if len(args) > 1 {
- server = args[1]
- }
- room, err := view.matrix.JoinRoom(identifer, server)
- debug.Print("Join room error:", err)
- if err == nil {
- view.AddRoom(room)
- }
- case "/logout":
- view.matrix.Logout()
- default:
- roomView.AddServiceMessage("Unknown command.")
- }
-}
-
func (view *MainView) ShowBare(roomView *RoomView) {
_, height := view.parent.app.GetScreen().Size()
view.parent.app.Suspend(func() {