Add a emacs-ycmd contrib layer.

This commit is contained in:
Tristan Hume 2015-01-10 18:57:24 -05:00 committed by syl20bnr
parent a383c273e6
commit 191d696dd1
4 changed files with 152 additions and 0 deletions

1
.gitignore vendored
View File

@ -34,6 +34,7 @@ tmp/
server/
*~
*.elc
*.pyc
/*.zip
*.db
python-*-docs-html

26
contrib/ycmd/Readme.md Normal file
View File

@ -0,0 +1,26 @@
# YCMD
This contrib layer adds [emacs-ycmd](https://github.com/abingham/emacs-ycmd) support.
In order to use this layer you must have a local [ycmd](https://github.com/Valloric/ycmd#building) installation
and must set the `ycmd-server-command` variable to reflect the path to that installation. See the emacs-ycmd
Readme for more instructions on this.
This package also requires the `company-mode` layer in order to get actual completion rather than just flychecking and
key bindings.
## Key Bindings
Adds the `SPC m g` go to definition binding to `c++-mode` as well as `SPC m G` for the more imprecise but faster version.
## Configuration
By default this layer only activates ycmd for `c++-mode` so company can provide completion that is better than mere keyword
completion for all the modes it would otherwise add itself to. If you want ycmd in all sorts of other modes then put this
snippet in your dotspacemacs init function:
```elisp
(setq ycmd/all-the-modes t)
```
otherwise you might just want to add it for specific languages like:
```elisp
(add-hook 'c++-mode-hook 'ycmd-mode)
```

View File

@ -0,0 +1,84 @@
import os
import ycm_core
default_flags = [
'-Wall',
'-Wextra',
'-Werror',
'-Wc++98-compat',
'-Wno-long-long',
'-Wno-variadic-macros',
'-fexceptions',
'-DNDEBUG',
'-std=c++11',
'-x',
'c++',
# This path will only work on OS X, but extra paths that don't exist are not harmful
'-isystem'
'/System/Library/Frameworks/Python.framework/Headers',
'-isystem',
'/usr/include',
'-isystem',
'/usr/local/include',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1',
'-isystem',
'/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include',
]
def DirectoryOfThisScript():
return os.path.dirname( os.path.abspath( __file__ ) )
def MakeRelativePathsInFlagsAbsolute( flags, working_directory ):
if not working_directory:
return list( flags )
new_flags = []
make_next_absolute = False
path_flags = [ '-isystem', '-I', '-iquote', '--sysroot=' ]
for flag in flags:
new_flag = flag
if make_next_absolute:
make_next_absolute = False
if not flag.startswith( '/' ):
new_flag = os.path.join( working_directory, flag )
for path_flag in path_flags:
if flag == path_flag:
make_next_absolute = True
break
if flag.startswith( path_flag ):
path = flag[ len( path_flag ): ]
new_flag = path_flag + os.path.join( working_directory, path )
break
if new_flag:
new_flags.append( new_flag )
return new_flags
# Thanks to https://github.com/decrispell/vim-config for this code
def FlagsForFile( filename, **kwargs ):
""" given the source filename, return the compiler flags """
opt_basename = '.clang_complete'
curr_dir = os.path.dirname(filename)
opt_fname = os.path.join(curr_dir, opt_basename)
# keep traversing up the tree until we find the file, or hit the root
while not os.path.exists(opt_fname):
new_dir = os.path.dirname(curr_dir)
if new_dir == curr_dir:
# we've reached the root of the tree
break
curr_dir = new_dir
opt_fname = os.path.join(curr_dir, opt_basename)
try:
fd = open(opt_fname, 'r')
except IOError:
return {'flags': default_flags, 'do_cache': True}
flags = [line.strip() for line in fd.readlines()]
relative_to = os.path.dirname(opt_fname)
flags = MakeRelativePathsInFlagsAbsolute(flags, relative_to)
return {
'flags': flags, 'do_cache': True
}

41
contrib/ycmd/packages.el Normal file
View File

@ -0,0 +1,41 @@
(defvar ycmd-packages
'(
ycmd
flycheck-ycmd
)
"List of all packages to install and/or initialize. Built-in packages
which require an initialization must be listed explicitly in the list.")
(unless (boundp 'ycmd-server-command)
(message "YCMD won't work unless you set the ycmd-server-command variable to the path to a ycmd install."))
(when (member 'company-mode dotspacemacs-configuration-layers)
(add-to-list 'ycmd-packages 'company-ycmd))
(defvar ycmd/all-the-modes nil
"use ycmd for all the modes it supports, most will only use fancy keyword completion.")
(defun ycmd/init-ycmd ()
(use-package ycmd
:init
(progn
(if ycmd/all-the-modes
(ycmd-setup)
(add-hook 'c++-mode-hook 'ycmd-mode))
(setq-default ycmd-global-config
(expand-file-name "~/.emacs.d/contrib/ycmd/global_conf.py")))
:config
(evil-leader/set-key-for-mode 'c++-mode
"mg" 'ycmd-goto
"mG" 'ycmd-goto-imprecise)))
(defun ycmd/init-company-ycmd ()
(use-package company-ycmd
:init (company-ycmd-setup)))
(defun ycmd/init-flycheck-ycmd ()
(use-package flycheck-ycmd
:init
(progn
(add-hook 'ycmd-file-parse-result-hook 'flycheck-ycmd--cache-parse-results)
(add-to-list 'flycheck-checkers 'ycmd))))