comparison Libs/AceConfig-3.0/AceConfigCmd-3.0/AceConfigCmd-3.0.lua @ 0:169f5211fc7f

First public revision. At this point ItemAuditor watches mail for auctions sold or purchased, watches for buy/sell (money and 1 item type change) and conversions/tradeskills. Milling isn't working yet because there is too much time between the first event and the last event.
author Asa Ayers <Asa.Ayers@Gmail.com>
date Thu, 20 May 2010 19:22:19 -0700
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:169f5211fc7f
1 --- AceConfigCmd-3.0 handles access to an options table through the "command line" interface via the ChatFrames.
2 -- @class file
3 -- @name AceConfigCmd-3.0
4 -- @release $Id: AceConfigCmd-3.0.lua 904 2009-12-13 11:56:37Z nevcairiel $
5
6 --[[
7 AceConfigCmd-3.0
8
9 Handles commandline optionstable access
10
11 REQUIRES: AceConsole-3.0 for command registration (loaded on demand)
12
13 ]]
14
15 -- TODO: plugin args
16
17
18 local MAJOR, MINOR = "AceConfigCmd-3.0", 12
19 local AceConfigCmd = LibStub:NewLibrary(MAJOR, MINOR)
20
21 if not AceConfigCmd then return end
22
23 AceConfigCmd.commands = AceConfigCmd.commands or {}
24 local commands = AceConfigCmd.commands
25
26 local cfgreg = LibStub("AceConfigRegistry-3.0")
27 local AceConsole -- LoD
28 local AceConsoleName = "AceConsole-3.0"
29
30 -- Lua APIs
31 local strsub, strsplit, strlower, strmatch, strtrim = string.sub, string.split, string.lower, string.match, string.trim
32 local format, tonumber, tostring = string.format, tonumber, tostring
33 local tsort, tinsert = table.sort, table.insert
34 local select, pairs, next, type = select, pairs, next, type
35 local error, assert = error, assert
36
37 -- WoW APIs
38 local _G = _G
39
40 -- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
41 -- List them here for Mikk's FindGlobals script
42 -- GLOBALS: LibStub, SELECTED_CHAT_FRAME, DEFAULT_CHAT_FRAME
43
44
45 local L = setmetatable({}, { -- TODO: replace with proper locale
46 __index = function(self,k) return k end
47 })
48
49
50
51 local function print(msg)
52 (SELECTED_CHAT_FRAME or DEFAULT_CHAT_FRAME):AddMessage(msg)
53 end
54
55 -- constants used by getparam() calls below
56
57 local handlertypes = {["table"]=true}
58 local handlermsg = "expected a table"
59
60 local functypes = {["function"]=true, ["string"]=true}
61 local funcmsg = "expected function or member name"
62
63
64 -- pickfirstset() - picks the first non-nil value and returns it
65
66 local function pickfirstset(...)
67 for i=1,select("#",...) do
68 if select(i,...)~=nil then
69 return select(i,...)
70 end
71 end
72 end
73
74
75 -- err() - produce real error() regarding malformed options tables etc
76
77 local function err(info,inputpos,msg )
78 local cmdstr=" "..strsub(info.input, 1, inputpos-1)
79 error(MAJOR..": /" ..info[0] ..cmdstr ..": "..(msg or "malformed options table"), 2)
80 end
81
82
83 -- usererr() - produce chatframe message regarding bad slash syntax etc
84
85 local function usererr(info,inputpos,msg )
86 local cmdstr=strsub(info.input, 1, inputpos-1);
87 print("/" ..info[0] .. " "..cmdstr ..": "..(msg or "malformed options table"))
88 end
89
90
91 -- callmethod() - call a given named method (e.g. "get", "set") with given arguments
92
93 local function callmethod(info, inputpos, tab, methodtype, ...)
94 local method = info[methodtype]
95 if not method then
96 err(info, inputpos, "'"..methodtype.."': not set")
97 end
98
99 info.arg = tab.arg
100 info.option = tab
101 info.type = tab.type
102
103 if type(method)=="function" then
104 return method(info, ...)
105 elseif type(method)=="string" then
106 if type(info.handler[method])~="function" then
107 err(info, inputpos, "'"..methodtype.."': '"..method.."' is not a member function of "..tostring(info.handler))
108 end
109 return info.handler[method](info.handler, info, ...)
110 else
111 assert(false) -- type should have already been checked on read
112 end
113 end
114
115 -- callfunction() - call a given named function (e.g. "name", "desc") with given arguments
116
117 local function callfunction(info, tab, methodtype, ...)
118 local method = tab[methodtype]
119
120 info.arg = tab.arg
121 info.option = tab
122 info.type = tab.type
123
124 if type(method)=="function" then
125 return method(info, ...)
126 else
127 assert(false) -- type should have already been checked on read
128 end
129 end
130
131 -- do_final() - do the final step (set/execute) along with validation and confirmation
132
133 local function do_final(info, inputpos, tab, methodtype, ...)
134 if info.validate then
135 local res = callmethod(info,inputpos,tab,"validate",...)
136 if type(res)=="string" then
137 usererr(info, inputpos, "'"..strsub(info.input, inputpos).."' - "..res)
138 return
139 end
140 end
141 -- console ignores .confirm
142
143 callmethod(info,inputpos,tab,methodtype, ...)
144 end
145
146
147 -- getparam() - used by handle() to retreive and store "handler", "get", "set", etc
148
149 local function getparam(info, inputpos, tab, depth, paramname, types, errormsg)
150 local old,oldat = info[paramname], info[paramname.."_at"]
151 local val=tab[paramname]
152 if val~=nil then
153 if val==false then
154 val=nil
155 elseif not types[type(val)] then
156 err(info, inputpos, "'" .. paramname.. "' - "..errormsg)
157 end
158 info[paramname] = val
159 info[paramname.."_at"] = depth
160 end
161 return old,oldat
162 end
163
164
165 -- iterateargs(tab) - custom iterator that iterates both t.args and t.plugins.*
166 local dummytable={}
167
168 local function iterateargs(tab)
169 if not tab.plugins then
170 return pairs(tab.args)
171 end
172
173 local argtabkey,argtab=next(tab.plugins)
174 local v
175
176 return function(_, k)
177 while argtab do
178 k,v = next(argtab, k)
179 if k then return k,v end
180 if argtab==tab.args then
181 argtab=nil
182 else
183 argtabkey,argtab = next(tab.plugins, argtabkey)
184 if not argtabkey then
185 argtab=tab.args
186 end
187 end
188 end
189 end
190 end
191
192 local function checkhidden(info, inputpos, tab)
193 if tab.cmdHidden~=nil then
194 return tab.cmdHidden
195 end
196 local hidden = tab.hidden
197 if type(hidden) == "function" or type(hidden) == "string" then
198 info.hidden = hidden
199 hidden = callmethod(info, inputpos, tab, 'hidden')
200 info.hidden = nil
201 end
202 return hidden
203 end
204
205 local function showhelp(info, inputpos, tab, depth, noHead)
206 if not noHead then
207 print("|cff33ff99"..info.appName.."|r: Arguments to |cffffff78/"..info[0].."|r "..strsub(info.input,1,inputpos-1)..":")
208 end
209
210 local sortTbl = {} -- [1..n]=name
211 local refTbl = {} -- [name]=tableref
212
213 for k,v in iterateargs(tab) do
214 if not refTbl[k] then -- a plugin overriding something in .args
215 tinsert(sortTbl, k)
216 refTbl[k] = v
217 end
218 end
219
220 tsort(sortTbl, function(one, two)
221 local o1 = refTbl[one].order or 100
222 local o2 = refTbl[two].order or 100
223 if type(o1) == "function" or type(o1) == "string" then
224 info.order = o1
225 info[#info+1] = one
226 o1 = callmethod(info, inputpos, refTbl[one], "order")
227 info[#info] = nil
228 info.order = nil
229 end
230 if type(o2) == "function" or type(o1) == "string" then
231 info.order = o2
232 info[#info+1] = two
233 o2 = callmethod(info, inputpos, refTbl[two], "order")
234 info[#info] = nil
235 info.order = nil
236 end
237 if o1<0 and o2<0 then return o1<o2 end
238 if o2<0 then return true end
239 if o1<0 then return false end
240 if o1==o2 then return tostring(one)<tostring(two) end -- compare names
241 return o1<o2
242 end)
243
244 for i = 1, #sortTbl do
245 local k = sortTbl[i]
246 local v = refTbl[k]
247 if not checkhidden(info, inputpos, v) then
248 if v.type ~= "description" and v.type ~= "header" then
249 -- recursively show all inline groups
250 local name, desc = v.name, v.desc
251 if type(name) == "function" then
252 name = callfunction(info, v, 'name')
253 end
254 if type(desc) == "function" then
255 desc = callfunction(info, v, 'desc')
256 end
257 if v.type == "group" and pickfirstset(v.cmdInline, v.inline, false) then
258 print(" "..(desc or name)..":")
259 local oldhandler,oldhandler_at = getparam(info, inputpos, v, depth, "handler", handlertypes, handlermsg)
260 showhelp(info, inputpos, v, depth, true)
261 info.handler,info.handler_at = oldhandler,oldhandler_at
262 else
263 local key = k:gsub(" ", "_")
264 print(" |cffffff78"..key.."|r - "..(desc or name or ""))
265 end
266 end
267 end
268 end
269 end
270
271
272 local function keybindingValidateFunc(text)
273 if text == nil or text == "NONE" then
274 return nil
275 end
276 text = text:upper()
277 local shift, ctrl, alt
278 local modifier
279 while true do
280 if text == "-" then
281 break
282 end
283 modifier, text = strsplit('-', text, 2)
284 if text then
285 if modifier ~= "SHIFT" and modifier ~= "CTRL" and modifier ~= "ALT" then
286 return false
287 end
288 if modifier == "SHIFT" then
289 if shift then
290 return false
291 end
292 shift = true
293 end
294 if modifier == "CTRL" then
295 if ctrl then
296 return false
297 end
298 ctrl = true
299 end
300 if modifier == "ALT" then
301 if alt then
302 return false
303 end
304 alt = true
305 end
306 else
307 text = modifier
308 break
309 end
310 end
311 if text == "" then
312 return false
313 end
314 if not text:find("^F%d+$") and text ~= "CAPSLOCK" and text:len() ~= 1 and (text:byte() < 128 or text:len() > 4) and not _G["KEY_" .. text] then
315 return false
316 end
317 local s = text
318 if shift then
319 s = "SHIFT-" .. s
320 end
321 if ctrl then
322 s = "CTRL-" .. s
323 end
324 if alt then
325 s = "ALT-" .. s
326 end
327 return s
328 end
329
330 -- handle() - selfrecursing function that processes input->optiontable
331 -- - depth - starts at 0
332 -- - retfalse - return false rather than produce error if a match is not found (used by inlined groups)
333
334 local function handle(info, inputpos, tab, depth, retfalse)
335
336 if not(type(tab)=="table" and type(tab.type)=="string") then err(info,inputpos) end
337
338 -------------------------------------------------------------------
339 -- Grab hold of handler,set,get,func,etc if set (and remember old ones)
340 -- Note that we do NOT validate if method names are correct at this stage,
341 -- the handler may change before they're actually used!
342
343 local oldhandler,oldhandler_at = getparam(info,inputpos,tab,depth,"handler",handlertypes,handlermsg)
344 local oldset,oldset_at = getparam(info,inputpos,tab,depth,"set",functypes,funcmsg)
345 local oldget,oldget_at = getparam(info,inputpos,tab,depth,"get",functypes,funcmsg)
346 local oldfunc,oldfunc_at = getparam(info,inputpos,tab,depth,"func",functypes,funcmsg)
347 local oldvalidate,oldvalidate_at = getparam(info,inputpos,tab,depth,"validate",functypes,funcmsg)
348 --local oldconfirm,oldconfirm_at = getparam(info,inputpos,tab,depth,"confirm",functypes,funcmsg)
349
350 -------------------------------------------------------------------
351 -- Act according to .type of this table
352
353 if tab.type=="group" then
354 ------------ group --------------------------------------------
355
356 if type(tab.args)~="table" then err(info, inputpos) end
357 if tab.plugins and type(tab.plugins)~="table" then err(info,inputpos) end
358
359 -- grab next arg from input
360 local _,nextpos,arg = (info.input):find(" *([^ ]+) *", inputpos)
361 if not arg then
362 showhelp(info, inputpos, tab, depth)
363 return
364 end
365 nextpos=nextpos+1
366
367 -- loop .args and try to find a key with a matching name
368 for k,v in iterateargs(tab) do
369 if not(type(k)=="string" and type(v)=="table" and type(v.type)=="string") then err(info,inputpos, "options table child '"..tostring(k).."' is malformed") end
370
371 -- is this child an inline group? if so, traverse into it
372 if v.type=="group" and pickfirstset(v.cmdInline, v.inline, false) then
373 info[depth+1] = k
374 if handle(info, inputpos, v, depth+1, true)==false then
375 info[depth+1] = nil
376 -- wasn't found in there, but that's ok, we just keep looking down here
377 else
378 return -- done, name was found in inline group
379 end
380 -- matching name and not a inline group
381 elseif strlower(arg)==strlower(k:gsub(" ", "_")) then
382 info[depth+1] = k
383 return handle(info,nextpos,v,depth+1)
384 end
385 end
386
387 -- no match
388 if retfalse then
389 -- restore old infotable members and return false to indicate failure
390 info.handler,info.handler_at = oldhandler,oldhandler_at
391 info.set,info.set_at = oldset,oldset_at
392 info.get,info.get_at = oldget,oldget_at
393 info.func,info.func_at = oldfunc,oldfunc_at
394 info.validate,info.validate_at = oldvalidate,oldvalidate_at
395 --info.confirm,info.confirm_at = oldconfirm,oldconfirm_at
396 return false
397 end
398
399 -- couldn't find the command, display error
400 usererr(info, inputpos, "'"..arg.."' - " .. L["unknown argument"])
401 return
402 end
403
404 local str = strsub(info.input,inputpos);
405
406 if tab.type=="execute" then
407 ------------ execute --------------------------------------------
408 do_final(info, inputpos, tab, "func")
409
410
411
412 elseif tab.type=="input" then
413 ------------ input --------------------------------------------
414
415 local res = true
416 if tab.pattern then
417 if not(type(tab.pattern)=="string") then err(info, inputpos, "'pattern' - expected a string") end
418 if not strmatch(str, tab.pattern) then
419 usererr(info, inputpos, "'"..str.."' - " .. L["invalid input"])
420 return
421 end
422 end
423
424 do_final(info, inputpos, tab, "set", str)
425
426
427
428 elseif tab.type=="toggle" then
429 ------------ toggle --------------------------------------------
430 local b
431 local str = strtrim(strlower(str))
432 if str=="" then
433 b = callmethod(info, inputpos, tab, "get")
434
435 if tab.tristate then
436 --cycle in true, nil, false order
437 if b then
438 b = nil
439 elseif b == nil then
440 b = false
441 else
442 b = true
443 end
444 else
445 b = not b
446 end
447
448 elseif str==L["on"] then
449 b = true
450 elseif str==L["off"] then
451 b = false
452 elseif tab.tristate and str==L["default"] then
453 b = nil
454 else
455 if tab.tristate then
456 usererr(info, inputpos, format(L["'%s' - expected 'on', 'off' or 'default', or no argument to toggle."], str))
457 else
458 usererr(info, inputpos, format(L["'%s' - expected 'on' or 'off', or no argument to toggle."], str))
459 end
460 return
461 end
462
463 do_final(info, inputpos, tab, "set", b)
464
465
466 elseif tab.type=="range" then
467 ------------ range --------------------------------------------
468 local val = tonumber(str)
469 if not val then
470 usererr(info, inputpos, "'"..str.."' - "..L["expected number"])
471 return
472 end
473 if type(info.step)=="number" then
474 val = val- (val % info.step)
475 end
476 if type(info.min)=="number" and val<info.min then
477 usererr(info, inputpos, val.." - "..format(L["must be equal to or higher than %s"], tostring(info.min)) )
478 return
479 end
480 if type(info.max)=="number" and val>info.max then
481 usererr(info, inputpos, val.." - "..format(L["must be equal to or lower than %s"], tostring(info.max)) )
482 return
483 end
484
485 do_final(info, inputpos, tab, "set", val)
486
487
488 elseif tab.type=="select" then
489 ------------ select ------------------------------------
490 local str = strtrim(strlower(str))
491
492 local values = tab.values
493 if type(values) == "function" or type(values) == "string" then
494 info.values = values
495 values = callmethod(info, inputpos, tab, "values")
496 info.values = nil
497 end
498
499 if str == "" then
500 local b = callmethod(info, inputpos, tab, "get")
501 local fmt = "|cffffff78- [%s]|r %s"
502 local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
503 print(L["Options for |cffffff78"..info[#info].."|r:"])
504 for k, v in pairs(values) do
505 if b == k then
506 print(fmt_sel:format(k, v))
507 else
508 print(fmt:format(k, v))
509 end
510 end
511 return
512 end
513
514 local ok
515 for k,v in pairs(values) do
516 if strlower(k)==str then
517 str = k -- overwrite with key (in case of case mismatches)
518 ok = true
519 break
520 end
521 end
522 if not ok then
523 usererr(info, inputpos, "'"..str.."' - "..L["unknown selection"])
524 return
525 end
526
527 do_final(info, inputpos, tab, "set", str)
528
529 elseif tab.type=="multiselect" then
530 ------------ multiselect -------------------------------------------
531 local str = strtrim(strlower(str))
532
533 local values = tab.values
534 if type(values) == "function" or type(values) == "string" then
535 info.values = values
536 values = callmethod(info, inputpos, tab, "values")
537 info.values = nil
538 end
539
540 if str == "" then
541 local fmt = "|cffffff78- [%s]|r %s"
542 local fmt_sel = "|cffffff78- [%s]|r %s |cffff0000*|r"
543 print(L["Options for |cffffff78"..info[#info].."|r (multiple possible):"])
544 for k, v in pairs(values) do
545 if callmethod(info, inputpos, tab, "get", k) then
546 print(fmt_sel:format(k, v))
547 else
548 print(fmt:format(k, v))
549 end
550 end
551 return
552 end
553
554 --build a table of the selections, checking that they exist
555 --parse for =on =off =default in the process
556 --table will be key = true for options that should toggle, key = [on|off|default] for options to be set
557 local sels = {}
558 for v in str:gmatch("[^ ]+") do
559 --parse option=on etc
560 local opt, val = v:match('(.+)=(.+)')
561 --get option if toggling
562 if not opt then
563 opt = v
564 end
565
566 --check that the opt is valid
567 local ok
568 for k,v in pairs(values) do
569 if strlower(k)==opt then
570 opt = k -- overwrite with key (in case of case mismatches)
571 ok = true
572 break
573 end
574 end
575
576 if not ok then
577 usererr(info, inputpos, "'"..opt.."' - "..L["unknown selection"])
578 return
579 end
580
581 --check that if val was supplied it is valid
582 if val then
583 if val == L["on"] or val == L["off"] or (tab.tristate and val == L["default"]) then
584 --val is valid insert it
585 sels[opt] = val
586 else
587 if tab.tristate then
588 usererr(info, inputpos, format(L["'%s' '%s' - expected 'on', 'off' or 'default', or no argument to toggle."], v, val))
589 else
590 usererr(info, inputpos, format(L["'%s' '%s' - expected 'on' or 'off', or no argument to toggle."], v, val))
591 end
592 return
593 end
594 else
595 -- no val supplied, toggle
596 sels[opt] = true
597 end
598 end
599
600 for opt, val in pairs(sels) do
601 local newval
602
603 if (val == true) then
604 --toggle the option
605 local b = callmethod(info, inputpos, tab, "get", opt)
606
607 if tab.tristate then
608 --cycle in true, nil, false order
609 if b then
610 b = nil
611 elseif b == nil then
612 b = false
613 else
614 b = true
615 end
616 else
617 b = not b
618 end
619 newval = b
620 else
621 --set the option as specified
622 if val==L["on"] then
623 newval = true
624 elseif val==L["off"] then
625 newval = false
626 elseif val==L["default"] then
627 newval = nil
628 end
629 end
630
631 do_final(info, inputpos, tab, "set", opt, newval)
632 end
633
634
635 elseif tab.type=="color" then
636 ------------ color --------------------------------------------
637 local str = strtrim(strlower(str))
638 if str == "" then
639 --TODO: Show current value
640 return
641 end
642
643 local r, g, b, a
644
645 if tab.hasAlpha then
646 if str:len() == 8 and str:find("^%x*$") then
647 --parse a hex string
648 r,g,b,a = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255, tonumber(str:sub(7, 8), 16) / 255
649 else
650 --parse seperate values
651 r,g,b,a = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+) ([%d%.]+)$")
652 r,g,b,a = tonumber(r), tonumber(g), tonumber(b), tonumber(a)
653 end
654 if not (r and g and b and a) then
655 usererr(info, inputpos, format(L["'%s' - expected 'RRGGBBAA' or 'r g b a'."], str))
656 return
657 end
658
659 if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 and a >= 0.0 and a <= 1.0 then
660 --values are valid
661 elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 and a >= 0 and a <= 255 then
662 --values are valid 0..255, convert to 0..1
663 r = r / 255
664 g = g / 255
665 b = b / 255
666 a = a / 255
667 else
668 --values are invalid
669 usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0..1 or 0..255."], str))
670 end
671 else
672 a = 1.0
673 if str:len() == 6 and str:find("^%x*$") then
674 --parse a hex string
675 r,g,b = tonumber(str:sub(1, 2), 16) / 255, tonumber(str:sub(3, 4), 16) / 255, tonumber(str:sub(5, 6), 16) / 255
676 else
677 --parse seperate values
678 r,g,b = str:match("^([%d%.]+) ([%d%.]+) ([%d%.]+)$")
679 r,g,b = tonumber(r), tonumber(g), tonumber(b)
680 end
681 if not (r and g and b) then
682 usererr(info, inputpos, format(L["'%s' - expected 'RRGGBB' or 'r g b'."], str))
683 return
684 end
685 if r >= 0.0 and r <= 1.0 and g >= 0.0 and g <= 1.0 and b >= 0.0 and b <= 1.0 then
686 --values are valid
687 elseif r >= 0 and r <= 255 and g >= 0 and g <= 255 and b >= 0 and b <= 255 then
688 --values are valid 0..255, convert to 0..1
689 r = r / 255
690 g = g / 255
691 b = b / 255
692 else
693 --values are invalid
694 usererr(info, inputpos, format(L["'%s' - values must all be either in the range 0-1 or 0-255."], str))
695 end
696 end
697
698 do_final(info, inputpos, tab, "set", r,g,b,a)
699
700 elseif tab.type=="keybinding" then
701 ------------ keybinding --------------------------------------------
702 local str = strtrim(strlower(str))
703 if str == "" then
704 --TODO: Show current value
705 return
706 end
707 local value = keybindingValidateFunc(str:upper())
708 if value == false then
709 usererr(info, inputpos, format(L["'%s' - Invalid Keybinding."], str))
710 return
711 end
712
713 do_final(info, inputpos, tab, "set", value)
714
715 elseif tab.type=="description" then
716 ------------ description --------------------
717 -- ignore description, GUI config only
718 else
719 err(info, inputpos, "unknown options table item type '"..tostring(tab.type).."'")
720 end
721 end
722
723 --- Handle the chat command.
724 -- This is usually called from a chat command handler to parse the command input as operations on an aceoptions table.\\
725 -- AceConfigCmd uses this function internally when a slash command is registered with `:CreateChatCommand`
726 -- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
727 -- @param appName The application name as given to `:RegisterOptionsTable()`
728 -- @param input The commandline input (as given by the WoW handler, i.e. without the command itself)
729 -- @usage
730 -- MyAddon = LibStub("AceAddon-3.0"):NewAddon("MyAddon", "AceConsole-3.0")
731 -- -- Use AceConsole-3.0 to register a Chat Command
732 -- MyAddon:RegisterChatCommand("mychat", "ChatCommand")
733 --
734 -- -- Show the GUI if no input is supplied, otherwise handle the chat input.
735 -- function MyAddon:ChatCommand(input)
736 -- -- Assuming "MyOptions" is the appName of a valid options table
737 -- if not input or input:trim() == "" then
738 -- LibStub("AceConfigDialog-3.0"):Open("MyOptions")
739 -- else
740 -- LibStub("AceConfigCmd-3.0").HandleCommand(MyAddon, "mychat", "MyOptions", input)
741 -- end
742 -- end
743 function AceConfigCmd:HandleCommand(slashcmd, appName, input)
744
745 local optgetter = cfgreg:GetOptionsTable(appName)
746 if not optgetter then
747 error([[Usage: HandleCommand("slashcmd", "appName", "input"): 'appName' - no options table "]]..tostring(appName)..[[" has been registered]], 2)
748 end
749 local options = assert( optgetter("cmd", MAJOR) )
750
751 local info = { -- Don't try to recycle this, it gets handed off to callbacks and whatnot
752 [0] = slashcmd,
753 appName = appName,
754 options = options,
755 input = input,
756 self = self,
757 handler = self,
758 uiType = "cmd",
759 uiName = MAJOR,
760 }
761
762 handle(info, 1, options, 0) -- (info, inputpos, table, depth)
763 end
764
765 --- Utility function to create a slash command handler.
766 -- Also registers tab completion with AceTab
767 -- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
768 -- @param appName The application name as given to `:RegisterOptionsTable()`
769 function AceConfigCmd:CreateChatCommand(slashcmd, appName)
770 if not AceConsole then
771 AceConsole = LibStub(AceConsoleName)
772 end
773 if AceConsole.RegisterChatCommand(self, slashcmd, function(input)
774 AceConfigCmd.HandleCommand(self, slashcmd, appName, input) -- upgradable
775 end,
776 true) then -- succesfully registered so lets get the command -> app table in
777 commands[slashcmd] = appName
778 end
779 end
780
781 --- Utility function that returns the options table that belongs to a slashcommand.
782 -- Designed to be used for the AceTab interface.
783 -- @param slashcmd The slash command WITHOUT leading slash (only used for error output)
784 -- @return The options table associated with the slash command (or nil if the slash command was not registered)
785 function AceConfigCmd:GetChatCommandOptions(slashcmd)
786 return commands[slashcmd]
787 end