You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

313 lines
8.2 KiB

--[[
Snippets.lua
@Author : DengSir (tdaddon@163.com)
@Link : https://dengsir.github.io
]]
local ns = select(2, ...)
local Addon = ns.Addon
local Util = ns.Util
local Condition = ns.Condition
local Snippets = {} ns.Snippets = Snippets
do
local function factory(opts)
local words = opts.words or {}
local filter = opts.filter
if opts.extend then
local set = {}
local function add(k)
if set[k] then return end
set[k] = true
tinsert(words, k)
end
for k in pairs(opts.extend) do
add(strsplit('.', k))
add(k)
end
end
sort(words)
local function callback(item)
return tinsert(words, 1, table.remove(words, item.index))
end
local function default(list, word, ...)
if not word then
return
end
local front, tail
local len = #word
for i, v in ipairs(words) do
if v ~= word then
front = v:sub(1, len)
if front == word and (not filter or filter(v, word, ...)) then
tail = v:sub(len + 1)
tinsert(list, {
text = format('|cff00ff00%s|r%s', front, tail),
value = tail,
callback = callback,
index = i,
})
end
end
end
return 1
end
return {
__default = default,
}
end
Snippets.Condition = factory({
extend = Condition.apis,
filter = function(v, word, owner, pet, arg, non, petInputed, argInputed)
if not Condition.apis[v] then
return true
end
local opts = Condition.opts[v]
local requiresOwner = opts.owner == 'required'
local forbidsOwner = opts.owner == 'not-allowed'
local hasOwner = not not owner
if (requiresOwner and not hasOwner) or (forbidsOwner and hasOwner) then
return false
end
if opts.pet and not pet then
return false
end
if not opts.pet and petInputed then
return false
end
if non and opts.type ~= 'boolean' then
return false
end
if not opts.arg and argInputed then
return false
end
local len = #word
local pos = v:find('.', nil, true)
if opts.arg and not argInputed and pos and len >= pos then
return false
end
if pos and pos > len then
return false
end
return true
end
})
Snippets.Action = factory({
words = { 'if', 'endif' },
extend = ns.Action.apis,
})
Snippets.Target = factory({
words = { 'self', 'enemy', 'ally' }
})
end
function Snippets:Check(line)
local list, column = {}
local condition = line:match('[[&]%s*([^&[]+)$')
if condition then
local owner, pet, word, arg, non, petInputed, argInputed = self:ParseCondition(condition)
word = word or line:match('(%w+)$')
if not word then
return
end
if not owner then
self.Target.__default(list, word)
end
if arg or not self.Condition[word] then
column = self.Condition.__default(list, word, owner, pet, arg, non, petInputed, argInputed)
else
column = self.Condition[word](list, word, owner, pet)
end
else
word = line:match('^%s*(%w+)$')
if not word then
return
end
if not self.Action[word] then
column = self.Action.__default(list, word)
else
column = self.Action[word](list, word)
end
end
if not column or #list == 0 then
return
end
return list, column
end
function Snippets:ParseCondition(condition)
if not condition then
return
end
local non do
local _cond
non, _cond = condition:match('^(!?)%s*(.+)$')
non = non == '!'
if non then
condition = _cond
end
end
local owner, pet, cmd, arg, petInputed, argInputed = Condition:ParseApi(condition)
return owner, pet, cmd, arg, non, petInputed, argInputed
end
local empty = {}
local function tfillrow(t, column)
for i = 1, column - #t % column do
tinsert(t, empty)
end
end
local function makeNameSnippet(name, id)
return {
text = name,
value = format('(%s:%d)', name, id),
}
end
local function makeIndexSnippet(index)
return {
text = format('#%d', index),
value = format('(#%d)', index),
}
end
local function makeIconSnippet(icon)
return {
icon = icon
}
end
local function fillAbility(list, owner, pet)
for i = 1, NUM_BATTLE_PET_ABILITIES do
local id, name, icon = C_PetBattles.GetAbilityInfo(owner, pet, i)
if id then
tinsert(list, makeIconSnippet(icon))
tinsert(list, makeNameSnippet(name, id))
tinsert(list, makeIndexSnippet(i))
end
end
return 3
end
local function fillPet(list, owner)
for i = 1, C_PetBattles.GetNumPets(owner) do
local name = C_PetBattles.GetName(owner, i)
local icon = C_PetBattles.GetIcon(owner, i)
local id = C_PetBattles.GetPetSpeciesID(owner, i)
tinsert(list, makeIconSnippet(icon))
tinsert(list, makeNameSnippet(name, id))
tinsert(list, makeIndexSnippet(i))
end
return 3
end
Snippets.Action.use = function(list)
return fillAbility(list, Enum.BattlePetOwner.Ally, C_PetBattles.GetActivePet(Enum.BattlePetOwner.Ally))
end
Snippets.Action.ability = Snippets.Action.use
local function fillNext(list, column)
tinsert(list, empty)
tinsert(list, {
text = 'next',
value = '(next)',
})
tfillrow(list, column)
return column
end
Snippets.Action.change = function(list)
return fillNext(list, fillPet(list, Enum.BattlePetOwner.Ally))
end
Snippets.Condition.enemy = function(list)
return fillPet(list, Enum.BattlePetOwner.Enemy)
end
Snippets.Condition.ally = function(list)
return fillPet(list, Enum.BattlePetOwner.Ally)
end
Snippets.Condition.self = Snippets.Condition.ally
Snippets.Condition.weather = function(list)
local weathers = {
171, -- Weather_BurntEarth
590, -- Weather_ArcaneStorm
596, -- Weather_Moonlight
257, -- Weather_Darkness
454, -- Weather_Sandstorm
205, -- Weather_Blizzard
718, -- Weather_Mud
229, -- Weather_Rain
403, -- Weather_Sunlight
203, -- Weather_LightningStorm
2320, -- Weather_LightningStorm
---, -- Weather_Windy
2350, -- Weather_Toxic_Gas
}
for i, id in ipairs(weathers) do
local id, name, icon = C_PetBattles.GetAbilityInfoByID(id)
tinsert(list, makeIconSnippet(icon))
tinsert(list, makeNameSnippet(name, id))
end
return 2
end
Snippets.Condition.aura = function(list, word, owner, pet)
if not owner or not pet then
return
end
for _, pet in ipairs({pet, PET_BATTLE_PAD_INDEX}) do
for i = 1, C_PetBattles.GetNumAuras(owner, pet) do
local id, name, icon = C_PetBattles.GetAbilityInfoByID(C_PetBattles.GetAuraInfo(owner, pet, i))
tinsert(list, makeIconSnippet(icon))
tinsert(list, makeNameSnippet(name, id))
end
end
return 2
end
Snippets.Condition.ability = function(list, word, owner, pet)
return fillAbility(list, owner, pet)
end
Snippets.Condition.is = function(list, word, owner, pet)
return fillPet(list, owner)
end