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.
303 lines
7.5 KiB
303 lines
7.5 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]
|
|
if not opts.owner ~= not owner and v ~= 'round' 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, LE_BATTLE_PET_ALLY, C_PetBattles.GetActivePet(LE_BATTLE_PET_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, LE_BATTLE_PET_ALLY))
|
|
end
|
|
|
|
Snippets.Condition.enemy = function(list)
|
|
return fillPet(list, LE_BATTLE_PET_ENEMY)
|
|
end
|
|
|
|
Snippets.Condition.ally = function(list)
|
|
return fillPet(list, LE_BATTLE_PET_ALLY)
|
|
end
|
|
|
|
Snippets.Condition.self = Snippets.Condition.ally
|
|
|
|
Snippets.Condition.weather = function(list)
|
|
local weathers = { 596, 590, 229, 403, 171, 205, 718, 257, 454 }
|
|
|
|
-- 596 月光
|
|
-- 590 奥术之风
|
|
-- 229 净化之雨
|
|
-- 403 晴天
|
|
-- 171 灼燃大地
|
|
-- 205 暴风雪
|
|
-- 718 泥石流
|
|
-- 257 黑暗
|
|
-- 454 沙尘暴
|
|
|
|
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
|
|
|