Я хотел бы определить ширину закладки, используемую в исходных файлах с отступом с пробелами. Это не сложно для файлов с особенно регулярным отступом, где ведущие пробелы используются только для отступов, всегда в кратных ширине табуляции и с отступом, увеличивающимся на один уровень в момент времени. Но у многих файлов будет некоторый отход от такого рода регулярных отступов, как правило, для некоторой формы вертикального выравнивания. Таким образом, я ищу хорошую эвристику, чтобы оценить, какая ширина табуляции была использована, что дает возможность нерегулярного отступа.
Мотивация для этого заключается в написании расширения для редактора SubEthaEdit. К сожалению, SubEthaEdit не делает ширину табуляции доступной для сценариев, поэтому я собираюсь угадать ее на основе текста.
Подходящая эвристика должна:
- Выполните достаточно хорошо для интерактивного использования. Я не думаю, что это будет проблемой, и только часть текста может быть использована в случае необходимости.
- Не зависит от языка.
- Верните самую длинную подходящую ширину вкладки. Например, любой файл с шириной табуляции в четыре пробела также может быть файлом с вкладками с двумя пробелами, если каждый отступ был фактически вдвое большим количеством уровней. Очевидно, что четыре места будут правильным выбором.
- Всегда делайте это правильно, если отступ полностью правильный.
Некоторые упрощающие факторы:
- По крайней мере, одна строка может считаться отступом.
- Ширина закладки может считаться как минимум двумя пробелами.
- Безопасно предположить, что отступ делается только с пробелами. Это не то, что у меня есть что-либо против вкладок - совсем наоборот, я сначала проверю, есть ли какие-либо вкладки, используемые для отступов, и обрабатывать их отдельно. Это означает, что вкладки и пробелы смещения отступа могут обрабатываться неправильно, но я не считаю это важным.
- Можно предположить, что нет строк, содержащих только пробелы.
- Не все языки должны обрабатываться правильно. Например, успех или неудача с такими языками, как lisp и go, будут совершенно неактуальны, поскольку они обычно не отступаются вручную.
- Совершенство не требуется. Мир не собирается заканчиваться, если несколько строк иногда необходимо отрегулировать вручную.
Какой подход вы возьмете, и что вы видите в его преимуществах и недостатках?
Если вы хотите предоставить рабочий код в своем ответе, лучше всего использовать оболочку script, которая читает исходный файл из 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
В этих таблицах "Правильно" следует принимать за определение ширины табуляции по языку "Неправильно" в качестве ненулевой ширины табуляции, не равной ширине языкового стандарта, и "Нет" в качестве нулевой табуляции, ширину или отсутствие ответа. "Режим" - это стратегия выбора наиболее часто встречающихся изменений в отступе; "Первый" принимает отступы первой строки с отступом; "Нет-долго" - это стратегия FastAl для исключения строк с большим отступом и с использованием режима, с указанием номера, указывающего максимально допустимое изменение отступа; "LR" - это стратегия Patrick87, основанная на линейной регрессии, с вариантами, основанными на изменении отступов между линиями и абсолютном отступе линий; "Doublecheck" (не может противостоять каламбуре!) Является модификацией Mark стратегии FastAl, ограничивающей возможную ширину табуляции и проверяющей частоту появления половины модального значения с двумя разными порогами для выбора меньшей ширины.