macvim-kaoriya or macvimをビルドする(2015/08)

vim 7.4.774で追加された v:completed_item をmacvim-kaoriyaで使いたくなったけど今日の時点だとまだバージョン7.4.769なので使えない...
Homebrewからインストールできるらしいけど手元の環境ではエラーが出たのでコンソールからビルドしてみる。

2015/08/26追記

エラーの原因は古いrecipeを参照しているせいでした。

brew tap splhack/homebrew-splhack
brew install --HEAD splhack/splhack/macvim-kaoriya

でHomebrewからインストールできたので以下は通常用途では使う必要なさそう。

  • vim本体のソースを変更したい
  • if_*を/usr/local以外のバージョンで使いたい

時くらいか。。。


ソースのダウンロード
  • macvim-kaoriya
git clone https://github.com/splhack/macvim

or

  • macvim
git clone https://github.com/b4winckler/macvim
ビルド

このビルドスクリプト

gist.github.com

macvimディレクトリで実行する。

cd macvim
./build-macvim.sh
実行
open src/MacVim/build/Release/MacVim.app

とりあえず動いた。

  • macvim-kaoriya
:version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 23 2015 20:28:09)
MacOS X (unix) version
Included patches: 1-826
Compiled by daisuzu <daisuzu@gmail.com>
Huge version with MacVim GUI.  Features included (+) or not (-):
+acl             +cmdline_info    +emacs_tags      -gettext         +listcmds        +mouse_netterm   +persistent_undo +signs           +termresponse    +wildignore
+arabic          +comments        +eval            +guess_encode    +localmap        +mouse_sgr       +postscript      +smartindent     +textobjects     +wildmenu
+autocmd         +conceal         +ex_extra        -hangul_input    +lua/dyn         -mouse_sysmouse  +printer         -sniff           +title           +windows
+balloon_eval    +cryptv          +extra_search    +iconv           +menu            +mouse_urxvt     +profile         +startuptime     +toolbar         +writebackup
+browse          +cscope          +farsi           +insert_expand   +migemo          +mouse_xterm     +python/dyn      +statusline      +transparency    -X11
++builtin_terms  +cursorbind      +file_in_path    +jumplist        +mksession       +multi_byte      +python3/dyn     -sun_workshop    +user_commands   -xfontset
+byte_offset     +cursorshape     +find_in_path    +keymap          +modify_fname    +multi_lang      +quickfix        +syntax          +vertsplit       +xim
+cindent         +dialog_con_gui  +float           +kaoriya         +mouse           -mzscheme        +reltime         +tag_binary      +virtualedit     -xsmp
+clientserver    +diff            +folding         +langmap         +mouseshape      +netbeans_intg   +rightleft       +tag_old_static  +visual          -xterm_clipboard
+clipboard       +digraphs        -footer          +libcall         +mouse_dec       +odbeditor       +ruby/dyn        -tag_any_white   +visualextra     -xterm_save
+cmdline_compl   +dnd             +fork()          +linebreak       -mouse_gpm       +path_extra      -ruby19          -tcl             +viminfo         -xpm
+cmdline_hist    -ebcdic          +fullscreen      +lispindent      -mouse_jsbterm   +perl/dyn        +scrollbind      +terminfo        +vreplace        
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "$VIM/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/Applications/MacVim.app/Contents/Resources/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe  -DMACOS_X_UNIX  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1       
Linking: gcc   -L. -L/usr/local/lib -L. -L/usr/local/lib  -L/usr/local/lib -o Vim -framework Cocoa -framework Carbon       -lm  -lncurses -liconv -lmigemo -framework Cocoa  -pagezero_size 10000 -image_base 100000000  -pagezero_size 10000 -image_base 100000000  -fstack-protector  -L/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE 
  • macvim
:version
VIM - Vi IMproved 7.4 (2013 Aug 10, compiled Aug 23 2015 20:37:09)
MacOS X (unix) version
Included patches: 1-383
Compiled by daisuzu <daisuzu@gmail.com>
Huge version with MacVim GUI.  Features included (+) or not (-):
+acl             +cmdline_info    +emacs_tags      -gettext         +lua/dyn         +mouse_urxvt     +profile         +statusline      +transparency    -X11
+arabic          +comments        +eval            -hangul_input    +menu            +mouse_xterm     +python/dyn      -sun_workshop    +user_commands   -xfontset
+autocmd         +conceal         +ex_extra        +iconv           +mksession       +multi_byte      +python3/dyn     +syntax          +vertsplit       +xim
+balloon_eval    +cryptv          +extra_search    +insert_expand   +modify_fname    +multi_lang      +quickfix        +tag_binary      +virtualedit     -xsmp
+browse          +cscope          +farsi           +jumplist        +mouse           -mzscheme        +reltime         +tag_old_static  +visual          -xterm_clipboard
++builtin_terms  +cursorbind      +file_in_path    +keymap          +mouseshape      +netbeans_intg   +rightleft       -tag_any_white   +visualextra     -xterm_save
+byte_offset     +cursorshape     +find_in_path    +langmap         +mouse_dec       +odbeditor       +ruby/dyn        -tcl             +viminfo         -xpm
+cindent         +dialog_con_gui  +float           +libcall         -mouse_gpm       +path_extra      +scrollbind      +terminfo        +vreplace        
+clientserver    +diff            +folding         +linebreak       -mouse_jsbterm   +perl/dyn        +signs           +termresponse    +wildignore      
+clipboard       +digraphs        -footer          +lispindent      +mouse_netterm   +persistent_undo +smartindent     +textobjects     +wildmenu        
+cmdline_compl   +dnd             +fork()          +listcmds        +mouse_sgr       +postscript      -sniff           +title           +windows         
+cmdline_hist    -ebcdic          +fullscreen      +localmap        -mouse_sysmouse  +printer         +startuptime     +toolbar         +writebackup     
   system vimrc file: "$VIM/vimrc"
     user vimrc file: "$HOME/.vimrc"
 2nd user vimrc file: "~/.vim/vimrc"
      user exrc file: "$HOME/.exrc"
  system gvimrc file: "$VIM/gvimrc"
    user gvimrc file: "$HOME/.gvimrc"
2nd user gvimrc file: "~/.vim/gvimrc"
    system menu file: "$VIMRUNTIME/menu.vim"
  fall-back for $VIM: "/Applications/MacVim.app/Contents/Resources/vim"
Compilation: gcc -c -I. -Iproto -DHAVE_CONFIG_H -DFEAT_GUI_MACVIM -Wall -Wno-unknown-pragmas -pipe  -DMACOS_X_UNIX  -g -O2 -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1      
Linking: gcc   -L. -L/usr/local/lib -L. -L/usr/local/lib  -L/usr/local/lib -o Vim -framework Cocoa -framework Carbon       -lm  -lncurses -liconv -framework Cocoa  -pagezero_size 10000 -image_base 100000000  -fstack-protector  -L/System/Library/Perl/5.18/darwin-thread-multi-2level/CORE 

gettext-mkやif_*の言語は全部Homebrew経由でインストールした。
luaenv、pyenv、rbenvあたりが有効だと多分ビルドできないので無効にするか以下を正しく設定する。

  • --with-lua-prefix
  • --with-lua52-prefix
  • --with-python-config-dir
  • --with-python3-config-dir
  • --with-ruby-command

Shibaで図を書いてTracで共有する

Shibaというマークダウンをプレビューしてくれるアプリがあるのですが、

と言ってみたところ

翌日にはmermaid.jsを利用した図が表示できるようになっていました。

これでちょっとした打ち合わせなどで図を見せつつ箇条書きでメモを書いていく、 なんて使い方ができそうです。
そうなると今度はその内容を共有したくなったりしますが、 毎回Shibaを起動して表示してもらうのは嫌がられそうだし、 そもそも全員がShibaをインストールしてくれるとは限らないのでWebに置けると良さそうです。

といっても専用のホストを用意するほどではないので今のチームで一番使われているTracで共有する方法を考えてみました。

  1. プラグインを作る
  2. Tracが稼働しているホストのHTMLを直接編集してmermaid.js(依存しているD3.jsやcssも含む)を追加する
  3. ThemeEnginePlugin をインストールしてCustomize: Advancedからmermaid.js(依存しているD3.jsやcssも含む)を直接埋め込む

http://trac-hacks.org/raw-attachment/wiki/ThemeEnginePlugin/admin_advanced.png

1は正直面倒、2は権限が無くて不可能、消去法的に3でやってみましたが、 Shibaで次のように図を書き、

```mermaid
gantt
    title A Gantt Diagram

    section Section
    A task           :a1, 2014-01-01, 30d
    Another task     :after a1  , 20d
    section Another
    Task in sec      :2014-01-12  , 12d
    anther task      : 24d
```

TracWikiなどでhtmlプロセッサを利用して同じように図を表示させることができるようになりました。

{{{
#!html
<div class="mermaid">
gantt
    title A Gantt Diagram

    section Section
    A task           :a1, 2014-01-01, 30d
    Another task     :after a1  , 20d
    section Another
    Task in sec      :2014-01-12  , 12d
    anther task      : 24d
</div>
}}}

コードブロックとdivの変換はvimで編集していればそんなに手間ではないでしょう。

ちなみにドキュメントには明示されていませんでしたがShibaでもガントチャートを表示させることが可能です。

Middleman(Slim) + Ractive.jsでWeb AppのUIを作る

JSONでバックエンドサーバとデータをやり取りするというごく普通のWeb Appを作るにあたり、 UIをどうするか悩みつつ MiddlemanRactive.js を使ってみることにした。

Middlemanを選んだのは

  • 開発中のlivereload
  • css, jsのconcat/minify
  • ページの構造化
  • 各種ライブラリの管理

がお手軽そうだったのと直接htmlを書かなくて済むから。

Ractive.jsはデータバインディングMiddlemanと組み合わせても違和感無く使えそうな感じだったから。

そして一番の理由は
「htmlがよくわからない」
ってメンバーでもtracredminewikiとかチケットはバリバリ使っていたので、 Slimで書かれているところは内容を理解してもらえそうだったから。
あわよくばUIや(フロント側が要求する)APIの修正なんかもやってくれるようになるかもと思い、ひと通りデモを見せたところ
「全然わかりませんでした」
と言われれるという残念な結果に...

そんなこんなで実際に作ったものはこのまま消えていってしまいそうなので 忘れないようにサンプルを残しておくことにする。

daisuzu/example-middleman-ractive · GitHub

Goでhttp.ClientのテストをするときにProxyを書き換えてテストサーバにリクエストを投げる

Goで外部リクエストが関わる処理をテストする - Qiitafetch(url string)と違って引数でURLを取れないような関数をテストする場合、
http.DefaultTransport.(*http.Transport).Proxyを書き換えるとテストサーバにリクエストを飛ばせる。

main.go

package main

import (
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
)

func fetch() []byte {
    res, err := http.Get("http://localhost:8000/test")
    if err != nil {
        log.Fatal(err)
    }
    defer res.Body.Close()

    body, err := ioutil.ReadAll(res.Body)
    if err != nil {
        log.Fatal(err)
    }
    return body
}

func main() {
    fmt.Printf("%s", fetch())
}

main_test.go

package main

import (
    "fmt"
    "net/http"
    "net/http/httptest"
    "net/url"
    "testing"
)

func TestFetch(t *testing.T) {
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprint(w, "test")
    }))
    defer ts.Close()

    defaultProxy := http.DefaultTransport.(*http.Transport).Proxy
    http.DefaultTransport.(*http.Transport).Proxy = func(req *http.Request) (*url.URL, error) {
        // テストサーバのURLをProxyに設定
        return url.Parse(ts.URL)
    }
    // テストが終わったらProxyを元に戻す
    defer func() { http.DefaultTransport.(*http.Transport).Proxy = defaultProxy }()

    value := string(fetch())
    expected := "test"
    if value != expected {
        t.Errorf("Expected %v, but %v:", expected, value)
    }
}
参考

mattn.kaoriya.net


前にどこかで似たような記事を見たような気がしたんけど今探したら見つからず...
かわりに

github.com

なんてのがあることを知った。

neocompleteのomniソースからneosnippetのスニペットを生成する

前回のTokyoVimで作ったアレプラグイン化しました。

github.com

プラグイン名は語感と強引なこじつけです。
クーポンなんかはありません。

を実装したかったところだけど、とりあえず公開してOmniSharp対応*1を優先させることにしました。

*1:thincaさんのPR

TokyoVim#24に行ってきた

tokyovim.connpass.com

今日のTokyoVimではneocompleteのomniソースから関数のシグネチャスニペットを生成するVim scriptを作ってみました。

今のところ対応しているのは

のみです。

使い方は以下のソースをvimrcにでも貼り付けて適当にマッピングするだけです。

imap <C-]> <Plug>(neosnippet_autogen_signature)

プラグイン化の予定は未定です。

vital-smtpを作った

Vim Advent Calendar 2014の7日目の記事です。 昨日は@katono123さんのVim script + Lua で rogue.vim を作った話でした。

以前unite-notmuchというメールを閲覧するプラグインを作ったのですが、 メールを送信する機能がないため、これと組み合わせて使うメール送信プラグインが欲しいと思っていました。

探してみると

などが見つかりましたが、これらは単体で使用するためのプラグインなので他のプラグインと組み合わせて使うには向いていないようです。
やはりVimでメールを送りたいという人がいないからなのか、これといったものが見つからなかったので自作してみることにしました。

他のプラグインと組み合わせて使うというと真っ先に思いつくのがvital.vimです。
少し前から気にはなっていたのですが(vital-overなど)、vital.vimは独自に外部モジュール作ることができるようなので今回はそれを試してみます。

1. vital外部モジュールの作成

作成するのはSMTPでメールを送信するvitalモジュールなのでプラグイン名は vital-smtp とします。
まずはプラグイン用のディレクトリ、 vital-smtp を作成します。
中身は本家vital.vimと同じでautoload配下に vital/__latest__ を配置すれば良いようです。
プラグイン本体はその配下に配置することになるので SMTP.vim を作成します。

vital-smtp
└── autoload
     └── vital
         └── __latest__
             └── SMTP.vim

完成したプラグインこちらです。
pythonのsmtplibを利用してメールを送信する s:sendmail という関数があるだけの簡単なプラグインになりました。

function! s:sendmail(addr, user, password, from_addr, to_addrs, msg)
    " 省略
endfunction

2. vital外部モジュールの使い方

vitalの外部モジュールを作成したら次は実際にプラグインに組み込んでみることにします。
とりあえず確認用なので適当なディレクトリにサンプルプラグインを作ります。

$ mkdir vim-sendmail-example
$ cd vim-sendmail-example/
$ mkdir autoload plugin
$ vim plugin/sendmail_example.vim

組み込み方はvital-smtpVimのruntimepathに通っていれば通常のvitalモジュールと同じようにVitalizeコマンドを実行するだけです。

:Vitalize --name=sendmail_example . SMTP

プラグイン内での呼び出し方も同様で、 import するだけで先ほど作成した関数を使うことができるようになります。

let s:SMTP = vital#of('sendmail_example').import('SMTP')
" call s:SMTP.sendmail()が使えるようになる

完成したサンプルプラグインこちらです。
:Sendmail コマンドを実行するとプロンプトに入力した内容でメールを送信します。

3. メール送信の確認

手っ取り早く使えそうなSMTPサーバが思いつかなかったのでローカルのメールサーバでサンプルプラグインの確認をします。

# pythonに付属しているデバッグ用サーバを起動する
$ sudo python -m smtpd -c DebuggingServer localhost:10025

サーバが起動したらVimを立ち上げてサンプルプラグインの:Sendmailコマンドを実行します。

:Sendmail
host: localhost<Enter>
port: 10025<Enter>
user: <Enter><Enter>
password: <Enter>
from: test@example.com<Enter>
to: test@example.com<Enter>
msg: test<Enter>

msgにtestと入力してEnterを押すとメールサーバのコンソールにVimから送ったメールが表示されました。

---------- MESSAGE FOLLOWS ----------
From: test@example.com
To: test@example.com
X-Peer: 127.0.0.1

test
------------ END MESSAGE ------------

4. テストの追加

順番は置いておいて、せっかくプラグインを作ったのでthincaさんのvim-themisを使ったテストを追加しておきます。

vital-smtp
├── autoload
│   └── vital
│       └── __latest__
│           └── SMTP.vim
└── test
    └── SMTP.vim

テストはthemisコマンドに --runtimepath でvital-smtpに必要なプラグインを指定して実行します。

$ themis --runtimepath /tmp/vital.vim
1..9
ok 1 - SMTP test_import
ok 2 - SMTP test_sendmail_success
ok 3 - SMTP test_sendmail_success_without_starttls
ok 4 - SMTP test_sendmail_success_without_login
ok 5 - SMTP test_sendmail_failed_to_connect
ok 6 - SMTP test_sendmail_failed_to_starttls
ok 7 - SMTP test_sendmail_failed_to_login
ok 8 - SMTP test_sendmail_failed_to_send
ok 9 - SMTP test_sendmail_failed_to_quit

# tests 9
# passes 9

5. ハマったところ

if_pyの例外

pythonで例外が発生するとコマンドラインにはpythonのTraceが表示されますが、 v:exception が常に 'Vim(python):Traceback (most recent call last):' になってしまうため、 Vim script内ではcatchできなくて困りました。
これが仕様なのかはよくわかりませんが、今回はif_py側で例外を捕捉したら文字列にしてVim script側に返す作りにしました。

if_pyを使った関数のテスト

pythonのsmtplib周りのテストにはメールサーバが必要なのですが、 例外を発生させるためのメールサーバを用意するのが面倒だったので mockを使うことにしました。
ただテストが

  1. Vim script: テスト関数が呼ばれるとmockを使うためにpythonを呼び出す(テストスクリプト)
  2. python: mockでsmtplibの挙動を制御して外部モジュールを呼び出す(テストスクリプト)
  3. Vim script: 引数を受け取ってpythonに渡す(外部モジュール)
  4. python: smtplibを使ってメールを送信し、例外が発生したらVim scriptに返す(外部モジュール)
  5. Vim script: pythonで例外が発生していたらthrowする(外部モジュール)
  6. python: 外部モジュールで例外が発生していたら文字列にして返す(テストスクリプト)
  7. Vim script: 戻り値が期待通りか判定する(テストスクリプト)

と、Vim scriptとpythonを行ったり来たりでとても気持ち悪いものになってしまいました。


さて、目的のメール送信プラグインは作れたのでそのうちunite-notmuchにvital-smtpを組み込むなどしてメールを送信できるようにしたいと思います。
が、MIME関連の機能が足りないのでその前にvital-mimeが必要になるのかも...!?

それからテストをTravis CIで動かしたくてTravis CIにアカウントを作ってみたのですがローカルで全部通ったテストが大コケしたまま、 この記事を書いていたTokyo Vim#23タイムアウト(スマブラタイム)してしまったので時間があるときに調べてみることにします。

 
明日は去年に引き続き@Linda_ppさんです。  
 
 
スマブラでボコボコにされている様子。