Latest post of the previous page:
Если плагин будет, это хорошо. А то количество макросов скоро зашкалит за все разумные пределыyms wrote:В принципе я собирался плагин на 3.0 перевести...
так шо, уже неактуально?
А пока очередная серия версия с диалоговой процедурой от zg, с обработкой пробела (был забыт), отключением перемещения курсора при щёлканьи мышью по строке ввода, с выполнением макросов, после закрытия диалога и пр. и пр.
Code: Select all
-- Description Fast Find
-- Замена для плагина DESCSS
local DFF_ID = "83689A78-99EA-4B01-98DE-ED8135140B20"
local DFF_GUID = win.Uuid(DFF_ID)
local F=far.Flags
local dff_hdlg
local dff_mask = ""
-- Заменить текст маски в поле ввода
local function dff_print(text)
far.SendDlgMessage(dff_hdlg,F.DM_SETTEXT,1,text)
end
-- Перерисовка диалога
local function dff_redraw()
far.SendDlgMessage(dff_hdlg,F.DM_REDRAW,0,0)
end
-- Сравнение описания файла по маске
local function dff_match(mask,diz)
-- при сравнении, в конец маски добавляем символ *, если его там нет
return mf.fmatch(diz,(mask:sub(-1)~="*") and (mask.."*") or mask) == 1
end
-- Сравнение описания файла с номером index по маске
local function dff_imatch(mask,index)
return dff_match(mask,Panel.Item(0,index,11))
end
-- Попытка найти следующее совпадение.
-- При успехе возвращаем индекс найденного файла, иначе - 0.
local function dff_next(mask)
local current = Panel.SetPosIdx(0,0)
local diz
-- со следующего и до конца
for index=current+1, APanel.ItemCount do
diz = Panel.Item(0,index,11)
if diz:len() > 0 then
if dff_match(mask,diz) then
return index
end
end
end
-- с первого до текущего (или лучше только до предыдущего?)
for index=1, current do
diz = Panel.Item(0,index,11)
if diz:len() > 0 then
if dff_match(mask,diz) then
return index
end
end
end
return 0
end
-- Попытка найти предыдущее совпадение
-- При успехе возвращаем индекс найденного файла, иначе - 0.
local function dff_prev(mask)
local current = Panel.SetPosIdx(0,0)
local diz
-- с предыдущего и до начала
for index=current-1, 1, -1 do
diz = Panel.Item(0,index,11)
if diz:len() > 0 then
if dff_match(mask,diz) then
return index
end
end
end
-- с последнего до текущего (или лучше только до следующего?)
for index=APanel.ItemCount, current, -1 do
diz = Panel.Item(0,index,11)
if diz:len() > 0 then
if dff_match(mask,diz) then
return index
end
end
end
return 0
end
-- Добавление одного символа к маске
local function dff_char(char)
local new_mask = dff_mask .. char
local index
if dff_imatch(new_mask,0) then
-- Если маска совпадает с описанием текущего файла, никуда не перемещаемся
dff_mask = new_mask
dff_print(dff_mask)
else
index = dff_next(new_mask) -- следующее совпадение или 0
if index > 0 then
-- Если есть совпадение - переход,
-- иначе символ никак не обрабатываем
dff_mask = new_mask
dff_print(dff_mask)
Panel.SetPosIdx(0,index)
dff_redraw()
end
end
end
-- Добавление нескольких символов к маске
local function dff_chars(chars)
local new_mask = dff_mask
local index
for i=1, chars:len() do
new_mask = new_mask .. chars:sub(i,i)
if dff_imatch(new_mask,0) then
-- Если маска совпадает с описанием текущего файла,
-- никуда не перемещаемся
dff_mask = new_mask
else
index = dff_next(new_mask)
if index > 0 then
dff_mask = new_mask
Panel.SetPosIdx(0,index)
else
-- если очередной символ добавить не удалось, заканчиваем вставку
break
end
end
end
dff_print(dff_mask)
dff_redraw()
return
end
-- Создаём диалог
local function dff_dialog(dlg_init)
local dlg_wid = 20 -- ширина строки ввода
local dlg_x1 = APanel.Left and 2 or PPanel.Width+2
local dlg_x2 = dlg_x1 + dlg_wid + 2
local dlg_y1 = APanel.Height - 1
local dlg_y2 = dlg_y1 + 2
local exit_key = false
if Area.Search then
Keys "Esc"
end
dff_mask = dlg_init
local dlg_items =
{ -- X1,Y1,X2,Y2,_,sHistory,sMask,Flags,sData,...
{F.DI_DOUBLEBOX,0,0,dlg_wid+1,2,0,0,0,0,"Description"}, -- 00
{F.DI_EDIT, 1,1,dlg_wid ,1,0,0,0,0,dff_mask}, -- 01
}
local function dlg_proc(hDlg,Msg,Param1,Param2)
if Msg==F.DN_INITDIALOG then
-- dff_hdlg = hDlg
local dlg_focus=far.SendDlgMessage(dff_hdlg,F.DM_GETFOCUS,0,0)
far.SendDlgMessage(dff_hdlg,F.DM_EDITUNCHANGEDFLAG,dlg_focus,0)
return false
elseif Msg==F.DN_CONTROLINPUT and Param1==1 and Param2.EventType==F.MOUSE_EVENT then
-- отключаем события мыши
return true
elseif Msg==F.DN_CONTROLINPUT and Param1==1 and Param2.EventType==F.KEY_EVENT and Param2.KeyDown then
--local a = mf.replace(far.InputRecordToName(Param2),"R?((Ctrl|Alt|Shift))","$1")
local k = far.InputRecordToName(Param2) -- клавиша "as is"
local a = k:gsub("[RL]Ctrl","Ctrl"):gsub("[RL]Alt","Alt") -- для упрощения проверки
local mask = ""
local index, clp
if a:len()==1 then
-- Введён один символ
dff_char(a)
elseif a=="Space" or a=="ShiftSpace" then
dff_char(" ")
elseif a=="BS" then
-- Удаление последнего символа,
-- перемещатся после этого не надо.
if dff_mask:len() > 0 then
dff_mask = dff_mask:sub(1,-2)
dff_print(dff_mask)
end
elseif a=="Left" or a=="Right" then
elseif a=="Ctrl" or a=="Alt" or a=="Shift" then
-- Ничего не делаем
elseif a=="CtrlEnter" then
-- Перемещение к следующему совпадению
if dff_mask:len() > 0 then
-- При непустой маске ищем следующее совпадение
index = dff_next(dff_mask)
if index > 0 then
Panel.SetPosIdx(0,index)
end
else
-- При пустой маске просто перемещаемся на следующий файл
if APanel.Eof then
Panel.SetPosIdx(0,1)
else
Panel.SetPosIdx(0,Panel.SetPosIdx(0,0)+1)
end
end
dff_redraw()
elseif a=="CtrlShiftEnter" then
-- Перемещение к предыдущему совпадению
if dff_mask:len() > 0 then
-- При непустой маске ищем предыдущее совпадение
index = dff_prev(dff_mask)
if index > 0 then
Panel.SetPosIdx(0,index)
end
else
-- При пустой маске просто перемещаемся на предыдущий файл
if APanel.Bof then
Panel.SetPosIdx(0,-1)
else
Panel.SetPosIdx(0,Panel.SetPosIdx(0,0)-1)
end
end
dff_redraw()
--elseif a=="Ins" then
-- Выделить и перейти к следующему
elseif a=="CtrlV" or a=="ShiftIns" then
-- Вставка
clp = mf.clip(0)
if type(clp)=="string" and clp:len()>0 then
dff_chars(clp)
end
elseif a=="Esc" or a =="CtrlY" or a=="CtrlX" or a=="CtrlC" then
-- для обработки возвращаем управление ФАРу
return false
else
exit_key = k
far.SendDlgMessage(hDlg,F.DM_CLOSE)
end
return true
end
end
local dlg_flags = F.FDLG_KEEPCONSOLETITLE + F.FDLG_NODRAWSHADOW + F.FDLG_SMALLDIALOG
dff_hdlg = far.DialogInit(DFF_GUID,dlg_x1,dlg_y1,dlg_x2,dlg_y2,"",dlg_items,dlg_flags,dlg_proc)
far.DialogRun(dff_hdlg)
far.DialogFree(dff_hdlg)
if exit_key then
if eval(exit_key,2)==-2 then
Keys(exit_key)
end
end
end
-- Условие для макросов
local function dff_condition()
return (Dlg.Id == DFF_ID)
end;
-- Макросы вызова
Macro { area="Shell Search"; key="AltShiftD Alt,"; flags="";
description="Description Fast Find";
action=function() dff_dialog("") end;
}
Macro { area="Shell Search"; key="AltSpace Alt."; flags="";
description="Description Fast Find";
action=function() dff_dialog("*") end;
}
На этом фантазия пока закончилась...
Может только обработку каких клавиш пропустил