diff --git a/contrib/company-mode/Readme.md b/contrib/company-mode/Readme.md new file mode 100644 index 000000000..a3ad2c146 --- /dev/null +++ b/contrib/company-mode/Readme.md @@ -0,0 +1,25 @@ +# Company Mode + +In order to use this you should disable the default `auto-complete` package plus everything that depends on it: + +```elisp +(setq-default dotspacemacs-excluded-packages + '(auto-complete ac-ispell tern-auto-complete auto-complete-clang enslime edts)) +``` + +## Clang Fanciness + +In `funcs.el` there are some fancy improvements to `company-clang`. +It includes a hook to load a projects `.clang_complete` file, which is just a text +file with one clang flag per line, a format also used by other text editor clang plugins. + +Not only does this allow proper autocomplete on projects with extra includes and flags, +but I also hooked it into flycheck so that the error messages don't complain about missing +header files and skip the actual problems. + +Basically, Spacemacs now has better Clang/C++ than any other Emacs config. + +## Maintainer + +This contrib layer was written by and should be maintained by @trishume, everyone else is +welcome to contribute. diff --git a/contrib/company-mode/funcs.el b/contrib/company-mode/funcs.el new file mode 100644 index 000000000..ec7783817 --- /dev/null +++ b/contrib/company-mode/funcs.el @@ -0,0 +1,83 @@ +; .clang_complete file loading +; Sets the arguments for company-clang based on a project-specific text file. + +; START Based on the Sarcasm/irony-mode compilation database code. + +(defun company-mode/find-clang-complete-file () + (when buffer-file-name + (let ((dir (locate-dominating-file buffer-file-name ".clang_complete"))) + (when dir + (concat (file-name-as-directory dir) ".clang_complete"))))) + +(defun company-mode/load-clang-complete-file (cc-file) + "Load the flags from CC-FILE, one flag per line." + (let ((invocation-dir (expand-file-name (file-name-directory cc-file))) + (case-fold-search nil) + compile-flags) + (with-temp-buffer + (insert-file-contents cc-file) + ; Replace relative paths with absolute paths (by @trishume) + ;(goto-char (point-min)) + (while (re-search-forward "\\(-I\\|-isystem\n\\)\\(\\S-\\)" nil t) + (replace-match (format "%s%s" (match-string 1) (expand-file-name (match-string 2) invocation-dir)))) + ; Turn lines into a list + (setq compile-flags + ;; remove whitespaces at the end of each line, if any + (mapcar #'(lambda (line) + (if (string-match "[ \t]+$" line) + (replace-match "" t t line) + line)) + (split-string (buffer-string) "\n" t)))) + compile-flags)) + +; END Back to things written by @trishume + +(defun company-mode/more-than-prefix-guesser () + (unless company-clang-arguments + (let* ((cc-file (company-mode/find-clang-complete-file)) + (flags (when cc-file (company-mode/load-clang-complete-file cc-file)))) + (when flags (setq-local company-clang-arguments flags)))) + (company-clang-guess-prefix)) + +; START Based on the built in flycheck-clang c++ checker +(eval-after-load 'flycheck + '(progn + (flycheck-define-checker c/c++-company + "A C/C++ syntax checker using parameters from clang-complete" + :command ("clang" + "-fsyntax-only" + "-fno-color-diagnostics" ; Do not include color codes in output + "-fno-caret-diagnostics" ; Do not visually indicate the source + ; location + "-fno-diagnostics-show-option" ; Do not show the corresponding + ; warning group + "-x" (eval + (pcase major-mode + (`c++-mode "c++") + (`c-mode "c"))) + (option-list "" company-clang-arguments concat) + source) + :error-patterns + ((error line-start + (message "In file included from") " " (file-name) ":" line ":" + line-end) + (info line-start (file-name) ":" line ":" column + ": note: " (optional (message)) line-end) + (warning line-start (file-name) ":" line ":" column + ": warning: " (optional (message)) line-end) + (error line-start (file-name) ":" line ":" column + ": " (or "fatal error" "error") ": " (optional (message)) line-end)) + :error-filter + (lambda (errors) + (let ((errors (flycheck-sanitize-errors errors))) + (dolist (err errors) + ;; Clang will output empty messages for #error/#warning pragmas without + ;; messages. We fill these empty errors with a dummy message to get + ;; them past our error filtering + (setf (flycheck-error-message err) + (or (flycheck-error-message err) "no message"))) + (flycheck-fold-include-errors errors "In file included from"))) + :modes (c-mode c++-mode) + :next-checkers ((warning . c/c++-cppcheck))) + (add-to-list 'flycheck-checkers 'c/c++-company))) +; END diff --git a/contrib/company-mode/packages.el b/contrib/company-mode/packages.el new file mode 100644 index 000000000..24034423e --- /dev/null +++ b/contrib/company-mode/packages.el @@ -0,0 +1,41 @@ +(defvar company-mode-packages + '( + company + company-tern + )) + +(defun company-mode/init-company () + (use-package company + :config + (progn + (setq company-idle-delay 0.0 + company-minimum-prefix-length 2 + company-require-match nil + company-transformers '(company-sort-by-occurrence) + company-dabbrev-ignore-case nil + company-dabbrev-downcase nil + company-tooltip-flip-when-above t + company-frontends '(company-pseudo-tooltip-frontend) + company-clang-prefix-guesser 'company-mode/more-than-prefix-guesser) + + (global-company-mode 1) + + ; Fix integration of company and yasnippet + (define-key company-active-map (kbd "TAB") nil) + (define-key company-active-map (kbd "") nil) + (define-key company-active-map [tab] nil) + + (add-hook 'markdown-mode-hook '(lambda () (company-mode -1))) + + ; The default common face is a really ugly underlined thing with a different background. + (custom-set-faces + '(company-tooltip-common ((t (:inherit company-tooltip :weight bold :underline nil)))) + '(company-tooltip-common-selection ((t (:inherit company-tooltip-selection :weight bold :underline nil))))) + + (spacemacs//diminish company-mode " Ⓒ")))) + +(defun company-mode/init-company-tern () + (use-package company-tern + :defer t + :config + (add-to-list 'company-backends 'company-tern))) diff --git a/contrib/trishume/Readme.md b/contrib/trishume/Readme.md index 0c1382cc3..633384bfe 100644 --- a/contrib/trishume/Readme.md +++ b/contrib/trishume/Readme.md @@ -4,3 +4,17 @@ Mostly consists of support for additional languages including: LaTeX, Idris, OpenSCAD, Julia, Arduino, QML, Lua Also adds smooth scrolling and Helm Ag support. + +## Company Auctex + +Along with other things this layer includes company-auctex, it's only enabled if you also enable my other contrib layer `company-mode`. +The autocompletion it offers is great and almost works, unlike auto-complete-auctex which lags so hard it's worthless. + +The problem is the almost. There are a few issues that need to be fixed for it to be nice: + +- https://github.com/capitaomorte/yasnippet/issues/537 To allow you to delete expanded macro braces, this will need to be merged. +- https://github.com/alexeyr/company-auctex/pull/3 For completing environments like `align*` properly, this will need to be merged. +- https://github.com/alexeyr/company-auctex/issues/4 + +Currently I've manually applied both of these patches to the folders in my `elpa` directory, which isn't a good solution. +If the patches aren't merged in a reasonable amount of time I'll add the patched forks/branches as extension submodules. diff --git a/contrib/trishume/packages.el b/contrib/trishume/packages.el index c01ce2109..c05df0697 100644 --- a/contrib/trishume/packages.el +++ b/contrib/trishume/packages.el @@ -15,6 +15,9 @@ ag )) +(when (member 'trishume dotspacemacs-configuration-layers) + (add-to-list 'trishume-packages 'company-auctex)) + (defun trishume/init-auctex () (defun load-auctex-on-demand () (interactive) @@ -24,6 +27,10 @@ (use-package smartparens :config (require 'smartparens-latex)) + (when (member 'company-mode dotspacemacs-configuration-layers) + (use-package company-auctex + :init (company-auctex-init))) + (defun build-view () (interactive) (if (buffer-modified-p) @@ -42,6 +49,7 @@ (add-hook 'LaTeX-mode-hook '(lambda () (local-set-key (kbd "H-r") 'build-view))) (add-hook 'LaTeX-mode-hook 'flyspell-mode) (add-hook 'LaTeX-mode-hook 'LaTeX-math-mode) + (add-hook 'LaTeX-mode-hook 'spacemacs/load-yasnippet) (evil-leader/set-key "oe" 'LaTeX-environment