Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

LuaShell

Назначение данной утилиты — реализовать запуск lua/moon/yue скриптов из командной строки максимально естественным образом, наподобие команд оболочки, и наравне с ними.

Точно так же скрипты можно запускать просто по имени, не задумываясь где именно они расположены (в текущей папке, или где-то в %PATH%).
И по тем же правилам им можно передавать аргументы в командной строке.

Скрипты удобно не только запускать вручную, но и использовать в ассоциациях, меню пользователя, диалоге “Применить команду” и т. п.

Область действия не ограничена панелями: командная строка доступна в любой области Far’а, с автодополнением и историей.

Также возможно непосредственно исполнять набранные в строке ввода lua(/moon/yue)-выражения, и просматривать возвращаемые значения.

Скриптам: предоставляется ряд средств (см. API), в числе которых — простое обращение к другим скриптам, доступным в %PATH%, что позволяет сформировать собственную экосистему, в некотором роде альтернативную модулям Lua.

Макросам: предоставляется модуль sh для доступа к скриптам.


Обсуждение на форуме: https://forum.farmanager.com/viewtopic.php?f=15&t=10907

Назначение

Данный скрипт возник в ответ на штатную возможность запускать lua-скрипты, появившуюся ещё в LuaMacro 198. В штатной реализации аргументы представляли собой lua-выражения, разделённые запятыми:

lua:@filename arg1, arg2, ... 

Из этого также следовало, что передать простую строку можно только заключив её в кавычки.

Всё это плохо совмещается с тем, как используются в командной строке обычные утилиты. Соответственно, довольно проблематично использовать таким образом lua-скрипты в ассоциациях, меню пользователя, диалоге “Применить команду” и т. п.

Поэтому основная цель данного скрипта (первоначально довольно простого) — реализовать передачу аргументов общепринятым способом, т.е. как список строк, разделяемых пробелами, с учётом кавычек:

luash:filename arg1 "arg 2" ... 

Примечание: в то же время есть возможность и аналогично LuaMacro, интерпретировать командную строку как список выражений, см. sh.eval.

К основной фунциональности относятся также:

  • Запуск скриптов без необходимости указывать полный путь, и даже без специального префикса; как обычные утилиты, доступные в %PATH%, но с полным доступом к FAR API.

  • Доступ к “командной строке” не только из панелей, но также из редактора и прочих областей.

  • Помимо “строкового” интерфейса командной строки, скрипты могут “экспортировать” свои функции непосредственно, что позволяет обращаться из скрипта к скрипту наиболее прямым образом, см. sh.

    Один и тот же скрипт может предусматривать как вызов из командной строки пользователем, так и обращение к его функциям из другого скрипта, см. _cmdline.

В процессе разработки возникали и другие идеи, которые в итоге воплотились в ряд дополнительных функций, задокументированных в разных разделах данной справки.

Также вокруг основного скрипта возник ряд вспомогательных, которые сначала приводились как пример применения LuaShell, а впоследствии образовали своеобразную экосистему, см. раздел Утилиты.

Утилиты

Помимо скриптов, входящих в комплект поставки LuaShell и являющихся его неотъемлемой частью, доступны также дополнительные наборы скриптов/утилит, спонтанно развившихся со временем в его экосистеме.

Набор 3rd-party

Набор 3rd-party, распространяемый отдельно, это скрипты и макросы других авторов, приспособленные для использования в LuaShell.
Обычное место размещения - Macros\utils\3rd-party.

Информацию о составе пакета можно получить в репозитории по ссылке выше.
Кроме того, большинство файлов снабжено описаниями (descript.ion).

Набор std

В наборе std представлены как полезные утилиты, которыми я регулярно пользуюсь, так и экспериментальные, а также скрипты написанные для тестирования и/или иллюстрации возможностей системы.
Набор предполагается размещать в директории Macros\utils\std.

Вот лишь несколько примеров:

  • filesmenu: поиск/выбор файла из меню
  • files/apply: Универсальный выбор/обработка файлов, удовлетворяющих заданному условию
  • lineup: Вертикальное выравнивание строк по разделителям
  • lorem: Lorem ipsum generator
  • RunMacro: исполнять макросы из макрофайлов, не устанавливая их
  • plugins: утилиты для загрузки/выгрузки плагинов, как с выбором через меню, так и массово
  • venv: работа с Python virtual environments

Помимо перечисленных выше в наборе присутствуют десятки скриптов-утилит, и для получения более подробной информации следует смотреть их непосредственно — как правило они снабжены подсказкой, отображаемой при их запуске без аргументов.
Также дополнительная информация содержится в файлах README, расположенных в некоторых поддиректориях.

Возможность использования отдельно от LuaShell

Часть утилит написаны так, что могут быть использованы и без LuaShell: либо как макросы (если в них содержатся определения Macro или MenuItem), либо исполняться штатными средствами LuaMacro: из командной строки, или с помощью mf.eval.

И конечно любой скрипт можно исполнить из макроса используя sh, см. например indent_macro.lua.sample.

Установка

Для базовой установки можно воспользоваться командой меню пользователя (по F2), или сделать это вручную как описано в README.md.

Это обеспечит запуск скриптов по префиксу (luash:) из разных мест (панели, ассоциации, меню пользователя, диалог “Применить команду”).
И без префикса из собственного диалога, доступного по Ctrl-G (в панелях — с удержанием, или Ctrl-Shift-G).

Чтобы свободно запускать скрипты без префикса отовсюду (что конечно удобнее), необходимы некоторые дополнительные действия:

  1. В редакторе конфигурации (far:config) активировать параметр System.Executor.UseAssociations.

  2. Добавить ассоциацию:

    *.lua,*.moon,*.yue | luash::"!\!.!"
    

Рекомендуются установить также дополнительные наборы готовых скриптов/утилит: std, 3rd-party.

Примечания:

  1. При старте в переменную среды PATHEXT добавляются расширения .lua;.moon;.yue (если отсутствуют).
    Это необходимо для работы автодополнения, и для запуска скриптов без префикса (см. выше).

  2. Для удобства к значению переменной PATH добавляется путь к директории Macros\utils и рекурсивно ко всем её поддиректориям (исключая скрытые).
    Содержимое Macros\utils\core является неотъемлемой частью LuaShell, остальные директории и их содержимое — опциональны.

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

  4. Следующие модули, при их наличии, будут обеспечивать просмотр и форматирование lua-значений (подробнее см. utils\core\README):

    Кроме того, для комфортной работы рекомендуются следующие скрипты:

    • Ctrl-O: просмотр пользовательского экрана из любой области
    • Макросы для работы с большим буфером консоли
    • MacroEx — запуск макросов нетрадиционными способами
    • Проверка корректности скрипта в редакторе + выполнение
    • Luacheck FAR scripts — статический анализатор для Lua/Moon-/Yuescript

Опции

  • prefix, path, pathext (string) позволяют переопределить значения, описанные в разделе Установка.

  • В LastResultKey (string) задаётся шорткат, по которому можно просмотреть возвращаемые значения последнего запущенного скрипта (подробнее в разделе Использование).
    По умолчанию: Ctrl-Shift-L.

  • С помощью функции initEval(env) можно изменить окружение, доступное при исполнении через eval при исполнении lua(/moon/yue)-выражений.
    По умолчанию: F=far.Flags; sh.autoload=true (см. sh.)

  • execDlgOptions (table) — настройки диалога запуска скрипта (см.)

  • debug (boolean) используется для отладки.
    В частности, отключает кэширование скриптов.

Опции можно изменить в начале скрипта (LuaShell.lua).

Но чтобы после каждого обновления скрипта не приходилось вручную восстанавливать изменённые значения, рекомендуется использовать возможности cfgscript из пакета ScriptsBrowser.

Использование

Скрипты можно запускать из командной строки Far по имени, как исполняемые файлы (при правильной установке), указывая при необходимости и аргументы.

Повторить запуск скрипта можно нажатием Ctrl-Alt-G или CtrlG:Double
(Внимание: шорткаты с “:Double” и “:Hold” предполагают наличие MacroEx).

По Ctrl-Shift-G доступен Диалог запуска скрипта, работающий во всех макрообластях (с раздельной историей). Кроме того, он вызывается и следующими шорткатами:

  • Ctrl-G (кроме панелей);
  • в панелях: CtrlG:Hold;
  • в редакторе CtrlG:Hold подхватывает выделенный текст или текущую строку.

Для создания нового скрипта необязательно переходить в целевую директорию, достаточно в том же диалоге набрать его имя и нажать F4 — скрипт будет создан в директории заданной по умолчанию.
Таким же образом можно открыть и существующий скрипт на редактирование (а с помощью F3 — на просмотр).

Альтернативно: запустить в командной строке edit <scriptname>.

При редактировании скрипта может встретиться обращение к другому скрипту (см. sh), установив курсор на его имени и нажав F4 можно открыть этот скрипт в редакторе.


Возвращаемые значения

LuaShell позволяет не только запускать скрипты, но и непосредственно исполнять lua(/moon/yue)-выражения, и получать возвращаемые значения.

Если скрипт/выражение возвращают значения, то в нижней части экрана отображается нотификация с предложением просмотреть их, нажав Enter.
Или же можно сразу при запуске указать, что после выполнения требуется отобразить результат (см. справку командной строки / диалога).
Кроме того, значения можно просмотреть и позже в любой момент, с помощью макроса на Ctrl-Shift-L (настраивается).

Примечаниe: массив значений также сохраняются в общую переменную sh._shared.LastCmdLineResult (см. sh), по аналогии с CmdLine.Result.


Это лишь краткий обзор возможностей, подробнее см. в соответствующих разделах.

Выполнение Lua-выражений

LuaShell позволяет не только запускать скрипты, но и непосредственно исполнять lua(/moon-/yuescript)-выражения, и получать возвращаемые значения:

При запуске из Диалога или командной строки сначала делается попытка найти скрипт по имени, и только после неудачи введённая строка рассматривается как выражение.
(Зависит от опции диалога [?] Expr.)

Примечания:

  • Допустимы как lua-, так и moon-/yuescript- выражения.
    Перед lua-выражением сначала делается попытка подставить "return ".

  • Выражения могут обращаться к скриптам, используя модуль sh, и даже просто по имени
    (зависит от значения sh.autoload, для выражений по умолчанию разрешено, см. Опции).

  • Окружение можно предварительно инициализировать функцией initEval (см. Опции).

  • При запуске из Диалога окружение можно предварительно инициализировать заданным скриптом (см.)

Командная строка

Запуск скрипта как “исполняемого файла”:

<filename[.ext]> [<arg1> <arg2> ...]
  • Аргументы указываются традиционным для командной строки образом, т.е. как строки, отделяемые друг от друга пробелами.
    Чтобы передать строку с пробелами необходимо заключить её в двойные кавычки.
    Сами кавычки не являются частью строки (кавычку можно передать только экранировав её с помощью обратного слэша).
  • Если не указан путь, то скрипт будет также искаться в %PATH%.
    Если не указано расширение, то сначала ищется “.lua”, затем “.moon” и “.yue”.
  • Чтобы данный способ запуска был возможен, требуется небольшая настройка.

Запуск скрипта через префикс плагина позволяет настроить ряд параметров, что может понадобиться при запуске по ассоциации, из меню пользователя, или диалога “Применить команду”.
Кроме того, при запуске через префикс можно выполнять не только скрипты, но и непосредственно lua(/moon/yue)-выражения, и просматривать возвращаемые значения (см. ниже).

 luash:[:][=|?][@|*]...
luashs:[:][=|?][@|*]...

При использовании префикса luashs: команда исполняется синхронно, а не в режиме макроса.

Модификаторы, используемые с префиксом:

  • Удвоенный символ ":" однозначно указывает, что в командной строке имя файла, и не следует пытаться выполнить её как выражение, если скрипт не найден.
  • Просмотр возвращаемых значений:
    • Символ ? позволяет отобразить список возвращаемых значений сразу, если они есть.
    • Символ = аналогично, но если возвращаемых значений нет, то об этом выводится сообщение.
      Если после = в командной строке ничего не указано, то отображаются значения, возвращённые последним выполненным скриптом.
  • В обычном режиме сама выполняемая команда отображается на экране только если скрипт использовал “print”.
    • Символ * используется для того, чтобы отобразить команду в любом случае.
    • Символ @ используется для запрета отображения команды.

Диалог запуска скрипта

Запуск скриптов возможен как из штатной командной строки Far’а, так и из собственного диалога, доступного отовсюду по заданным макросам (см. Использование).

Строка ввода сохраняет историю команд (по макрообластям).

По Enter запускать можно как lua(/moon/yue)-скрипты с параметрами (см. Командная строка), так и непосредственно lua(/moon/yue)-выражения.

Ctrl-Enter запускает скрипт на исполнение, выставив опции [x] Reuse env и [x] Reopen.

Shift-Enter после исполнения показывает возвращённые значения, через опцию [x] Show ret.
(также они всегда доступны по Ctrl-Shift-L, подробнее в разделе Использование).

F4 открывает редактор со скриптом, имя которого содержится в строке ввода. И например чтобы создать новый скрипт, достаточно ввести желаемое имя и нажать F4.

F3 открывает скрипт во вьювере.

Также в диалоге работают кнопки PgUp / PgDn / Home.

Дополнительные возможности

  • На нижней рамке диалога отображается результат(ы) предыдущего выполнения скрипта/выражения, просмотреть подробнее их можно нажав Ctrl-L, или воспользовавшись кнопкой.
    Ctrl-Ins на кнопке — копирует строку в буфер обмена.

    В выражениях на предыдущий результат можно сослаться, использовав имя ans (используется только первое значение).
    А с помощью функции last(i) можно получить все значения (опционально: начиная с i).
    Примечание: ans и last() реализованы внешними скриптами (см. utils\core\eval\).

  • На верхнем поле диалога располагается строка статуса, в которой может отображаться результат выражения, вычисляемый динамически по мере ввода.
    С помощью Ctrl-E можно просмотреть его подробно.
    По умолчанию функция динамического обновление статуса активируется при включённом ScrollLock.
    С помощью опции autostatus=true можно её включить безусловно, а с помощью autostatus=false наоборот, полностью отключить.

  • На верхней рамке слева находится кнопка ..., позволяющая выбрать скрипт предварительной настройки окружения для выражений.
    Таким образом можно например добавить любые пользовательские функции, или реализовать обращение к функциям math напрямую без префикса, или запретить autoload (обращение к сприптам без sh.)
    См. прилагаемые примеры _eval_extra, _eval_noauto, …

    При выборе скрипта его имя отображается на кнопке. F4 позволяет открыть его в редакторе. Сбросить выбор можно с помощью Del или указав пустую строку.

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

    Примечание:

    При использовании опции [x] Keep env повторный запуск не приведёт к запуску скрипта инициализации.
    Если скрипт требуется выполнять каждый раз, надо в нём установить _inited = false, см. _eval_noauto.lua.

Опции

Допустимо предварять строку ввода теми же символами-модификаторами, что предусмотрены для использования с префиксом, или же можно задать требуемые опции с помощью чекбоксов:

  • [ ] Synchro - синхронный режим запуска
    [x] соответствует префиксу luashs:, опция synchro
  • [?] Expr. - рассматривать текст как выражение, если скрипт с соответствующим именем не найден
    [ ] только запуск скриптов, соответствует удвоенному символу :, опция noexpr [x] только выполнение выражений, соответствует опции expr_only
  • [?] echo - печать выполняемой команды
    [x] соответствует символу *, опция echo_force [ ] соответствует символу @, опция echo_off
  • [ ] Show result - отобразить возвращаемые значения
    [x] соответствует символу =, опция showret [?] соответствует символу ?, опция showret_ifany

Кроме того, есть опции специально для диалога запуска:

  • [ ] Keep env - сохранять окружение между запусками
    [x] соответствует опции keepenv
    Окружение можно просмотреть нажав Ctrl-K, удалить — Ctrl-Shift-K (или Del, когда курсор на опции).
  • [ ] Reopen - после выполнения команды заново открыть диалог запуска
    [x] соответствует опции reopen

Состояние опций “по-умолчанию” можно сохранить для текущей сессиии кнопкой [ Save options ].
Изменить опции перманентно можно в Опциях, имена ключей см. выше, состояние [?] кодируется числом 2.

Кроме того, есть несколько параметров, которые можно задать только вручную, через execDlgOptions:

  • initenv (string) и autostatus (boolean) описаны выше.
  • small (boolean) отображает диалог без полей.

Просмотр возвращаемых значений

Для просмотра возвращаемых значений можно воспользоваться соответствующей опцией в диалоге запуска скрипта или же шорткатом Shift-Enter;
аналогичная возможность предусмотрена и в командной строке, указанием специального символа =.

Таблицы можно просматривать в виде списка (рекомендуются модули “le” и “inspect”, см. раздел Установка).

Кроме того, когда скрипт (или lua(/moon/yue)-выражение) возвращает значения — в нижней части экрана кратковременно выводится нотификация с предложением просмотреть их, нажав Enter.

Эта же функция доступна и позже в любой момент по Ctrl-Shift-L (подробнее в разделе Использование).

В списке значений доступны следующие действия:

  • Enter - просмотреть значение в диалоге
  • Ctrl-Ins - скопировать дамп значения
  • Ctrl-E - заново открыть диалог с командой

API

API, предоставляемый скрипту

  • ... (vararg)
    Аргументы командной строки.

  • _filename (string)
    Полное имя скрипта.

  • _cmdline (string)
    Переменная, в которую помещаются неразделённые аргументы скрипта в виде строки (исключая имя скрипта), в случае когда скрипт исполняется напрямую (из командной строки или диалога).

    • Если скрипт вызван без параметров, то _cmdline==""

    • Если скрипт запущен не из командной строки, а вызван другим скриптом (см. ниже sh), то переменной _cmdline в окружении не будет.

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

    if _cmdline=="" then
      print "Скрипт запущен без аргументов, выводим подсказку"
      return
    elseif _cmdline then
      print("Командная строка:", _cmdline)
      print("Аргументы:", ...)
    else
      -- скрипт вызван другим скриптом, экспортируем функцию
      return some_function
    end

    Для того чтобы рассмотреть командную строку как выражение — можно использовать sh.eval(_cmdline) (см.)

  • nocache (boolean)
    Параметр, позволяющий запретить кэширование результата исполнения скрипта.
    См. примеры использования в utils\core\eval\ans.lua/last.lua и utils\std\far\api\*.lua

    Примечания:

    • По умолчанию возвращаемое скриптом значение кэшируется, т.е. скрипт исполняется только при первом обращении к sh.somefile, а все последующие — используют кэшированное значение.
    • Опция debug также отключает кэширование.
  • print (function)
    То же что и sh.print (см.)

  • sh (table)
    API для обращения к другим скриптам + дополнительные сервисные функции.

API для обращения к другим скриптам — sh

Модуль sh доступен из скрипта непосредственно, а в обычном макросе — через require.

Загрузить скрипт по его имени можно двумя способами:

  • sh.<name> (т.е. индексируя нэймспейс sh, используя в качестве ключа имя скрипта)
    Рекомендуется к использованию в большинстве случаев.
    Позволяет обратиться непосредственно к возвращаемому значению скрипта.

    Примечание:
    При исполнении скрипту в качестве аргумента передаётся собственное имя (для совместимости с модулями).

    Примеры:

    local ret = sh.name    -- исполняет скрипт, возвращая результат
    sh.name(arg1,arg2,...) -- если экспортируется функция
    sh.name.somefunc(...)  -- если возвращается таблица содержащая функцию somefunc
  • sh(name,env)
    Даёт больше контроля при загрузке скрипта:

    • Не исполняет скрипт непосредственно, а возвращает функцию, аналогично loadfile.
      Таким образом скрипту можно передать параметры, как и при обычном запуске из командной строки.

      Примеры:

    local fn = sh"name"                  -- загружает скрипт (но не исполняет)
    local ret = fn(arg1,arg2,...)        -- исполняет ранее загруженный скрипт, передавая аргументы
    
    local ret = sh"name"(arg1,arg2,...)  -- то же самое но за один шаг
    
    sh"name"("name")                     -- то же что и `sh.name`
    • Позволяет (опционально) задать окружение.
      Например если скрипт используется как короткий алиас другого скрипта, для работы которого может требоваться передать не только аргументы, но и служебное окружение (_filename, _cmdline).
    sh("name", {_cmdline=_cmdline})(...) -- можно передать собственный _cmdline
    sh("name", getfenv())(...)           -- или собственное окружение целиком

Примечание:

В директории utils\core\ можно найти некоторые “внутренние” скрипты, которые (как и все прочие) можно адресовать через sh.


Дополнительные сервисные функции

  • sh.print(...)
    Аналог стандартной Lua-функции print, реализован на основе win.WriteConsole.
    Выводит текст в буфер под панелями (панели гасятся, а после завершения скрипта восстанавливаются автоматически).
    Скриптам LuaShell данная функция доступна и просто как print, без префикса.
    (Это не мешает использовать штатную _G.print / mf.print там где нужна именно она.)

    Примечание: по функциональности sh.print похожа на mf.printconsole, однако последняя гасит/восстанавливает панели (Get/SetUserScreen) при каждом вызове, что не всегда удобно, и ограничивает производительность.

  • sh.eval(expr, env, ...) (реализовано отдельным скриптом)
    Вычисляет строку как lua-выражение (опционально, передавая таблицу с окружением, и аргументы).
    Полезно как для собственно вычислений (1+math.sin(2)), так и для передачи любых lua-значений (_G, Far, 123, "abc", {k="v"}, function() print"hello" end, ...).

    Типичный случай использования: sh.eval(_cmdline).
    Другие примеры использования в utils\core\eval\README.

  • sh._shared (table)
    Доступ к некоторым внутренним параметрам, таким как мета-информация о скрипте LuaShell.lua, и его таблица options.
    Может служить для обмена информацией между скриптами (в частности содержит поле LastCmdLineResult, подробнее в разделе Использование).
    Там же скрипты могут сохранять свои данные между запусками (в рамках одной сессии).
    Один из вариантов обеспечения уникальности используемого ключа, это использовать путь к скрипту:

    local mydata = sh._shared[_filename]
    if not mydata then
      mydata = {}
      sh._shared[_filename] = mydata
    end
  • sh.autoload (boolean/function)
    Параметр, дающий возможность загружать скрипты не используя sh., а просто по имени, как глобальную переменную.
    Если значение истинно, то при обращении к любому необъявленному идентификатору будет произведена попытка загрузить одноимённый скрипт, и использовать возвращённое им значение.
    По умолчанию: нет.
    Предполагается что задать значение может понадобиться в каком-либо скрипте локально, для его собственных нужд.

    Примечания:

    • Для выражений окружение предустановлено (см. Опции), и значение по умолчанию истинно.
    • Если в качестве значения задана функция, и будучи вызванной с искомым именем в качестве аргумента она вернёт значение, то будет использованно именно оно (см. core\eval\eval.lua).
      Только если функция не вернула значений, искомое имя будет использовано для загрузки скрипта.