PageRenderTime 55ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/pack/general/start/easymotion/autoload/EasyMotion/command_line.vim

https://bitbucket.org/lilydjwg/dotvim
Vim Script | 283 lines | 211 code | 15 blank | 57 comment | 36 complexity | 9a0acada9583c5a04f34190a019afa56 MD5 | raw file
  1. "=============================================================================
  2. " FILE: autoload/EasyMotion/command_line.vim
  3. " AUTHOR: haya14busa
  4. " Reference: https://github.com/osyo-manga/vim-over
  5. " License: MIT license {{{
  6. " Permission is hereby granted, free of charge, to any person obtaining
  7. " a copy of this software and associated documentation files (the
  8. " "Software"), to deal in the Software without restriction, including
  9. " without limitation the rights to use, copy, modify, merge, publish,
  10. " distribute, sublicense, and/or sell copies of the Software, and to
  11. " permit persons to whom the Software is furnished to do so, subject to
  12. " the following conditions:
  13. "
  14. " The above copyright notice and this permission notice shall be included
  15. " in all copies or substantial portions of the Software.
  16. "
  17. " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  18. " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19. " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  20. " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  21. " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  22. " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  23. " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  24. " }}}
  25. "=============================================================================
  26. scriptencoding utf-8
  27. " Saving 'cpoptions' {{{
  28. let s:save_cpo = &cpo
  29. set cpo&vim
  30. " }}}
  31. " CommandLine:
  32. let s:V = vital#easymotion#new()
  33. let s:cmdline = s:V.import('Over.Commandline.Base')
  34. let s:modules = s:V.import("Over.Commandline.Modules")
  35. let s:search = s:cmdline.make()
  36. let s:search.highlights.prompt = 'Question'
  37. " Add Module: {{{
  38. call s:search.connect('Exit')
  39. call s:search.connect('Cancel')
  40. call s:search.connect('Redraw')
  41. call s:search.connect('DrawCommandline')
  42. call s:search.connect('Delete')
  43. call s:search.connect('CursorMove')
  44. call s:search.connect('Paste')
  45. call s:search.connect('BufferComplete')
  46. call s:search.connect('InsertRegister')
  47. call s:search.connect('ExceptionExit')
  48. call s:search.connect(s:modules.get('ExceptionMessage').make('EasyMotion: ', 'echom'))
  49. call s:search.connect(s:modules.get('History').make('/'))
  50. call s:search.connect(s:modules.get('NoInsert').make_special_chars())
  51. call s:search.connect(s:modules.get('KeyMapping').make_emacs())
  52. call s:search.connect(s:modules.get('Doautocmd').make('EMCommandLine'))
  53. let s:module = {
  54. \ "name" : "EasyMotion",
  55. \}
  56. function! s:module.on_char_pre(cmdline)
  57. if a:cmdline.is_input("<Over>(em-scroll-f)")
  58. call s:scroll(0)
  59. call a:cmdline.setchar('')
  60. elseif a:cmdline.is_input("<Over>(em-scroll-b)")
  61. call s:scroll(1)
  62. call a:cmdline.setchar('')
  63. elseif a:cmdline.is_input("<Over>(em-jumpback)")
  64. keepjumps call setpos('.', s:save_orig_pos)
  65. let s:orig_pos = s:save_orig_pos
  66. let s:orig_line_start = getpos('w0')
  67. let s:orig_line_end = getpos('w$')
  68. let s:direction = s:save_direction
  69. call a:cmdline.setchar('')
  70. elseif a:cmdline.is_input("<Over>(em-openallfold)")
  71. " TODO: better solution
  72. normal! zR
  73. call a:cmdline.setchar('')
  74. endif
  75. endfunction
  76. call s:search.connect(s:module)
  77. "}}}
  78. " CommandLine Keymap: {{{
  79. " .keymapping() won't be remapped by user defined KeyMappings.
  80. function! s:search.keymapping() "{{{
  81. return {
  82. \ "\<CR>" : {
  83. \ "key" : "<Over>(exit)",
  84. \ "noremap" : 1,
  85. \ "lock" : 1,
  86. \ },
  87. \ }
  88. endfunction "}}}
  89. call s:search.cnoremap("\<C-l>", '<Over>(buffer-complete)')
  90. call s:search.cnoremap("\<Tab>", '<Over>(em-scroll-f)')
  91. call s:search.cnoremap("\<S-Tab>", '<Over>(em-scroll-b)')
  92. call s:search.cnoremap("\<C-o>", '<Over>(em-jumpback)')
  93. call s:search.cnoremap("\<C-z>", '<Over>(em-openallfold)')
  94. " Fins Motion CommandLine Mapping Command: {{{
  95. function! EasyMotion#command_line#cmap(args)
  96. let lhs = s:as_keymapping(a:args[0])
  97. let rhs = s:as_keymapping(a:args[1])
  98. call s:search.cmap(lhs, rhs)
  99. endfunction
  100. function! EasyMotion#command_line#cnoremap(args)
  101. let lhs = s:as_keymapping(a:args[0])
  102. let rhs = s:as_keymapping(a:args[1])
  103. call s:search.cnoremap(lhs, rhs)
  104. endfunction
  105. function! EasyMotion#command_line#cunmap(lhs)
  106. let lhs = s:as_keymapping(a:lhs)
  107. call s:search.cunmap(lhs)
  108. endfunction
  109. function! s:as_keymapping(key)
  110. execute 'let result = "' . substitute(a:key, '\(<.\{-}>\)', '\\\1', 'g') . '"'
  111. return result
  112. endfunction
  113. "}}}
  114. "}}}
  115. " Event: {{{
  116. function! s:search.on_enter(cmdline) "{{{
  117. if s:num_strokes == -1
  118. call EasyMotion#highlight#delete_highlight()
  119. call EasyMotion#helper#VarReset('&scrolloff', 0)
  120. if g:EasyMotion_do_shade
  121. call EasyMotion#highlight#add_highlight('\_.*',
  122. \ g:EasyMotion_hl_group_shade)
  123. endif
  124. endif
  125. if g:EasyMotion_cursor_highlight
  126. call EasyMotion#highlight#add_highlight('\%#',
  127. \ g:EasyMotion_hl_inc_cursor)
  128. endif
  129. endfunction "}}}
  130. function! s:search.on_leave(cmdline) "{{{
  131. if s:num_strokes == -1
  132. call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
  133. if g:EasyMotion_do_shade
  134. call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_group_shade)
  135. endif
  136. endif
  137. if g:EasyMotion_cursor_highlight
  138. call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_cursor)
  139. endif
  140. endfunction "}}}
  141. function! s:search.on_char(cmdline) "{{{
  142. if s:num_strokes == -1
  143. let re = s:search.getline()
  144. if EasyMotion#helper#should_case_sensitive(re, 1)
  145. let case_flag = '\c'
  146. else
  147. let case_flag = '\C'
  148. endif
  149. let re .= case_flag
  150. if g:EasyMotion_inc_highlight
  151. call s:inc_highlight(re)
  152. endif
  153. if g:EasyMotion_off_screen_search
  154. call s:off_screen_search(re)
  155. endif
  156. elseif s:search.line.length() >= s:num_strokes
  157. call s:search.exit()
  158. endif
  159. endfunction "}}}
  160. "}}}
  161. " Main:
  162. function! EasyMotion#command_line#GetInput(num_strokes, prev, direction) "{{{
  163. let s:num_strokes = a:num_strokes
  164. let s:prompt_base = s:getPromptMessage(a:num_strokes)
  165. call s:search.set_prompt(s:prompt_base)
  166. " Screen: cursor position, first and last line
  167. let s:orig_pos = getpos('.')
  168. let s:orig_line_start = getpos('w0')
  169. let s:orig_line_end = getpos('w$')
  170. let s:save_orig_pos = deepcopy(s:orig_pos)
  171. " Direction:
  172. let s:direction = a:direction == 1 ? 'b' : ''
  173. let s:save_direction = deepcopy(s:direction)
  174. let input = s:search.get()
  175. if input == '' && ! s:search.exit_code()
  176. return a:prev
  177. elseif s:search.exit_code() == 1 || s:search.exit_code() == -1
  178. call s:Cancell()
  179. return ''
  180. else
  181. return input
  182. endif
  183. endfunction "}}}
  184. " Helper:
  185. function! s:Cancell() " {{{
  186. call EasyMotion#highlight#delete_highlight()
  187. call EasyMotion#helper#VarReset('&scrolloff')
  188. keepjumps call setpos('.', s:save_orig_pos)
  189. if g:EasyMotion_verbose
  190. echo 'EasyMotion: Cancelled'
  191. endif
  192. return ''
  193. endfunction " }}}
  194. function! s:getPromptMessage(num_strokes) "{{{
  195. if a:num_strokes == 1
  196. let prompt = substitute(
  197. \ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
  198. \ '(s)', '', 'g')
  199. elseif a:num_strokes == -1
  200. let prompt = substitute(
  201. \ substitute(g:EasyMotion_prompt, '{n}\s\{0,1}', '', 'g'),
  202. \ '(s)', 's', 'g')
  203. else
  204. let prompt = substitute(
  205. \ substitute(g:EasyMotion_prompt,'{n}', a:num_strokes, 'g'),
  206. \ '(s)', 's', 'g')
  207. endif
  208. return prompt
  209. endfunction "}}}
  210. function! s:off_screen_search(re) "{{{
  211. " First: search within visible screen range
  212. call s:adjust_screen()
  213. " Error occur when '\zs' without '!'
  214. silent! let pos = searchpos(a:re, s:direction . 'n', s:orig_line_end[1])
  215. if pos != [0, 0]
  216. " Restore cursor posision
  217. keepjumps call setpos('.', s:orig_pos)
  218. else
  219. " Second: if there were no much, search off screen
  220. silent! let pos = searchpos(a:re, s:direction)
  221. if pos != [0, 0]
  222. " Match
  223. keepjumps call setpos('.', pos)
  224. " Move cursor
  225. if s:save_direction != 'b'
  226. normal! zzH0
  227. else
  228. normal! zzL0
  229. endif
  230. else
  231. " No much
  232. call s:adjust_screen()
  233. keepjumps call setpos('.', s:orig_pos)
  234. endif
  235. endif
  236. " redraw
  237. endfunction "}}}
  238. function! s:adjust_screen() "{{{
  239. if s:save_direction != 'b'
  240. " Forward
  241. keepjumps call setpos('.', s:orig_line_start)
  242. normal! zt
  243. else
  244. " Backward
  245. keepjumps call setpos('.', s:orig_line_end)
  246. normal! zb
  247. endif
  248. endfunction "}}}
  249. function! s:scroll(direction) "{{{
  250. " direction: 0 -> forward, 1 -> backward
  251. exec a:direction == 0 ? "normal! \<C-f>" : "normal! \<C-b>"
  252. let s:orig_pos = getpos('.')
  253. let s:orig_line_start = getpos('w0')
  254. let s:orig_line_end = getpos('w$')
  255. let s:direction = a:direction == 0 ? '' : 'b'
  256. endfunction "}}}
  257. function! s:inc_highlight(re) "{{{
  258. call EasyMotion#highlight#delete_highlight(g:EasyMotion_hl_inc_search)
  259. if s:search.line.length() > 0
  260. " Error occur when '\zs' without '!'
  261. silent! call EasyMotion#highlight#add_highlight(a:re, g:EasyMotion_hl_inc_search)
  262. endif
  263. endfunction "}}}
  264. " Restore 'cpoptions' {{{
  265. let &cpo = s:save_cpo
  266. unlet s:save_cpo
  267. " }}}
  268. " vim: fdm=marker:et:ts=4:sw=4:sts=4