WoW:Creating a slash command: Difference between revisions

From AddOn Studio
Jump to navigation Jump to search
(Typo fixing using AWB)
m (→‎Stategy: correct labels to match bullets.)
Line 1: Line 1:
This [[HOWTO]] teaches the basics of '''creating a slash command''' for your [[AddOn]].
{{UIHowTo}}
'''Slash commands''' allow the player to interact with addons by typing commands into the chat window. This tutorial describes the necessary steps to add the ability to handle slash commands to your addon.


== Simple Example ==
Summary: assign a handler function to <code>SlashCmdList[''key'']</code>, and create <code>SLASH_''key''1</code>, ..., <code>SLASH_''key''n</code> global constants containing the desired command names, where ''key'' is some unique command-specific string.
Suppose you have:


function MyScript_Command(cmd)
==Background==
  DEFAULT_CHAT_FRAME:AddMessage("Command: " .. cmd);
Slash command handlers are typically invoked by Blizzard's FrameXML code handling the player's chat input; therefore, an addon offering a slash command must register the command by placing certain values in a location where the chat input handling code looks for them.
end
In the '''OnLoad function''' of your script, ''or'' in the .lua '''any place after the function is defined''', put in the following:
 
SLASH_MYSCRIPT1 = "/myscript";
SLASH_MYSCRIPT2 = "/mys"; -- A shortcut or alias
SlashCmdList["MYSCRIPT"] = MyScript_Command;


'''Note''': The slash command(s) must be defined in an OnLoad Function or after the function has been defined. If the slash command is defined when the function it "points to" (which is <tt>MyScript_Command</tt> in the above script) has not been defined yet, the slash command '''will not work'''.
An addon must create a function that would handle the slash command (possibly parsing the argument string passed to it), and place it into the SlashCmdList table. Additionally, an addon must declare which slash commands it wishes to bind to its handler function.


== Further Examples ==
== Stategy ==
'''OnLoad Function:'''
# Pick a unique identifier for the slash command: i.e. MYADDON
#: A common convention is ADDONNAME if you only have one slash command, or ADDONNAME_COMMANDNAME if you have multiple (where ADDONNAME is the name of your addon).
# Decide which slash commands you want to respond to: i.e. /myadd.
#: You can select multiple alternatives for the same command -- allowing shorter or longer command names to be used in case of conflicts.
# Assign your selected slash commands to SLASH_MYADDON1, SLASH_MYADDON2, etc global variables.
# Write a slash command handler function (taking (msg, editbox) as arguments), and place assign it to SlashCmdList["MYADDON"].


  function AddonName_OnLoad()
Here is a simple example that can be placed anywhere in a Lua file:
  SlashCmdList["ADDONNAME"] = AddonName_SlashCmdHandler;
-- 1. Pick HELLOWORLD as the unique identifier.
  SLASH_ADDONNAME1 = "/slash1";
  -- 2. Pick /hiw and /hellow as slash commands (/hi and /hello are actual emotes)
  SLASH_ADDONNAME2 = "/slash2";
SLASH_HELLOWORLD1, SLASH_HELLOWORLD2 = '/hiw', '/hellow'; -- 3.
end
  function SlashCmdList.HELLOWORLD(msg, editbox) -- 4.
   print("Hello, World!");
  function AddonName_SlashCmdHandler()
   -- do stuff
  end
  end
And in your XML file:


<OnLoad>
== Parsing Arguments ==
  AddonName_OnLoad();
If the user types '''/yourcmd someargs''' into chat, the function handling '''/yourcmd''' is passed "someargs" as the first argument (the second being the edit box widget into which the slash command was typed). Your handler function can then choose to act on that argument string. For simple slash commands, comparisons to pre-determined strings may be sufficient: suppose we wanted to modify the "Hello, World!" example above to display a different string if the command was passed an argument (say '''/hiw bye'''):
</OnLoad>


The above example will work as long as <tt>AddonName_OnLoad</tt> is called.
SLASH_HELLOWORLD1, SLASH_HELLOWORLD2 = '/hiw', '/hellow';
 
local function handler(msg, editbox)
'''After the function has been defined:'''
  if msg == 'bye' then
  print('Goodbye, World!');
  else
  print("Hello, World!");
  end
end
SlashCmdList["HELLOWORLD"] = handler; -- Also a valid assignment strategy


  function MySlashCmdFunction()
More complex slash commands may wish to use [[Pattern matching]] to parse the arguments string:
-- Some stuff here
  local function handler(msg, editbox)
  local command, rest = msg:match("^(%S*)%s*(.-)$");
  -- Any leading non-whitespace is captured into command;
  -- the rest (minus leading whitespace) is captured into rest.
  if command == "add" and rest ~= "" then
  -- Handle adding of the contents of rest... to something.
  elseif command == "remove" and rest ~= "" then
  -- Handle removing of the contents of rest... to something. 
  else
  -- If not handled above, display some sort of help message
  print("Syntax: /yourcmd (add|remove) someIdentifier");
  end
  end
  end
  SlashCmdList["ADDONNAME"] = MySlashCmdFunction;
  SLASH_ADDONNAME1 = "/slash1";
  SLASH_ADDONNAME2 = "/slash2";


 
== Notes ==
 
* Default UI commands often have precedence over addon-created slash commands. There is no defined precedence order for addon-created commands, so conflicts caused by multiple addons attempting to use the same slash command will resolve non-deterministically.
== The Details ==
** If the unique command identifier (the key in SlashCmdList) conflicts between multiple addons, the addon that executes the assignment last will own the slash command.
<pre>SLASH_<CommandId><num>
* Command identifiers are generally all caps, with underscores if necessary. These can also contain lowercase characters.
SlashCmdList["<CommandId>"] = <CodeToExecute></pre>
** The actual '''SLASH_''&lt;CommandId&gt;''''&lt;Number&gt;''''' values should be localizable if you plan on your addon being translated, but the command ID will remain the same.
 
Slash command parsing is done by the chat frame, and it works as follows.
 
* The key of each entry is the <CommandId>. It should be the unique name of your Addon.
* The parser then examines '''SLASH_''&lt;CommandId&gt;''1''', '''SLASH_''&lt;CommandId&gt;''2''', ... and so on, until it either finds a match, or gets a nil value (undefined) on the next '''SLASH_''&lt;CommandId&gt;''''&lt;Number&gt;'''''.
* If there was a hit, then the function value of '''SlashCmdList["''&lt;CommandId&gt;''"]''' is invoked, with the rest of the command line as its single parameter
 
* Special 'built in' slash commands for chat are handled first.
* The chat handler then iterates over the contents of the global table '''SlashCmdList'''
* Otherwise, the next command is searched until a match is found or the list is exhausted.
 
== Conventions ==
* Command ID's are generally all caps, with underscores if necessary. These can also contain lowercase characters.
* Pick a command ID that's going to be unique to your addon, a common convention is ADDONNAME_COMMANDNAME, or if you just have one, then ADDONNAME (Where ADDONNAME is the name of your addon).
* The actual '''SLASH_''&lt;CommandId&gt;''''&lt;Number&gt;''''' values should be localizable if you plan on your addon being translated, but the command ID will remain the same.
* Be prudent about how many aliases you make for your command, and try and pick something that's unlikely to collide with someone else's (including Blizzard's!)
* Be prudent about how many aliases you make for your command, and try and pick something that's unlikely to collide with someone else's (including Blizzard's!)
 
* There's a second parameter passed to the slash command handler functions that is rarely used. It is the chat frame edit box frame that the slash command originated from.
== Notes ==
Command ID's in SlashCmdList are not protected from being overwritten, including Blizzard added Command ID's. Alias' are not lost if the function that is triggered is changed, but individual alias' can be overwrote as well.
 
There's a second parameter to the SlashCmdList["''&lt;CommandId&gt;''"] function that is rarely used. It is the chat frame edit box frame that the slash command originated from.
  SLASH_BLAH1 = "/blah"
  SLASH_BLAH1 = "/blah"
  SlashCmdList["BLAH"] = function(msg, editBox)
  SlashCmdList["BLAH"] = function(msg, editBox)
Line 78: Line 66:
     editBox:SetText("Blah blah blah!")
     editBox:SetText("Blah blah blah!")
  end
  end
== See also ==
* [[Extracting info from a slash command]] - parsing arguments given to your slash command.


[[Category:AddOns]]
[[Category:AddOns]]
[[Category:HOWTOs]]
[[Category:HOWTOs]]
{{DEFAULTSORT:Create a Slash Command}}

Revision as of 10:35, 26 May 2009

HOWTOs

Slash commands allow the player to interact with addons by typing commands into the chat window. This tutorial describes the necessary steps to add the ability to handle slash commands to your addon.

Summary: assign a handler function to SlashCmdList[key], and create SLASH_key1, ..., SLASH_keyn global constants containing the desired command names, where key is some unique command-specific string.

Background

Slash command handlers are typically invoked by Blizzard's FrameXML code handling the player's chat input; therefore, an addon offering a slash command must register the command by placing certain values in a location where the chat input handling code looks for them.

An addon must create a function that would handle the slash command (possibly parsing the argument string passed to it), and place it into the SlashCmdList table. Additionally, an addon must declare which slash commands it wishes to bind to its handler function.

Stategy

  1. Pick a unique identifier for the slash command: i.e. MYADDON
    A common convention is ADDONNAME if you only have one slash command, or ADDONNAME_COMMANDNAME if you have multiple (where ADDONNAME is the name of your addon).
  2. Decide which slash commands you want to respond to: i.e. /myadd.
    You can select multiple alternatives for the same command -- allowing shorter or longer command names to be used in case of conflicts.
  3. Assign your selected slash commands to SLASH_MYADDON1, SLASH_MYADDON2, etc global variables.
  4. Write a slash command handler function (taking (msg, editbox) as arguments), and place assign it to SlashCmdList["MYADDON"].

Here is a simple example that can be placed anywhere in a Lua file:

-- 1. Pick HELLOWORLD as the unique identifier.
-- 2. Pick /hiw and /hellow as slash commands (/hi and /hello are actual emotes)
SLASH_HELLOWORLD1, SLASH_HELLOWORLD2 = '/hiw', '/hellow'; -- 3.
function SlashCmdList.HELLOWORLD(msg, editbox) -- 4.
 print("Hello, World!");
end

Parsing Arguments

If the user types /yourcmd someargs into chat, the function handling /yourcmd is passed "someargs" as the first argument (the second being the edit box widget into which the slash command was typed). Your handler function can then choose to act on that argument string. For simple slash commands, comparisons to pre-determined strings may be sufficient: suppose we wanted to modify the "Hello, World!" example above to display a different string if the command was passed an argument (say /hiw bye):

SLASH_HELLOWORLD1, SLASH_HELLOWORLD2 = '/hiw', '/hellow';
local function handler(msg, editbox)
 if msg == 'bye' then
  print('Goodbye, World!');
 else
  print("Hello, World!");
 end
end
SlashCmdList["HELLOWORLD"] = handler; -- Also a valid assignment strategy

More complex slash commands may wish to use Pattern matching to parse the arguments string:

local function handler(msg, editbox)
 local command, rest = msg:match("^(%S*)%s*(.-)$");
 -- Any leading non-whitespace is captured into command;
 -- the rest (minus leading whitespace) is captured into rest.
 if command == "add" and rest ~= "" then
  -- Handle adding of the contents of rest... to something.
 elseif command == "remove" and rest ~= "" then
  -- Handle removing of the contents of rest... to something.   
 else
  -- If not handled above, display some sort of help message
  print("Syntax: /yourcmd (add|remove) someIdentifier");
 end
end

Notes

  • Default UI commands often have precedence over addon-created slash commands. There is no defined precedence order for addon-created commands, so conflicts caused by multiple addons attempting to use the same slash command will resolve non-deterministically.
    • If the unique command identifier (the key in SlashCmdList) conflicts between multiple addons, the addon that executes the assignment last will own the slash command.
  • Command identifiers are generally all caps, with underscores if necessary. These can also contain lowercase characters.
    • The actual SLASH_<CommandId>'<Number> values should be localizable if you plan on your addon being translated, but the command ID will remain the same.
  • Be prudent about how many aliases you make for your command, and try and pick something that's unlikely to collide with someone else's (including Blizzard's!)
  • There's a second parameter passed to the slash command handler functions that is rarely used. It is the chat frame edit box frame that the slash command originated from.
SLASH_BLAH1 = "/blah"
SlashCmdList["BLAH"] = function(msg, editBox)
    -- change the text on the editBox.
    editBox:Show()
    editBox:SetText("Blah blah blah!")
end