From 507f893b4cf17a07fea6eccd293c6ddebd2381d0 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sat, 5 Feb 2011 16:32:35 -0800 Subject: [PATCH 1/4] Add support for per-file user options through g:per_file_user_options. --- plugin/clang_complete.vim | 23 ++++++++++++++++++++++- plugin/libclang.py | 10 ++++++---- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/plugin/clang_complete.vim b/plugin/clang_complete.vim index cd18ad9d..4783de58 100644 --- a/plugin/clang_complete.vim +++ b/plugin/clang_complete.vim @@ -45,7 +45,7 @@ " - g:clang_exec: " Name or path of clang executable. " Note: Use this if clang has a non-standard name, or isn't in the -" path. +" path. Not used if |g:clang_use_library| is set. " Default: 'clang' " " - g:clang_user_options: @@ -55,6 +55,21 @@ " Default: '' " Example: '|| exit 0' (it will discard clang return value) " +" - g:clang_per_file_user_options: +" Can be set to a function that is called with the name of the current +" buffer. This should return a list of additional flags for this file. +" Useful if compilation flags differ on a per-file or per-directory +" base. Works only if |g:clang_use_library| is set. +" Default: Not set. +" Example: +" fu! g:clang_per_file_user_options(path) +" if a:path =~ 'clang' +" return '-I/Users/thakis/src/llvm-rw/tools/clang/include' +" else +" return '' +" endif +" endfu +" " - g:clang_use_library: " Instead of calling the clang/clang++ tool use libclang directly. This " should improve the performance, but is still experimental. @@ -144,6 +159,12 @@ function! s:ClangCompleteInit() let g:clang_user_options = '' endif + if !exists('*g:clang_per_file_user_options') + function g:clang_per_file_user_options(path) + return '' + endfunction + endif + " Only use libclang if the user clearly show intent to do so for now if !exists('g:clang_use_library') let g:clang_use_library = (has('python') && exists('g:clang_library_path')) diff --git a/plugin/libclang.py b/plugin/libclang.py index 316135a2..329a999f 100644 --- a/plugin/libclang.py +++ b/plugin/libclang.py @@ -16,13 +16,15 @@ def getCurrentFile(): return (vim.current.buffer.name, file) def getCurrentTranslationUnit(update = False): - userOptionsGlobal = vim.eval("g:clang_user_options").split(" ") - userOptionsLocal = vim.eval("b:clang_user_options").split(" ") - args = userOptionsGlobal + userOptionsLocal - currentFile = getCurrentFile() fileName = vim.current.buffer.name + userOptionsGlobal = vim.eval("g:clang_user_options").split(" ") + userOptionsLocal = vim.eval("b:clang_user_options").split(" ") + userOptionsPerFile = vim.eval( + "g:clang_per_file_user_options('%s')" % fileName).split(" ") + args = userOptionsGlobal + userOptionsLocal + userOptionsPerFile + if fileName in translationUnits: tu = translationUnits[fileName] if update: From bc34a8503cd35920a020d36b92dd2e47dac309c4 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 6 Feb 2011 10:50:12 -0800 Subject: [PATCH 2/4] Add support for per-file user options through g:per_file_user_options. --- plugin/libclang.py | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/plugin/libclang.py b/plugin/libclang.py index 38261b34..f45d43e8 100644 --- a/plugin/libclang.py +++ b/plugin/libclang.py @@ -34,6 +34,29 @@ def getCurrentTranslationUnit(update = False): "g:clang_per_file_user_options('%s')" % fileName).split(" ") args = userOptionsGlobal + userOptionsLocal + userOptionsPerFile + # Filter out options that -cc1 doesn't understand. + args0 = args + args = [] + i = 0 + while i < len(args0): + arg = args0[i] + if (arg.startswith('-I') or arg.startswith('-D') or arg.startswith('-W') or + arg.startswith('-F') or arg.startswith('-O') or arg.startswith('-f') or + arg.startswith('-m')): + args.append(arg) + + if arg == '-isysroot': + args.append(arg) + args.append(userOptionsPerFile[i + 1]) + i += 1 + if arg == '-arch': + args.append(arg) + args.append(userOptionsPerFile[i + 1]) + i += 1 + i += 1 + + #vim.command('echoe "' + ' '.join(args) + '"') + if fileName in translationUnits: tu = translationUnits[fileName] if update: From f9b9c50642cc437d42d5b4a3144b452f0194ae97 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 6 Feb 2011 14:45:13 -0800 Subject: [PATCH 3/4] also support a per-file cwd --- plugin/clang_complete.vim | 16 +++++---- plugin/libclang.py | 68 +++++++++++++++++++-------------------- 2 files changed, 43 insertions(+), 41 deletions(-) diff --git a/plugin/clang_complete.vim b/plugin/clang_complete.vim index acbf1483..7f7dadce 100644 --- a/plugin/clang_complete.vim +++ b/plugin/clang_complete.vim @@ -57,16 +57,20 @@ " " - g:clang_per_file_user_options: " Can be set to a function that is called with the name of the current -" buffer. This should return a list of additional flags for this file. -" Useful if compilation flags differ on a per-file or per-directory -" base. Works only if |g:clang_use_library| is set. +" buffer. This should return a dictionary that can contain the following +" keys: +" 'flags': list of additional flags for this file. Useful if +" compilation flags differ on a per-file or per-directory +" base. +" 'cwd': The working directory the compile job should be executed in. +" Works only if |g:clang_use_library| is set. " Default: Not set. " Example: " fu! g:clang_per_file_user_options(path) -" if a:path =~ 'clang' -" return '-I/Users/thakis/src/llvm-rw/tools/clang/include' +" if a:path =~? 'subfolder' +" return { 'flags': '-I/Users/thakis/src/myproject/subfolder/include' } " else -" return '' +" return {} " endif " endfu " diff --git a/plugin/libclang.py b/plugin/libclang.py index f45d43e8..7d6a44eb 100644 --- a/plugin/libclang.py +++ b/plugin/libclang.py @@ -1,8 +1,8 @@ from clang.cindex import * -import vim -import time import re +import time import threading +import vim def initClangComplete(clang_complete_flags, library_path = None): global index @@ -28,35 +28,6 @@ def getCurrentTranslationUnit(update = False): currentFile = getCurrentFile() fileName = vim.current.buffer.name - userOptionsGlobal = vim.eval("g:clang_user_options").split(" ") - userOptionsLocal = vim.eval("b:clang_user_options").split(" ") - userOptionsPerFile = vim.eval( - "g:clang_per_file_user_options('%s')" % fileName).split(" ") - args = userOptionsGlobal + userOptionsLocal + userOptionsPerFile - - # Filter out options that -cc1 doesn't understand. - args0 = args - args = [] - i = 0 - while i < len(args0): - arg = args0[i] - if (arg.startswith('-I') or arg.startswith('-D') or arg.startswith('-W') or - arg.startswith('-F') or arg.startswith('-O') or arg.startswith('-f') or - arg.startswith('-m')): - args.append(arg) - - if arg == '-isysroot': - args.append(arg) - args.append(userOptionsPerFile[i + 1]) - i += 1 - if arg == '-arch': - args.append(arg) - args.append(userOptionsPerFile[i + 1]) - i += 1 - i += 1 - - #vim.command('echoe "' + ' '.join(args) + '"') - if fileName in translationUnits: tu = translationUnits[fileName] if update: @@ -68,10 +39,32 @@ def getCurrentTranslationUnit(update = False): print "LibClang - Reparsing: %.3f" % elapsed return tu + userOptionsGlobal = vim.eval("g:clang_user_options").split(" ") + userOptionsLocal = vim.eval("b:clang_user_options").split(" ") + userOptionsPerFileDict = vim.eval( + "g:clang_per_file_user_options('%s')" % fileName) + userOptionsPerFile = userOptionsPerFileDict.get("flags", "").split(" ") + args = userOptionsGlobal + userOptionsLocal + userOptionsPerFile + + old_cwd = vim.eval('getcwd()') + new_cwd = userOptionsPerFileDict.get('cwd', old_cwd) + print old_cwd, new_cwd + if debug: start = time.time() - flags = TranslationUnit.PARSE_PRECOMPILED_PREAMBLE - tu = index.parse(fileName, args, [currentFile], flags) + try: + #os.chdir(new_cwd) + vim.command('cd ' + new_cwd) + #vim.command('cd base') + #print vim.eval('getcwd()') + flags = TranslationUnit.PARSE_PRECOMPILED_PREAMBLE + tu = index.parse(fileName, args, [currentFile], flags) + tu.cwd = new_cwd + finally: + #os.chdir(old_cwd) + vim.command('cd ' + old_cwd) + pass + if debug: elapsed = (time.time() - start) print "LibClang - First parse: %.3f" % elapsed @@ -202,8 +195,13 @@ def getCurrentCompletionResults(line, column, args, currentFile, fileName, tu = getCurrentTranslationUnit(args, currentFile, fileName) timer.registerEvent("Get TU") - cr = tu.codeComplete(fileName, line, column, [currentFile], - complete_flags) + old_cwd = vim.eval('getcwd()') + try: + vim.command('cd ' + tu.cwd) + cr = tu.codeComplete(fileName, line, column, [currentFile], + complete_flags) + finally: + vim.command('cd ' + old_cwd) timer.registerEvent("Code Complete") return cr From 42cfd72f0c5207d23dc8adc09ca9e9dd53e23b10 Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Sun, 6 Feb 2011 14:48:51 -0800 Subject: [PATCH 4/4] remove debug garbage --- plugin/libclang.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugin/libclang.py b/plugin/libclang.py index 7d6a44eb..3eea207d 100644 --- a/plugin/libclang.py +++ b/plugin/libclang.py @@ -53,7 +53,6 @@ def getCurrentTranslationUnit(update = False): if debug: start = time.time() try: - #os.chdir(new_cwd) vim.command('cd ' + new_cwd) #vim.command('cd base') #print vim.eval('getcwd()') @@ -61,9 +60,7 @@ def getCurrentTranslationUnit(update = False): tu = index.parse(fileName, args, [currentFile], flags) tu.cwd = new_cwd finally: - #os.chdir(old_cwd) vim.command('cd ' + old_cwd) - pass if debug: elapsed = (time.time() - start)