以下の記事に触発されて、vimでmarkdownのクォートの中を上手くシンタックスハイライトさせる方法は無いか調べてみました。
- RubyMineのシンタックスハイライトがすごかった件について - くりにっき
- Vim でコンテキストによって filetype を自動的に切り換えるプラグインをつくっている - C++でゲームプログラミング
vim-preciousでも良さそうなのですが、最初からハイライトされてる方が自分好みだったので。
Vim Advent Calendarとして書けば良かったかもしれない。
別言語のシンタックス設定を読み込む
function! MarkdownQuoteSyntaxGroup(filetype)
let ft = toupper(a:filetype)
return 'markdownCodeGroup'.ft
endfunction
function! IncludeOtherSyntax(filetype)
let group = MarkdownQuoteSyntaxGroup(a:filetype)
" syntax save
if exists('b:current_syntax')
let s:current_syntax = b:current_syntax
unlet b:current_syntax
endif
execute 'syntax include @'.group.' syntax/'.a:filetype.'.vim'
" syntax restore
if exists('s:current_syntax')
let b:current_syntax=s:current_syntax
else
unlet b:current_syntax
endif
return group
endfunction
syntax include @groupName syntax/javascript.vim
で他のシンタックスファイルを読み込み名前付ける事ができる。
ただし、シンタックスファイルはb:current_syntax
が存在すると読み込みをストップするようになってます。
なので、一時的にb:current_syntax
を無効化してからシンタックスを読み込みます。
シンタックス設定を利用するパターンを指定する
function! MarkdownQuoteSyntaxRegion(filetype)
let ft = toupper(a:filetype)
return 'markdownCodeRegion'.ft
endfunction
function! EnableMarkdownQuoteSyntax(filetype, start)
let group = MarkdownQuoteSyntaxGroup(a:filetype)
let region = MarkdownQuoteSyntaxRegion(a:filetype)
let regexp_start = "^\\s*```".a:start."$"
let regexp_end = "^\\s*```\\ze\\s*$"
execute 'syntax region '.region.'
\ matchgroup=markdownCodeDelimiter
\ start="'.regexp_start.'" end="'.regexp_end.'"
\ keepend contains=@'.group
endfunction
syntax region
を使うと指定のパターンに囲まれた部分に対してシンタックス設定を適用できる。
それと合わせてcontains
オプションを指定する事でregionの内側で使うシンタックス設定を設定できる。
さっき読み込んで名前を付けたシンタックス設定をcontainsに指定する事で、特定の領域内だけ他言語のシンタックスハイライトを適用できる。
call IncludeOtherSyntax("javascript")
call EnableMarkdownQuoteSyntax("javascript", "\\%(javascript\\|js\\)")
で、せっかくなのでプラギンにしてみました。
joker1007/vim-markdown-quote-syntax
joker1007/vim-ruby-heredoc-syntax
これでvimのシンタックスハイライトは大したことないとか言わせねえ!
まだドキュメントとか全然書いてないので対応言語が分かりづらいですが、現在デフォルトで対応しているのは以下の通りです。
-
vim-markdown-quote-syntax
- vim
- diff
- c
- cpp
- java
- ruby
- haskell
- python
- perl
- javascript
- html
- sh
- sql
- ocaml
- erlang
-
vim-ruby-heredoc-syntax
- javascript
- coffeescript
- sql
- html
デフォルトの設定は適当に目についた言語とrubyのヒアドキュメントで書く事の多そうな言語です。
Rubyのヒアドキュメントのシンタックス定義を解読するの辛かった…。
let regexp1 = "\\%(\\%(class\\s*\\|\\%([]})\"'.]\\|::\\)\\)\\_s*\\|\\w\\)\\@<!<<-\\=\\zs".a:start
let regexp2 = "\\%(\\%(class\\|::\\)\\_s*\\|\\%([]}).]\\)\\s\\|\\w\\)\\@<!<<-\\=\\z(".a:start."\\)\\ze\\%(.*<<-\\=['`\"]\\=\\h\\)\\@!"
書いたプラグインのコードの一部ですが、もう意味分かりませんw