snippet.vim 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. scriptencoding utf-8
  2. let s:is_vim = !has('nvim')
  3. let s:map_next = 1
  4. let s:map_prev = 1
  5. let s:cmd_mapping = has('nvim') || has('patch-8.2.1978')
  6. function! coc#snippet#_select_mappings()
  7. if !get(g:, 'coc_selectmode_mapping', 1)
  8. return
  9. endif
  10. redir => mappings
  11. silent! smap
  12. redir END
  13. for map in map(filter(split(mappings, '\n'),
  14. \ "v:val !~# '^s' && v:val !~# '^\\a*\\s*<\\S\\+>'"),
  15. \ "matchstr(v:val, '^\\a*\\s*\\zs\\S\\+')")
  16. silent! execute 'sunmap' map
  17. silent! execute 'sunmap <buffer>' map
  18. endfor
  19. " same behaviour of ultisnips
  20. snoremap <silent> <BS> <c-g>c
  21. snoremap <silent> <DEL> <c-g>c
  22. snoremap <silent> <c-h> <c-g>c
  23. snoremap <c-r> <c-g>"_c<c-r>
  24. endfunction
  25. function! coc#snippet#show_choices(lnum, col, len, values) abort
  26. let m = mode()
  27. call cursor(a:lnum, a:col + a:len)
  28. if m !=# 'i'
  29. call feedkeys("\<Esc>i", 'in')
  30. endif
  31. let changedtick = b:changedtick
  32. call timer_start(20, { -> coc#_do_complete(a:col - 1, a:values, 0, changedtick)})
  33. redraw
  34. endfunction
  35. function! coc#snippet#enable(...)
  36. if get(b:, 'coc_snippet_active', 0) == 1
  37. return
  38. endif
  39. let complete = get(a:, 1, 0)
  40. let b:coc_snippet_active = 1
  41. call coc#snippet#_select_mappings()
  42. let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
  43. let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
  44. if maparg(nextkey, 'i') =~# 'snippet'
  45. let s:map_next = 0
  46. endif
  47. if maparg(prevkey, 'i') =~# 'snippet'
  48. let s:map_prev = 0
  49. endif
  50. if !empty(nextkey)
  51. if s:map_next
  52. execute 'inoremap <buffer><nowait><silent>'.nextkey." <C-R>=coc#snippet#jump(1, ".complete.")<cr>"
  53. endif
  54. execute 'snoremap <buffer><nowait><silent>'.nextkey." <Esc>:call coc#snippet#jump(1, ".complete.")<cr>"
  55. endif
  56. if !empty(prevkey)
  57. if s:map_prev
  58. execute 'inoremap <buffer><nowait><silent>'.prevkey." <C-R>=coc#snippet#jump(0, ".complete.")<cr>"
  59. endif
  60. execute 'snoremap <buffer><nowait><silent>'.prevkey." <Esc>:call coc#snippet#jump(0, ".complete.")<cr>"
  61. endif
  62. endfunction
  63. function! coc#snippet#prev() abort
  64. call coc#rpc#request('snippetPrev', [])
  65. return ''
  66. endfunction
  67. function! coc#snippet#next() abort
  68. call coc#rpc#request('snippetNext', [])
  69. return ''
  70. endfunction
  71. function! coc#snippet#jump(direction, complete) abort
  72. if a:direction == 1 && a:complete && pumvisible()
  73. let pre = exists('*complete_info') && complete_info()['selected'] == -1 ? "\<C-n>" : ''
  74. call feedkeys(pre."\<C-y>", 'in')
  75. return ''
  76. endif
  77. call coc#rpc#request(a:direction == 1 ? 'snippetNext' : 'snippetPrev', [])
  78. return ''
  79. endfunction
  80. function! coc#snippet#disable()
  81. if get(b:, 'coc_snippet_active', 0) == 0
  82. return
  83. endif
  84. let b:coc_snippet_active = 0
  85. let nextkey = get(g:, 'coc_snippet_next', '<C-j>')
  86. let prevkey = get(g:, 'coc_snippet_prev', '<C-k>')
  87. if s:map_next
  88. silent! execute 'iunmap <buffer> <silent> '.nextkey
  89. endif
  90. if s:map_prev
  91. silent! execute 'iunmap <buffer> <silent> '.prevkey
  92. endif
  93. silent! execute 'sunmap <buffer> <silent> '.prevkey
  94. silent! execute 'sunmap <buffer> <silent> '.nextkey
  95. endfunction
  96. function! coc#snippet#select(start, end, text) abort
  97. if coc#pum#visible()
  98. call coc#pum#close()
  99. endif
  100. if mode() == 's'
  101. call feedkeys("\<Esc>", 'in')
  102. endif
  103. if &selection ==# 'exclusive'
  104. let cursor = coc#snippet#to_cursor(a:start)
  105. call cursor([cursor[0], cursor[1]])
  106. let cmd = ''
  107. let cmd .= mode()[0] ==# 'i' ? "\<Esc>".(col('.') == 1 ? '' : 'l') : ''
  108. let cmd .= printf('v%s', strchars(a:text) . 'l')
  109. let cmd .= "\<C-g>"
  110. else
  111. let cursor = coc#snippet#to_cursor(a:end)
  112. call cursor([cursor[0], cursor[1] - 1])
  113. let len = strchars(a:text) - 1
  114. let cmd = ''
  115. let cmd .= mode()[0] ==# 'i' ? "\<Esc>l" : ''
  116. let cmd .= printf('v%s', len > 0 ? len . 'h' : '')
  117. let cmd .= "o\<C-g>"
  118. endif
  119. call feedkeys(cmd, 'n')
  120. endfunction
  121. function! coc#snippet#move(position) abort
  122. let m = mode()
  123. if m == 's'
  124. call feedkeys("\<Esc>", 'in')
  125. elseif coc#pum#visible()
  126. call coc#pum#close()
  127. endif
  128. let pos = coc#snippet#to_cursor(a:position)
  129. call cursor(pos)
  130. if pos[1] > strlen(getline(pos[0]))
  131. startinsert!
  132. else
  133. startinsert
  134. endif
  135. endfunction
  136. function! coc#snippet#to_cursor(position) abort
  137. let line = getline(a:position.line + 1)
  138. if line is v:null
  139. return [a:position.line + 1, a:position.character + 1]
  140. endif
  141. return [a:position.line + 1, byteidx(line, a:position.character) + 1]
  142. endfunction