Help us understand the problem. What is going on with this article?

vimでmarkdownのクォート内をシンタックスハイライトする方法とプラグイン

More than 5 years have passed since last update.

以下の記事に触発されて、vimでmarkdownのクォートの中を上手くシンタックスハイライトさせる方法は無いか調べてみました。

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
screenshot.png

joker1007/vim-ruby-heredoc-syntax

screenshot.png

これで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

repro
世界59か国6,500以上の導入実績を持つCE(カスタマーエンゲージメント)プラットフォーム「Repro(リプロ)」を提供
https://repro.io/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした