+ Reply to Thread
Results 1 to 3 of 3

Thread: [How To] Simple slash commands

  1. #1
    Telaran
    Join Date
    Mar 2012
    Posts
    83

    Default [How To] Simple slash commands

    Hi,

    As most addons do need at least simple slash commands to configure or to bring up some window, I'd like to give a short "How To" on LUA slash commands made simple.

    First the code:
    Code:
    local slashCommands = setmetatable({
      help =  function()
                print("Insert Addon help text here")
              end,
      config =  function()
                launchConfigStuffHere()
              end,
    }, { __index = function(t) return assert(t.help) end })
    
    table.insert(Command.Slash.Register(toc.NameShort), {function(p) slashCommands[p]() end, Identifier, Identifier.." slash command"})
    So whats this all about?
    LUA has this handy feature to be able to store everything in a table including functions, this is the basic feature used in this example. Instead of writing several functions and have a long if..else loop, all functions are stored in one table using the name of the function or rather parameter of the slash command as their key. The slash handler is then just a simple lookup function that uses the command as key to get the right function to launch.
    In the example above, the user can type "/myaddon help" or "/myaddon config" to launch the function help or config respectively.

    But what if the user enters random stuff?
    Here LUA's second feature for tables comes into play: metatables. Essentially these allow to define what LUA should do if something is done with a table. One of those things is: What to do if a given key is not in the table? In this example the function help is called instead by linking the __index entry in the metatable (the "what to do if the key could not be found" function) with an anonymous function that just redirects to the help function instead. The assert around it is just to notify you if you forgot to define the help function.

    How do I add more functions?
    Just write them in the same way the function "config" is written. Although it looks like a set of functions from the formatting, it is just a list of table entries in the form { a = f, b = g, c = h, } where a, b, c are function/slash-command names and f, g, h are the actual function to run if that command is entered.
    Remember that each addon must and should in general at least define the "help" function and if it's just to tell the user to click on the icon right next to the minimap. ;)

    What's "Identifier" and "toc.nameShort"?
    These are the values extracted from your .toc file. It is very convenient to not hard-code your addon's name here, but instead use the values you supplied to the toc entry. This has several benefits:
    • Your user knows that the short name of your addon, which is shown on every print command, is as well the slash command to use.
    • Should you ever modify your addon's name, short name or other (think about a typo) all your code will be instantly adapted to use those changed values.
    • In your next addon you can just simply copy over the code and it will "magically" work with the correct values.

    You can query your addon's toc content with the following code:
    Code:
    -------------------------------------------------------------------------------------
    -- Queries the current addon for its toc information.
    -- Returns: id  - Identifier of the current addon
    --          toc - ToC of the current addon as a table
    -------------------------------------------------------------------------------------
    function getAddonInfo()
      local id = Inspect.Addon.Current()
      local detail = Inspect.Addon.Detail(id)
      return detail.id, detail.toc
    end
    The table detail will contain exactly what you put into your .toc file.

    So how can I process parameters for my slash commands?
    In this example you can't, however it is simple to change the code to be able to process parameters as well. All you have to do is to modify the anonymous function used in the last line to use only the first word as the lookup key and all others as parameter for the function. To do this you can use the function string.match and an appropriate pattern. Something like "^(%S+)%s*(%S*)" should do (read as: find all non-white-space characters followed by possibly one or more white-spaces followed by possibly one or more non-white-space characters). However dependent on the values you'd like to parse, you would need to adapt the pattern or do a second parse inside the function.

  2. #2
    RIFT Community Ambassador the_real_seebs's Avatar
    Join Date
    Jan 2011
    Posts
    16,859

    Default

    LibGetOpt (up on riftui) can do option parsing including letting the user quote words to spell out things with spaces. One of the people in the riftuidev IRC channel pointed out an interesting usage; if you use the dequote feature to break a line up, you can even have different options which are selected by an initial keyword, as well.

    Not as slick a Lua-ism as this, but handy for parsing command lines.
    You can play WoW in any MMO. You don't have to play WoW in RIFT. Oh, and no, RIFT is not a WoW clone. Not having fun any more? Learn to play, noob! I don't speak for Riftui, but I moderate stuff there. Just came back? Welcome back! Here's what's changed. (Updated for 2.5!)

  3. #3
    Telaran
    Join Date
    Mar 2012
    Posts
    72

    Default

    Seebs,

    That was me, it seems to work, but not had much time to look at it, busy the last few days, and this week.

    I should also chase you to post a bug fixed libgetopt for the couple of bugs I found and fixed locally in my copy

    Thanks,
    Mere

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts