Копирование файла в панель другого Фара

Хотите предложить идею нового плагина или знаете, что улучшить в существующем? Пишите сюда.
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

Копирование файла в панель другого Фара

Post by fml2 »

Latest post of the previous page:

Пока что это только хотелка, поэтому я думаю, что Мантис -- не совсем неправильно. А дальше пусть решают "боссы".
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

Я, конечно, может и не прав, но мне кажется, что реализовать эту "хотелку" можно было бы, если бы можно было запускать макрос по событию FE_REDRAW из панелей. Тогда этот макрос мог бы записывать, например, в специальный файл пути к директориям отображаемым в панелях, а другой экземпляр Far при необходимости этот файл бы считывал.
Если я не ошибаюсь с таким сценарием, то может быть можно пересмотреть вот это
Сообщение Shmuel » Ср 06 фев, 2013 03:59

John Doe писал(а):Действительно ли в перспективе все эти события станут доступны макросам?


Что касается панельных событий, то они предназначены для плагинов, создающих панели. А остальное по идее можно реализовать.

.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

iva wrote: если бы можно было запускать макрос по событию FE_REDRAW из панелей.
Об этом есть запись на багтрекере: http://bugs.farmanager.com/view.php?id=2826
iva wrote: Если я не ошибаюсь с таким сценарием,
Тут основная задача в другом: грамотно реализовать межпроцессное взаимодействие (IPC)
Max Rusov
Posts: 3651
Joined: Wed 23 Nov, 2005 11:11
Location: Москва-Питер
Has thanked: 2 times
Been thanked: 19 times

Копирование файла в панель другого Фара

Post by Max Rusov »

John Doe wrote:Тут основная задача в другом: грамотно реализовать межпроцессное взаимодействие (IPC)
Проще всего - через Shared Memory.
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

John Doe » Вт 13 янв, 2015 12:47
Тут основная задача в другом: грамотно реализовать межпроцессное взаимодействие (IPC)
Я понимаю, что реализовать такое копирование при помощи межпроцессного взаимодействия очень интересно. Но, если я не пропускаю какие-то подводные камни, мне видится другой путь.
А именно, каждый экземпляр FAR создаёт в определённом месте на диске файл, в который по событию FE_REDRAW записывает пути к директориям, отображаемым в панелях (про временные панели пока не думаем). При завершении работы FAR этот файл удаляет.
Теперь, если в каком-то экземпляре FAR пользователь вызывает диалог копирования в панели другого FAR, то нужно прочитать все файлы, созданные всеми экземплярами FAR, и дальше разбираться со списком директорий.
Может быть, пока FE_REDRAW недоступен, можно организовать такую запись информации о состоянии панелей по таймеру. Мне для этого умения не хватает.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

iva wrote: мне видится другой путь.
Выше по теме уже предлагалось. Да, это должно быть возможно, хоть и с ограничениями.
iva wrote: можно организовать такую запись информации о состоянии панелей по таймеру. Мне для этого умения не хватает.
У кого-то умения, а у кого-то желания.
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

Вот то, что я умею сходу. Не судите строго.
Чтобы работало нужно в %FARPROFILE% создать поддиректорию PanelInfo.
Пока я повесил запись состояния на Enter, а надо бы на событие смены папок или, хотя бы, на таймер .
Операцию получения данных от всех экземпляров FAR повесил на ShiftF7.
Как реализовать выбор из того списка, который получается, и собственно копирование я пока не знаю.
Attachments
CopyToOtherFar.lua.7z
(871 Bytes) Downloaded 167 times
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

Всем было бы удобнее, если бы вы разместили код не вложением, а прямо в тексте, в теге [code]...[/code]
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

вот уже чуть исправленное

Code: Select all

local unit = {}
 local FILENAME

local function ExpandEnv (s)
  return s:gsub("%%(.-)%%", win.GetEnv) -- подставляет значение %FARPROFILE%
end

-- Парсинг имени файла, на входе имя_файла
-- на выходе {диск, путь, имя, расширение}
local function ParseFileName(str)
	local a, b, c, d
	if str == nil then str="" end

	a = string.match(str, "^%s*(.*:)")
	str=str:gsub("^%s*(.*:)","")

	b=string.match(str, "^(.*)[\\/]")
	str=str:gsub("^(.*)[\\/]","")

	d=string.match(str, "%.([^%.]*)$")
	c=str:gsub("%.([^%.]*)$","")

	if d == nil then d="" end
	if c == nil then c="" end
	if b == nil then b="" end
	if a == nil then a="" end
	
	return a, b, c, d
end


do
 function unit.DefinePanelInfoFileName()
   local  Path = ExpandEnv([[%FARPROFILE%\PanelInfo\]])
   local List = far.GetDirList(Path)
   local no = 0
   if #List then
    for i = 1, #List do
     local a,b,c,d = ParseFileName(List[i].FileName)
     local n = tonumber(c)
     if no < n then no = n end
    end -- нашли максимум  
   end
   FILENAME = Path..(no+1) -- здесь надо брать номер на 1 больше, чем тот,
                                 -- который существует   
--   far.Message('FILENAME='..FILENAME) --
 end

 function unit.SavePanelInfo()
   if FILENAME == nil then unit.DefinePanelInfoFileName() end
   local f=io.output(FILENAME)
   local ADir = panel.GetPanelDirectory(nil,0)
   local BDir = panel.GetPanelDirectory(nil,1)
   f:write(ADir.Name.."\n")
   f:write(BDir.Name.."\n")
   f:close()
--   far.Message('WRITTEN: to '..FILENAME) --
 end

function unit.CopyToPanelsOfOtheFar()
   local  Path = ExpandEnv([[%FARPROFILE%\PanelInfo\]])
   local List = far.GetDirList(Path)
   local A = {}
   local B = {}
   for i = 1,#List do
     local name = List[i].FileName
     local f=io.input(name)
     A[i] = f:read()
     B[i] = f:read()
     f:close()
   end
   local s = 'LIST of directories'
   for i = 1,#List do
     s = s..'\nFAR<'..i..'>: \n'..A[i]..'\n'..B[i]
   end
   far.Message(s)
 end

 function unit.RemovePanelInfo()
   os.remove(FILENAME)
 end
end -- do
-----------------------------------------------------------------
Event { group = "ExitFAR", description = "Remove information file",
  action = function ()
    unit.RemovePanelInfo()
  end,
} -- Event "ExitFAR"

Macro { description="Save Panel Info to information file";
  area="Shell"; key="Enter";
  condition=function()
    unit.SavePanelInfo()
    return false
  end;
  action=function()
  end;
}

Macro { description="Get Panel Info from all Far's";
        area="Shell"; key="ShiftF7";
        action=function()
        unit.CopyToPanelsOfOtheFar()
        end;
}
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

Вроде такой вариант рабочий.
Напоминаю, что должна быть создана директория %FARPROFILE%\PanelInfo

Code: Select all

local unit = {}
 local FILENAME

local function ExpandEnv (s)
  return s:gsub("%%(.-)%%", win.GetEnv) -- подставляет значение %FARPROFILE%
end

do
 function unit.DefinePanelInfoFileName()
   local Path = ExpandEnv([[%FARPROFILE%\PanelInfo\]])
   FILENAME = Path..os.date("%d_%H_%M_%S") -- имя по дате
 end

 function unit.SavePanelInfo()
   if FILENAME == nil then unit.DefinePanelInfoFileName() end
   local f=io.output(FILENAME)
   local ADir = panel.GetPanelDirectory(nil,0)
   local BDir = panel.GetPanelDirectory(nil,1)
   f:write(ADir.Name.."\n")
   f:write(BDir.Name.."\n")
   f:close()
 end

function unit.CopyToPanelsOfOtherFar()
   local Path = ExpandEnv([[%FARPROFILE%\PanelInfo\]])
   local List = far.GetDirList(Path)
   local Items = {}
   local name = panel.GetCurrentPanelItem(nil,1) -- File to copy
   name = name.FileName
   local width = name:len() + 13
   for i = 1,#List do
     local name = List[i].FileName
     if name ~= FILENAME then                    -- Exclude itself
       local f=io.input(name)
       local A = f:read()
       local curw = A:len()
       if width < curw then width = curw end
       table.insert(Items,{ Flags = 0, Text = A })
       A = f:read()
       curw = A:len()
       if width < curw then width = curw end
       table.insert(Items,{ Flags = 0, Text = A })
       f:close()
     end
   end
  if #Items then                 
    local Form = {{"DI_LISTBOX", 0, 0, width+3, #Items+1, Items, 0, 0, 0, 
                   "Copy '"..name.."' to:"}}

    local function DlgProc (dlg, msg, param1, param2) end -- заглушка

    local hDlg = far.DialogInit("",5,5,8+width, 6+#Items, nil, Form, 0, DlgProc)
    local Index = far.DialogRun(hDlg) > 0 and
      far.SendDlgMessage(hDlg, far.Flags.DM_LISTGETCURPOS, 1).SelectPos or nil
    far.DialogFree(hDlg)
    if Index then
      local to = Items[Index].Text..[[\]]..name
      Keys("F5")
      print(to)
      Keys("Enter")
    end
  end
end

 function unit.RemovePanelInfo()
   os.remove(FILENAME)
 end
end -- do
-----------------------------------------------------------------
Event { group = "ExitFAR", description = "Remove information file",
  action = function ()
    unit.RemovePanelInfo()
  end,
} -- Event "ExitFAR"

Macro { description="Save Panel Info to information file";
  area="Shell"; key="Enter";
  condition=function()
    unit.SavePanelInfo()
    return false
  end;
  action=function()
  end;
}

Macro { description="Copy current file to other Far's";
        area="Shell"; key="ShiftF7";
        action=function()
          unit.CopyToPanelsOfOtherFar()
        end;
}
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

iva, вы напрасно усложнили задачу: не надо ничего копировать.
Достаточно только подставлять путь в стандартный диалог копирования/перемещения.

Что касается имён файлов, то для уникальности проще всего использовать Far.PID
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

Копирование файла в панель другого Фара

Post by fml2 »

iva, я думал сделать что-то более общее и сложное, на основе чего можно было бы довольно легко реализовать и копирование (но и многое другое) -- подход математика-теоретика. А вы быстро сделали нечто более ограниченное, но именно то, что надо -- подход инженера! :-)
iva
Posts: 128
Joined: Sat 02 Nov, 2013 21:32
Been thanked: 3 times

Копирование файла в панель другого Фара

Post by iva »

Я, к сожалению, исчерпал лимит свободного времени и в ближайшие дни не смогу дорабатывать код. Если кто-нибудь, доведёт до ума - было бы здорово.
Я планировал повесить запись в информационный файл, который сейчас повешен на Enter, на все кнопкосочетания, пробовал так

Code: Select all

  key=[[/[\w]/ Enter Tab Left Right Up Down Esc /F[1-9]/ F11 F12]]; 
Далее, надо было бы делать такую запись в режиме пост-обработки. Сходу, я не уверен, что правильно понял John Doe про Keys"Akey". Особенно меня смущает случай, когда нажата клавиша выхода из Far.
И, действительно, хорошо было бы встроится в стандартный диалог копирования, но я пока не умею.

fml2: Вы интересно расклассифицировали подходы.

P.S. A как оформляется "офтопик"?
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

iva wrote: P.S. A как оформляется "офтопик"?
Никак. Просто его следует избегать.
iva wrote: И, действительно, хорошо было бы встроится в стандартный диалог копирования, но я пока не умею.
Ваш макрос мог бы вызываться прямо из диалога копирования, а не из панелей.
User avatar
John Doe
Бюрократ
Posts: 13801
Joined: Wed 27 Apr, 2005 20:42
Has thanked: 72 times
Been thanked: 425 times
Contact:

Копирование файла в панель другого Фара

Post by John Doe »

Вот набросал что-то.

При вызове опрашивает прочие запущенные экземпляры фара, и предоставляет выбор из списка путей на их панелях.

Вызывается так:
— комбинацией CtrlUp (в предопредёлённых диалогах)
— из меню плагинов (во всех диалогах, а также в редакторе и командной строке)
Attachments
PickPathFromOtherFAR.lua.7z
(1.75 KiB) Downloaded 231 times
fml2
Posts: 534
Joined: Mon 09 Jul, 2012 22:10
Has thanked: 2 times
Been thanked: 8 times

Копирование файла в панель другого Фара

Post by fml2 »

Работает! Здорово, спасибо!

Есть еще следующие предложения. Я сам не уверен, стоит ли их реализовывать, но обдумать, по-моему, неплохо бы. Может, сделать опции?

1. Сортировать все пункты по алфавиту. Если других экземпляров Фара много, то уже не помнишь, где там что, и поэтому, наверное, будет легче найти искомый элемент, если элементы отсортированы по алфавиту.

2. Включать в список и пути из "собственного" экземпляра. Бывает, надо скопировать куда-то, и я точно знаю, что путь назначения где-то открыт. Но уже не помню где, т.к. внимание сконцентрировано только на одной (активной) панели -- настолько, что даже не помню, какой путь на неактивной.

3. Включать в список каждое значение только один раз, если один и тот же путь открыт в нескольких экземплярах Фара (т.е., иными словами, исключать дубликаты)

4. Сделать вызов скрипта возможным и из диалога перемещения файлов (а не только копирования)

Спасибо iva и вам за скрипт!
Post Reply

Return to “Предложения и идеи”