1 " Vimball Archiver by Charles E. Campbell, Jr., Ph.D.
4 autoload/snippets/clang_complete.vim [[[1
6 " clang_complete clang_complete's snippet generator
7 " Author: Xavier Deguillard, Philippe Vaucher
9 function! snippets#clang_complete#init()
10 noremap <expr> <silent> <buffer> <tab> UpdateSnips()
11 snoremap <expr> <silent> <buffer> <tab> UpdateSnips()
12 syntax match Conceal /<#/ conceal
13 syntax match Conceal /#>/ conceal
16 " fullname = strcat(char *dest, const char *src)
17 " args_pos = [ [8, 17], [20, 34] ]
18 function! snippets#clang_complete#add_snippet(fullname, args_pos)
22 let l:res .= a:fullname[l:prev_idx : elt[0] - 1] . '<#' . a:fullname[elt[0] : elt[1] - 1] . '#>'
23 let l:prev_idx = elt[1]
26 let l:res .= a:fullname[l:prev_idx : ]
31 function! snippets#clang_complete#trigger()
35 function! snippets#clang_complete#reset()
39 " ---------------- Helpers ----------------
41 function! UpdateSnips()
42 let l:line = getline('.')
43 let l:pattern = '<#[^#]*#>'
44 if match(l:line, l:pattern) == -1
50 let l:commands .= "\<esc>"
53 let l:commands .= ":call MoveToCCSnippetBegin()\<CR>"
54 let l:commands .= "m'"
55 let l:commands .= ":call MoveToCCSnippetEnd()\<CR>"
57 if &selection == "exclusive"
58 let l:commands .= "ll"
63 let l:commands .= "v`'o\<C-G>"
68 function! MoveToCCSnippetBegin()
70 let l:line = getline('.')
71 let l:startpos = col('.') + 1
72 let l:ind = match(l:line, l:pattern, l:startpos)
74 let l:ind = match(l:line, l:pattern, 0)
76 call cursor(line('.'), l:ind + 1)
79 function! MoveToCCSnippetEnd()
80 let l:line = getline('.')
82 let l:startpos = col('.') + 2
84 call cursor(line('.'), match(l:line, l:pattern, l:startpos) + 1)
87 function! s:BeginSnips()
92 " Do we need to launch UpdateSnippets()?
93 let l:line = getline('.')
94 let l:pattern = '<#[^#]*#>'
95 if match(l:line, l:pattern) == -1
98 call feedkeys("\<esc>^\<tab>")
101 " vim: set ts=2 sts=2 sw=2 expandtab :
102 autoload/snippets/dummy.vim [[[1
104 " Prepare the snippet engine
105 function! snippets#dummy#init()
106 echo 'Initializing stuffs'
109 " Add a snippet to be triggered
110 " fullname: contain an unmangled name. ex: strcat(char *dest, const char *src)
111 " args_pos: contain the position of the argument in fullname. ex [ [8, 17], [20, 34] ]
112 " Returns: text to be inserted for when trigger() is called
113 function! snippets#dummy#add_snippet(fullname, args_pos)
114 echo 'Creating snippet for "' . a:fullname
118 " Trigger the snippet
119 " Note: usually as simple as triggering the tab key
120 function! snippets#dummy#trigger()
121 echo 'Triggering snippet'
124 " Remove all snippets
125 function! snippets#dummy#reset()
126 echo 'Resetting all snippets'
128 autoload/snippets/snipmate.vim [[[1
130 " clang_complete snipmate's snippet generator
131 " Author: Philippe Vaucher
133 function! snippets#snipmate#init()
134 call snippets#snipmate#reset()
137 " fullname = strcat(char *dest, const char *src)
138 " args_pos = [ [8, 17], [20, 34] ]
139 function! snippets#snipmate#add_snippet(fullname, args_pos)
140 " If we are already in a snipmate snippet, well not much we can do until snipmate supports nested snippets
141 if exists('g:snipPos')
148 for elt in a:args_pos
149 let l:snip .= a:fullname[l:prev_idx : elt[0] - 1] . '${' . l:snip_idx . ':' . a:fullname[elt[0] : elt[1] - 1] . '}'
151 let l:prev_idx = elt[1]
154 let l:snip .= a:fullname[l:prev_idx : ] . '${' . l:snip_idx . '}'
156 let l:snippet_id = substitute(a:fullname, ' ', '_', 'g')
158 call MakeSnip(&filetype, l:snippet_id, l:snip)
163 function! snippets#snipmate#trigger()
164 " If we are already in a snipmate snippet, well not much we can do until snipmate supports nested snippets
165 if exists('g:snipPos')
170 call feedkeys("\<Tab>", 't')
173 function! snippets#snipmate#reset()
174 " Quick & Easy way to prevent snippets to be added twice
175 " Ideally we should modify snipmate to be smarter about this
176 call ReloadSnippets(&filetype)
179 " vim: set ts=2 sts=2 sw=2 expandtab :
180 autoload/snippets/ultisnips.vim [[[1
182 " clang_complete ultisnips's snippet generator
183 " Author: Philippe Vaucher
185 function! snippets#ultisnips#init()
186 call snippets#ultisnips#reset()
189 " fullname = strcat(char *dest, const char *src)
190 " args_pos = [ [8, 17], [20, 34] ]
191 function! snippets#ultisnips#add_snippet(fullname, args_pos)
195 for elt in a:args_pos
196 let l:snip .= a:fullname[l:prev_idx : elt[0] - 1] . '${' . l:snip_idx . ':' . a:fullname[elt[0] : elt[1] - 1] . '}'
198 let l:prev_idx = elt[1]
201 let l:snip .= a:fullname[l:prev_idx : ] . '${' . l:snip_idx . '}'
203 let l:snippet_id = substitute(a:fullname, ' ', '_', 'g')
205 call UltiSnips_AddSnippet(l:snippet_id, l:snip, a:fullname, 'i', &filetype)
210 function! snippets#ultisnips#trigger()
211 call UltiSnips_ExpandSnippet()
214 function! snippets#ultisnips#reset()
215 python UltiSnips_Manager.reset()
218 " vim: set ts=2 sts=2 sw=2 expandtab :
221 #!/usr/bin/env python
222 #-*- coding: utf-8 -*-
227 CONFIG_NAME = ".clang_complete"
229 def readConfiguration():
231 f = open(CONFIG_NAME, "r")
236 for line in f.readlines():
237 strippedLine = line.strip()
238 if len(strippedLine) > 0:
239 result += [strippedLine]
243 def writeConfiguration(lines):
244 f = open(CONFIG_NAME, "w")
248 def parseArguments(arguments):
249 nextIsInclude = False
251 nextIsIncludeFile = False
257 for arg in arguments:
260 nextIsInclude = False
264 elif nextIsIncludeFile:
265 include_file += [arg]
266 nextIsIncludeFile = False
271 elif arg[:2] == "-I":
272 includes += [arg[2:]]
273 elif arg[:2] == "-D":
275 elif arg == "-include":
276 nextIsIncludeFile = True
278 result = map(lambda x: "-I" + x, includes)
279 result += map(lambda x: "-D" + x, defines)
280 result += map(lambda x: "-include " + x, include_file)
284 def mergeLists(base, new):
288 result.index(newLine)
293 configuration = readConfiguration()
294 args = parseArguments(sys.argv)
295 result = mergeLists(configuration, args)
296 writeConfiguration(map(lambda x: x + "\n", result))
299 status = os.system(" ".join(sys.argv[1:]))
300 if not os.WIFEXITED(status):
302 sys.exit(os.WEXITSTATUS(status))
304 # vim: set ts=2 sts=2 sw=2 expandtab :
305 doc/clang_complete.txt [[[1
307 *clang_complete.txt* For Vim version 7.3. Last change: 2011 Jun 04
310 clang_complete plugin documentation
313 clang_complete plugin *clang_complete*
315 1. Description |clang_complete-description|
316 2. Completion kinds |clang_complete-compl_kinds|
317 3. Configuration |clang_complete-configuration|
318 4. Options |clang_complete-options|
319 5. Known issues |clang_complete-issues|
320 6. PCH |clang_complete-pch|
321 7. cc_args.py script |clang_complete-cc_args|
322 8. To do |clang_complete-todo|
323 9. License |clang_complete-license|
325 Author: Xavier Deguillard <deguilx@gmail.com> *clang_complete-author*
327 ==============================================================================
328 1. Description *clang_complete-description*
330 This plugin use clang for accurately completing C and C++ code.
332 Note: This plugin is incompatible with omnicppcomplete due to the
333 unconditionnaly set mapping done by omnicppcomplete. So don't forget to
334 suppress it before using this plugin.
336 ==============================================================================
337 2. Completion kinds *clang_complete-compl_kinds*
339 Because libclang provides a lot of information about completion, there are
340 some additional kinds of completion along with standard ones (see >
345 'e' - enumerator constant
346 'a' - parameter ('a' from "argument") of a function, method or template
347 'u' - unknown or buildin type (int, float, ...)
348 'n' - namespace or its alias
349 'p' - template ('p' from "pattern")
351 ==============================================================================
352 3. Configuration *clang_complete-configuration*
354 Each project can have a .clang_complete at his root, containing the compiler
355 options. This is useful if you're using some non-standard include paths. For
356 simplicity, please don't put relative and absolute include path on the same
357 line. It is not currently correctly handled.
359 ==============================================================================
360 4. Options *clang_complete-options*
362 *clang_complete-auto_select*
363 *g:clang_auto_select*
364 If equal to 0, nothing is selected.
365 If equal to 1, automatically select the first entry in the popup menu, but
366 without inserting it into the code.
367 If equal to 2, automatically select the first entry in the popup menu, and
368 insert it into the code.
371 *clang_complete-complete_auto*
372 *g:clang_complete_auto*
373 If equal to 1, automatically complete after ->, ., ::
376 *clang_complete-copen*
377 *g:clang_complete_copen*
378 If equal to 1, open quickfix window on error.
381 *clang_complete-hl_errors*
383 If equal to 1, it will highlight the warnings and errors the same way clang
387 *clang_complete-periodic_quickfix*
388 *g:clang_periodic_quickfix*
389 If equal to 1, it will periodically update the quickfix window.
391 Note: You could use the g:ClangUpdateQuickFix() to do the same with a mapping.
393 *clang_complete-snippets*
395 If equal to 1, it will do some snippets magic after a ( or a , inside function
396 call. Not currently fully working.
399 *clang_complete-snippets_engine*
400 *g:clang_snippets_engine*
401 The snippets engine (clang_complete, snipmate, ultisnips... see the snippets
403 Default: "clang_complete"
405 *clang_complete-conceal_snippets*
406 *g:clang_conceal_snippets*
407 If equal to 1, vim will use vim 7.3 conceal feature to hide <# and #> which
409 Default: 1 (0 if conceal not available)
410 Note: See concealcursor and conceallevel for conceal configuration.
412 *clang_complete-exec*
414 Name or path of clang executable.
415 Note: Use this if clang has a non-standard name, or isn't in the path.
418 *clang_complete-user_options*
419 *g:clang_user_options*
420 Option added at the end of clang command. Useful if you want to filter the
421 result, or do other stuffs. To ignore the error code returned by clang, set
422 |g:clang_exec| to `"clang` and |g:clang_user_options| to `2>/dev/null || exit
423 0"` if you're on *nix, or `2>NUL || exit 0"` if you are on windows.
426 *clang_complete-auto_user_options*
427 *g:clang_auto_user_options*
428 Set sources for user options passed to clang. Available sources are:
429 - path - use &path content as list of include directories (relative paths are
431 - .clang_complete - use information from .clang_complete file Multiple options
432 are separated by comma.
433 Default: "path, .clang_complete"
435 *clang_complete-use_library*
436 *g:clang_use_library*
437 Instead of calling the clang/clang++ tool use libclang directly. This gives
438 access to many more clang features. Furthermore it automatically caches all
439 includes in memory. Updates after changes in the same file will therefore be a
443 *clang_complete-library_path*
444 *g:clang_library_path*
445 If libclang.[dll/so/dylib] is not in your library search path, set this to the
446 absolute path where libclang is available.
449 *clang_complete-sort_algo*
451 How results are sorted (alpha, priority). Currently only works with libclang.
454 *clang_complete-complete_macros*
455 *g:clang_complete_macros*
456 If clang should complete preprocessor macros and constants.
459 *clang_complete-complete_patterns*
460 *g:clang_complete_patterns*
461 If clang should complete code patterns, i.e loop constructs etc.
464 ==============================================================================
465 5. Known issues *clang_complete-issues*
467 If you find that completion is slow, please read the |clang_complete-pch|
470 If you get following error message while trying to complete anything: >
471 E121: Undefined variable: b:should_overload
472 it means that your version of Vim is too old (this is an old bug and it has
473 been fixed with one of patches for Vim 7.2) and you need to update it.
475 If clang is not able to compile your file, it cannot complete anything. Since
476 clang is not supporting every C++0x features, this is normal if it can do any
477 completion on C++0x file.
479 There is no difference in clang's output between private methods/members and
480 public ones. Which means that I cannot filter private methods on the
483 ==============================================================================
484 6. PCH *clang_complete-pch*
486 In case you can not or you do not want to install libclang, a precompiled
487 header file is another way to accelerate compilation, and so, to accelerate
488 the completion. It is however more complicated to install and is still slower
489 than the use of libclang.
491 Here is how to create the <vector> pch, on linux (OSX users may use
492 -fnext-runtime instead of -fgnu-runtime): >
493 clang -x c++-header /path/to/c++/vector -fno-exceptions -fgnu-runtime \
495 You just have to insert it into your .clang_complete: >
496 echo '-include-pch /path/to/vector.pch -fgnu-runtime' >> .clang_complete
498 One of the major problem is that you cannot include more that one pch, the
499 solution is to put the system headers or non changing headers into another
500 header and then compile it to pch: >
501 echo '#include <iostream>\n#include <vector>' > pchheader.h
502 clang -x c++-header ./pchheader.h -fno-exceptions -fnu-runtime \
504 And then add it to the .clang_complete file.
506 ==============================================================================
507 7. cc_args.py script *clang_complete-cc_args*
509 This script, installed at ~/.vim/bin/cc_args.py, could be used to generate or
510 update the .clang_complete file. It works similar to gccsence's gccrec and
511 simply stores -I and -D arguments passed to the compiler in the
512 .clang_complete file. Just add the cc_args.py script as the first argument of
513 the compile command. You should do that every time compile options have
516 Example (we need -B flag to force compiling even if project is up to date): >
517 make CC='~/.vim/bin/cc_args.py gcc' CXX='~/.vim/bin/cc_args.py g++' -B
518 After running this command, .clang_complete will be created or updated with
519 new options. If you don't want to update an existing configuration file,
520 delete it before running make.
522 ==============================================================================
523 8. To do *clang_complete-todo*
525 - Write some unit tests
526 - clang vs libclang accuracy for complex completions
527 - clang vs libclang timing
528 - Explore "jump to declaration/definition" with libclang FGJ
529 - Think about supertab (<C-X><C-U> with supertab and clang_auto_select)
530 - Parse fix-its and do something useful with it
532 ==============================================================================
533 9. License *clang_complete-license*
535 Copyright (c) 2010, 2011, Xavier Deguillard
538 Redistribution and use in source and binary forms, with or without
539 modification, are permitted provided that the following conditions are met:
540 * Redistributions of source code must retain the above copyright
541 notice, this list of conditions and the following disclaimer.
542 * Redistributions in binary form must reproduce the above copyright
543 notice, this list of conditions and the following disclaimer in the
544 documentation and/or other materials provided with the distribution.
545 * Neither the name of Xavier Deguillard nor the
546 names of its contributors may be used to endorse or promote products
547 derived from this software without specific prior written permission.
549 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
550 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
551 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
552 DISCLAIMED. IN NO EVENT SHALL XAVIER DEGUILLARD BE LIABLE FOR ANY
553 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
554 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
555 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
556 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
557 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
558 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
560 Note: This license does not cover the files that come from the LLVM project,
561 namely, cindex.py and __init__.py, which are covered by the LLVM license.
563 vim:tw=78:ts=8:ft=help:norl:
564 plugin/clang/__init__.py [[[1
566 #===- __init__.py - Clang Python Bindings --------------------*- python -*--===#
568 # The LLVM Compiler Infrastructure
570 # This file is distributed under the University of Illinois Open Source
571 # License. See LICENSE.TXT for details.
573 #===------------------------------------------------------------------------===#
576 Clang Library Bindings
577 ======================
579 This package provides access to the Clang compiler and libraries.
581 The available modules are:
585 Bindings for the Clang indexing library.
590 plugin/clang/cindex.py [[[1
592 #===- cindex.py - Python Indexing Library Bindings -----------*- python -*--===#
594 # The LLVM Compiler Infrastructure
596 # This file is distributed under the University of Illinois Open Source
597 # License. See LICENSE.TXT for details.
599 #===------------------------------------------------------------------------===#
602 Clang Indexing Library Bindings
603 ===============================
605 This module provides an interface to the Clang indexing library. It is a
606 low-level interface to the indexing library which attempts to match the Clang
607 API directly while also being "pythonic". Notable differences from the C API
610 * string results are returned as Python strings, not CXString objects.
612 * null cursors are translated to None.
614 * access to child cursors is done via iteration, not visitation.
616 The major indexing objects are:
620 The top-level object which manages some global library state.
624 High-level object encapsulating the AST for a single translation unit. These
625 can be loaded from .ast files or parsed on the fly.
629 Generic object for representing a node in the AST.
631 SourceRange, SourceLocation, and File
633 Objects representing information about the input source.
635 Most object information is exposed using properties, when the underlying API
642 # o API support for invalid translation units. Currently we can't even get the
643 # diagnostics on failure because they refer to locations in an object that
644 # will have been invalidated.
646 # o fix memory management issues (currently client must hold on to index and
647 # translation unit, or risk crashes).
649 # o expose code completion APIs.
651 # o cleanup ctypes wrapping, would be nice to separate the ctypes details more
652 # clearly, and hide from the external interface (i.e., help(cindex)).
654 # o implement additional SourceLocation, SourceRange, and File methods.
659 def get_cindex_library():
660 # FIXME: It's probably not the case that the library is actually found in
661 # this location. We need a better system of identifying and loading the
662 # CIndex library. It could be on path or elsewhere, or versioned, etc.
664 name = platform.system()
669 path += 'libclang.dylib'
670 elif name == 'Windows':
671 path += 'libclang.dll'
673 path += 'libclang.so'
674 return cdll.LoadLibrary(path)
676 # ctypes doesn't implicitly convert c_void_p to the appropriate wrapper
677 # object. This is a problem, because it means that from_parameter will see an
678 # integer and pass the wrong value on platforms where int != void*. Work around
679 # this by marshalling object arguments as void**.
680 c_object_p = POINTER(c_void_p)
682 lib = get_cindex_library()
684 ### Structures and Utility Classes ###
686 class _CXString(Structure):
687 """Helper for transforming CXString results."""
689 _fields_ = [("spelling", c_char_p), ("free", c_int)]
692 _CXString_dispose(self)
695 def from_result(res, fn, args):
696 assert isinstance(res, _CXString)
697 return _CXString_getCString(res)
699 class SourceLocation(Structure):
701 A SourceLocation represents a particular location within a source file.
703 _fields_ = [("ptr_data", c_void_p * 2), ("int_data", c_uint)]
706 def _get_instantiation(self):
707 if self._data is None:
708 f, l, c, o = c_object_p(), c_uint(), c_uint(), c_uint()
709 SourceLocation_loc(self, byref(f), byref(l), byref(c), byref(o))
714 self._data = (f, int(l.value), int(c.value), int(c.value))
719 """Get the file represented by this source location."""
720 return self._get_instantiation()[0]
724 """Get the line represented by this source location."""
725 return self._get_instantiation()[1]
729 """Get the column represented by this source location."""
730 return self._get_instantiation()[2]
734 """Get the file offset represented by this source location."""
735 return self._get_instantiation()[3]
739 filename = self.file.name
742 return "<SourceLocation file %r, line %r, column %r>" % (
743 filename, self.line, self.column)
745 class SourceRange(Structure):
747 A SourceRange describes a range of source locations within the source
751 ("ptr_data", c_void_p * 2),
752 ("begin_int_data", c_uint),
753 ("end_int_data", c_uint)]
755 # FIXME: Eliminate this and make normal constructor? Requires hiding ctypes
758 def from_locations(start, end):
759 return SourceRange_getRange(start, end)
764 Return a SourceLocation representing the first character within a
767 return SourceRange_start(self)
772 Return a SourceLocation representing the last character within a
775 return SourceRange_end(self)
778 return "<SourceRange start %r, end %r>" % (self.start, self.end)
780 class Diagnostic(object):
782 A Diagnostic is a single instance of a Clang diagnostic. It includes the
783 diagnostic severity, the message, the location the diagnostic occurred, as
784 well as additional source ranges and associated fix-it hints.
793 def __init__(self, ptr):
797 _clang_disposeDiagnostic(self)
801 return _clang_getDiagnosticSeverity(self)
805 return _clang_getDiagnosticLocation(self)
809 return _clang_getDiagnosticSpelling(self)
814 def __init__(self, diag):
818 return int(_clang_getDiagnosticNumRanges(self.diag))
820 def __getitem__(self, key):
821 if (key >= len(self)):
823 return _clang_getDiagnosticRange(self.diag, key)
825 return RangeIterator(self)
830 def __init__(self, diag):
834 return int(_clang_getDiagnosticNumFixIts(self.diag))
836 def __getitem__(self, key):
837 range = SourceRange()
838 value = _clang_getDiagnosticFixIt(self.diag, key, byref(range))
842 return FixIt(range, value)
844 return FixItIterator(self)
847 return "<Diagnostic severity %r, location %r, spelling %r>" % (
848 self.severity, self.location, self.spelling)
850 def from_param(self):
855 A FixIt represents a transformation to be applied to the source to
856 "fix-it". The fix-it shouldbe applied by replacing the given source range
857 with the given value.
860 def __init__(self, range, value):
865 return "<FixIt range %r, value %r>" % (self.range, self.value)
869 class CursorKind(object):
871 A CursorKind describes the kind of entity that a cursor points to.
874 # The unique kind objects, indexed by id.
878 def __init__(self, value):
879 if value >= len(CursorKind._kinds):
880 CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
881 if CursorKind._kinds[value] is not None:
882 raise ValueError,'CursorKind already loaded'
884 CursorKind._kinds[value] = self
885 CursorKind._name_map = None
887 def from_param(self):
892 """Get the enumeration name of this cursor kind."""
893 if self._name_map is None:
895 for key,value in CursorKind.__dict__.items():
896 if isinstance(value,CursorKind):
897 self._name_map[value] = key
898 return self._name_map[self]
902 if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
903 raise ValueError,'Unknown cursor kind'
904 return CursorKind._kinds[id]
908 """Return all CursorKind enumeration instances."""
909 return filter(None, CursorKind._kinds)
911 def is_declaration(self):
912 """Test if this is a declaration kind."""
913 return CursorKind_is_decl(self)
915 def is_reference(self):
916 """Test if this is a reference kind."""
917 return CursorKind_is_ref(self)
919 def is_expression(self):
920 """Test if this is an expression kind."""
921 return CursorKind_is_expr(self)
923 def is_statement(self):
924 """Test if this is a statement kind."""
925 return CursorKind_is_stmt(self)
927 def is_invalid(self):
928 """Test if this is an invalid kind."""
929 return CursorKind_is_inv(self)
932 return 'CursorKind.%s' % (self.name,)
934 # FIXME: Is there a nicer way to expose this enumeration? We could potentially
935 # represent the nested structure, or even build a class hierarchy. The main
936 # things we want for sure are (a) simple external access to kinds, (b) a place
937 # to hang a description and name, (c) easy to keep in sync with Index.h.
942 # A declaration whose specific kind is not exposed via this interface.
944 # Unexposed declarations have the same operations as any other kind of
945 # declaration; one can extract their location information, spelling, find their
946 # definitions, etc. However, the specific kind of the declaration is not
948 CursorKind.UNEXPOSED_DECL = CursorKind(1)
951 CursorKind.STRUCT_DECL = CursorKind(2)
954 CursorKind.UNION_DECL = CursorKind(3)
957 CursorKind.CLASS_DECL = CursorKind(4)
960 CursorKind.ENUM_DECL = CursorKind(5)
962 # A field (in C) or non-static data member (in C++) in a struct, union, or C++
964 CursorKind.FIELD_DECL = CursorKind(6)
966 # An enumerator constant.
967 CursorKind.ENUM_CONSTANT_DECL = CursorKind(7)
970 CursorKind.FUNCTION_DECL = CursorKind(8)
973 CursorKind.VAR_DECL = CursorKind(9)
975 # A function or method parameter.
976 CursorKind.PARM_DECL = CursorKind(10)
978 # An Objective-C @interface.
979 CursorKind.OBJC_INTERFACE_DECL = CursorKind(11)
981 # An Objective-C @interface for a category.
982 CursorKind.OBJC_CATEGORY_DECL = CursorKind(12)
984 # An Objective-C @protocol declaration.
985 CursorKind.OBJC_PROTOCOL_DECL = CursorKind(13)
987 # An Objective-C @property declaration.
988 CursorKind.OBJC_PROPERTY_DECL = CursorKind(14)
990 # An Objective-C instance variable.
991 CursorKind.OBJC_IVAR_DECL = CursorKind(15)
993 # An Objective-C instance method.
994 CursorKind.OBJC_INSTANCE_METHOD_DECL = CursorKind(16)
996 # An Objective-C class method.
997 CursorKind.OBJC_CLASS_METHOD_DECL = CursorKind(17)
999 # An Objective-C @implementation.
1000 CursorKind.OBJC_IMPLEMENTATION_DECL = CursorKind(18)
1002 # An Objective-C @implementation for a category.
1003 CursorKind.OBJC_CATEGORY_IMPL_DECL = CursorKind(19)
1006 CursorKind.TYPEDEF_DECL = CursorKind(20)
1011 CursorKind.OBJC_SUPER_CLASS_REF = CursorKind(40)
1012 CursorKind.OBJC_PROTOCOL_REF = CursorKind(41)
1013 CursorKind.OBJC_CLASS_REF = CursorKind(42)
1015 # A reference to a type declaration.
1017 # A type reference occurs anywhere where a type is named but not
1018 # declared. For example, given:
1019 # typedef unsigned size_type;
1022 # The typedef is a declaration of size_type (CXCursor_TypedefDecl),
1023 # while the type of the variable "size" is referenced. The cursor
1024 # referenced by the type of size is the typedef for size_type.
1025 CursorKind.TYPE_REF = CursorKind(43)
1028 # Invalid/Error Kinds
1030 CursorKind.INVALID_FILE = CursorKind(70)
1031 CursorKind.NO_DECL_FOUND = CursorKind(71)
1032 CursorKind.NOT_IMPLEMENTED = CursorKind(72)
1037 # An expression whose specific kind is not exposed via this interface.
1039 # Unexposed expressions have the same operations as any other kind of
1040 # expression; one can extract their location information, spelling, children,
1041 # etc. However, the specific kind of the expression is not reported.
1042 CursorKind.UNEXPOSED_EXPR = CursorKind(100)
1044 # An expression that refers to some value declaration, such as a function,
1045 # varible, or enumerator.
1046 CursorKind.DECL_REF_EXPR = CursorKind(101)
1048 # An expression that refers to a member of a struct, union, class, Objective-C
1050 CursorKind.MEMBER_REF_EXPR = CursorKind(102)
1052 # An expression that calls a function.
1053 CursorKind.CALL_EXPR = CursorKind(103)
1055 # An expression that sends a message to an Objective-C object or class.
1056 CursorKind.OBJC_MESSAGE_EXPR = CursorKind(104)
1058 # A statement whose specific kind is not exposed via this interface.
1060 # Unexposed statements have the same operations as any other kind of statement;
1061 # one can extract their location information, spelling, children, etc. However,
1062 # the specific kind of the statement is not reported.
1063 CursorKind.UNEXPOSED_STMT = CursorKind(200)
1068 # Cursor that represents the translation unit itself.
1070 # The translation unit cursor exists primarily to act as the root cursor for
1071 # traversing the contents of a translation unit.
1072 CursorKind.TRANSLATION_UNIT = CursorKind(300)
1076 class Cursor(Structure):
1078 The Cursor class represents a reference to an element within the AST. It
1079 acts as a kind of iterator.
1081 _fields_ = [("_kind_id", c_int), ("data", c_void_p * 3)]
1083 def __eq__(self, other):
1084 return Cursor_eq(self, other)
1086 def __ne__(self, other):
1087 return not Cursor_eq(self, other)
1089 def is_definition(self):
1091 Returns true if the declaration pointed at by the cursor is also a
1092 definition of that entity.
1094 return Cursor_is_def(self)
1096 def get_definition(self):
1098 If the cursor is a reference to a declaration or a declaration of
1099 some entity, return a cursor that points to the definition of that
1102 # TODO: Should probably check that this is either a reference or
1103 # declaration prior to issuing the lookup.
1104 return Cursor_def(self)
1107 """Return the Unified Symbol Resultion (USR) for the entity referenced
1108 by the given cursor (or None).
1110 A Unified Symbol Resolution (USR) is a string that identifies a
1111 particular entity (function, class, variable, etc.) within a
1112 program. USRs can be compared across translation units to determine,
1113 e.g., when references in one translation refer to an entity defined in
1114 another translation unit."""
1115 return Cursor_usr(self)
1119 """Return the kind of this cursor."""
1120 return CursorKind.from_id(self._kind_id)
1124 """Return the spelling of the entity pointed at by the cursor."""
1125 if not self.kind.is_declaration():
1126 # FIXME: clang_getCursorSpelling should be fixed to not assert on
1127 # this, for consistency with clang_getCursorUSR.
1129 return Cursor_spelling(self)
1134 Return the source location (the starting character) of the entity
1135 pointed at by the cursor.
1137 return Cursor_loc(self)
1142 Return the source range (the range of text) occupied by the entity
1143 pointed at by the cursor.
1145 return Cursor_extent(self)
1147 def get_children(self):
1148 """Return an iterator for accessing the children of this cursor."""
1150 # FIXME: Expose iteration from CIndex, PR6125.
1151 def visitor(child, parent, children):
1152 # FIXME: Document this assertion in API.
1153 # FIXME: There should just be an isNull method.
1154 assert child != Cursor_null()
1155 children.append(child)
1158 Cursor_visit(self, Cursor_visit_callback(visitor), children)
1159 return iter(children)
1162 def from_result(res, fn, args):
1163 assert isinstance(res, Cursor)
1164 # FIXME: There should just be an isNull method.
1165 if res == Cursor_null():
1169 ## CIndex Objects ##
1171 # CIndex objects (derived from ClangObject) are essentially lightweight
1172 # wrappers attached to some underlying object, which is exposed via CIndex as
1175 class ClangObject(object):
1177 A helper for Clang objects. This class helps act as an intermediary for
1178 the ctypes library and the Clang CIndex library.
1180 def __init__(self, obj):
1181 assert isinstance(obj, c_object_p) and obj
1182 self.obj = self._as_parameter_ = obj
1184 def from_param(self):
1185 return self._as_parameter_
1188 class _CXUnsavedFile(Structure):
1189 """Helper for passing unsaved file arguments."""
1190 _fields_ = [("name", c_char_p), ("contents", c_char_p), ('length', c_ulong)]
1192 ## Diagnostic Conversion ##
1194 _clang_getNumDiagnostics = lib.clang_getNumDiagnostics
1195 _clang_getNumDiagnostics.argtypes = [c_object_p]
1196 _clang_getNumDiagnostics.restype = c_uint
1198 _clang_getDiagnostic = lib.clang_getDiagnostic
1199 _clang_getDiagnostic.argtypes = [c_object_p, c_uint]
1200 _clang_getDiagnostic.restype = c_object_p
1202 _clang_disposeDiagnostic = lib.clang_disposeDiagnostic
1203 _clang_disposeDiagnostic.argtypes = [Diagnostic]
1205 _clang_getDiagnosticSeverity = lib.clang_getDiagnosticSeverity
1206 _clang_getDiagnosticSeverity.argtypes = [Diagnostic]
1207 _clang_getDiagnosticSeverity.restype = c_int
1209 _clang_getDiagnosticLocation = lib.clang_getDiagnosticLocation
1210 _clang_getDiagnosticLocation.argtypes = [Diagnostic]
1211 _clang_getDiagnosticLocation.restype = SourceLocation
1213 _clang_getDiagnosticSpelling = lib.clang_getDiagnosticSpelling
1214 _clang_getDiagnosticSpelling.argtypes = [Diagnostic]
1215 _clang_getDiagnosticSpelling.restype = _CXString
1216 _clang_getDiagnosticSpelling.errcheck = _CXString.from_result
1218 _clang_getDiagnosticNumRanges = lib.clang_getDiagnosticNumRanges
1219 _clang_getDiagnosticNumRanges.argtypes = [Diagnostic]
1220 _clang_getDiagnosticNumRanges.restype = c_uint
1222 _clang_getDiagnosticRange = lib.clang_getDiagnosticRange
1223 _clang_getDiagnosticRange.argtypes = [Diagnostic, c_uint]
1224 _clang_getDiagnosticRange.restype = SourceRange
1226 _clang_getDiagnosticNumFixIts = lib.clang_getDiagnosticNumFixIts
1227 _clang_getDiagnosticNumFixIts.argtypes = [Diagnostic]
1228 _clang_getDiagnosticNumFixIts.restype = c_uint
1230 _clang_getDiagnosticFixIt = lib.clang_getDiagnosticFixIt
1231 _clang_getDiagnosticFixIt.argtypes = [Diagnostic, c_uint, POINTER(SourceRange)]
1232 _clang_getDiagnosticFixIt.restype = _CXString
1233 _clang_getDiagnosticFixIt.errcheck = _CXString.from_result
1237 class CompletionChunk:
1239 def __init__(self, name):
1246 return "<ChunkKind: %s>" % self
1248 def __init__(self, completionString, key):
1249 self.cs = completionString
1253 return "{'" + self.spelling + "', " + str(self.kind) + "}"
1257 return _clang_getCompletionChunkText(self.cs, self.key).spelling
1261 res = _clang_getCompletionChunkKind(self.cs, self.key)
1262 return completionChunkKindMap[res]
1266 res = _clang_getCompletionChunkCompletionString(self.cs, self.key)
1269 return CompletionString(res)
1273 def isKindOptional(self):
1274 return self.kind == completionChunkKindMap[0]
1276 def isKindTypedText(self):
1277 return self.kind == completionChunkKindMap[1]
1279 def isKindPlaceHolder(self):
1280 return self.kind == completionChunkKindMap[3]
1282 def isKindInformative(self):
1283 return self.kind == completionChunkKindMap[4]
1285 def isKindResultType(self):
1286 return self.kind == completionChunkKindMap[15]
1288 completionChunkKindMap = {
1289 0: CompletionChunk.Kind("Optional"),
1290 1: CompletionChunk.Kind("TypedText"),
1291 2: CompletionChunk.Kind("Text"),
1292 3: CompletionChunk.Kind("Placeholder"),
1293 4: CompletionChunk.Kind("Informative"),
1294 5: CompletionChunk.Kind("CurrentParameter"),
1295 6: CompletionChunk.Kind("LeftParen"),
1296 7: CompletionChunk.Kind("RightParen"),
1297 8: CompletionChunk.Kind("LeftBracket"),
1298 9: CompletionChunk.Kind("RightBracket"),
1299 10: CompletionChunk.Kind("LeftBrace"),
1300 11: CompletionChunk.Kind("RightBrace"),
1301 12: CompletionChunk.Kind("LeftAngle"),
1302 13: CompletionChunk.Kind("RightAngle"),
1303 14: CompletionChunk.Kind("Comma"),
1304 15: CompletionChunk.Kind("ResultType"),
1305 16: CompletionChunk.Kind("Colon"),
1306 17: CompletionChunk.Kind("SemiColon"),
1307 18: CompletionChunk.Kind("Equal"),
1308 19: CompletionChunk.Kind("HorizontalSpace"),
1309 20: CompletionChunk.Kind("VerticalSpace")}
1311 class CompletionString(ClangObject):
1313 def __init__(self, name):
1320 return "<Availability: %s>" % self
1323 return _clang_getNumCompletionChunks(self.obj)
1325 def __getitem__(self, key):
1326 if len(self) <= key:
1328 return CompletionChunk(self.obj, key)
1332 return _clang_getCompletionPriority(self.obj)
1335 def availability(self):
1336 res = _clang_getCompletionAvailability(self.obj)
1337 return availabilityKinds[res]
1340 return " | ".join([str(a) for a in self]) \
1341 + " || Priority: " + str(self.priority) \
1342 + " || Availability: " + str(self.availability)
1344 availabilityKinds = {
1345 0: CompletionChunk.Kind("Available"),
1346 1: CompletionChunk.Kind("Deprecated"),
1347 2: CompletionChunk.Kind("NotAvailable")}
1349 class CodeCompletionResult(Structure):
1350 _fields_ = [('cursorKind', c_int), ('completionString', c_object_p)]
1353 return str(CompletionString(self.completionString))
1357 return CompletionString(self.completionString)
1359 class CCRStructure(Structure):
1360 _fields_ = [('results', POINTER(CodeCompletionResult)),
1361 ('numResults', c_int)]
1364 return self.numResults
1366 def __getitem__(self, key):
1367 if len(self) <= key:
1370 return self.results[key]
1372 class CodeCompletionResults(ClangObject):
1373 def __init__(self, ptr):
1374 assert isinstance(ptr, POINTER(CCRStructure)) and ptr
1375 self.ptr = self._as_parameter_ = ptr
1377 def from_param(self):
1378 return self._as_parameter_
1381 CodeCompletionResults_dispose(self)
1385 return self.ptr.contents
1388 def diagnostics(self):
1389 class DiagnosticsItr:
1390 def __init__(self, ccr):
1394 return int(_clang_codeCompleteGetNumDiagnostics(self.ccr))
1396 def __getitem__(self, key):
1397 return _clang_codeCompleteGetDiagnostic(self.ccr, key)
1399 return DiagnosticsItr(self)
1401 class TranslationUnit(ClangObject):
1403 The TranslationUnit class represents a source code translation unit and
1404 provides read-only access to its top-level declarations.
1407 # enum CXTranslationUnit_Flags
1409 DetailedPreprocessingRecord = 0x01
1411 PrecompiledPreamble = 0x04
1412 CacheCompletionResults = 0x08
1413 CXXPrecompiledPreamble = 0x10
1414 CXXChainedPCH = 0x20
1416 def __init__(self, ptr):
1417 ClangObject.__init__(self, ptr)
1420 TranslationUnit_dispose(self)
1424 """Retrieve the cursor that represents the given translation unit."""
1425 return TranslationUnit_cursor(self)
1429 """Get the original translation unit source file name."""
1430 return TranslationUnit_spelling(self)
1432 def get_includes(self):
1434 Return an iterable sequence of FileInclusion objects that describe the
1435 sequence of inclusions in a translation unit. The first object in
1436 this sequence is always the input file. Note that this method will not
1437 recursively iterate over header files included through precompiled
1440 def visitor(fobj, lptr, depth, includes):
1442 includes.append(FileInclusion(loc.file, File(fobj), loc, depth))
1444 # Automatically adapt CIndex/ctype pointers to python objects
1446 TranslationUnit_includes(self,
1447 TranslationUnit_includes_callback(visitor),
1449 return iter(includes)
1452 def diagnostics(self):
1454 Return an iterable (and indexable) object containing the diagnostics.
1457 def __init__(self, tu):
1461 return int(_clang_getNumDiagnostics(self.tu))
1463 def __getitem__(self, key):
1464 diag = _clang_getDiagnostic(self.tu, key)
1467 return Diagnostic(diag)
1469 return DiagIterator(self)
1471 def reparse(self, unsaved_files = [], options = Nothing):
1473 Reparse an already parsed translation unit.
1475 In-memory contents for files can be provided by passing a list of pairs
1476 as unsaved_files, the first items should be the filenames to be mapped
1477 and the second should be the contents to be substituted for the
1478 file. The contents may be passed as strings or file objects.
1480 unsaved_files_array = 0
1481 if len(unsaved_files):
1482 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1483 for i,(name,value) in enumerate(unsaved_files):
1484 if not isinstance(value, str):
1485 # FIXME: It would be great to support an efficient version
1487 value = value.read()
1489 if not isinstance(value, str):
1490 raise TypeError,'Unexpected unsaved file contents.'
1491 unsaved_files_array[i].name = name
1492 unsaved_files_array[i].contents = value
1493 unsaved_files_array[i].length = len(value)
1494 ptr = TranslationUnit_reparse(self, len(unsaved_files),
1495 unsaved_files_array,
1497 def codeComplete(self, path, line, column, unsaved_files = [], options = 0):
1499 Code complete in this translation unit.
1501 In-memory contents for files can be provided by passing a list of pairs
1502 as unsaved_files, the first items should be the filenames to be mapped
1503 and the second should be the contents to be substituted for the
1504 file. The contents may be passed as strings or file objects.
1506 unsaved_files_array = 0
1507 if len(unsaved_files):
1508 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1509 for i,(name,value) in enumerate(unsaved_files):
1510 if not isinstance(value, str):
1511 # FIXME: It would be great to support an efficient version
1513 value = value.read()
1515 if not isinstance(value, str):
1516 raise TypeError,'Unexpected unsaved file contents.'
1517 unsaved_files_array[i].name = name
1518 unsaved_files_array[i].contents = value
1519 unsaved_files_array[i].length = len(value)
1520 ptr = TranslationUnit_codeComplete(self, path,
1522 unsaved_files_array,
1526 return CodeCompletionResults(ptr)
1530 class Index(ClangObject):
1532 The Index type provides the primary interface to the Clang CIndex library,
1533 primarily by providing an interface for reading and parsing translation
1538 def create(excludeDecls=False):
1542 excludeDecls -- Exclude local declarations from translation units.
1544 return Index(Index_create(excludeDecls, 0))
1549 def read(self, path):
1550 """Load the translation unit from the given AST file."""
1551 ptr = TranslationUnit_read(self, path)
1553 return TranslationUnit(ptr)
1556 def parse(self, path, args = [], unsaved_files = [], options = TranslationUnit.Nothing):
1558 Load the translation unit from the given source code file by running
1559 clang and generating the AST before loading. Additional command line
1560 parameters can be passed to clang via the args parameter.
1562 In-memory contents for files can be provided by passing a list of pairs
1563 to as unsaved_files, the first item should be the filenames to be mapped
1564 and the second should be the contents to be substituted for the
1565 file. The contents may be passed as strings or file objects.
1569 arg_array = (c_char_p * len(args))(* args)
1570 unsaved_files_array = 0
1571 if len(unsaved_files):
1572 unsaved_files_array = (_CXUnsavedFile * len(unsaved_files))()
1573 for i,(name,value) in enumerate(unsaved_files):
1574 if not isinstance(value, str):
1575 # FIXME: It would be great to support an efficient version
1577 value = value.read()
1579 if not isinstance(value, str):
1580 raise TypeError,'Unexpected unsaved file contents.'
1581 unsaved_files_array[i].name = name
1582 unsaved_files_array[i].contents = value
1583 unsaved_files_array[i].length = len(value)
1584 ptr = TranslationUnit_parse(self, path, arg_array, len(args),
1585 unsaved_files_array, len(unsaved_files),
1588 return TranslationUnit(ptr)
1591 class File(ClangObject):
1593 The File class represents a particular source file that is part of a
1599 """Return the complete file and path name of the file."""
1600 return File_name(self)
1604 """Return the last modification time of the file."""
1605 return File_time(self)
1607 class FileInclusion(object):
1609 The FileInclusion class represents the inclusion of one source file by
1610 another via a '#include' directive or as the input file for the translation
1611 unit. This class provides information about the included file, the including
1612 file, the location of the '#include' directive and the depth of the included
1613 file in the stack. Note that the input file has depth 0.
1616 def __init__(self, src, tgt, loc, depth):
1623 def is_input_file(self):
1624 """True if the included file is the input file."""
1625 return self.depth == 0
1627 # Additional Functions and Types
1630 _CXString_dispose = lib.clang_disposeString
1631 _CXString_dispose.argtypes = [_CXString]
1633 _CXString_getCString = lib.clang_getCString
1634 _CXString_getCString.argtypes = [_CXString]
1635 _CXString_getCString.restype = c_char_p
1637 # Source Location Functions
1638 SourceLocation_loc = lib.clang_getInstantiationLocation
1639 SourceLocation_loc.argtypes = [SourceLocation, POINTER(c_object_p),
1640 POINTER(c_uint), POINTER(c_uint),
1643 # Source Range Functions
1644 SourceRange_getRange = lib.clang_getRange
1645 SourceRange_getRange.argtypes = [SourceLocation, SourceLocation]
1646 SourceRange_getRange.restype = SourceRange
1648 SourceRange_start = lib.clang_getRangeStart
1649 SourceRange_start.argtypes = [SourceRange]
1650 SourceRange_start.restype = SourceLocation
1652 SourceRange_end = lib.clang_getRangeEnd
1653 SourceRange_end.argtypes = [SourceRange]
1654 SourceRange_end.restype = SourceLocation
1656 # CursorKind Functions
1657 CursorKind_is_decl = lib.clang_isDeclaration
1658 CursorKind_is_decl.argtypes = [CursorKind]
1659 CursorKind_is_decl.restype = bool
1661 CursorKind_is_ref = lib.clang_isReference
1662 CursorKind_is_ref.argtypes = [CursorKind]
1663 CursorKind_is_ref.restype = bool
1665 CursorKind_is_expr = lib.clang_isExpression
1666 CursorKind_is_expr.argtypes = [CursorKind]
1667 CursorKind_is_expr.restype = bool
1669 CursorKind_is_stmt = lib.clang_isStatement
1670 CursorKind_is_stmt.argtypes = [CursorKind]
1671 CursorKind_is_stmt.restype = bool
1673 CursorKind_is_inv = lib.clang_isInvalid
1674 CursorKind_is_inv.argtypes = [CursorKind]
1675 CursorKind_is_inv.restype = bool
1678 # TODO: Implement this function
1679 Cursor_get = lib.clang_getCursor
1680 Cursor_get.argtypes = [TranslationUnit, SourceLocation]
1681 Cursor_get.restype = Cursor
1683 Cursor_null = lib.clang_getNullCursor
1684 Cursor_null.restype = Cursor
1686 Cursor_usr = lib.clang_getCursorUSR
1687 Cursor_usr.argtypes = [Cursor]
1688 Cursor_usr.restype = _CXString
1689 Cursor_usr.errcheck = _CXString.from_result
1691 Cursor_is_def = lib.clang_isCursorDefinition
1692 Cursor_is_def.argtypes = [Cursor]
1693 Cursor_is_def.restype = bool
1695 Cursor_def = lib.clang_getCursorDefinition
1696 Cursor_def.argtypes = [Cursor]
1697 Cursor_def.restype = Cursor
1698 Cursor_def.errcheck = Cursor.from_result
1700 Cursor_eq = lib.clang_equalCursors
1701 Cursor_eq.argtypes = [Cursor, Cursor]
1702 Cursor_eq.restype = c_uint
1704 Cursor_spelling = lib.clang_getCursorSpelling
1705 Cursor_spelling.argtypes = [Cursor]
1706 Cursor_spelling.restype = _CXString
1707 Cursor_spelling.errcheck = _CXString.from_result
1709 Cursor_loc = lib.clang_getCursorLocation
1710 Cursor_loc.argtypes = [Cursor]
1711 Cursor_loc.restype = SourceLocation
1713 Cursor_extent = lib.clang_getCursorExtent
1714 Cursor_extent.argtypes = [Cursor]
1715 Cursor_extent.restype = SourceRange
1717 Cursor_ref = lib.clang_getCursorReferenced
1718 Cursor_ref.argtypes = [Cursor]
1719 Cursor_ref.restype = Cursor
1720 Cursor_ref.errcheck = Cursor.from_result
1722 Cursor_visit_callback = CFUNCTYPE(c_int, Cursor, Cursor, py_object)
1723 Cursor_visit = lib.clang_visitChildren
1724 Cursor_visit.argtypes = [Cursor, Cursor_visit_callback, py_object]
1725 Cursor_visit.restype = c_uint
1728 Index_create = lib.clang_createIndex
1729 Index_create.argtypes = [c_int, c_int]
1730 Index_create.restype = c_object_p
1732 Index_dispose = lib.clang_disposeIndex
1733 Index_dispose.argtypes = [Index]
1735 # Translation Unit Functions
1736 TranslationUnit_read = lib.clang_createTranslationUnit
1737 TranslationUnit_read.argtypes = [Index, c_char_p]
1738 TranslationUnit_read.restype = c_object_p
1740 TranslationUnit_parse = lib.clang_parseTranslationUnit
1741 TranslationUnit_parse.argtypes = [Index, c_char_p, c_void_p,
1742 c_int, c_void_p, c_int, c_int]
1743 TranslationUnit_parse.restype = c_object_p
1745 TranslationUnit_reparse = lib.clang_reparseTranslationUnit
1746 TranslationUnit_reparse.argtypes = [TranslationUnit, c_int, c_void_p, c_int]
1747 TranslationUnit_reparse.restype = c_int
1749 TranslationUnit_codeComplete = lib.clang_codeCompleteAt
1750 TranslationUnit_codeComplete.argtypes = [TranslationUnit, c_char_p, c_int,
1751 c_int, c_void_p, c_int, c_int]
1752 TranslationUnit_codeComplete.restype = POINTER(CCRStructure)
1754 TranslationUnit_cursor = lib.clang_getTranslationUnitCursor
1755 TranslationUnit_cursor.argtypes = [TranslationUnit]
1756 TranslationUnit_cursor.restype = Cursor
1757 TranslationUnit_cursor.errcheck = Cursor.from_result
1759 TranslationUnit_spelling = lib.clang_getTranslationUnitSpelling
1760 TranslationUnit_spelling.argtypes = [TranslationUnit]
1761 TranslationUnit_spelling.restype = _CXString
1762 TranslationUnit_spelling.errcheck = _CXString.from_result
1764 TranslationUnit_dispose = lib.clang_disposeTranslationUnit
1765 TranslationUnit_dispose.argtypes = [TranslationUnit]
1767 TranslationUnit_includes_callback = CFUNCTYPE(None,
1769 POINTER(SourceLocation),
1771 TranslationUnit_includes = lib.clang_getInclusions
1772 TranslationUnit_includes.argtypes = [TranslationUnit,
1773 TranslationUnit_includes_callback,
1777 File_name = lib.clang_getFileName
1778 File_name.argtypes = [File]
1779 File_name.restype = c_char_p
1781 File_time = lib.clang_getFileTime
1782 File_time.argtypes = [File]
1783 File_time.restype = c_uint
1787 CodeCompletionResults_dispose = lib.clang_disposeCodeCompleteResults
1788 CodeCompletionResults_dispose.argtypes = [CodeCompletionResults]
1790 _clang_codeCompleteGetNumDiagnostics = lib.clang_codeCompleteGetNumDiagnostics
1791 _clang_codeCompleteGetNumDiagnostics.argtypes = [CodeCompletionResults]
1792 _clang_codeCompleteGetNumDiagnostics.restype = c_int
1794 _clang_codeCompleteGetDiagnostic = lib.clang_codeCompleteGetDiagnostic
1795 _clang_codeCompleteGetDiagnostic.argtypes = [CodeCompletionResults, c_int]
1796 _clang_codeCompleteGetDiagnostic.restype = Diagnostic
1798 _clang_getCompletionChunkText = lib.clang_getCompletionChunkText
1799 _clang_getCompletionChunkText.argtypes = [c_void_p, c_int]
1800 _clang_getCompletionChunkText.restype = _CXString
1802 _clang_getCompletionChunkKind = lib.clang_getCompletionChunkKind
1803 _clang_getCompletionChunkKind.argtypes = [c_void_p, c_int]
1804 _clang_getCompletionChunkKind.restype = c_int
1806 _clang_getCompletionChunkCompletionString = lib.clang_getCompletionChunkCompletionString
1807 _clang_getCompletionChunkCompletionString.argtypes = [c_void_p, c_int]
1808 _clang_getCompletionChunkCompletionString.restype = c_object_p
1810 _clang_getNumCompletionChunks = lib.clang_getNumCompletionChunks
1811 _clang_getNumCompletionChunks.argtypes = [c_void_p]
1812 _clang_getNumCompletionChunks.restype = c_int
1814 _clang_getCompletionAvailability = lib.clang_getCompletionAvailability
1815 _clang_getCompletionAvailability.argtypes = [c_void_p]
1816 _clang_getCompletionAvailability.restype = c_int
1818 _clang_getCompletionPriority = lib.clang_getCompletionPriority
1819 _clang_getCompletionPriority.argtypes = [c_void_p]
1820 _clang_getCompletionPriority.restype = c_int
1825 __all__ = ['Index', 'TranslationUnit', 'Cursor', 'CursorKind',
1826 'Diagnostic', 'FixIt', 'CodeCompletionResults', 'SourceRange',
1827 'SourceLocation', 'File']
1828 plugin/clang_complete.vim [[[1
1831 " File: clang_complete.vim
1832 " Author: Xavier Deguillard <deguilx@gmail.com>
1834 " Description: Use of clang to complete in C/C++.
1836 " Help: Use :help clang_complete
1839 au FileType c,cpp,objc,objcpp call <SID>ClangCompleteInit()
1841 let b:clang_parameters = ''
1842 let b:clang_user_options = ''
1843 let b:my_changedtick = 0
1845 " Store plugin path, as this is available only when sourcing the file,
1846 " not during a function call.
1847 let s:plugin_path = escape(expand('<sfile>:p:h'), '\')
1849 function! s:ClangCompleteInit()
1850 if !exists('g:clang_auto_select')
1851 let g:clang_auto_select = 0
1854 if !exists('g:clang_complete_auto')
1855 let g:clang_complete_auto = 1
1858 if !exists('g:clang_complete_copen')
1859 let g:clang_complete_copen = 0
1862 if !exists('g:clang_hl_errors')
1863 let g:clang_hl_errors = 1
1866 if !exists('g:clang_periodic_quickfix')
1867 let g:clang_periodic_quickfix = 0
1870 if !exists('g:clang_snippets')
1871 let g:clang_snippets = 0
1874 if !exists('g:clang_snippets_engine')
1875 let g:clang_snippets_engine = 'clang_complete'
1878 if !exists('g:clang_exec')
1879 let g:clang_exec = 'clang'
1882 if !exists('g:clang_user_options')
1883 let g:clang_user_options = ''
1886 " Only use libclang if the user clearly show intent to do so for now
1887 if !exists('g:clang_use_library')
1888 let g:clang_use_library = (has('python') && exists('g:clang_library_path'))
1891 if !exists('g:clang_complete_macros')
1892 let g:clang_complete_macros = 0
1895 if !exists('g:clang_complete_patterns')
1896 let g:clang_complete_patterns = 0
1899 if !exists('g:clang_debug')
1900 let g:clang_debug = 0
1903 if !exists('g:clang_sort_algo')
1904 let g:clang_sort_algo = 'priority'
1907 if !exists('g:clang_auto_user_options')
1908 let g:clang_auto_user_options = 'path, .clang_complete'
1911 call LoadUserOptions()
1913 inoremap <expr> <buffer> <C-X><C-U> <SID>LaunchCompletion()
1914 inoremap <expr> <buffer> . <SID>CompleteDot()
1915 inoremap <expr> <buffer> > <SID>CompleteArrow()
1916 inoremap <expr> <buffer> : <SID>CompleteColon()
1917 inoremap <expr> <buffer> <CR> <SID>HandlePossibleSelectionEnter()
1919 if g:clang_snippets == 1
1920 call g:ClangSetSnippetEngine(g:clang_snippets_engine)
1923 " Force menuone. Without it, when there's only one completion result,
1924 " it can be confusing (not completing and no popup)
1925 if g:clang_auto_select != 2
1926 set completeopt-=menu
1927 set completeopt+=menuone
1930 " Disable every autocmd that could have been set.
1931 augroup ClangComplete
1935 let b:should_overload = 0
1936 let b:my_changedtick = b:changedtick
1937 let b:clang_parameters = '-x c'
1939 if &filetype == 'objc'
1940 let b:clang_parameters = '-x objective-c'
1943 if &filetype == 'cpp' || &filetype == 'objcpp'
1944 let b:clang_parameters .= '++'
1947 if expand('%:e') =~ 'h*'
1948 let b:clang_parameters .= '-header'
1951 let g:clang_complete_lib_flags = 0
1953 if g:clang_complete_macros == 1
1954 let b:clang_parameters .= ' -code-completion-macros'
1955 let g:clang_complete_lib_flags = 1
1958 if g:clang_complete_patterns == 1
1959 let b:clang_parameters .= ' -code-completion-patterns'
1960 let g:clang_complete_lib_flags += 2
1963 setlocal completefunc=ClangComplete
1964 setlocal omnifunc=ClangComplete
1966 if g:clang_periodic_quickfix == 1
1967 augroup ClangComplete
1968 au CursorHold,CursorHoldI <buffer> call <SID>DoPeriodicQuickFix()
1972 " Load the python bindings of libclang
1973 if g:clang_use_library == 1
1975 exe s:initClangCompletePython()
1977 echoe 'clang_complete: No python support available.'
1978 echoe 'Cannot use clang library, using executable'
1979 echoe 'Compile vim with python support to use libclang'
1980 let g:clang_use_library = 0
1986 function! LoadUserOptions()
1987 let b:clang_user_options = ''
1989 let l:option_sources = split(g:clang_auto_user_options, ',')
1990 let l:remove_spaces_cmd = 'substitute(v:val, "\\s*\\(.*\\)\\s*", "\\1", "")'
1991 let l:option_sources = map(l:option_sources, l:remove_spaces_cmd)
1993 for l:source in l:option_sources
1994 if l:source == 'path'
1995 call s:parsePathOption()
1996 elseif l:source == '.clang_complete'
1997 call s:parseConfig()
2002 function! s:parseConfig()
2003 let l:local_conf = findfile('.clang_complete', getcwd() . ',.;')
2004 if l:local_conf == '' || !filereadable(l:local_conf)
2008 let l:opts = readfile(l:local_conf)
2010 " Better handling of absolute path
2011 " I don't know if those pattern will work on windows
2013 if matchstr(l:opt, '\C-I\s*/') != ''
2014 let l:opt = substitute(l:opt, '\C-I\s*\(/\%(\w\|\\\s\)*\)',
2017 let l:opt = substitute(l:opt, '\C-I\s*\(\%(\w\|\\\s\)*\)',
2018 \ '-I' . l:local_conf[:-16] . '\1', 'g')
2020 let b:clang_user_options .= ' ' . l:opt
2024 function! s:parsePathOption()
2025 let l:dirs = split(&path, ',')
2027 if len(l:dir) == 0 || !isdirectory(l:dir)
2031 " Add only absolute paths
2032 if matchstr(l:dir, '\s*/') != ''
2033 let l:opt = '-I' . l:dir
2034 let b:clang_user_options .= ' ' . l:opt
2039 function! s:initClangCompletePython()
2040 " Only parse the python library once
2041 if !exists('s:libclang_loaded')
2043 if exists('g:clang_library_path')
2044 " Load the library from the given library path.
2045 exe 'python sys.argv = ["' . escape(g:clang_library_path, '\') . '"]'
2047 " By setting argv[0] to '' force the python bindings to load the library
2048 " from the normal system search path.
2049 python sys.argv[0] = ''
2052 exe 'python sys.path = ["' . s:plugin_path . '"] + sys.path'
2053 exe 'pyfile ' . s:plugin_path . '/libclang.py'
2054 python initClangComplete(vim.eval('g:clang_complete_lib_flags'))
2055 let s:libclang_loaded = 1
2057 python WarmupCache()
2060 function! s:GetKind(proto)
2064 let l:ret = match(a:proto, '^\[#')
2065 let l:params = match(a:proto, '(')
2066 if l:ret == -1 && l:params == -1
2069 if l:ret != -1 && l:params == -1
2078 function! s:CallClangBinaryForDiagnostics(tempfile)
2079 let l:escaped_tempfile = shellescape(a:tempfile)
2080 let l:buf = getline(1, '$')
2082 call writefile(l:buf, a:tempfile)
2083 catch /^Vim\%((\a\+)\)\=:E482/
2087 let l:command = g:clang_exec . ' -cc1 -fsyntax-only'
2088 \ . ' -fno-caret-diagnostics -fdiagnostics-print-source-range-info'
2089 \ . ' ' . l:escaped_tempfile
2090 \ . ' ' . b:clang_parameters . ' ' . b:clang_user_options . ' ' . g:clang_user_options
2092 let l:clang_output = split(system(l:command), "\n")
2093 call delete(a:tempfile)
2094 return l:clang_output
2097 function! s:CallClangForDiagnostics(tempfile)
2098 if g:clang_use_library == 1
2099 python updateCurrentDiagnostics()
2101 return s:CallClangBinaryForDiagnostics(a:tempfile)
2105 function! s:DoPeriodicQuickFix()
2106 " Don't do any superfluous reparsing.
2107 if b:my_changedtick == b:changedtick
2110 let b:my_changedtick = b:changedtick
2112 " Create tempfile name for clang/clang++ executable mode
2113 let b:my_changedtick = b:changedtick
2114 let l:tempfile = expand('%:p:h') . '/' . localtime() . expand('%:t')
2116 let l:clang_output = s:CallClangForDiagnostics(l:tempfile)
2118 call s:ClangQuickFix(l:clang_output, l:tempfile)
2121 function! s:ClangQuickFix(clang_output, tempfname)
2122 " Clear the bad spell, the user may have corrected them.
2123 syntax clear SpellBad
2124 syntax clear SpellLocal
2126 if g:clang_use_library == 0
2127 let l:list = s:ClangUpdateQuickFix(a:clang_output, a:tempfname)
2129 python vim.command('let l:list = ' + str(getCurrentQuickFixList()))
2130 python highlightCurrentDiagnostics()
2133 if g:clang_complete_copen == 1
2134 " We should get back to the original buffer
2135 let l:bufnr = bufnr('%')
2138 " http://vim.1045645.n5.nabble.com/setqflist-inconsistency-td1211423.html
2145 let l:winbufnr = bufwinnr(l:bufnr)
2146 exe l:winbufnr . 'wincmd w'
2148 call setqflist(l:list)
2149 silent doautocmd QuickFixCmdPost make
2152 function! s:ClangUpdateQuickFix(clang_output, tempfname)
2154 for l:line in a:clang_output
2155 let l:erridx = match(l:line, '\%(error\|warning\|note\): ')
2157 " Error are always at the beginning.
2158 if l:line[:11] == 'COMPLETION: ' || l:line[:9] == 'OVERLOAD: '
2163 let l:pattern = '^\(.*\):\(\d*\):\(\d*\):\(\%({\d\+:\d\+-\d\+:\d\+}\)*\)'
2164 let l:tmp = matchstr(l:line, l:pattern)
2165 let l:fname = substitute(l:tmp, l:pattern, '\1', '')
2166 if l:fname == a:tempfname
2169 let l:bufnr = bufnr(l:fname, 1)
2170 let l:lnum = substitute(l:tmp, l:pattern, '\2', '')
2171 let l:col = substitute(l:tmp, l:pattern, '\3', '')
2172 let l:errors = substitute(l:tmp, l:pattern, '\4', '')
2173 if l:line[l:erridx] == 'e'
2174 let l:text = l:line[l:erridx + 7:]
2176 let l:hlgroup = ' SpellBad '
2177 elseif l:line[l:erridx] == 'w'
2178 let l:text = l:line[l:erridx + 9:]
2180 let l:hlgroup = ' SpellLocal '
2182 let l:text = l:line[l:erridx + 6:]
2192 let l:list = add(l:list, l:item)
2194 if g:clang_hl_errors == 0 || l:fname != '%' || l:type == 'I'
2198 " Highlighting the ^
2199 let l:pat = '/\%' . l:lnum . 'l' . '\%' . l:col . 'c./'
2200 exe 'syntax match' . l:hlgroup . l:pat
2205 let l:ranges = split(l:errors, '}')
2206 for l:range in l:ranges
2207 " Doing precise error and warning handling.
2208 " The highlight will be the same as clang's carets.
2209 let l:pattern = '{\%(\d\+\):\(\d\+\)-\%(\d\+\):\(\d\+\)'
2210 let l:tmp = matchstr(l:range, l:pattern)
2211 let l:startcol = substitute(l:tmp, l:pattern, '\1', '')
2212 let l:endcol = substitute(l:tmp, l:pattern, '\2', '')
2213 " Highlighting the ~~~~
2214 let l:pat = '/\%' . l:lnum . 'l'
2215 \ . '\%' . l:startcol . 'c'
2217 \ . '\%' . l:endcol . 'c/'
2218 exe 'syntax match' . l:hlgroup . l:pat
2224 function! s:DemangleProto(prototype)
2225 let l:proto = substitute(a:prototype, '\[#[^#]*#\]', '', 'g')
2226 let l:proto = substitute(l:proto, '{#.*#}', '', 'g')
2232 function! s:ClangCompleteBinary(base)
2233 let l:buf = getline(1, '$')
2234 let l:tempfile = expand('%:p:h') . '/' . localtime() . expand('%:t')
2236 call writefile(l:buf, l:tempfile)
2237 catch /^Vim\%((\a\+)\)\=:E482/
2240 let l:escaped_tempfile = shellescape(l:tempfile)
2242 let l:command = g:clang_exec . ' -cc1 -fsyntax-only'
2243 \ . ' -fno-caret-diagnostics -fdiagnostics-print-source-range-info'
2244 \ . ' -code-completion-at=' . l:escaped_tempfile . ':'
2245 \ . line('.') . ':' . b:col . ' ' . l:escaped_tempfile
2246 \ . ' ' . b:clang_parameters . ' ' . b:clang_user_options . ' ' . g:clang_user_options
2247 let l:clang_output = split(system(l:command), "\n")
2248 call delete(l:tempfile)
2250 call s:ClangQuickFix(l:clang_output, l:tempfile)
2254 if l:clang_output == []
2258 let l:filter_str = "v:val =~ '^COMPLETION: " . a:base . "\\|^OVERLOAD: '"
2259 call filter(l:clang_output, l:filter_str)
2262 for l:line in l:clang_output
2264 if l:line[:11] == 'COMPLETION: ' && b:should_overload != 1
2266 let l:value = l:line[12:]
2268 let l:colonidx = stridx(l:value, ' : ')
2270 let l:wabbr = s:DemangleProto(l:value)
2271 let l:word = l:value
2272 let l:proto = l:value
2274 let l:word = l:value[:l:colonidx - 1]
2276 if l:word =~ '(Hidden)'
2277 let l:word = l:word[:-10]
2279 let l:wabbr = l:word
2280 let l:proto = l:value[l:colonidx + 3:]
2283 let l:kind = s:GetKind(l:proto)
2284 if l:kind == 't' && b:clang_complete_type == 0
2288 let l:word = l:wabbr
2290 let l:proto = s:DemangleProto(l:proto)
2292 elseif l:line[:9] == 'OVERLOAD: ' && b:should_overload == 1
2294 let l:value = l:line[10:]
2295 if match(l:value, '<#') == -1
2298 let l:word = substitute(l:value, '.*<#', '<#', 'g')
2299 let l:word = substitute(l:word, '#>.*', '#>', 'g')
2300 let l:wabbr = substitute(l:word, '<#\([^#]*\)#>', '\1', 'g')
2301 let l:proto = l:value
2302 let l:proto = s:DemangleProto(l:value)
2309 if g:clang_snippets == 1
2310 let l:startidx = match(l:proto, '<#')
2311 while l:startidx != -1
2312 let l:proto = substitute(l:proto, '<#', '', '')
2313 let l:endidx = match(l:proto, '#>')
2314 let l:proto = substitute(l:proto, '#>', '', '')
2315 let l:args_pos += [[ l:startidx, l:endidx ]]
2316 let l:startidx = match(l:proto, '<#')
2327 \ 'args_pos': l:args_pos }
2329 call add(l:res, l:item)
2334 function! ClangComplete(findstart, base)
2336 let l:line = getline('.')
2337 let l:start = col('.') - 1
2338 let b:clang_complete_type = 1
2339 let l:wsstart = l:start
2340 if l:line[l:wsstart - 1] =~ '\s'
2341 while l:wsstart > 0 && l:line[l:wsstart - 1] =~ '\s'
2345 if l:line[l:wsstart - 1] =~ '[(,]'
2346 let b:should_overload = 1
2347 let b:col = l:wsstart + 1
2350 let b:should_overload = 0
2351 while l:start > 0 && l:line[l:start - 1] =~ '\i'
2354 if l:line[l:start - 2:] =~ '->' || l:line[l:start - 1] == '.'
2355 let b:clang_complete_type = 0
2357 let b:col = l:start + 1
2360 if g:clang_debug == 1
2361 let l:time_start = reltime()
2364 if g:clang_snippets == 1
2368 if g:clang_use_library == 1
2369 python vim.command('let l:res = ' + str(getCurrentCompletions(vim.eval('a:base'))))
2371 let l:res = s:ClangCompleteBinary(a:base)
2375 if g:clang_snippets == 1
2376 let item['word'] = b:AddSnip(item['info'], item['args_pos'])
2378 let item['word'] = item['abbr']
2381 if g:clang_snippets == 1
2382 inoremap <expr> <buffer> <C-Y> <SID>HandlePossibleSelectionCtrlY()
2383 augroup ClangComplete
2384 au CursorMovedI <buffer> call <SID>TriggerSnippet()
2386 let b:snippet_chosen = 0
2389 if g:clang_debug == 1
2390 echom 'clang_complete: completion time (' . (g:clang_use_library == 1 ? 'library' : 'binary') . ') '. split(reltimestr(reltime(l:time_start)))[0]
2396 function! s:HandlePossibleSelectionEnter()
2398 let b:snippet_chosen = 1
2404 function! s:HandlePossibleSelectionCtrlY()
2406 let b:snippet_chosen = 1
2411 function! s:TriggerSnippet()
2412 " Dont bother doing anything until we're sure the user exited the menu
2413 if !b:snippet_chosen
2417 " Stop monitoring as we'll trigger a snippet
2418 silent! iunmap <buffer> <C-Y>
2419 augroup ClangComplete
2420 au! CursorMovedI <buffer>
2423 " Trigger the snippet
2424 call b:TriggerSnip()
2427 function! s:ShouldComplete()
2428 if (getline('.') =~ '#\s*\(include\|import\)')
2434 for l:id in synstack(line('.'), col('.') - 1)
2435 if match(synIDattr(l:id, 'name'), '\CComment\|String\|Number')
2444 function! s:LaunchCompletion()
2446 if s:ShouldComplete()
2447 let l:result = "\<C-X>\<C-U>"
2448 if g:clang_auto_select != 2
2449 let l:result .= "\<C-P>"
2451 if g:clang_auto_select == 1
2452 let l:result .= "\<C-R>=(pumvisible() ? \"\\<Down>\" : '')\<CR>"
2458 function! s:CompleteDot()
2459 if g:clang_complete_auto == 1
2460 return '.' . s:LaunchCompletion()
2465 function! s:CompleteArrow()
2466 if g:clang_complete_auto != 1 || getline('.')[col('.') - 2] != '-'
2469 return '>' . s:LaunchCompletion()
2472 function! s:CompleteColon()
2473 if g:clang_complete_auto != 1 || getline('.')[col('.') - 2] != ':'
2476 return ':' . s:LaunchCompletion()
2479 " May be used in a mapping to update the quickfix window.
2480 function! g:ClangUpdateQuickFix()
2481 call s:DoPeriodicQuickFix()
2485 function! g:ClangSetSnippetEngine(engine_name)
2487 call eval('snippets#' . a:engine_name . '#init()')
2488 let b:AddSnip = function('snippets#' . a:engine_name . '#add_snippet')
2489 let b:ResetSnip = function('snippets#' . a:engine_name . '#reset')
2490 let b:TriggerSnip = function('snippets#' . a:engine_name . '#trigger')
2491 catch /^Vim\%((\a\+)\)\=:E117/
2492 echoe 'Snippets engine ' . a:engine_name . ' not found.'
2493 let g:clang_snippets = 0
2497 " vim: set ts=2 sts=2 sw=2 expandtab :
2498 plugin/libclang.py [[[1
2500 from clang.cindex import *
2506 def initClangComplete(clang_complete_flags):
2508 index = Index.create()
2509 global translationUnits
2510 translationUnits = dict()
2511 global complete_flags
2512 complete_flags = int(clang_complete_flags)
2514 # Get a tuple (fileName, fileContent) for the file opened in the current
2515 # vim buffer. The fileContent contains the unsafed buffer content.
2516 def getCurrentFile():
2517 file = "\n".join(vim.eval("getline(1, '$')"))
2518 return (vim.current.buffer.name, file)
2520 def getCurrentTranslationUnit(args, currentFile, fileName, update = False):
2521 if fileName in translationUnits:
2522 tu = translationUnits[fileName]
2526 tu.reparse([currentFile])
2528 elapsed = (time.time() - start)
2529 print "LibClang - Reparsing: " + str(elapsed)
2534 flags = TranslationUnit.PrecompiledPreamble | TranslationUnit.CXXPrecompiledPreamble # | TranslationUnit.CacheCompletionResults
2535 tu = index.parse(fileName, args, [currentFile], flags)
2537 elapsed = (time.time() - start)
2538 print "LibClang - First parse: " + str(elapsed)
2541 print "Cannot parse this source file. The following arguments " \
2542 + "are used for clang: " + " ".join(args)
2545 translationUnits[fileName] = tu
2547 # Reparse to initialize the PCH cache even for auto completion
2548 # This should be done by index.parse(), however it is not.
2549 # So we need to reparse ourselves.
2552 tu.reparse([currentFile])
2554 elapsed = (time.time() - start)
2555 print "LibClang - First reparse (generate PCH cache): " + str(elapsed)
2558 def splitOptions(options):
2563 for char in options:
2564 if char == ' ' and not quoted:
2577 def getQuickFix(diagnostic):
2578 # Some diagnostics have no file, e.g. "too many errors emitted, stopping now"
2579 if diagnostic.location.file:
2580 filename = diagnostic.location.file.name
2584 if diagnostic.severity == diagnostic.Ignored:
2586 elif diagnostic.severity == diagnostic.Note:
2588 elif diagnostic.severity == diagnostic.Warning:
2590 elif diagnostic.severity == diagnostic.Error:
2592 elif diagnostic.severity == diagnostic.Fatal:
2597 return dict({ 'bufnr' : int(vim.eval("bufnr('" + filename + "', 1)")),
2598 'lnum' : diagnostic.location.line,
2599 'col' : diagnostic.location.column,
2600 'text' : diagnostic.spelling,
2603 def getQuickFixList(tu):
2604 return filter (None, map (getQuickFix, tu.diagnostics))
2606 def highlightRange(range, hlGroup):
2607 pattern = '/\%' + str(range.start.line) + 'l' + '\%' \
2608 + str(range.start.column) + 'c' + '.*' \
2609 + '\%' + str(range.end.column) + 'c/'
2610 command = "exe 'syntax match' . ' " + hlGroup + ' ' + pattern + "'"
2611 vim.command(command)
2613 def highlightDiagnostic(diagnostic):
2614 if diagnostic.severity == diagnostic.Warning:
2615 hlGroup = 'SpellLocal'
2616 elif diagnostic.severity == diagnostic.Error:
2617 hlGroup = 'SpellBad'
2621 pattern = '/\%' + str(diagnostic.location.line) + 'l\%' \
2622 + str(diagnostic.location.column) + 'c./'
2623 command = "exe 'syntax match' . ' " + hlGroup + ' ' + pattern + "'"
2624 vim.command(command)
2626 # Use this wired kind of iterator as the python clang libraries
2627 # have a bug in the range iterator that stops us to use:
2629 # | for range in diagnostic.ranges
2631 for i in range(len(diagnostic.ranges)):
2632 highlightRange(diagnostic.ranges[i], hlGroup)
2634 def highlightDiagnostics(tu):
2635 map (highlightDiagnostic, tu.diagnostics)
2637 def highlightCurrentDiagnostics():
2638 if vim.current.buffer.name in translationUnits:
2639 highlightDiagnostics(translationUnits[vim.current.buffer.name])
2641 def getCurrentQuickFixList():
2642 if vim.current.buffer.name in translationUnits:
2643 return getQuickFixList(translationUnits[vim.current.buffer.name])
2646 def updateCurrentDiagnostics():
2648 debug = int(vim.eval("g:clang_debug")) == 1
2649 userOptionsGlobal = splitOptions(vim.eval("g:clang_user_options"))
2650 userOptionsLocal = splitOptions(vim.eval("b:clang_user_options"))
2651 args = userOptionsGlobal + userOptionsLocal
2652 getCurrentTranslationUnit(args, getCurrentFile(),
2653 vim.current.buffer.name, update = True)
2655 def getCurrentCompletionResults(line, column, args, currentFile, fileName):
2656 tu = getCurrentTranslationUnit(args, currentFile, fileName)
2659 cr = tu.codeComplete(fileName, line, column, [currentFile],
2662 elapsed = (time.time() - start)
2663 print "LibClang - Code completion time: " + str(elapsed)
2666 def formatResult(result):
2669 abbr = getAbbr(result.string)
2670 word = filter(lambda x: not x.isKindInformative() and not x.isKindResultType(), result.string)
2675 chunk_len = len(chunk.spelling)
2676 if chunk.isKindPlaceHolder():
2677 args_pos += [[ cur_pos, cur_pos + chunk_len ]]
2678 cur_pos += chunk_len
2680 word = "".join(map(lambda x: x.spelling, word))
2682 completion['word'] = word
2683 completion['abbr'] = abbr
2684 completion['menu'] = word
2685 completion['info'] = word
2686 completion['args_pos'] = args_pos
2687 completion['dup'] = 0
2689 # Replace the number that represents a specific kind with a better
2690 # textual representation.
2691 completion['kind'] = kinds[result.cursorKind]
2696 class CompleteThread(threading.Thread):
2697 lock = threading.Lock()
2699 def __init__(self, line, column, currentFile, fileName):
2700 threading.Thread.__init__(self)
2702 self.column = column
2703 self.currentFile = currentFile
2704 self.fileName = fileName
2706 userOptionsGlobal = splitOptions(vim.eval("g:clang_user_options"))
2707 userOptionsLocal = splitOptions(vim.eval("b:clang_user_options"))
2708 self.args = userOptionsGlobal + userOptionsLocal
2712 CompleteThread.lock.acquire()
2714 # Warm up the caches. For this it is sufficient to get the current
2715 # translation unit. No need to retrieve completion results.
2716 # This short pause is necessary to allow vim to initialize itself.
2717 # Otherwise we would get: E293: block was not locked
2718 # The user does not see any delay, as we just pause a background thread.
2720 getCurrentTranslationUnit(self.args, self.currentFile, self.fileName)
2722 self.result = getCurrentCompletionResults(self.line, self.column,
2723 self.args, self.currentFile, self.fileName)
2726 CompleteThread.lock.release()
2730 debug = int(vim.eval("g:clang_debug")) == 1
2731 t = CompleteThread(-1, -1, getCurrentFile(), vim.current.buffer.name)
2736 def getCurrentCompletions(base):
2738 debug = int(vim.eval("g:clang_debug")) == 1
2739 priority = vim.eval("g:clang_sort_algo") == 'priority'
2740 line = int(vim.eval("line('.')"))
2741 column = int(vim.eval("b:col"))
2743 t = CompleteThread(line, column, getCurrentFile(), vim.current.buffer.name)
2747 cancel = int(vim.eval('complete_check()'))
2754 regexp = re.compile("^" + base)
2755 filteredResult = filter(lambda x: regexp.match(getAbbr(x.string)), cr.results)
2757 getPriority = lambda x: x.string.priority
2758 getAbbrevation = lambda x: getAbbr(x.string).lower()
2762 key = getAbbrevation
2763 sortedResult = sorted(filteredResult, None, key)
2764 return map(formatResult, sortedResult)
2766 def getAbbr(strings):
2767 tmplst = filter(lambda x: x.isKindTypedText(), strings)
2768 if len(tmplst) == 0:
2771 return tmplst[0].spelling
2775 1 : 't', # CXCursor_UnexposedDecl (A declaration whose specific kind is not \
2776 # exposed via this interface) \
2777 2 : 't', # CXCursor_StructDecl (A C or C++ struct) \
2778 3 : 't', # CXCursor_UnionDecl (A C or C++ union) \
2779 4 : 't', # CXCursor_ClassDecl (A C++ class) \
2780 5 : 't', # CXCursor_EnumDecl (An enumeration) \
2781 6 : 'm', # CXCursor_FieldDecl (A field (in C) or non-static data member \
2782 # (in C++) in a struct, union, or C++ class) \
2783 7 : 'e', # CXCursor_EnumConstantDecl (An enumerator constant) \
2784 8 : 'f', # CXCursor_FunctionDecl (A function) \
2785 9 : 'v', # CXCursor_VarDecl (A variable) \
2786 10 : 'a', # CXCursor_ParmDecl (A function or method parameter) \
2787 11 : '11', # CXCursor_ObjCInterfaceDecl (An Objective-C @interface) \
2788 12 : '12', # CXCursor_ObjCCategoryDecl (An Objective-C @interface for a \
2790 13 : '13', # CXCursor_ObjCProtocolDecl (An Objective-C @protocol declaration) \
2791 14 : '14', # CXCursor_ObjCPropertyDecl (An Objective-C @property declaration) \
2792 15 : '15', # CXCursor_ObjCIvarDecl (An Objective-C instance variable) \
2793 16 : '16', # CXCursor_ObjCInstanceMethodDecl (An Objective-C instance method) \
2794 17 : '17', # CXCursor_ObjCClassMethodDecl (An Objective-C class method) \
2795 18 : '18', # CXCursor_ObjCImplementationDec (An Objective-C @implementation) \
2796 19 : '19', # CXCursor_ObjCCategoryImplDecll (An Objective-C @implementation \
2798 20 : 't', # CXCursor_TypedefDecl (A typedef) \
2799 21 : 'f', # CXCursor_CXXMethod (A C++ class method) \
2800 22 : 'n', # CXCursor_Namespace (A C++ namespace) \
2801 23 : '23', # CXCursor_LinkageSpec (A linkage specification, e.g. 'extern "C"') \
2802 24 : '+', # CXCursor_Constructor (A C++ constructor) \
2803 25 : '~', # CXCursor_Destructor (A C++ destructor) \
2804 26 : '26', # CXCursor_ConversionFunction (A C++ conversion function) \
2805 27 : 'a', # CXCursor_TemplateTypeParameter (A C++ template type parameter) \
2806 28 : 'a', # CXCursor_NonTypeTemplateParameter (A C++ non-type template \
2808 29 : 'a', # CXCursor_TemplateTemplateParameter (A C++ template template \
2810 30 : 'f', # CXCursor_FunctionTemplate (A C++ function template) \
2811 31 : 'p', # CXCursor_ClassTemplate (A C++ class template) \
2812 32 : '32', # CXCursor_ClassTemplatePartialSpecialization (A C++ class template \
2813 # partial specialization) \
2814 33 : 'n', # CXCursor_NamespaceAlias (A C++ namespace alias declaration) \
2815 34 : '34', # CXCursor_UsingDirective (A C++ using directive) \
2816 35 : '35', # CXCursor_UsingDeclaration (A using declaration) \
2819 40 : '40', # CXCursor_ObjCSuperClassRef \
2820 41 : '41', # CXCursor_ObjCProtocolRef \
2821 42 : '42', # CXCursor_ObjCClassRef \
2822 43 : '43', # CXCursor_TypeRef \
2823 44 : '44', # CXCursor_CXXBaseSpecifier \
2824 45 : '45', # CXCursor_TemplateRef (A reference to a class template, function \
2825 # template, template template parameter, or class template partial \
2827 46 : '46', # CXCursor_NamespaceRef (A reference to a namespace or namespace \
2829 47 : '47', # CXCursor_MemberRef (A reference to a member of a struct, union, \
2830 # or class that occurs in some non-expression context, e.g., a \
2831 # designated initializer) \
2832 48 : '48', # CXCursor_LabelRef (A reference to a labeled statement) \
2833 49 : '49', # CXCursor_OverloadedDeclRef (A reference to a set of overloaded \
2834 # functions or function templates that has not yet been resolved to \
2835 # a specific function or function template) \
2837 # Error conditions \
2838 #70 : '70', # CXCursor_FirstInvalid \
2839 70 : '70', # CXCursor_InvalidFile \
2840 71 : '71', # CXCursor_NoDeclFound \
2841 72 : 'u', # CXCursor_NotImplemented \
2842 73 : '73', # CXCursor_InvalidCode \
2845 100 : '100', # CXCursor_UnexposedExpr (An expression whose specific kind is \
2846 # not exposed via this interface) \
2847 101 : '101', # CXCursor_DeclRefExpr (An expression that refers to some value \
2848 # declaration, such as a function, varible, or enumerator) \
2849 102 : '102', # CXCursor_MemberRefExpr (An expression that refers to a member \
2850 # of a struct, union, class, Objective-C class, etc) \
2851 103 : '103', # CXCursor_CallExpr (An expression that calls a function) \
2852 104 : '104', # CXCursor_ObjCMessageExpr (An expression that sends a message \
2853 # to an Objective-C object or class) \
2854 105 : '105', # CXCursor_BlockExpr (An expression that represents a block \
2858 200 : '200', # CXCursor_UnexposedStmt (A statement whose specific kind is not \
2859 # exposed via this interface) \
2860 201 : '201', # CXCursor_LabelStmt (A labelled statement in a function) \
2862 # Translation unit \
2863 300 : '300', # CXCursor_TranslationUnit (Cursor that represents the \
2864 # translation unit itself) \
2867 400 : '400', # CXCursor_UnexposedAttr (An attribute whose specific kind is \
2868 # not exposed via this interface) \
2869 401 : '401', # CXCursor_IBActionAttr \
2870 402 : '402', # CXCursor_IBOutletAttr \
2871 403 : '403', # CXCursor_IBOutletCollectionAttr \
2874 500 : '500', # CXCursor_PreprocessingDirective \
2875 501 : 'd', # CXCursor_MacroDefinition \
2876 502 : '502', # CXCursor_MacroInstantiation \
2877 503 : '503' # CXCursor_InclusionDirective \
2880 # vim: set ts=2 sts=2 sw=2 expandtab :