llvm.org GIT mirror llvm / 446c6c4
Experimental clang-based code-completion support for vim. This currently depends on some clang patches which are not yet upstream. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112204 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 9 years ago
1 changed file(s) with 124 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
9090 "set showmode
9191 "set incsearch
9292 "set ruler
93
94 " Clang code-completion support. This is highly experimental!
95
96 " TODO: code-completing on
97 " cast_cast<
98 " turns up some peculiarities -- "asm("?
99
100 " A path to the a executable.
101 let g:clang_path = "Release/bin/clang++"
102
103 " A list of options to add to the clang commandline, for example to add
104 " include paths, predefined macros, and language options.
105 let g:clang_opts = [
106 \ "-x","c++",
107 \ "-D__STDC_LIMIT_MACROS=1","-D__STDC_CONSTANT_MACROS=1",
108 \ "-Iinclude" ]
109
110 function! ClangComplete(findstart, base)
111 if a:findstart == 1
112 " In findstart mode, look for the beginning of the current identifier.
113 let l:line = getline('.')
114 let l:start = col('.') - 1
115 while l:start > 0 && l:line[l:start - 1] =~ '\i'
116 let l:start -= 1
117 endwhile
118 return l:start
119 endif
120
121 " Get the current line and column numbers.
122 let l:l = line('.')
123 let l:c = col('.')
124
125 " Build a clang commandline to do code completion on stdin.
126 let l:the_command = shellescape(g:clang_path) .
127 \ " -cc1 -code-completion-at=-:" . l:l . ":" . l:c
128 for l:opt in g:clang_opts
129 let l:the_command .= " " . shellescape(l:opt)
130 endfor
131
132 " Copy the contents of the current buffer into a string for stdin.
133 " TODO: The extra space at the end is for working around clang's
134 " apparent inability to do code completion at the very end of the
135 " input.
136 " TODO: Is it better to feed clang the entire file instead of truncating
137 " it at the current line?
138 let l:process_input = join(getline(1, l:l), "\n") . " "
139
140 " Run it!
141 let l:input_lines = split(system(l:the_command, l:process_input), "\n")
142
143 " Parse the output.
144 for l:input_line in l:input_lines
145 " Vim's substring operator is annoyingly inconsistent with python's.
146 if l:input_line[:11] == 'COMPLETION: '
147 let l:value = l:input_line[12:]
148
149 " Chop off anything after " : ", if present, and move it to the menu.
150 let l:menu = ""
151 let l:spacecolonspace = stridx(l:value, " : ")
152 if l:spacecolonspace != -1
153 let l:menu = l:value[l:spacecolonspace+3:]
154 let l:value = l:value[:l:spacecolonspace-1]
155 endif
156
157 " Handle Pattern. TODO: Make clang less weird.
158 if l:value == "Pattern"
159 let l:value = l:menu
160 let l:pound = stridx(l:value, "#")
161 " Truncate the at the first [#, <#, or {#.
162 if l:pound != -1
163 let l:value = l:value[:l:pound-2]
164 endif
165 endif
166
167 " Filter out results which don't match the base string.
168 if a:base != ""
169 if l:value[:strlen(a:base)-1] != a:base
170 continue
171 end
172 endif
173
174 " TODO: Don't dump the raw input into info, though it's nice for now.
175 " TODO: The kind string?
176 let l:item = {
177 \ "word": l:value,
178 \ "menu": l:menu,
179 \ "info": l:input_line,
180 \ "dup": 1 }
181
182 " Report a result.
183 if complete_add(l:item) == 0
184 return []
185 endif
186 if complete_check()
187 return []
188 endif
189
190 elseif l:input_line[:9] == "OVERLOAD: "
191 " An overload candidate. Use a crazy hack to get vim to
192 " display the results. TODO: Make this better.
193 let l:value = l:input_line[10:]
194 let l:item = {
195 \ "word": " ",
196 \ "menu": l:value,
197 \ "info": l:input_line,
198 \ "dup": 1}
199
200 " Report a result.
201 if complete_add(l:item) == 0
202 return []
203 endif
204 if complete_check()
205 return []
206 endif
207
208 endif
209 endfor
210
211
212 return []
213 endfunction ClangComplete
214
215 " Uncomment this to enable the highly-broken autocompletion support.
216 "set omnifunc=ClangComplete