diff --git a/.gitignore b/.gitignore
index fde244ed..d451092f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,4 @@
*.vmb
*.cache
tags
+*.swp
diff --git a/README b/README
deleted file mode 100644
index db7be6f4..00000000
--- a/README
+++ /dev/null
@@ -1,15 +0,0 @@
-This plugin uses clang for accurately completing C and C++ code.
-
-To build and install in one step, type:
-$ make install
-
-To build and install in two steps, type:
-$ make
-$ vim clang_complete.vmb -c 'so %' -c 'q'
-
-Alternatively, you can also put the files in ~/.vim/
-
-You need Vim 7.3 or higher, compiled with python support and ideally, with
-the conceal feature.
-
-See doc/clang_complete.txt for help and license.
diff --git a/README.md b/README.md
new file mode 100755
index 00000000..2973b184
--- /dev/null
+++ b/README.md
@@ -0,0 +1,64 @@
+This plugin uses clang for accurately completing C and C++ code.
+
+## Installation
+
+- To build and install in one step, type: `$ make install`
+
+- To build and install in two steps, type:
+
+```
+$ make
+$ vim clang_complete.vmb -c 'so %' -c 'q'
+```
+
+- Alternatively, you can also put the files in `~/.vim/`
+
+You need Vim 7.3 or higher, compiled with python support and ideally, with
+the conceal feature.
+
+## Minimum Configuration
+
+- Set the `clang_library_path` to the directory containing file named
+ libclang.{dll,so,dylib} (for Windows, Unix variants and OS X respectively) or
+ the file itself, example:
+
+```vim
+ " path to directory where library can be found
+ let g:clang_library_path='/usr/lib/llvm-3.8/lib'
+ " or path directly to the library file
+ let g:clang_library_path='/usr/lib64/libclang.so.3.8'
+```
+
+- Compiler options can be configured in a `.clang_complete` file in each project
+ root. Example of `.clang_complete` file:
+
+```
+-DDEBUG
+-include ../config.h
+-I../common
+-I/usr/include/c++/4.5.3/
+-I/usr/include/c++/4.5.3/x86_64-slackware-linux/
+```
+
+## Usage
+
+The plugin provides list of matches, after that you pick completion from a
+generic completion menu where Ctrl+N, Ctrl+P and alike
+work and wrap around ends of list.
+
+## License
+
+See doc/clang_complete.txt for help and license.
+
+## Troubleshooting
+
+The first step is to check values of `'omnifunc'` and `'completefunc'` options
+in a C++ buffer where completion doesn't work (the value should be
+`ClangComplete`). This can be done with the following command:
+`:set omnifunc? completefunc?`
+
+Output of `:messages` command after startup could also show something useful in
+case there were problems with plugin initialization.
+
+If everything is fine, next step might be to load only clang_complete plugin
+and see if anything changes.
diff --git a/bin/cc_args.py b/bin/cc_args.py
index 5f6ac3d9..eebd79fa 100755
--- a/bin/cc_args.py
+++ b/bin/cc_args.py
@@ -28,11 +28,13 @@ def parseArguments(arguments):
nextIsInclude = False
nextIsDefine = False
nextIsIncludeFile = False
+ nextIsIsystem = False
includes = []
defines = []
include_file = []
options = []
+ isystem = []
for arg in arguments:
if nextIsInclude:
@@ -44,6 +46,9 @@ def parseArguments(arguments):
elif nextIsIncludeFile:
include_file += [arg]
nextIsIncludeFile = False
+ elif nextIsIsystem:
+ isystem += [arg]
+ nextIsIsystem = False
elif arg == "-I":
nextIsInclude = True
elif arg == "-D":
@@ -54,6 +59,8 @@ def parseArguments(arguments):
defines += [arg[2:]]
elif arg == "-include":
nextIsIncludeFile = True
+ elif arg == "-isystem":
+ nextIsIsystem = True
elif arg.startswith('-std='):
options.append(arg)
elif arg == '-ansi':
@@ -66,6 +73,7 @@ def parseArguments(arguments):
result = list(map(lambda x: "-I" + x, includes))
result.extend(map(lambda x: "-D" + x, defines))
result.extend(map(lambda x: "-include " + x, include_file))
+ result.extend(map(lambda x: "-isystem" + x, isystem))
result.extend(options)
return result
diff --git a/bin/generate_kinds.py b/bin/generate_kinds.py
new file mode 100755
index 00000000..8e975507
--- /dev/null
+++ b/bin/generate_kinds.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+#-*- coding: utf-8 -*-
+
+import re
+import sys
+import os.path
+import clang.cindex
+
+# you can use this dictionary to map some kinds to better
+# textual representation than just the number
+mapping = {
+ 1 : 't' , # CXCursor_UnexposedDecl (A declaration whose specific kind is not
+ # exposed via this interface)
+ 2 : 't' , # CXCursor_StructDecl (A C or C++ struct)
+ 3 : 't' , # CXCursor_UnionDecl (A C or C++ union)
+ 4 : 't' , # CXCursor_ClassDecl (A C++ class)
+ 5 : 't' , # CXCursor_EnumDecl (An enumeration)
+ 6 : 'm' , # CXCursor_FieldDecl (A field (in C) or non-static data member
+ # (in C++) in a struct, union, or C++ class)
+ 7 : 'e' , # CXCursor_EnumConstantDecl (An enumerator constant)
+ 8 : 'f' , # CXCursor_FunctionDecl (A function)
+ 9 : 'v' , # CXCursor_VarDecl (A variable)
+ 10 : 'a' , # CXCursor_ParmDecl (A function or method parameter)
+ 20 : 't' , # CXCursor_TypedefDecl (A typedef)
+ 21 : 'f' , # CXCursor_CXXMethod (A C++ class method)
+ 22 : 'n' , # CXCursor_Namespace (A C++ namespace)
+ 24 : '+' , # CXCursor_Constructor (A C++ constructor)
+ 25 : '~' , # CXCursor_Destructor (A C++ destructor)
+ 27 : 'a' , # CXCursor_TemplateTypeParameter (A C++ template type parameter)
+ 28 : 'a' , # CXCursor_NonTypeTemplateParameter (A C++ non-type template
+ # parameter)
+ 29 : 'a' , # CXCursor_TemplateTemplateParameter (A C++ template template
+ # parameter)
+ 30 : 'f' , # CXCursor_FunctionTemplate (A C++ function template)
+ 31 : 'p' , # CXCursor_ClassTemplate (A C++ class template)
+ 33 : 'n' , # CXCursor_NamespaceAlias (A C++ namespace alias declaration)
+ 36 : 't' , # CXCursor_TypeAliasDecl (A C++ alias declaration)
+ 72 : 'u' , # CXCursor_NotImplemented
+ 501 : 'd' , # CXCursor_MacroDefinition
+ 601 : 'ta', # CXCursor_TypeAliasTemplateDecl (Template alias declaration).
+ 700 : 'oc', # CXCursor_OverloadCandidate A code completion overload candidate.
+}
+
+if len(sys.argv) != 2:
+ print("Usage:", sys.argv[0], "")
+ exit(-1)
+
+index = clang.cindex.Index.create()
+tu = index.parse(sys.argv[1])
+
+kinds = None
+for child in tu.cursor.get_children():
+ if (child.spelling == "CXCursorKind"):
+ kinds = child
+ break
+else:
+ print("Index.h doesn't contain CXCursorKind where it is expected, please report a bug.")
+ exit(-1)
+
+kinds_py_path = os.path.join(
+ os.path.dirname(
+ os.path.dirname(
+ os.path.abspath(__file__)
+ )
+ ),
+ "plugin",
+ "kinds.py"
+)
+
+with open(kinds_py_path, "w") as f:
+ # First/Last pattern
+ fl = re.compile("CXCursor_(First|Last)[A-Z].*")
+
+ f.write("# !! GENERATED FILE, DO NOT EDIT\n")
+ f.write("kinds = {\n")
+
+ for kind in kinds.get_children():
+ # filter out First/Last markers from the enum
+ if fl.match(kind.spelling) is not None:
+ continue
+
+ text = mapping.get(kind.enum_value, kind.enum_value)
+ f.write("{0} : '{1}', # {2} {3}\n".format(kind.enum_value, text, kind.spelling, kind.brief_comment))
+
+ f.write("}\n")
+
+# vim: set ts=2 sts=2 sw=2 expandtab :
diff --git a/doc/clang_complete.txt b/doc/clang_complete.txt
index b3a50024..73b42bd4 100644
--- a/doc/clang_complete.txt
+++ b/doc/clang_complete.txt
@@ -1,4 +1,4 @@
-*clang_complete.txt* For Vim version 7.3. Last change: 2014 Apr 13
+*clang_complete.txt* For Vim version 7.3. Last change: 2016 Sep 24
clang_complete plugin documentation
@@ -184,7 +184,7 @@ Default: 0
*clang_complete-user_options*
*g:clang_user_options*
-Additionnal compilation argument passed to libclang.
+Additional compilation argument passed to libclang.
Example: >
" compile all sources as c++11 (just for example, use .clang_complete for
@@ -239,11 +239,18 @@ Default: 1
*clang_complete-library_path*
*g:clang_library_path*
-If libclang is not in your library search path, set this to the absolute path
-where libclang is available. This should either be a directory containing a
-file named libclang.[dll/so/dylib] or the clang shared library file itself.
+If libclang is not in the library search path of your system, you should set
+this variable to the absolute path of either directory containing
+libclang.{dll,so,dylib} (for Windows, Unix variants and OS X respectively) or
+to that file itself.
Default: ""
+Example: >
+ " path to directory where library can be found
+ let g:clang_library_path='/usr/lib/llvm-3.8/lib'
+ " or path directly to the library file
+ let g:clang_library_path='/usr/lib64/libclang.so.3.8'
+<
*clang_complete-sort_algo*
*g:clang_sort_algo*
How results are sorted (alpha, priority, none). Currently only works with
@@ -258,18 +265,18 @@ Default: 0
*clang_complete-complete_patterns*
*g:clang_complete_patterns*
If clang should complete code patterns, i.e loop constructs etc.
-Defaut: 0
+Default: 0
*clang_complete-jumpto_declaration_key*
*g:clang_jumpto_declaration_key*
Set the key used to jump to declaration.
-Defaut: ""
+Default: ""
Note: You could use the g:ClangGotoDeclaration() to do the same with a mapping.
*clang_complete-jumpto_declaration_in_preview_key*
*g:clang_jumpto_declaration_in_preview_key*
Set the key used to jump to declaration in a preview window.
-Defaut: "]"
+Default: "]"
Note: You could use the g:ClangGotoDeclarationPreview() to do the same with a mapping.
*clang_complete-jumpto_back_key*
@@ -277,7 +284,7 @@ Note: You could use the g:ClangGotoDeclarationPreview() to do the same with a ma
Set the key used to jump back.
Note: Effectively this will be remapped to . The default value is chosen
to be coherent with ctags implementation.
-Defaut: ""
+Default: ""
*clang_complete-make_default_keymappings*
*g:clang_make_default_keymappings*
@@ -290,7 +297,7 @@ Default: 1
Omnicppcomplete compatibility mode. Keeps omni auto-completion in control of
omnicppcomplete, disables clang's auto-completion (|g:clang_complete_auto|)
and enables only as main clang completion function.
-Defaut: 0
+Default: 0
==============================================================================
6. Known issues *clang_complete-issues*
diff --git a/plugin/clang/cindex.py b/plugin/clang/cindex.py
index eb05560c..4e6e3c5b 100644
--- a/plugin/clang/cindex.py
+++ b/plugin/clang/cindex.py
@@ -76,6 +76,16 @@
callbacks = {}
+def encode(value):
+ import sys
+ if sys.version_info[0] == 2:
+ return value
+
+ try:
+ return value.encode('utf-8')
+ except AttributeError:
+ return value
+
### Exception Classes ###
class TranslationUnitLoadError(Exception):
@@ -427,7 +437,7 @@ def get_tokens(tu, extent):
token_group = TokenGroup(tu, tokens_memory, tokens_count)
- for i in xrange(0, count):
+ for i in range(0, count):
token = Token()
token.int_data = tokens_array[i].int_data
token.ptr_data = tokens_array[i].ptr_data
@@ -488,7 +498,7 @@ def __init__(self, value):
if value >= len(CursorKind._kinds):
CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1)
if CursorKind._kinds[value] is not None:
- raise ValueError,'CursorKind already loaded'
+ raise ValueError('CursorKind already loaded')
self.value = value
CursorKind._kinds[value] = self
CursorKind._name_map = None
@@ -509,13 +519,13 @@ def name(self):
@staticmethod
def from_id(id):
if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None:
- raise ValueError,'Unknown cursor kind'
+ raise ValueError('Unknown cursor kind')
return CursorKind._kinds[id]
@staticmethod
def get_all_kinds():
"""Return all CursorKind enumeration instances."""
- return filter(None, CursorKind._kinds)
+ return [_f for _f in CursorKind._kinds if _f]
def is_declaration(self):
"""Test if this is a declaration kind."""
@@ -1363,7 +1373,7 @@ def __init__(self, value):
if value >= len(TypeKind._kinds):
TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1)
if TypeKind._kinds[value] is not None:
- raise ValueError,'TypeKind already loaded'
+ raise ValueError('TypeKind already loaded')
self.value = value
TypeKind._kinds[value] = self
TypeKind._name_map = None
@@ -1389,7 +1399,7 @@ def spelling(self):
@staticmethod
def from_id(id):
if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None:
- raise ValueError,'Unknown type kind %d' % id
+ raise ValueError('Unknown type kind %d' % id)
return TypeKind._kinds[id]
def __repr__(self):
@@ -1990,6 +2000,11 @@ def from_source(cls, filename, args=None, unsaved_files=None, options=0,
"""
if args is None:
args = []
+ else:
+ # make a copy, because we're modifying the list right below
+ args = list(args)
+
+ args.append('-fno-color-diagnostics')
if unsaved_files is None:
unsaved_files = []
@@ -1999,7 +2014,7 @@ def from_source(cls, filename, args=None, unsaved_files=None, options=0,
args_array = None
if len(args) > 0:
- args_array = (c_char_p * len(args))(* args)
+ args_array = (c_char_p * len(args))(* [encode(arg) for arg in args])
unsaved_array = None
if len(unsaved_files) > 0:
@@ -2008,12 +2023,12 @@ def from_source(cls, filename, args=None, unsaved_files=None, options=0,
if hasattr(contents, "read"):
contents = contents.read()
- unsaved_array[i].name = name
- unsaved_array[i].contents = contents
+ unsaved_array[i].name = encode(name)
+ unsaved_array[i].contents = encode(contents)
unsaved_array[i].length = len(contents)
- ptr = conf.lib.clang_parseTranslationUnit(index, filename, args_array,
- len(args), unsaved_array,
+ ptr = conf.lib.clang_parseTranslationUnit(index, encode(filename),
+ args_array, len(args), unsaved_array,
len(unsaved_files), options)
if not ptr:
@@ -2187,11 +2202,11 @@ def reparse(self, unsaved_files=None, options=0):
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
- print value
+ print(value)
if not isinstance(value, str):
- raise TypeError,'Unexpected unsaved file contents.'
- unsaved_files_array[i].name = name
- unsaved_files_array[i].contents = value
+ raise TypeError('Unexpected unsaved file contents.')
+ unsaved_files_array[i].name = encode(name)
+ unsaved_files_array[i].contents = encode(value)
unsaved_files_array[i].length = len(value)
ptr = conf.lib.clang_reparseTranslationUnit(self, len(unsaved_files),
unsaved_files_array, options)
@@ -2251,13 +2266,13 @@ def codeComplete(self, path, line, column, unsaved_files=None,
# FIXME: It would be great to support an efficient version
# of this, one day.
value = value.read()
- print value
+ print(value)
if not isinstance(value, str):
- raise TypeError,'Unexpected unsaved file contents.'
- unsaved_files_array[i].name = name
- unsaved_files_array[i].contents = value
+ raise TypeError('Unexpected unsaved file contents.')
+ unsaved_files_array[i].name = encode(name)
+ unsaved_files_array[i].contents = encode(value)
unsaved_files_array[i].length = len(value)
- ptr = conf.lib.clang_codeCompleteAt(self, path, line, column,
+ ptr = conf.lib.clang_codeCompleteAt(self, encode(path), line, column,
unsaved_files_array, len(unsaved_files), options)
if ptr:
return CodeCompletionResults(ptr)
@@ -2285,7 +2300,7 @@ class File(ClangObject):
@staticmethod
def from_name(translation_unit, file_name):
"""Retrieve a file handle within the given translation unit."""
- return File(conf.lib.clang_getFile(translation_unit, file_name))
+ return File(conf.lib.clang_getFile(translation_unit, encode(file_name)))
@property
def name(self):
@@ -2378,7 +2393,7 @@ def arguments(self):
Invariant : the first argument is the compiler executable
"""
length = conf.lib.clang_CompileCommand_getNumArgs(self.cmd)
- for i in xrange(length):
+ for i in range(length):
yield conf.lib.clang_CompileCommand_getArg(self.cmd, i)
class CompileCommands(object):
@@ -2430,8 +2445,8 @@ def fromDirectory(buildDir):
"""Builds a CompilationDatabase from the database found in buildDir"""
errorCode = c_uint()
try:
- cdb = conf.lib.clang_CompilationDatabase_fromDirectory(buildDir,
- byref(errorCode))
+ cdb = conf.lib.clang_CompilationDatabase_fromDirectory(encode(buildDir),
+ byref(errorCode))
except CompilationDatabaseError as e:
raise CompilationDatabaseError(int(errorCode.value),
"CompilationDatabase loading failed")
@@ -2443,7 +2458,7 @@ def getCompileCommands(self, filename):
build filename. Returns None if filename is not found in the database.
"""
return conf.lib.clang_CompilationDatabase_getCompileCommands(self,
- filename)
+ encode(filename))
class Token(Structure):
"""Represents a single token from the preprocessor.
@@ -3079,7 +3094,7 @@ def register_functions(lib, ignore_errors):
def register(item):
return register_function(lib, item, ignore_errors)
- map(register, functionList)
+ list(map(register, functionList))
class Config:
library_path = None
diff --git a/plugin/clang_complete.vim b/plugin/clang_complete.vim
index ef20fa79..df791f1b 100644
--- a/plugin/clang_complete.vim
+++ b/plugin/clang_complete.vim
@@ -13,19 +13,26 @@ endif
let g:clang_complete_loaded = 1
au FileType c,cpp,objc,objcpp call ClangCompleteInit()
-au FileType c.*,cpp.*,objc.*,objcpp.* call ClangCompleteInit()
-
-let b:clang_parameters = ''
-let b:clang_user_options = ''
-let b:my_changedtick = 0
" Store plugin path, as this is available only when sourcing the file,
" not during a function call.
let s:plugin_path = escape(expand(':p:h'), '\')
+let b:clang_parameters = ''
+let b:clang_user_options = ''
+let b:my_changedtick = 0
+
" Older versions of Vim can't check if a map was made with
let s:use_maparg = v:version > 703 || (v:version == 703 && has('patch32'))
+if has('python')
+ let s:py_cmd = 'python'
+ let s:pyfile_cmd = 'pyfile'
+elseif has('python3')
+ let s:py_cmd = 'python3'
+ let s:pyfile_cmd = 'py3file'
+endif
+
function! s:ClangCompleteInit()
let l:bufname = bufname("%")
if l:bufname == ''
@@ -154,7 +161,7 @@ function! s:ClangCompleteInit()
let b:clang_parameters = '-x objective-c'
endif
- if &filetype == 'cpp' || &filetype == 'objcpp'
+ if &filetype == 'cpp' || &filetype == 'objcpp' || &filetype =~ 'cpp.*' || &filetype =~ 'objcpp.*'
let b:clang_parameters .= '++'
endif
@@ -176,7 +183,7 @@ function! s:ClangCompleteInit()
return
endif
- python snippetsInit()
+ execute s:py_cmd 'snippetsInit()'
if g:clang_make_default_keymappings == 1
inoremap LaunchCompletion()
@@ -214,7 +221,6 @@ function! s:ClangCompleteInit()
if g:clang_omnicppcomplete_compliance == 0
setlocal omnifunc=ClangComplete
endif
-
endfunction
function! LoadUserOptions()
@@ -268,14 +274,12 @@ for s:flag in values(s:flagInfo)
endfor
let s:flagPattern = '\%(' . join(s:flagPatterns, '\|') . '\)'
-
function! s:processFilename(filename, root)
" Handle Unix absolute path
if matchstr(a:filename, '\C^[''"\\]\=/') != ''
let l:filename = a:filename
" Handle Windows absolute path
- elseif s:isWindows()
- \ && matchstr(a:filename, '\C^"\=[a-zA-Z]:[/\\]') != ''
+ elseif s:isWindows() && matchstr(a:filename, '\C^"\=[a-zA-Z]:[/\\]') != ''
let l:filename = a:filename
" Convert relative path to absolute path
else
@@ -312,24 +316,34 @@ function! s:parseConfig()
endif
let l:root = fnamemodify(l:local_conf, ':p:h') . l:sep
-
let l:opts = readfile(l:local_conf)
- for l:opt in l:opts
- " Ensure passed filenames are absolute. Only performed on flags which
- " require a filename/directory as an argument, as specified in s:flagInfo
- if matchstr(l:opt, '\C^\s*' . s:flagPattern . '\s*') != ''
- let l:flag = substitute(l:opt, '\C^\s*\(' . s:flagPattern . '\).*'
- \ , '\1', 'g')
- let l:flag = substitute(l:flag, '^\(.\{-}\)\s*$', '\1', 'g')
- let l:filename = substitute(l:opt,
- \ '\C^\s*' . s:flagPattern . '\(.\{-}\)\s*$',
- \ '\1', 'g')
- let l:filename = s:processFilename(l:filename, l:root)
- let l:opt = s:flagInfo[l:flag].output . l:filename
- endif
- let b:clang_user_options .= ' ' . l:opt
- endfor
+ if 0
+ let g:opt_processed = []
+
+ for l:opt in l:opts
+ " Ensure passed filenames are absolute. Only performed on flags which
+ " require a filename/directory as an argument, as specified in s:flagInfo
+ if matchstr(l:opt, '\C^\s*' . s:flagPattern . '\s*') != ''
+ let l:flag = substitute(l:opt, '\C^\s*\(' . s:flagPattern . '\).*', '\1', 'g')
+ let l:flag = substitute(l:flag, '^\(.\{-}\)\s*$', '\1', 'g')
+ let l:filename = substitute(l:opt,
+ \ '\C^\s*' . s:flagPattern . '\(.\{-}\)\s*$',
+ \ '\1', 'g')
+ " [j5shi]: no need to process filename for my options
+ " let l:filename = s:processFilename(l:filename, l:root)
+ echo l:opt
+ let l:opt = s:flagInfo[l:flag].output . l:filename
+ echo l:opt
+ endif
+
+ let g:opt_processed = add(g:opt_processed, l:opt)
+ endfor
+
+ let b:clang_user_options .= join(g:opt_processed, ' ')
+ else
+ let b:clang_user_options .= join(l:opts, ' ')
+ endif
endfunction
function! s:findCompilationDatase(cdb)
@@ -357,7 +371,7 @@ function! s:parsePathOption()
endfunction
function! s:initClangCompletePython()
- if !has('python')
+ if !has('python') && !has('python3')
echoe 'clang_complete: No python support available.'
echoe 'Cannot use clang library'
echoe 'Compile vim with python support to use libclang'
@@ -366,13 +380,14 @@ function! s:initClangCompletePython()
" Only parse the python library once
if !exists('s:libclang_loaded')
- python import sys
+ execute s:py_cmd 'import sys'
+ execute s:py_cmd 'import json'
- exe 'python sys.path = ["' . s:plugin_path . '"] + sys.path'
- exe 'pyfile ' . fnameescape(s:plugin_path) . '/libclang.py'
+ execute s:py_cmd 'sys.path = ["' . s:plugin_path . '"] + sys.path'
+ execute s:pyfile_cmd fnameescape(s:plugin_path) . '/libclang.py'
try
- exe 'python from snippets.' . g:clang_snippets_engine . ' import *'
+ execute s:py_cmd 'from snippets.' . g:clang_snippets_engine . ' import *'
let l:snips_loaded = 1
catch
let l:snips_loaded = 0
@@ -380,18 +395,20 @@ function! s:initClangCompletePython()
if l:snips_loaded == 0
" Oh yeah, vimscript rocks!
" Putting that echoe inside the catch, will throw an error, and
- " display spurious unwanted errors…
+ " display spurious unwanted error
echoe 'Snippets engine ' . g:clang_snippets_engine . ' not found'
return 0
endif
- py vim.command('let l:res = ' + str(initClangComplete(vim.eval('g:clang_complete_lib_flags'), vim.eval('g:clang_compilation_database'), vim.eval('g:clang_library_path'))))
+ execute s:py_cmd "vim.command('let l:res = ' + str(initClangComplete(vim.eval('g:clang_complete_lib_flags'),"
+ \."vim.eval('g:clang_compilation_database'),"
+ \."vim.eval('g:clang_library_path'))))"
if l:res == 0
return 0
endif
let s:libclang_loaded = 1
endif
- python WarmupCache()
+ execute s:py_cmd 'WarmupCache()'
return 1
endfunction
@@ -402,7 +419,7 @@ function! s:DoPeriodicQuickFix()
endif
let b:my_changedtick = b:changedtick
- python updateCurrentDiagnostics()
+ execute s:py_cmd 'updateCurrentDiagnostics()'
call s:ClangQuickFix()
endfunction
@@ -411,8 +428,8 @@ function! s:ClangQuickFix()
syntax clear SpellBad
syntax clear SpellLocal
- python vim.command('let l:list = ' + str(getCurrentQuickFixList()))
- python highlightCurrentDiagnostics()
+ execute s:py_cmd "vim.command('let l:list = ' + json.dumps(getCurrentQuickFixList()))"
+ execute s:py_cmd 'highlightCurrentDiagnostics()'
if g:clang_complete_copen == 1
" We should get back to the original buffer
@@ -464,11 +481,11 @@ function! ClangComplete(findstart, base)
let l:time_start = reltime()
endif
- python snippetsReset()
+ execute s:py_cmd 'snippetsReset()'
- python completions, timer = getCurrentCompletions(vim.eval('a:base'))
- python vim.command('let l:res = ' + completions)
- python timer.registerEvent("Load into vimscript")
+ execute s:py_cmd "completions, timer = getCurrentCompletions(vim.eval('a:base'))"
+ execute s:py_cmd "vim.command('let l:res = ' + completions)"
+ execute s:py_cmd "timer.registerEvent('Load into vimscript')"
if g:clang_make_default_keymappings == 1
if s:use_maparg
@@ -489,7 +506,7 @@ function! ClangComplete(findstart, base)
augroup end
let b:snippet_chosen = 0
- python timer.finish()
+ execute s:py_cmd 'timer.finish()'
if g:clang_debug == 1
echom 'clang_complete: completion time ' . split(reltimestr(reltime(l:time_start)))[0]
@@ -560,7 +577,7 @@ function! s:TriggerSnippet()
call s:StopMonitoring()
" Trigger the snippet
- python snippetsTrigger()
+ execute s:py_cmd 'snippetsTrigger()'
if g:clang_close_preview
pclose
@@ -621,7 +638,7 @@ endfunction
function! s:GotoDeclaration(preview)
try
- python gotoDeclaration(vim.eval('a:preview') == '1')
+ execute s:py_cmd "gotoDeclaration(vim.eval('a:preview') == '1')"
catch /^Vim\%((\a\+)\)\=:E37/
echoe "The current file is not saved, and 'hidden' is not set."
\ "Either save the file or add 'set hidden' in your vimrc."
diff --git a/plugin/kinds.py b/plugin/kinds.py
new file mode 100755
index 00000000..4325c6fd
--- /dev/null
+++ b/plugin/kinds.py
@@ -0,0 +1,196 @@
+# !! GENERATED FILE, DO NOT EDIT
+kinds = {
+1 : 't', # CXCursor_UnexposedDecl A declaration whose specific kind is not exposed via this interface.
+2 : 't', # CXCursor_StructDecl A C or C++ struct.
+3 : 't', # CXCursor_UnionDecl A C or C++ union.
+4 : 't', # CXCursor_ClassDecl A C++ class.
+5 : 't', # CXCursor_EnumDecl An enumeration.
+6 : 'm', # CXCursor_FieldDecl A field (in C) or non-static data member (in C++) in a struct, union, or C++ class.
+7 : 'e', # CXCursor_EnumConstantDecl An enumerator constant.
+8 : 'f', # CXCursor_FunctionDecl A function.
+9 : 'v', # CXCursor_VarDecl A variable.
+10 : 'a', # CXCursor_ParmDecl A function or method parameter.
+11 : '11', # CXCursor_ObjCInterfaceDecl An Objective-C @interface.
+12 : '12', # CXCursor_ObjCCategoryDecl An Objective-C @interface for a category.
+13 : '13', # CXCursor_ObjCProtocolDecl An Objective-C @protocol declaration.
+14 : '14', # CXCursor_ObjCPropertyDecl An Objective-C @property declaration.
+15 : '15', # CXCursor_ObjCIvarDecl An Objective-C instance variable.
+16 : '16', # CXCursor_ObjCInstanceMethodDecl An Objective-C instance method.
+17 : '17', # CXCursor_ObjCClassMethodDecl An Objective-C class method.
+18 : '18', # CXCursor_ObjCImplementationDecl An Objective-C @implementation.
+19 : '19', # CXCursor_ObjCCategoryImplDecl An Objective-C @implementation for a category.
+20 : 't', # CXCursor_TypedefDecl A typedef.
+21 : 'f', # CXCursor_CXXMethod A C++ class method.
+22 : 'n', # CXCursor_Namespace A C++ namespace.
+23 : '23', # CXCursor_LinkageSpec A linkage specification, e.g. 'extern "C"'.
+24 : '+', # CXCursor_Constructor A C++ constructor.
+25 : '~', # CXCursor_Destructor A C++ destructor.
+26 : '26', # CXCursor_ConversionFunction A C++ conversion function.
+27 : 'a', # CXCursor_TemplateTypeParameter A C++ template type parameter.
+28 : 'a', # CXCursor_NonTypeTemplateParameter A C++ non-type template parameter.
+29 : 'a', # CXCursor_TemplateTemplateParameter A C++ template template parameter.
+30 : 'f', # CXCursor_FunctionTemplate A C++ function template.
+31 : 'p', # CXCursor_ClassTemplate A C++ class template.
+32 : '32', # CXCursor_ClassTemplatePartialSpecialization A C++ class template partial specialization.
+33 : 'n', # CXCursor_NamespaceAlias A C++ namespace alias declaration.
+34 : '34', # CXCursor_UsingDirective A C++ using directive.
+35 : '35', # CXCursor_UsingDeclaration A C++ using declaration.
+36 : 't', # CXCursor_TypeAliasDecl A C++ alias declaration
+37 : '37', # CXCursor_ObjCSynthesizeDecl An Objective-C @synthesize definition.
+38 : '38', # CXCursor_ObjCDynamicDecl An Objective-C @dynamic definition.
+39 : '39', # CXCursor_CXXAccessSpecifier An access specifier.
+40 : '40', # CXCursor_ObjCSuperClassRef An access specifier.
+41 : '41', # CXCursor_ObjCProtocolRef An access specifier.
+42 : '42', # CXCursor_ObjCClassRef An access specifier.
+43 : '43', # CXCursor_TypeRef A reference to a type declaration.
+44 : '44', # CXCursor_CXXBaseSpecifier A reference to a type declaration.
+45 : '45', # CXCursor_TemplateRef A reference to a class template, function template, template template parameter, or class template partial specialization.
+46 : '46', # CXCursor_NamespaceRef A reference to a namespace or namespace alias.
+47 : '47', # CXCursor_MemberRef A reference to a member of a struct, union, or class that occurs in some non-expression context, e.g., a designated initializer.
+48 : '48', # CXCursor_LabelRef A reference to a labeled statement.
+49 : '49', # CXCursor_OverloadedDeclRef A reference to a set of overloaded functions or function templates that has not yet been resolved to a specific function or function template.
+50 : '50', # CXCursor_VariableRef A reference to a variable that occurs in some non-expression context, e.g., a C++ lambda capture list.
+70 : '70', # CXCursor_InvalidFile A reference to a variable that occurs in some non-expression context, e.g., a C++ lambda capture list.
+71 : '71', # CXCursor_NoDeclFound A reference to a variable that occurs in some non-expression context, e.g., a C++ lambda capture list.
+72 : 'u', # CXCursor_NotImplemented A reference to a variable that occurs in some non-expression context, e.g., a C++ lambda capture list.
+73 : '73', # CXCursor_InvalidCode A reference to a variable that occurs in some non-expression context, e.g., a C++ lambda capture list.
+100 : '100', # CXCursor_UnexposedExpr An expression whose specific kind is not exposed via this interface.
+101 : '101', # CXCursor_DeclRefExpr An expression that refers to some value declaration, such as a function, variable, or enumerator.
+102 : '102', # CXCursor_MemberRefExpr An expression that refers to a member of a struct, union, class, Objective-C class, etc.
+103 : '103', # CXCursor_CallExpr An expression that calls a function.
+104 : '104', # CXCursor_ObjCMessageExpr An expression that sends a message to an Objective-C object or class.
+105 : '105', # CXCursor_BlockExpr An expression that represents a block literal.
+106 : '106', # CXCursor_IntegerLiteral An integer literal.
+107 : '107', # CXCursor_FloatingLiteral A floating point number literal.
+108 : '108', # CXCursor_ImaginaryLiteral An imaginary number literal.
+109 : '109', # CXCursor_StringLiteral A string literal.
+110 : '110', # CXCursor_CharacterLiteral A character literal.
+111 : '111', # CXCursor_ParenExpr A parenthesized expression, e.g. "(1)".
+112 : '112', # CXCursor_UnaryOperator This represents the unary-expression's (except sizeof and alignof).
+113 : '113', # CXCursor_ArraySubscriptExpr [C99 6.5.2.1] Array Subscripting.
+114 : '114', # CXCursor_BinaryOperator A builtin binary operation expression such as "x + y" or "x <= y".
+115 : '115', # CXCursor_CompoundAssignOperator Compound assignment such as "+=".
+116 : '116', # CXCursor_ConditionalOperator The ?: ternary operator.
+117 : '117', # CXCursor_CStyleCastExpr An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr.cast]), which uses the syntax (Type)expr.
+118 : '118', # CXCursor_CompoundLiteralExpr [C99 6.5.2.5]
+119 : '119', # CXCursor_InitListExpr Describes an C or C++ initializer list.
+120 : '120', # CXCursor_AddrLabelExpr The GNU address of label extension, representing &&label.
+121 : '121', # CXCursor_StmtExpr This is the GNU Statement Expression extension: ({int X=4; X;})
+122 : '122', # CXCursor_GenericSelectionExpr Represents a C11 generic selection.
+123 : '123', # CXCursor_GNUNullExpr Implements the GNU __null extension, which is a name for a null pointer constant that has integral type (e.g., int or long) and is the same size and alignment as a pointer.
+124 : '124', # CXCursor_CXXStaticCastExpr C++'s static_cast<> expression.
+125 : '125', # CXCursor_CXXDynamicCastExpr C++'s dynamic_cast<> expression.
+126 : '126', # CXCursor_CXXReinterpretCastExpr C++'s reinterpret_cast<> expression.
+127 : '127', # CXCursor_CXXConstCastExpr C++'s const_cast<> expression.
+128 : '128', # CXCursor_CXXFunctionalCastExpr Represents an explicit C++ type conversion that uses "functional" notion (C++ [expr.type.conv]).
+129 : '129', # CXCursor_CXXTypeidExpr A C++ typeid expression (C++ [expr.typeid]).
+130 : '130', # CXCursor_CXXBoolLiteralExpr [C++ 2.13.5] C++ Boolean Literal.
+131 : '131', # CXCursor_CXXNullPtrLiteralExpr [C++0x 2.14.7] C++ Pointer Literal.
+132 : '132', # CXCursor_CXXThisExpr Represents the "this" expression in C++
+133 : '133', # CXCursor_CXXThrowExpr [C++ 15] C++ Throw Expression.
+134 : '134', # CXCursor_CXXNewExpr A new expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
+135 : '135', # CXCursor_CXXDeleteExpr A delete expression for memory deallocation and destructor calls, e.g. "delete[] pArray".
+136 : '136', # CXCursor_UnaryExpr A unary expression.
+137 : '137', # CXCursor_ObjCStringLiteral An Objective-C string literal i.e. "foo".
+138 : '138', # CXCursor_ObjCEncodeExpr An Objective-C @encode expression.
+139 : '139', # CXCursor_ObjCSelectorExpr An Objective-C @selector expression.
+140 : '140', # CXCursor_ObjCProtocolExpr An Objective-C @protocol expression.
+141 : '141', # CXCursor_ObjCBridgedCastExpr An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers, transferring ownership in the process.
+142 : '142', # CXCursor_PackExpansionExpr Represents a C++0x pack expansion that produces a sequence of expressions.
+143 : '143', # CXCursor_SizeOfPackExpr Represents an expression that computes the length of a parameter pack.
+144 : '144', # CXCursor_LambdaExpr None
+145 : '145', # CXCursor_ObjCBoolLiteralExpr Objective-c Boolean Literal.
+146 : '146', # CXCursor_ObjCSelfExpr Represents the "self" expression in an Objective-C method.
+147 : '147', # CXCursor_OMPArraySectionExpr OpenMP 4.0 [2.4, Array Section].
+200 : '200', # CXCursor_UnexposedStmt A statement whose specific kind is not exposed via this interface.
+201 : '201', # CXCursor_LabelStmt A labelled statement in a function.
+202 : '202', # CXCursor_CompoundStmt A group of statements like { stmt stmt }.
+203 : '203', # CXCursor_CaseStmt A case statement.
+204 : '204', # CXCursor_DefaultStmt A default statement.
+205 : '205', # CXCursor_IfStmt An if statement
+206 : '206', # CXCursor_SwitchStmt A switch statement.
+207 : '207', # CXCursor_WhileStmt A while statement.
+208 : '208', # CXCursor_DoStmt A do statement.
+209 : '209', # CXCursor_ForStmt A for statement.
+210 : '210', # CXCursor_GotoStmt A goto statement.
+211 : '211', # CXCursor_IndirectGotoStmt An indirect goto statement.
+212 : '212', # CXCursor_ContinueStmt A continue statement.
+213 : '213', # CXCursor_BreakStmt A break statement.
+214 : '214', # CXCursor_ReturnStmt A return statement.
+215 : '215', # CXCursor_GCCAsmStmt A GCC inline assembly statement extension.
+215 : '215', # CXCursor_AsmStmt A GCC inline assembly statement extension.
+216 : '216', # CXCursor_ObjCAtTryStmt Objective-C's overall @try-@catch-@finally statement.
+217 : '217', # CXCursor_ObjCAtCatchStmt Objective-C's @catch statement.
+218 : '218', # CXCursor_ObjCAtFinallyStmt Objective-C's @finally statement.
+219 : '219', # CXCursor_ObjCAtThrowStmt Objective-C's @throw statement.
+220 : '220', # CXCursor_ObjCAtSynchronizedStmt Objective-C's @synchronized statement.
+221 : '221', # CXCursor_ObjCAutoreleasePoolStmt Objective-C's autorelease pool statement.
+222 : '222', # CXCursor_ObjCForCollectionStmt Objective-C's collection statement.
+223 : '223', # CXCursor_CXXCatchStmt C++'s catch statement.
+224 : '224', # CXCursor_CXXTryStmt C++'s try statement.
+225 : '225', # CXCursor_CXXForRangeStmt C++'s for (* : *) statement.
+226 : '226', # CXCursor_SEHTryStmt Windows Structured Exception Handling's try statement.
+227 : '227', # CXCursor_SEHExceptStmt Windows Structured Exception Handling's except statement.
+228 : '228', # CXCursor_SEHFinallyStmt Windows Structured Exception Handling's finally statement.
+229 : '229', # CXCursor_MSAsmStmt A MS inline assembly statement extension.
+230 : '230', # CXCursor_NullStmt The null statement ";": C99 6.8.3p3.
+231 : '231', # CXCursor_DeclStmt Adaptor class for mixing declarations with statements and expressions.
+232 : '232', # CXCursor_OMPParallelDirective OpenMP parallel directive.
+233 : '233', # CXCursor_OMPSimdDirective OpenMP SIMD directive.
+234 : '234', # CXCursor_OMPForDirective OpenMP for directive.
+235 : '235', # CXCursor_OMPSectionsDirective OpenMP sections directive.
+236 : '236', # CXCursor_OMPSectionDirective OpenMP section directive.
+237 : '237', # CXCursor_OMPSingleDirective OpenMP single directive.
+238 : '238', # CXCursor_OMPParallelForDirective OpenMP parallel for directive.
+239 : '239', # CXCursor_OMPParallelSectionsDirective OpenMP parallel sections directive.
+240 : '240', # CXCursor_OMPTaskDirective OpenMP task directive.
+241 : '241', # CXCursor_OMPMasterDirective OpenMP master directive.
+242 : '242', # CXCursor_OMPCriticalDirective OpenMP critical directive.
+243 : '243', # CXCursor_OMPTaskyieldDirective OpenMP taskyield directive.
+244 : '244', # CXCursor_OMPBarrierDirective OpenMP barrier directive.
+245 : '245', # CXCursor_OMPTaskwaitDirective OpenMP taskwait directive.
+246 : '246', # CXCursor_OMPFlushDirective OpenMP flush directive.
+247 : '247', # CXCursor_SEHLeaveStmt Windows Structured Exception Handling's leave statement.
+248 : '248', # CXCursor_OMPOrderedDirective OpenMP ordered directive.
+249 : '249', # CXCursor_OMPAtomicDirective OpenMP atomic directive.
+250 : '250', # CXCursor_OMPForSimdDirective OpenMP for SIMD directive.
+251 : '251', # CXCursor_OMPParallelForSimdDirective OpenMP parallel for SIMD directive.
+252 : '252', # CXCursor_OMPTargetDirective OpenMP target directive.
+253 : '253', # CXCursor_OMPTeamsDirective OpenMP teams directive.
+254 : '254', # CXCursor_OMPTaskgroupDirective OpenMP taskgroup directive.
+255 : '255', # CXCursor_OMPCancellationPointDirective OpenMP cancellation point directive.
+256 : '256', # CXCursor_OMPCancelDirective OpenMP cancel directive.
+257 : '257', # CXCursor_OMPTargetDataDirective OpenMP target data directive.
+258 : '258', # CXCursor_OMPTaskLoopDirective OpenMP taskloop directive.
+259 : '259', # CXCursor_OMPTaskLoopSimdDirective OpenMP taskloop simd directive.
+260 : '260', # CXCursor_OMPDistributeDirective OpenMP distribute directive.
+300 : '300', # CXCursor_TranslationUnit Cursor that represents the translation unit itself.
+400 : '400', # CXCursor_UnexposedAttr An attribute whose specific kind is not exposed via this interface.
+401 : '401', # CXCursor_IBActionAttr An attribute whose specific kind is not exposed via this interface.
+402 : '402', # CXCursor_IBOutletAttr An attribute whose specific kind is not exposed via this interface.
+403 : '403', # CXCursor_IBOutletCollectionAttr An attribute whose specific kind is not exposed via this interface.
+404 : '404', # CXCursor_CXXFinalAttr An attribute whose specific kind is not exposed via this interface.
+405 : '405', # CXCursor_CXXOverrideAttr An attribute whose specific kind is not exposed via this interface.
+406 : '406', # CXCursor_AnnotateAttr An attribute whose specific kind is not exposed via this interface.
+407 : '407', # CXCursor_AsmLabelAttr An attribute whose specific kind is not exposed via this interface.
+408 : '408', # CXCursor_PackedAttr An attribute whose specific kind is not exposed via this interface.
+409 : '409', # CXCursor_PureAttr An attribute whose specific kind is not exposed via this interface.
+410 : '410', # CXCursor_ConstAttr An attribute whose specific kind is not exposed via this interface.
+411 : '411', # CXCursor_NoDuplicateAttr An attribute whose specific kind is not exposed via this interface.
+412 : '412', # CXCursor_CUDAConstantAttr An attribute whose specific kind is not exposed via this interface.
+413 : '413', # CXCursor_CUDADeviceAttr An attribute whose specific kind is not exposed via this interface.
+414 : '414', # CXCursor_CUDAGlobalAttr An attribute whose specific kind is not exposed via this interface.
+415 : '415', # CXCursor_CUDAHostAttr An attribute whose specific kind is not exposed via this interface.
+416 : '416', # CXCursor_CUDASharedAttr An attribute whose specific kind is not exposed via this interface.
+417 : '417', # CXCursor_VisibilityAttr An attribute whose specific kind is not exposed via this interface.
+418 : '418', # CXCursor_DLLExport An attribute whose specific kind is not exposed via this interface.
+419 : '419', # CXCursor_DLLImport An attribute whose specific kind is not exposed via this interface.
+500 : '500', # CXCursor_PreprocessingDirective An attribute whose specific kind is not exposed via this interface.
+501 : 'd', # CXCursor_MacroDefinition An attribute whose specific kind is not exposed via this interface.
+502 : '502', # CXCursor_MacroExpansion An attribute whose specific kind is not exposed via this interface.
+502 : '502', # CXCursor_MacroInstantiation An attribute whose specific kind is not exposed via this interface.
+503 : '503', # CXCursor_InclusionDirective An attribute whose specific kind is not exposed via this interface.
+600 : '600', # CXCursor_ModuleImportDecl A module import declaration.
+601 : 'ta', # CXCursor_TypeAliasTemplateDecl A module import declaration.
+700 : 'oc', # CXCursor_OverloadCandidate A code completion overload candidate.
+}
diff --git a/plugin/libclang.py b/plugin/libclang.py
index 4cb7f125..7c31f855 100644
--- a/plugin/libclang.py
+++ b/plugin/libclang.py
@@ -1,3 +1,5 @@
+from __future__ import print_function
+
from clang.cindex import *
import vim
import time
@@ -5,6 +7,18 @@
import os
import shlex
+from kinds import kinds
+
+def decode(value):
+ import sys
+ if sys.version_info[0] == 2:
+ return value
+
+ try:
+ return value.decode('utf-8')
+ except AttributeError:
+ return value
+
# Check if libclang is able to find the builtin include files.
#
# libclang sometimes fails to correctly locate its builtin include files. This
@@ -15,7 +29,7 @@ def canFindBuiltinHeaders(index, args = []):
currentFile = ("test.c", '#include "stddef.h"')
try:
tu = index.parse("test.c", args, [currentFile], flags)
- except TranslationUnitLoadError, e:
+ except TranslationUnitLoadError as e:
return 0
return len(tu.diagnostics) == 0
@@ -40,15 +54,10 @@ def getBuiltinHeaderPath(library_path):
for path in knownPaths:
try:
- files = os.listdir(path)
- if len(files) >= 1:
- files = sorted(files)
- subDir = files[-1]
- else:
- subDir = '.'
- path = path + "/" + subDir + "/include/"
- arg = "-I" + path
- if canFindBuiltinHeaders(index, [arg]):
+ subDirs = [f for f in os.listdir(path) if os.path.isdir(path + "/" + f)]
+ subDirs = sorted(subDirs) or ['.']
+ path = path + "/" + subDirs[-1] + "/include"
+ if canFindBuiltinHeaders(index, ["-I" + path]):
return path
except:
pass
@@ -71,7 +80,7 @@ def initClangComplete(clang_complete_flags, clang_compilation_database, \
try:
index = Index.create()
- except Exception, e:
+ except Exception as e:
if library_path:
suggestion = "Are you sure '%s' contains libclang?" % library_path
else:
@@ -82,9 +91,9 @@ def initClangComplete(clang_complete_flags, clang_compilation_database, \
else:
exception_msg = ''
- print '''Loading libclang failed, completion won't be available. %s
+ print('''Loading libclang failed, completion won't be available. %s
%s
- ''' % (suggestion, exception_msg)
+ ''' % (suggestion, exception_msg))
return 0
global builtinHeaderPath
@@ -93,12 +102,20 @@ def initClangComplete(clang_complete_flags, clang_compilation_database, \
builtinHeaderPath = getBuiltinHeaderPath(library_path)
if not builtinHeaderPath:
- print "WARNING: libclang can not find the builtin includes."
- print " This will cause slow code completion."
- print " Please report the problem."
-
+ print("WARNING: libclang can not find the builtin includes.")
+ print(" This will cause slow code completion.")
+ print(" Please report the problem.")
+
+ # Cache of translation units. Maps paths of files:
+ #