Syntastic から vim-vimlint が呼び出されるようになったみたい

3.4.0 2014-03-17 7.0

  • Added vimlint checker for VimL (@lcd047)
Syntastic - Automatic syntax checking : vim online

でもでも, watchdogs は非同期で動くからいいけど, 同期でしか動けない(ですよね?) syntastic において, vim-vimlint の遅さは悪だと思う.

undocumented な機能つかっているじゃんかーーーとかおもってたら, help に書いてあった. びっくりした.

+function! SyntaxCheckers_vim_vimlint_GetLocList() dict
+    " EVL102: unused variable v
+    " EVL103: unused argument v
+    " EVL105: global variable v is defined without g:
+    " EVL201: unreachable code
+    " EVL204: constant in conditional context
+    " EVL205: missing scriptencoding
+    " value 3: the message is a warning
+    "
+    " References: :help vimlint-errorcode and :help vimlint-variables
+    return vimlint#vimlint(expand('%'), {
+        \ 'output': function('s:vimlintOutput'),
+        \ 'quiet':  1,
+        \ 'EVL102': 3,
+        \ 'EVL103': 3,
+        \ 'EVL105': 3,
+        \ 'EVL201': 3,
+        \ 'EVL204': 3,
+        \ 'EVL205': 3 })
+endfunction
New checker: vimlint. · vim-syntastic/syntastic@87e237a · GitHub
追記

@ynkdir さんによる宣伝の効果らしい

Here is a syntax checker for VimL. https://github.com/syngan/vim-vimlint/

answered Dec 11 '13 at 15:29 ynkdir

vim - syntax-check a VimL script - Stack Overflow

ありがたいですが, vim 本体がチェック機能を提供して, vim-vimlint なんて使わないのが一番良いですよね.

VimL is a pain in the rear of a language, and it's good to have a high quality checker for it.

Checker for vim scripts · Issue #725 · vim-syntastic/syntastic · GitHub

vim-vimlint で Travis-CI 連携

この記事は Vim Advent Calendar 2013 111日目の記事になります.
vim plugin を github で公開している皆様こんにちわ. vim-vimlint で Travis-CI 連携やってみませんか. github でたまに見る, https://api.travis-ci.org/syngan/vim-operator-keeppos.png こういうやつです.

公開中の github 上の plugin に push するだけで, vim-vimlint がうごいて, エラーがないかチェックしてくれます, 便利.
vim-vimlint の遅さなんて気にしなくて良くなりますね, 素敵.

Travis-CI 連携のための手順

step1: travis-ci の設定

最初に Travis CI - Test and Deploy Your Code with Confidencegithub と連携する設定をします.

http://f.st-hatena.com/images/fotolife/s/syngan/20140321/20140321224738.png

step2: .travis.yml ファイルを作る

以下のようなファイルを作ります.

before_script:
    - git clone https://github.com/syngan/vim-vimlint /tmp/vim-vimlint
    - git clone https://github.com/ynkdir/vim-vimlparser /tmp/vim-vimlparser

script:
  - sh /tmp/vim-vimlint/bin/vimlint.sh -l /tmp/vim-vimlint -p /tmp/vim-vimlparser autoload plugin

最後の行の "autoload plugin" の部分は必要に応じて修正してください.

step3: push する.

おしまい. これだけです. 簡単, 便利, かっこいい.
README.md に, Travis-CI の結果の画像を乗せるとよりかっこ良いです.

きっと聞かれるであろう Q/A

vim-vimlint が誤検知します.

はい. lint と名前を付けたので, エラーっぽいのはエラーに倒しているので仕方がありません. ごめんなさい. 一応, コメントにいれてエラーを無効にする方法があります.
誤ったエラーの出る箇所に以下のようなコメントを追加してください.

" @vimlint(EVL103, 1, a:_)
  • 1 番目の引数がエラー番号
  • 2 番目の引数が 1 の場合に無効に, 0 の場合に有効になります.
  • 3 番目の引数に変数名を設定します. 変数名には l:, g:, a:などが必要です.

上記の例だと, a:_ は使わない引数だけどエラーになってしまうのを無効にしています.
できれば, それ以降のエラーにならないといけない箇所のエラーの検出が出来なくなってしまうので, 有効にするためのコメントを追加してほしいのですが, 悲しいかな, 実装をさぼっているので有効にするためのコメントを書く場所には注意が必要です. こんな感じで, 関数に関するエラーの判定は endfunction 時にやるので, endfunction より下に書く必要があります. 変な仕様ですね.

" @vimlint(EVL103, 1, a:node)
function s:VimlLint.compile_delfunction(node, refchk) " {{{
  .....
endfunction " }}}
" @vimlint(EVL103, 0, a:node)
vim-vimlparser でエラーになります.

ごめんなさい. 諦めてください. もしくは vim-vimlparser に pull req 送ってください.
テスト系で独自のコマンドを定義しているような場合は良くお亡くなりになるようです. vimlparser の仕様なので仕方がないのです...

/tmp/vim-vimlint/bin/vimlint.sh の引数に与えるファイルを調整していただけると嬉しです.

おわりに

vim-vimlint の効果は微々たるものですが, エラールートなどはテストされていない人がおおいですよね. やっても少ししか損はしないと思います.

あと, これは対応してくれよい、な問題があれば issues に具体例を添えて連絡ください.

関数名に g: は使ってはいけない(確信)

thinca
https://groups.google.com/d/topic/vim_dev/iZMnLrMXEZM/discussion
関数名に g: は使ってはいけない(確信)

vim-jp – Lingr

That's a bug. A function name should not be allowed to contain a colon.
The intention, as mentioned in the quoted docs, is only alphanumeric
characters and '_', while prepending s: is allowed to make the function
script-local. Something like abc:def() was never intended to work.

Google グループ

対応しました. g: な関数はエラー(EVL107)になります

vim-operator-furround の挙動を少し変えた.

vim-operator-furround は, "hoge(" のようなものを yank している状態で, 選択したテキストオブジェクトに対して, "hoge({textobj})" のように hoge() で囲うオペレーターです. hoge() で囲いたい症候群にかかっているときにはドットの公式が使えて仕事が捗ります.

これの挙動を少し修正しました.

開き括弧が複数ある場合

以前は「ヤンクされた最後の文字」のみをみていたのですが途中の開き括弧も見るようにしました.

以下の表は, tako という単語に対して `(opeartor-furround-append)iw` したときの動作です.

ヤンクしている内容 実行結果 備考
hoge hoge(tako) デフォルト動作
hoge[ hoge[tako]
hoge hoge
hoge" hoge"tako"
hoge' hoge"tako'
hoge[" hoge["tako"]
hoge([" hoge(["tako"])
hoge()[" hoge()["tako"]
hoge(3, hoge(3, tako)
hoge(3, " hoge(3, "tako")

operator_furround_use_input

ヤンクレジスタの内容をみずに, input 待ちにするオプションを追加しました.
デフォルトは 0 で無効になっています.

vim-operator-furround で LaTeX/XML 編集

LaTeX みたいなのだと, \begin{hoge} と \end{hoge} で囲みたいのでこういうのを変換できると便利なことはありそうな感じですが, これこそピンポイントすぎる気がしたので対応していません. 自分が使わないし.

hoge() で囲みたい症候群 - vim 初心者の作業メモ

syngan
html系は考えましたが、自分が使わないのでいらないになりました。
(この記事書いてる時に、textobj の色つけるところで使いたかったですが。。)

vim-jp – Lingr

LaTeX などを vim で編集するときはだいたい \begin{xxx} こぴってきて, 2 回ペーストして, begin->end して... としていて, 意外と使えそうな....
ということで, 数日前に自分でいらないといっていた機能ですが, ほしくなったので実装してみました. ヤンクしている文字列の最後が, 括弧始まり(({[<|'"`)でない場合に機能します.

前回と同様に

    map H <Plug>(opeartor-furround-append)

などとしておいて,

  : カーソル位置

i am a pen.

という状態であるとします.

LaTeX モード

デフォルトで有効です. b:operator_furround_latex または, g:operator_furround_latex を 0 に設定することで, 無効にできます.

例えば, "\begin{center}" をヤンクしている状態で, Hiw すれば

i am a \begin{center}pen\end{center}.

例えば,

\begin{table}[htb]
\begin{center}
\begin{tabular}{c|l}

を yank している状態で, VH すれば

\begin{table}[htb]
\begin{center}
\begin{tabular}{c|l}
i am a pen.
\end{tabular}
\end{center}
\end{table}

となります. (改行有無は motion=line かどうかで判断)

XML モード

デフォルトは無効です. b:operator_furround_xml または, g:operator_furround_xml を 1 に設定することで, 有効にできます.

例えば, "<p>" をヤンクしている状態で, Hiw すれば

i am a <p>pen</p>.

例えば, "<p><q key=value><r>" をヤンクしている状態で Hiw すれば

i am a <p><q key=value><r>pen</r></q></p>.

となります.便利. こっちは改行しません.

hoge() で囲みたい症候群

この記事は Vim Advent Calendar 2013 91日目の記事になります。


みなさんは, 変数を hoge() で囲みたくなることはありませんか.
私の場合は必要になる hoge の種類が少ないので, vimrc に surround の設定を追加して対応していました.

b:surround_{char2nr("a")} = "hoge(\r)"

これだとドットの公式も使えるし, サクサク hoge() で囲えるわけです.

でも, 不満が2点あって,

  • 囲みたい対象が配列や関数な形式のときはどうすんべ
  • たまに hage でも囲みたいときがあるけど, vimrc に追加するのは面倒

そこで毎度の lingr で聞いてみました. (以下抜粋+勝手加工)

syngan
v[123] みたいなのを hoge(v[123]) と hoge() で囲うをたくさんやりたいのですが
この操作にドットの公式で実現するにはどうするのが正解ですか?

thinca
q
そのくらい複雑になるとマクロくらいしかないかと

syngan
そうですかぁ。。悲しい。。
マッピングされていない問題
ぬぅ。。録音が面倒で。。。

manga_osyo
ふと、hoge() を yank している場合、hoge({textobj}) みたいに貼り付ける operator があれば便利そうな気がしたけどピンポイントだなぁ

syngan
現時点で operator-surround は surround.vim でいうところの, b:surround_{char2nr("a")} = "hoge(\r)" みたいなのって実現できるんですか?

manga_osyo
let g:operator#surround#blocks = {
\ "-" : [
\ { 'block' : ['hoge(', ')'], 'motionwise' : ['char', 'line', 'block'], 'keys' : ['(', ')'] },
\ ]
\ }
で
( を append しようとすると hoge(foo) になる
http://lingr.com/room/vim/archives/2014/02/26#message-18446167

んで, マクロは面倒なので, これを解決するために, 2 つプラグインを作りました.

vim-operator-furround

上でおしょーさんが言っているのとは少し違いますが, hoge( を yank しているときに hoge() で囲うプラグインです. hoge[ とか hoge<, hoge{ など, yank している文字列の最後の文字をみて囲う方法が変わります.

LaTeX を書いているときに使ったのは, \verb|| で囲うバージョン.
何か所か, 囲うのが漏れていたので修正に便利でした.
LaTeX みたいなのだと, \begin{hoge} と \end{hoge} で囲みたいのでこういうのを変換できると便利なことはありそうな感じですが, これこそピンポイントすぎる気がしたので対応していません. 自分が使わないし.

簡単な使い方

繰り返しになりますが,

    map H <Plug>(opeartor-furround-append)

などとしておいて,

  : カーソル位置

I am a pen.

こういう状態のときに,
'hoge' または 'hoge(' が yank されている状態で, Hiw とすると

I am a hoge(pen).

'hoge[' が yank されている状態で, Hiw とすると

I am a hoge[pen].

レジスタ a に 'hoge<' が格納されている状態で "aHiw とすると

I am a hoge.

となります.

vim-textobj-postexpr

名前があれなんですが, v[123] とか f() みたいなのを対象とします.

以下のプラグインが近い動きをしてくれるのですがほしいものと違ったので作りました.

こんな感じで, name に対して [] とか () で続くもの, というイメージでしょうか.
postexpr-a は改行の先も見に行くようになっています.

  : カーソル位置
  : 範囲


printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " postexpr-i
printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " parameter-i

printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " postexpr-i
printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " parameter-i

printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " postexpr-i
printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " parameter-i

printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " postexpr-i
printf("hoge\n", (sqrt(value[1,2][3]) + 1) + func[1,2](a, b, c));  " parameter-i


func(value[1]
() + 2);  " postexpr-i
func(value[1]
() + 2);  " postexpr-a


func(value[1]
() + 2);  " postexpr-i
func(value[1]
() + 2);  " postexpr-a

まとめ

これでめでたくドットの公式を使って hoge() で囲えるようになりました。

vimプラグインが同等機能を実現するコマンドと関数を提供する理由

lingr にて. id:thinca さんいつもありがとうございます.

syngan
プラグインが、関数と同等のコマンドを持っているとユーザにとって何が嬉しいのですか?
quickrun ってば, Quickrun というコマンドと quickrun#run が提供されていますよね
なぜ両方提供するんでしょう?

thinca
コマンドは文字列しか渡せないので、直接的なデータを渡すのに向いてない
わざわざコマンドラインの引数用に文字列を組み立てる必要がある
関数だとこういうことがない。ただし、普段使うには関数よりコマンドの方が補完などが使えるので便利
scripting → 関数
interarctive → コマンド
まあ vimrc などでマクロ的にコマンドを利用することもあるけど
http://lingr.com/room/vim/archives/2014/02/25#message-18438008