Skip to content

Commit

Permalink
Bug 892973 - Add support for the YouCompleteMe vim plugin; r=gps
Browse files Browse the repository at this point in the history
  • Loading branch information
ehsan committed Apr 27, 2015
1 parent 5db25db commit 6b10d0f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 9 deletions.
27 changes: 27 additions & 0 deletions .ycm_extra_conf.py
Original file line number Diff line number Diff line change
@@ -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
}
7 changes: 7 additions & 0 deletions build/Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions build/mach_bootstrap.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
'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',
Expand Down
23 changes: 14 additions & 9 deletions mach
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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__))

print('Could not run mach: No mach source directory found.')
sys.exit(1)
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__':
Expand Down
85 changes: 85 additions & 0 deletions python/mozbuild/mozbuild/compilation/codecomplete.py
Original file line number Diff line number Diff line change
@@ -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))

0 comments on commit 6b10d0f

Please sign in to comment.