Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display brief comments in preview window #199

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 37 additions & 2 deletions plugin/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1735,10 +1735,17 @@ def availability(self):
res = conf.lib.clang_getCompletionAvailability(self.obj)
return availabilityKinds[res]

@property
def briefComment(self):
if conf.function_exists("clang_getCompletionBriefComment"):
return conf.lib.clang_getCompletionBriefComment(self.obj)
return _CXString()

def __repr__(self):
return " | ".join([str(a) for a in self]) \
+ " || Priority: " + str(self.priority) \
+ " || Availability: " + str(self.availability)
+ " || Availability: " + str(self.availability) \
+ " || Brief comment: " + str(self.briefComment.spelling)

availabilityKinds = {
0: CompletionChunk.Kind("Available"),
Expand Down Expand Up @@ -1877,6 +1884,10 @@ class TranslationUnit(ClangObject):
# searching for declarations/definitions.
PARSE_SKIP_FUNCTION_BODIES = 64

# Used to indicate that brief documentation comments should be included
# into the set of code completions returned from this translation unit.
PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION = 128

@classmethod
def from_source(cls, filename, args=None, unsaved_files=None, options=0,
index=None):
Expand Down Expand Up @@ -2149,7 +2160,9 @@ def save(self, filename):
raise TranslationUnitSaveError(result,
'Error saving TranslationUnit.')

def codeComplete(self, path, line, column, unsaved_files=None, options=0):
def codeComplete(self, path, line, column, unsaved_files=None,
include_macros=False, include_code_patterns=False,
include_brief_comments=False):
"""
Code complete in this translation unit.

Expand All @@ -2158,6 +2171,17 @@ def codeComplete(self, path, line, column, unsaved_files=None, options=0):
and the second should be the contents to be substituted for the
file. The contents may be passed as strings or file objects.
"""
options = 0

if include_macros:
options += 1

if include_code_patterns:
options += 2

if include_brief_comments:
options += 4

if unsaved_files is None:
unsaved_files = []

Expand Down Expand Up @@ -2556,6 +2580,10 @@ def cursor(self):
[c_void_p],
c_int),

("clang_getCompletionBriefComment",
[c_void_p],
_CXString),

("clang_getCompletionChunkCompletionString",
[c_void_p, c_int],
c_object_p),
Expand Down Expand Up @@ -3071,6 +3099,13 @@ def get_cindex_library(self):

return library

def function_exists(self, name):
try:
getattr(self.lib, name)
except AttributeError:
return False

return True

def register_enumerations():
for name, value in clang.enumerations.TokenKinds:
Expand Down
22 changes: 15 additions & 7 deletions plugin/clang_complete.vim
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ function! s:ClangCompleteInit()
let g:clang_complete_patterns = 0
endif

if !exists('g:clang_include_brief_comments')
let g:clang_include_brief_comments = 1
endif

if !exists('g:clang_debug')
let g:clang_debug = 0
endif
Expand Down Expand Up @@ -136,16 +140,12 @@ function! s:ClangCompleteInit()
let b:clang_parameters .= '-header'
endif

let g:clang_complete_lib_flags = 0

if g:clang_complete_macros == 1
let b:clang_parameters .= ' -code-completion-macros'
let g:clang_complete_lib_flags = 1
endif

if g:clang_complete_patterns == 1
let b:clang_parameters .= ' -code-completion-patterns'
let g:clang_complete_lib_flags += 2
endif

setlocal completefunc=ClangComplete
Expand Down Expand Up @@ -239,9 +239,16 @@ function! s:initClangCompletePython()
exe 'python sys.path = ["' . s:plugin_path . '"] + sys.path'
exe 'pyfile ' . s:plugin_path . '/libclang.py'
if exists('g:clang_library_path')
python initClangComplete(vim.eval('g:clang_complete_lib_flags'), vim.eval('g:clang_library_path'))
python initClangComplete(
\ include_macros=vim.eval('g:clang_complete_macros'),
\ include_code_patterns=vim.eval('g:clang_complete_patterns'),
\ include_brief_comments=vim.eval('g:clang_include_brief_comments'),
\ library_path=vim.eval('g:clang_library_path'))
else
python initClangComplete(vim.eval('g:clang_complete_lib_flags'))
python initClangComplete(
\ include_macros=vim.eval('g:clang_complete_macros'),
\ include_code_patterns=vim.eval('g:clang_complete_patterns'),
\ include_brief_comments=vim.eval('g:clang_include_brief_comments'))
endif
let s:libclang_loaded = 1
endif
Expand Down Expand Up @@ -571,7 +578,7 @@ function! ClangComplete(findstart, base)

if g:clang_use_library == 1
python completions, timer = getCurrentCompletions(vim.eval('a:base'))
python vim.command('let l:res = ' + completions)
python vim.command('let l:res = ' + toVimRepr(completions))
python timer.registerEvent("Load into vimscript")
else
let l:res = s:ClangCompleteBinary(a:base)
Expand All @@ -582,6 +589,7 @@ function! ClangComplete(findstart, base)
let item['word'] = b:AddSnip(item['info'], item['args_pos'])
else
let item['word'] = item['abbr']
let item['info'] = item['info'] . "\n" . item['brief_comment']
endif
endfor

Expand Down
89 changes: 85 additions & 4 deletions plugin/libclang.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@
import time
import re
import threading
import types

def initClangComplete(clang_complete_flags, library_path = None):
def initClangComplete(include_macros=False, include_code_patterns=False,
include_brief_comments=False, library_path=None):
global index
if library_path:
Config.set_library_path(library_path)
Expand All @@ -14,7 +16,11 @@ def initClangComplete(clang_complete_flags, library_path = None):
global translationUnits
translationUnits = dict()
global complete_flags
complete_flags = int(clang_complete_flags)
complete_flags = {
'include_macros': include_macros,
'include_code_patterns': include_code_patterns,
'include_brief_comments': include_brief_comments
}
global libclangLock
libclangLock = threading.Lock()

Expand Down Expand Up @@ -88,6 +94,8 @@ def getCurrentTranslationUnit(args, currentFile, fileName, update = False):
if debug:
start = time.time()
flags = TranslationUnit.PARSE_PRECOMPILED_PREAMBLE
if complete_flags['include_brief_comments']:
flags |= TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION
tu = index.parse(fileName, args, [currentFile], flags)
if debug:
elapsed = (time.time() - start)
Expand Down Expand Up @@ -220,7 +228,7 @@ def getCurrentCompletionResults(line, column, args, currentFile, fileName,
timer.registerEvent("Get TU")

cr = tu.codeComplete(fileName, line, column, [currentFile],
complete_flags)
**complete_flags)
timer.registerEvent("Code Complete")
return cr

Expand Down Expand Up @@ -263,6 +271,7 @@ def formatResult(result):
completion['info'] = word
completion['args_pos'] = args_pos
completion['dup'] = 0
completion['brief_comment'] = result.string.briefComment.spelling or ""

# Replace the number that represents a specific kind with a better
# textual representation.
Expand Down Expand Up @@ -354,7 +363,79 @@ def getCurrentCompletions(base):
result = map(formatResult, results)

timer.registerEvent("Format")
return (str(result), timer)
return (result, timer)

class VimReprHelper:
def __init__(self):
self._result = []

def getResult(self):
return ''.join(self._result)

def append(self, v):
t = type(v)
if t in [types.IntType, types.LongType, types.FloatType]:
self._result.append(repr(v))
if t in [types.StringType, types.UnicodeType]:
self.appendString(v)
if t is types.ListType:
self.appendList(v)
if t is types.DictType:
self.appendDict(v)

def appendString(self, s):
if '\'' in s:
self._result.append('\'')
self._result.append(s.replace('\'', '\'\''))
self._result.append('\'')
else:
self._result.append(repr(s))

def appendList(self, l):
self._result.append('[')
for i in xrange(len(l)):
self.append(l[i])
if i != len(l) - 1:
self._result.append(',')
self._result.append(']')

def appendDict(self, d):
self._result.append('{')
keys = d.keys()
for i in xrange(len(keys)):
k = keys[i]
self.append(k)
self._result.append(':')
self.append(d[k])
if i != len(keys) - 1:
self._result.append(',')
self._result.append('}')

def needsSpecialConversion(v):
t = type(v)
if t in [types.IntType, types.LongType, types.FloatType]:
return False
if t in [types.StringType, types.UnicodeType]:
return '\'' in v
if t is types.ListType:
for e in v:
if needsSpecialConversion(e):
return True
if t is types.DictType:
for k, val in v.items():
if needsSpecialConversion(k):
return True
if needsSpecialConversion(val):
return True
return False

def toVimRepr(v):
if needsSpecialConversion(v):
helper = VimReprHelper()
helper.append(v)
return helper.getResult()
else:
return repr(v)

def getAbbr(strings):
tmplst = filter(lambda x: x.isKindTypedText(), strings)
Expand Down