Макросы для работы с описаниями файлов

Здесь выкладываются готовые к использованию макросы и скрипты.
Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Макросы для работы с описаниями файлов

Post by Smitis » Wed 20 Feb, 2013 21:54

Макросы для замены плагина DESCSS

Плагин DESCSS позволял выполнять некоторые действия с описаниями файлов как с именами файлов, а именно
- установка и снятия пометки по маске аналогично NumPad+ (Grey+) и NumPad- (Grey-) используя вместо имён файлов описания,
- быстрый поиск файлов аналогично Alt-символ в панелях (Quick Search, он же Fast Find) используя, опять-таки, описания вместо имён файлов.
Так как плагин DESCSS не работает под FAR3, были написаны макросы для его замены.
  1. --[=[ ----------------------------------------------------------------------------------------------
  2. Макросы для замены плагина DESCSS
  3. v.1.06 (C) 2013-2016 Smitis
  4. http://forum.farmanager.com/viewtopic.php?t=7846
  5. --]=] ----------------------------------------------------------------------------------------------
  6.  
  7. ----------------------------------------------------------------------------------------------------
  8. -- Настройки. Персональные настройки можно держать в файле DescSS.cfg (см. пример DescSS.example.cfg)
  9. ----------------------------------------------------------------------------------------------------
  10.  
  11. local cfg = {}
  12. -- Внимание! Используемый здесь AltSpace работает при наличие плагина XKeys.
  13. -- ДЛЯ ОТКЛЮЧЕНИЯ МАКРОСОВ И ГОРЯЧИХ КЛАВИШ ОСТАВИТЬ СТРОКУ ПУСТОЙ!
  14. cfg.sample = "" -- Пример: так отключать макросы
  15.  
  16. -- Макросы для установки/снятия пометки
  17. cfg.dss_sel   = "AltShiftS" -- макрос Select
  18. cfg.dss_unsel = "AltShiftU" -- макрос Unselect
  19. cfg.dss_fill  = "AltShiftD" -- макрос Select with init
  20. cfg.dss_post  = "* * Left" -- иницилизация маски для предыдущего макроса (макропоследовательность!)
  21.  
  22. -- Макросы быстрого поиска
  23. cfg.dff_empty = "Alt," -- открыть пустой диалог
  24. cfg.dff_fill  = "AltSpace" -- открыть непустой диалог
  25. cfg.dff_text  = "*" -- иницилизация непустого диалога для предыдущего макроса (текст!)
  26.  
  27. -- Диалоговая процедура быстрого поиска.
  28. -- Правые и левые модификаторы не проверяются для упрощения обработки!
  29. -- Несколько комбинаций перечисляются через пробел, регэкспы не поддерживаются.
  30. cfg.dff_next   = "CtrlEnter CtrlNumEnter CtrlDown" -- следующее совпадение
  31. cfg.dff_prev   = "CtrlShiftEnter CtrlShiftNumEnter CtrlUp" -- предыдущее совпадение
  32. cfg.dff_last   = "CtrlEnd" -- последнее совпадение
  33. cfg.dff_first  = "CtrlHome" -- первое совпадение
  34. cfg.dff_invert = "Ins" -- инвертировать пометку текущего файла/папки
  35. cfg.dff_insert = "CtrlV ShiftIns" -- вставка
  36. cfg.far    = "Esc CtrlY CtrlX CtrlC" -- отдать ФАРу
  37. cfg.dummy  = "Left Right Ctrl Alt Shift" -- ничего не делать с этими хоткеями
  38. cfg.search_empty = "Alt," -- выйти и открыть пустой Search
  39. cfg.search_fill  = "AltSpace Alt." -- выйти и открыть непустой Search
  40. cfg.search_text  = "*" -- иницилизация для непустого Search (текст!)
  41.  
  42. cfg.cyclic = true -- использовать циклический поиск
  43.  
  44. ----------------------------------------------------------------------------------------------------
  45. -- Загрузка персональных настроек
  46. ----------------------------------------------------------------------------------------------------
  47. --do local f,m=loadfile(debug.getinfo(1,"S").source:match("^@(.+)%.")..".cfg")
  48. do local f,m=loadfile((...):gsub("[^.]+$","cfg"))
  49. if f then setfenv(f,{cfg=cfg}) if not pcall(f) then msgbox("DescSS","\nCONFIG ERROR\n ",1)
  50. end end end
  51.  
  52. ----------------------------------------------------------------------------------------------------
  53. -- Локализация
  54. ----------------------------------------------------------------------------------------------------
  55.  
  56. local langs = { english = {}, russian = {} }
  57.  
  58. langs.english.dss_sel   = "Description Select"
  59. langs.english.dss_unsel = "Description Unselect"
  60. langs.english.dff_title = "Description"
  61.  
  62. langs.russian.dss_sel   = "Пометка по описанию"
  63. langs.russian.dss_unsel = "Снятие пометки по описанию"
  64. langs.russian.dff_title = "Описание"
  65.  
  66. ----------------------------------------------------------------------------------------------------
  67. local F = far.Flags
  68.  
  69. ----------------------------------------------------------------------------------------------------
  70. -- Выделение/снятие выделения по описаниям (Description Select/Unselect)
  71. ----------------------------------------------------------------------------------------------------
  72.  
  73. local DescSSId = "5A71088D-CB13-4F43-A314-C2B4D65C3D59"
  74. local DescSSIdB = win.Uuid(DescSSId)
  75. far.Guids.DescriptionSelectUnselectId = DescSSId
  76.  
  77. local dss_recur = false
  78. local dss_init = ""
  79.  
  80. -- замена mf.fmatch
  81. local function dff_fmatch(fn,mask)
  82.     --return mf.fmatch(fn,mask)==1
  83.     return far.ProcessName(F.PN_CMPNAME,mask,fn)
  84. end
  85.  
  86. -- Основная функция
  87. local function descriptions_select( sel, init )
  88.     if Area.Search then Keys "Esc" end
  89.     local lang = langs[win.GetEnv("FARLANG"):lower()] or langs.english
  90.     local diz
  91.     local Title = (sel==1) and lang.dss_sel or lang.dss_unsel
  92.     local HistName = "DSS"
  93.     local Flags = F.FIB_ENABLEEMPTY + F.FIB_BUTTONS + (init and F.FIB_NOUSELASTHISTORY or 0)
  94.     dss_init = init
  95.     dss_recur = type(init)~="string"
  96.     mask = far.InputBox(DescSSIdB,Title,"",HistName,"",nil,nil,Flags)
  97.     if mask == nil or mask == "" then return end
  98.     local sel_fold = cfg.selfold or Far.GetConfig("Panel.SelectFolders") -- использовать пометку папок
  99.     for index=1,APanel.ItemCount do
  100.         if sel_fold or band(Panel.Item(0,index,2),0x10)==0 then
  101.             diz = Panel.Item(0,index,11)
  102.             if diz:len() > 0 then
  103.                 if dff_fmatch(diz,mask) then
  104.                     Panel.Select(0,sel,1,index)
  105.                 end
  106.             end
  107.         end
  108.     end
  109. end
  110.  
  111. if cfg.dss_post ~= "" and cfg.dss_fill ~= "" then
  112.     Event { -- Установить строку иницилизации
  113.         description="Description: Init string";
  114.         group="DialogEvent";
  115.         condition=function(event,param)
  116.             if not dss_recur and event==F.DE_DLGPROCEND and param.Msg==F.DN_INITDIALOG then
  117.                 local info = param.hDlg:send(F.DM_GETDIALOGINFO)
  118.                 return info and info.Id==DescSSIdB
  119.             end
  120.         end;
  121.         action=function(event,param)
  122.             dss_recur = true -- исключить рекурсивный вход
  123.             far.MacroPost('Keys("'..dss_init..'")')
  124.         end;
  125.     }
  126. end
  127.  
  128. if cfg.dss_sel ~= "" then
  129.     Macro { -- Выделить
  130.         description="Description: Select";
  131.         area="Shell Search";
  132.         key=cfg.dss_sel;
  133.         action=function()
  134.             descriptions_select(1)
  135.         end;
  136.     }
  137. end
  138. if cfg.dss_fill ~= "" then
  139.     Macro { -- Выделить с установкой начальной маски **
  140.         description="Description: Select **";
  141.         area="Shell Search";
  142.         key=cfg.dss_fill;
  143.         action=function()
  144.             descriptions_select(1,"* * Left")
  145.         end;
  146.     }
  147. end
  148. if cfg.dss_unsel ~= "" then
  149.     Macro { -- Снять выделение
  150.         description="Description: Unselect";
  151.         area="Shell Search";
  152.         key=cfg.dss_unsel;
  153.         action=function()
  154.             descriptions_select(0)
  155.         end;
  156.     }
  157. end
  158.  
  159. ----------------------------------------------------------------------------------------------------
  160. -- Быстрый поиск по описаниям (Description Fast Find = Description Quick Search)
  161. ----------------------------------------------------------------------------------------------------
  162.  
  163. local DFF_ID = "83689A78-99EA-4B01-98DE-ED8135140B20"
  164. local DFF_GUID = win.Uuid(DFF_ID)
  165. local dff_hdlg
  166. local dff_mask = ""
  167. local dff_focus = 2 -- фокус поля ввода
  168.  
  169. local item_property = 11
  170.  
  171. -- Установить текст маски в поле ввода
  172. local function dff_print(text)
  173.     far.SendDlgMessage(dff_hdlg,F.DM_SETTEXT,dff_focus,text)
  174. end
  175.  
  176. -- Перерисовка диалога
  177. local function dff_redraw()
  178.     far.SendDlgMessage(dff_hdlg,F.DM_REDRAW,0,0)
  179. end
  180.  
  181. -- Сравнение описания файла по маске
  182. local function dff_match(mask,diz)
  183.     -- При сравнении, в конец маски добавляем символ *, если его там нет
  184.     -- Делаем фичу: непустая маска никогда не должна совпадать с пустым описанием, даже если маска *
  185.     -- Короче, с пустым описанием может совпасть только пуская маска.
  186.         return (diz ~= "" or mask == "" ) -- то же not (diz == "" and mask ~= "" )
  187.     -- Заключаем всё в кавычки, что бы получить один регексп (особенность сравнения по маска mf.fmatch)
  188.                 --and dff_fmatch(diz,'"'..((mask:sub(-1)~='*') and (mask..'*') or mask)..'"')
  189.     -- Вариант без заключения маски в кавычки
  190.                 and dff_fmatch(diz,(mask:sub(-1)~='*') and (mask..'*') or mask)
  191. end
  192.  
  193. -- Сравнение описания файла с номером index по маске
  194. local function dff_imatch(mask,index)
  195.     return dff_match(mask,Panel.Item(0,index,11))
  196. end
  197.  
  198. -- Поиск следующего совпадения.
  199. -- При успехе возвращаем индекс найденного файла, иначе - 0.
  200. local function dff_next(mask)
  201.     local current = Panel.SetPosIdx(0,0)
  202.     local diz
  203.     -- со следующего и до конца
  204.     for index=current+1, APanel.ItemCount do
  205.         diz = Panel.Item(0,index,11)
  206.         if diz:len() > 0 then
  207.             if dff_match(mask,diz) then
  208.                 return index
  209.             end
  210.         end
  211.     end
  212.     if not cfg.cyclic then return 0 end
  213.     -- с первого до текущего
  214.     for index=1, current do
  215.         diz = Panel.Item(0,index,11)
  216.         if diz:len() > 0 then
  217.             if dff_match(mask,diz) then
  218.                 return index
  219.             end
  220.         end
  221.     end
  222.     return 0
  223. end
  224.  
  225. -- Поиск предыдущего совпадения.
  226. -- При успехе возвращаем индекс найденного файла, иначе - 0.
  227. local function dff_prev(mask)
  228.     local current = Panel.SetPosIdx(0,0)
  229.     local diz
  230.     -- с предыдущего и до начала
  231.     for index=current-1, 1, -1 do
  232.         diz = Panel.Item(0,index,11)
  233.         if diz:len() > 0 then
  234.             if dff_match(mask,diz) then
  235.                 return index
  236.             end
  237.         end
  238.     end
  239.     -- с последнего до текущего
  240.     if not cfg.cyclic then return 0 end
  241.     for index=APanel.ItemCount, current, -1 do
  242.         diz = Panel.Item(0,index,11)
  243.         if diz:len() > 0 then
  244.             if dff_match(mask,diz) then
  245.                 return index
  246.             end
  247.         end
  248.     end
  249.     return 0
  250. end
  251.  
  252. -- Поиск последнего совпадения
  253. local function dff_end(mask)
  254.     local current = Panel.SetPosIdx(0,0)
  255.     local diz
  256.     for index=APanel.ItemCount, Panel.SetPosIdx(0,0), -1 do -- ??? Panel.SetPosIdx(0,0)+1
  257.         diz = Panel.Item(0,index,11)
  258.         if diz:len() > 0 then
  259.             if dff_match(mask,diz) then
  260.                 return index
  261.             end
  262.         end
  263.     end
  264.     return 0
  265. end
  266.  
  267. -- Поиск первого совпадения
  268. local function dff_home(mask)
  269.     local diz
  270.     for index=1, Panel.SetPosIdx(0,0) do -- ??? Panel.SetPosIdx(0,0)-1
  271.         diz = Panel.Item(0,index,11)
  272.         if diz:len() > 0 then
  273.             if dff_match(mask,diz) then
  274.                 return index
  275.             end
  276.         end
  277.     end
  278.     return 0
  279. end
  280.  
  281. -- Добавление одного символа к маске
  282. local function dff_char(char)
  283.     local new_mask = dff_mask .. char
  284.     local index
  285.     if dff_imatch(new_mask,0) then
  286.         -- Если маска совпадает с описанием текущего файла, никуда не перемещаемся
  287.         dff_mask = new_mask
  288.         dff_print(dff_mask)
  289.     else
  290.         index = dff_next(new_mask) -- следующее совпадение или 0
  291.         if index > 0 then
  292.             -- Если есть совпадение - переход,
  293.             -- иначе символ никак не обрабатываем
  294.             dff_mask = new_mask
  295.             dff_print(dff_mask)
  296.             Panel.SetPosIdx(0,index)
  297.             dff_redraw()
  298.         end
  299.     end
  300. end
  301.  
  302. -- Добавление нескольких символов к маске
  303. local function dff_chars(chars)
  304.     local new_mask = dff_mask
  305.     local index
  306.     for i=1, chars:len() do
  307.         new_mask = new_mask .. chars:sub(i,i)
  308.         if dff_imatch(new_mask,0) then
  309.             -- Если маска совпадает с описанием текущего файла,
  310.             -- никуда не перемещаемся
  311.             dff_mask = new_mask
  312.         else
  313.             index = dff_next(new_mask)
  314.             if index > 0 then
  315.                 dff_mask = new_mask
  316.                 Panel.SetPosIdx(0,index)
  317.             else
  318.                 -- если очередной символ добавить не удалось, заканчиваем вставку
  319.                 break
  320.             end
  321.         end
  322.     end
  323.     dff_print(dff_mask)
  324.     dff_redraw()
  325.     return
  326. end
  327.  
  328. -- Вниз
  329. local function dff_down()
  330.     if dff_mask:len() > 0 then
  331.         -- При непустой маске ищем следующее совпадение
  332.         index = dff_next(dff_mask)
  333.         if index > 0 then
  334.             Panel.SetPosIdx(0,index)
  335.         end
  336.     else
  337.         -- При пустой маске просто перемещаемся на следующий файл
  338.         if APanel.Eof then
  339.             Panel.SetPosIdx(0,1)
  340.         else
  341.             Panel.SetPosIdx(0,Panel.SetPosIdx(0,0)+1)
  342.         end
  343.     end
  344.     dff_redraw()
  345. end
  346.  
  347. -- Вверх
  348. local function dff_up()
  349.     if dff_mask:len() > 0 then
  350.         -- При непустой маске ищем предыдущее совпадение
  351.         index = dff_prev(dff_mask)
  352.         if index > 0 then
  353.             Panel.SetPosIdx(0,index)
  354.         end
  355.     else
  356.         -- При пустой маске просто перемещаемся на предыдущий файл
  357.         if APanel.Bof then
  358.             Panel.SetPosIdx(0,-1)
  359.         else
  360.             Panel.SetPosIdx(0,Panel.SetPosIdx(0,0)-1)
  361.         end
  362.     end
  363.     dff_redraw()
  364. end
  365.  
  366. -- Для поиска клавиши в строке клавиш
  367. local function instr(s,k)
  368.     return (" "..s:lower().." "):match(" "..k:lower().." ")
  369. end
  370.  
  371. -- Создаём диалог
  372. local function dff_dialog(dlg_init)
  373.     local lang = langs[win.GetEnv("FARLANG"):lower()]
  374.     if not lang then lang = langs.english end
  375.     local dlg_wid = 20  -- ширина строки ввода
  376.     local dlg_x1 = APanel.Left and 2 or PPanel.Width+2
  377.     local dlg_x2 = dlg_x1 + dlg_wid + 2
  378.     local dlg_y1 = APanel.Height - 1
  379.     local dlg_y2 = dlg_y1 + 2
  380.     local exit_key = false
  381.     local exit_keys = false
  382.  
  383.     if Area.Search then Keys "Esc" end
  384.  
  385.     dff_mask = ""
  386.     local dlg_items =
  387.     {   -- X1,Y1,X2,Y2,_,sHistory,sMask,Flags,sData,...
  388.         {F.DI_DOUBLEBOX,0,0,dlg_wid+1,2,0,0,0,0,lang.dff_title}, -- 01
  389.         {F.DI_EDIT,     1,1,dlg_wid  ,1,0,0,0,0,dff_mask},       -- 02
  390.     }
  391.  
  392.     -- Диалоговая процедура (thanks ZG за помощь)
  393.     local function dlg_proc(hDlg,Msg,Param1,Param2)
  394.         if Msg==F.DN_INITDIALOG then
  395.             -- Фокус будет на единственном поле ввода
  396.             dff_focus = far.SendDlgMessage(dff_hdlg,F.DM_GETFOCUS,0,0)
  397.             -- Снимаем признак "неизменённый", что бы не было выделения цветом
  398.             far.SendDlgMessage(dff_hdlg,F.DM_EDITUNCHANGEDFLAG,dff_focus,0)
  399.             dff_chars(dlg_init) -- начальная иницилизация маски с переходом к ближайшему совпадению
  400.             return false
  401.  
  402.         elseif Msg==F.DN_CONTROLINPUT and Param1==dff_focus and Param2.EventType==F.MOUSE_EVENT then
  403.             -- отключаем события мыши, чтобы не перемещался курсор
  404.             return true
  405.  
  406.         elseif Msg==F.DN_CONTROLINPUT and Param1==dff_focus and Param2.EventType==F.KEY_EVENT and Param2.KeyDown then
  407.             local k = far.InputRecordToName(Param2) -- клавиша "as is"
  408.             local a = k:gsub("[RL]Ctrl","Ctrl"):gsub("[RL]Alt","Alt") -- для упрощения проверки
  409.             local mask = ""
  410.             local index, clp
  411.  
  412.             if a:len()==1 then
  413.                 -- Введён один символ
  414.                 dff_char(a)
  415.  
  416.             elseif a=="Space" or a=="ShiftSpace" then
  417.                 dff_char(" ")
  418.  
  419.             elseif a=="BackSlash" then
  420.                 dff_char("\\")
  421.  
  422.             elseif a=="BS" then
  423.                 -- Удаление последнего символа, перемещаться после этого не надо (совпадение уже проверенно)
  424.                 if dff_mask:len() > 0 then
  425.                     dff_mask = dff_mask:sub(1,-2)
  426.                     dff_print(dff_mask)
  427.                 end
  428.  
  429.             elseif instr(cfg.dff_next,a) then
  430.                 -- Перемещение к следующему совпадению
  431.                 dff_down()
  432.  
  433.             elseif instr(cfg.dff_prev,a) then
  434.                 -- Перемещение к предыдущему совпадению
  435.                 dff_up()
  436.  
  437.             elseif instr(cfg.dff_last,a) then
  438.                 -- Перемещение к последнему совпадению
  439.                 if dff_mask:len() > 0 then
  440.                     index = dff_end(dff_mask)
  441.                     if index > 0 then
  442.                         Panel.SetPosIdx(0,index)
  443.                     end
  444.                 else
  445.                     Panel.SetPosIdx(0,APanel.ItemCount)
  446.                 end
  447.                 dff_redraw()
  448.  
  449.             elseif instr(cfg.dff_first,a) then
  450.                 -- Перемещение к первому совпадению
  451.                 if dff_mask:len() > 0 then
  452.                     index = dff_home(dff_mask)
  453.                     if index > 0 then
  454.                         Panel.SetPosIdx(0,index)
  455.                     end
  456.                 else
  457.                     Panel.SetPosIdx(0,1)
  458.                 end
  459.                 dff_redraw()
  460.  
  461.             elseif instr(cfg.dff_invert,a) then
  462.                 -- Выделить и перейти к следующему
  463.                 Panel.Select(0,2,1)
  464.                 dff_down()
  465.  
  466.             elseif instr(cfg.dff_insert,a) then
  467.                 -- Вставка
  468.                 clp = mf.clip(0)
  469.                 if type(clp)=="string" and clp:len()>0 then
  470.                     dff_chars(clp)
  471.                 end
  472.  
  473.             elseif instr(cfg.far,a) then
  474.                 -- для обработки возвращаем управление ФАРу
  475.                 return false
  476.  
  477.             elseif instr(cfg.dummy,a) then
  478.                 -- Ничего не делаем
  479.  
  480.             elseif instr(cfg.search_empty,a) then
  481.                 -- Перейти к обычному Search
  482.                 exit_keys = "Alt<" -- комбинация клавиш, вызывающая обычный Search
  483.                 far.SendDlgMessage(hDlg,F.DM_CLOSE)
  484.  
  485.             elseif instr(cfg.search_fill,a) then
  486.                 -- Перейти к Search
  487.                 exit_keys = "Alt< " .. cfg.search_text
  488.                 far.SendDlgMessage(hDlg,F.DM_CLOSE)
  489.  
  490.             else
  491.                 exit_key = k
  492.                 far.SendDlgMessage(hDlg,F.DM_CLOSE)
  493.  
  494.             end
  495.             return true
  496.         end
  497.     end -- dlg_proc
  498.  
  499.     local dlg_flags = F.FDLG_KEEPCONSOLETITLE + F.FDLG_NODRAWSHADOW + F.FDLG_SMALLDIALOG
  500.     dff_hdlg = far.DialogInit(DFF_GUID,dlg_x1,dlg_y1,dlg_x2,dlg_y2,"",dlg_items,dlg_flags,dlg_proc)
  501.     far.DialogRun(dff_hdlg)
  502.     far.DialogFree(dff_hdlg)
  503.     if exit_keys then
  504.         Keys(exit_keys)
  505.     elseif exit_key then
  506.         if eval(exit_key,2)==-2 then
  507.             Keys(exit_key)
  508.         end
  509.     end
  510. end
  511.  
  512. -- Макросы
  513.  
  514. if cfg.dff_empty ~= "" then
  515.     Macro { -- Вызов диалога быстрого поиска
  516.         description="Description: Fast Find";
  517.         area="Shell Search";
  518.         key=cfg.dff_empty;
  519.         action=function() dff_dialog("") end;
  520.     }
  521. end
  522. if cfg.dff_fill ~= "" then
  523.     Macro { -- Вызов диалога быстрого поиска с начальной маской
  524.         description="Description: Fast Find";
  525.         area="Shell Search";
  526.         key=cfg.dff_fill;
  527.         action=function() dff_dialog(cfg.dff_text) end;
  528.     }
  529. end
  530. ----------------------------------------------------------------------------------------------------
Пример файла конфигурации
  1. --[[ -----------------------------------------------------------------------------------------------
  2.     Пример файла конфигурации для макросов DescSS.
  3.     Файл должен лежать в той же папке, что и файл макросов, иметь тоже имя и расширение cfg.
  4.     По умолчанию, если основной скрипт не переименован, имя должно быть DescSS.cfg
  5.  
  6.     Файл конфигурации представляет собой скрипт Lua. Если файл содержит синтаксические ошибки
  7.     и не может быть обработам интерпретатором Lua, будет выдано сообщение:
  8.  
  9.     ╔═══ DescSS ═══╗
  10.     ║              ║
  11.     ║ CONFIG ERROR ║
  12.     ║              ║
  13.     ╟──────────────╢
  14.     ║    { OK }    ║
  15.     ╚══════════════╝
  16.  
  17.     Если файл конфигурации отсутствует или содержит ошибки, будут использованны значения по умолчанию,
  18.     заданные в основном скрипте. В случае отсутствия каких-либо параметров (например, они будут
  19.     закоментированы), вместо них также будут использованы значения по умолчанию.
  20.  
  21.     В диалоговой процедуре правые и левые модификаторы не проверяются для упрощения обработки,
  22.     регэкспы не поддерживаются.
  23.  
  24.     Внимание! Используемый здесь AltSpace работает при наличие плагина XKeys.
  25.  
  26.     ДЛЯ ОТКЛЮЧЕНИЯ МАКРОСОВ И ГОРЯЧИХ КЛАВИШ ОСТАВИТЬ СТРОКУ В КОВЫЧКАХ ПУСТОЙ!
  27.  
  28. cfg.sample = "" -- Пример: так отключать макросы
  29.  
  30. --]] -----------------------------------------------------------------------------------------------
  31.  
  32. -- Макросы для установки/снятия пометки
  33.  
  34. cfg.dss_sel   = "AltShiftS" -- макрос Select
  35. cfg.dss_unsel = "AltShiftU" -- макрос Unselect
  36. cfg.dss_fill  = "AltShiftD" -- макрос Select with init
  37. cfg.dss_post  = "* * Left" -- иницилизация маски для предыдущего макроса (макропоследовательность!)
  38.  
  39. -- Макросы быстрого поиска
  40.  
  41. cfg.dff_empty = "Alt," -- открыть пустой диалог
  42. cfg.dff_fill  = "AltSpace Alt." -- открыть непустой диалог
  43. cfg.dff_text  = "*" -- иницилизация непустого диалога для предыдущего макроса (текст!)
  44.  
  45. -- Диалоговая процедура быстрого поиска.
  46. -- Правые и левые модификаторы не проверяются, регэкспы не поддерживаются!
  47.  
  48. cfg.dff_next   = "CtrlEnter CtrlNumEnter CtrlDown" -- следующее совпадение
  49. cfg.dff_prev   = "CtrlShiftEnter CtrlShiftNumEnter CtrlUp" -- предыдущее совпадение
  50. cfg.dff_last   = "CtrlEnd" -- последнее совпадение
  51. cfg.dff_first  = "CtrlHome" -- первое совпадение
  52. cfg.dff_invert = "Ins" -- инвертировать пометку текущего файла/папки
  53. cfg.dff_insert = "CtrlV ShiftIns" -- вставка
  54. cfg.far    = "Esc CtrlY CtrlX CtrlC" -- отдать ФАРу
  55. cfg.dummy  = "Left Right Ctrl Alt Shift" -- ничего не делать с этими хоткеями
  56. cfg.search_empty = "Alt," -- выйти и открыть пустой Search
  57. cfg.search_fill  = "AltSpace Alt." -- выйти и открыть непустой Search
  58. cfg.search_text  = "*" -- иницилизация для непустого Search (текст!)
  59.  
  60. -- прочее
  61.  
  62. cfg.cyclic = true -- использовать циклический поиск
  63.  
  64. ----------------------------------------------------------------------------------------------------
Прочие макросы для работы с описаниями.

Обычный CtrlZ, если есть отмеченные файлы/папки, выполняется поочерёдно для них всех. Сколько лет пользуюсь описаниями, ни разу не понадобилось такая "пакетная" обработка. Поэтому были написаны макросы для работы только с описанием текущего файла и сохраняющие пометку. Дополнительно, макросы сохряняют предыдущее не пустое описание при изменении/удалении, которое может быть восстановленно.

С версии 1.03 макрос CtrlZ был переименован в DescriptionEdit. Не забудьте удалить старый CtrlZ.lua!
  1. ----------------------------------------------------------------------------------------------------
  2. -- Работа с описаниями файлов
  3. -- v.1.03 (C) 2013-2016 Smitis
  4. ----------------------------------------------------------------------------------------------------
  5.  
  6. local F = far.Flags
  7. local diz_prev = ""
  8.  
  9. ----------------------------------------------------------------------------------------------------
  10. -- Замена стандартного диалога редактирования.
  11. -- Редактируется описание только текущего элемента панелей, не зависимо от выделения.
  12. -- Выделение сохраняется/восстанавливается через внутренний буфер. Откат через CtrlM теряется.
  13. ----------------------------------------------------------------------------------------------------
  14.  
  15. local DescriptionEditId = "1B8B8080-09EE-4AB2-B723-1014C1C0A97E"
  16. local DescriptionEditIdB = win.Uuid(DescriptionEditId)
  17. --far.Guids.DescriptionEditId = DescriptionEditId
  18.  
  19. local diz_changed = false
  20.  
  21. local function diz_edit(init,changed)
  22.     if Area.Search then Keys "Esc" end
  23.  
  24.     local selected = APanel.Selected
  25.     local diz = Panel.Item(0,0,11)
  26.     if init and type(init)=="string" then
  27.         diz = init
  28.     end
  29.     diz_changed = changed
  30.     local Title = "Describe file"
  31.     local Prompt = "Enter description for " .. APanel.Current .. ":"
  32.     local HistName = "DizText"
  33.     local Flags = F.FIB_ENABLEEMPTY + F.FIB_BUTTONS + F.FIB_NOUSELASTHISTORY
  34.     local diz_new = far.InputBox(DescriptionEditIdB,Title,Prompt,HistName,diz,nil,nil,Flags)
  35.     if diz_new then
  36.         diz_new = diz_new:gsub("^%s+",""):gsub("%s+$","") -- trim
  37.         mf.clip(5,2)
  38.         diz_prev = diz
  39.         if selected then -- сохранить выделение
  40.             Keys "CtrlShiftIns"
  41.             Panel.Select(0,0)
  42.         end
  43.         Keys "CtrlZ"
  44.         print(diz_new)
  45.         Keys "Enter"
  46.         if selected then -- восстановить выделение
  47.             Panel.Select(0,1,2,mf.clip(0))
  48.         end
  49.     end
  50. end
  51. ----------------------------------------------------------------------------------------------------
  52. Event { -- сделать поле ввода "изменённое" для некоторых операций
  53.     description="Description: Make unchanged";
  54.     group="DialogEvent";
  55.     condition=function(event,param)
  56.         return event == F.DE_DLGPROCINIT
  57.                 and param.Msg == F.DN_DRAWDIALOGDONE
  58.                 and diz_changed
  59.                 and Dlg.Id == DescriptionEditId
  60.     end;
  61.     action=function(event,param)
  62.         diz_changed = false -- исключить рекурсивный вход
  63.         far.MacroPost('Keys("End")')
  64.     end;
  65. }
  66. ----------------------------------------------------------------------------------------------------
  67. Macro { --  Описание только одного файла
  68.     description="Description: Edit";
  69.     area="Shell Search";
  70.     key="CtrlZ";
  71.     action=function()
  72.         diz_edit()
  73.     end;
  74. }
  75. ----------------------------------------------------------------------------------------------------
  76. Macro { --  Копирование описания в буфер обмена
  77.     description="Description: Copy to clipboard";
  78.     area="Shell Search";
  79.     key="AltC";
  80.     action=function()
  81.         if Area.Search then Keys "Esc" end
  82.         mf.clip(1,Panel.Item(0,0,11))
  83.     end;
  84. }
  85. ----------------------------------------------------------------------------------------------------
  86. Macro { --  Новое описание из буфера обмена
  87.     description="Description: New from clipboard";
  88.     area="Shell Search";
  89.     key="AltZ";
  90.     action=function()
  91.         diz_edit(mf.clip(0),true)
  92.     end;
  93. }
  94. ----------------------------------------------------------------------------------------------------
  95. Macro { --  Добавить описание из буфера обмена к текущему описанию через пробел.
  96.     description="Description: Append from clipboard";
  97.     area="Shell Search";
  98.     key="AltV";
  99.     action=function()
  100.         if Area.Search then Keys "Esc" end
  101.         local diz = Panel.Item(0,0,11)
  102.         if diz:len() > 0 then
  103.             diz_edit(diz.." "..mf.clip(0),true)
  104.         else
  105.             diz_edit(mf.clip(0),true)
  106.         end
  107.     end;
  108. }
  109. ----------------------------------------------------------------------------------------------------
  110. Macro { --  Удалить описание в буфер обмена
  111.     description="Description: Cut to clipboard";
  112.     area="Shell Search";
  113.     key="AltX";
  114.     action=function()
  115.         if Area.Search then Keys "Esc" end
  116.         local diz = Panel.Item(0,0,11)
  117.         if diz:len() > 0 then
  118.             mf.clip(1,diz)
  119.             local selected = APanel.Selected
  120.             mf.clip(5,2)
  121.             if selected then
  122.                 Keys "CtrlShiftIns"
  123.                 Panel.Select(0,0)
  124.             end
  125.             Keys "CtrlZ CtrlY Enter"
  126.             if selected then
  127.                 Panel.Select(0,1,2,mf.clip(0))
  128.             end
  129.         end
  130.     end;
  131. }
  132. ----------------------------------------------------------------------------------------------------
  133. Macro { --  Удалить описание
  134.     description="Description: Delete";
  135.     area="Shell Search";
  136.     key="AltD";
  137.     action=function()
  138.         if Area.Search then Keys "Esc" end
  139.         local diz = Panel.Item(0,0,11)
  140.         if diz:len() > 0 then
  141.             diz_prev = diz
  142.             local selected = APanel.Selected
  143.             mf.clip(5,2)
  144.             if selected then
  145.                 Keys "CtrlShiftIns"
  146.                 Panel.Select(0,0)
  147.             end
  148.             Keys "CtrlZ CtrlY Enter"
  149.             if selected then
  150.                 Panel.Select(0,1,2,mf.clip(0))
  151.             end
  152.         end
  153.     end;
  154. }
  155. ----------------------------------------------------------------------------------------------------
  156. Macro { --  Восстановить описание
  157.     description="Description: Restore";
  158.     area="Shell Search";
  159.     key="AltShiftZ";
  160.     action=function()
  161.         diz_edit(diz_prev)
  162.     end;
  163. }
  164. ----------------------------------------------------------------------------------------------------
Макросы DescriptionMultiEdit являются модификацией макросов DescriptionEdit с добавленной функцией редактирования во встроенном редакторе многострочных описаний, поддерживаемых TotalCommander. Вызывается из диалога изменения описаний по F4. По поводу кривизны этих многострочных описаний я уже высказался в этой теме и смежной.
СОВМЕСТИМОСТЬ С TC ТОЛЬКО ДЛЯ ОПИСАНИЙ В ANSI КОДИРОВКЕ!
Эти макросы требуют для работы модуль DialogClass
Нумерация версий совпадает с DescriptionEdit.
  1. --[=[ ------------------------------------------------------------------------------------------------------------------
  2. Работа с описаниями файлов, в том числе и с многострочными
  3. v.1.03 (C) 2013-2016 Smitis
  4. Приватная версия с дополнительным полем с именем файла.
  5.  
  6. - Замена стандартного диалога редактирования.
  7. - Редактируется описание только текущего элемента панелей, не зависимо от выделения (Выделение сохраняется/восстанавливается через внутренний буфер. Восстановление предыдущего выделения через CtrlM теряется.)
  8. - Возможность редактирования многострочных описаний.
  9.  
  10. Для работы требуется модуль DialogClass
  11.     http://forum.farmanager.com/viewtopic.php?t=8523
  12. Обсуждение макросов для работы с описаниями
  13.     http://forum.farmanager.com/viewtopic.php?t=7846
  14. Обсуждение многострочного редактора описаний
  15.     http://forum.farmanager.com/viewtopic.php?t=285
  16. --]=] ------------------------------------------------------------------------------------------------------------------
  17.  
  18. local F = far.Flags
  19. local dialog = require 'DialogClass'
  20.  
  21. ------------------------------------------------------------------------------------------------------------------------
  22.  
  23. local DescriptionMultiEditId = "75CA1288-4C06-4621-870E-A4FDD9E7319E"
  24. --far.Guids.DescriptionMultiEditId = DescriptionMultiEditId
  25.  
  26. local HistoryLimitLen = 80 -- описания длиней чем HistoryLimitLen в историю добавляться не будут
  27. local DescriptionPrev = ""
  28.  
  29. ------------------------------------------------------------------------------------------------------------------------
  30. -- Редактирование в окне с рамкой
  31. local MultiEditId = "736B91DE-2525-4296-9529-F0BAD8503B57"
  32. --far.Guids.MultiEditId = MultiEditId
  33. local function MultiEdit(x1,y1,x2,y2,text,title)
  34.     dialog.New {
  35.         Guid = MultiEditId,
  36.         X1=x1, Y1=y1, X2=x2, Y2=y2, Frame=2,
  37.         DlgProc = function(hDlg,Msg,Param1,Param2,D,DI)
  38.             local coord, hfile, tmpfile
  39.             if Msg==F.DN_DRAWDIALOGDONE then
  40.                 coord = D:Send(F.DM_GETDLGRECT,0,0)
  41.                 tmpfile = far.MkTemp()
  42.                 hfile = io.open(tmpfile,"w") hfile:write(text) hfile:close()
  43.                 editor.Editor(tmpfile,title,coord.Left+4,coord.Top+2,coord.Right-4,coord.Bottom-2, bor(F.EF_DISABLEHISTORY,F.EF_DISABLESAVEPOS),0,0,65001)
  44.                 hfile = io.open(tmpfile,"r") text = hfile:read("*a") hfile:close()
  45.                 win.DeleteFile(tmpfile)
  46.                 D:Send(F.DM_CLOSE)
  47.             end
  48.         end
  49.     } ()
  50.     return text
  51. end
  52. ------------------------------------------------------------------------------------------------------------------------
  53. local idtc = win.Utf16ToUtf8(win.MultiByteToWideChar(unicode.ascii.char(0x04,0xC2),win.GetACP())) -- идентификатор TC в UTF-8
  54. local function DescriptionEdit(init,changed)
  55.     local Selected = APanel.Selected
  56.     local Description = Panel.Item(0,0,11)
  57.     local HistoryName = "DizText"
  58.     local FileName = APanel.Current
  59.  
  60.     if Area.Search then Keys "Esc" end
  61.  
  62.     local D,DI = dialog.New {
  63.         Guid = DescriptionMultiEditId,
  64.         Title = "Describe file",
  65.         W=76, H=8,
  66.         DlgProc = function(hDlg,Msg,Param1,Param2,D,DI)
  67.             if Msg==F.DN_INITDIALOG then
  68.                 -- для некоторых макросов требуется, чтобы поле не было "неизменённое"
  69.                 if changed then
  70.                     DI.Description:Unchanged(0)
  71.                 end
  72.             elseif Msg==F.DN_CLOSE then
  73.                 -- не записываем в историю пустые, слишком большие и многострочные описания
  74.                 local text = DI.Description:GetText()
  75.                 if text~="" and text:len()<=HistoryLimitLen and text:find('\n')==nil then
  76.                     DI.Description:Send(F.DM_ADDHISTORY,text)
  77.                 end
  78.                 return true
  79.             elseif Msg==F.DN_CONTROLINPUT and Param2.EventType==F.KEY_EVENT and Param2.KeyDown then
  80.                 local k = far.InputRecordToName(Param2):gsub('[RL]Ctrl','Ctrl')
  81.                 if k=="CtrlE" or k=="F4" then
  82.                     local coord = D:Send(F.DM_GETDLGRECT,0,0)
  83.                     --local text = DI.Description:GetText():gsub('\x02',''):gsub('\x03','\n')
  84.                     local text = DI.Description:GetText()
  85.                     if text:sub(-2)==idtc then -- проверка частичная, так как мы не знаем, из какой кодировки конвертировали в юникод
  86.                         idsymbol = text:sub(-1) -- это то, во что был преобразован id после конвертирования ANSI->UNICODE
  87.                         text = text:sub(1,-3):gsub('(\\*\\n)',
  88.                             function(s)
  89.                                 if s:sub(1,-3):len()%2==0 then
  90.                                     return s:sub(1,-3)..'\n' -- перед \n чётное число или 0 символов \
  91.                                 end
  92.                                 return s
  93.                             end
  94.                         ):gsub('\\\\','\\')
  95.                     end
  96.                     local newtext = MultiEdit(coord.Left,coord.Top-5,coord.Right,coord.Bottom+5,text,"Description Edit")
  97.                     if newtext ~= text then
  98.                         if newtext:find('\n') then
  99.                             newtext = newtext:gsub('\\','\\\\'):gsub('\n','\\n')..idtc
  100.                         end
  101.                         DI.Description:SetText(newtext)
  102.                     end
  103.                     return true
  104.                 end
  105.             end
  106.         end,
  107.         Items = {
  108.             {"t+", Text="Description:"},
  109.             {"emh+@", Name="Description", Text=init or Description, History=HistoryName},
  110.             {"s+"},
  111.             {"b=!+", Name="OK"},
  112.             {"b=", Name="Cancel"},
  113.         },
  114.     }
  115.     D()
  116.     if D.Ret ~= -1 and D.Ret ~= DI.Cancel.Id then
  117.         if DI.Description.Text ~= Description then
  118.             DescriptionPrev = Description
  119.             Description = DI.Description.Text:gsub("^%s+",""):gsub("%s+$","") -- trim
  120.             mf.clip(5,2)
  121.             if Selected then -- сохранить выделение
  122.                 Keys "CtrlShiftIns"
  123.                 Panel.Select(0,0)
  124.             end
  125.             Far.DisableHistory(-1) -- добавляются в DlgProc
  126.             Keys "CtrlZ"
  127.             print(Description)
  128.             Keys "Enter"
  129.             if Selected then -- восстановить выделение
  130.                 Panel.Select(0,1,2,mf.clip(0))
  131.             end
  132.         end
  133.     end
  134. end
  135. ------------------------------------------------------------------------------------------------------------------------
  136. Macro { --  Описание
  137.     description="Description";
  138.     area="Shell Search";
  139.     key="CtrlAltZ";
  140.     action=function()
  141.         Keys "CtrlZ"
  142.     end;
  143. }
  144. ------------------------------------------------------------------------------------------------------------------------
  145. Macro { --  Описание только одного файла
  146.     description="Description: Edit";
  147.     area="Shell Search";
  148.     key="CtrlZ";
  149.     action=function()
  150.         DescriptionEdit()
  151.     end;
  152. }
  153. ------------------------------------------------------------------------------------------------------------------------
  154. Macro { --  Копирование описания в буфер обмена
  155.     description="Description: Copy to clipboard";
  156.     area="Shell Search";
  157.     key="AltC";
  158.     action=function()
  159.         if Area.Search then Keys "Esc" end
  160.         mf.clip(1,Panel.Item(0,0,11))
  161.     end;
  162. }
  163. ------------------------------------------------------------------------------------------------------------------------
  164. Macro { --  Новое описание из буфера обмена
  165.     description="Description: New from clipboard";
  166.     area="Shell Search";
  167.     key="AltZ";
  168.     action=function()
  169.         if Area.Search then Keys "Esc" end
  170.         local Clipboard = mf.clip(0)
  171.         if type(Clipboard)=="string" then
  172.             DescriptionEdit(Clipboard:gsub("[\r\n]+"," "),true)
  173.         end
  174.     end;
  175. }
  176. ------------------------------------------------------------------------------------------------------------------------
  177. Macro { --  Добавить описание из буфера обмена к текущему описанию через пробел.
  178.     description="Description: Append from clipboard";
  179.     area="Shell Search";
  180.     key="AltV";
  181.     action=function()
  182.         if Area.Search then Keys "Esc" end
  183.         local Clipboard = mf.clip(0)
  184.         if type(Clipboard)=="string" and Clipboard:len()>0 then
  185.             local Description = Panel.Item(0,0,11)
  186.             if Description:len() > 0 then
  187.                 DescriptionEdit(Description.." "..Clipboard:gsub("[\r\n]+"," "),true)
  188.             else
  189.                 DescriptionEdit(Clipboard,true)
  190.             end
  191.         end
  192.     end;
  193. }
  194. ------------------------------------------------------------------------------------------------------------------------
  195. Macro { --  Удалить описание в буфер обмена. Это описание не будет помещено в DescriptionPrev
  196.     description="Description: Cut to clipboard";
  197.     area="Shell Search";
  198.     key="AltX";
  199.     action=function()
  200.         if Area.Search then Keys "Esc" end
  201.         local Description = Panel.Item(0,0,11)
  202.         if Description:len() > 0 then
  203.             Far.DisableHistory(-1) -- пустое описание не будет добавлено в историю
  204.             mf.clip(1,Description)
  205.             local selected = APanel.Selected
  206.             mf.clip(5,2)
  207.             if selected then
  208.                 Keys "CtrlShiftIns"
  209.                 Panel.Select(0,0)
  210.             end
  211.             Keys "CtrlZ CtrlY Enter"
  212.             if selected then
  213.                 Panel.Select(0,1,2,mf.clip(0))
  214.             end
  215.         end
  216.     end;
  217. }
  218. ------------------------------------------------------------------------------------------------------------------------
  219. Macro { --  Удалить описание. Это описание будет помещено в DescriptionPrev
  220.     description="Description: Delete";
  221.     area="Shell Search";
  222.     key="AltD";
  223.     action=function()
  224.         if Area.Search then Keys "Esc" end
  225.         local Description = Panel.Item(0,0,11)
  226.         if Description:len() > 0 then
  227.             Far.DisableHistory(-1) -- пустое описание не будет добавлено в историю
  228.             DescriptionPrev = Description
  229.             local selected = APanel.Selected
  230.             mf.clip(5,2)
  231.             if selected then
  232.                 Keys "CtrlShiftIns"
  233.                 Panel.Select(0,0)
  234.             end
  235.             Keys "CtrlZ CtrlY Enter"
  236.             if selected then
  237.                 Panel.Select(0,1,2,mf.clip(0))
  238.             end
  239.         end
  240.     end;
  241. }
  242. ------------------------------------------------------------------------------------------------------------------------
  243. Macro { --  Восстановить описание
  244.     description="Description: Restore";
  245.     area="Shell Search";
  246.     key="AltShiftZ";
  247.     action=function()
  248.         DescriptionEdit(DescriptionPrev)
  249.     end;
  250. }
  251. ------------------------------------------------------------------------------------------------------------------------
Attachments
descss.1.06.7z
DescSS 1.06
(5.72 KiB) Downloaded 37 times
DescriptionEdit.1.03.7z
DescriptionEdit (CtrlZ) 1.03
(1.53 KiB) Downloaded 32 times
DescriptionMultiEdit.1.03.7z
DescriptionMultiEdit 1.03
(2.85 KiB) Downloaded 38 times

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Fri 22 Feb, 2013 19:43

В принципе, плагин можно заменить и макросами.
Простейшие операции плагина - выделение и снятие выделения получаются просто:

Смущает одно - не знаю, как ФАР обновляет внутренюю информацию о файлах, и что будет если, например, где-то между строчками Panel.Item и Panel.Select изменится количество файлов и их описание (по закону подлости) и в момент select индекс проверяемого файла уже будет другим.

П.С.
С макрос для description search будет позамысловатее, но тоже возможен.

П.П.С.
Вроде, эксперимент показывает, что во время выполнения макроса информация не обновляется.
Разум когда-нибудь победит.

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Sat 23 Feb, 2013 22:24

Тигрёнок wrote:Было бы здорово.
С наскока не получилось... :(
Разум когда-нибудь победит.

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Sun 24 Feb, 2013 23:16

Вот такое вот... DescriptionFastFind в первом приближении. Куча недостатков, багов и пр. Любая критика принимается.
Думаю, что обработку клавиш лучше организовать не макросами, а через DlgProc диалога, но пока не получается.

П.С. Нет обработки всяких CtrlV, CtrlX, CtrlY и пр.
Разум когда-нибудь победит.

User avatar
Тигрёнок
Posts: 390
Joined: Wed 03 May, 2006 06:07
Location: Россия
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Тигрёнок » Mon 25 Feb, 2013 07:27

Я пока не всё вкурил, поэтому буду задавать мелкие вопросы по ходу (в т.ч. и по lua).
1) Зачем создавать maskx? Нельзя ли результат класть в mask (она же локальная для dss_match)?
2) Зачем объявлять через local индекс цикла for?
3) Как Вы надыбали такие чудесные конструкции как #diz для длины и dss_mask:sub(-1,-1) для подстроки? Они же не документированы...
4) local dlg_flags = F.FDLG_KEEPCONSOLETITLE + F.FDLG_NODRAWSHADOW + F.FDLG_SMALLDIALOG у меня прекрасно даёт диалог без тени. Единственное, я бы обрез ему габариты до размеров диалога поиска.
5) Что за странные клавиши в описании Macro { area="Dialog"; key="/.+/"; ?
Съешь мыша – стань настоящим клавишником!

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Mon 25 Feb, 2013 08:15

Тигрёнок
1) mask это переданный параметр в функцию, а maskx это mask.."*" (что бы срабатывало условие mf.fmatch)
2) да как-то принято объявлять локальные переменные как локальные :)
3) это обычные конструкции Lua (встроенные)
4) Да, без тени, это что-то ночью меня глючило. И согласен, диалог надо обрезать (у себя уже обрезал), но сделал чуть длинее диалога Search
5) Это перехват ВСЕХ клавиш через регулярное выражение. Это то, что на данный момент мне очень не нравится.
Разум когда-нибудь победит.

Shmuel
Posts: 5234
Joined: Thu 23 Mar, 2006 21:36
Location: Israel
Has thanked: 16 times
Been thanked: 152 times

Re: DescSS — поиск и выделение по описаниям файлов

Post by Shmuel » Mon 25 Feb, 2013 08:21

Тигрёнок wrote:Я пока не всё вкурил, поэтому буду задавать мелкие вопросы по ходу (в т.ч. и по lua).
1) Зачем создавать maskx? Нельзя ли результат класть в mask (она же локальная для dss_match)?
2) Зачем объявлять через local индекс цикла for?
3) Как Вы надыбали такие чудесные конструкции как #diz для длины и dss_mask:sub(-1,-1) для подстроки? Они же не документированы...
Ответы по Lua:
1) Можно.
2) Незачем. На самом деле, это получаются 2 разные, хоть и одноимённые, переменные.
3) Всё это документировано в мануале Lua.
-- #diz даёт длину diz в байтах. Чтобы получить длину в символах, нужно diz:len().
-- sub(-1,-1) - это то же самое, что sub(-1), то-есть, получение последнего символа.

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Mon 25 Feb, 2013 12:14

Я Lua ещё сам изучаю. Совершенно забыл, что в for переменная локальная.
О # как-то не задумывался, пожалуй, len будет правильней.
Поправил размеры диалога. Добавил вставку CtrlV ShiftIns и пр.


Интересный визуальный глюк возникает, если из диалога выйти в режим Search

П.С. Выяснил, глюк возникает из-за плагина PanelTabs.
Разум когда-нибудь победит.

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Tue 26 Feb, 2013 08:47

Подправил макрос в предыдущем посте. После выхода из диалога нажатая клавиша сначала выполняется как макрос через eval, а если такого макроса нет, передаётся дальше через Keys.
Разум когда-нибудь победит.

User avatar
zg
zero-gravity
Posts: 5313
Joined: Tue 15 Mar, 2005 17:36
Location: riga
Been thanked: 48 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by zg » Tue 26 Feb, 2013 15:06

с диалоговой процедурой:

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Tue 26 Feb, 2013 16:51

zg wrote:с диалоговой процедурой
Класс!
Разум когда-нибудь победит.

yms
Posts: 209
Joined: Sun 14 Jun, 2009 10:38
Been thanked: 2 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by yms » Tue 26 Feb, 2013 19:22

В принципе я собирался плагин на 3.0 перевести...
так шо, уже неактуально? :)

User avatar
sToLp
Posts: 767
Joined: Thu 23 Jul, 2009 10:16
Has thanked: 57 times
Been thanked: 5 times

Re: DescSS — поиск и выделение по описаниям файлов

Post by sToLp » Tue 26 Feb, 2013 19:32

yms wrote:В принципе я собирался плагин на 3.0 перевести...
Если есть возможность/время/желание — сделайте пожалуйста, а то пока ещё луа освоится...

User avatar
HaRT
Moderator
Posts: 8118
Joined: Tue 30 Aug, 2005 17:21
Location: Санкт-Петербург
Has thanked: 68 times
Been thanked: 107 times

Re: DescSS — поиск и выделение по описаниям файлов

Post by HaRT » Tue 26 Feb, 2013 19:39

yms wrote:В принципе я собирался плагин на 3.0 перевести...
Актуально, особенно если заодно добавите поддержку регулярных выражений, — конечно, если FAR API предоставляет такую возможность.
Фар есть инструмент, а не нянька. © 2009 DrKnS

Smitis
Posts: 1492
Joined: Fri 18 Mar, 2005 12:51
Location: Питер
Has thanked: 14 times
Been thanked: 24 times
Contact:

Re: DescSS — поиск и выделение по описаниям файлов

Post by Smitis » Wed 27 Feb, 2013 14:02

yms wrote:В принципе я собирался плагин на 3.0 перевести...
так шо, уже неактуально? :)
Если плагин будет, это хорошо. А то количество макросов скоро зашкалит за все разумные пределы :)

А пока очередная серия версия с диалоговой процедурой от zg, с обработкой пробела (был забыт), отключением перемещения курсора при щёлканьи мышью по строке ввода, с выполнением макросов, после закрытия диалога и пр. и пр.

На этом фантазия пока закончилась...
Может только обработку каких клавиш пропустил
Разум когда-нибудь победит.

User avatar
John Doe
Бюрократ
Posts: 11421
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 17 times
Been thanked: 101 times

Re: DescSS — поиск и выделение по описаниям файлов

Post by John Doe » Wed 27 Feb, 2013 14:08

Smitis wrote:Если плагин будет, это хорошо. А то количество макросов скоро зашкалит за все разумные пределы :)
А конструктивные соображения есть?
В чём недостаток этого макроса по сравнению с плагином?
Тормозит? Не всё обрабатывает?

Post Reply

Return to “Полезные макросы и скрипты”