Vim противоречиво подсвечивает синтаксис bash-файлов - PullRequest
28 голосов
/ 17 сентября 2011

Когда я открываю некоторые файлы скриптов bash с помощью vim, он иногда идентифицирует их как conf файлы, это нормально, я могу просто исправить это, установив тип файла на sh с :setf sh.

Это здорово, за исключением того, что я заметил, что это не совсем исправляет ситуацию:

Two files side-by-side with different highlighting

Обратите внимание, что shopt правильно выделен слева, но не справа, где я вручную установил тип файла sh.

Это означает, что когда vim идентифицирует файл как bash или sh, он устанавливает тип файла равным sh, но затем выполняет некоторые дополнительные шаги, которые я не выполняю, когда устанавливаю тип файла вручную.

Кто-нибудь знает, что это может быть и как я могу это исправить?

Ответы [ 4 ]

30 голосов
/ 17 сентября 2011

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

vim автоматически устанавливает тип файла для определенных имен файлов, таких как .bashrc, .tcshrc и т. Д. Но файл с расширением .sh будет распознаваться как сценарий csh, ksh или bash. Чтобы определить, что это за скрипт, vim читает первую строку файла, чтобы посмотреть на #! линия.

Если в первой строке содержится слово bash, файл определяется как скрипт bash. Обычно вы видите #!/bin/bash, если сценарий предназначен для непосредственного выполнения, для какого-то другого файла конфигурации оболочки вы должны использовать расширения .bash.

Помощь в vim объясняет это также на :help ft-bash-syntax. Вы также можете использовать let g:is_bash=1 в вашем .vimrc, чтобы сделать синтаксис bash подсветкой по умолчанию для всех файлов с filetype=sh. Если вы хотите посмотреть на детали, это реализовано в $VIMRUNTIME/filetype.vim.

7 голосов
/ 17 сентября 2011

Оказывается, что syntax/sh.vim включает специальную подсветку для Korn , Bash и sh , вам просто нужно указать, что вы используете.Это делается с помощью b:is_kornshell, b:is_bash и b:is_sh соответственно.

В зависимости от ситуации, которую я считаю, я буду использовать следующее:

ftdetect / bash.vim:

au BufRead,BufNewFile *bash* let g:is_bash=1
au BufRead,BufNewFile *bash* setf sh

Modeline:

# vim:let g:is_bash=1:set filetype=sh:

Отображение клавиш

nmap <silent> <leader>b :let g:is_bash=1<cr> :setf sh<cr> 
3 голосов
/ 19 ноября 2012

Аналогично решению Питера Култона и задокументированному, а также альтернативе в разделе «new-filetype» справки «filetype» файла Vim ~/.vim/filetype.vim может содержать следующий код:

if exists("did_load_filetypes")
  finish
endif

augroup filetypedetect
  au! BufRead,BufNewFile *bash* let b:is_bash = 1 | setfiletype sh
augroup END

Этот подход имеет следующие последствия:

  1. Для каждого типа файлов в каталоге ~/.vim/ftdetect имеется один ~/.vim/filetype.vim файл.
  2. Задана переменная b:is_bashлокальный по отношению к буферу, а не глобальный, ссылаясь на него как g:is_bash.
3 голосов
/ 17 сентября 2011

Попробуйте просмотреть эффективную настройку синтаксиса

:windo echo b:current_syntax

(Я ожидаю, что первое окно скажет bash, а второе скажет sh ...?)

Также попробуйте заглянуть с синхронизацией Synatx:

:windo syn sync fromstart
:windo syn sync minlines=300

В общем

:he syn-sync

для получения дополнительной информации


PS.

Длинный выстрел, но некоторые другие выделения могут мешать:

:windo se @/=''
:match none
:2match none
:3match none
...