Задача интересная, хоть и специфическая.
На самом деле за всё время множество хотелок было по расширению метасимволов (не раз встречал как на форуме, так и на мантисе).
И всё обычно ограничивается обсуждением а многим ли это полезно, и какой метасимвол придумать (и не дофига ли и так непонятных закорючек).
Что если предоставить пользователю возможность самостоятельно запрограммировать нужную функциональность?
Синтаксически это будет как один метасимвол, но с параметрами.
Это по идее не очень сложно реализовать, но 10-20 часов работы просматриваются.
В принципе проверить полезность этой идеи можно прямо сейчас перехватом закрытия диалога "Apply command" (Ctrl-G). Естественно, сначала придумать какой-то новый метасимвол, включающий параметры, сопоставить ему Lua-функцию, возвращаемое значение которой будет подставлено в результирующую строку.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 12:32
by John Doe
Shmuel wrote: ↑Wed 31 Oct, 2018 12:20
проверить полезность этой идеи можно прямо сейчас перехватом закрытия диалога "Apply command" (Ctrl-G)
Не совсем понял, что именно таким образом можно проверить?
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 12:39
by HaRT
Shmuel wrote: ↑Wed 31 Oct, 2018 12:20
придумать какой-то новый метасимвол, включающий параметры, сопоставить ему Lua-функцию, возвращаемое значение которой будет подставлено в результирующую строку
В качестве отправной точки для обсуждения синтаксиса можно взять аналогичную функциональность из замены в плагине RESearch.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 12:46
by DrKnS
John Doe wrote: ↑Wed 31 Oct, 2018 11:50Навеяно обсуждением на гитхабе
Забавно, я о чем-то таком тоже думал после этого обсуждения - метасимвол, в который можно будет засунуть вызов плагина по префиксу или ууиду.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 13:18
by Shmuel
John Doe wrote: ↑Wed 31 Oct, 2018 12:32
Не совсем понял, что именно таким образом можно проверить?
Проверить и продемонстрировать полезность этой идеи, ещё до того, как она будет (если будет) реализована Far Group.
John Doe wrote: ↑Wed 31 Oct, 2018 12:32
Не совсем понял, что именно таким образом можно проверить?
Проверить и продемонстрировать полезность этой идеи, ещё до того, как она будет (если будет) реализована Far Group.
Так просто не выйдет, ведь подстановка не один раз должна производиться, а для каждого файла.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 13:22
by John Doe
Shmuel wrote: ↑Wed 31 Oct, 2018 12:20
придумать какой-то новый метасимвол, включающий параметры
Как вариант, синтаксис может быть похож на используемый в lua при вызове функции: !*func(arg1,arg2), где аргументы указываются стандартным образом, т.е. строки в "кавычках", или в [[скобках]] (для экранирования).
Символ может быть и другим, можно и уйти от закорючек: !lua!func(arg1,arg2)
(А при вызове без параметров возможно и скобки не нужны.)
Todo
Наличие аргументов усложняют для парсера задачу вычленения метасимвола из строки, поэтому могут понадобиться какие-то правила экранирования.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 13:59
by John Doe
Учитывая равную применяемость метасимволов в Ассоциациях (панельных, и командной строки), Меню Пользователя, и Применить Команду, определение может выглядеть так :
Поля description и id – опциональные, их значения по умолчанию – пустая строка.
name - имя, используемое для вызова функции в метасимволе. Предполагается что оно уникально.
flags - флаги, в настоящий момент нужен лишь один [поэтому возможно достаточно логического поля].
Флаг "runonce" (или "SelectedAtOnce") указывает фару, что при использовании в Применить команду требуется однократный вызов (не нужно повторять команду для каждого выделенного файла отдельно). То же самое поведение в настоящий момент мы наблюдаем при использовании метасимволов !@!, !$!, !&, !&~.
action - функция, выполняющая подстановку (замену символа на реальное значение).
[возможно правильнее использовать имя process]
Функция получает следующие аргументы:
Params - таблица, в которой передаются необходимые параметры.
Перечень параметров пока не вполне определён, поэтому передача через таблицу видится предпочтительнее позиционной, но впоследствии возможно разделить её на отдельные параметры.
В числе параметров необходимы следующие:
Item: таблица (вероятно), через которую передаются данные обрабатываемого файла. Какие именно данные доступны (fnparce.cpp) - вопрос к специалистам.
State: таблица, общая для всех вызовов action в пределах одного запуска "Применить команду", что позволяет использовать её для хранения состояние в процессе итераций.
[Возможно вместо отдельного аргумента стоит просто сохранять само окружение функции]
Source: number флаг, означающий источник вызова: ApplyCommand|UserMenu|Association|CmdLine.
preprocess: boolean флаг, означающий, что выполняется предварительная подстановка, для отображения в меню пользователя, или при конфликте ассоциаций.
В этом случае подстановка может отличаться, например, не будет показан диалог, и т.п. (возможны и другие сценарии). То же самое поведение в настоящий момент мы наблюдаем при использовании метасимволов !@!, !$! (см. справку), а также !?<title>?<init>!.
[Возможно, понадобятся и другие параметры, например строка ассоциации (или введённая в диалоге Применить команду), или та же строка, но уже с развёрнутыми метасимволами]
... - аргументы, передаваемые через метасимвол.
Возвращаемое значение: string, или nil, или false:
string строка для подстановки
nil пропустить элемент
не выполнять команду для этого элемента. В частности:
в Применить команду: пометка с файла не будет снята, переходим к следующей итерации.
в Ассоциациях: команда будет отсеяна при анализе подходящих ассоциаций (и не попадёт в меню конфликта). Аналогичное поведение в настоящий момент мы наблюдаем при использовании конструкций if defined/if exist (см. справку).
false прервать всю операцию. Аналогично nil, но в случае Применить команду:
пометка с файла не будет снята, прекращаем итерацию. То же самое поведение в настоящий момент мы наблюдаем при использовании метасимвола !?<title>?<init>! (при отмене диалога).
Кроме того, если идея получит развитие, то возможны дополнения, например дополнительный запуск функции после обработки нескольких выделенных файлов.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 14:05
by HaRT
John Doe wrote: ↑Wed 31 Oct, 2018 13:59
Параметры функций обдумываю
Учитываете ли вы возможность передавать метасимволу не только какие-то данные одного элемента, но и все выделенные элементы (инлайн-списком или путём к файлу-списку)?
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 14:42
by John Doe
HaRT wrote: ↑Wed 31 Oct, 2018 14:05
Учитываете ли вы возможность передавать метасимволу не только какие-то данные одного элемента, но и все выделенные элементы (инлайн-списком или путём к файлу-списку)?
В том виде, как это сформулировали вы, ничего специально делать не потребуется: если фар будет предварительно раскрывать прочие метасимволы, то можно будет передать эти данные указав аргументом соответствующий метасимвол.
Только врядли это удобно, скрипту проще получить эти элементы самостоятельно, используя апи.
Edit: возможно впоследствии окажется удобным сразу получать данные, как таблицу элементов, но пока этот вопрос не принципиален.
Идея: скрипты в метасимволах
Posted: Wed 31 Oct, 2018 15:52
by John Doe
Добавил в спецификацию flags="runonce";
Указал требуемые действия, в зависимости от возвращаемого значения action.
Идея: скрипты в метасимволах
Posted: Thu 01 Nov, 2018 08:59
by John Doe
John Doe wrote: ↑Wed 31 Oct, 2018 15:52
Указал требуемые действия, в зависимости от возвращаемого значения action.
nil === Пропустить: команда не выполняется, соответствующий элемент панели остаётся помеченым.
Ещё одна мысль, делающая обсуждаемую идею вдвойне привлекательной: а ведь так программируемые метасимволы могут служить условиями выполнения ассоциаций!
Напомню, что если файлу сопоставлено несколько ассоциаций, то при запуске показывается меню выбора.
Но сначала отсеиваются ассоциации, в которых присутствуют и не выполняются условия if exist / if defined.
И вот тут вместо этих ограниченных условий могут быть lua-скрипты, определяемые метасимволами.
Осталась неопределённость с параметрами action, поскольку мне неизвестно, какие в точности данные об обрабатываемых элементах (и контексте) предоставит фар.
Плюс, в тех местах, где требуетсяжелательна различная реакция фара в зависимости от результата подстановки, нет уверенности что это легко реализовать.
Идея: скрипты в метасимволах
Posted: Fri 02 Nov, 2018 06:04
by IgorZ
Предлагаю в список возвращаемых значений добавить true - команду не выполнять, пометку снять: функция уже сама всё сделала.
Может, вместо ... лучше таблицу? В ряде случаев это удобнее.
Все флаги в параметрах, наверное, логично убрать в State.
В итоге, функция будет выглядеть как имя(Item,State,Args)
Для Item, вероятно, наиболее логично использовать tPluginPanelItem.