タグ「vim」が付けられているもの

「入門 UML 2.0」を読んだ

  • 投稿日:
  • by
  • カテゴリ:

「入門 UML 2.0」を読んだ。 UMLってユースケースを表現するためのものでしょ?と思っていて、図を使ってユースケースを書く必要に迫られることも無かったのであまり勉強する気にもなっていなかったのですが、Plant UMLというテキストでUMLを既述できるものを知り、図を描くのにテキストで記述できるのは便利そうということで読んでみることにしました。

読んでみると、そもそもユースケース図を描くたものものという認識が誤りで、ユースケース図を表現することにも使えるが、それ以外の様々なものを表現するために使えるものであるということがわかりました。また、表現の仕方が定義されていて、UMLを知っている人であれば書き方を説明せずに記述できるということもよく分かりました。そのため、記述ルールについての凡例を書く必要もないのです。

UMLは既述したい目的毎に図の書き方がいくつも用意されています。そして、その目的や使い分けについて説明しています。しかし、その使い方は限定的ではありません。ある特定の種類の図ですべてを表現する必要はなく、その図で表現したい箇所だけをその図で表現し、そのほかの場所は異なる種類の図で表現しても良いとされています。結局は表現すべき重要な事柄を、それを表現するのに適切な図を使って表現すべきとしています。 つまり、何を表現すべきかを考えて使い分けるということです。

この本を読むことで、システム設計においてどのような情報を表現するべきかということがわかると思います。全体の概要を示したい場合や、特定部分の詳細について説明したい場合がありますが、それらがどのような種類の情報であるか、また混ぜるべきではない情報というのはどういうものかというのがなんとなくわかると思います。実際に書いて表現することを繰り返すことで、システムのどの部分をどのように表現するべきかというのがより直感的にわかるようになってくるのだと思います。

ところで、Plant UMLはテキストで記述したものをUML図に変換する仕組み(Webサービス、Javaプログラムとして提供されています)ですが、テキストをエディタで変更すると即座にその結果のUML図が変更されるという使い方ができます。

Vimでは、previmというpluginを使うことで実現できます。 previmはそもそもMarkdownに対してのプレビューを提供するものでしたが、PlantUMLにも対応したのです。

これを使いたかったという気持ちもあります。

そんなわけで、今後、図を記述する必要がある場合にはPlantUMLを積極的に使っていきたいと思っています。

vim plugin の ftdetectの効かせ方

  • 投稿日:
  • by
  • カテゴリ:

vim plugin を作っていてなかなか解決できなかった課題のメモです。

vim ではファイルタイププラグインという種類のプラグインが作成できます。 ファイルタイププラグインはファイルタイプに合わせて挙動を変えることができるようにするためのプラグインです。 vim はファイルを開いた際に、そのファイルがどのファイルタイプか判別します。 ファイルタイプはC言語のようなプログラミング言語毎にあらかじめ定義されていますし、自分で作成することもできます。 自分で作成する場合には、ファイルタイプ名を決めて、そのファイルタイプの場合にどのような挙動にするかを定義したプラグインファイルを作成します。 例えば、ファイルタイプ毎に異なるマップを定義することができます。 その場合、プラグインファイルには定義したいマップコマンドを記述します。そうすることで、特定のファイルタイプの場合にのみそのマップコマンドが実行されるようになります。

ところで、ファイルを開くたびにそのファイルがどのファイルタイプかを判別する必要がありますが、自分で作成したファイルタイプのことはvimは知らないので、どのファイルが自作のファイルタイプに該当するかを定義する必要があります。 それには何らかの方法で以下のようにしてファイルタイプを指定する必要があります。これを実現する方法はいくつかありますが、その一つに ftdetect/*.vim というファイルを使う方法があります。

set filetype=aaaa

ftdetect/*.vim というファイルは、ファイルを開いた際(厳密にはバッファを開いた際)に自動的に読み込まれて実行されるファイルの一つです。 runtimepath配下にあるftdetect/*.vimを実行します。 このファイルは、以下の設定がされていないと読み込まれないようですが、これだけを設定していても読み込まれない場合がありました。

set runtimepath+=~/where/to/pluginpath/
filetype plugin on

読み込まれるようにするためには以下のように、runtimepathの設定の前に filetype offを設定する必要がありました。

filetype off
set runtimepath+=~/where/to/pluginpath/
filetype plugin on

blogの始め方その1

  • 投稿日:
  • by
  • カテゴリ:

どこに書くか

blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。

何で書くか

Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。

そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。

さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。

足りない機能

エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。

  • ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
  • ファイルの更新チェックを行うデーモンを用意する
  • エディタの保存処理をフックする仕組みを用意する

カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。

保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。

vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。

足りない機能を補う

vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。

Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。

作成中の vim プラグイン vim-mtdataapi

記事を投稿する

プラグインが完成したら、ようやく記事を投稿できます。 長い道のりでした。

実践Vimを読んだ。

  • 投稿日:
  • by
  • カテゴリ:

実践Vimを読みました。 本書は初心者向けの内容ということですが、触ったこともないような初心者向けというよりは、vimtutorを終えて基本的な操作がわかった人向けという感触です。 タイトル通り、実践的な内容となっていて、実現したいことの実現方法をいくつも紹介しながらメリット、デメリットを紹介していて、それぞれで使用するオペレータやモーションの理解が深まるようになっています。そのため、どういう場合にどういうオペレータを使うべきかを理解できるようになっています。 なるべく繰り返し操作がしやすいような操作を求めていくと、実現したいことにぴったり一致するオペレータを知る必要が出てきますが、いろいろなオペレータを紹介することで、よくある操作を実行するのに必要なオペレータは既にあるということをうまく示せているように思います。繰り返しを基本とするように考えていくと、段々とどんなオペレータがあるのか調べる必要が出てくるので、今後の上達にもつながっていくと感じます。

印象に残った使い方としては、マークの使い方(vimgrepの実行前とかquickfix関連の実行前とかにマーク設定)とか、挿入モードやコマンドラインモードでのC-rを使った文字入力(C-r0とかC-rC-wとか)とか、globalコマンドの使い方(実行するexコマンドに、rangeを与えて範囲を広く指定するとか)です。でも、そもそも繰り返し可能にするためにどういうオペレータにすべきかとか、マクロの直列実行、並列実行とかそういう考え方が整理されて記述されているのがとても理解の助けになりました。

今後もvimの上達に向けて精進したいと思います。

msys2でrbenv

  • 投稿日:
  • by
  • カテゴリ:

msys2を使ってみることにして、とりあえずvimのビルドしようと思ったらrubyがなかったので、rbenvを入れようとしたらなぜか動かない。

$ ~/.rbenv/bin/rbenv init
.rbenv/bin/rbenv: 行 1: ../libexec/rbenv: No such file or directory

ファイルは存在しているのに無いと言われてしまう。 同じ悩みを持つひとは、これをシンボリックリンクに変えて対処したようだ。こちら参照。 同じようにシンボリックリンクにしてみると確かに動く。 .rbenv/bin/rbenvの中身は確かに1行しかなくて、これを実行するだけなのでリンクに置き換えても問題なさそう。 問題は相対パスで書かれたものを実行できないということなのか。

切り分けのために、rbenvの中身を絶対パスに変更してみると。。

うん。動く。と思ったら引数が渡らない。 リンクのように振舞っているということか?相対パスの始まりが、コマンド実行時のカレントディレクトリになっているみたい。 試しに ~/.rbenv/bin に移動してから実行するとやはり動く。 相対パスの解釈の仕方が問題のようだ。 でも、この後の調べ方がわからない。相対パスを実行しようとするのは誰なのか。bashか? bash -xで見ても特に何も出ない。

Movable Type 用 Vim Plugin を開発中

  • 投稿日:
  • by
  • カテゴリ:

Movable Type というCMSを使ってブログを書いていますが、基本的にブラウザで入力するため文章入力が非効率に感じることが多々あったので、vimから投稿できるようにvim pluginを開発しています。

単純な更新ができるようになってきたので、一旦githubに公開しましたが、とても一般の方が使える状態ではありません。 需要があるようでしたら、issueやSNSなどで連絡もらえると嬉しいです。

Movable Type 用 Vim Plugin: mtdataapi.vim

vimのhelpを読んで新たに覚えた便利なコマンド(usr42)

  • 投稿日:
  • by
  • カテゴリ:

前回の続きです。 usr42はGUIメニューについて。

あまりGUIにこだわりはないので情報少なめ。

  • :menu メニューの編集などが可能。mapコマンドのようにモード別のコマンドがある。 引数無しだと定義済みのメニューが表示される。

  • guioptions-=T ツールバーを非表示にする。 個人的に、メニューは使うこともあるがツールバー(アイコンのボタン)は使わないので、いらない。

vimのhelpを読んで新たに覚えた便利なコマンド(usr41)

  • 投稿日:
  • by
  • カテゴリ:

前回の続きです。

この賞はVim scriptの記法について。

  • let 変数定義に使います。 以下のようにs:を付けるとスクリプトローカルな変数を定義できます。 let s:count

使わなくなったら、unlet s:countで変数を削除してメモリを解放します。

  • exists() 変数の存在確認結果を返す。 引数は変数名の文字列を指定するため、以下のように実行します。 if exists("s:count")

  • $HOME $で始まるのは環境変数。

  • &ic &で始まるのはオプション。 &icはignorecaseオプションのこと。

  • @r @で始まるのはレジスタ。

  • . ピリオドを使って文字の連結ができます。 Perlと同じ。

  • a ? b : c aならばb、aでないならc。 よくある3項演算子。

  • a =~ b aがbパターンにマッチする。 =~ではなく、!~ならマッチしない。 Perlと同じ。ただし、大文字小文字を区別しない。 パターンは文字列として指定する。 "test" =~ "e"

  • a =~# b aがbパターンにマッチする。大文字小文字を区別する。 Perlと同じ。 =~?とすると大文字小文字を区別しない。

  • continue.break while文のループ中で、次のループへ遷移したりループを終了する。

  • eval 文字列を評価した結果を返す。 executeコマンドは結果をコマンドとして実行するが、evalは評価のみで価を返す。

  • function 関数定義。 関数名は大文字で開始。 関数の中で引数を参照するときは、a:countという形でa:を付ける。 関数の中でletコマンドによって定義した変数は関数ローカルな価となる。 s:等を付けた場合はそれに従う。

  • function FunctionName() range rangeを付けると範囲指定を受け付ける。以下のように実行できる。 10,30call FunctionName 範囲は、a:firstline、a:lastlineで参照する。

rangeを付けなかった関数を10,30callで呼ぶと、同じ関数を21回呼ぶことになる。

  • function FunctionName(Start, ...) ...で可変長引数を指定。 a:0は可変長引数の数。a:000は可変長引数のリスト。 a:1は可変長引数の最初の値。

  • function() 引数に指定した関数名の関数への参照を返す。 let Func1 = function( 'FunctionName') 参照を代入する変数名は大文字で始める。

関数参照を実行するにはcall()関数を使う。

  • call() call( Func1 , []) 第2引数は参照している関数の引数リスト。

  • [] リスト。 ['a'] + ['b','c'] "これは['a' , 'b' , 'c'] extend(['b','c'])でも同じ。 add()を使うと、入れ子になる。

  • for n in [] リストの要素をnに代入しながらループ。 rangeと組み合わせて指定回数ループ可能。

  • range() range(3)とすると[0,1,2]のリストが返る。

  • {} 辞書。 let dict = {'a':'b', 'c':'d'} echo dict['a'] echo dict.a

  • for n in sort(keys(dict)) 辞書のキーでループ。

  • function dict.FunctionName dict 辞書に対する関数として定義。 以下のように実行すると、self変数に辞書そのものを格納して関数を実行する。 let dict = {} function dict.FunctionName dict endfunction echo dict.FunctionName

  • get() 辞書にキーがあれば価を返し、なければデフォルト価を返す。 get(dict, key , default)

  • map() リストの各要素に第二引数の処理を加えたリストを返す。 map(alist,'command') 第2引数は文字列として渡す。

  • copy() 辞書をコピーする。

  • try, catch, finally, endtry エラーを例外とする。

  • ma"aYHmbgg"aPbzta ビューの復元のサンプル。 YとPは違うコマンドでも良い。 aとbのマークを付けて、aで移動してztでスクロールして、aでカーソル移動。

vimのhelpを読んで新たに覚えた便利なコマンド(usr40)

  • 投稿日:
  • by
  • カテゴリ:

前回の続きです。

この賞は「新しいコマンドを作る」ということで、「map」、「command」、「autocmd」が説明されています。

  • map、unmap キーのマップを定義します。 をほかのキーに割り当てたりすることで、便利なキーとして登録できます。 unmapでマップを削除します。

  • command コマンドを定義します。 コマンド名は大文字で始める必要があります。

  • autocmd イベント発生時に自動的に実行するコマンドを指定します。 commandで作成したコマンドやcallコマンドを使って関数を実行できます。 executeコマンドを使うと実行するコマンドを動的に作成して実行することができます。

前回の続きです。

  • =a{ コードブロック(a{)を再インデント gg=Gとするとファイル全体の再インデント。

  • a{ コードブロック(a{)をインデント {}の行も含む。含まないときはi{を使う。

  • 挿入モードでCtrl-D, Ctrl-T インデント削除(Ctrl-D)とインデント追加(Ctrl-T) カーソルの位置は関係なく、その行に対して適用

  • set expandtabと:%retab set expandtabでタブ文字を使用不可に設定。 retabコマンドで、バッファ中のタブ文字をスペースに置換

  • undo 2 2番の変更に戻る(アンドゥ)

  • g-、g+ g-で前の変更に戻る(アンドゥ) g+で次の変更に進む(リドゥ) ただし、アンドゥしてから変更した場合などもその順ですべての変更状態に遷移できる。

  • earlier 1f、later 10m earlier、laterで変更履歴を戻ったり進んだりする。 1fは最後に保存した状態。10mは10分など。 undolistで変更確認可能。

前回からの続きです。

  • :argdo %s/a/b/ge :args *.cというように指定して引数リストに関連ファイルを設定した上で、argdoコマンドで引数リストのファイルすべてに対してコマンドを実行。検索の場合、eが無いと文字列が見つからない場合にエラーで途中終了する。 ほかに:windo、bufdoコマンドもある。

  • ls | vim - vimのバッファを標準入力で埋める。

  • vim -w script file.txt scriptファイルにfile.txtの操作コマンド(ノーマルモードコマンド)の履歴を保存する。 後からvim -s script file.txtとすると同じ操作を適用できる。

  • set ignorecase smartcase 検索時の大文字小文字の違いを無視するが、パターンに大文字が含まれる場合は無視しない。

  • /\Cword \Cは大文字小文字の違いを無視しない。\cだと無視する。

  • /abc/2 abcが見つかった行の2行下に移動する オフセットという。

  • /abc/e+2 見つかった文字の最後(c)の二つ右に移動する bだと先頭を基準に移動する。 文字オフセットという。

  • set foldclose=all 折り畳みを自動的に閉じる

  • set foldmethod=indent インデントによって自動的に折り畳みを作る。 shiftwidthによって折り畳みを判断する

前回の続きです。

  • :%!xxd 16進ダンプとテキスト表示に変更(バッファを書き換える) 戻すときは以下。 編集は16進数部分のみ可能。それ以外は無視される。 これを使えばバイナリエディタとして使える。 :%!xxd -r

  • set showmatch 閉じ括弧の入力時に開き括弧にカーソルが移動する。

  • 挿入モードでのCTRL-P、CTRL-N カーソル直前の文字列を使って補完入力 カレントバッファ等にある文字列から補完候補を選ぶ。

  • 挿入モードでのCTRL-X CTRL-F ファイル名の補完。 /と打ってから補完すると/usrなどが候補として表示される。 さらに深い階層の補完候補を出すには再度CTRL-X CTRL-Fを入力。

  • 挿入モードでのCTRL-A 前回と同じ文字を挿入する。 連続して同じ文字列を挿入する際に便利。 CTRL-@は挿入後挿入モードを抜けるらしいが、実際に試しても何も怒らなかった。なんでだろ。

  • 挿入モードでのCTRL-YとCTRL-E CTRL-Yはカーソル位置の一行上の文字を挿入する。 CTRL-Eはカーソル位置の一行下の文字を挿入する。

  • gj、gk 表示行での移動。 折り返すほど長い行での移動を小刻みにする。

  • set virtualedit=all 行末より後ろなどの文字の無い場所にもカーソル移動ができ、文字の挿入や矩形選択が可能となる。 終了するときは以下。 set virtualedit=

  • gr、gR 画面上の表示幅が崩れないように文字を置換。 tabを置換する際に崩れない。

前回の続きです。

  • q: コマンドラインの履歴を編集して再実行できる。 過去実行したコマンドを編集(変更)して似たようなコマンドを実行したいときに便利。例えば、検索コマンドとか。

  • :oldfiles 最近開いたファイルの一覧を表示。

    <2とすると2番目のファイルを指す。:e #<2という感じで使う。

  • :mksession file.vim file.vimにセッション情報を保存する。 セッション情報を使うと開いていたファイルなどの情報を再現してvimを起動することができる。 vim -S file.vim または :source file.vim

vimのhelpを読んで新たに覚えた便利なコマンド(usr10まで)

  • 投稿日:
  • by
  • カテゴリ:

[前回](https://www.sei-yo.jp/blog/engineer/2018/12/vimhelpusr-04txt.html"に引き続き、helpをみてそれまで知らなかったけれども使えそうと思ったコマンドを紹介。

  • qa レジスタaにマクロとして操作を保存。 実行は@a レジスタはヤンクで使われるものと同じなので、バッファの文字列をレジスタにヤンクしてマクロとして実行することも可能。 "ayyみたいに。

  • ?pattern1?+1,/pattern2/-2s/foo/bar/g 上方向(後方)にpattern1を検索し見つかった行の次の行から、下方向(前方)にpattern2を検索し2行手前(上の行)までを対象に、fooをbarにすべて置換する。

  • !Gsort バッファの内容をsortコマンドの結果で置き換える。 一時ファイルを用意する必要ないので便利

  • :read !ls コマンドの実行結果をバッファに挿入。 以下だと現在位置を書き換え :.!ls

  • :wirte !wc ファイルの中身をコマンドに渡す。 結果が表示されるが、その後enterを押すと表示が消える。

vimのCTRL-^が動かない

  • 投稿日:
  • by
  • カテゴリ:

vimのヘルプの、「07.3 他のファイルにジャンプする」にあるCTRL-^が期待通りに動かない。。なんでだろ。

:argsで現在ファイルを確認して、:nextや:previousでファイルを変更してからCTRL-^を入力しても何も変わらない。

vimのテキストをhtmlに変換

  • 投稿日:
  • by
  • カテゴリ:

何がうれしいかって、blogにコードを張るときにhtmlコードをそのままコピペできる点。
でも、出来上がるhtmlファイルはそれ単体で完結している作りなので部分的にコピペが必要で勝手はいまいち。スタイルシートはblogに事前に設定しておけば変更不要なのでそこの手間は不要。

以下のコマンドで変換できる。

:TOhtml

以下が例。

1 if exists('g:loaded_helloworld')
2  finish
3 endif
4 let g:loaded_helloworld = 1
5 command! HWorld call helloworld#hello_world()

vimを使いこなせていない自信があったのでヘルプを見て勉強し直したら便利な使い方がたくさん載っていたのでここにメモ。 とりあえずusr_04.txtの範囲まで。

  • * カーソル位置の単語と一致する単語を検索

  • g* カーソル位置の単語を含むものを検索

  • H 画面上部にカーソル移動

  • M 画面中央にカーソル移動

-L 画面下部にカーソル移動

  • CTRL-O、CTRL-I(Tab) 前、後の位置にジャンプ(カーソル移動)

  • ma、a maでマークして、aで移動。 CTRL-O、CTRL-Iでジャンプもできる

  • `` 一つ前の位置にジャンプする(最初はCTRL-Oと同じ挙動)

  • ~ 大文字小文字変換 ビジュアルモードでも利用可

  • (ビジュアルモード)o、O 選択範囲の変更のために、カーソルを反対側に移動 始点の変更ができる。矩形選択の場合はOも使って範囲変更可能。

  • "* yやpと合わせてクリップボードを使用

dein.vim使ったvimrcでのcolorscheme設定

  • 投稿日:
  • by
  • カテゴリ:

icebergというcolorschemeを作った人の発表をvimconf2017で聞いたら、colorshcemeが大好きなちょっと?変わった人だったので、きっとこれは良いに違いないと導入を決めました。

dein.vimを使っているとどうもうまく反映されないので以下のページを参考にautocmdを使って設定したらうまくいきました。

au MyAutoCmd VimEnter * nested colorscheme iceberg
syntax enable

参考URL

dein.vimによるプラグイン管理のマイベストプラクティス