Vim противоречиво подсвечивает синтаксис bash-файлов

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

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

Два файла рядом с различной подсветкой

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

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

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

4 ответа

Решение

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,

Оказывается, что 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

режимной_строки:

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

Key Mapping

nmap <silent> <leader>b :let g:is_bash=1<cr> :setf sh<cr> 

Подобно решению Питера Коултона и задокументированному, а также альтернативе в разделе "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/filetype.vim файл вместо одного для каждого типа файла под ~/.vim/ftdetect каталог.
  2. b:is_bash переменная устанавливается локальной для буфера, в отличие от глобальной, ссылаясь на нее как g:is_bash,

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

: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
Другие вопросы по тегам