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
Этот подход имеет следующие последствия:
- Есть один
~/.vim/filetype.vim
файл вместо одного для каждого типа файла под~/.vim/ftdetect
каталог. 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