Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions packagedef
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//

Описание.Имя("cli")
.Версия("0.11.0")
.Версия("0.12.0")
Comment thread
nixel2007 marked this conversation as resolved.
.Автор("Khorev Aleksey")
.АдресАвтора("khorevaa@gmail.com")
.Описание("Данный пакет облегчает создание консольных приложений на Oscript")
Expand All @@ -15,7 +15,6 @@
//.ВключитьФайл("package-loader.os")
//.ВключитьФайл("packagedef")
.ЗависитОт("logos", "1.1.1")
.ЗависитОт("delegate", "0.2.0")
.ЗависитОт("reflector", "0.5.1")
.ЗависитОт("fluent", "0.6.0")
.ЗависитОт("datetime", "0.1.0")
Expand All @@ -25,4 +24,5 @@
.ОпределяетКласс("КонсольноеПриложение", "src/core/Классы/КонсольноеПриложение.os")
.ОпределяетКласс("КомандаПриложения", "src/core/Классы/КомандаПриложения.os")
.ОпределяетКласс("ПараметрКоманды", "src/core/Классы/ПараметрКоманды.os")
.ОпределяетКласс("КомандаДополнения", "src/core/Классы/КомандаДополнения.os")
;
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
// Генератор (посетитель) скрипта автодополнения для GNU Bash.
// Реализует контракт ОбходчикКомандДополнения.

Перем ИмяПриложенияГлоб;
Перем ИмяФункцииГлоб;

Функция Оболочка() Экспорт
Возврат "bash";
КонецФункции

Функция СформироватьСкрипт(ИмяПриложения, КореньКоманд) Экспорт

ИмяПриложенияГлоб = ИмяПриложения;
ИмяФункцииГлоб = "_" + БезопасноеИмяФункции(ИмяПриложения) + "_completions";

Буфер = Новый Массив;
Контекст = НовыйКонтекст(0, "", Буфер);

Обходчик = Новый ОбходчикКомандДополнения();
Обходчик.Обойти(КореньКоманд, ЭтотОбъект, Контекст);

Возврат СтрСоединить(Буфер, Символы.ПС);

КонецФункции

Процедура НачатьКоманду(Команда, Контекст) Экспорт

Если Контекст.Глубина = 0 Тогда
Б = Контекст.Буфер;
Б.Добавить("# " + ИмяПриложенияГлоб + " bash completions");
Б.Добавить("# Добавьте строку ниже в ~/.bashrc для активации:");
Б.Добавить("# source <(" + ИмяПриложенияГлоб + " completions --shell bash)");
Б.Добавить("");
Б.Добавить(ИмяФункцииГлоб + "() {");
Б.Добавить(" local cur prev words cword");
Б.Добавить(" _init_completion 2>/dev/null || {");
Б.Добавить(" COMPREPLY=()");
Б.Добавить(" cur=""${COMP_WORDS[COMP_CWORD]}""");
Б.Добавить(" prev=""${COMP_WORDS[COMP_CWORD-1]}""");
Б.Добавить(" words=(""${COMP_WORDS[@]}"")");
Б.Добавить(" cword=$COMP_CWORD");
Б.Добавить(" }");
Иначе
Контекст.Буфер.Добавить(Контекст.Отступ + СтрСоединить(ПолучитьИменаКоманды(Команда), "|") + ")");
КонецЕсли;

КонецПроцедуры

Процедура ПосетитьОпцию(СтрокаОпции, Контекст) Экспорт

ЕстьЗначения = СтрокаОпции.ЗначенияДополнения.Количество() > 0;
Для Каждого ИмяОпции Из СтрокаОпции.НаименованияПараметров Цикл
Контекст.ИменаОпций.Добавить(ИмяОпции);
Если ЕстьЗначения Тогда
Контекст.ОпцииСоЗначениями.Вставить(ИмяОпции, СтрокаОпции.ЗначенияДополнения);
КонецЕсли;
КонецЦикла;

КонецПроцедуры

Процедура ПосетитьАргумент(СтрокаАргумента, Контекст) Экспорт

Для Каждого Значение Из СтрокаАргумента.ЗначенияДополнения Цикл
Контекст.ЗначенияАргументов.Добавить(Значение);
КонецЦикла;

КонецПроцедуры

Процедура ПередПодкомандами(Команда, Подкоманды, Контекст) Экспорт

Б = Контекст.Буфер;
О = Контекст.Отступ;
Контекст.ЕстьПодкоманды = Подкоманды.Количество() > 0;

Если Контекст.Глубина = 0 Тогда
Б.Добавить("");
Б.Добавить(" local commands=""" + СтрСоединить(СобратьИменаВсех(Подкоманды), " ") + """");
Б.Добавить("");
Б.Добавить(" if [ $cword -eq 1 ]; then");
Б.Добавить(" COMPREPLY=($(compgen -W ""$commands"" -- ""$cur""))");
Б.Добавить(" return 0");
Б.Добавить(" fi");
Б.Добавить("");
Б.Добавить(" local command=""${words[1]-}""");
Б.Добавить(" case ""$command"" in");
Возврат;
КонецЕсли;

Для Каждого КлючЗначение Из Контекст.ОпцииСоЗначениями Цикл
Б.Добавить(О + " if [ ""$prev"" = """ + КлючЗначение.Ключ + """ ]; then");
Б.Добавить(О + " COMPREPLY=($(compgen -W """ + СтрСоединить(КлючЗначение.Значение, " ") + """ -- ""$cur""))");
Б.Добавить(О + " return 0");
Б.Добавить(О + " fi");
КонецЦикла;

ИменаДляКомплита = Новый Массив;
ИменаДляКомплита.Добавить("--help");
Для Каждого Имя Из Контекст.ИменаОпций Цикл
ИменаДляКомплита.Добавить(Имя);
КонецЦикла;
Б.Добавить(О + " if [[ ""$cur"" == -* ]]; then");
Б.Добавить(О + " COMPREPLY=($(compgen -W """ + СтрСоединить(ИменаДляКомплита, " ") + """ -- ""$cur""))");
Б.Добавить(О + " return 0");
Б.Добавить(О + " fi");

Если Контекст.ЕстьПодкоманды Тогда
СледИндекс = Формат(Контекст.Глубина + 1, "ЧГ=0");
Б.Добавить(О + " if [ $cword -eq " + СледИндекс + " ]; then");
Б.Добавить(О + " COMPREPLY=($(compgen -W """ + СтрСоединить(СобратьИменаВсех(Подкоманды), " ") + """ -- ""$cur""))");
Б.Добавить(О + " return 0");
Б.Добавить(О + " fi");
Б.Добавить(О + " local sub" + СледИндекс + "=""${words[" + СледИндекс + "]-}""");
Б.Добавить(О + " case ""$sub" + СледИндекс + """ in");
ИначеЕсли Контекст.ЗначенияАргументов.Количество() > 0 Тогда
Б.Добавить(О + " COMPREPLY=($(compgen -W """ + СтрСоединить(Контекст.ЗначенияАргументов, " ") + """ -- ""$cur""))");
КонецЕсли;

КонецПроцедуры

Функция ОткрытьПодкоманду(Подкоманда, Контекст) Экспорт

Возврат НовыйКонтекст(Контекст.Глубина + 1, Контекст.Отступ + " ", Контекст.Буфер);

КонецФункции

Процедура ЗакрытьПодкоманду(Подкоманда, ПодчинённыйКонтекст, Контекст) Экспорт
// Для bash дочерний узел сам завершает свою ветку case в ЗавершитьКоманду.
КонецПроцедуры

Процедура ЗавершитьКоманду(Команда, Контекст) Экспорт

Б = Контекст.Буфер;
О = Контекст.Отступ;

Если Контекст.Глубина = 0 Тогда
Б.Добавить(" *)");
Б.Добавить(" ;;");
Б.Добавить(" esac");
Б.Добавить("");
Б.Добавить(" return 0");
Б.Добавить("}");
Б.Добавить("");
Б.Добавить("complete -F " + ИмяФункцииГлоб + " " + ИмяПриложенияГлоб);
Возврат;
КонецЕсли;

Если Контекст.ЕстьПодкоманды Тогда
Б.Добавить(О + " *)");
Б.Добавить(О + " ;;");
Б.Добавить(О + " esac");
КонецЕсли;
Б.Добавить(О + " ;;");

КонецПроцедуры

Функция НовыйКонтекст(Глубина, Отступ, Буфер)

К = Новый Структура();
К.Вставить("Глубина", Глубина);
К.Вставить("Отступ", Отступ);
К.Вставить("Буфер", Буфер);
К.Вставить("ИменаОпций", Новый Массив);
К.Вставить("ОпцииСоЗначениями", Новый Соответствие);
К.Вставить("ЗначенияАргументов", Новый Массив);
К.Вставить("ЕстьПодкоманды", Ложь);
Возврат К;

КонецФункции

Функция ПолучитьИменаКоманды(Команда)

Имена = Новый Массив;
Имена.Добавить(Команда.ПолучитьИмяКоманды());
Для Каждого Синоним Из Команда.ПолучитьСинонимы() Цикл
Если Синоним <> Команда.ПолучитьИмяКоманды() Тогда
Имена.Добавить(Синоним);
КонецЕсли;
КонецЦикла;
Возврат Имена;

КонецФункции

Функция СобратьИменаВсех(Подкоманды)

Результат = Новый Массив;
Для Каждого Подкоманда Из Подкоманды Цикл
Результат.Добавить(Подкоманда.ПолучитьИмяКоманды());
КонецЦикла;
Возврат Результат;

КонецФункции

Функция БезопасноеИмяФункции(Имя)

Результат = "";
Для Инд = 1 По СтрДлина(Имя) Цикл
Символ = Сред(Имя, Инд, 1);
Если (Символ >= "a" И Символ <= "z")
Или (Символ >= "A" И Символ <= "Z")
Или (Символ >= "0" И Символ <= "9")
Или Символ = "_" Тогда
Результат = Результат + Символ;
Иначе
Результат = Результат + "_";
КонецЕсли;
КонецЦикла;
Возврат Результат;

КонецФункции
Loading