Найти тему
Блокнот математика

Рубрика "Секреты Вим". Распознавание типа файла

Привет, коллеги. Мы уже знаем, что Вим умеет распознавать тип файла и, например, раскрашивать текст по синтаксису. А еще можно задавать отступы; оба случая полезны для программирования. Можно задавать и другие настройки: скажем, создавать привязки, для каждого типа файла свои.

Распознавай!))
Распознавай!))

Можно это всё сделать самому через автокоманды. Но многое уже сделано за нас, и можно пользоваться готовыми средствами или модифицировать их под себя минимальными усилиями. Итак...

В поставке Вим идет плагин filetype, который всё вышесказанное и делает. Дайте команду :filetype и посмотрите, что у вас включено. А включено может быть: распознавание типа файла, файловые плагины (то есть, скрипты с настройками) и отступы: скрипты, задающие правила для них.

Включить распознавание типа: filetype on

Чтобы выключить, замените on на off и это всегда так.

Распознав тип файла, Вим задаст переменную filetype. Если файл распознался неправильно, можете ее вручную изменить; в частности, если вам вообще не надо распознавать тип (пример: когда приходится открывать старый фортран с фиксированной записью), сбросьте filetype (set filetype '') или выставьте заведомо непредусмотренное значение: set filetype=ignored

Вим ориентируется по расширению, а при необходимости заглядывает в содержимое файла. Однако бывает так, что под одним расширением скрываются разные типы файлов. Например, *.tex может быть plaintex, LaTeX, AMSTeX, Beamer и бог знает что ещё. И по содержимому не всегда понятно, что это. Иногда можно помочь Виму, задав некоторую переменную. Для ТеХ есть, например, g:tex_flavor. А для .sh имеется g:bash_is_sh.

Еще есть такая вещь, как modeline. Вы можете в своем файле, в конце, задать эту (и другие) переменную, оформив их как комментарий. Подробнее в другой раз, а пока пример: %% vim: filetype=tex

Плагином для файла называется специальный скрипт, настраивающий Вим для данного типа файлов. Включаем плагины для файлов: filetype plugin on. Включение файловых плагинов включает и распознавание типа файлов. Вим будет сам отрабатывать автокоманду и загружать скрипт настроек для данного типа файла. Вы можете использовать готовый (их много в поставке), написать свой или дополнить вимовский своим.

Аналогично с отступами. Они описываются отдельным скриптом и их можно включать или отключать независимо от плагина: filetype indent on. Это тоже включает и распознавание типа. Про правила отступов в другой раз расскажу. Важно, что "простые" отступы - это другое.

Включение раскраски синтаксиса syntax on тоже включает распознавание типа файла.

Можно попросить Вим снова попробовать распознать тип файла: filetype detect. Это полезно, когда вы начали с пустого файла и ввели что-то показательное, вроде #!/usr/bin/perl

Если ваш тип файлов не предусмотрен, можно добавить новый. Вариантов несколько.

1. Создайте папку ftdetect где-нибудь, где Вим ее найдет (см. runtimepath, там должно быть что-то вроде ~/.vim) и поместите туда файл с именем тип.vim с автокомандой

au BufRead,BufNewFile *.my set filetype=my

Здесь тип my и, следовательно, файл my.vim и распознает файлы с расширением .my. При этом вы перекрываете стандартное распознавание.

Можно использовать вместо set filetype особую команду setfiletype: она выставит значение filetype, если оно еще не выставлено. При этом вы дополняете стандартное распознавание: распозналось, и хорошо, а нет - распознаем сами.

2. Еще можно создать в ~/.vim файл filetype.vim и эти автокоманды поместить туда. Удобство, что файл один на все типы. Этот файл отработает до стандартных, но те не будут менять filetype, если она уже выставлена.

3. Наконец, можно создать там же файл scripts.vim и поместить туда скрипт для анализа содержимого файла. Этот скрипт отработает раньше всего. Далее можно усложнять до бесконечности, распознавая, любовная ли это лирика или квартальный отчет. Дело ваше. В конце полезные примеры распознавания по содержимому.

Обилие вариантов позволяет распознавать тип до или после встроенных распознавалок. Еще возможность создать один файлик для своего типа и не мешать удобна, особенно если пользователей много.

Аналогично осуществляются и модификации стандартных файловых плагинов. В папке ftplugin в том же месте (например, ~/.vim/ftplugin) создаете файл вида тип.vim; например, tex.vim, если желаете добавить чего-то при работе с техом. Там можете задавать опции (лучше через setlocal, чтобы это было локально для файла) и привязки (в виде map <buffer> ... ...).

Заметьте, что буквы FTP никакого отношения к протоколу не имеют. Это file type plugin.

Можно в начале комбинации указать <LocalLeader> и тогда комбинация начнется со слеша или с того, что указано в переменной maplocalleader. Так можно обезопасить свои глобальные привязки. Если переменная maplocalleader не задана, то, скажем,

map <buffer> <LocalLeader>q i$$<ESC>hi

создаст привязку \q, которая будет вставлять два доллара и помещать курсор между ними, включая режим вставки. А если переменная содержит запятую, то привязка будет ,q.

Пара примеров распознавания по содержимому.

  1. Скрипты часто начинаются с шебанга: строки #!/путь/интерпретатор. Вот пример из справки Вим. Первый if проверяет, не распозан ли уже тип файла. Второй извлекает первую строку и проверяет ее на совпадение с шебангом.
    if did_filetype()
    finish
    endif
    if getline(1) =~ '^#!.*[/\\]xyz\>'
    setf xyz
    endif
  2. Вы пишете тексты по-русски, итальянски и на иврите. Вам надо, чтобы раскладка была соответствующая. Русская по умолчанию в .vimrc прописана. Как определить язык? Для начала, выполните первый if, чтобы не работать зря. Затем:
    let lines = getline(1,12) возьмем первые 12 строк в список
    let text = join(lines, '') здесь два апострофа, а не двойная кавычка!
    if text =~ '[èóì]' проверим, нет ли типичных для языка букв
    set filetype = italian если есть, то всё ясно
    endif
    if text =~ '[אהו]'
    set filetype = hebrew
    endif
    if text =~ '[аеоуйы]'
    set filetype = russian
    endif
    Конечно, двенадцати строк может не хватить, но мы же не атомную станцию конструируем.

Эти примеры должны лежать в папке ~/.vim (уточните в переменной runtimepath) в файле scripts.vim. А как создать файловый плагин для этих типов, смотрите выше!

Удачи, коллеги!

Оглавление рубрики

Путеводитель по каналу