Experimental clang-based code-completion support for vim. This currently
authorDan Gohman <gohman@apple.com>
Thu, 26 Aug 2010 18:12:22 +0000 (18:12 +0000)
committerDan Gohman <gohman@apple.com>
Thu, 26 Aug 2010 18:12:22 +0000 (18:12 +0000)
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

utils/vim/vimrc

index 8ae3e678cfeaf05badf011b3b346de45f904400a..8b029daba58445ead0f08df0f35582a5c1cbc9fc 100644 (file)
@@ -91,3 +91,127 @@ augroup END
 "set showmode
 "set incsearch
 "set ruler
+
+" Clang code-completion support. This is highly experimental!
+
+" TODO: code-completing on
+"          cast_cast<
+" turns up some peculiarities -- "asm("? 
+
+" A path to the a executable.
+let g:clang_path = "Release/bin/clang++"
+
+" A list of options to add to the clang commandline, for example to add
+" include paths, predefined macros, and language options.
+let g:clang_opts = [
+  \ "-x","c++",
+  \ "-D__STDC_LIMIT_MACROS=1","-D__STDC_CONSTANT_MACROS=1",
+  \ "-Iinclude" ]
+
+function! ClangComplete(findstart, base)
+   if a:findstart == 1
+      " In findstart mode, look for the beginning of the current identifier.
+      let l:line = getline('.')
+      let l:start = col('.') - 1
+      while l:start > 0 && l:line[l:start - 1] =~ '\i'
+         let l:start -= 1
+      endwhile
+      return l:start
+   endif
+
+   " Get the current line and column numbers.
+   let l:l = line('.')
+   let l:c = col('.')
+
+   " Build a clang commandline to do code completion on stdin.
+   let l:the_command = shellescape(g:clang_path) .
+                     \ " -cc1 -code-completion-at=-:" . l:l . ":" . l:c
+   for l:opt in g:clang_opts
+      let l:the_command .= " " . shellescape(l:opt)
+   endfor
+
+   " Copy the contents of the current buffer into a string for stdin.
+   " TODO: The extra space at the end is for working around clang's
+   " apparent inability to do code completion at the very end of the
+   " input.
+   " TODO: Is it better to feed clang the entire file instead of truncating
+   " it at the current line?
+   let l:process_input = join(getline(1, l:l), "\n") . " "
+
+   " Run it!
+   let l:input_lines = split(system(l:the_command, l:process_input), "\n")
+
+   " Parse the output.
+   for l:input_line in l:input_lines
+      " Vim's substring operator is annoyingly inconsistent with python's.
+      if l:input_line[:11] == 'COMPLETION: '
+         let l:value = l:input_line[12:]
+
+        " Chop off anything after " : ", if present, and move it to the menu.
+        let l:menu = ""
+        let l:spacecolonspace = stridx(l:value, " : ")
+        if l:spacecolonspace != -1
+           let l:menu = l:value[l:spacecolonspace+3:]
+           let l:value = l:value[:l:spacecolonspace-1]
+        endif
+
+        " Handle Pattern. TODO: Make clang less weird.
+        if l:value == "Pattern"
+           let l:value = l:menu
+           let l:pound = stridx(l:value, "#")
+           " Truncate the at the first [#, <#, or {#.
+           if l:pound != -1
+              let l:value = l:value[:l:pound-2]
+           endif
+        endif
+
+         " Filter out results which don't match the base string.
+         if a:base != ""
+            if l:value[:strlen(a:base)-1] != a:base
+               continue
+            end
+         endif
+
+        " TODO: Don't dump the raw input into info, though it's nice for now.
+        " TODO: The kind string?
+        let l:item = {
+          \ "word": l:value,
+          \ "menu": l:menu,
+          \ "info": l:input_line,
+          \ "dup": 1 }
+
+        " Report a result.
+        if complete_add(l:item) == 0
+           return []
+        endif
+        if complete_check()
+           return []
+        endif
+
+      elseif l:input_line[:9] == "OVERLOAD: "
+         " An overload candidate. Use a crazy hack to get vim to
+         " display the results. TODO: Make this better.
+         let l:value = l:input_line[10:]
+         let l:item = {
+           \ "word": " ",
+           \ "menu": l:value,
+           \ "info": l:input_line,
+           \ "dup": 1}
+
+        " Report a result.
+        if complete_add(l:item) == 0
+           return []
+        endif
+        if complete_check()
+           return []
+        endif
+
+      endif
+   endfor
+
+
+   return []
+endfunction ClangComplete
+
+" Uncomment this to enable the highly-broken autocompletion support.
+"set omnifunc=ClangComplete