Change filetype (or other Vim settings) blockwise

2019-03-30 14:31发布

问题:

I program a lot of Perl in Vim. Often I just hack together some CGI script and put the CSS right into the program code. So lately I asked myself if it was possible, to put some Vim-specific comments around such blocks in my code, so that vim highlights the specific area not as a Perl script, but as a cascading stylesheet.

This also would be neat when working with Mojolicious where you can embed entire templates just into the DATA-area but lose all the highlighting of the HTML then.

Of course, I could switch manually between the filetypes/highlighting. But I wonder if there is better way.

Thanks, Sven

回答1:

You can have multiple filetypes set for a single file :

:set ft=perl.css

With that you get omnicompletion (and snippets if applicable) for both languages and semi-correct highlighting: if you put your CSS rules in quotes it will be highlighted as a string.

I've just found (yesterday) a cool plugin inspired by an Emacs feature called NrrwRgn. It allows you to select a "region" of code, say the CSS part of your Perl file and edit it in a scratch window for which you :set ft=css. Each save is reflected in the original window. Very useful when dealing with PHP templates full of PHP/HTML/JS/CSS.



回答2:

If you don't want to come up with your own hybrid highlighting rules:

:set syntax=perl

then when you want to edit css,

:set syntax=css

To make it easier, you could map some keys for both in your .vimrc, which would make it easy to toggle back and forth.

map <F3> :execute "set syntax=perl" <CR>
map <F4> :execute "set syntax=css" <CR>


回答3:

I'm not familiar with Perl and how the CSS fits within the code, but if you use heredocs, here's a nice article that deals with a similar problem: http://blogs.perl.org/users/ovid/2011/06/syntax-highlight-your-sql-heredocs-in-vim.html

What the author is trying to do is highlight SQL within heredocs marked with an SQL delimiter. In your case, you could put something like this in .vim/after/ftplugin/perl.vim:

syntax on

unlet b:current_syntax
syntax include @CSS syntax/css.vim
syntax region cssSnip matchgroup=Snip start=+<<['"]CSS['"].*;\s*$+ end=+^\s*CSS$+ contains=@CSS

hi link Snip SpecialComment

The CSS will be highlighted, as long as you write it like this:

my $css = <<"CSS";
  a {
    background-color: blue;
  }
CSS

If you want to use comments as delimiters instead, you could hack on the above snippet, particularly the start and end patterns. For example, this:

syntax region cssSnip matchgroup=Snip start=+^\s*# -- CSS --\s*$+ end=+^\s*# -- END CSS --\s*$+ contains=@CSS

Gets you highlighting within specific comments like so:

# -- CSS --
  a {
    background-color: blue;
  }
# -- END CSS --


回答4:

You can use my SyntaxRange plugin for that. Assuming you delimit the CSS lines with @cssbegin@ / @cssend@, put the following into ~/.vim/after/syntax/perl/perl_cssinclude.vim:

:call SyntaxRange#Include('^@cssbegin@', '^@cssend@', 'css', 'NonText')