Не могу сообразить с какой стороны подойти к автоматизации отступов в редакторе.
http://cc-mode.sourceforge.net/html-manual/Indentation-Engine-Basics.html
- Определить синтаксическую конструкцию, первую на строке, на которой мы находимся, и найти ее "опорную точку" (anchor position). Например, открывающуюся скобку на предыдущей строке.
- Найти в настройках смещение(-ия) отступа для этой синтаксической конструкции и применить его.
http://stackoverflow.com/questions/1318976/smart-indent-algorithm-documentation
Одна из идей - применить подход pretty printer-а: построить AST, запустить по нему Visiter-а и сформировать layout-ы в виде вложенных прямоугольников.
http://steve-yegge.blogspot.com/2008/03/js2-mode-new-javascript-mode-for-emacs.html
Перемотать к Indentation
Каждый токен классифицируем как
- '(3' токен начинающий вложенный блок, для таких токенов указываем сдвиг 3
- ')' токен заканчивающий вложенный блок
- ',' токен разделитель элементов внутри блоке
- '.' прочие токены
Токены в разных синтаксических правилах будем рассматривать, как различные. Тогда алгоритм следующий:
- производим синтаксический разбор и строим AST из '(),.'
- если уровень вложенности 0, выравниваем в позицию 1
- если первый токен в строке ')' выравниваем его под соответствующим '(' без сдвига
- если предыдущий токен ',' выравниваем строку под соответствующим '(' со сдвигом
- если предыдущий токен '(' выравниваем строку под соответствующим '(' со сдвигом
- иначе выравниваем под соответствующим '('+2. (Возможно нужен алгоритм сложнее, учитывающий отступ от предыдущей аналогичной строки
generic_subprogram_declaration:: ::=
generic_formal_part **procedure**,,//)//,, defining_program_unit_name parameter_profile;,,//,//,,
generic_formal_part:: ::=
**generic**,,//(3//,, {generic_formal_parameter_declaration | use_clause}
use_clause:: ::= **use** package_name {, package_name};,,//,//,,
parameter_profile:: ::=
[(,,//(1//,,parameter_specification {;,,//,//,, parameter_specification}),,//)//,, ]
generic_formal_parameter_declaration:: ::=
**with** subprogram_specification [is subprogram_default];,,//,//,,
generic -- пр. 2
use Some_Package; -- пр. 5
with procedure Proc (X : Integer; -- пр. 4
Y : Integer); -- пр. 4
procedure Do -- пр. 3
(Param : -- пр. 6 тут ошибка, срабатывает пр. 2
Long_Type_Name := Long_Default_Expression; -- пр. 6
Result : out Integer); -- пр. 4