読者です 読者をやめる 読者になる 読者になる

ニート脱出できたっぽい

一度ニート脱出したと思ったら再び無職になった前例があるので油断は出来ないが、とりあえず脱出できたっぽい。

やったことといったらハロワで検索して書類送って面接に行ったことくらいだが。
パソコンに強そうというイメージで採用されたっぽいな。
ちなみに私は大学卒業してから6年間、正社員歴はない。
その会社はAmazon楽天やYahooにネットショップを出していて、運営を手伝ってくれる人を探していた。

私は別にウェブデザイナーではないのだが、楽天やYahooのショップのデザインが酷いというのが分かった。ウェブデザイナーではないがウェブデザイナー的な仕事を期待されてるんだろうなー。全然分からんけど。

ニートにコツなんてない。
資格を取ってそれを足がかりにするという方法を選ばないのであれば、
駄目な自分を採用してくれるような奇特な経営者を捜すしかないのだ。
経験上、B型の経営者は人情家で、ブランクを気にせずに採用してくれる気がする。
しっかりしてそうなところはブランクを気にして敬遠してくる。*1
だから、採用してくれそうなところに当たるまで頑張るしかないだろう。

私はハローワークしか利用しなかったが、ブランクのある人間が利用するのに、ハロワが最も適していると思っている。

他の求人サイトは登録料が必要なので、企業はそれだけ元を取ろうとする力が働いている。
ハロワの登録はタダだ(たぶん)。だから低クオリティの人材でもある程度許容してくれるかも知れない。
それに、ハロワの求人は始めに書類郵送させるものが多い。就活の交通費は高い。
実際に訪ねてみて問題外とはねられるくらいなら、書類選考の時点ではねられた方がお金も無駄にならない。
そのために、A4の封筒と、120円切手*2と、証明写真を大量に用意しておいて、いつでも履歴書を送れるようにしておく。 履歴書は、Wordでフォーマットを作っておいて、自分の名前だけ手書きにした。 履歴書手書き論なんてクソ食らえ。手書きでないことを理由に落とすようなところは端から相手にしないようにした。
こちとら何通も送るつもりなのだ。手書きでは量を送ることが出来ない。
そして、ハロワの求人では、「正社員以外」「登録派遣」「常用型派遣」の方が、「正社員」よりも採用されやすいような気がする。

そうして、私は何とか、月給16万円くらいのお仕事に就くことが出来た。

尤も、初めに言ったとおり、継続して雇用されるかどうかが重要で、少なくとも一年は雇用されなければ雇用保険は出ない。
人間関係が良好なので、このまま最低1年は継続していきたい。

*1:ブランクについて訊かれたとき、私は登録型の派遣の仕事をやっていたと言って誤魔化したが、実のところほとんど何もやっていなかった(Vimプラグインを開発していた)。

*2:これはもしかしたら今度の増税で値上がりするかも知れない

statusline系プラグイン第4の刺客 vim-ezbar

この記事はVim Advent Calendar 2013 40日目の記事です。

statuslineをモダンに改造するプラグインの系譜

そして第4の刺客として、t9md/vim-ezbar が登場しました。
以下、特徴と利用法を解説します。

※ezbarの仕様が変わりました。そのうちこの記事を書き直すかも

[特徴]

lightline.vimとの比較*1、細かく説明すると長くなるので簡潔に述べます。
利点:

  • よりシンプルに設定を記述可能
  • 文脈に合わせての色変更がやりやすい(gitのブランチがmasterでない時は色を変更するなど)
  • 文脈に応じて表示する部品を削除できる(特定プラグインを利用している時にはそれ用の部品以外は表示させないなど)
  • グローバル関数を用意しなくてもいい
  • ctrlp.vimと競合しない

欠点:

  • デフォルト設定はない(設定は作らないといけない)
  • タブライン機能はない
  • カラーテーマはない(基本、色は自分が一から指定する)
  • 部品と色設定との結合が強い
  • 文字列を返すだけの部品ではお手軽さで劣る

向いている人:

  • 色から表示する内容まで細かく指定したい人
  • 簡潔な記述を望む人
  • 文脈に応じてラインの内容を変更したい人

向いていない人:

  • 設定抜きにすぐに使い始めたい人
  • プラグインをなるべくデフォルトで使って満足できる人
  • 複数のカラーテーマを着せ替え気分で使い分けたい人
  • タブラインを利用していて、ステータスラインと同じプラグインタブラインも設定したい人

[実践]

以前 lightline.vimをカスタマイズする という記事を公開しました。そこで作ったステータスラインとほぼ同じ物を vim-ezbar で実現してみます(一部簡略化します)。

let g:ezbar = {'separator_L': '', 'separator_R': ''}

まずこのようにg:ezbar辞書を定義します。separator_L separator_R は部品を区切る区切り文字です。デフォルトでは|で区切られますが、境界をなくしたいので空文字を指定します。

(レイアウト)

どの部品をどのように並べるのかを決めます。
標準で用意されている部品や、新しく部品を登録する方法は後述します。
ちなみにlightline.vimでは部品のことをコンポネントと呼びましたが、ezbarではパートと呼びます。
パートのレイアウトを決めるには2種類のリスト変数g:ezbar.activeg:ezbar.inactive を使います。
g:ezbar.active が現在アクティブなステータスラインに表示される内容。
g:ezbar.inactive非アクティブなステータスラインに表示される内容です。

これらのリストに利用したいパートの名前の文字列を並べていきます。
{'chg_color': <color>}{'__SEP__': <color>} という特殊なパートがあります。
この<color>の部分 にはハイライトグループ名(文字列)を指定するか、

{'gui': [guibg, guifg, gui], 'cterm': [ctermbg, ctermfg, cterm] }

という形の辞書を指定します。この辞書の要素の 'cterm' などは省略可能です。
例えば{'gui': ['green', 'white']} だと、:highlight guibg=green guifg=white になります。

この特殊なパート{'chg_color': <color>}は、挿入した場所から先の g:ezbar.parts.__default_color(色が指定されていないとき使われる色)*2 を変更します。
{'__SEP__': <color>}はstatusline の左側と右側を分け隔てる区切りです。そしてその区切りの色は、指定したものになります。

次のg:ezbar.activeは私が使っているものです。

let g:ezbar.active = [
  \ 'winbufnum',
  \ 'dir',
  \ 'filename',
  \ {'chg_color': {'gui': ['SlateGray', 'white', 'bold']}},
  \ 'filetype',
  \ 'modified',
  \ 'currentfuncrow',
  \ {'__SEP__': 'StatusLine'},
  \ 'cfi',
  \ 'fileformat',
  \ 'encoding',
  \ 'percent',
  \ 'line_col',
  \ ]

途中でchg_color されているので、g:ezbar.parts.__default_colorが変更され、この後のパート('filetype' や 'modified'など)はgui背景色がSlateGray 文字色が白で太字で表示されます。
'currentfuncrow' の後に __SEP__ があるので、ここでステータスラインの左右が分かたれ、間はハイライトグループStatusLineで埋められます。

let g:ezbar.inactive = [
  \ 'winbufnum',
  \ 'dir',
  \ 'filename',
  \ {'chg_color': {'gui': ['SlateGray', 'white']}},
  \ 'filetype',
  \ 'modified',
  \ {'__SEP__': 'StatusLine'},
  \ 'encoding',
  \ 'percent',
  \ 'line_col',
  \ ]

このようにezbarはパートという部品を列挙するだけで簡単にステータスラインを作成できます。
標準のパートは以下のものです。(標準のパートを使うためにはそのための関数を呼ぶ必要があります)

パート 説明
mode ノーマルモードやインサートモードなど、モードの状態を表示
percent 現在バッファの上から何パーセントの場所にいるか表示(なぜかアクティブ時には色が付く)
modified &modifiedされているか
readonly 読み込み専用か
line_col 行と列を表示
line 現在行/総行数
encoding バッファのエンコード
fileformat バッファのfileformat
filetype バッファのfiletype
filename バッファのファイル名
winnr ウィンドウの番号

残りのパートは自分で作って用意します。

(パートの用意)

パートはg:ezbar.partsに登録して用意します。
部品を作るに当たり、他のライン系プラグインと違って、できないことがあります。ですが回避手段も用意されています。
以下のことが出来ません。

  • g:ezbar.partsに登録するのは全て関数です。複雑な処理をせず、ただ文字列だけのパートであっても、一度関数を作ってそれに文字列を返させるという冗長なことをする必要があります。
  • 'statusline' に渡す文字列に %{} (実行されるときの文脈で'%{'と'}'の間の expression を評価し結果に置き換える)を使うことが出来ません
    • 当然%{expand('%')} で現在の文脈のバッファ名を得るなんてことも出来ません。
    • 当然%{winnr()} で現在の文脈のウィンドウ番号を得ることも出来ません。
    • ウィンドウローカル変数やバッファローカル変数%{w:varname} %{b:varname} で参照することも出来ません。

%{} で文脈を得ることの代替として、パート関数には引数に "現在評価中のステータスラインのあるウィンドウの番号" が渡されます。このウィンドウ番号を文脈として、必要な情報を作るようにします。

  • 現在の文脈のバッファ名はbufname(winbufnr(a:n))で得るようにします。
  • ウィンドウ番号は与えられます。
  • 現在の文脈のウィンドウローカル変数やバッファローカル変数getwinvar(a:n, 'varname') getbufvar(winbufnr(a:n), 'varname') で得るようにします。

こういうことをしないと文脈情報を得られなくなったので、冗長になったように思えますが、しかし逆に文脈を取得した後は、関数内でその文脈を使って複雑な処理をすることが可能になりました。つまりこの冗長さはezbarのパワフルさとトレードオフです。
しかもこの文脈をg:ezbar.parts._init()で一度 self 変数に登録してしまえば、以後はどの部品からでも登録した文脈を利用することが出来るので益の方が大きくなります。g:ezbar.parts._init()はステータスラインの評価の開始時に一番始めに実行される関数です。

g:ezbar.partsは、パートを収めた辞書ですが、その中で "_init" と "_filter"*3 というパートは特別な役割を果たします。
g:ezbar.parts._init() は、パート関数の中で一番始めに実行されてこれから各パートで使う変数を用意したり、ステータスラインの状態を変えたりします。
g:ezbar.parts._filter()は、パート関数の中で一番最後に実行されて、各パートのプロパティを書き換えたり、パートそのものをなかったことにすることができます。

では"_init"から"_filter"まで、各パートの中身を書くことにします。
なお、ここではs:uという変数を用意し、最後にs:us:ezbar.partsに統合する方針を採るので、これから出てくるs:uは、最終的にはs:ezbar.partsに統合されると考えて下さい。

let s:u = {}
function! s:u._init(n)
  let self.bufname = bufname(winbufnr(a:n))
  let self.mode = mode()
  if self.__is_active && self.mode==#'i'    "アクティブでインサートモードの時、デフォルト色変更
    let self.__default_color = {'gui': ['DarkKhaki', 'black', 'bold']}
  end
endfunction

前述の通りg:ezbar.parts._init()に渡される引数は評価中ステータスラインのウィンドウ番号です。
現在の文脈のバッファをself.bufnameに代入します。これでこれ以降のパートではself.bufnameでバッファ名を得られるようになりました。
他に、現在のモードによって表示を変更するというのを複数のパートでやりたいのでmode()の結果もself.modeに代入します。

また、self.__is_active は評価中のステータスラインはアクティブかどうかが代入されます。self.__default_colorは、特に色を指定していないパートはこの色になるようにします。評価開始時にはStatusLine StatusLineNCの色がデフォルトになっていますが、途中で変更することが出来ます。変更すると以降のパートでは変更した色が利用されます。
ezbarで使われる色はハイライトグループ名か、{'gui': [guibg, guifg, gui], 'cterm': [ctermbg, ctermfg, cterm] }の形式で指定します。

さて、_init()で準備は整えたのでいよいよパートを作ります。まずはバッファ番号とウィンドウ番号を表す"winbufnum"です。

function! s:u.winbufnum(n)
  return '%n%{repeat(",", winnr())}%<'
endfunction

返り値である文字列がパートになります。

次に現在ウィンドウに表示中のバッファのあるディレクトリを返す"dir"です。

function! s:u.dir(n)
  let bg = self.mode==#'i' ? 'LightSkyBlue1': 'azure' "インサートモードの時文字色変更
  return {'s': '%.35('. fnamemodify(self.bufname, ':h'). '%)',
    \ 'ac': {'gui': [bg, 'black', 'bold']}, 'ic': {'gui': ['azure', 'black']}}
endfunction

"dir" のパート関数で _init() で定義しておいたself.modeself.bufnameを利用しています。
返り値は文字列ではなく辞書を使っています。そうした場合、キー"s" の文字列がパート本体になり、キー"ac"、 "ic"、 "c"でアクティブ時の色、非アクティブ時の色、デフォルトの色を指定することが出来ます。

次の部品は 'filetype' が "vim" のとき、現在カーソル位置が、関数の始まりから何行目なのかを表すものです。

  function! s:u.currentfuncrow(n)
    if &ft != 'vim'
      return ''
    end
    let funcbgn = search('^\s*\<fu\%[nction]\>', 'bcnW', search('^\s*\<endf\%[unction]\>', 'bcnW'))
    if funcbgn > 0
      let row = line('.') - funcbgn
      return row ? {'s': row, 'c': {'gui': ['azure', 'black', 'bold']}} : ''
    endif
    return ''
  endfunction

条件に合わないときには空文字を返しています。パート関数の返り値がempty()だった場合、g:ezbar.parts._filter()が呼ばれる前に除去されて存在しなかったことになります。
こうして文脈に応じてパート自身が自分の色を決めたり、自分が存在するかどうかを決めることが可能です。
g:ezbar.parts._filter()でも色を変更したり、除去したり、出力される文字列を変更したり出来ます。だから気に入らない色は最終的に修正することは可能です。
ただ、g:ezbar.parts._filter()での処理は若干煩雑になるので、出来るならパーツ内で処理を完結させたほうがいいでしょう。

では、tyru/current-func-info.vimという、現在のカーソル位置が関数内にあるときに関数名を返してくれるプラグインがありますが、それを利用する部品を作ります。

function! s:u.cfi(n)
  if exists('*cfi#format')
    return {'s': cfi#format('%.43s()', ''), 'c': {'gui': ['azure', 'black', 'bold']}}
  end
  return ''
endfunction

これで自分で作るパートは"_filter"を除いて揃いました。最後に標準で用意されているパートを統合します。*4

call extend(s:u, ezbar#parts#default#new(), 'keep')

(最終処理)

g:ezbar.parts._filter()で最終処理を行います。
自分で作ったパートはすでに色を設定したり文脈に応じた処理を施しましたが、標準で用意されているパートには何の手も加えていません。
そこで、最後にカスタマイズします。
g:ezbar.parts._filter()に渡される引数は今までのパートのものと違います。
引数は2つ。各パートをg:ezbar.active g:ezbar.inactiveの順に並べたリストである layout と、各パートを収めた辞書 parts です。
全てのパートは辞書化されています。文字列で返したパートも辞書化されて、キー"c" には、そのときのself.__default_colorがセットされています。また、新しく "name" というキーも作られ、それにパート名が収められています。
リストlayoutと、辞書parts、どちらにも要素にはパートが収められていて同じ物を参照しています。a:layout[0]a:parts.winbufnum でどちらでも"winbufnum"パートにアクセスできます。
これの使い分けはpartsが個のパートを直接修正するときに利用し、layout特定のパートを除去するのに使います。各パートに追加されたキー"name"はパートをフィルタリングするのに使えます。(しかし今回は使いません。)
処理を追えたら最後にlayoutを返します。

function! s:u._filter(layout, parts)
  if self.mode == 'i'
    let a:parts.__SEP__.ac = {'gui': ['DarkKhaki', 'black', 'bold']}
  end
  if has_key(a:parts, 'filename')
    let a:parts.filename.ac = {'gui': [(self.mode==#'i' ? 'RosyBrown1': 'MistyRose'), 'black', 'bold']}
    let a:parts.filename.ic = {'gui': ['MistyRose', 'black']}
  end
  call extend(a:parts.percent, {'ac': {'gui': ['MistyRose', 'black', 'bold']}, 'c': {'gui': ['MistyRose', 'black']}})
  call extend(a:parts.line_col, {'ac': {'gui': ['NavajoWhite1', 'black', 'bold']}, 'c': {'gui': ['NavajoWhite1', 'black']}})
  return a:layout
endfunction

2行目でa:parts.__SEP__にキー"ac" を追加しています。__SEP__もパートです。*5
インサートモードの時、アクティブウィンドウのステータスラインのセパレータ色を変更するようにしました。
4行目でfilenameがあるかどうかを確認しているのは、無名バッファを開いたときにはfilenameは空文字になるため、除去されて存在しなくなるからです。
今回は色の変更にしか使っていませんが、g:ezbar.parts._filter()では文脈に応じて高度なことも出来るようです。

(完成)

s:ug:ezbar.partsに代入して完成です。

let g:ezbar.parts = s:u
unlet s:u

f:id:leafcage:20140109172118p:plain

ミニマリスト向けと銘打っているとおり、シンプルな設定でステータスラインを実現できました。

[アフターケア]

どこかの表記がおかしくてエラーが発生すると抜けられなくなります。そんなときには:EzBarDisableコマンドでezbarを無効にしてから対処しましょう。

色の選択には vim-ezbar/misc/colortest/compact.vimvim-ezbar/misc/colortest/full.vim を開いて :so %すると、とても見やすい色一覧が表示されます(素晴らしいです。ezbar以外でも利用できそうですね)。

f:id:leafcage:20140109172212p:plain

vim-ezbar/README-JP.mdに制作者による解説が、
vim-ezbar/misc/config_sampleに設定例が掲載されています。

*1:他のline系プラグインは使ったことがないので

*2:標準では__default_colorにはアクティブウィンドウでは StatusLine 非アクティブウィンドウでは StatusLineNC のハイライトグループが使わます

*3:将来的に_finishという名前に変更される可能性があるそうです

*4:もし全ての部品を自前で用意するのなら、この処理は必要ありません

*5:'chg_color'はパートではありません

yankround.vimがunite.vimでの履歴の閲覧に対応しました。

LeafCage/yankround.vim

:Unite yankround

これでShougo/unite.vimレジスタの履歴を閲覧できます。
出来ることはunite-source-history/yankとほぼ同じです。(参考にさせていただきました。Shougoさんありがとうございます。)

kien/ctrlp.vimと比較すると、unite.vimでの閲覧は一覧性に優れています。
ctrlp.vimで履歴を一覧するには、何も入力されていない状態で、<C-j> <C-k>で1行ずつスクロールするか、<PageUp> <PageDown>というvimmerにとっては苦行に近いキーによってページスクロールするしかありませんでした。
その点、unite.vimでは通常のVimの操作でスクロールして一覧できます。

もちろん、ctrlp.vimにも利点はあります。速度はctrlp.vimが優れています。*1
インターフェイスについては好みが分かれるところですが、ご自分の使いやすいインターフェイスを選んでお使い下さい。

*1:ctrlp.vimのインターフェイスは絞り込みに特化しているので挿入したい候補が決まっているときに使うと良いでしょう。

yankround.vimにリージョンハイライト機能が付きました

  let g:yankround_use_region_hl = 1

で有効になります。*1
有効にするとyankroundが有効な間、貼り付けたテキストがハイライトされるようになります。
<C-p> <C-n> で回したテキストもです。

g:yankround_region_hl_groupname でハイライトに使うグループを指定できます。
既定の設定は以下のような感じになっています。

let g:yankround_region_hl_groupname = 'YankRoundRegion'

autocmd ColorScheme *   call s:define_region_hl()
function! s:define_region_hl()
  if &bg=='dark'
    highlight default YankRoundRegion   guibg=Brown ctermbg=Brown term=reverse
  else
    highlight default YankRoundRegion   guibg=LightRed ctermbg=LightRed term=reverse
  end
endfunction

動作画面(貼り付けた部分がハイライトされている)

f:id:leafcage:20131211191702p:plain

まだ挙動に謎な部分がありますが、主要なバグは取り除けたと思います。

*1:t9mdさんのプルリクです。ありがとうございます。

Vimコマンドラインのキーマッピングを改造するプラグイン作りました。

LeafCage/cmdlineplus.vim

提供している機能は、単語単位の移動、Emacsライクなキル、特定キャラクタのエスケープ、レジスタクリップボードに現在のコマンドラインの内容をセットする、以上になります。

lastmess.vimで表示されるメッセージのハイライトをいろいろ定義できるようにした。

メッセージの開始と、メッセージの中身の色を定義できるようにした

g:lastmess_highlight_errstartg:lastmess_highlight_errcontentsを指定することで、
エラーの開始点と内容が色分けされてこのようにエラーメッセージが見やすくなります。
(デフォルトでエラーの中身は"PreProc"のハイライトを使うように変更されました。)

f:id:leafcage:20131205005439p:plain

(あっ比較のために更新前の画像もキャプっとけばよかった。このE716:とかE15:という行は今までならエラー開始点と同じく、"ErrorMsg"でハイライトされていたのですよ。それを"PreProc"にしたことで1つのエラーのメッセージがどこまで続いているのかが視覚的に判別しやすくなったわけです。)

ユーザが指定したパターンにマッチしたメッセージの色に指定したハイライトを使うようにした

g:lastmess_special_highlightを使います。
これは[{hilight-group-name}, {pattern}]というリストを収めたリスト(つまりリストが入れ子になったリスト)です。
次のように使います。

let g:lastmess_special_highlight = [['MoreMsg', '^sourced:']]

これで'^sourced:'にマッチするメッセージにMoreMsgのハイライトが利用されます。

蛇足、便利な設定

あと、次のように無視したいメッセージパターンを登録しておくと、ノイズがなくなって便利です。

let g:lastmess_ignore_pattern = 'スキャン中\|検索したので\|箇所変更しました;\|行 削除しました;\|行 追加しました\|\d\+L, \d\+C$\|行 --\d\+%--$\|--バッファに行がありません--$\|既に一番新しい変更です\|^\s*\d\+:\s\%(\~\|\u:\)/'

また、次のように、メッセージクリアコマンドを使えるようにしておくと捗ります。

command! MessageClear for n in range(200) | echom "" | endfor| ec 'Cleared Message'
nnoremap mc :<C-u>MessageClear<CR>

コマンドラインで :b を実行するときにバッファリストを表示する

Vim - hjklマスターに薦める意外と便利な機能 - Qiita [キータ]
バッファを選択する際に、同時にリストを表示する

nnoremap B :ls<CR>:b 

という設定を見て閃いた。

cnoreabb <expr>b getcmdtype()==':' && getcmdline()=='b' ? 'ls<CR>:b' : 'b'

こうすればコマンドラインで:bを打ってから<Space>キーを打つと勝手に:lsが表示されるようになる。