Split command system from main view
This commit is contained in:
		
							
								
								
									
										128
									
								
								ui/command-processor.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								ui/command-processor.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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) | ||||||
|  | } | ||||||
							
								
								
									
										99
									
								
								ui/commands.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								ui/commands.go
									
									
									
									
									
										Normal file
									
								
							| @@ -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() | ||||||
|  | } | ||||||
| @@ -18,7 +18,6 @@ package ui | |||||||
|  |  | ||||||
| import ( | import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"strings" |  | ||||||
| 	"time" | 	"time" | ||||||
| 	"unicode" | 	"unicode" | ||||||
|  |  | ||||||
| @@ -40,9 +39,10 @@ import ( | |||||||
| type MainView struct { | type MainView struct { | ||||||
| 	*tview.Flex | 	*tview.Flex | ||||||
|  |  | ||||||
| 	roomList *RoomList | 	roomList     *RoomList | ||||||
| 	roomView *tview.Pages | 	roomView     *tview.Pages | ||||||
| 	rooms    map[string]*RoomView | 	rooms        map[string]*RoomView | ||||||
|  | 	cmdProcessor *CommandProcessor | ||||||
|  |  | ||||||
| 	lastFocusTime time.Time | 	lastFocusTime time.Time | ||||||
|  |  | ||||||
| @@ -73,6 +73,7 @@ func (ui *GomuksUI) NewMainView() tview.Primitive { | |||||||
| 		hideRoomList: prefs.HideRoomList, | 		hideRoomList: prefs.HideRoomList, | ||||||
| 		bareMessages: prefs.BareMessageView, | 		bareMessages: prefs.BareMessageView, | ||||||
| 	} | 	} | ||||||
|  | 	mainView.cmdProcessor = NewCommandProcessor(mainView) | ||||||
|  |  | ||||||
| 	mainView. | 	mainView. | ||||||
| 		SetDirection(tview.FlexColumn). | 		SetDirection(tview.FlexColumn). | ||||||
| @@ -133,10 +134,8 @@ func (view *MainView) InputSubmit(roomView *RoomView, text string) { | |||||||
| 	if len(text) == 0 { | 	if len(text) == 0 { | ||||||
| 		return | 		return | ||||||
| 	} else if text[0] == '/' { | 	} else if text[0] == '/' { | ||||||
| 		args := strings.SplitN(text, " ", 2) | 		cmd := view.cmdProcessor.ParseCommand(roomView, text) | ||||||
| 		command := strings.ToLower(args[0]) | 		go view.cmdProcessor.HandleCommand(cmd) | ||||||
| 		args = args[1:] |  | ||||||
| 		go view.HandleCommand(roomView, command, args) |  | ||||||
| 	} else { | 	} else { | ||||||
| 		view.SendMessage(roomView, text) | 		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) { | func (view *MainView) ShowBare(roomView *RoomView) { | ||||||
| 	_, height := view.parent.app.GetScreen().Size() | 	_, height := view.parent.app.GetScreen().Size() | ||||||
| 	view.parent.app.Suspend(func() { | 	view.parent.app.Suspend(func() { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user