local _,builtin_standards=pcall(require, "luacheck.builtin_standards")
local macroCheck = {
[Area or 1]=1, [APanel or 1]=1, [PPanel or 1]=1, [CmdLine or 1]=1,
[Dlg or 1]=1, [Drv or 1]=1, [Editor or 1]=1, [Far or 1]=1, [Help or 1]=1,
[Menu or 1]=1, [Mouse or 1]=1, [Object or 1]=1, [Viewer or 1]=1,
}
Macro{
-- id="";
area="Editor";
key="CtrlShiftSpace";
description="Подстановка известных слов";
filemask="*.lua,*.moon,*.fmlua";
flags="";
-- priority=50;
-- sortpriority=50;
-- condition=function(key) return true end;
action=function()
local function _aiFind(tbl, sample)
for _,w in ipairs(tbl) do
if (type(w) == type(sample)) and
(w == sample) then
return true
end
end
end
local xWas, asCurr={}, {}
local function AddPath(t, pref, nn, vv, subfield)
local s
if nn ~= '' then
s=(pref=='' and '' or pref..'.') .. nn
t[#t+1] = s
else
s = ''
end
if type(vv) == 'table' and not _aiFind(xWas, vv) then
xWas[#xWas+1] = vv
if subfield and vv[subfield] then
for n,v in pairs(vv[subfield]) do
AddPath(t, s, n, v, subfield)
end
if macroCheck[vv[subfield]] and vv[subfield].properties then
for n,v in pairs(vv[subfield].properties) do
AddPath(t, s, n, v)
end
end
else
for n,v in pairs(vv) do
AddPath(t, s, n, v)
end
if macroCheck[vv] and vv.properties then
for n, v in pairs(vv.properties) do
AddPath(t, s, n, v)
end
end
end
end
end
AddPath(asCurr, '', '', _G, nil)
if type(builtin_standards) == 'table' then
AddPath(asCurr, '', '', builtin_standards.max.read_globals, 'fields')
end
table.sort(asCurr)
for i=#asCurr,2,-1 do
if asCurr[i] == asCurr[i-1] then
table.remove(asCurr, i)
end
end
-- Вычленение текста
local Str, xPos=Editor.GetStr(), Editor.RealPos
local Str1=Str:sub(1,xPos-1)
local ForSearch
if Str1:sub(-1) == '.' then -- Кончается на точку
ForSearch = Str1:match('.-([%w%d_%.]+)%.$') ..'.'
else
ForSearch=(Str1:match('.-([%w%d_%.]+)$') or '') --..(Str2:match('[%w%d_]*') or '')
end
-- Тут: ForSearch - Строка для поиска;
-- Поиск по сортированному массиву
local items={}
local function FillMenu(ForSearch, Title)
local i0, i1, i=1,#asCurr
i = math.floor((i1+i0)/2)
while i1 > i0 + 1 do
if asCurr[i] < ForSearch then
i0 = i
elseif asCurr[i] > ForSearch then
i1 = i
else
break
end
i = math.floor((i1+i0)/2)
end
if i > 1 and asCurr[i]:sub(1,ForSearch:len()) < ForSearch then i = i + 1 end
local bWas=false
local Tail
local Last=''
for j=i,#asCurr do
if asCurr[j]:sub(1,ForSearch:len()) == ForSearch then -- Начинается с искомого
if not bWas or asCurr[j]:sub(1,Last:len()) ~= Last then
-- Сверяю с предыдущим, чтоб не было повтора
Tail = asCurr[j]:sub(ForSearch:len())
if Tail:sub(1,1) == '.' then Tail = Tail:sub(2) end
if Tail:gsub('[^.]',''):len() <= 1 then -- Не более одной точки после найденной
if not bWas and Title then
items[#items+1] = {text=Title; separator=true}
bWas = true
end
items[#items+1] = {text=asCurr[j]:match('[^.]-$')}
items[#items].result = asCurr[j]:sub(ForSearch:len()+1)
Last = asCurr[j] .. '.'
end
end
elseif asCurr[j]:sub(1,ForSearch:len()) > ForSearch then
break
end
end
end -- FillMenu
if not ForSearch:match('%.') then
-- Если в искомой строке нет точки - добавлю ключевые слова
FillMenu('package.loaded.moonscript.data.lua_keywords.'..ForSearch, 'Ключевые слова LUA')
end
FillMenu(ForSearch,'Таблицы, функции:')
if #items > 0 then
local _,Ch= far.Menu({Title="Выберите элемент для вставки"}, items)
if Ch then
print(items[Ch].result or items[Ch].text)
end
end
end;
}