cafegale(LeafCage備忘録)

LeafCage備忘録(はてなダイアリー)と統一しました。

正直しんどいです。

今月頭からニート脱出したんですが、正直肩書きだけ社員で、やることはアルバイトと変わらないような、低レイヤーの仕事です。
夢や希望で仕事をしているのではなく、ただ必要性からやってるだけあって、緩やかに苦痛です。
数年続けても鬱になるほど苦痛ではないですが、半月足らずでしんどさが否めません。

接客業なのですが、コミュ力不足が日々身にしみます。
接客だけでなく、従業員との会話も。

前職はいわゆるSIでした。あそこは数年続けていたら鬱になっていたかも知れません。
4ヶ月目に首にさせられた形とは言え、半分は身の危険を感じて自分から脱出したようなものでした。
入社後1ヶ月で、以前凍結されていたプロジェクトの再開発(二次開発)のプロジェクトに参加することになりましたが、そのシステムのコードは、私は素人ですが、for文が4つネストしていたり変数名やメソッド名がコード番号だったりして、私から見ても酷いコードでした。*1
部品の一つを解読するだけで一日がかりで、少し修正するだけでも上司のレビューが必要で、誰も試用を把握しておらず、試用を一番把握している前PMは鬱病にかかってしまいました。
そのプロジェクトは今年3月に納品の筈ですが、今頃大炎上していると予想します(恐らく納期を先延ばしにしているでしょうが、碌なものは出来上がらないでしょう)。
そして私は、大阪でのプログラマのお仕事はこんなものなのかと絶望し、プログラマ以外の道を模索し始めたのでした。*2

それに比べたら、今の仕事は救いはあります。しかし、面白くはありません。
お客様と面と向かうのはすごくプレッシャーがかかりますし、私はプレッシャーにすごく弱いことが分かりました。
ただでさえ頭の回転が悪いのに、お客様と面しているときの私の脳は、小学生低学年並みの知能レベルにまで低下していて、普通なら気付くことにすら全く気付かないほどに鈍感になっています。

私は自分のやりたいことにかまけて今まで彼女を作ったことがなかったのですが、コミュ力のためだけに彼女を作っておくべきだと後悔しました。彼女を作って、色々とコミュニケーションで失敗をして、学習しておくべきなのでした。
私の家には会話と言えるものがありません。そして私はほとんど友達を作ったことがなかったので、未だ会話というものを全く学んでいないのです。

今のお仕事で、深い鬱になることはないでしょうけれど、コミュ力不足による自己嫌悪はこれから絶えず直面するでしょう。
いえ、どこのお仕事に行っても、私が今の私である限りはこれは直面することです。

*1:この程度の作品でン千万取れるという文化に驚きました

*2:IT系の有名企業は東京に多いですから幸せなプログラマは東京に行くのかも知れません

ニート脱出できたっぽい

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

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

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

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

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

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

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

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

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

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

オペレータにはテキストオブジェクトだけでなく:コマンドも渡せる

clever-f.vim 読書会にて

thinca
> > .のリピート対応
> 僕も分かっていないので,thinca さんに教えてもらえるとうれしい.
えーと、これは

thinca
この場合の repeat ってのはそもそも motion のリピートで
dfx とかしたときに . するとまた dfx みたいな動作をする

thinca
で、この motion 的な部分は omap と同じ位置で

thinca
omap で : コマンドを実行すると、repeat 時にも前回と同じ : コマンドが呼ばれる
説明むずい

thinca
えーと、例えば、 d:call search('foo') とかすると、search() で探した位置まで削除される

thinca
. を押すと、まったく同じコマンドが実行され(=関数が呼ばれ)、同じような動作をする

manga_osyo

こんな書き方できたのか

haya14busa
clever-fだとそれが d:call clever_f#find(map, char)になるってことかな

thinca
なので、operator pending mode で clever-f が呼ばれたら、「次の位置まで移動する」関数を呼べばよい
そんな感じです

http://lingr.com/room/vim/archives/2014/01/11#message-18046333

Vimの関数がどのバージョンで追加されたのか調べる

itchyny
関数がどのパッチで追加されたかってみんなどうやって調べてるんだろう.

http://lingr.com/room/vim/archives/2014/01/10#message-18034846

manga_osyo
わたしは version7.3 とかから
探してきているなー
:help version7.3

http://lingr.com/room/vim/archives/2014/01/10#message-18034854

itchyny
おお 便利. ありがとうございます.

http://lingr.com/room/vim/archives/2014/01/10#message-18034865

manga_osyo
:help fixed-7.3
こっちの方が見やすいか

http://lingr.com/room/vim/archives/2014/01/10#message-18034874

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'はパートではありません

uniteの標準actionで利用できるcandidateのaction__{name}要素

@Linda_pp @kaoriya ワーイ。あと action__codic_word ではなくて action__text に設定すれば insert_codic_word ではなくて unite.vim のinsert アクションがそのまま流用できると思います。

https://twitter.com/osyo_memo/status/419499833653608448

uniteの標準アクションinsertには他にも action__regtype でレジスタのタイプを指定できるし、まだ隠された利用できる要素が存在しそう。

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のインターフェイスは絞り込みに特化しているので挿入したい候補が決まっているときに使うと良いでしょう。