Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[18.118.12.54] |
|
Прикр. сообщ.
#1
,
|
|
|
Far Manager
Windows. FreeWare. Многофункциональный файловый менеджер для работы с различными файлами, позволяет просматривать файлы и каталоги, редактировать, копировать и переименовывать файлы. Поддерживает Unicode имеет удобный и простой в использовании пользовательский интерфейс с многоязычной поддержкой. Позволяет работать с архивами, FTP-клиентами, и просматривать сеть с помощью реализованных в стандартную поставку плагинов. Кроме того есть возможность расширения функциональности за счет подключения дополнительных плагинов. Ну очень странно что его уже давным давно не включили в разделе "Полезного ПО" Подключаемые модули (плагины) Возможности FAR существенно расширяются благодаря плагинам различного назначения: Домашняя страничка: https://farmanager.com |
Сообщ.
#1
,
|
|
|
Lua-скрипт EditorTools
Позволяет подключать и исполнять в редакторе Far'а различные обработчики - фильтры, компиляторы, интерпретаторы. Исполнять их без отрытия дополнительных окон, отлавливать stdout и stdrr, загружать результаты обработки назад в редактор, выводить сообщения об ошибках и результатах обработки в виде диалогов. Возможно кому-то пригодится. Предыстория Для быстрого редактирования файлов - встроенный редактор Far'а просто прекрасен. Но, к сожалению, определенных функций в нем не хватает. Конечно можно, при наличии времени и сил, сесть и написать свой инструмент обработки в виде полноценного плагина, либо Lua-скрипта. Меня же заинтересовал чисто практический вопрос - найти способ подключения уже готовых инструментов не через подсистему ассоциаций файлов. Надоело сохраняться, обрабатывать файл, потом опять грузить файл в редактор. Ну и вот родилась идея создать более-менее универсальное средство. Прошу учесть - это моя первая программа на языке Lua, так что принимайте мой отказ от ответственности, еличе На момент написания скрипта мне нужно было подключить: Функионал Команды обработки прописываются в файл конфигурации EditorTools.conf, который лежит рядом с макросом. Программы могут работать в четырех режимах: 1) Filter Используется для запуска программ, которые могут непосредственно вносить изменения в файл. После выполнения содержимое редактора заменяется результатом обработки 2) Pipe Используется для запуска программ, которые могут читать и обрабатывать файл, но вывод умеют делать только в STDOUT После выполнения содержимое редактора заменяется результатом обработки 3) Compiler Используется для запуска компиляторов После выполнения выводится диалог об успешной компиляции, либо диалог, содержащий ошибки компилятора 4) Execute Используется для запуска как правило интерпретаторов После выполнения выводится диалог, в котором отображается результат обрабтки текста внешней программой Скрипт EditorTools.lua Скрытый текст ------------------------------------------------------------------------------------------------------------------------ -- Скрипт EditorTools v.1.1 -- подключение внешних инструментов в редакторе Far'а -- -- 2020 (C) Автор Majestio aka JoeUser -- -- http://majestio.info -- ------------------------------------------------------------------------------------------------------------------------ -- local inspect = require('inspect') local ScriptName = ... local EOPT_BOM = 0x00000200 local BTYPE_STREAM = 1 local SW_HIDE = 0 ------------------------------------------------------------------------------------------------------------------------ local EditorTools = function () local CurPath = mf.fsplit(ScriptName,3) local ConfigName = ScriptName:gsub("[^.]+$","conf") local Conf = io.open(ConfigName,"r") -- читаем файл конфигурации ------------------------------------------------------------------------------------------ if Conf == nil then far.Message('Файл конфигурации нельзя прочесть!', 'Ошибка', ';Ok', 'w') return else local Cmd = {} local Idx = 1 -- разбираем файл конфигурации на список "инструментов" ------------------------------------------------------------ for line in Conf:lines() do if regex.match(line,'^(F|P|C|E)') then for w1,w2,w3 in regex.gmatch(line, "^(F|P|C|E)\\s*,\\s*'\\s*([^']+?)\\s*'\\s*,\\s*'\\s*([^']+?)\\s*'\\s*$") do Cmd[Idx] = {w1,w2,w3} end Idx = Idx + 1 end end Conf:close() -- формируем и выводим диалог выбора "инструментов" ---------------------------------------------------------------- local Choice = '' for Idx = 1, #Cmd do Choice = Choice..Cmd[Idx][2]..'\n'; end local ChoiceIdx = Menu.Show(Choice, nil, 8+0x200) if ChoiceIdx == 0 then return end -- формируем имя временного файла для сброса содержимого редактора ------------------------------------------------- math.randomseed(os.time()) local RndNumber = math.random(1000) local EditorFullName = editor.GetFileName() local EditorFilePath = regex.match(EditorFullName,"^(.+\\\\).+$") local EditorFileName = regex.match(EditorFullName,"^.+\\\\([^\\.]+)\\.*.*$") local EditorFileExt = regex.match(EditorFullName,"^.+?\\.([^\\.]+)$") if EditorFileExt == nil then EditorFileExt = "" end local TmpName = EditorFilePath..EditorFileName..'-tmp-'..RndNumber..'.'..EditorFileExt local OutName = EditorFilePath..EditorFileName..'-tmp-'..RndNumber..'.'.."out" local ResName = EditorFilePath..EditorFileName..'-tmp-'..RndNumber..'.'.."res" local ErrName = EditorFilePath..EditorFileName..'-tmp-'..RndNumber..'.'.."err" -- в командной строке производим замены в плэйсхолдерах ------------------------------------------------------------ local CmdName = regex.gsub(Cmd[ChoiceIdx][3],"%p",EditorFilePath) -- %p на значение EditorFilePath CmdName = regex.gsub(CmdName,"%n",EditorFileName) -- %n на значение EditorFileName CmdName = regex.gsub(CmdName,"%e",EditorFileExt) -- %e на значение EditorFileExt CmdName = regex.gsub(CmdName,"%t",TmpName) -- %t на значение TmpName CmdName = regex.gsub(CmdName,"%o",OutName) -- %o на значение OutName CmdName = regex.gsub(CmdName,"%r",ResName) -- %r на значение ResName -- запускаем внешнюю обработку в зависимости от "режима" выбранного инструмента ------------------------------------ if WriteFile(TmpName) ~= nil then local Out, Err = ExecCommand(CmdName, TmpName, OutName, ResName, ErrName, Cmd[ChoiceIdx][1]) if Cmd[ChoiceIdx][1] == "C" then if Err == "" or Err == nil then far.Message("Компиляция прошла удачно", 'Результат компиляции', ';Ok', 'k') else far.Message(win.OemToUtf8(Err), 'Ошибка', ';Ok', 'w') end else if Out ~= "" and Out ~= nil then if Cmd[ChoiceIdx][1] == "E" then far.Message(win.WideCharToMultiByte(win.MultiByteToWideChar(Out,1251),65001), 'Результат выполнения', ';Ok', 'k') else LoadContent(Out) end else if Err == "" or Err == nil then far.Message('Обработчик вернул пустой вывод!', 'Ошибка', ';Ok', 'w') end end end else far.Message('Ошибка записи временного файла!!', 'Ошибка', ';Ok', 'w') end end end ------------------------------------------------------------------------------------------------------------------------ -- Загрузка файла в редактор ------------------------------------------------------------------------------------------------------------------------ function LoadContent(Content) local Ei = editor.GetInfo() local EId = Ei.EditorID local Flags = far.Flags editor.UndoRedo(EId, Flags.EUR_BEGIN) editor.Select(EId, BTYPE_STREAM, 1, 1, 1, Ei.TotalLines+1) editor.DeleteBlock(EId) Content = regex.gsub(Content,"^(\xef\xbb\xbf)","") editor.InsertText(EId,Content) editor.UndoRedo(EId,Flags.EUR_END) editor.SetPosition(EId, 1, 1) end ------------------------------------------------------------------------------------------------------------------------ -- Запуск процесса по обработке файла ------------------------------------------------------------------------------------------------------------------------ function ExecCommand(CmdName, TmpName, OutName, ResName, ErrName, Mode) local RetOut, RetErr local File = io.popen(('"%s >"%s" 2>"%s"'):format(CmdName, OutName, ErrName),"w") if File == nil then far.Message('Ошибка при запуске команды!', 'Ошибка', ';Ok', 'w') return nil, nil end File:close() local TheName = OutName if Mode ~= "P" and Mode ~= "E" then TheName = ResName end if win.GetFileInfo(TheName) ~= nil then OutFile = io.open(TheName) if OutFile~= nil then RetOut = OutFile:read("*a") OutFile:close() end end if win.GetFileInfo(ErrName) ~= nil then ErrFile = io.open(ErrName) if ErrFile~= nil then RetErr = ErrFile:read("*a") ErrFile:close() end end win.ShellExecute(nil,nil,win.GetEnv"COMSPEC",('/c "del "%s" "%s" "%s" "%s"'):format(TmpName, OutName, ResName, ErrName),nil,SW_HIDE) return RetOut, RetErr end ------------------------------------------------------------------------------------------------------------------------ -- Запись файла ------------------------------------------------------------------------------------------------------------------------ function WriteFile (FileName) local Info = editor.GetInfo() local File = io.open(FileName,"wb") if File == nil then far.Message('Ошибка записи временного файла!', 'Ошибка', ';Ok', 'w') return nil else if (bit.band(Info.Options, EOPT_BOM) == EOPT_BOM) then File:write(string.char(239,187,191)) end for Line = 1, Info.TotalLines do local Gs = editor.GetString(Info.EditorID, Line, 0) File:write(Gs.StringText, Gs.StringEOL) end File:close() return Info.TotalLines end end ------------------------------------------------------------------------------------------------------------------------ -- Macro ------------------------------------------------------------------------------------------------------------------------ Macro { area="Editor"; key="CtrlE"; flags=""; description="EditorTools"; action = function() EditorTools() end; } Пример конфига EditorTools.conf Скрытый текст ; Поля конфига следующие: ; ; Режим, "Название-инструмента", "командная строка" ; ; Режим: ; ; [F]ilter - записываем временный файл, обрабатываем его, потом загружаем в редактор ; [P]ipe - записываем временный файл, обрабатываем его, но загружаем STDOUT программы ; [C]ompiler - сохраняем файл, запускаем команду компилятора ; [E]xecute - сохраняем файл, запускаем команду интерпретатора, результат выводим в виде диалога ; ; Плейсхолдеры: ; ; %p - путь к файлу в редакторе ; %n - имя файла в редакторе (без расширения) ; %e - расширение имени файла в редакторе ; %t - полное имя временного файла ; %o - полное имя временного файла-результата (куда пишется из пайпа) ; %r - полное имя временного файла-результата (куда может писать сама программа) ; ; Пример: ; ; F,'Инструмент-1','comm-1.cmd' ; P,'Инструмент-2','comm-2.cmd' ; C,'Инструмент-3','comm-3.cmd' ; E,'Инструмент-4','comm-4.cmd' ; P,'AStyle (Space-P)','C:\Tools\AStyle\AStyle.exe --options=C:\Tools\AStyle\.astylerc-space --stdin=%t' F,'AStyle (Space-F)','C:\Tools\AStyle\AStyle.exe --options=C:\Tools\AStyle\.astylerc-space --stdin=%t --stdout=%r' P,'TidyP','C:\Tools\Tidy\tidy.exe -config c:\Tools\Tidy\tidy.conf "%t"' P,'Hello Ruby','ruby.exe C:\Tools\Far3-x64\Profile\Macros\scripts\EditorTools\hello.rb' P,'Test Perl-P','perl.exe C:\Tools\Far3-x64\Profile\Macros\scripts\EditorTools\test-p.pl "%p%n.%e"' F,'Test Perl-F','perl.exe C:\Tools\Far3-x64\Profile\Macros\scripts\EditorTools\test-f.pl "%t" "%r"' C,'Компилировать FASM программу','C:\Tools\Fasm\FASM.CMD "%t" "%p%n.exe"' E,'Исполнить Perl скрипт','perl.exe %t' E,'Исполнить SWI-Prolog скрипт','C:\Tools\Prolog\bin\swipl.exe -q -f %t' Мои конфиги форматеров Скрытый текст .astylerc-space align-pointer=type align-reference=type attach-classes attach-closing-while attach-extern-c attach-inlines attach-namespaces attach-return-type break-one-line-headers close-templates delete-empty-lines indent-cases indent-classes indent-col1-comments indent-modifiers indent-namespaces indent-preproc-block indent-preproc-define indent-switches indent=spaces=2 keep-one-line-blocks max-continuation-indent=40 min-conditional-indent=1 pad-comma pad-header pad-oper remove-brackets style=java unpad-paren .astylerc-tabs align-pointer=type align-reference=type attach-classes attach-closing-while attach-extern-c attach-inlines attach-namespaces attach-return-type break-one-line-headers close-templates delete-empty-lines indent-cases indent-classes indent-col1-comments indent-modifiers indent-namespaces indent-preproc-block indent-preproc-define indent-switches indent=force-tab=2 keep-one-line-blocks max-continuation-indent=40 min-conditional-indent=1 pad-comma pad-header pad-oper remove-brackets style=java unpad-paren tidy.conf // sample config file for HTML tidy indent: auto indent-spaces: 2 wrap: 0 markup: yes output-xml: no input-xml: no show-warnings: yes numeric-entities: yes quote-marks: yes quote-nbsp: yes quote-ampersand: no break-before-br: no uppercase-tags: no uppercase-attributes: no char-encoding: utf8 new-inline-tags: cfif, cfelse, math, mroot, mrow, mi, mn, mo, msqrt, mfrac, msubsup, munderover, munder, mover, mmultiscripts, msup, msub, mtext, mprescripts, mtable, mtr, mtd, mth new-blocklevel-tags: cfoutput, cfquery new-empty-tags: cfelse drop-empty-elements: no Установка Скрипт и его конфиг нужно переписать в каталог скриптов (в свой подкаталог). Перезапустить Far. Для себя я настроил Far так, чтобы каталог профилей лежал рядом, а не в домашнем каталоге. По итогу у меня макрос лежит в каталоге - C:\Tools\Far3-x64\Profile\Macros\scripts\EditorTools Если будут вопросы - прошу в личку. Чтобы не засорять тред про Far. |
Сообщ.
#2
,
|
|
|
А чем он лучше Total Commander-a ?
|
Сообщ.
#3
,
|
|
|
Цитата ... @ А чем он лучше Total Commander-a ? Три преимущества (ну на вкус и цвет): * удобная работа с консольными программами * встроенный быстрый редактор, который как и сам Фар можно обвесить плагинами * уже давно подключили поддержку Lua, с нативными плагинами можно не париться |
Сообщ.
#4
,
|
|
|
Цитата ... @ А чем он лучше Total Commander-a ? Total - это как DOS Navigator: швейцарский нож, уже не помещающийся в руку из-за неудобной толщины. А вот FAR - это классический Norton, быстро и легко. Мультитул, у которого можно отстегнуть всё лишнее. |
Сообщ.
#5
,
|
|
|
Цитата Mr.Delphist @ А вот FAR - это классический Norton, быстро и легко. Мультитул, у которого можно отстегнуть всё лишнее. Когда-то был более удачный вариант - Volkov Commander, типа Нортона - но гораздо шустрее и меньше хавал ресурсов. А на счет FAR'а - полностью согласен. А если его запускать под ConEmu, то еще добавляется мешок сахара. |
Сообщ.
#6
,
|
|
|
Я даже видел гика, что запускал FAR из-под вайна вместо MC в линухе.
|
Сообщ.
#7
,
|
|
|
Цитата Qraizer @ видел гика, что запускал FAR из-под вайна вместо MC в линухе. О, мсье знает толк в извращениях! |
Сообщ.
#8
,
|
|
|
Цитата Qraizer @ Я даже видел гика, что запускал FAR из-под вайна вместо MC в линухе. Мну сейчас запускает Far2 из под Wine 6.10 в рамках LiveCD Linux Puppy (пакет собранный взял из топика форума Puppy) P.S. После запуска Far2 через команду терминала: wine Far.exe дальше запускаю Total Commander, а через него повторно Far2 для получения графического вида гуи Fara Windows софт, запускаемый в рамках окружения Linux, зачастую показывает лучшую "рабочесть" чем в родной для него Windows! и это приятно удивляет и при этом не требует гигабайт дискового пространства для установки Windows системы нативно или в VM (виртуальные машины) |