Advertisement
Guest User

Plugin_VisualCompare.lua

a guest
Aug 4th, 2019
171
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.91 KB | None | 0 0
  1. -- Visual Compare files or folders for panels: Files, Branch, Temporary, Arclite, Netbox, Observer, TorrentView.
  2. -- v.1.7.1
  3. -- http://forum.ru-board.com/topic.cgi?forum=5&topic=49572&start=2080#6
  4. -- Версия 1.7.1. изменения:
  5. -- закомментирован диалог с путями сравнения пар файлов в строках 109 и 110
  6. -- уточнена логика вывода сообщения если один или оба файла нулевой длины
  7. -- VictorVG 05.08.2019 04:58:28 +0300
  8.  
  9. local ffi = require("ffi")
  10.  
  11. ffi.cdef([[
  12. typedef struct {
  13.   void*          hwnd;
  14.   uint32_t       wFunc;
  15.   const wchar_t* pFrom;
  16.   const wchar_t* pTo;
  17.   unsigned short fFlags;
  18.   int            fAnyOperationsAborted;
  19.   void*          hNameMappings;
  20.   const wchar_t* lpszProgressTitle;
  21. } SHFILEOPSTRUCTW;
  22. int SHFileOperationW(SHFILEOPSTRUCTW *);
  23. ]])
  24.  
  25. local FO_DELETE          = 0x0003
  26. local FOF_SILENT         = 0x0004
  27. local FOF_NOCONFIRMATION = 0x0010
  28.  
  29. local function utf16(str)
  30.   local strw = win.Utf8ToUtf16(str)
  31.   local result = ffi.new("wchar_t[?]", #strw/2+1)
  32.   ffi.copy(result, strw)
  33.   return result
  34. end
  35.  
  36. local function remove(fname)
  37.   local fileopw = ffi.new("SHFILEOPSTRUCTW")
  38.   fileopw.wFunc = FO_DELETE
  39.   fileopw.pFrom = utf16(fname.."\0\0")
  40.   fileopw.pTo = utf16("\0\0")
  41.   fileopw.fFlags = FOF_SILENT+FOF_NOCONFIRMATION
  42.   return 0 == ffi.load("shell32").SHFileOperationW(fileopw)
  43. end
  44.  
  45. local VisComp = "AF4DAB38-C00A-4653-900E-7A8230308010"
  46. local CopyDl1 = "42E4AEB1-A230-44F4-B33C-F195BB654931"
  47. local CopyDl2 = "FCEF11C4-5490-451D-8B4A-62FA03F52759"
  48. local CopyDl3 = "2430BA2F-D52E-4129-9561-5E8B1C3BACDB"
  49. local ExtrDlg = "97877FD0-78E6-4169-B4FB-D76746249F4D"
  50. local TorrDlg = "00000000-0000-0000-546F-7272656E7400"
  51. local MArcDlg = "C5508DDB-5175-4736-9A10-C8F6EED7B32F"
  52.  
  53. local function f(p,f) if f:match("^[A-Z]:") then p=f elseif p=="" then p="\\" elseif f~=".." then if p:sub(-1,-1)=="\\" then p=p..f else p=p.."\\"..f end end return p end
  54. local function e(p,f)
  55.   local h=Far.DisableHistory(-1)
  56.   if f==".." then Panel.Select(0,1) end
  57.   Keys("F5"); p=p.."\\"
  58.   if Area.Dialog and Dlg.ItemType==4 and (Dlg.Id==CopyDl1 or Dlg.Id==CopyDl2 or Dlg.Id==CopyDl3 or Dlg.Owner==MArcDlg) then print(p) Keys("Enter") end
  59.   if Area.Dialog and (Dlg.ItemType==4 or Dlg.ItemType==8) and (Dlg.Id==CopyDl1 or Dlg.Id==CopyDl3 or Dlg.Owner==MArcDlg) then print(p) Keys("Enter") end -- fix 2nd dialog
  60.   if Area.Dialog and Dlg.Owner==TorrDlg then print(p) Keys("Enter") end
  61.   if Area.Dialog and Dlg.ItemType==7 and Dlg.Id==CopyDl1 then Keys("Enter") end
  62.   if Area.Dialog and Dlg.ItemType==4 and Dlg.Id==ExtrDlg then print(p) Keys("AltO Enter") end
  63.   Far.DisableHistory(h)
  64. end
  65.  
  66. local VC="Visual Compare"
  67. local msg=[[Selection wrong! - I don't know what to compare.
  68.  
  69. File compare modes by priority order:
  70. 1. At Active panel selected 2 files
  71. 2. At Active panel selected 1 file and Passive panel selected 1 file
  72. 3. At Active panel selected 1 file and 2nd under cursor
  73. 4. At Active panel selected 0 files, will be used file under cursor
  74. a) At Passive panel (plugin) can be selected 1 file under cursor
  75. b) At Passive panel (file or branch) any number of files
  76.    can be selected, will be used file under cursor                 ]]
  77.  
  78. Macro {
  79. description="VC: Визуальное сравнение файлов"; area="Shell"; key="CtrlAltC";
  80. condition = function()
  81.  if APanel.SelCount>2 and APanel.Plugin and (APanel.Format~="Branch") and (APanel.Prefix~="tmp") or APanel.SelCount==0 and PPanel.SelCount>1 and PPanel.Plugin and (PPanel.Format~="Branch") and (PPanel.Prefix~="tmp") or APanel.SelCount==0 and PPanel.SelCount==1 and (panel.GetCurrentPanelItem(nil,0).FileName~=panel.GetSelectedPanelItem(nil,0).FileName)
  82.  then far.Message(msg,VC)
  83.  else return true
  84.  end
  85. end;
  86. action = function()
  87.  local APR,PPR,AP,PP,AC,PC,AF,PF,ePF,APD,PPD,TMP,S2,CI = APanel.Prefix,PPanel.Prefix,APanel.Path0,PPanel.Path0,APanel.Current,PPanel.Current,APanel.Format,PPanel.Format,regex.new"netbox|observe|torrent","\\AP","\\PP",win.GetEnv("Temp").."\\~arc"
  88.  remove(TMP)
  89.  if APanel.SelCount==2 then
  90.    S2,PC,AC = true,panel.GetSelectedPanelItem(nil,1,1).FileName,panel.GetSelectedPanelItem(nil,1,2).FileName
  91.    --if not APanel.Left then AC,PC = PC,AC end
  92.  elseif APanel.SelCount==1 and PPanel.SelCount==1 then PC,AC = panel.GetSelectedPanelItem(nil,0,1).FileName,panel.GetSelectedPanelItem(nil,1,1).FileName
  93.  elseif APanel.SelCount==1 then S2,PC,AC = true,panel.GetSelectedPanelItem(nil,1,1).FileName,panel.GetCurrentPanelItem(nil,1).FileName
  94.    --Keys("Ins")
  95.    CI=panel.GetPanelInfo(nil,1).CurrentItem
  96.    panel.SetSelection(nil,1,CI,true)
  97.  end
  98.  local eAP,ePP = AF=="arc" or APR=="ma" or ePF:match(APR or ""),PF=="arc" or PPR=="ma" or ePF:match(PPR or "")
  99.  if S2 and eAP then
  100.    AP=TMP..APD PP=AP e(AP,AC)
  101.  elseif S2 then
  102.    PP=AP
  103.  else
  104.    if eAP then AP=TMP..APD e(AP,AC) end
  105.    if ePP then PP=TMP..PPD panel.SetActivePanel(nil,0) e(PP,PC) panel.SetActivePanel(nil,0) end
  106.  end
  107.  if CI then panel.SetSelection(nil,1,CI,false) end
  108.  AP,PP = f(AP,AC),f(PP,PC)
  109.  -- local APlen = AP:len()-PP:len()
  110.  -- far.Message("1st: "..PP..(APlen>0 and string.rep(" ",APlen) or "").."\n2nd: "..AP..(APlen<0 and string.rep(" ",-APlen) or ""),VC)
  111.  if AP==PP then far.Message("it's the same object\n\n1st: "..PP.."\n2nd: "..AP,VC)
  112.  else
  113.    local function checksz0(f)
  114.      local res=false
  115.      if not win.GetFileInfo(f).FileAttributes:find("d") then
  116.        local fh=io.open(f,"rb")
  117.        if fh then res=fh:read(1)==nil fh:close() end
  118.      end
  119.      return res and true or false
  120.    end
  121.    if checksz0(AP) or checksz0(PP) then far.Message("Comparison is pointless because one or both files of zero length",VC)
  122.    else
  123.      if APanel.Left
  124.      then Plugin.Command(VisComp,'"'..AP..'" "'..PP..'"')
  125.      else Plugin.Command(VisComp,'"'..PP..'" "'..AP..'"') Keys("Tab")
  126.      end
  127.    end
  128.  end
  129. end
  130. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement