Какова хорошая эвристика для определения ширины табуляции, используемой в исходном файле?

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

Мотивация для этого - написание расширения для редактора SubEthaEdit. SubEthaEdit, к сожалению, не делает ширину табуляции доступной для скриптов, поэтому я собираюсь угадать ее на основе текста.

Подходящая эвристика должна:

  • Работать достаточно хорошо для интерактивного использования. Я не думаю, что это будет проблемой, и при необходимости можно использовать только часть текста.
  • Будьте независимы от языка.
  • Возвращает самую длинную подходящую ширину табуляции. Например, любой файл с шириной табуляции в четыре пробела также может быть файлом с двумя пробелами табуляции, если каждый отступ фактически был на вдвое больше уровней. Ясно, что четыре пробела были бы правильным выбором.
  • Всегда делайте это правильно, если отступ полностью ровный.

Некоторые упрощающие факторы:

  • Можно предположить, что по меньшей мере одна строка имеет отступ.
  • Можно принять, что ширина табуляции составляет по меньшей мере два пробела.
  • Можно с уверенностью предположить, что отступ делается только с пробелами. Дело не в том, что я имею что-то против вкладок - напротив, я сначала проверю, используются ли какие-либо вкладки для отступов, и обработаю их отдельно. Это действительно означает, что табуляции и пробелы, смешанные с отступом, могут не обрабатываться должным образом, но я не считаю это важным.
  • Можно предположить, что нет строк, содержащих только пробелы.
  • Не со всеми языками нужно обращаться правильно. Например, успех или неудача с такими языками, как lisp и go, будут совершенно не важны, поскольку они обычно не имеют отступа вручную.
  • Совершенство не требуется. Мир не закончится, если несколько строк нужно будет время от времени корректировать вручную.

Какой подход вы выберете, и в чем вы видите его преимущества и недостатки?

Если вы хотите предоставить рабочий код в своем ответе, лучшим подходом, вероятно, будет использование сценария оболочки, который читает исходный файл из stdin и записывает ширину табуляции в stdout . Псевдокод или четкое описание словами тоже подойдут.

Некоторые результаты

Чтобы проверить различные стратегии, мы можем применять разные стратегии к файлам в стандартных библиотеках для языковых дистрибутивов, поскольку они предположительно следуют стандартному отступу для языка. Я рассмотрю библиотеки Python 2.7 и Ruby 1.8 (системный фреймворк устанавливается в Mac OS X 10.7), для которых ожидаемая ширина вкладок составляет 4 и 2 соответственно. Исключаются те файлы, строки которых начинаются с символов табуляции или не имеют строк, начинающихся как минимум с двух пробелов.

Python:

                     Right  None  Wrong
Mode:                 2523     1    102
First:                2169     1    456
No-long (12):         2529     9     88
No-long (8):          2535    16     75
LR (changes):         2509     1    116
LR (indent):          1533     1   1092
Doublecheck (10):     2480    15    130
Doublecheck (20):     2509    15    101

Ruby:

                     Right  None  Wrong
Mode:                  594    29     51
First:                 578     0     54
No-long (12):          595    29     50
No-long (8):           597    29     48
LR (changes):          585     0     47
LR (indent):           496     0    136
Doublecheck (10):      610     0     22
Doublecheck (20):      609     0     23

В этих таблицах "Right" следует рассматривать как определение стандартной ширины табуляции в языковом стандарте, "Wrong" как ненулевую ширину табуляции, не равную стандарту языка width, а «None» означает нулевую ширину табуляции или отсутствие ответа. «Режим» - это стратегия выбора наиболее часто встречающегося изменения отступа; «Первый» - это отступ первой строки с отступом; «No-long» - это стратегия FastAl по исключению строк с большим отступом и переходу в режим с числом, указывающим максимально допустимое изменение отступа; "LR" - это стратегия Patrick87, основанная на линейной регрессии,с вариантами, основанными на изменении отступа между строками и на абсолютном отступе строк; «Doublecheck» (не мог устоять перед каламбуром!) - это модификация Марком стратегии FastAl, ограничивающая возможную ширину табуляции и проверяющую, часто ли встречается половина модального значения, с двумя разными порогами для выбора меньшей ширины.

12
задан JasonMArcher 15 July 2015 в 22:08
поделиться