Mercurial > wow > icu
comparison Libs/AceConsole-3.0/AceConsole-3.0.lua @ 0:98c6f55e6619
First commit
| author | Xiiph |
|---|---|
| date | Sat, 05 Feb 2011 16:45:02 +0100 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:98c6f55e6619 |
|---|---|
| 1 --- **AceConsole-3.0** provides registration facilities for slash commands. | |
| 2 -- You can register slash commands to your custom functions and use the `GetArgs` function to parse them | |
| 3 -- to your addons individual needs. | |
| 4 -- | |
| 5 -- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by | |
| 6 -- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object | |
| 7 -- and can be accessed directly, without having to explicitly call AceConsole itself.\\ | |
| 8 -- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you | |
| 9 -- make into AceConsole. | |
| 10 -- @class file | |
| 11 -- @name AceConsole-3.0 | |
| 12 -- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $ | |
| 13 local MAJOR,MINOR = "AceConsole-3.0", 7 | |
| 14 | |
| 15 local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR) | |
| 16 | |
| 17 if not AceConsole then return end -- No upgrade needed | |
| 18 | |
| 19 AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in. | |
| 20 AceConsole.commands = AceConsole.commands or {} -- table containing commands registered | |
| 21 AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable | |
| 22 | |
| 23 -- Lua APIs | |
| 24 local tconcat, tostring, select = table.concat, tostring, select | |
| 25 local type, pairs, error = type, pairs, error | |
| 26 local format, strfind, strsub = string.format, string.find, string.sub | |
| 27 local max = math.max | |
| 28 | |
| 29 -- WoW APIs | |
| 30 local _G = _G | |
| 31 | |
| 32 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded | |
| 33 -- List them here for Mikk's FindGlobals script | |
| 34 -- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList | |
| 35 | |
| 36 local tmp={} | |
| 37 local function Print(self,frame,...) | |
| 38 local n=0 | |
| 39 if self ~= AceConsole then | |
| 40 n=n+1 | |
| 41 tmp[n] = "|cff33ff99"..tostring( self ).."|r:" | |
| 42 end | |
| 43 for i=1, select("#", ...) do | |
| 44 n=n+1 | |
| 45 tmp[n] = tostring(select(i, ...)) | |
| 46 end | |
| 47 frame:AddMessage( tconcat(tmp," ",1,n) ) | |
| 48 end | |
| 49 | |
| 50 --- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) | |
| 51 -- @paramsig [chatframe ,] ... | |
| 52 -- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) | |
| 53 -- @param ... List of any values to be printed | |
| 54 function AceConsole:Print(...) | |
| 55 local frame = ... | |
| 56 if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? | |
| 57 return Print(self, frame, select(2,...)) | |
| 58 else | |
| 59 return Print(self, DEFAULT_CHAT_FRAME, ...) | |
| 60 end | |
| 61 end | |
| 62 | |
| 63 | |
| 64 --- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function) | |
| 65 -- @paramsig [chatframe ,] "format"[, ...] | |
| 66 -- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function) | |
| 67 -- @param format Format string - same syntax as standard Lua format() | |
| 68 -- @param ... Arguments to the format string | |
| 69 function AceConsole:Printf(...) | |
| 70 local frame = ... | |
| 71 if type(frame) == "table" and frame.AddMessage then -- Is first argument something with an .AddMessage member? | |
| 72 return Print(self, frame, format(select(2,...))) | |
| 73 else | |
| 74 return Print(self, DEFAULT_CHAT_FRAME, format(...)) | |
| 75 end | |
| 76 end | |
| 77 | |
| 78 | |
| 79 | |
| 80 | |
| 81 --- Register a simple chat command | |
| 82 -- @param command Chat command to be registered WITHOUT leading "/" | |
| 83 -- @param func Function to call when the slash command is being used (funcref or methodname) | |
| 84 -- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true) | |
| 85 function AceConsole:RegisterChatCommand( command, func, persist ) | |
| 86 if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end | |
| 87 | |
| 88 if persist==nil then persist=true end -- I'd rather have my addon's "/addon enable" around if the author screws up. Having some extra slash regged when it shouldnt be isn't as destructive. True is a better default. /Mikk | |
| 89 | |
| 90 local name = "ACECONSOLE_"..command:upper() | |
| 91 | |
| 92 if type( func ) == "string" then | |
| 93 SlashCmdList[name] = function(input, editBox) | |
| 94 self[func](self, input, editBox) | |
| 95 end | |
| 96 else | |
| 97 SlashCmdList[name] = func | |
| 98 end | |
| 99 _G["SLASH_"..name.."1"] = "/"..command:lower() | |
| 100 AceConsole.commands[command] = name | |
| 101 -- non-persisting commands are registered for enabling disabling | |
| 102 if not persist then | |
| 103 if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end | |
| 104 AceConsole.weakcommands[self][command] = func | |
| 105 end | |
| 106 return true | |
| 107 end | |
| 108 | |
| 109 --- Unregister a chatcommand | |
| 110 -- @param command Chat command to be unregistered WITHOUT leading "/" | |
| 111 function AceConsole:UnregisterChatCommand( command ) | |
| 112 local name = AceConsole.commands[command] | |
| 113 if name then | |
| 114 SlashCmdList[name] = nil | |
| 115 _G["SLASH_" .. name .. "1"] = nil | |
| 116 hash_SlashCmdList["/" .. command:upper()] = nil | |
| 117 AceConsole.commands[command] = nil | |
| 118 end | |
| 119 end | |
| 120 | |
| 121 --- Get an iterator over all Chat Commands registered with AceConsole | |
| 122 -- @return Iterator (pairs) over all commands | |
| 123 function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end | |
| 124 | |
| 125 | |
| 126 local function nils(n, ...) | |
| 127 if n>1 then | |
| 128 return nil, nils(n-1, ...) | |
| 129 elseif n==1 then | |
| 130 return nil, ... | |
| 131 else | |
| 132 return ... | |
| 133 end | |
| 134 end | |
| 135 | |
| 136 | |
| 137 --- Retreive one or more space-separated arguments from a string. | |
| 138 -- Treats quoted strings and itemlinks as non-spaced. | |
| 139 -- @param string The raw argument string | |
| 140 -- @param numargs How many arguments to get (default 1) | |
| 141 -- @param startpos Where in the string to start scanning (default 1) | |
| 142 -- @return Returns arg1, arg2, ..., nextposition\\ | |
| 143 -- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string. | |
| 144 function AceConsole:GetArgs(str, numargs, startpos) | |
| 145 numargs = numargs or 1 | |
| 146 startpos = max(startpos or 1, 1) | |
| 147 | |
| 148 local pos=startpos | |
| 149 | |
| 150 -- find start of new arg | |
| 151 pos = strfind(str, "[^ ]", pos) | |
| 152 if not pos then -- whoops, end of string | |
| 153 return nils(numargs, 1e9) | |
| 154 end | |
| 155 | |
| 156 if numargs<1 then | |
| 157 return pos | |
| 158 end | |
| 159 | |
| 160 -- quoted or space separated? find out which pattern to use | |
| 161 local delim_or_pipe | |
| 162 local ch = strsub(str, pos, pos) | |
| 163 if ch=='"' then | |
| 164 pos = pos + 1 | |
| 165 delim_or_pipe='([|"])' | |
| 166 elseif ch=="'" then | |
| 167 pos = pos + 1 | |
| 168 delim_or_pipe="([|'])" | |
| 169 else | |
| 170 delim_or_pipe="([| ])" | |
| 171 end | |
| 172 | |
| 173 startpos = pos | |
| 174 | |
| 175 while true do | |
| 176 -- find delimiter or hyperlink | |
| 177 local ch,_ | |
| 178 pos,_,ch = strfind(str, delim_or_pipe, pos) | |
| 179 | |
| 180 if not pos then break end | |
| 181 | |
| 182 if ch=="|" then | |
| 183 -- some kind of escape | |
| 184 | |
| 185 if strsub(str,pos,pos+1)=="|H" then | |
| 186 -- It's a |H....|hhyper link!|h | |
| 187 pos=strfind(str, "|h", pos+2) -- first |h | |
| 188 if not pos then break end | |
| 189 | |
| 190 pos=strfind(str, "|h", pos+2) -- second |h | |
| 191 if not pos then break end | |
| 192 elseif strsub(str,pos, pos+1) == "|T" then | |
| 193 -- It's a |T....|t texture | |
| 194 pos=strfind(str, "|t", pos+2) | |
| 195 if not pos then break end | |
| 196 end | |
| 197 | |
| 198 pos=pos+2 -- skip past this escape (last |h if it was a hyperlink) | |
| 199 | |
| 200 else | |
| 201 -- found delimiter, done with this arg | |
| 202 return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1) | |
| 203 end | |
| 204 | |
| 205 end | |
| 206 | |
| 207 -- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink) | |
| 208 return strsub(str, startpos), nils(numargs-1, 1e9) | |
| 209 end | |
| 210 | |
| 211 | |
| 212 --- embedding and embed handling | |
| 213 | |
| 214 local mixins = { | |
| 215 "Print", | |
| 216 "Printf", | |
| 217 "RegisterChatCommand", | |
| 218 "UnregisterChatCommand", | |
| 219 "GetArgs", | |
| 220 } | |
| 221 | |
| 222 -- Embeds AceConsole into the target object making the functions from the mixins list available on target:.. | |
| 223 -- @param target target object to embed AceBucket in | |
| 224 function AceConsole:Embed( target ) | |
| 225 for k, v in pairs( mixins ) do | |
| 226 target[v] = self[v] | |
| 227 end | |
| 228 self.embeds[target] = true | |
| 229 return target | |
| 230 end | |
| 231 | |
| 232 function AceConsole:OnEmbedEnable( target ) | |
| 233 if AceConsole.weakcommands[target] then | |
| 234 for command, func in pairs( AceConsole.weakcommands[target] ) do | |
| 235 target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry | |
| 236 end | |
| 237 end | |
| 238 end | |
| 239 | |
| 240 function AceConsole:OnEmbedDisable( target ) | |
| 241 if AceConsole.weakcommands[target] then | |
| 242 for command, func in pairs( AceConsole.weakcommands[target] ) do | |
| 243 target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care? | |
| 244 end | |
| 245 end | |
| 246 end | |
| 247 | |
| 248 for addon in pairs(AceConsole.embeds) do | |
| 249 AceConsole:Embed(addon) | |
| 250 end |
