diff Libs/AceConsole-3.0/AceConsole-3.0.lua @ 57:01b63b8ed811 v21

total rewrite to version 21
author yellowfive
date Fri, 05 Jun 2015 11:05:15 -0700
parents
children e635cd648e01
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Libs/AceConsole-3.0/AceConsole-3.0.lua	Fri Jun 05 11:05:15 2015 -0700
@@ -0,0 +1,250 @@
+--- **AceConsole-3.0** provides registration facilities for slash commands.
+-- You can register slash commands to your custom functions and use the `GetArgs` function to parse them
+-- to your addons individual needs.
+--
+-- **AceConsole-3.0** can be embeded into your addon, either explicitly by calling AceConsole:Embed(MyAddon) or by 
+-- specifying it as an embeded library in your AceAddon. All functions will be available on your addon object
+-- and can be accessed directly, without having to explicitly call AceConsole itself.\\
+-- It is recommended to embed AceConsole, otherwise you'll have to specify a custom `self` on all calls you
+-- make into AceConsole.
+-- @class file
+-- @name AceConsole-3.0
+-- @release $Id: AceConsole-3.0.lua 878 2009-11-02 18:51:58Z nevcairiel $
+local MAJOR,MINOR = "AceConsole-3.0", 7
+
+local AceConsole, oldminor = LibStub:NewLibrary(MAJOR, MINOR)
+
+if not AceConsole then return end -- No upgrade needed
+
+AceConsole.embeds = AceConsole.embeds or {} -- table containing objects AceConsole is embedded in.
+AceConsole.commands = AceConsole.commands or {} -- table containing commands registered
+AceConsole.weakcommands = AceConsole.weakcommands or {} -- table containing self, command => func references for weak commands that don't persist through enable/disable
+
+-- Lua APIs
+local tconcat, tostring, select = table.concat, tostring, select
+local type, pairs, error = type, pairs, error
+local format, strfind, strsub = string.format, string.find, string.sub
+local max = math.max
+
+-- WoW APIs
+local _G = _G
+
+-- Global vars/functions that we don't upvalue since they might get hooked, or upgraded
+-- List them here for Mikk's FindGlobals script
+-- GLOBALS: DEFAULT_CHAT_FRAME, SlashCmdList, hash_SlashCmdList
+
+local tmp={}
+local function Print(self,frame,...)
+	local n=0
+	if self ~= AceConsole then
+		n=n+1
+		tmp[n] = "|cff33ff99"..tostring( self ).."|r:"
+	end
+	for i=1, select("#", ...) do
+		n=n+1
+		tmp[n] = tostring(select(i, ...))
+	end
+	frame:AddMessage( tconcat(tmp," ",1,n) )
+end
+
+--- Print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
+-- @paramsig [chatframe ,] ...
+-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
+-- @param ... List of any values to be printed
+function AceConsole:Print(...)
+	local frame = ...
+	if type(frame) == "table" and frame.AddMessage then	-- Is first argument something with an .AddMessage member?
+		return Print(self, frame, select(2,...))
+	else
+		return Print(self, DEFAULT_CHAT_FRAME, ...)
+	end
+end
+
+
+--- Formatted (using format()) print to DEFAULT_CHAT_FRAME or given ChatFrame (anything with an .AddMessage function)
+-- @paramsig [chatframe ,] "format"[, ...]
+-- @param chatframe Custom ChatFrame to print to (or any frame with an .AddMessage function)
+-- @param format Format string - same syntax as standard Lua format()
+-- @param ... Arguments to the format string
+function AceConsole:Printf(...)
+	local frame = ...
+	if type(frame) == "table" and frame.AddMessage then	-- Is first argument something with an .AddMessage member?
+		return Print(self, frame, format(select(2,...)))
+	else
+		return Print(self, DEFAULT_CHAT_FRAME, format(...))
+	end
+end
+
+
+
+
+--- Register a simple chat command
+-- @param command Chat command to be registered WITHOUT leading "/"
+-- @param func Function to call when the slash command is being used (funcref or methodname)
+-- @param persist if false, the command will be soft disabled/enabled when aceconsole is used as a mixin (default: true)
+function AceConsole:RegisterChatCommand( command, func, persist )
+	if type(command)~="string" then error([[Usage: AceConsole:RegisterChatCommand( "command", func[, persist ]): 'command' - expected a string]], 2) end
+	
+	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
+	
+	local name = "ACECONSOLE_"..command:upper()
+	
+	if type( func ) == "string" then
+		SlashCmdList[name] = function(input, editBox)
+			self[func](self, input, editBox)
+		end
+	else
+		SlashCmdList[name] = func
+	end
+	_G["SLASH_"..name.."1"] = "/"..command:lower()
+	AceConsole.commands[command] = name
+	-- non-persisting commands are registered for enabling disabling
+	if not persist then
+		if not AceConsole.weakcommands[self] then AceConsole.weakcommands[self] = {} end
+		AceConsole.weakcommands[self][command] = func
+	end
+	return true
+end
+
+--- Unregister a chatcommand
+-- @param command Chat command to be unregistered WITHOUT leading "/"
+function AceConsole:UnregisterChatCommand( command )
+	local name = AceConsole.commands[command]
+	if name then
+		SlashCmdList[name] = nil
+		_G["SLASH_" .. name .. "1"] = nil
+		hash_SlashCmdList["/" .. command:upper()] = nil
+		AceConsole.commands[command] = nil
+	end
+end
+
+--- Get an iterator over all Chat Commands registered with AceConsole
+-- @return Iterator (pairs) over all commands
+function AceConsole:IterateChatCommands() return pairs(AceConsole.commands) end
+
+
+local function nils(n, ...)
+	if n>1 then
+		return nil, nils(n-1, ...)
+	elseif n==1 then
+		return nil, ...
+	else
+		return ...
+	end
+end
+	
+
+--- Retreive one or more space-separated arguments from a string. 
+-- Treats quoted strings and itemlinks as non-spaced.
+-- @param string The raw argument string
+-- @param numargs How many arguments to get (default 1)
+-- @param startpos Where in the string to start scanning (default  1)
+-- @return Returns arg1, arg2, ..., nextposition\\
+-- Missing arguments will be returned as nils. 'nextposition' is returned as 1e9 at the end of the string.
+function AceConsole:GetArgs(str, numargs, startpos)
+	numargs = numargs or 1
+	startpos = max(startpos or 1, 1)
+	
+	local pos=startpos
+
+	-- find start of new arg
+	pos = strfind(str, "[^ ]", pos)
+	if not pos then	-- whoops, end of string
+		return nils(numargs, 1e9)
+	end
+
+	if numargs<1 then
+		return pos
+	end
+
+	-- quoted or space separated? find out which pattern to use
+	local delim_or_pipe
+	local ch = strsub(str, pos, pos)
+	if ch=='"' then
+		pos = pos + 1
+		delim_or_pipe='([|"])'
+	elseif ch=="'" then
+		pos = pos + 1
+		delim_or_pipe="([|'])"
+	else
+		delim_or_pipe="([| ])"
+	end
+	
+	startpos = pos
+	
+	while true do
+		-- find delimiter or hyperlink
+		local ch,_
+		pos,_,ch = strfind(str, delim_or_pipe, pos)
+		
+		if not pos then break end
+		
+		if ch=="|" then
+			-- some kind of escape
+			
+			if strsub(str,pos,pos+1)=="|H" then
+				-- It's a |H....|hhyper link!|h
+				pos=strfind(str, "|h", pos+2)	-- first |h
+				if not pos then break end
+				
+				pos=strfind(str, "|h", pos+2)	-- second |h
+				if not pos then break end
+			elseif strsub(str,pos, pos+1) == "|T" then
+				-- It's a |T....|t  texture
+				pos=strfind(str, "|t", pos+2)
+				if not pos then break end
+			end
+			
+			pos=pos+2 -- skip past this escape (last |h if it was a hyperlink)
+		
+		else
+			-- found delimiter, done with this arg
+			return strsub(str, startpos, pos-1), AceConsole:GetArgs(str, numargs-1, pos+1)
+		end
+		
+	end
+	
+	-- search aborted, we hit end of string. return it all as one argument. (yes, even if it's an unterminated quote or hyperlink)
+	return strsub(str, startpos), nils(numargs-1, 1e9)
+end
+
+
+--- embedding and embed handling
+
+local mixins = {
+	"Print",
+	"Printf",
+	"RegisterChatCommand", 
+	"UnregisterChatCommand",
+	"GetArgs",
+} 
+
+-- Embeds AceConsole into the target object making the functions from the mixins list available on target:..
+-- @param target target object to embed AceBucket in
+function AceConsole:Embed( target )
+	for k, v in pairs( mixins ) do
+		target[v] = self[v]
+	end
+	self.embeds[target] = true
+	return target
+end
+
+function AceConsole:OnEmbedEnable( target )
+	if AceConsole.weakcommands[target] then
+		for command, func in pairs( AceConsole.weakcommands[target] ) do
+			target:RegisterChatCommand( command, func, false, true ) -- nonpersisting and silent registry
+		end
+	end
+end
+
+function AceConsole:OnEmbedDisable( target )
+	if AceConsole.weakcommands[target] then
+		for command, func in pairs( AceConsole.weakcommands[target] ) do
+			target:UnregisterChatCommand( command ) -- TODO: this could potentially unregister a command from another application in case of command conflicts. Do we care?
+		end
+	end
+end
+
+for addon in pairs(AceConsole.embeds) do
+	AceConsole:Embed(addon)
+end