VimConf 2016 に行ってきた

VimConf 2016に行ってきた。

発表メモ

Introduction to Vim 8.0 by Ken Takata
  • 最近Vimに入った機能の中でjob, timer, packagesは使ったけど *1 *2 Partial, lambda, closureはまだ触っていないので試してみたい
  • 日本人VimmerVim本体に多くのパッチを送っているのは知っていたけど改めて数字で見てみると予想以上にすごかった
  • Vimのテストが充実してきたおかげで新機能の使用例としても参考にできてありがたい
Vim as the MAIN text editor by bird_nitryn
  • 自分もVimに乗り換えた時は同じようにメインエディタにして使いまくった
  • 最近はVimmerを育てる機会の方が多いので参考にしたい
Denite.nvim ~The next generation of unite~ by Shougo
  • unite.vimを使っていてパフォーマンス的な不満は特になかったけどデモに触発されてMacVimでDenite.nvimを試してみたらすごく速かった
  • Decoupled UIはちょっと気になるのでそのうち試してみたい
Go、C、Pythonのためのdeoplete.nvimのソースの紹介と、Neovim専用にpure Goでvim-goをスクラッチした話 by zchee
  • neovimに全然興味なかったけど発表を聞いてとりあえずインストールしてみることにした
  • nvim-goの作りが気になるのでソースを見てみる
エディタの壁を越えるGoの開発ツールの文化と作成法 by tenntenn
  • 自分の近くでは「Goやったことある方」でほとんどの人が手を挙げていた
  • gofmt(ごーふむと)、GOOS(ぐーす)、GOARCH(ごーち)
  • ファイルを生成するツール *3 は作ったから次はファイルを書き換えるツールと思っていたのでgorenameのところがとても参考になった
vim-mode-plus for Atom editor by t9md
  • vim-mode-plusのアーキテクチャとそこに到るまでの考え方がただただすごかった
    • Vimでテキストを編集するということへの捉え方
    • モーションやオペレータの表現
  • persistence-selectionはVimにも欲しい
Vimの日本語ドキュメント by MURAOKA Taro
  • 「翻訳作業に手と目と知恵を貸してくれる人募集中」
    • リファレンス&ユーザー・マニュアル
    • メッセージ
    • メニュー
    • など
  • 脱線しかけたのはAho-Corasick法(文字列探索アルゴリズム)
  • 技術者はSPOFは排除したいはず
Vim script parser written in Go by haya14busa
  • Fixer、Formatterに期待!
  • stacktrace便利そう
  • Vim8とV8(node)は紛らわしい?
僕の友達を紹介するよ by aiya000
Best practices for building Vim plugins by thinca
  • :help design-goalsは知らなかった
  • シャイで有名なthincaさんがハイテンションで発表に懸ける強い想いが感じられた

感想

  • Vimハラスメント」に気をつけようと思った
    • (自分としてはネタのつもりだけど)職場でよく「Vimを使おう」と言っているので...
      • 開発関連のやるべき事をやってくれていれば何も言わないけどできていない
      • Vimだったらそのためにどうすれば良いかはいくらでもサポートできる
      • というのが言い訳
  • 今回はチームのメンバ(2名)に参加してもらう事に成功した
    • 楽しんでもらえたようで良かった

終わりに

発表者のみなさま、スタッフのみなさま、会場を提供してくださったミクシィさん、
ありがとうございました。
来年も是非参加したいです。

gRPCサーバのベンチマーククライアントを生成する

google.golang.org/grpcでサーバ書いたのでそろそろベンチマークしてみようと思ったらgoogle.golang.org/grpc/benchmarkという便利そうなパッケージを発見した。

早速clientをビルドしてみたけどgrpc_testingパッケージ専用だったので中のmain.goをテンプレート化して任意のパッケージで使えるようにするツールを作ってみた。
※今のところstreaming RPCには非対応

github.com

exampleshelloworldで試してみるとこんな感じ。

# ベンチマーククライアントを生成する
$ grpc-bench-generator -path $GOPATH/src/google.golang.org/grpc/examples/helloworld/helloworld > main.go

# greeter_serverが起動している状態で実行する
$ go run main.go -server=localhost:50051 -duration=1 -enable_ssl=false -data='{"Name": "grpc-bench-generator"}'
2016/09/23 15:20:57 Client profiling address:  [::]:62291
2016/09/23 15:20:58 Histogram (unit: µs)
Count: 5961  Min: 126  Max: 737  Avg: 164.21
------------------------------------------------------------
[126.000000, 127.000000)     1    0.0%    0.0%  
[127.000000, 127.025476)     0    0.0%    0.0%  
[127.025476, 127.051602)     0    0.0%    0.0%  
[127.051602, 127.078393)     0    0.0%    0.0%  
[127.078393, 127.105866)     0    0.0%    0.0%  
[127.105866, 127.134040)     0    0.0%    0.0%  
[127.134040, 127.162931)     0    0.0%    0.0%  
[127.162931, 127.192558)     0    0.0%    0.0%  
[127.192558, 127.222940)     0    0.0%    0.0%  
[127.222940, 127.254096)     0    0.0%    0.0%  
[127.254096, 127.286046)     0    0.0%    0.0%  
[127.286046, 127.318810)     0    0.0%    0.0%  
[127.318810, 127.352408)     0    0.0%    0.0%  
[127.352408, 127.386863)     0    0.0%    0.0%  
[127.386863, 127.422195)     0    0.0%    0.0%  
[127.422195, 127.458427)     0    0.0%    0.0%  
[127.458427, 127.495583)     0    0.0%    0.0%  
[127.495583, 127.533685)     0    0.0%    0.0%  
[127.533685, 127.572757)     0    0.0%    0.0%  
[127.572757, 127.612826)     0    0.0%    0.0%  
[127.612826, 127.653914)     0    0.0%    0.0%  
[127.653914, 127.696050)     0    0.0%    0.0%  
[127.696050, 127.739259)     0    0.0%    0.0%  
[127.739259, 127.783569)     0    0.0%    0.0%  
[127.783569, 127.829008)     0    0.0%    0.0%  
[127.829008, 127.875605)     0    0.0%    0.0%  
[127.875605, 127.923388)     0    0.0%    0.0%  
[127.923388, 127.972389)     0    0.0%    0.0%  
[127.972389, 128.022638)     1    0.0%    0.0%  
[128.022638, 128.074168)     0    0.0%    0.0%  
[128.074168, 128.127010)     0    0.0%    0.0%  
[128.127010, 128.181199)     0    0.0%    0.0%  
[128.181199, 128.236768)     0    0.0%    0.0%  
[128.236768, 128.293752)     0    0.0%    0.0%  
[128.293752, 128.352189)     0    0.0%    0.0%  
[128.352189, 128.412114)     0    0.0%    0.0%  
[128.412114, 128.473566)     0    0.0%    0.0%  
[128.473566, 128.536583)     0    0.0%    0.0%  
[128.536583, 128.601206)     0    0.0%    0.0%  
[128.601206, 128.667475)     0    0.0%    0.0%  
[128.667475, 128.735433)     0    0.0%    0.0%  
[128.735433, 128.805122)     0    0.0%    0.0%  
[128.805122, 128.876586)     0    0.0%    0.0%  
[128.876586, 128.949871)     0    0.0%    0.0%  
[128.949871, 129.025023)     6    0.1%    0.1%  
[129.025023, 129.102090)     0    0.0%    0.1%  
[129.102090, 129.181119)     0    0.0%    0.1%  
[129.181119, 129.262163)     0    0.0%    0.1%  
[129.262163, 129.345271)     0    0.0%    0.1%  
[129.345271, 129.430496)     0    0.0%    0.1%  
[129.430496, 129.517893)     0    0.0%    0.1%  
[129.517893, 129.607516)     0    0.0%    0.1%  
[129.607516, 129.699422)     0    0.0%    0.1%  
[129.699422, 129.793670)     0    0.0%    0.1%  
[129.793670, 129.890319)     0    0.0%    0.1%  
[129.890319, 129.989430)     0    0.0%    0.1%  
[129.989430, 130.091066)    17    0.3%    0.4%  
[130.091066, 130.195292)     0    0.0%    0.4%  
[130.195292, 130.302172)     0    0.0%    0.4%  
[130.302172, 130.411776)     0    0.0%    0.4%  
[130.411776, 130.524172)     0    0.0%    0.4%  
[130.524172, 130.639431)     0    0.0%    0.4%  
[130.639431, 130.757627)     0    0.0%    0.4%  
[130.757627, 130.878834)     0    0.0%    0.4%  
[130.878834, 131.003129)    33    0.6%    1.0%  
[131.003129, 131.130591)     0    0.0%    1.0%  
[131.130591, 131.261299)     0    0.0%    1.0%  
[131.261299, 131.395338)     0    0.0%    1.0%  
[131.395338, 131.532792)     0    0.0%    1.0%  
[131.532792, 131.673747)     0    0.0%    1.0%  
[131.673747, 131.818294)     0    0.0%    1.0%  
[131.818294, 131.966522)     0    0.0%    1.0%  
[131.966522, 132.118528)    42    0.7%    1.7%  
[132.118528, 132.274405)     0    0.0%    1.7%  
[132.274405, 132.434254)     0    0.0%    1.7%  
[132.434254, 132.598176)     0    0.0%    1.7%  
[132.598176, 132.766273)     0    0.0%    1.7%  
[132.766273, 132.938653)     0    0.0%    1.7%  
[132.938653, 133.115425)    45    0.8%    2.4%  
[133.115425, 133.296700)     0    0.0%    2.4%  
[133.296700, 133.482593)     0    0.0%    2.4%  
[133.482593, 133.673223)     0    0.0%    2.4%  
[133.673223, 133.868708)     0    0.0%    2.4%  
[133.868708, 134.069174)    61    1.0%    3.5%  
[134.069174, 134.274748)     0    0.0%    3.5%  
[134.274748, 134.485558)     0    0.0%    3.5%  
[134.485558, 134.701739)     0    0.0%    3.5%  
[134.701739, 134.923428)     0    0.0%    3.5%  
[134.923428, 135.150764)    72    1.2%    4.7%  
[135.150764, 135.383892)     0    0.0%    4.7%  
[135.383892, 135.622960)     0    0.0%    4.7%  
[135.622960, 135.868118)     0    0.0%    4.7%  
[135.868118, 136.119521)   113    1.9%    6.6%  
[136.119521, 136.377330)     0    0.0%    6.6%  
[136.377330, 136.641706)     0    0.0%    6.6%  
[136.641706, 136.912818)     0    0.0%    6.6%  
[136.912818, 137.190837)   127    2.1%    8.7%  
[137.190837, 137.475939)     0    0.0%    8.7%  
[137.475939, 137.768304)     0    0.0%    8.7%  
[137.768304, 138.068117)   165    2.8%   11.5%  
[138.068117, 138.375569)     0    0.0%   11.5%  
[138.375569, 138.690854)     0    0.0%   11.5%  
[138.690854, 139.014170)   179    3.0%   14.5%  
[139.014170, 139.345724)     0    0.0%   14.5%  
[139.345724, 139.685724)     0    0.0%   14.5%  
[139.685724, 140.034387)   193    3.2%   17.7%  
[140.034387, 140.391932)     0    0.0%   17.7%  
[140.391932, 140.758586)     0    0.0%   17.7%  
[140.758586, 141.134581)   198    3.3%   21.0%  
[141.134581, 141.520155)     0    0.0%   21.0%  
[141.520155, 141.915552)     0    0.0%   21.0%  
[141.915552, 142.321022)   193    3.2%   24.3%  
[142.321022, 142.736822)     0    0.0%   24.3%  
[142.736822, 143.163215)   181    3.0%   27.3%  
[143.163215, 143.600472)     0    0.0%   27.3%  
[143.600472, 144.048868)   190    3.2%   30.5%  
[144.048868, 144.508687)     0    0.0%   30.5%  
[144.508687, 144.980221)     0    0.0%   30.5%  
[144.980221, 145.463768)   169    2.8%   33.3%  
[145.463768, 145.959634)     0    0.0%   33.3%  
[145.959634, 146.468132)   169    2.8%   36.2%  
[146.468132, 146.989586)     0    0.0%   36.2%  
[146.989586, 147.524324)   148    2.5%   38.6%  
[147.524324, 148.072685)   150    2.5%   41.2%  
[148.072685, 148.635017)     0    0.0%   41.2%  
[148.635017, 149.211675)   161    2.7%   43.9%  
[149.211675, 149.803024)     0    0.0%   43.9%  
[149.803024, 150.409438)   141    2.4%   46.2%  
[150.409438, 151.031301)   135    2.3%   48.5%  
[151.031301, 151.669008)     0    0.0%   48.5%  
[151.669008, 152.322961)   122    2.0%   50.5%  
[152.322961, 152.993574)     0    0.0%   50.5%  
[152.993574, 153.681272)   127    2.1%   52.7%  
[153.681272, 154.386490)   120    2.0%   54.7%  
[154.386490, 155.109674)   120    2.0%   56.7%  
[155.109674, 155.851282)     0    0.0%   56.7%  
[155.851282, 156.611784)    95    1.6%   58.3%  
[156.611784, 157.391661)    87    1.5%   59.7%  
[157.391661, 158.191406)    93    1.6%   61.3%  
[158.191406, 159.011526)    66    1.1%   62.4%  
[159.011526, 159.852539)     0    0.0%   62.4%  
[159.852539, 160.714979)    69    1.2%   63.6%  
[160.714979, 161.599390)    71    1.2%   64.8%  
[161.599390, 162.506333)    63    1.1%   65.8%  
[162.506333, 163.436381)    48    0.8%   66.6%  
[163.436381, 164.390124)    68    1.1%   67.8%  
[164.390124, 165.368164)    66    1.1%   68.9%  
[165.368164, 166.371122)    47    0.8%   69.7%  
[166.371122, 167.399631)    45    0.8%   70.4%  
[167.399631, 168.454342)    47    0.8%   71.2%  
[168.454342, 169.535924)    53    0.9%   72.1%  
[169.535924, 170.645061)    45    0.8%   72.8%  
[170.645061, 171.782455)    44    0.7%   73.6%  
[171.782455, 172.948825)    36    0.6%   74.2%  
[172.948825, 174.144910)    81    1.4%   75.5%  
[174.144910, 175.371467)    29    0.5%   76.0%  
[175.371467, 176.629272)    38    0.6%   76.7%  
[176.629272, 177.919121)    27    0.5%   77.1%  
[177.919121, 179.241831)    46    0.8%   77.9%  
[179.241831, 180.598239)    27    0.5%   78.3%  
[180.598239, 181.989203)    26    0.4%   78.8%  
[181.989203, 183.415604)    64    1.1%   79.9%  
[183.415604, 184.878345)    36    0.6%   80.5%  
[184.878345, 186.378351)    49    0.8%   81.3%  
[186.378351, 187.916571)    28    0.5%   81.7%  
[187.916571, 189.493980)    47    0.8%   82.5%  
[189.493980, 191.111575)    45    0.8%   83.3%  
[191.111575, 192.770381)    20    0.3%   83.6%  
[192.770381, 194.471447)    56    0.9%   84.6%  
[194.471447, 196.215850)    45    0.8%   85.3%  
[196.215850, 198.004694)    35    0.6%   85.9%  
[198.004694, 199.839111)    17    0.3%   86.2%  
[199.839111, 201.720262)    38    0.6%   86.8%  
[201.720262, 203.649339)    33    0.6%   87.4%  
[203.649339, 205.627561)    27    0.5%   87.8%  
[205.627561, 207.656181)    30    0.5%   88.3%  
[207.656181, 209.736483)    28    0.5%   88.8%  
[209.736483, 211.869784)    30    0.5%   89.3%  
[211.869784, 214.057433)    56    0.9%   90.3%  
[214.057433, 216.300816)    28    0.5%   90.7%  
[216.300816, 218.601351)    44    0.7%   91.5%  
[218.601351, 220.960497)    21    0.4%   91.8%  
[220.960497, 223.379744)    60    1.0%   92.8%  
[223.379744, 225.860625)    31    0.5%   93.3%  
[225.860625, 228.404710)    44    0.7%   94.1%  
[228.404710, 231.013609)    51    0.9%   94.9%  
[231.013609, 233.688973)    25    0.4%   95.4%  
[233.688973, 236.432496)    46    0.8%   96.1%  
[236.432496, 239.245913)    50    0.8%   97.0%  
[239.245913, 242.131007)    34    0.6%   97.5%  
[242.131007, 245.089602)    28    0.5%   98.0%  
[245.089602, 248.123571)    19    0.3%   98.3%  
[248.123571, 251.234835)    15    0.3%   98.6%  
[251.234835, 254.425362)    18    0.3%   98.9%  
[254.425362, 257.697172)    10    0.2%   99.0%  
[257.697172, 261.052336)    12    0.2%   99.2%  
[261.052336, 264.492978)     3    0.1%   99.3%  
[264.492978, 268.021274)     4    0.1%   99.4%  
[268.021274, 271.639459)     4    0.1%   99.4%  
[271.639459, 275.349822)     2    0.0%   99.5%  
[275.349822, 279.154711)     1    0.0%   99.5%  
[279.154711, 283.056535)     2    0.0%   99.5%  
[283.056535, 287.057764)     2    0.0%   99.5%  
[287.057764, 291.160929)     3    0.1%   99.6%  
[291.160929, 295.368628)     0    0.0%   99.6%  
[295.368628, 299.683523)     1    0.0%   99.6%  
[299.683523, 304.108346)     2    0.0%   99.6%  
[304.108346, 308.645898)     0    0.0%   99.6%  
[308.645898, 313.299050)     1    0.0%   99.7%  
[313.299050, 318.070748)     0    0.0%   99.7%  
[318.070748, 322.964011)     0    0.0%   99.7%  
[322.964011, 327.981936)     0    0.0%   99.7%  
[327.981936, 333.127700)     1    0.0%   99.7%  
[333.127700, 338.404559)     0    0.0%   99.7%  
[338.404559, 343.815854)     0    0.0%   99.7%  
[343.815854, 349.365008)     0    0.0%   99.7%  
[349.365008, 355.055535)     1    0.0%   99.7%  
[355.055535, 360.891035)     1    0.0%   99.7%  
[360.891035, 366.875203)     1    0.0%   99.7%  
[366.875203, 373.011825)     2    0.0%   99.8%  
[373.011825, 379.304787)     0    0.0%   99.8%  
[379.304787, 385.758070)     1    0.0%   99.8%  
[385.758070, 392.375759)     1    0.0%   99.8%  
[392.375759, 399.162043)     2    0.0%   99.8%  
[399.162043, 406.121217)     1    0.0%   99.8%  
[406.121217, 413.257685)     1    0.0%   99.9%  
[413.257685, 420.575964)     0    0.0%   99.9%  
[420.575964, 428.080687)     0    0.0%   99.9%  
[428.080687, 435.776602)     1    0.0%   99.9%  
[435.776602, 443.668581)     0    0.0%   99.9%  
[443.668581, 451.761619)     0    0.0%   99.9%  
[451.761619, 460.060839)     1    0.0%   99.9%  
[460.060839, 468.571492)     0    0.0%   99.9%  
[468.571492, 477.298965)     1    0.0%   99.9%  
[477.298965, 486.248783)     0    0.0%   99.9%  
[486.248783, 495.426610)     0    0.0%   99.9%  
[495.426610, 504.838254)     1    0.0%   99.9%  
[504.838254, 514.489672)     2    0.0%  100.0%  
[514.489672, 524.386974)     0    0.0%  100.0%  
[524.386974, 534.536422)     0    0.0%  100.0%  
[534.536422, 544.944442)     0    0.0%  100.0%  
[544.944442, 555.617620)     0    0.0%  100.0%  
[555.617620, 566.562712)     0    0.0%  100.0%  
[566.562712, 577.786645)     1    0.0%  100.0%  
[577.786645, 589.296522)     0    0.0%  100.0%  
[589.296522, 601.099630)     0    0.0%  100.0%  
[601.099630, 613.203438)     0    0.0%  100.0%  
[613.203438, 625.615606)     0    0.0%  100.0%  
[625.615606, 638.343992)     0    0.0%  100.0%  
[638.343992, 651.396650)     0    0.0%  100.0%  
[651.396650, 664.781843)     0    0.0%  100.0%  
[664.781843, 678.508041)     0    0.0%  100.0%  
[678.508041, 692.583933)     0    0.0%  100.0%  
[692.583933, 707.018428)     0    0.0%  100.0%  
[707.018428, 721.820660)     0    0.0%  100.0%  
[721.820660, 737.000000)     0    0.0%  100.0%  
[737.000000,        inf)     1    0.0%  100.0%  

2016/09/23 15:20:58 Status Codes
OK: 5961

neocompleteとneobundleを捨てた

半年ほど使っていなかったのでvimrcを整理するタイミングで完全に消すことにした。
ただ長年ツートップだったプラグインなので消すに至った経緯を軽くメモっておく。

neocomplete

今の自分にはVim標準の補完機能(ins-completion)で十分だった。

  • 自動補完が発動するとVimが固まって使い物にならなくなることがある
    • 特定の環境でたまにしか発生しないけど発生するとすごくストレス
  • 自動補完されないと補完自体ができないと思ってしまう
    • そんなことはなく、基本的には常に手動補完可能
    • そもそも自動補完の対象になっていない補完機能もある
  • if_luaが必須
    • どうせ有効化するけどプラグインのためだけにluaを入れたくはなかった

昔は自動補完が必須だと思っていたけどVimの熟練度が上がったからか、

「補完したくなったらその時にCTRL-X(or N,P)押せばいいじゃん」

と思うようになった。
CTRL-Xが押しにくいと感じていたのもいつの間にか全然気にならなくなっていた。

neobundle

Vim標準のパッケージ機能(packages)を使うことにした。

  • 開発終了宣言されたのでどうするか悩んでいたけどどれも決め手に欠けていた
    1. それでもneobundleを使い続ける
      • どうせいつかは移行しないといけなくなるはず
    2. 順当にdein.vimに移行する
      • 機能にあまり魅力を感じなかったし、安定性や将来性に不安があった
    3. ミニマリストを謳うvim-plugに移行する
      • Installationを見た瞬間にもうめんどくさくなった
  • Vimプラグインマネージャーに求める最低限の機能はただ1つ
  • あったら便利な機能は自分でなんとかするか諦める
    1. プラグインのインストールとアップデート
      • Bitbucketにあるプラグインは使わないのでgitさえ叩ければOK
      • 単純なシェルコマンドならVimに依存する必要もない
      • それでも後処理以外はVimからできるようにはしたけど
    2. 依存関係のあるプラグインを自動で解決してインストールする機能
    3. 遅延読み込み
      • 個別に設定するのが面倒なのでbackground loadingで代用している
      • その方が起動時間の短縮にもなるし

どうもプラグインを管理するプラグインに依存するのに疲れたっぽい。
決定版が出るまでは当分これでいくつもり。

次は脱unite!?

インターフェースは便利なんだけどやっぱり安定性はイマイチ...
(今までできていたことが急にできなくなったりすることがあるし)
いつ無くなっても困らないくらいには依存度を減らすようにしておくかな。

vimのjob機能を使ってプラグインを更新する

2ヶ月以上経ってるけど一応前回の続き。

~/.vim/pack/bundle/opt/配下にインストールされているプラグインを更新するには、

ls -d ~/.vim/pack/bundle/opt/* | xargs -I{} git -C {} pull --ff --ff-only

でやってしまうのが手っ取り早いんだけど、あえてvimでやってみた。

以下のようにjob機能を使うことでvimをブロックせず、結果をバッファに出力するといった処理が簡単に実現できた。

let s:plugins = [
            \     'vim-quickrun',
            \ ]

"プラグインを更新したくなったら :call UpdatePackPlugins() を実行する
function! UpdatePackPlugins()
    " 結果を表示するためのバッファを作成
    topleft split
    edit `='[update plugins]'`

    let s:idx = 0
    call timer_start(100, 'PluginUpdateHandler', {'repeat': len(s:plugins)})
endfunction

function! PluginUpdateHandler(timer)
    let path = expand('~/.vim/pack/bundle/opt/' . s:plugins[s:idx])
    let cmd = printf('git -C %s pull --ff --ff-only', path)
    " コマンドを実行し、結果をout_nameで指定したバッファに出力する
    call job_start(cmd, {'out_io': 'buffer', 'out_name': '[update plugins]'})

    let s:idx += 1
endfunction

UpdatePackPlugins()内でforを使うと全部更新できなかったのでtimer機能でPluginUpdateHandler()を呼び出すようにしている。

vim pluginのbackground loading

最近vimに追加されたpackagestimerを使ってvimが起動した後にプラグインの読み込みができたらどうだろう? と思ったのでやってみました。

以下のような設定をvimrcに追加してvimを起動するとvimが立ち上がってからプラグインが読み込まれます。

" vim起動後に~/.vim/pack/bundle/opt/vim-quickrunを読み込む例

let s:plugins = [
            \     'vim-quickrun',
            \ ]

let s:idx = 0
function! PackAddHandler(timer)
    execute 'packadd ' . s:plugins[s:idx]
    let s:idx += 1
endfunction

autocmd VimEnter * call timer_start(1, 'PackAddHandler', {'repeat': len(s:plugins)})

約150個のプラグインある状態のMacVim-KaoriYaで、起動時間が

  • NeoBundle: 約530ms
  • background loading: 約130ms

と、だいぶ高速化されました。

ただし、

  • packagesの仕様*1で読み込まれないプラグインがあったり、
    • 追記(2016-03-21)
      • textobj-userruntime! plugin/textobj/*.vim
      • operator-userruntime! plugin/operator/*.vim
      • PackAddHandlerで実行すると読み込める
    • 追記(2016-04-03)
      • 7.4.1699からはサブディレクトリの.vimも読み込まれるようになったのでruntime!は不要
  • 起動時に指定したファイルのfiletypeが(ファイルを開いた後に読み込まれるので)反映されなかったり、
    • 追記(2016-03-21)
      • PackAddHandlerdoautocmd BufReadPostを実行すると反映される
  • 引数の-cで指定したコマンドが(実行後に読み込まれるので)失敗したり、

するので有効に使うには色々と考えないといけなさそうです。


ところで、e-honAmazonオムニ7にある

「仕事ですぐ役立つ VimEmacsエキスパート活用術」

4月9日(土) に発売されます。

f:id:daisuzu:20160318234059p:plain

技術評論社さんのサイトにも来週にはページができるそうなのでできました。 gihyo.jp
興味のある人はチェックしてみてください。

goemonを使ってblockdiagを書いてみたら快適だった

そこそこちゃんとしたドキュメントを書くときは

を使うけど、
図だけライブプレビューしながら書くには大げさすぎるのでgoemonを使ってみた。

まずはこの記事を参考にmarkdownのライブリロード環境を構築。
ただcssは無くても良かったのでhtmlテンプレートに追加したのはlivereload.jsのみ。

pandoc -D html | sed '/<\/head>/i\  <script src="http://localhost:35730/livereload.js"></script>' > template.html

あとはgoemon.ymlにblockdiagを追加して

tasks:
- match: '*.md'
  commands:
  - pandoc -f markdown -t html --template=template.html -o ${GOEMON_TARGET_DIR}/${GOEMON_TARGET_NAME}.html ${GOEMON_TARGET_FILE}
  - :livereload /
- match: '*.diag'
  commands:
  - blockdiag -Tsvg -o ${GOEMON_TARGET_DIR}/${GOEMON_TARGET_NAME}.svg ${GOEMON_TARGET_FILE}
  - :livereload /

goemonを起動したら

goemon python -m SimpleHTTPServer

こんな感じのmarkdownを作って

![](blockdiag.svg)

blockdiag.diagを書いていくだけ。

Sphinxに比べるとファイルを保存してからブラウザに反映されるまでが速い!
とりあえずでやってみたものの、こんなに快適に書けるとは思ってなかった...

複数のblockdiagシリーズを同時に使うときのことはあんまり考えてなかったけど
ファイルの拡張子で実行するコマンドを分ければなんとかなりそう。

- match: '*.diag'
  commands:
  - blockdiag -Tsvg -o ${GOEMON_TARGET_DIR}/${GOEMON_TARGET_NAME}.svg ${GOEMON_TARGET_FILE}
  - :livereload /
- match: '*.seqdiag'
  commands:
  - seqdiag -Tsvg -o ${GOEMON_TARGET_DIR}/${GOEMON_TARGET_NAME}.svg ${GOEMON_TARGET_FILE}
  - :livereload /

これをやる前に

  • Shibaを改造してPRするか
  • 指定パスの.diagを全て監視してimg一覧画面を生成するツールを作るか

考えてもみたけど今のところそこまで汎用的なのは必要ないかなぁという感じ。
初期設定が楽になってもパフォーマンスは落ちそうだし...


と、ここまで書いてdiagram-autobuildがあるということを知った。

blog.amedama.jp

1ファイルしか指定できないけど書きたい図が1つだけの時はこれで良さそう。
手元の環境だとgoemonに比べてワンテンポくらい遅かったけど...

VimのCTRL-X補完について

この記事はVim Advent Calendar 2015の5日目の記事です。

Vimで補完といえばShougoさんのプラグインneocompleteが有名ですが、プラグインを使わなくてもCTRL-X サブモードで補完を行うことが可能です。
この機能はブログや書籍などでたびたび紹介されてはいますが、文字だけではイメージがつきにくいところもあるのでGIFアニメで紹介してみたいと思います。


行(全体)補完: CTRL-X CTRL-L

if から始まる行と l から始まる行を補完(go)

f:id:daisuzu:20151205000331g:plain

検索対象はcompleteオプションで設定可能


局所キーワード補完: CTRL-X CTRL-N / CTRL-X CTRL-P

現在のファイルから T で始まるキーワードを補完(perl)

f:id:daisuzu:20151205000332g:plain


辞書補完: CTRL-X CTRL-K

dictionaryオプションで設定したファイルから twist で始まる単語を補完

f:id:daisuzu:20151205000322g:plain

dictionaryオプションに使用するファイルを設定する必要がある(デフォルトは未設定)

set dictionary=/usr/share/dict/words

シソーラス補完: CTRL-X CTRL-T

thesaurusオプションで設定したファイルから twister の類語を補完

f:id:daisuzu:20151205000329g:plain

thesaurusオプションに使用するファイルを設定する必要がある(デフォルトは未設定)

set thesaurus=/usr/share/mythes/th_en_US_v2.dat

パスパターン補完: CTRL-X CTRL-I

インクルードしているSocket.pmから getpr で始まるキーワードを補完(perl)

f:id:daisuzu:20151205000325g:plain

検索対象はincludeオプションとpathオプションで設定可能


タグ補完: CTRL-X CTRL-]

tagsファイルからクラス名とメソッド名を補完(ruby)

f:id:daisuzu:20151205000328g:plain

読み込むtagsファイルはtagsオプションで設定可能


ファイル名補完: CTRL-X CTRL-F

/etc/y から始まるファイル名を補完

f:id:daisuzu:20151205000323g:plain


定義補完: CTRL-X CTRL-D

mixinを補完(sass)

f:id:daisuzu:20151205000321g:plain

検索対象はdefineオプションとincludeオプションとpathオプションで設定可能


コマンドライン補完: CTRL-X CTRL-V

vimのコマンドと関数を補完

f:id:daisuzu:20151205000330g:plain


ユーザー定義補完: CTRL-X CTRL-U

completefuncオプションに設定したCompleteMonthsで月の名前を補完

f:id:daisuzu:20151205000324g:plain

fun! CompleteMonths(findstart, base)
  if a:findstart
    " 単語の始点を検索する
    let line = getline('.')
    let start = col('.') - 1
    while start > 0 && line[start - 1] =~ '\a'
      let start -= 1
    endwhile
    return start
  else
    " "a:base" にマッチする月を探す
    let res = []
    for m in split("Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec")
      if m =~ '^' . a:base
        call add(res, m)
      endif
    endfor
    return res
  endif
endfun

オムニ補完: CTRL-X CTRL-O

omnifuncオプションに設定されたjavascriptcomplete#CompleteJSでDate型のメソッドを補完(javascript)

f:id:daisuzu:20151205000326g:plain


スペリング補完: CTRL-X s / CTRL-X CTRL-S

頭文字が大文字になっていない単語と綴りが間違っている単語の修正候補を補完

f:id:daisuzu:20151205000327g:plain

spellオプションをオンにする必要がある


上記環境はDocker上のcentos6に以下のパッケージをインストールしたものです。
プラグインは一切インストールしておらず、vimrcも作成していません。

yum install vim-enhanced ctags words mythes-en

CTRL-X サブモード について

順序が逆転してしまいましたが、CTRL-X サブモード挿入モードまたは置換モード中にCTRL-Xキーで入ることができます。

ポップアップメニューの補完候補はCTRL-N(次の候補)またはCTRL-P(前の候補)キーで選択し、CTRL-Yキーやスペース、エンターなどで挿入することができます。
また、CTRL-Eキーで補完を中止して元のテキストに戻すことができます。


最近neocompleteが入っていないVimを触ることがちょこちょことあり、ここ1週間くらいはメインのVimでもneocompleteを使わずに過ごしてみました。
昔は自動補完プラグインが無いとコーディングなんてできない...とか思っていましたがそこまで困らないくらいには成長していたようです。
ただ、CTRL-Xキーがイマイチ押しにくいと感じているのでこれさえなんとかなれば自動補完プラグインは使わなくなるかもしれません。
今はこんなマッピングを試してみています。

inoremap <expr><Tab> pumvisible() ? "\<C-n>" : MyInsCompl()
function! MyInsCompl()
  let c = nr2char(getchar())
  if c == "l"
    return "\<C-x>\<C-l>"
  elseif c == "n"
    return "\<C-x>\<C-n>"
  elseif c == "p"
    return "\<C-x>\<C-p>"
  elseif c == "k"
    return "\<C-x>\<C-k>"
  elseif c == "t"
    return "\<C-x>\<C-t>"
  elseif c == "i"
    return "\<C-x>\<C-i>"
  elseif c == "]"
    return "\<C-x>\<C-]>"
  elseif c == "f"
    return "\<C-x>\<C-f>"
  elseif c == "d"
    return "\<C-x>\<C-d>"
  elseif c == "v"
    return "\<C-x>\<C-v>"
  elseif c == "u"
    return "\<C-x>\<C-u>"
  elseif c == "o"
    return "\<C-x>\<C-o>"
  elseif c == "s"
    return "\<C-x>s"
  endif
  return "\<Tab>"
endfunction