ラベル Vim の投稿を表示しています。 すべての投稿を表示
ラベル Vim の投稿を表示しています。 すべての投稿を表示

2016/12/13

vim のアウトライン表示プラグイン outline.vim を作った

c 言語の関数一覧が欲しかったので作ったので、 そのあたりの作業について備忘メモしておく。

名前負けはご愛敬。

目的

c 言語の関数一覧が欲しかった。

何を考えたか?

c 言語の関数一覧が欲しいけど、 自分で抽出処理はかけない。

そんなわけで、方針としては

以下、各要素について書いていく。

アウトライン抽出

アウトライン抽出は ctags を使う。

ctags -x FILE_NAME --sort=no

これで member, struct, function のリストが表示される。 ここから member を取り除き、awk で無用な列を削除する。

ctags -x FILE_PATH --sort=no | grep -v member | awk '{$1=\"\";$2=\"\";$3=\"\" + $3;$4=\"\";print}'

これを、vim のバッファに読み込ませるには、 read! コマンドを使う。

silent execute "read !ctags -x " . file_path . " --sort=no | grep -v member | awk '{$1=\"\";$2=\"\";$3=\"\" + $3;$4=\"\";print}'"

これで、 ctags の実行結果を成形したものをバッファに読み込むことができる。

対象にジャンプ

ctags を成形した結果は、各行が 行番号 関数名 となっているので、 split してリストの 0 番目をとってきて、元のバッファに戻って [count]gg すれば OK。

で、できたのが下記な感じ。

以上。

2016/12/04

ファイル検索プラグイン file_selector.vim を作った

ファイル一覧を絞り込んで選択するやつを作ったので、 そのあたりの作業について備忘メモしておく。

目的

netrw でファイルを開くのが面倒。 プロジェクト内のファイル一覧から、文字列打ち込んで絞り込みつつファイル選択したい。 この欲望を満たすプラグインを作る。

何を考えたか?

ファイル絞り込みの構成要素としては、

  1. ファイル一覧取得
  2. 入力文字列取得
  3. 入力文字列を使った絞り込み処理
  4. バッファへの反映

みたいなのがあると思っていて、 2 と 4 のイメージがついてなくって途方に暮れていたところ、 @pink_bangbi さんにつぶやきを拾っていただいた。

そんなわけで、方針としては

  • 文字列取得は InsertCharPre から一文字ずつ取得
  • バッファは全部書き直し

の方針で考えた。

構成要素の実現方法を考える

それぞれ考えていく。

ファイル一覧取得

単純に glob("./**/*") とする。

入力文字列取得

autocmdInsertCharPre を捕まえる。

入力文字列を使った絞り込み処理 + バッファへの反映

v/文字列/d で、文字列が含まれていない行を削除できるので、

  1. バッファクリア
  2. glob("./**/*") で取得した一覧をバッファに流し込む
  3. v/文字列/d で関係ない行を削除

を、文字列入力・削除が行われるたびに実行する。

文字列のハンドリング

InsertCharPre で取得するのはいいけど、それどう管理するの?」を考える。

  • ファイル一覧
    • ファイル一覧はスクリプト変数
    • ファイル絞り込み用バッファを開くときに、``glob("./**/*") する
  • 絞り込み文字列
    • 絞り込み文字列はスクリプト変数
    • ファイル絞り込み用バッファを開くときに、空文字で初期化する
    • InsertCharPre で取得した文字列を絞り込み文字列に追加する
    • <BS> 押下で絞り込み文字列の末尾の文字を消す

file_selector をクラスとして考えると、下図のような感じ。

  • OpenFileSelector() を呼ぶたびに s:patterns:all_file_list を初期化する。
  • 文字入力されるたび( InsertCharPre が呼ばれるたび) AddChar()s:pattern 更新
    • InsertCharPre 内でバッファの更新ができないようなので、バッファの更新は TextChangedI で行う
  • <BS> が押されたら、 DelChar() -> UpdateBuffer() する。

上記のような方針で実装して、下記のような挙動が実現できた。

所感

「OpenFileSelector() を呼び出したバッファでファイルを開きたい」とか、 すでに気に入らないところがあるが、とりあえず絞り込み UI の習作として使用・改良していきたい。

リポジトリはこちら。

以上。

2016/11/28

vim-themis, vital-power-assert を使って vim plugin の単体テストを書いてみた

vim-themis, vital-power-assert を使って単体テストのコードを書いたので、ここに作業を記録する。

手順概要

  1. 必要なパッケージを導入
  2. .themisrc を作成する
  3. テストコードを書く
  4. テストを実行する

以下、各手順を説明していく。

1. vim-themis 導入

vim 標準のパッケージマネージャを使っているので、下記構成で git submodule add した。

.vim
└── pack
     └── test
         └── opt
             ├── vim-themis
             ├── vital.vim
             ├── vital-power-assert
             ├── vital-safe-string
             └── vital-vimlcompiler

注意点 :

  • vital-power-assert は、 vital.vim, vital-vimlcompiler, vital-safe-string に依存しているので忘れず導入する
  • テスト時しか使用しないので、 opt に入れる

2. .themisrc を作成する

vital-power-assert の README, '.themisrc' を参照しつつ .themisrc を作成。

packadd! vital.vim
packadd! vital-vimlcompiler
packadd! vital-safe-string
packadd! vital-power-assert
"
let g:__vital_power_assert_config = {
\   '__debug__': 1,
\   '__pseudo_throw__': 0
\ }

注意点 :

  • 必要なパッケージを packadd! で追加
  • themis へのランタイムパス追加は必要なかった。(packadd! で追加されるのかな?)

3. テストコードを書く

テストコードは、プラグインディレクトリ直下に test ディレクトリを作ってその中に書いていく。

vital-power-assert の README, 'test/Example.vimspec' をマネして Vimspeck-style で記述した。

Describe Test for buffer_selector
  Before all
    let V = vital#of('vital')
    let PowerAssert = V.import('Vim.PowerAssert')
    let s:assert = PowerAssert.assert
  End

  It test_GetBufNo
    let buffers_buffer =  '  1  h   "[無名]"                       行 0'
        \ . "\n" . '  9  h   "[無名]"                       行 0'
        \ . "\n" . ' 10  h   "[無名]"                       行 0'
        \ . "\n" . '119 %a   "[無名]"                       行 1'

    put!=buffers_buffer

    call cursor(1, 1)
    let bufno = buffer_selector#GetBufNo()
    execute s:assert('bufno is# "1"')

    call cursor(2, 1)
    let bufno = buffer_selector#GetBufNo()
    execute s:assert('bufno is# "9"')

    call cursor(3, 1)
    let bufno = buffer_selector#GetBufNo()
    execute s:assert('bufno is# "10"')

    call cursor(4, 1)
    let bufno = buffer_selector#GetBufNo()
    execute s:assert('bufno is# "119"')
  End
End

4. テストを実行する

ターミナルでプラグインのルートディレクトリに移動して、themis を実行すると、 vimspec ファイルを探して実行してくれる。

 ~/.vim/pack/test/opt/vim-themis/bin/themis --reporter spec
Test for buffer_selector
  [✓] test_GetBufNo

tests 1
passes 1

fail の場合は下記のようになる。

~/.vim/pack/test/opt/vim-themis/bin/themis --reporter spec
Test for buffer_selector
  [✖] test_GetBufNo
      function 89() abort dict  Line:22  ()

      vital: PowerAssert:
      bufno is# "120"
      |     |
      '119' 0

tests 1
passes 0
fails 1

実際にやってみたプロジェクトはこちら

buffer_selector.vim - Added test code.

「どうすればテストしやすいか」と、「どうやってテストするか」はまだまだ勉強が必要だ...。

以上。

2016/11/21

シンプルバッファーセレクタープラグイン buffer_selector.vim を作成した

シンプルバッファーセレクタープラグイン buffer_selector.vim を作成した。

mikoto2000/buffer_selector.vim: シンプルで簡単に使えるバッファーセレクター

目的と経緯

目的のバッファーへの切り替えをもっと簡単に行いたい。

今までは、:buffers してバッファー番号を確認した後 :buffer number でバッファを切り替えていた。 これが意外とつらい。

  1. :Unite buffer みたいに選びたいけど、Unite ヘビーなので入れたくない
  2. bufferlist.vim を試したけど、縦分割が気に入らない
  3. 勉強がてら作ってみようか

という感じ。

これ書きながら思ったのが、バッファーセレクターじゃなくて、 ファイルセレクターあたりも視野に入れてプラグイン探したほうが良かった気がする。

手順概要

大体こんな流れで実装していった。

  1. とりあえず書く
  2. 関数化して、それっぽい場所に移動
  3. help ドキュメントを書く
  4. plugin として切り出す

以下、各手順について説明していく。

1. とりあえず書く

適当なファイルにスクリプトを書いて、都度都度 source % で実行していった。

最初は、こんな感じのスクリプトを書いてバッファ一覧がとれるか確認した。

""" 変数 buffer_list に ``ls`` の結果を格納
let buffer_list=""
redir => buffer_list
silent ls
redir END

""" 新しいバッファを作成
new __BUFFERLIST__

""" __BUFFERLIST__ に ``ls`` の結果を表示
put!=buffer_list

その後、インクリメンタルに source % しながら実装していき、最終的にできたのがこれ。

""" 変数 buffer_list に ``:ls`` の結果を格納
let buffer_list=""
redir => buffer_list
silent ls
redir END

""" 新しいバッファを作成
if bufexists(bufnr('__BUFFERLIST__'))
    bwipeout! __BUFFERLIST__
endif
silent bo new __BUFFERLIST__

""" __BUFFERLIST__ に ``:ls`` の結果を表示
silent put!=buffer_list

""" 先頭と末尾が空行になるのでそれを削除
normal G"_dd
normal gg"_dd

""" ウィンドウサイズ調整
let current_win_height=winheight('%')
let line_num=line('$')
if current_win_height - line_num > 0
    execute "normal z" . line_num . "\<Return>"
endif

""" バッファリスト用バッファの設定
setlocal noshowcmd
setlocal noswapfile
setlocal buftype=nofile
setlocal bufhidden=delete
setlocal nobuflisted
setlocal nomodifiable
setlocal nowrap
setlocal nonumber

""" 選択したバッファに移動
map <buffer> <Return> ^viwy:bwipeout!<Return>:buffer <C-r>"<Return>
map <buffer> q :bwipeout!<Return>

2. 関数化して、それっぽい場所に移動

「1.」の段階で、 source % すれば所望の動きになることが確認できているので、 あとは

  1. 関数化して autoload に突っ込む
  2. .vimrc で関数を呼び出すマッピングを定義する

をすれば OK。

具体的に、どこにどう配置したかは、 コミット見るのが早そうなのでリンク張る。

Added simple buffer select process

3. help ドキュメントを書く

はじめてプラグインを作ってみた。それとhelpの書き方など - 反省はしても後悔はしない を参考に、 jax ファイルを作成。

これもコミットへのリンクのほうがわかりやすいか。

Added document of 'buffer_selector'.

4. plugin として切り出す

新しいリポジトリを作って作成したファイルを追加。

mikoto2000/buffer_selector.vim: シンプルで簡単に使えるバッファーセレクター

その後、もともと作っていたソースを削除し、代わりに、新しく作ったリポジトリをパッケージに登録。

Carve out 'buffer_selector.vim' to external plugin.

プラグイン作成作業は以上。

所感

だらだら作っていったけど、 プラグイン管理の仕組みを使ってすぐインストールできる vim プラグインが作れたからとりあえず満足した。

以上。

2016/11/08

VimConf 2016 に参加しました

VimConf 2016 への参加記録として、殴り書きメモを張り付けていきます。

Introduction to Vim 8.0

  • See :help version8
  • See :help channel-demo
  • See :help job_start()
  • See :help timer_start()
  • See :help Partial
    • Partial : 部分適用, コールバック等で便利らしい
  • See :help lambda
  • See :help closure
  • See :help window-id
    • Window に、不変の、一意な Window ID がつくようになったらしい。
  • See :help test-functions
  • See :help breakindent
    • マージに 10 年!
  • See :help renderoptions
  • Search Coveralls

知らない機能たくさん。特に、「Partial」「window-id」「breakindent」は今の自分に有用そうなので調べる。

VIM AS THE MAIN TEXT EDITOR

  • 「vimrc をオリジナルにする」、同感。
  • Vim に移行するためのモチベーションは何だろうか?
    • 仕事で使う必要があった
  • Vim を使うための準備運動
    • vim tutorial
    • VIMIUM
  • Vim を育てる
    • github で vimrc を検索
    • 内容を把握してコピペ
    • 気になったことを issue で書く
  • Q: Vim に移行して一番テンションの上がった機能は?
    • A: VimFiler, UI, 操作性が直感的で感動した

プロジェクトメンバに Vim 布教するにあたりこの辺のステップを参考にしていきたい。

Denite.nvim ~The next generation of unite~

NeoVim かー、 Python かー、速いのかー、うらやましいなー。って聞いてた。 (NeoVim 専用と誤解してた、NeoVim が Linux でしか動かないと思ってた。)

※ 懇親会にて Shougo さんに NeoVim は Windows ネイティブでも動くようになってるし、Bash on Ubuntu on Windows なら完璧に動くという話をしていただいたので試す。

Go、C、Pythonのためのdeoplete.nvimのソースの紹介と、Neovim専用にpure Goでvim-goをスクラッチした話

NeoVim かー、 Python かー、速いのかー、うらやましいなー。って聞いてた。

エディタの壁を超える Go の開発ツールの文化と作成方法

  • 特徴
    • 強力でシンプルな言語設計と文法
    • 平行プログラミング
    • 豊富なライブラリ
    • 豊富なツール
    • シングルバイナリ/クロスコンパイル
      • Windows 界隈だとシングルバイナリ便利
  • ツール群
    • govet
    • guru
    • gocode
    • errcheck
    • gorename
    • gomvpkg
  • Search gofmt -s

社内ツールで Go 使うときの宣伝文句としてスライド ぱくりたい 超参考になった。

vim-mode-plus for Atom editor

  • Search operation-stack
  • Search Vim で
  • Search occurrence
  • Search Vim で vip
  • Search Vim で「キャメルケース/スネークケース」変換

モーションとオペレータの考え方がわかりやすかった。 そのあたりを意識しながらコマンド使っていきたいと思った。

Vimの日本語ドキュメント

  • vim のドキュメント
    • vim-jp/vimdoc-ja
      • リファレンスとユーザーマニュアル
    • vim-jp/lang-ja
      • メニュー・メッセージ
    • Vim のユーザーマニュアルは、 usr_ で始まるやつ
  • Travis-CI 上で表記ゆれチェック
    • koron/nvcheck
  • vimdoc-ja の課題
    • 訳文の統一
      • 表記ゆれ
      • 文体の統一
    • 翻訳支援ツールの利用
      • 原文成形済み
        • なので、差分検出が難しい
          • なので、マークアップと成形ツールがほしい
      • これで、翻訳の品質向上を目指す

ドキュメント翻訳って、翻訳そのものも大変だけど、翻訳のための仕組み作りもまた大変なんだなぁ。 表記ゆれチェックはうちのプロジェクトに取り込めたら取り込んでいきたい。

Vim script parser written in Go

  • Linter
  • Fixer
  • Formatter
  • Completion

殴り書きで上記単語だけ書かれていた...。完全に内容についていけてなかった...。

僕の友達を紹介するよ

この辺試していきたい。

Best practices for building Vim plugins

  • ドキュメントを書きましょう
    • README を置くだけでは不十分
    • See :help design-documented
  • namespace を意識しましょう
    • 他プラグインと名前がバッティングしないように注意
    • プラグイン名を prefix にする
      • 勝手に省略するのはダメ
      • 実際どう呼ぶかはユーザーに任せる
    • プラグイン名を決める前にググる
    • 外部インターフェースの関数, 変数名も同じなので注意
  • autoload を使いましょう
    • plugin/xxx.vim には UI 定義のみ
    • 逆に言うと、 plugin/xxx.vim から autoload 内のコードを呼ぶのは残念な感じ
  • カスタマイズできるようにするのが Vim っぽい
    • 高カスタマイズ性
  • <Plut> キーマッピングを使いましょう
  • Plugin original buffer is useful
    • 実際のバッファに紐づかないバッファ?
    • BufReadCmd, BufWriteCmd
    • {plugin-name}://...
    • バッファを使うプラグインはスコープに注意
  • デフォルトで移動するキーのマッピングを上書きしちゃうと顰蹙を買うかも...
  • See <Leader>, <LocalReader>
  • Open API
  • マルチプラットフォーム対応しましょう
    • See :help design-multi-platform
  • テスト書くとよい
  • スクリプト内で省略形を使うのはダメ
    • 省略形はコマンドモードで楽に入力するためのもの

もりだくさん。 Vim script 書くときに意識していきたい。

所感

  • 書き殴ったことを消化・吸収しつつ、Vim 力を高めていきたい
  • NeoVim, Go を全くウォッチしていなかったのが悔やまれる
  • Windows で NeoVim 動かして deoplete.nvim を使ってみよう

2016/11/01

[Vim] Vim で、カーソル下の数値を変換したい

上から順に、

  • 2 進数変換
  • 10 進数変換
  • 16 進数変換
  • 数値の桁(ゼロオリジン)のマスク値に変換
  • 数値の桁(1オリジン)のマスク値に変換

という感じ。

マクロ

viwc^R=printf("0b%b", ^R")^M^[
viwc^R=printf("%d", ^R")^M^[
viwc^R=printf("0x%04X", ^R")^M^[
viwc^R=printf("0x%04X", printf("%.f", pow(2, ^R")))^M^[
viwc^R=printf("0x%04X", printf("%.f", pow(2, ^R"-1)))^M^[

コマンドバージョン

command! Num2b execute "normal viwc<C-R>=printf(\"0b%b\", <C-R>\")<Return><Esc>"
command! Num2d execute "normal viwc<C-R>=printf(\"%d\", <C-R>\")<Return><Esc>"
command! Num2x execute "normal viwc<C-R>=printf(\"0x%04X\", <C-R>\")<Return><Esc>"
command! Num2Mask0 execute "normal viwc<C-R>=printf(\"0x%04X\", printf(\"%.f\", pow(2, <C-R>\")))<Return><Esc>"
command! Num2Mask1 execute "normal viwc<C-R>=printf(\"0x%04X\", printf(\"%.f\", pow(2, <C-R>\"-1)))<Return><Esc>"

2016/09/24

[Vim] Vim8 の job_start と Pandoc を使って Markdown -> html 変換

job_start を使って pandoc を呼び出すだけ。

function! M2H()
    " 一時ファイル名をもらう
    let tempbuf_in = tempname()
    let tempbuf_out = tempname()

    " 入力用一時ファイルに現在のバッファの内容を保存
    w `=tempbuf_in`

    " pandoc で Markdown -> html 変換
    " 出力先は出力用一時バッファ
    call job_start("pandoc -f markdown -t html5 " . tempbuf_in, {'out_io': 'buffer', 'out_name': tempbuf_out})

    " 出力用一時バッファを split して開く
    new `=tempbuf_out`

    " 先頭行の 'Reading from channel output...' を削除
    1delete
endfunction

command! M2h call M2H()

2016/09/21

[作業記録][Vim]Bash on Ubuntu on Windows で Vim 8 をビルドする

Bash on Ubuntu on Windows で +lua の Vim 8 をビルドします。

前提条件

環境的には下記投稿からの続き。
親知らずの日記: [作業記録]Ubuntu on Windows で Autoware を動かしたかった : http://oyasirazu.blogspot.jp/2016/08/ubuntu-on-windows-autoware.html

以前の実績があるので、 gitbuild-essential, libncurses5-dev あたりが入っていればよさそう。

作業ログ

sudo apt update
sudo apt install liblua5.1-dev libluajit-5.1-dev luajit

cd ~/project
git clone https://github.com/vim/vim
cd vim

./configure --enable-luainterp --with-luajit --prefix=/home/mikoto/app/vim/ --enable-fail-if-missing
make -j8
make install
あとは ~/app/vim/bin にパスを通して完了。

2014/11/08

[Vim, Ubuntu]Ubuntu1204 での vim ビルドメモ

忘れないように。 Ubuntu1204 をインストールして、 aptitude で build-essential を入れたくらいのはず。

sudo aptitude install libncurses5-dev
sudo aptitude install liblua5.2-dev
sudo aptitude install liblua5.1-0-dev
sudo aptitude install luajit libluajit-5.1-dev

cd ~/project/vimsrc/

hg pull
hg update

./configure --enable-luainterp --with-luajit --prefix=/home/mikoto/app/vim/ --enable-fail-if-missing
make -j8
make install

2013/10/13

vim を +lua でコンパイルする

vim7.4 で neocomplete が使いたいので頑張る。

sudo aptitude install lua
cd /PATH/TO/VIM/SRC
hg pull
hg update
./configure --enable-luainterp=yes --with-luajit --prefix=/home/mikoto/app/vim/
make && make install

... -lua だ! .configure の出力を真面目に見てみよう...。

./configure --enable-luainterp=yes --with-luajit --prefix=/home/mikoto/app/vim/ | grep lua
checking --enable-luainterp argument... yes
checking --with-lua-prefix argument... no
checking --with-luajit... yes
checking for luajit... no
checking if lua.h can be found in /usr/include... no
checking if lua.h can be found in /usr/include/lua... no

ヘッダが無いとダメなのかー。

sudo aptitude install liblua5.2-dev
ls /usr/include | grep lua
lua5.2

oh...パスが違うようだ。

sudo ln -s /usr/include/lua5.2 /usr/include/lua
./configure --enable-luainterp=yes --with-luajit --prefix=/home/mikoto/app/vim/ | grep lua
checking --enable-luainterp argument... yes
checking --with-lua-prefix argument... no
checking --with-luajit... yes
checking for luajit... no
checking if lua.h can be found in /usr/include... no
checking if lua.h can be found in /usr/include/lua... yes
checking if link with -L/usr/lib/x86_64-linux-gnu -lluajit is sane... no

luajit が有効にならない...。 別途 luajit が必要? wheezy には deb パッケージなかったので今回はいいや。 luajit なしで続行。

# こっちだと lua5.2 見つけてくれるのね...
./configure --enable-luainterp=yes --prefix=/home/mikoto/app/vim/ | grep lua
checking --enable-luainterp argument... yes
checking --with-lua-prefix argument... no
checking --with-luajit... no
checking for lua... (cached) /usr/bin/lua
checking if lua.h can be found in /usr/include... no
checking if lua.h can be found in /usr/include/lua5.2... yes
checking if link with -L/usr/lib -llua5.2 is sane... yes
make && make install
vim --version | grep +lua
+dialog_con_gui  +lua             -rightleft       +windows

よしできた。