My dotfiles. Period.

function.vim 6.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. "=============================================================================
  2. " $Id: function.vim 520 2012-03-19 18:09:15Z luc.hermitte $
  3. " File: autoload/lh/function.vim {{{1
  4. " Author: Luc Hermitte <EMAIL:hermitte {at} free {dot} fr>
  5. " <URL:http://code.google.com/p/lh-vim/>
  6. " License: GPLv3 with exceptions
  7. " <URL:http://code.google.com/p/lh-vim/wiki/License>
  8. " Version: 3.0.0
  9. " Created: 03rd Nov 2008
  10. " Last Update: $Date: 2012-03-19 19:09:15 +0100 (Mon, 19 Mar 2012) $
  11. "------------------------------------------------------------------------
  12. " Description:
  13. " Implements:
  14. " - lh#function#bind()
  15. " - lh#function#execute()
  16. " - lh#function#prepare()
  17. " - a binded function type
  18. "
  19. "------------------------------------------------------------------------
  20. " Installation:
  21. " Drop it into {rtp}/autoload/lh/
  22. " Vim 7+ required.
  23. " History:
  24. " v2.2.0: first implementation
  25. " v3.0.0: GPLv3
  26. " TODO: «missing features»
  27. " }}}1
  28. "=============================================================================
  29. let s:cpo_save=&cpo
  30. set cpo&vim
  31. "------------------------------------------------------------------------
  32. " ## Functions {{{1
  33. " # Debug {{{2
  34. function! lh#function#verbose(level)
  35. let s:verbose = a:level
  36. endfunction
  37. function! s:Verbose(expr)
  38. if exists('s:verbose') && s:verbose
  39. echomsg a:expr
  40. endif
  41. endfunction
  42. function! lh#function#debug(expr)
  43. return eval(a:expr)
  44. endfunction
  45. " # Function: s:Join(arguments...) {{{2
  46. function! s:Join(args)
  47. let res = ''
  48. if len(a:args) > 0
  49. let res = string(a:args[0])
  50. let i = 1
  51. while i != len(a:args)
  52. let res.=','.string(a:args[i])
  53. let i += 1
  54. endwhile
  55. endif
  56. return res
  57. endfunction
  58. " # Function: s:DoBindList(arguments...) {{{2
  59. function! s:DoBindList(formal, real)
  60. let args = []
  61. for arg in a:formal
  62. if type(arg)==type('string') && arg =~ '^v:\d\+_$'
  63. let new = a:real[matchstr(arg, 'v:\zs\d\+\ze_')-1]
  64. elseif type(arg)==type('string')
  65. let new = eval(s:DoBindEvaluatedString(arg, a:real))
  66. else
  67. let new = arg
  68. endif
  69. call add(args, new)
  70. unlet new
  71. unlet arg
  72. endfor
  73. return args
  74. endfunction
  75. " # Function: s:DoBindString(arguments...) {{{2
  76. function! s:DoBindString(expr, real)
  77. let expr = substitute(a:expr, '\<v:\(\d\+\)_\>', a:real.'[\1-1]', 'g')
  78. return expr
  79. endfunction
  80. function! s:ToString(expr)
  81. return type(a:expr) != type('')
  82. \ ? string(a:expr)
  83. \ : (a:expr)
  84. endfunction
  85. function! s:DoBindEvaluatedString(expr, real)
  86. let expr = a:expr
  87. let p = 0
  88. while 1
  89. let p = match(expr, '\<v:\d\+_\>', p)
  90. if -1 == p | break | endif
  91. let e = matchend(expr, '\<v:\d\+_\>', p)
  92. let n = eval(expr[p+2 : e-2])
  93. " let new = (type(a:real[n-1])==type('') && a:real[n-1]=~ '\<v:\d\+_\>')
  94. " \ ? a:real[n-1]
  95. " \ : string(a:real[n-1])
  96. let new = s:ToString(a:real[n-1])
  97. " let new = string(a:real[n-1]) " -> bind_counpound vars
  98. let expr = ((p>0) ? (expr[0:p-1]) : '') . new . expr[e : -1]
  99. " echo expr
  100. let p += len(new)
  101. " silent! unlet new
  102. endwhile
  103. return expr
  104. endfunction
  105. " # Function: s:Execute(arguments...) {{{2
  106. function! s:Execute(args) dict
  107. if type(self.function) == type(function('exists'))
  108. let args = s:DoBindList(self.args, a:args)
  109. " echomsg '##'.string(self.function).'('.join(args, ',').')'
  110. let res = eval(string(self.function).'('.s:Join(args).')')
  111. elseif type(self.function) == type('string')
  112. let expr = s:DoBindString(self.function, 'a:args')
  113. let res = eval(expr)
  114. elseif type(self.function) == type({})
  115. return self.function.execute(a:args)
  116. else
  117. throw "lh#functor#execute: unpected function type: ".type(self.function)
  118. endif
  119. return res
  120. endfunction
  121. " # Function: lh#function#prepare(function, arguments_list) {{{2
  122. function! lh#function#prepare(Fn, arguments_list)
  123. if type(a:Fn) == type(function('exists'))
  124. let expr = string(a:Fn).'('.s:Join(a:arguments_list).')'
  125. return expr
  126. elseif type(a:Fn) == type('string')
  127. if a:Fn =~ '^[a-zA-Z0-9_#]\+$'
  128. let expr = string(function(a:Fn)).'('.s:Join(a:arguments_list).')'
  129. return expr
  130. else
  131. let expr = s:DoBindString(a:Fn, 'a:000')
  132. return expr
  133. endif
  134. else
  135. throw "lh#function#prepare(): {Fn} argument of type ".type(a:Fn). " is unsupported"
  136. endif
  137. endfunction
  138. " # Function: lh#function#execute(function, arguments...) {{{2
  139. function! lh#function#execute(Fn, ...)
  140. if type(a:Fn) == type({}) && has_key(a:Fn, 'execute')
  141. return a:Fn.execute(a:000)
  142. else
  143. let expr = lh#function#prepare(a:Fn, a:000)
  144. return eval(expr)
  145. endif
  146. endfunction
  147. " # Function: lh#function#bind(function, arguments...) {{{2
  148. function! lh#function#bind(Fn, ...)
  149. let args = copy(a:000)
  150. if type(a:Fn) == type('string') && a:Fn =~ '^[a-zA-Z0-9_#]\+$'
  151. \ && exists('*'.a:Fn)
  152. let Fn = function(a:Fn)
  153. elseif type(a:Fn) == type({})
  154. " echo string(a:Fn).'('.string(a:000).')'
  155. " Rebinding another binded function
  156. " TASSERT has_key(a:Fn, 'function')
  157. " TASSERT has_key(a:Fn, 'execute')
  158. " TASSERT has_key(a:Fn, 'args')
  159. let Fn = a:Fn.function
  160. let N = len(a:Fn.args)
  161. if N != 0 " args to rebind
  162. let i = 0
  163. let t_args = [] " necessary to avoid type changes
  164. while i != N
  165. silent! unlet arg
  166. let arg = a:Fn.args[i]
  167. if arg =~ 'v:\d\+_$'
  168. let arg2 = eval(s:DoBindString(arg, string(args)))
  169. " echo arg."-(".string(args).")->".string(arg2)
  170. unlet arg
  171. let arg = arg2
  172. unlet arg2
  173. endif
  174. call add(t_args, arg)
  175. let i += 1
  176. endwhile
  177. unlet a:Fn.args
  178. let a:Fn.args = t_args
  179. else " expression to fix
  180. " echo Fn
  181. " echo s:DoBindString(Fn, string(args))
  182. " echo eval(string(s:DoBindString(Fn, string(args))))
  183. let Fn = (s:DoBindEvaluatedString(Fn, args))
  184. endif
  185. let args = a:Fn.args
  186. else
  187. let Fn = a:Fn
  188. endif
  189. let binded_fn = {
  190. \ 'function': Fn,
  191. \ 'args': args,
  192. \ 'execute': function('s:Execute')
  193. \}
  194. return binded_fn
  195. endfunction
  196. " }}1
  197. "------------------------------------------------------------------------
  198. let &cpo=s:cpo_save
  199. "=============================================================================
  200. " vim600: set fdm=marker:
  201. " Vim: let g:UTfiles='tests/lh/function.vim'