summaryrefslogtreecommitdiff
path: root/autoload/deoplete/mapping.vim
blob: 84d4917a60a730318d36ea4da98ed04bdf896122 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
"=============================================================================
" FILE: mapping.vim
" AUTHOR: Shougo Matsushita <Shougo.Matsu at gmail.com>
" License: MIT license
"=============================================================================

function! deoplete#mapping#_init() abort
  " Note: The dummy function is needed for cpoptions bug in neovim
  inoremap <expr><silent> <Plug>_
        \ deoplete#mapping#_dummy('deoplete#mapping#_complete')
  inoremap <expr><silent> <Plug>+
        \ deoplete#mapping#_dummy('deoplete#mapping#_prev_complete')
endfunction
function! deoplete#mapping#_dummy(func) abort
  return "\<C-r>=".a:func."()\<CR>"
endfunction
function! s:check_completion_info(candidates) abort
  if !exists('*complete_info')
    return 0
  endif

  let info = complete_info()
  let noinsert = &completeopt =~# 'noinsert'
  if (info.mode !=# '' && info.mode !=# 'eval')
        \ || (noinsert && info.selected > 0)
        \ || (!noinsert && info.selected >= 0)
        \ || !has_key(g:deoplete#_context, 'complete_position')
    return 1
  endif

  let input = getline('.')[: g:deoplete#_context.complete_position - 1]
  if deoplete#util#check_eskk_phase_henkan()
        \ && matchstr(input, '.$') =~# '[\u3040-\u304A]$'
    return 0
  endif
  return 0

  let old_candidates = sort(map(copy(info.items), 'v:val.word'))
  return sort(map(copy(a:candidates), 'v:val.word')) ==# old_candidates
endfunction
function! deoplete#mapping#_complete() abort
  if !has_key(g:deoplete#_context, 'candidates')
        \ || s:check_completion_info(g:deoplete#_context.candidates)
        \ || !&modifiable
    return ''
  endif

  " echomsg string(g:deoplete#_context)
  if empty(g:deoplete#_context.candidates) && deoplete#util#check_popup()
    " Note: call complete() to close the popup
    call complete(1, [])
    return ''
  endif

  call complete(g:deoplete#_context.complete_position + 1,
        \ g:deoplete#_context.candidates)

  return ''
endfunction
function! deoplete#mapping#_prev_complete() abort
  if s:check_completion_info(g:deoplete#_filtered_prev.candidates)
    return ''
  endif

  call complete(g:deoplete#_filtered_prev.complete_position + 1,
        \ g:deoplete#_filtered_prev.candidates)

  return ''
endfunction
function! deoplete#mapping#_set_completeopt() abort
  if exists('g:deoplete#_saved_completeopt')
    return
  endif
  let g:deoplete#_saved_completeopt = &completeopt
  set completeopt-=longest
  set completeopt+=menuone
  set completeopt-=menu
  if &completeopt !~# 'noinsert\|noselect'
    set completeopt+=noselect
  endif
endfunction
function! deoplete#mapping#_restore_completeopt() abort
  if exists('g:deoplete#_saved_completeopt')
    let &completeopt = g:deoplete#_saved_completeopt
    unlet g:deoplete#_saved_completeopt
  endif
endfunction
function! deoplete#mapping#_rpcrequest_wrapper(sources) abort
  return deoplete#util#rpcnotify(
        \ 'deoplete_manual_completion_begin',
        \ {
        \  'event': 'Manual',
        \  'sources': deoplete#util#convert2list(a:sources)
        \ })
endfunction
function! deoplete#mapping#_undo_completion() abort
  if empty(v:completed_item)
    return ''
  endif

  let input = deoplete#util#get_input('')
  if strridx(input, v:completed_item.word) !=
        \ len(input) - len(v:completed_item.word)
    return ''
  endif

  return repeat("\<C-h>", strchars(v:completed_item.word))
endfunction
function! deoplete#mapping#_complete_common_string() abort
  if !deoplete#is_enabled()
    return ''
  endif

  " Get cursor word.
  let prev = g:deoplete#_prev_completion
  if empty(prev)
    return ''
  endif

  let complete_str = prev.input[prev.complete_position :]
  let candidates = filter(copy(prev.candidates),
        \ 'stridx(tolower(v:val.word), tolower(complete_str)) == 0')

  if empty(candidates) || complete_str ==# ''
    return ''
  endif

  let common_str = candidates[0].word
  for candidate in candidates[1:]
    while stridx(tolower(candidate.word), tolower(common_str)) != 0
      let common_str = common_str[: -2]
    endwhile
  endfor

  if common_str ==# '' || complete_str ==? common_str
    return ''
  endif

  return (pumvisible() ? "\<C-e>" : '')
        \ . repeat("\<BS>", strchars(complete_str)) . common_str
endfunction
function! deoplete#mapping#_insert_candidate(number) abort
  let prev = g:deoplete#_prev_completion
  let candidates = get(prev, 'candidates', [])
  let word = get(candidates, a:number, {'word': ''}).word
  if word ==# ''
    return ''
  endif

  " Get cursor word.
  let complete_str = prev.input[prev.complete_position :]
  return (pumvisible() ? "\<C-e>" : '')
        \ . repeat("\<BS>", strchars(complete_str)) . word
endfunction