Page 1 of 3

Идея: скрипты в метасимволах

Posted: Wed 31 Oct, 2018 11:50
by John Doe
Навеяно обсуждением на гитхабе: Enhancement: Special Symbol for File Description #65
Там предлагается ввести новый метасимвол !*, в который будет подставляться описание файла.

Задача интересная, хоть и специфическая.
На самом деле за всё время множество хотелок было по расширению метасимволов (не раз встречал как на форуме, так и на мантисе).
И всё обычно ограничивается обсуждением а многим ли это полезно, и какой метасимвол придумать (и не дофига ли и так непонятных закорючек).

Что если предоставить пользователю возможность самостоятельно запрограммировать нужную функциональность?
Синтаксически это будет как один метасимвол, но с параметрами.

Update: https://bugs.farmanager.com/view.php?id=3681

Идея: скрипты в метасимволах

Posted: Wed 31 Oct, 2018 12:20
by Shmuel
Это по идее не очень сложно реализовать, но 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.

Идея: скрипты в метасимволах

Posted: Wed 31 Oct, 2018 13:21
by John Doe
Shmuel wrote:
Wed 31 Oct, 2018 13:18
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
Учитывая равную применяемость метасимволов в Ассоциациях (панельных, и командной строки), Меню Пользователя, и Применить Команду, определение может выглядеть так :

Code: Select all

Symbol {
  description="";                 --string (optional)
  name="func";                    --string
  flags="runonce";                --string (optional)
  --or: runonce=true;             --boolean (optional)
  action=function(Params,...)     --function
    return SubstValue             --string, boolean, or nil
  end;
}
  • Поля description и id – опциональные, их значения по умолчанию – пустая строка.
  • name - имя, используемое для вызова функции в метасимволе. Предполагается что оно уникально.
  • flags - флаги, в настоящий момент нужен лишь один [поэтому возможно достаточно логического поля].
    Флаг "runonce" (или "SelectedAtOnce") указывает фару, что при использовании в Применить команду требуется однократный вызов (не нужно повторять команду для каждого выделенного файла отдельно).
    То же самое поведение в настоящий момент мы наблюдаем при использовании метасимволов !@!, !$!, !&, !&~.
  • action - функция, выполняющая подстановку (замену символа на реальное значение).
    [возможно правильнее использовать имя process]
    • Функция получает следующие аргументы:
    • Возвращаемое значение: string, или nil, или false:
Кроме того, если идея получит развитие, то возможны дополнения, например дополнительный запуск функции после обработки нескольких выделенных файлов.

Идея: скрипты в метасимволах

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-скрипты, определяемые метасимволами.

Идея: скрипты в метасимволах

Posted: Thu 01 Nov, 2018 11:46
by John Doe
Обновил определение, постаравшись учесть максимум ньюансов.

Осталась неопределённость с параметрами action, поскольку мне неизвестно, какие в точности данные об обрабатываемых элементах (и контексте) предоставит фар.

Плюс, в тех местах, где требуетсяжелательна различная реакция фара в зависимости от результата подстановки, нет уверенности что это легко реализовать.

Идея: скрипты в метасимволах

Posted: Fri 02 Nov, 2018 06:04
by IgorZ
Предлагаю в список возвращаемых значений добавить true - команду не выполнять, пометку снять: функция уже сама всё сделала.
Может, вместо ... лучше таблицу? В ряде случаев это удобнее.
Все флаги в параметрах, наверное, логично убрать в State.
В итоге, функция будет выглядеть как имя(Item,State,Args)
Для Item, вероятно, наиболее логично использовать tPluginPanelItem.

Идея: скрипты в метасимволах

Posted: Fri 02 Nov, 2018 08:25
by John Doe
IgorZ wrote:
Fri 02 Nov, 2018 06:04
Предлагаю в список возвращаемых значений добавить true - команду не выполнять, пометку снять: функция уже сама всё сделала.
Подскажите в каком сценарии это может быть полезно.
IgorZ wrote:
Fri 02 Nov, 2018 06:04
Может, вместо ... лучше таблицу?
... соответствует тому, как аргументы представлены при использовании метасимвола.
Это кстати тоже вполне вопрос для обсуждения, ведь можно и !lua!func {arg1=val1,arg2=val2} (имхо избыточно, но решать всё равно не мне).
IgorZ wrote:
Fri 02 Nov, 2018 06:04
В ряде случаев это удобнее.
arg = {...}.
IgorZ wrote:
Fri 02 Nov, 2018 06:04
Все флаги в параметрах, наверное, логично убрать в State.
Поясните.
IgorZ wrote:
Fri 02 Nov, 2018 06:04
Для Item, вероятно, наиболее логично использовать tPluginPanelItem.
Да, но см. fnparce.cpp: я вовсе не уверен что эта информация там доступна.
Также вспомните, что на плагиновых панелях Применить Команду вообще не реализовано, а при использовании ассоциаций элемент распаковывается во временную папку, и это уже совсем не tPluginPanelItem. Edit
При использовании ассоциаций из командной строки аналогично, элемент не принадлежит панели.