Подтвердить что ты не робот

Vim несовместимо выделяет синтаксис bash файлов

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

Это здорово, если не заметить, что это не полностью исправить:

Two files side-by-side with different highlighting

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

Сопоставление клавиш

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

Ответ 3

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

: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

Ответ 4

Подобно решению Питера Култона и документированному, а также альтернативе в разделе "тип нового файла" файла "тип файла" 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.