Fri, 15 Nov 2024 03:12:00 -0600
Add an overview on how commands work
Testing Done:
Built the docs and verified them locally and called in the turtles for good measure.
Reviewed at https://reviews.imfreedom.org/r/3655/
--- a/libpurple/purplecommand.h Fri Nov 15 02:31:25 2024 -0600 +++ b/libpurple/purplecommand.h Fri Nov 15 03:12:00 2024 -0600 @@ -41,6 +41,8 @@ * * An object that represents a command. * + * See the [Commands Overview](section-commands.html) for more information. + * * Since: 3.0 */
--- a/libpurple/reference/libpurple.toml.in Fri Nov 15 02:31:25 2024 -0600 +++ b/libpurple/reference/libpurple.toml.in Fri Nov 15 03:12:00 2024 -0600 @@ -37,8 +37,9 @@ [extra] # The same order will be used when generating the index content_files = [ - "contributing.md", - "tut_c_plugins.md", + "contributing.md", + "section-commands.md", + "tut_c_plugins.md", ] content_images = [ ]
--- a/libpurple/reference/meson.build Fri Nov 15 02:31:25 2024 -0600 +++ b/libpurple/reference/meson.build Fri Nov 15 03:12:00 2024 -0600 @@ -1,5 +1,6 @@ libpurple_doc_content_files = [ 'contributing.md', + 'section-commands.md', 'tut_c_plugins.md', ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libpurple/reference/section-commands.md Fri Nov 15 03:12:00 2024 -0600 @@ -0,0 +1,65 @@ +Title: Commands Overview +Slug: purple-commands + +Many chat services have commands that users can enter in the same place as +messages. These are sometimes called "slash commands" and can be used for all +sorts of different things. They can be conversation specific and may by +implemented by anything including libpurple, user interfaces, plugins, and +protocols. + +They are identified by the [property@Command:name] property which can be +shared by multiple commands. The [property@Command:source] property can be used +to find a specific command or the [property@Command:priority] property can be +used to decide which command to execute. + +Commands are only available in conversations that have all of the [class@Tags] +that are in the [property@Command:tags] property of the command. If the +[property@Command:tags] is %NULL or `empty` the [class@Command] will be +available to all conversations. + +# Implementing Commands + +To implement a command, you create a new instance with [ctor@Command.new], +add a handler to the [signal@Command::executed] signal, and add that command +to the default [class@CommandManager]. The example below shows a simplified +version of creating a command that is only available in channels and adding it +to the default manager. + +```c +PurpleCommand *command = NULL; +PurpleCommandManager *manager = NULL; +PurpleTags *tags = NULL; + +manager = purple_command_manager_get_default(); + +/* Create the command and add our signal handler. */ +command = purple_command_new("example", "Commands Overview", 0); +g_signal_connect(command, "executed", + G_CALLBACK(example_command_executed), NULL); + +/* Get the tags from the command and make it only work on channels. */ +tags = purple_command_get_tags(command); +purple_tags_add(tags, "type=channel"); + +/* Finally add the command to the manager. */ +purple_command_manager_add(manager, command); +``` + +# Handling Commands in a User Interface + +User interfaces only need to interact with the default [class@CommandManager] +to handle all commands. User interfaces can define any prefix they want for a +command, but it is recommended to use a `/` as that is the common case. + +When a user has entered a message that starts with the expected prefix, the +user interface can call [method@CommandManager.find_and_execute] with the +contents of the message with the prefix removed. + +If a command is found and executed, the user interface is done and can clear +the input field for the next message. If a command is not found, the user +interface can then decide to send the message as is or present a warning about +an unknown command. + +There is also [method@CommandManager.get_commands_for_conversation] which the +user interface can use to present a list of commands to the user as they're +typing.