Занялся сегодня вопросом, почему не работает smart indenting — эта опция даже задизаблена в диалоге настройки VS->Tools->Options->Text Editor->Nemerle
Для включения такой возможности нужно было добавить в реестр ключ ShowSmartIndent (полный путь в статье —
Registering a Language Service)
Ключ только включает возможность выбора этой опции, логику нужно писать руками. Способ подключения логики описан в статье автора интеграции для Boo (
http://jagregory.com/writings/smart-indentation-for-visual-studio-extensibility-projects/). Джейм пишет, что единственный рабочий способ — это переопределение метода ViewFilter.HandleSmartIndent (кто бы мог подумать). Несмотря на видимую очевидность такого решения, добраться до него непросто — в api интеграции с пол десятка методов и интерфейсов, в описании который встречается намек на indenting.
В репозитории интеграции Boo лежит и реализация алгоритма smart indenting, но она довольно примитивная: увеличиваем отступ после строк, оканчивающихся на ":", и уменьшаем после строк, подходящих под регулярное выражение "(?:return|pass)(?:[\t ]?[\w]*[\t ]?(?<exp>(?:if|unless)))?".
Я начал было писать свою логику (уменьшаем отступ после закрывающей скобки, после ";" остаемся на месте, и увеличиваем отступ во всех остальных способах). Логика эта даже заработала, но неохваченными осталить match, case и случаи со вложенными конструкциями типа if() без операторных скобок:
if()
if()
if()
foo();
foo();
И подумалось мне — а ведь Влад уже реализовал всю логику форматирования. Наверное будет правильнее не париться и не изобретать ее заново а переиспользовать готовый форматер? От форматтера нужен метод типа GetIndentLevel(line : int, engine : IEngine, filePath : string) : int, возвращающий уровень вложенности для текущей строки. Но тут без помощи Влада мне не обойтись.
И еще наверное нужно как то передаать в форматер настройки форматирования (LanguagePreferences), сейчас количество и тип пробельных заменителей захаркодены в форматере. А еще лучше написать свою реализацию LanguagePreferences (NemerleLanguagePreferences), с дополнительными параметрами форматирования — те же matchCasesIndentOffset, matchCasesBodyIndentOffset, variantOptionIndentOffset значения которых сейчас тоже жестко прошиты в коде. А потом глядишь и выведем эти параметры в GUI конфигурации.
Влад, как думаешь?