2009/01/16


今日、とある場所でkanaさんからvimに"syn-include"なんて物があるのを教えて貰いました。

:he syn-include
9. Including syntax files                               *:syn-include* *E397*

It is often useful for one language's syntax file to include a syntax file for
a related language.  Depending on the exact relationship, this can be done in
two different ways:

        - If top-level syntax items in the included syntax file are to be
          allowed at the top level in the including syntax, you can simply use
          the |:runtime| command: >

  " In cpp.vim:
  :runtime! syntax/c.vim
  :unlet b:current_syntax

<       - If top-level syntax items in the included syntax file are to be
          contained within a region in the including syntax, you can use the
          ":syntax include" command:

:sy[ntax] include [@{grouplist-name}] {file-name}

          All syntax items declared in the included file will have the
          "contained" flag added.  In addition, if a group list is specified,
          all top-level syntax items in the included file will be added to
          that list. >

   " In perl.vim:
   :syntax include @Pod <sfile>:p:h/pod.vim
   :syntax region perlPOD start="^=head" end="^=cut" contains=@Pod
<
          When {file-name} is an absolute path (starts with "/", "c:", "$VAR"
          or "<sfile>") that file is sourced.  When it is a relative path
          (e.g., "syntax/pod.vim") the file is searched for in 'runtimepath'.
          All matching files are loaded.  Using a relative path is
          recommended, because it allows a user to replace the included file
          with his own version, without replacing the file that does the ":syn
          include".
知らんかった...
これを使えばPerlのPodだけ別のsyntaxファイルから適用出来るといった物。
これは凄い!

つまりはregionだけ決められれば、その部分に言語毎のsyntaxが適用出来る事になる。試しに、はてなのスーパーPre記法に色を付けられる様にしてみた。
ベースはmotemenさんのhatena-vim
motemen's hatena-vim at master - GitHub

Vim scripts for posting/updating hatena diary/group

http://github.com/motemen/hatena-vim/tree/master
このsyntax/hatena.vimの最下行に以下のコードを貼り付ける。
" append to syntax/hatena.vim
function SyntaxSuperPre()
  let lnum = 1
  let lmax = line("$")
  let mx = '^>|\(.*\)|$'
  while lnum <= lmax
    let curline = getline(lnum)
    if curline =~ mx
      let lang = substitute(curline, mx, '\1', '')
      exec 'runtime! syntax/'.lang.'.vim'
      unlet b:current_syntax
      let syntaxfile = fnameescape(substitute(globpath(&rtp, 'syntax/'.lang.'.vim'), '[\r\n].*$', '', ''))
      if len(syntaxfile)
        exec 'syntax include @inline_'.lang.' '.syntaxfile
        exec 'syn region hatenaSuperPre matchgroup=hatenaBlockDelimiter start=+^>|'.lang.'|$+ end=+^||<$+ contains=@inline_'.lang
      endif
    end
    let lnum = lnum + 1
  endwhile
  " workaround for perl
  syn cluster inline_perl remove=perlFunctionName
endfunction
call SyntaxSuperPre()
適当なので使わないで下さい
perlFunctionNameはregionが広すぎるので無効にしてます
すると...
hatena super pre on vim
おーーー!出ました。

続きはこの辺でやっていきます。出来上がったらmotemenさんにmergeして貰うのも良いかも。
ちなみに、filetype適用時にロードしているので、pre記法の言語を編集途中で変更したり、新しくスーパーPre記法を追加したりするとsyntaxが適用されなくなります。ま、これからですな。

syn-include++
Posted at by



2008/11/13


Gist GitHubが提供するコードスニペットサービス(という言い方で良いのかな?)、「Gist」をvimから扱えるvimscript「Gist.vim」を書いた。
内部はcurlコマンドを使っており
  • 一覧
  • 閲覧
  • ポスト
  • プライベートポスト
が出来る様になっています。導入にはcurlコマンドとgitコマンドが必要です(コマンドライン版gistコマンドやrubyは必要ありません)。ただし、グローバル変数に"github_user"と"github_token"さえ設定していればgitコマンドも必要ありません。
使い方は、適当にバッファを開いて :Gist
とすればポストされ、公開URLがコマンドライン上に表示されます。
またビジュアル選択して :'<,'>Gist
で部分的にポストする事も出来ます。なお引数として :Gist -p
もしくは--private
を指定するとprivateモードでポストします。 GistのIDが分かっている場合には :Gist XXXXX
とID指定でgistを開く事も出来ます。
さらに :Gist -la もしくは--listall
で全ユーザの最新gist一覧 :Gist -l mattn もしくは--list mattn
でユーザ指定一覧、といった使い方も出来ます。

現在、github上で開発を進めておりvim.orgでも公開しています。
よかったら使ってみて下さい。

Posted at by



2008/11/10


最近のインターネットは便利になったもので、なんと美輪明宏のチンコがあるのかないのかを返してくれるWebAPIまである。インターネットリソースの大きさは今後もきっと拡大して行き、いずれはきっとGoogle Alertや、はてなアンテナ、はたまたEngadget Japanese等でのリーク流出等で実際の「あり/なし」が判明、本当に正しい結果が返って来る事になると思われる。

だがしかし、上記JSONサーバにはRSS/Feedが存在せず、実は「美輪明宏にはチンコがない」とユーザが初めて気付く為には、結果をメール等で通知する様なデーモンプロセスを稼働させてこのサービスを監視(ポーリング)しJSONをパースした結果としてユーザに通知するか、ユーザにとって使用頻度の高い乗用アプリケーションへチェック機能を付けユーザの操作(トリガ)でチェックを行う方法が選択肢となってしまう。たしかにポーリングは簡単に、かつ昼夜を問わず最新の情報を人手無しに監視し続ける事が出来る。
しかしながら、このサーバに負荷を掛けることは今後のインターネット発達が望まれる中、希少な有志の力を自ら塞ぎ込む形と成り得ない。
ここはトリガ形式を考えるのが適切である。

では、トリガ形式としてどんな常用アプリケーションが適切か。私が考えた結果がテキストエディタである。テキストエディタはユーザであればほぼ万人が使っている。今回私は、このテキストエディタの中でもギーク性が高いと言われるvimを選んだ。

まずは、何をもって「美輪明宏のチンコの有無」を確認するか。
テキストエディタであれば、入力補完がユーザのニーズに答えられる物になるだろう。
たとえば
美輪明宏にチンコは
まで入力し、<tab>を押下して「ある」もしくは「ない」が補完されたとすれば、それはかなり使い勝手のある物になると思われる。

運が良いことに、vimでは入力補完にフックメソッドを組み込む事が出来るため、今回私は、以下の様なソースを書いた。
func! s:CheckTimpo()
  " ここにデータ取得処理を入れる
endfunc
iabbr <silent> 美輪明宏にチンコは 美輪明宏にチンコは<C-R>=<SID>CheckTimpo()<CR>
入力I/Fに対するメソッド呼出部が完成した。
あとはJSONをどう解釈するか。ここで私にあるひらめきが。
たしかvim7のDictionaryは、JSON展開形式に似てたはず
そして以下のようなコードを書いた。 func! s:CheckTimpo()
  let ret = system("curl -s http://dzfl.jp/mojo/")
  let true = 'ある'
  let false = 'ない'
  exec "let json = " . ret
  return json['miwa']
endfunc
iabbr <silent> 美輪明宏にチンコは 美輪明宏にチンコは<C-R>=<SID>CheckTimpo()<CR>
以下にこのソースの解説を行う。
JSONサーバからは以下の形式でデータが戻される。
{ "miwa": true }
vim7ではDictionaryが導入されており、そのシンタックスは { key: value }
となる。つまりtrue/falseといった予約語を定義してやればJSON形式が扱える事になるのだ。
上記ソースではtrue/falseの定義を行った上でDictionaryへ値展開し、代入している。これによりvim7ではjsonという変数に対して json["miwa"]
とアクセス出来るのである。true/falseはそれぞれ「ある」/「ない」と定義している為、もし美輪明宏にチンコがあれば
json["miwa"] == "ある"
また、美輪明宏にチンコがなければ
json["miwa"] == "ない"
となるのだ。
この値をスクリプト内メソッドCheckTimpoの戻り値として返し、入力補完を行えるようになる。
以上の処理手順により、vim7を使っているならば何時でも
美輪明宏にチンコは
とまで入力し、補完トリガと成り得るようなキー(例えばスペース)を入力すれば
美輪明宏にチンコはある
と入力補完されるのである。

今回は、vimとJSONでマッシュアップを行ったが、これはあくまで一例に過ぎない。これを応用すれば「某国会議員がカツラなのか」、「モー娘のあの娘はタバコを吸っているかどうか」が、テキストエディタから補完出来るのである。

皆さんも、色んなマッシュアップを試して見てほしいと切に感じている。

以下、今回作成したソース「miwa.vim」を公開しておく。

ダウンロード:
注意:vimの入力補完は、全構文を途切れなく入力する必要がある。
Posted at by