WedX - журнал о программировании и компьютерных науках

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

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

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

Два файла рядом с разным выделением

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

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

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


Ответы:


1

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.

16.09.2011
  • Я отмечаю это как ответ, потому что он хорошо объясняет, почему, а также предлагает вполне разумное решение. Я также добавил ответ с подробным описанием моего собственного решения. 18.09.2011
  • Тьфу. Хотя вводный обзор полезен, представленное решение (например, let g:is_bash=1 в .vimrc) бесполезно. Почему? Потому что это заставляет буферы сценариев оболочки, отличные от Bash (например, Bourne, Korn), использовать подсветку синтаксиса, специфичную для Bash. Рассмотрим Тима Фриске отличное решение вместо этого. 17.08.2017
  • @CecilCurry Именно поэтому я добавил справедливое предупреждение о том, что это влияет на каждый файл с filetype=sh. На самом деле, я только что воспроизвел то, что :help ft-bash-syntax рекомендует добавить к вашему .vimrc, чтобы сделать его глобальным по умолчанию. Этот синтаксис не будет применяться ко всем файлам оболочки. Более конкретный шебанг, такой как #!/bin/ksh, по-прежнему будет переопределять этот выбор по умолчанию, поэтому я не могу воспроизвести ваше беспокойство. 20.08.2017

  • 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> 
    
    16.09.2011
  • +1 Сладко! Модельный подход был бы моим любимым. (Если бы меня волновали такие мелкие отклонения :)) 17.09.2011
  • @Peter Coulton: Разве вы не хотели установить переменную b:is_bash локальной для буфера вместо глобальной переменной g:is_bash. По крайней мере, ваш фрагмент кода не отражает этого обстоятельства. Также вы можете объединить две команды au, закончив первую командой let b:is_bash = 1 | setfiletype sh. 19.11.2012
  • Я не вижу преимуществ в установке глобального значения каждый раз, когда вы загружаете файл с «bash» в имени файла, по сравнению с простой установкой его один раз в вашем .vimrc и выполнением этого. 16.05.2015
  • К сожалению, для этого варианта использования невозможно установить переменную в модели. 14.04.2016
  • Неидеально. Глобальное включение g:is_bash=1 включает подсветку синтаксиса, характерную для Bash, для всех буферов сценариев оболочки, отличных от Bash (например, Bourne, Korn), что плохо. Локальное включение b:is_bash=1 гораздо предпочтительнее. Аналогичным образом, файлы ftdetect/ для каждого типа файлов в значительной степени устарели благодаря одному файлу filetype.vim, объединяющему обнаружение всех типов файлов. Решение, которое решает оба вопроса, см. в статье Тима Фриске отличное решение. 17.08.2017

  • 3

    Подобно решению Питера Коултона и задокументированному, а также альтернативе в разделе «new-filetype» справки Vim «filetype», файл ~/.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.
    18.11.2012

    4

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

    :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
    
    16.09.2011
    Новые материалы

    Объяснение документов 02: BERT
    BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

    Как проанализировать работу вашего классификатора?
    Не всегда просто знать, какие показатели использовать С развитием глубокого обучения все больше и больше людей учатся обучать свой первый классификатор. Но как только вы закончите..

    Работа с цепями Маркова, часть 4 (Машинное обучение)
    Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

    Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
    Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..

    Использование машинного обучения и Python для классификации 1000 сезонов новичков MLB Hitter
    Чему может научиться машина, глядя на сезоны новичков 1000 игроков MLB? Это то, что исследует это приложение. В этом процессе мы будем использовать неконтролируемое обучение, чтобы..

    Учебные заметки: создание моего первого пакета Node.js
    Это мои обучающие заметки, когда я научился создавать свой самый первый пакет Node.js, распространяемый через npm. Оглавление Глоссарий I. Новый пакет 1.1 советы по инициализации..

    Забудьте о Matplotlib: улучшите визуализацию данных с помощью умопомрачительных функций Seaborn!
    Примечание. Эта запись в блоге предполагает базовое знакомство с Python и концепциями анализа данных. Привет, энтузиасты данных! Добро пожаловать в мой блог, где я расскажу о невероятных..


    Для любых предложений по сайту: [email protected]