unite.vim で vim-pukiwiki の検索をする その 2

  1. unite.vim で vim-pukiwiki の検索をする その 1 - vim 初心者の作業メモ
  2. unite.vim で vim-pukiwiki の検索をする その 2 - vim 初心者の作業メモ
  3. unite.vim で vim-pukiwiki の検索をする その 3 - vim 初心者の作業メモ
  4. unite.vim で vim-pukiwiki の検索をする その 4 - vim 初心者の作業メモ

unite.vim 標準の source process を理解する

動作を理解する.

process -- Nominates processes.
Note: This source is required "ps" command or "tasklist" command(in Windows).


":Unite process" すると以下の一覧がでた

Sources: process (161/161)
[process] USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
> 
-       root         1  0.0  0.0   2768  1700 ?        Ss   Nov15   0:03 /sbin/init                                                                
-       root         2  0.0  0.0      0     0 ?        S    Nov15   0:00 [kthreadd]                             
-       root         3  0.0  0.0      0     0 ?        S    Nov15   0:00 [migration/0]                                                            
-       root         4  0.0  0.0      0     0 ?        S    Nov15   0:01 [ksoftirqd/0]                
... (略)

"ps aux" の実行結果

> ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0   2768  1700 ?        Ss   Nov15   0:03 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Nov15   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Nov15   0:00 [migration/0]
... (略)


":Unite process" 後にプロセスを選択して TAB を押す.

[action] default_action: sigterm
>
- delete               -- send KILL signal to processes
- echo                 -- echo candidates for debug
- ex                   -- insert candidates into command line
- insert               -- insert word or text
- insert_directory     -- insert directory
- preview              -- preview word
- sigkill              -- send KILL signal to processes
- sigterm              -- send TERM signal to processes
- yank                 -- yank word or text
- yank_escape          -- yank escaped word or text
  • デフォルトの action は sigterm に設定されている.
  • sigkill/sigterm は追加された action.
  • delete が "KILL" になっている.

ソースを読む (unix ルートのみ)

function! unite#sources#process#define()"{{{
  return executable('ps') ? s:source : {}
endfunction"}}}
  • ps コマンドがある場合のみ, source を登録する.
let s:source = {
      \ 'name' : 'process',
      \ 'description' : 'candidates from processes',
      \ 'default_action' : 'sigterm',
      \ 'action_table' : {},
      \ 'alias_table' : { 'delete' : 'sigkill' },
      \ }
  • source 名は process
  • kind は指定されていないので common
  • デフォルトの動作は sigterm.
  • alias_table で 'delete' のときの動作を sigkill に置き換えている
  • action_table はここでは何も設定していない
function! s:source.gather_candidates(args, context)"{{{
" Get process list.
  let _ = []

  " 'ps aux' の結果を result に保存し, 1 行ずつの文字列のリストに保存
  let result = split(vimproc#system('ps aux'), '\n')
  if empty(result)
    return []
  endif

  let [message_linenr, start_result, min_len] = [0, 1, 2]

  " ここは unite 上で単にメッセージを表示するだけ.
  " 実行結果の 2 行目.
  call unite#print_source_message(result[message_linenr], s:source.name)

  " 各行ごとに処理していく
  for line in result[start_result :]
    " タブか空行とかで分ける.
    let process = split(line)
    if len(process) < min_len
" Invalid output.
      " きっと 2 文字以下の場合は何かエラーなんでしょう.
      continue
    endif

    call add(_, {
  " USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  " root         1  0.0  0.0   2768  1700 ?        Ss   Nov15   0:03 /sbin/init
          " process[10:] は COMMAND 以降か?
          \ 'word' : join(process[10:]),
          \ 'abbr' : ' ' . line,
          " process[1] は PID.
          \ 'action__pid' : process[1],
          \})
  endfor

  return _
endfunction"}}}

候補の一覧を作っているだけだった. action_table がこの source のキモか.

" Actions"{{{
let s:source.action_table.sigkill = {
      \ 'description' : 'send KILL signal to processes',
      \ 'is_invalidate_cache' : 1,
      \ 'is_quit' : 0,
      \ 'is_selectable' : 1,
      \ }
" 
function! s:source.action_table.sigkill.func(candidates)"{{{
  for candidate in a:candidates
    call unite#util#system(printf('kill %s %d', '-KILL', candidate.action__pid))
  endfor
endfunction"}}}
  • action_table は |unite-kind-attribute-action_table| を参照
    • func に action 実行時に呼び出される関数を定義する.
let s:source.action_table.unite__new_candidate = {
      \ 'description' : 'create new process',
      \ 'is_invalidate_cache' : 1,
      \ 'is_quit' : 0,
      \ }
function! s:source.action_table.unite__new_candidate.func(candidate)"{{{
  let cmdline = input('Please input command args : ', '', 'shellcmd')
  call system(cmdline . ' &')
endfunction"}}}
  • これはなんだろう...?

Note: If name is "unite__new_candidate", it will be
used for |(unite_new_candidate)|. It adds a
candidate in current source.

  • Unite のバッファで 'N' すると, 呼び出される. 新しいプロセスの起動, だそうな.
  • [2012/11/19 追記]

Shougo
unite.vimのインタフェースからsourceの候補を生成するときに呼び出される特殊なアクションです

http://lingr.com/room/vim/archives/2012/11/18

気になったこと

  • デフォルトの動作が確認なしで KILL は危険な気がする.
  • 権限がないプロセスに対して KILL してもエラーメッセージは何もでない.
  • SIGTERM があって, SIGINT がないのはなんでだろ.
  • [2012/11/19 追記] 修正されました

Github
[vimproc/master] - Improved vimproc#get_last_errmsg(). - Shougo Matsushita : https://github.com/Shougo/vimproc/compare/419bb2e57b2e...961b044408fb
[unite.vim/master] - Improved process source. - Shougo Matsushita : https://github.com/Shougo/unite.vim/compare/7b40c9ce1060...bae05a969870

Shougo
> デフォルトの動作が確認なしで KILL は危険な気がする.
>権限がないプロセスに対して KILL してもエラーメッセージは何もでない.
>SIGTERM があって, SIGINT がないのはなんでだろ.
確認を追加しました
エラー時はエラーメッセージを出すようにしました。
ただし、vimprocを使用していないとメッセージは出ないと思われます