Bug 892973 - Add support for the YouCompleteMe vim plugin; r=gps

This commit is contained in:
Ehsan Akhgari 2015-04-24 15:12:50 -04:00
parent 514c33e8a5
commit 583f4bd680
5 changed files with 134 additions and 9 deletions

27
.ycm_extra_conf.py Normal file
View File

@ -0,0 +1,27 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import imp
import os
from StringIO import StringIO
import shlex
path = os.path.join(os.path.dirname(__file__), 'mach')
if not os.path.exists(path):
path = os.path.join(os.path.dirname(__file__), 'config.status')
config = imp.load_module('_buildconfig', open(path), path, ('', 'r', imp.PY_SOURCE))
path = os.path.join(config.topsrcdir, 'mach')
mach_module = imp.load_module('_mach', open(path), path, ('', 'r', imp.PY_SOURCE))
def FlagsForFile(filename):
mach = mach_module.get_mach()
out = StringIO()
out.encoding = None
mach.run(['compileflags', filename], stdout=out, stderr=out)
return {
'flags': shlex.split(out.getvalue()),
'do_cache': True
}

View File

@ -53,6 +53,13 @@ LLDBINIT_FINAL_TARGET_FILES := $(DEPTH)/.lldbinit
LLDBINIT_FINAL_TARGET_DEST = $(FINAL_TARGET)
INSTALL_TARGETS += LLDBINIT_FINAL_TARGET
# Put the .ycm_extra_conf.py file at the root of the objdir. It is used by
# the vim plugin YouCompleteMe.
YCM_FILES := $(topsrcdir)/.ycm_extra_conf.py
YCM_DEST := $(abspath $(DEPTH))
YCM_TARGET := export
INSTALL_TARGETS += YCM
ifdef MOZTTDIR
# Install the Firefox OS fonts.
include $(MOZTTDIR)/fonts.mk

View File

@ -83,6 +83,7 @@ MACH_MODULES = [
'python/mozboot/mozboot/mach_commands.py',
'python/mozbuild/mozbuild/mach_commands.py',
'python/mozbuild/mozbuild/backend/mach_commands.py',
'python/mozbuild/mozbuild/compilation/codecomplete.py',
'python/mozbuild/mozbuild/frontend/mach_commands.py',
'services/common/tests/mach_commands.py',
'testing/luciddream/mach_commands.py',

19
mach
View File

@ -27,15 +27,14 @@ def load_mach(topsrcdir):
return mach_bootstrap.bootstrap(topsrcdir)
def check_and_run_mach(dir_path, args):
def check_and_get_mach(dir_path):
# If we find the mach bootstrap module, we are in the srcdir.
mach_path = os.path.join(dir_path, 'build/mach_bootstrap.py')
if os.path.isfile(mach_path):
mach = load_mach(dir_path)
sys.exit(mach.run(args))
return load_mach(dir_path)
return None
def main(args):
def get_mach():
# Check whether the current directory is within a mach src or obj dir.
for dir_path in ancestors(os.getcwd()):
# If we find a "mozinfo.json" file, we are in the objdir.
@ -56,14 +55,20 @@ def main(args):
# Continue searching for mach_bootstrap in the source directory.
dir_path = info['topsrcdir']
check_and_run_mach(dir_path, args)
mach = check_and_get_mach(dir_path)
if mach:
return mach
# If we didn't find a source path by scanning for a mozinfo.json, check
# whether the directory containing this script is a source directory.
check_and_run_mach(os.path.dirname(__file__), args)
return check_and_get_mach(os.path.dirname(__file__))
def main(args):
mach = get_mach()
if not mach:
print('Could not run mach: No mach source directory found.')
sys.exit(1)
sys.exit(mach.run(args))
if __name__ == '__main__':

View File

@ -0,0 +1,85 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# This modules provides functionality for dealing with code completion.
import os
from mach.decorators import (
CommandArgument,
CommandProvider,
Command,
)
from mozbuild.base import MachCommandBase
@CommandProvider
class Introspection(MachCommandBase):
"""Instropection commands."""
@Command('compileflags', category='devenv',
description='Display the compilation flags for a given source file')
@CommandArgument('what', default=None,
help='Source file to display compilation flags for')
def compileflags(self, what):
from mozbuild.util import resolve_target_to_make
import shlex
top_make = os.path.join(self.topobjdir, 'Makefile')
if not os.path.exists(top_make):
print('Your tree has not been built yet. Please run '
'|mach build| with no arguments.')
return 1
path_arg = self._wrap_path_argument(what)
make_dir, make_target = resolve_target_to_make(self.topobjdir,
path_arg.relpath())
if make_dir is None and make_target is None:
return 1
build_vars = {}
def on_line(line):
elements = [s.strip() for s in line.split('=', 1)]
if len(elements) != 2:
return
build_vars[elements[0]] = elements[1]
try:
old_logger = self.log_manager.replace_terminal_handler(None)
self._run_make(directory=make_dir, target='showbuild', log=False,
print_directory=False, allow_parallel=False, silent=True,
line_handler=on_line)
finally:
self.log_manager.replace_terminal_handler(old_logger)
if what.endswith('.c'):
name = 'COMPILE_CFLAGS'
else:
name = 'COMPILE_CXXFLAGS'
if name not in build_vars:
return
flags = ['-isystem', '-I', '-include', '-MF']
new_args = []
path = os.path.join(self.topobjdir, make_dir)
for arg in shlex.split(build_vars[name]):
if new_args and new_args[-1] in flags:
arg = os.path.normpath(os.path.join(path, arg))
else:
flag = [(f, arg[len(f):]) for f in flags + ['--sysroot=']
if arg.startswith(f)]
if flag:
flag, val = flag[0]
if val:
arg = flag + os.path.normpath(os.path.join(path, val))
new_args.append(arg)
print(' '.join(new_args))