Show
Ignore:
Timestamp:
02/02/08 18:24:37 (5 years ago)
Author:
kana
Message:

dotfiles/vim/kana:
* Merge the following changes:

r392@colinux (orig r823): kana | 2008-01-31 02:06:55 +0900

vim/dot.vim/autoload/ku.vim:

  • Add type() values as constants and modify to use them.

r393@colinux (orig r824): kana | 2008-01-31 02:23:50 +0900

vim/dot.vim/autoload/vcsi.vim:

  • s:normalize_items(): Fix the bug that '-' will be expanded to wrong name.

r397@colinux (orig r825): kana | 2008-01-31 21:27:58 +0900

vim/dot.vim/autoload/ku.vim:

  • s:choose_action_for_item():
    • Rename from s:choose_action().
    • Separate messaging part as s:show_available_actions_message().
  • s:show_available_actions_message():
    • New, from s:choose_action_for_item().
    • Revise the style of message (multi column).

r398@colinux (orig r826): kana | 2008-01-31 21:38:34 +0900

vim/dot.vim/autoload/ku.vim:

  • s:apply(), s:pa(), s:callable_p():
    • New, and modify to use these for action.function.
  • s:make_asis_regexp():
    • Normalize spaces.
  • type buffer:
    • Add actions with direction modifier.
  • type file:
    • Add actions with direction modifier.

r399@colinux (orig r827): kana | 2008-02-01 00:19:01 +0900

vim/dot.vimrc:

  • Key Mappings / Misc.:
    • g/: New.

r400@colinux (orig r828): kana | 2008-02-01 03:12:59 +0900

vim/dot.vim/autoload/ku.vim:

  • type file: s:_type_file_gather():
    • Implement, not stub, functional one with some faults.

r401@colinux (orig r829): kana | 2008-02-01 04:09:54 +0900

vim/dot.vim/autoload/ku.vim:

  • ku#start():
    • Modify to call type.initialize().
  • s:valid_type_definition_p():
    • Add check for 'initialize'.
  • s:valid_type_definition_p():
    • Add check for 'initialize'.
  • type file:
    • Modify to do simple chaching.

r414@colinux (orig r830): kana | 2008-02-02 01:42:13 +0900

vim/dot.vim/autoload/ku.vim:

  • s:make_skip_regexp():
    • Modify to treat path separators as special ones.

r415@colinux (orig r831): kana | 2008-02-02 01:42:31 +0900

vim/dot.vim/autoload/ku.vim:

  • s:valid_type_definition_p():
    • Fix some comments.

vim/dot.vim/doc/ku.txt:

  • Update document for the current state.

r416@colinux (orig r832): kana | 2008-02-02 01:42:49 +0900

vim/dot.vim/autoload/ku.vim:

  • Revise some commments.

r417@colinux (orig r833): kana | 2008-02-02 01:43:03 +0900

vim/dot.vim/autoload/ku.vim:

  • s:string():
    • New, for further changes and to express it by the code.

r419@colinux (orig r835): kana | 2008-02-02 03:24:22 +0900

vim/dot.vim/autoload/ku.vim:

  • type buffer:
    • 'gather': Check the validity of the cache even if the number of buffers is
      not changed.
    • 'actions': Add unload, delete and wipeout.

r420@colinux (orig r836): kana | 2008-02-02 10:00:43 +0900

vim/dot.vim/autoload/ku.vim:

  • Add some FIXMEs.

vim/dot.vim/doc/ku.txt:

  • :Ku: Revise the description of {preferred-type}.

r425@colinux (orig r838): kana | 2008-02-02 18:17:02 +0900

vim/dot.vimrc:

  • Utilities / CMapABC:
    • Add a note on another way to implement.
Files:
1 modified

Legend:

Unmodified
Added
Removed
  • dotfiles/vim/kana/dot.vim/autoload/ku.vim

    r5824 r6039  
    44" License: MIT license (see <http://www.opensource.org/licenses/mit-license>) 
    55" $Id$  "{{{1 
    6 " FIXME: Translate the following FIXMEs in English. 
    7 " 
    8 " FIXME: ドキュメント更新。 
    9 " 
    10 " FIXME: s:do(): どのitemにもマッチしない入力であってもactionに渡す。 
    11 "   例えば今の状況ではtype fileで新規ファイルを開けないので、 
    12 "   このような処理は必要である。 
    13 " 
    14 "   ただし、これをするならばどのtypeのactionを使うかが問題。 
    15 "   s:preferred_typeが定義されている場合に限定か。 
    16 " 
    17 " FIXME: より「賢い」ソーティング (優先順位: 低) 
    18 "   - パスっぽいものは最後のコンポーネントを重視するのはどうか? 
    19 "   - type buffer: フルパスと相対パスのどちらを使うべきか? 
    20 "   - パスっぽいものは相対パス優先の方がいい? 
    21 "     '/'の値は若い以上、今のままでは自動的に相対パスが軽視されることになる。 
    22 " 
    23 " FIXME: strtrans()の代替作成。<Left>等を正しく変換するように。 
    24 " 
    25 " FIXME: type file - stub. 
    26 " FIXME: type directory - NIY. 
    27 " 
    28 " FIXME: 各種比較でのcase sensitivityの統一・見直し。 
    29 " 
    30 " FIXME: 実装方法の選択 
    31 "   (A) ins-completion-menuを利用(Omni completion) 
    32 "       + Insert modeの基本的な操作体系を利用可能。 
    33 "       - 一部キーをmappingできないため、細かい情報を取れない。 
    34 "         * 特に問題な点は 
    35 "           「どの項目が選択されているか」と 
    36 "           「選択状況が変化したか」を 
    37 "           知ることができないこと。 
    38 "           * このために 
    39 "             「actionを<Tab>で選んで実行」というI/Fや、 
    40 "             「利用可能なactionを適宜表示」ということができない。 
    41 "       - CursorMovedIのフックを利用しての検出のため、カオス過ぎる。 
    42 "         特にs:PROMPTはひどい発明。 
    43 " 
    44 "   (B) getchar()で自力管理 
    45 "       + キー入力を全て把握できるため、ins-completion-menuの問題はない。 
    46 "       - キー入力を自力で管理する以上、 
    47 "         基本的な操作体系も含めて実装しなければならない。 
    48 "       * itemsの一覧表示はins-completion-menu以外の方法が取れる。 
    49 "         例えばtype毎に並べたitemsのうち、 
    50 "         preferred以外はfoldする等。 
    51 " 
    52 "   buffuzzy/zapitの経験から(A)を利用していたが、 
    53 "   itemsの表示はバッファを使ってどうとでもできるので、 
    54 "   (B)も一考の価値はある。 
    55 " 
    56 "   ただ、(A)でもある程度の問題は解決してしまったため、一先ずは(A)で行く。 
    57 "   (B)には(B)で魅力的なメリットがあるので、落ち着いたらそちらも考える。 
     6" FIXME: auto-complete 1 component for each typing '/' (like bluewind). 
     7" FIXME: s:do(): Force action on unmatched pattern. 
     8" FIXME: more smart sorting: 
     9"        - considering last component. 
     10"        - type buffer: full path vs. relative path. 
     11" FIXME: review on case sensitivity. 
     12" FIXME: alternative implementation (getchar()), if necessary. 
    5813" 
    5914" Variables and Constants  "{{{1 
     
    6116let s:FALSE = 0 
    6217let s:TRUE = !s:FALSE 
     18 
     19let s:TYPE_NUMBER = type(0) 
     20let s:TYPE_STRING = type('') 
     21let s:TYPE_FUNCTION = type(function('function')) 
     22let s:TYPE_LIST = type([]) 
     23let s:TYPE_DICTONARY = type({}) 
     24 
    6325 
    6426" Flag which indicates whether the ku window is opened with bang (:Ku!). 
     
    143105  2 wincmd _ 
    144106 
     107  " Do some initialization for each type. 
     108  for type_name in keys(s:types) 
     109    call s:types[type_name].initialize() 
     110  endfor 
     111 
    145112  " Start Insert mode. 
    146113  % delete _ 
     
    168135  if !s:valid_type_definition_p(a:args) 
    169136    echohl ErrorMsg 
    170     echomsg 'Invalid type definition:' strtrans(a:args) 
     137    echomsg 'Invalid type definition:' string(a:args) 
    171138    echohl None 
    172139    return s:FALSE 
     
    289256 
    290257  " Do the specified aciton. 
    291   if type(item) != type('') 
     258  if type(item) == s:TYPE_DICTONARY 
    292259    let ActionFunction = (a:choose_p 
    293       \                   ? s:choose_action(item._ku_type.actions) 
     260      \                   ? s:choose_action_for_item(item) 
    294261      \                   : item._ku_type.actions[0].function) 
    295     call ActionFunction(item) 
     262    call s:apply(ActionFunction, [item]) 
    296263  endif 
    297264endfunction 
     
    365332function! s:nop(...)  "{{{2 
    366333  return 
     334endfunction 
     335 
     336 
     337 
     338 
     339function! s:string(s)  "{{{2 
     340  " like strtrans(), but convert into more human-readable notation on special 
     341  " keys such as <Left>. 
     342  return strtrans(a:s)  " FIXME: NIY. 
    367343endfunction 
    368344 
     
    477453function! s:make_asis_regexp(s)  "{{{2 
    478454  " FIXME: case sensitivity 
    479   return '\c\V' . substitute(a:s, '\', '\\', 'g') 
     455  return '\c\V' . substitute(substitute(a:s, '\s\+', ' ', 'g'), '\', '\\', 'g') 
    480456endfunction 
    481457 
     
    485461function! s:make_skip_regexp(s)  "{{{2 
    486462  " FIXME: case sensitivity 
    487   return substitute(s:make_asis_regexp(a:s), '\s', '\\.\\*', 'g') 
     463  " FIXME: path separator assumption 
     464  let p_asis = s:make_asis_regexp(substitute(a:s, '/', ' / ', 'g')) 
     465  return substitute(p_asis, '\s', '\\.\\*', 'g') 
    488466endfunction 
    489467 
     
    543521 
    544522 
    545 function! s:choose_action(actions)  "{{{2 
    546   " FIXME: style of the menu message. 
    547   echo 'Available actions are:' 
    548   for action in a:actions 
    549     echo printf('%s :: %s', strtrans(action.key), action.name) 
    550   endfor 
    551   echo '' 
     523function! s:choose_action_for_item(item)  "{{{2 
     524  let actions = a:item._ku_type.actions 
     525  call s:show_available_actions_message(a:item) 
    552526 
    553527  let c = nr2char(getchar()) 
    554528  redraw  " clear the menu message lines to avoid hit-enter prompt. 
    555529 
    556   for action in a:actions 
     530  for action in actions 
    557531    if c ==# action.key 
    558532      return action.function 
     
    560534  endfor 
    561535 
    562   echo 'The key' strtrans(c) 'is not associated with any action' 
     536  echo 'The key' s:string(c) 'is not associated with any action' 
    563537     \ '-- nothing happened.' 
    564538  return function('s:nop') 
     539endfunction 
     540 
     541 
     542 
     543 
     544function! s:show_available_actions_message(item)  "{{{2 
     545  " FIXME: like ls(1). 
     546  let actions = a:item._ku_type.actions 
     547  let max_key_length = max(map(copy(actions), 'len(s:string(v:val.key))')) 
     548  let max_name_length = max(map(copy(actions), 'len(v:val.name)')) 
     549  let padding = 3 
     550  let max_cell_length = max_key_length + 3 + max_name_length + padding 
     551  let format = '%*s%*s - %-*s' 
     552 
     553  let max_column = max([1, (&columns + padding - 1) / max_cell_length]) 
     554  let max_column = min([max_column, 4]) 
     555  let n = len(actions) 
     556  let max_row = n / max_column + (n % max_column != 0) 
     557 
     558  echo printf('Available actions for %s (type %s) are:', 
     559     \        a:item.word, a:item._ku_type.name) 
     560  for r in range(max_row) 
     561    let i = r 
     562    echo '' 
     563    while i < n 
     564      echon printf(format, 
     565          \        (i == r ? 0 : padding), '', 
     566          \        max_key_length, s:string(actions[i].key), 
     567          \        max_name_length, actions[i].name) 
     568      let i += max_row 
     569    endwhile 
     570  endfor 
     571  echo '' 
    565572endfunction 
    566573 
     
    581588 
    582589function! s:valid_type_definition_p(args)  "{{{2 
    583   let T_NUM = type(0) 
    584   let T_STR = type('') 
    585   let T_FUNC = type(function('function')) 
    586   let T_LIST = type([]) 
    587   let T_DICT = type({}) 
    588  
    589   if type(a:args) != T_DICT 
     590  if type(a:args) != s:TYPE_DICTONARY 
    590591    return s:FALSE 
    591592  endif 
    592593 
    593594  " -- The name of this type. 
    594   if !s:has_valid_entry(a:args, 'name', T_STR) | return s:FALSE | endif 
     595  if !s:has_valid_entry(a:args, 'name', s:TYPE_STRING) | return s:FALSE | endif 
    595596  if !(a:args.name =~# '^[a-z]\+$') | return s:FALSE | endif 
    596597 
     
    604605  " 'name'      The name of the action. 
    605606  " 'function'  The function of the action.  It is called with one parameter, 
    606   "             the selected item (as described in :help complete-items). 
    607   if !s:has_valid_entry(a:args, 'actions', T_LIST) | return s:FALSE | endif 
     607  "             the selected item (as described in |complete-items|). 
     608  if !s:has_valid_entry(a:args,'actions',s:TYPE_LIST) | return s:FALSE | endif 
    608609  if !(1 <= len(a:args.actions)) | return s:FALSE | endif 
    609610  for v in a:args.actions 
    610     if !s:has_valid_entry(v, 'key', T_STR) | return s:FALSE | endif 
    611     if !s:has_valid_entry(v, 'name', T_STR) | return s:FALSE | endif 
    612     if !s:has_valid_entry(v, 'function', T_FUNC) | return s:FALSE | endif 
     611    if !s:has_valid_entry(v, 'key', s:TYPE_STRING) | return s:FALSE | endif 
     612    if !s:has_valid_entry(v, 'name', s:TYPE_STRING) | return s:FALSE | endif 
     613    if !(has_key(v, 'function') && s:callable_p(v.function)) 
     614      return s:FALSE 
     615    endif 
    613616  endfor 
    614617 
    615618  " -- Function to gather items which match to the given pattern. 
    616619  " It takes 1 argument (user input pattern). 
    617   " It returns a list of items.  Each item is a string. 
    618   if !s:has_valid_entry(a:args, 'gather', T_FUNC) | return s:FALSE | endif 
    619  
    620   " FIXME: other entries. 
     620  " It returns a list of items.  Each item is a |complete-items|. 
     621  if !s:has_valid_entry(a:args,'gather',s:TYPE_FUNCTION) |return s:FALSE |endif 
     622 
     623  " -- Function to initialize some information of 'gather'. 
     624  " It will be called with no argument. 
     625  " Its returning value will be discarded. 
     626  " This entry may be missing, if so, nothing will be happened on 
     627  " initialization. 
     628  if has_key(a:args, 'initialize') 
     629    if !(type(a:args.initialize) == s:TYPE_FUNCTION) | return s:FALSE | endif 
     630  else 
     631    let a:args.initialize = function('s:nop') 
     632  endif 
     633 
     634  " -- other entries -- 
     635 
    621636  return s:TRUE 
    622637endfunction 
     
    632647 
    633648 
     649function! s:callable_p(obj)  "{{{2 
     650  return (type(a:obj) == s:TYPE_FUNCTION) 
     651       \ || ((type(a:obj) == s:TYPE_DICTONARY) && has_key(a:obj, '__call__')) 
     652endfunction 
     653 
     654 
     655 
     656 
     657function! s:apply(obj, args)  "{{{2 
     658  if type(a:obj) == s:TYPE_FUNCTION 
     659    return call(a:obj, a:args) 
     660  elseif type(a:obj) == s:TYPE_DICTONARY && has_key(a:obj, '__call__') 
     661    return call(a:obj.__call__, a:args, a:obj) 
     662  else 
     663    throw 'This object is not callable:' string(a:obj) 
     664  endif 
     665endfunction 
     666 
     667 
     668 
     669 
     670function! s:pa(f, ...)  "{{{2 
     671  " pa = Partial Apply 
     672  " Returns a callable object g, 
     673  " where g(b, ...) is equivalent to f(a, ..., b, ...). 
     674  let g = {} 
     675  let g.f = a:f 
     676  let g.args = copy(a:000)  " a:000 will be lost after this execution. 
     677  function! g.__call__(...) 
     678    return call(self.f, self.args + a:000) 
     679  endfunction 
     680  return g 
     681endfunction 
     682 
     683 
     684 
     685 
    634686 
    635687 
     
    638690" Built-in Types  "{{{1 
    639691" buffer  "{{{2 
     692" FIXME: how about unlisted buffers? 
    640693let s:_type_buffer_cached_items = [] 
    641694let s:_type_buffer_last_bufnr = s:INVALID_BUFNR 
    642695function! s:_type_buffer_gather(pattern) 
    643   if s:_type_buffer_last_bufnr != bufnr('$') 
     696  if s:_type_buffer_last_bufnr == bufnr('$') 
     697    call filter(s:_type_buffer_cached_items, 'bufexists(v:val._buffer_number)') 
     698  else 
    644699    let s:_type_buffer_cached_items = [] 
    645700    let format = 'buffer %' . len(bufnr('$')) . 'd' 
     
    664719  execute a:item._buffer_number 'buffer'.ku#bang() 
    665720endfunction 
    666 function! s:_type_buffer_action_split_open(item) 
    667   execute a:item._buffer_number 'sbuffer' 
    668 endfunction 
    669 function! s:_type_buffer_action_vsplit_open(item) 
    670   execute 'vertical' a:item._buffer_number 'sbuffer' 
    671 endfunction 
    672  
    673  
    674 " FIXME: other variants: hjkl HJKL. 
     721function! s:_type_buffer_action_xsplit(modifier, item) 
     722  execute a:modifier a:item._buffer_number 'sbuffer' 
     723endfunction 
     724function! s:_type_buffer_action_xdelete(command, item) 
     725  execute a:item._buffer_number a:command.ku#bang() 
     726endfunction 
     727 
     728 
    675729call ku#register_type({ 
    676730   \   'name': 'buffer', 
     731   \   'gather': function('s:_type_buffer_gather'), 
    677732   \   'actions': [ 
    678733   \     {'key': 'o', 
    679734   \      'name': 'open', 
    680735   \      'function': function('s:_type_buffer_action_open')}, 
     736   \     {'key': 'n', 
     737   \      'name': 'split', 
     738   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), '')}, 
    681739   \     {'key': 's', 
    682    \      'name': 'split open', 
    683    \      'function': function('s:_type_buffer_action_split_open')}, 
     740   \      'name': 'split', 
     741   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), '')}, 
    684742   \     {'key': 'v', 
    685    \      'name': 'vsplit open', 
    686    \      'function': function('s:_type_buffer_action_vsplit_open')}, 
     743   \      'name': 'vsplit', 
     744   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     745   \                       'vertical')}, 
     746   \     {'key': 'h', 
     747   \      'name': 'split left', 
     748   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     749   \                       'vertical leftabove')}, 
     750   \     {'key': 'j', 
     751   \      'name': 'split down', 
     752   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     753   \                       'rightbelow')}, 
     754   \     {'key': 'k', 
     755   \      'name': 'split up', 
     756   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     757   \                       'leftabove')}, 
     758   \     {'key': 'l', 
     759   \      'name': 'split right', 
     760   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     761   \                       'vertical rightbelow')}, 
     762   \     {'key': "\<C-h>", 
     763   \      'name': 'split left', 
     764   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     765   \                       'vertical leftabove')}, 
     766   \     {'key': "\<C-j>", 
     767   \      'name': 'split down', 
     768   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     769   \                       'rightbelow')}, 
     770   \     {'key': "\<C-k>", 
     771   \      'name': 'split up', 
     772   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     773   \                       'leftabove')}, 
     774   \     {'key': "\<C-l>", 
     775   \      'name': 'split right', 
     776   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     777   \                       'vertical rightbelow')}, 
     778   \     {'key': 'H', 
     779   \      'name': 'split far left', 
     780   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     781   \                       'vertical topleft')}, 
     782   \     {'key': 'J', 
     783   \      'name': 'split bottom', 
     784   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     785   \                       'botright')}, 
     786   \     {'key': 'K', 
     787   \      'name': 'split top', 
     788   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     789   \                       'topleft')}, 
     790   \     {'key': 'L', 
     791   \      'name': 'split far right', 
     792   \      'function': s:pa(function('s:_type_buffer_action_xsplit'), 
     793   \                       'vertical botright')}, 
     794   \     {'key': 'U', 
     795   \      'name': 'unload', 
     796   \      'function': s:pa(function('s:_type_buffer_action_xdelete'), 
     797   \                       'bunload')}, 
     798   \     {'key': 'D', 
     799   \      'name': 'delete', 
     800   \      'function': s:pa(function('s:_type_buffer_action_xdelete'), 
     801   \                       'bdelete')}, 
     802   \     {'key': 'W', 
     803   \      'name': 'wipeout', 
     804   \      'function': s:pa(function('s:_type_buffer_action_xdelete'), 
     805   \                       'bwipeout')}, 
    687806   \   ], 
    688    \   'gather': function('s:_type_buffer_gather'), 
    689807   \ }) 
    690808 
     
    693811 
    694812" file  "{{{2 
    695 " FIXME: stub. 
    696 let s:_type_file_cached_items = [] 
    697 let s:_type_file_last_bufnr = s:INVALID_BUFNR 
     813" FIXME: action idea: source 
     814" FIXME: action idea: ':' - set up ":<cursor> <item>" for any Ex command. 
     815" FIXME: unexpected propmt on some environments when glob() is called. 
     816"        it happens when the pattern contains '{foo,bar}'. 
     817" FIXME: smart caching. 
     818" FIXME: can't list the root directory. 
     819function! s:_type_file_initialize() 
     820  let s:_type_file_cache = {} 
     821  let s:_type_file_frags_count = -1 
     822endfunction 
     823 
    698824function! s:_type_file_gather(pattern) 
    699   if s:_type_file_last_bufnr != bufnr('$') 
    700     let s:_type_file_cached_items = [] 
    701     for i in range(1, bufnr('$')) 
    702       if bufexists(i) && buflisted(i) && getbufvar(i, '&buftype') == '' 
    703         call add(s:_type_file_cached_items, 
    704            \     { 
    705            \       'word': bufname(i), 
    706            \       'menu': 'file', 
    707            \       'dup': s:TRUE, 
    708            \     }) 
    709       endif 
    710     endfor 
    711     let s:_type_file_last_bufnr = bufnr('$') 
    712   endif 
    713   return s:_type_file_cached_items 
    714 endfunction 
    715  
    716  
     825  let c = len(split(a:pattern, '/', s:TRUE)) - 1 
     826  if s:_type_file_frags_count != c 
     827    let s:_type_file_frags_count = c 
     828    let s:_type_file_cache[c] 
     829      \ = map(split(glob(s:make_glob_pattern(a:pattern)), '\n'), 
     830      \       "{'word': v:val, 'menu': 'file', 'dup': s:TRUE}") 
     831  endif 
     832  return s:_type_file_cache[c] 
     833endfunction 
     834 
     835function! s:make_glob_pattern(s) 
     836  " FIXME: path separetor assumption. 
     837  let frags = split(substitute(a:s, '\s\+', '*', 'g'), '/', 1) 
     838  call map(frags, '"{,.??,.[^.]}*" . v:val . "*"') 
     839  call map(frags, 'substitute(v:val, "\\*\\+", "*", "g")') 
     840  return join(frags, '/') 
     841endfunction 
     842 
     843 
     844" FIXME: filename with special characters -- should escape? 
    717845function! s:_type_file_action_open(item) 
    718846  execute 'edit'.ku#bang() a:item.word 
    719847endfunction 
    720 function! s:_type_file_action_split_open(item) 
    721   execute 'split' a:item.word 
    722 endfunction 
    723 function! s:_type_file_action_vsplit_open(item) 
    724   execute 'vsplit' a:item.word 
     848function! s:_type_file_action_xsplit(modifier, item) 
     849  execute a:modifier 'split' a:item.word 
    725850endfunction 
    726851 
     
    728853call ku#register_type({ 
    729854   \   'name': 'file', 
     855   \   'initialize': function('s:_type_file_initialize'), 
     856   \   'gather': function('s:_type_file_gather'), 
    730857   \   'actions': [ 
    731858   \     {'key': 'o', 
    732859   \      'name': 'open', 
    733860   \      'function': function('s:_type_file_action_open')}, 
     861   \     {'key': 'n', 
     862   \      'name': 'split', 
     863   \      'function': s:pa(function('s:_type_file_action_xsplit'), '')}, 
    734864   \     {'key': 's', 
    735    \      'name': 'split open', 
    736    \      'function': function('s:_type_file_action_split_open')}, 
     865   \      'name': 'split', 
     866   \      'function': s:pa(function('s:_type_file_action_xsplit'), '')}, 
    737867   \     {'key': 'v', 
    738    \      'name': 'vsplit open', 
    739    \      'function': function('s:_type_file_action_vsplit_open')}, 
     868   \      'name': 'vsplit', 
     869   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     870   \                       'vertical')}, 
     871   \     {'key': 'h', 
     872   \      'name': 'split left', 
     873   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     874   \                       'vertical leftabove')}, 
     875   \     {'key': 'j', 
     876   \      'name': 'split down', 
     877   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     878   \                       'rightbelow')}, 
     879   \     {'key': 'k', 
     880   \      'name': 'split up', 
     881   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     882   \                       'leftabove')}, 
     883   \     {'key': 'l', 
     884   \      'name': 'split right', 
     885   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     886   \                       'vertical rightbelow')}, 
     887   \     {'key': "\<C-h>", 
     888   \      'name': 'split left', 
     889   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     890   \                       'vertical leftabove')}, 
     891   \     {'key': "\<C-j>", 
     892   \      'name': 'split down', 
     893   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     894   \                       'rightbelow')}, 
     895   \     {'key': "\<C-k>", 
     896   \      'name': 'split up', 
     897   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     898   \                       'leftabove')}, 
     899   \     {'key': "\<C-l>", 
     900   \      'name': 'split right', 
     901   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     902   \                       'vertical rightbelow')}, 
     903   \     {'key': 'H', 
     904   \      'name': 'split far left', 
     905   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     906   \                       'vertical topleft')}, 
     907   \     {'key': 'J', 
     908   \      'name': 'split bottom', 
     909   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     910   \                       'botright')}, 
     911   \     {'key': 'K', 
     912   \      'name': 'split top', 
     913   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     914   \                       'topleft')}, 
     915   \     {'key': 'L', 
     916   \      'name': 'split far right', 
     917   \      'function': s:pa(function('s:_type_file_action_xsplit'), 
     918   \                       'vertical botright')}, 
    740919   \   ], 
    741    \   'gather': function('s:_type_file_gather'), 
    742920   \ }) 
    743921 
     
    750928 
    751929" directory  "{{{2 
    752 " FIXME: not written yet. 
     930" FIXME: not written yet -- integrate into type file? 
    753931 
    754932