Пометить на панелях файлы с одинаковым содержимым независимо от имён

Столкнулись с проблемой в использовании макросов? Здесь можно получить помощь.
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

Latest post of the previous page:

Впрочем, решаемо:

Code: Select all

local function CreateList(_Panel, WhatPanel, whatpanel)
	local Result = {}
	local res_status
	local Path = _Panel.Path..(_Panel.Path:sub(-1) == '\\' and '' or '\\')
	local i1 = 1
	local i2 = _Panel.Selected and _Panel.SelCount or _Panel.ItemCount
	local GetFun = _Panel.Selected and panel.GetSelectedPanelItem or panel.GetPanelItem
	for i = i1, i2 do
		local Item = GetFun(nil, whatpanel, i)
		if not Item.FileAttributes:match("d")
		then
			local	FullName = Path..Item.FileName
			local	plgin_call_res = Plugin.SyncCall("E186306E-3B0D-48C1-9668-ED7CF64C0E65", "gethash", 'SHA-512', FullName, true)
			if	plgin_call_res == "userabort"
			then	res_status = plgin_call_res
				break
			end
			local sKey = ('%.10d;%s'):format(
				Item.FileSize,
			--	Item.FileSize == 0 and (' '):rep(128) or
				plgin_call_res
					)
			if Result[sKey] == nil then Result[sKey] = { } end
			tin(Result[sKey], Item.FileName)
		end
	end
	return Result, res_status
end -- CreateList
.. и:

Code: Select all

	local AList, act_status
	local PList, pas_status
	AList, act_status = CreateList(APanel, 0, 1)
	if act_status == "userabort" then goto after_create_list end
	PList, pas_status = CreateList(PPanel, 1, 0)
	if pas_status == "userabort" then goto after_create_list end
	::after_create_list::
--	local ASelList, PSelList, KeyList = { }, { }, { }
	local ASelList, PSelList = { }, { }
Да, я знаю что GOTO это плохо, только не знаю почему :)
Думаю что так же как и со всем остальным,
в одних ситуациях это хорошо, а в других - плохо
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by buniak_a_h »

citRiks wrote: Fri 15 Jan, 2021 21:06 buniak_a_h,
а есть идеи как отменить calculations не выходя из ФАРа ?
А то он пока не досчитает не успокоится..
Да, как-то неаккуратно.
После строки
for i=i1,i2 do
надо вставить:

Code: Select all

   if mf.waitkey(1,0) == 'Esc' and 
      far.Message('Вы действительно хотите прервать процесс сравнения файлов?', 'Сравнение панелей по содержимому', ';YesNo', 'w') == 1 then
    break
   end
То, что Вы написали я, извините, не анализировал - очень много буковок
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by buniak_a_h »

Получилось так:
  1. --[[
  2.  
  3. Вариант группирования файлов по длине и CRC, обхода файлов одной панели и поиска на другой
  4.  
  5. "парных" (совпадающих по длине и CRC).
  6.  
  7. --]]
  8.  
  9. --local F = far.Flags
  10.  
  11. --local DialogTools = require"BAX.DialogTools"
  12.  
  13. --local GetMsgEx = require"BAX.GetMsg"
  14.  
  15. local tin = table.insert
  16.  
  17. -- Сравнение панелей по содержимому.
  18.  
  19. -- Выделяются файлы, копия которых (безотносительно к имени) имеется на другой панели
  20.  
  21. ----[[*D*]]local le = require"le"
  22.  
  23. -------------------------------------------------------------------------------------
  24.  
  25. --local function CmpDial()
  26.  
  27. -- local DlgItems = {}
  28.  
  29. -- local function Add(DItem) tin(DlgItems, DialogTools.DialogItem(DItem)) end
  30.  
  31. -- local h,w=13,70
  32.  
  33. -- Add{'DI_DOUBLEBOX',x1=0,y1=0,x2=w,y2=h,text='Сравнение панелей'}
  34.  
  35. -- Add{'DI_CHECKBOX', x1=3,y1=2,Text='При сравнении учитывать дату'; Checked=0}
  36.  
  37. -- Add{'DI_CHECKBOX', x1=3,y1=3,Text='Выделить одинаковые файлы на панелях'; Checked=1}
  38.  
  39. -- Add{'DI_TEXT', x1=1,x2=w-2,y1=5; Text='Выполнить сценарий для совпавших файлов:'; Flags='DIF_CENTERTEXT'}
  40.  
  41. -- Add{'DI_TEXT', x1=3;y1=6;Text='Для файлов с активной  панели (%1 - имя файла)'}
  42.  
  43. -- Add{'DI_EDIT', x1=3,x2=w-4,y1=7}
  44.  
  45. -- Add{'DI_TEXT', x1=3;y1=8;Text='Для файлов с пассивной панели (%1 - имя файла)'}
  46.  
  47. -- Add{'DI_EDIT', x1=3,x2=w-4,y1=9}
  48.  
  49. -- Add{'DI_TEXT', x1=-1, y1=10, Flags='DIF_SEPARATOR'}
  50.  
  51. -- Add{'DI_BUTTON', y1=11, Flags='DIF_CENTERGROUP|DIF_DEFAULTBUTTON', Text='Ok'}
  52.  
  53. -- Add{'DI_BUTTON', y1=11, Flags='DIF_CENTERGROUP', Text='Cancel'}
  54.  
  55. -- far.Dialog('44C0A2E9-5F23-4E5C-9BE9-D94F3849D63B', -1,-1,w,h,nil,DlgItems, F.FDLG_SMALLDIALOG)
  56.  
  57. --end -- CmpDial
  58.  
  59. -------------------------------------------------------------------------------------
  60.  
  61. local function CmpFunc()
  62.  
  63.  local function CreateList(_Panel, WhatPanel, whatpanel)
  64.  
  65.   local Result ={}
  66.  
  67.   local Path = _Panel.Path .. (_Panel.Path:sub(-1)=='\\' and '' or '\\')
  68.  
  69.   local i1,i2,GetFun=1,_Panel.Selected and _Panel.SelCount or _Panel.ItemCount, _Panel.Selected and panel.GetSelectedPanelItem or panel.GetPanelItem
  70.  
  71.   for i=i1,i2 do
  72.  
  73.    if mf.waitkey(1,0) == 'Esc' and
  74.  
  75.       far.Message('Вы действительно хотите прервать процесс сравнения файлов?', 'Сравнение панелей по содержимому', ';YesNo', 'w') == 1 then
  76.  
  77.     break
  78.  
  79.    end
  80.  
  81.    local Item = GetFun(nil, whatpanel, i)
  82.  
  83.    if not Item.FileAttributes:match"d" then
  84.  
  85.     local FullName = Path .. Item.FileName
  86.  
  87.     local sKey = ('%.10d;%s'):format(Item.FileSize, Item.FileSize == 0 and (' '):rep(128) or Plugin.SyncCall("E186306E-3B0D-48C1-9668-ED7CF64C0E65", "gethash", 'SHA-512', FullName, true))
  88.  
  89.     if Result[sKey] == nil then Result[sKey] = {} end
  90.  
  91.     tin(Result[sKey], Item.FileName)
  92.  
  93.    end
  94.  
  95.   end
  96.  
  97.   return Result
  98.  
  99.  end -- CreateList
  100.  
  101.  --local tStart = Far.UpTime
  102.  
  103.  local AList, PList = CreateList(APanel, 0,1), CreateList(PPanel,1,0)
  104.  
  105.  --local ASelList, PSelList, KeyList = {}, {}, {}
  106.  
  107.  local ASelList, PSelList = {}, {}
  108.  
  109.  local i,v = next(AList)
  110.  
  111.  while i do
  112.  
  113.   if PList[i] then
  114.  
  115.    --KeyList[i] = {v, PList[i]}
  116.  
  117.    for _,w in ipairs(v) do tin(ASelList, w) end
  118.  
  119.    for _,w in ipairs(PList[i]) do tin(PSelList, w) end
  120.  
  121.   end
  122.  
  123.   i,v = next(AList, i)
  124.  
  125.  end
  126.  
  127.  if #ASelList > 0 then
  128.  
  129.   Panel.Select(0, 0)
  130.  
  131.   Panel.Select(1, 0)
  132.  
  133.   Panel.Select(0, 1, 2, table.concat(ASelList, '\n'))
  134.  
  135.   Panel.Select(1, 1, 2, table.concat(PSelList, '\n'))
  136.  
  137.   --CmpDial()
  138.  
  139.  end
  140.  
  141.  ----[[*D*]]le({Time=Far.UpTime-tStart, AList=AList, PList=PList, ASelList=ASelList, PSelList=PSelList})
  142.  
  143. end -- CmpFunc
  144.  
  145. -------------------------------------------------------------------------
  146.  
  147. MenuItem {
  148.  
  149.   description = "Сравнение панелей по содержимому";
  150.  
  151.   menu   = "Plugins";
  152.  
  153.   area   = "Shell";
  154.  
  155.   guid   = "C95988A8-E802-4541-A2F3-323D8FA89A12";
  156.  
  157.   text   = function(menu,area)
  158.  
  159.    return "Сравнение панелей по содержимому"
  160.  
  161.   end;
  162.  
  163.   action = function(OpenFrom,Item)
  164.  
  165.    CmpFunc()
  166.  
  167.   end;
  168.  
  169. }
  170.  
  171. -------------------------------------------------------------------------
  172.  
  173. NoMacro{ -- Для активации уберите 'No' в начале строки
  174.  
  175.   id="748A9A2C-1D4B-4A85-9B27-B881F98BAC90";
  176.  
  177.   area="Shell";
  178.  
  179.   key=""; -- Сюда свой хоткей вставить
  180.  
  181.   description = "Сравнение панелей по содержимому";
  182.  
  183.   flags="";
  184.  
  185.   condition=function(key, data) return APanel.Visible and PPanel.Visible end;
  186.  
  187.   action=function(data)
  188.  
  189.    CmpFunc()
  190.  
  191.   end;
  192.  
  193. }
  194.  
  195.  
По-прежнему настройка хоткея и включение макроса - на совести юзера.
ContentCompare.lua.7z
Для удобства скачивания. То же самое, что в тексте.
(1.96 KiB) Downloaded 111 times
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h,
Еще мне показалось что неаккуратно это когда вычисляем бессмысленно файлы,
у которых нет такого же размера файла на противоположной панели
Положил фикс сюда:
https://github.com/dr-dba/far-lua-panel-duplicates
(со ссылкой на оригинал конечно)
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h wrote: Fri 15 Jan, 2021 22:02 Получилось так:
Подход с использованием waitkey весьма интересный,
но замедляет на больших директориях вычисления раз в *дцать.
Без WaitKey: 700 мс
С WaitKey: 11 сек (11,500+ мс)
а мною предложенное не замедляет :)
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by buniak_a_h »

citRiks wrote: Fri 15 Jan, 2021 22:46
buniak_a_h wrote: Fri 15 Jan, 2021 22:02 Получилось так:
Подход с использованием waitkey весьма интересный,
но замедляет на больших директориях вычисления раз в *дцать.
Без WaitKey: 700 мс
С WaitKey: 11 сек (11,500+ мс)
а мною предложенное не замедляет :)
1. Если я правильно понял, Вы анализируете код выхода из плагина. Это - правильно, но если много очень маленьких файлов, трудно снять именно плагин (нажать Esc во время вычисления КС). Или плагин будет прерван даже если нажать во время выполнения макроса?
2. Про коды возврата не видел…
waitkey(1,… ) - одна миллисекунда. Не ожидал, что это может замедлить.
citRiks wrote: Fri 15 Jan, 2021 21:23 Впрочем, решаемо: …
Это на каком языке? Вроде, в lua нет ни goto, ни меток вида ::label::. Или я чего-то не знаю?
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h wrote: Fri 15 Jan, 2021 23:51 Если я правильно понял, Вы анализируете код выхода из плагина.
это да
buniak_a_h wrote: Fri 15 Jan, 2021 23:51 Это - правильно, но если много очень маленьких файлов, трудно снять именно плагин (нажать Esc во время вычисления КС)
может быть, но с маленькими файлами все и так пролетает очень быстро,
а проблемы есть с большими файлами, когда надо отменить,
потому что получается медленно/напрасно/передумали
buniak_a_h wrote: Fri 15 Jan, 2021 23:51 Или плагин будет прерван даже если нажать во время выполнения макроса?
хммм..
сложно проверить потому что у меня пока на том количестве мелких файлах (~ тысячи) пролетает быстро :)
но я конечно обращу внимание когда найду такую папку

Может быть, надо сделать комбинированниую отмену,
вместе с WaitKey мапример на каждом 20-м файле,
и вместе с проверкой на userabort в плагине,
ведь одно другому никак не мешает
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h wrote: Fri 15 Jan, 2021 23:51 waitkey(1,… ) - одна миллисекунда. Не ожидал, что это может замедлить.
может потому что все что пытается ловить реакции пользователя вынуждено синхронизироваться с основным потоком?
а когда без реакции пользователя, то шпарит себе не отвлекаясь ни на что ..
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by buniak_a_h »

citRiks wrote: Sat 16 Jan, 2021 09:23 сложно проверить
А вставить в цикл win.Sleep ?
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h, пока слету не уловил что и как это должно доказать ..?
И пока у меня и ни у кого (?) нет ощутимых проблем с юзабельностью, наверное не буду углубляться

PS
На всякий случай напомню, что самое главное это считать ТОЛьКО файлы которые имеют одинаковый размер с чем-либо на противоположной панели, вы это у себя пофиксили?
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

buniak_a_h wrote: Fri 15 Jan, 2021 23:51 Это на каком языке? Вроде, в lua нет ни goto, ни меток вида ::label::. Или я чего-то не знаю?
да, действительно, в чистом Луа 5.1 нет GOTO.
Но у нас это не чистое Луа 5.1 от производителя, а LuaJit 2.1.0,
кроме других отличий это включает элементы синтаксиса из Луа 5.2,
а в Луа 5.2 уже есть неимоверный прогресс ввиде оператора GOTO, куда ж без него :)
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by John Doe »

citRiks wrote: Fri 15 Jan, 2021 21:23 Да, я знаю что GOTO это плохо, только не знаю почему :)
Если вы обнаружили что goto решает вашу задачу, то с большой долей вероятности это означает что код нуждается в рефакторинге.
Разумеется избавление от goto не должно быть самоцелью, но как-то само собой получается, что после рефакторинга он оказывается не нужен.
https://t.me/FarManager — Telegram чат
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

John Doe,
Ну вот здесь например, лаконично, симметрично, выравнивание типа.
выравнивание позволяет видеть и опечатки и логику, аналогии.
не придумал как без ГОТО получилось бы лучше. есть идеи?

Code: Select all

	...
	AList, act_status = CreateList(APanel, 0, 1)
	if act_status == "userabort" then goto after_create_list end
	PList, pas_status = CreateList(PPanel, 1, 0)
	if pas_status == "userabort" then goto after_create_list end
	::after_create_list::
	...
User avatar
John Doe
Бюрократ
Posts: 13807
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 73 times
Been thanked: 426 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by John Doe »

Code: Select all

	...
	AList, act_status = CreateList(APanel, 0, 1)
	if act_status != "userabort" then
		PList, pas_status = CreateList(PPanel, 1, 0)
	end
	...
https://t.me/FarManager — Telegram чат
User avatar
citRiks
Posts: 1733
Joined: Fri 25 Oct, 2019 18:18
Has thanked: 610 times
Been thanked: 102 times

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by citRiks »

John Doe,
понятно, но симметрия нарушена..
мне лучше понимается когда все симметрично

Я бы сделал опрос, как визуально понятнее с первой доли секунды,
вариант с ГОТО или без ?
Примеры обоего выше
User avatar
buniak_a_h
Posts: 4236
Joined: Sat 20 Apr, 2013 00:17
Location: Санкт-Петробад
Has thanked: 222 times
Been thanked: 643 times
Contact:

Пометить на панелях файлы с одинаковым содержимым независимо от имён

Post by buniak_a_h »

John Doe, citRiks,переписка интересная, но для для темы "Ликбез по LUA"
John Doe, это же Ваша тема? Не могли бы Вы добавить туда что-то типа "отличия нашего LUA от стандартного LUA версии 5.1"
Post Reply

Return to “Нужна помощь”