-
Notifications
You must be signed in to change notification settings - Fork 17
feat: built-in completions command with shell script generation #88
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nixel2007
wants to merge
11
commits into
oscript-library:develop
Choose a base branch
from
nixel2007:feature/completions
base: develop
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
24d19c5
feat: built-in completions command with shell script generation
nixel2007 0c50f50
refactor(completion): promote КомандаДополнения to top-level class
nixel2007 767078c
refactor(completion): use existing ПолучитьТаблицуОпций/Аргументов fo…
nixel2007 80072b9
refactor(completion): flatten completion values into table row
nixel2007 84a86ac
refactor(completion): use builtin Действие instead of delegate package
nixel2007 26a8800
refactor(completion): trust the provider contract
nixel2007 ff92eb9
refactor: drop delegate package dependency in favor of native Действие
nixel2007 2d721ac
refactor(completions): normalize command model and simplify shell gen…
nixel2007 2e57bf2
refactor(completions): generators as visitors over command tree
nixel2007 e442264
fix(completions): предлагать только канонические имена команд
nixel2007 a762093
fix(completions/zsh): предлагать опции при вводе флага
nixel2007 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
209 changes: 209 additions & 0 deletions
209
src/core/Классы/internal/completion/Классы/ГенераторДополненияBash.os
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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") | ||
| Или Символ = "_" Тогда | ||
| Результат = Результат + Символ; | ||
| Иначе | ||
| Результат = Результат + "_"; | ||
| КонецЕсли; | ||
| КонецЦикла; | ||
| Возврат Результат; | ||
|
|
||
| КонецФункции |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.