Skip to content

Commit

Permalink
New layer auto-completion
Browse files Browse the repository at this point in the history
Move company and auto-complete to a common layer.
They are not enabled globally anymore, each mode using them
must explicitly declare a hook.
Only one frontend is supported for a given mode, we have to
choose the best between the two.
Only one key binding to toggle auto-completion on `SPC t a` no
matter if it is company or auto-complete. The lighter in the
mode-line is Ⓐ for both frontends.
  • Loading branch information
syl20bnr committed Apr 3, 2015
1 parent 2905190 commit 769d54d
Show file tree
Hide file tree
Showing 22 changed files with 350 additions and 284 deletions.
77 changes: 77 additions & 0 deletions contrib/auto-completion/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Auto-Completion configuration layer for Spacemacs

<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc/generate-toc again -->
**Table of Contents**

- [Colors contribution layer for Spacemacs](#colors-contribution-layer-for-spacemacs)
- [Description](#description)
- [Install](#install)
- [Enable rainbow-identifiers](#enable-rainbow-identifiers)
- [Enable Nyan cat](#enable-nyan-cat)
- [Key bindings](#key-bindings)
- [Rainbow Identifiers](#rainbow-identifiers)
- [Rainbow Mode](#rainbow-mode)

<!-- markdown-toc end -->

## Description

This layer provides auto-completion to Spacemacs.
The following front-ends are supported:
- [company][]
- [auto-complete][]

**Notes***
- `company` is the most supported and preferred front-end in Spacemacs.
- For a given language, Spacemacs supports one and only one front-end.

## Install

To use this contribution add it to your `~/.spacemacs`

```elisp
(setq-default dotspacemacs-configuration-layers '(auto-completion))
```

### Company variables

To use tab instead of enter to complete your selection,
`dotspacemacs/init` set `auto-completion-use-tab-instead-of-enter` to
`t`, for example:

``` elisp
(setq-default dotspacemacs-configuration-layers
'(auto-completion :variables
auto-completion-use-tab-instead-of-enter t))
```

To enable docstring tooltips set `auto-completion-enable-company-help-tooltip`
to `t`

``` elisp
(setq-default dotspacemacs-configuration-layers
'(auto-completion :variables
auto-completion-enable-company-help-tooltip t))
```

## Key Bindings

### Company

No Debug | Description
---------------------|------------------------------------------------------------
<kbd>C-j</kbd> | go down in company dropdown menu
<kbd>C-k</kbd> | go up in company dropdown menu
<kbd>C-/</kbd> | search in company dropdown
<kbd>C-M-/</kbd> | filter the company dropdown menu
<kbd>C-d</kbd> | open minibuffer with documentation of thing at point in company dropdown

### Auto-complete

Key Binding | Description
-------------------|------------------------------------------------------------
<kbd>C-j</kbd> | select next candidate
<kbd>C-k</kbd> | select previous candidate
<kbd>TAB</kbd> | expand selection or select next candidate
<kbd>S-TAB</kbd> | select previous candidate
<kbd>return</kbd> | complete word, if word is already completed insert a carriage return
32 changes: 32 additions & 0 deletions contrib/auto-completion/config.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
;;; config.el --- Auto-completion configuration File for Spacemacs
;;
;; Copyright (c) 2012-2014 Sylvain Benner
;; Copyright (c) 2014-2015 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

;; Company -------------------------------------------------------------------

;; not used for now
(defvar auto-completion-enable-company-yasnippet t
"If non nil enable yasnippet for all company backends.
Not used for now.")

(defvar auto-completion-enable-company-help-tooltip nil
"If non nil the docstring appears in a tooltip.")

(defvar auto-completion-use-tab-instead-of-enter nil
"If non nil use tab instead of enter for completion.")

(defvar company-mode-completion-cancel-keywords
'("do"
"then"
"begin"
"case")
"Keywords on which to cancel completion so that you can use RET
to complet without blocking common line endings.")
89 changes: 89 additions & 0 deletions contrib/auto-completion/funcs.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
;;; funcs.el --- Auto-completion functions File
;;
;; Copyright (c) 2012-2014 Sylvain Benner
;; Copyright (c) 2014-2015 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

(spacemacs|add-toggle auto-completion
:status
(if (eq 'company auto-completion-front-end)
company-mode
auto-complete-mode)
:on
(progn
(if (eq 'company auto-completion-front-end)
(company-mode)
(auto-complete-mode))
(message "Enabled %S." auto-completion-front-end))
:off
(progn
(if (eq 'company auto-completion-front-end)
(company-mode -1)
(auto-complete-mode -1))
(message "Disabled %S." auto-completion-front-end))
:documentation "Activate auto-completion."
:evil-leader "ta")

;; Company -------------------------------------------------------------------

(defmacro spacemacs|enable-company (mode &optional hook)
"Enable company for the given MODE.
MODE must match the symbol passed in `spacemacs|init-company-backends'.
By default the initialization function is hooked to `MODE-hook', it is
possible to explicitly define a hook with HOOK."
(when (configuration-layer/layer-declaredp 'auto-completion)

This comment has been minimized.

Copy link
@trishume

trishume Apr 3, 2015

Contributor

Won't this function only be loaded with the layer since it's in the funcs.el file?

(let ((mode-hook (if hook hook
(intern (format "%S-hook" mode))))
(func (intern (format "spacemacs//init-company-%S" mode))))
`(progn
(defun ,func ()
,(format "Initialize company for %S" mode)
(set (make-variable-buffer-local 'auto-completion-front-end)
'company)
(set (make-variable-buffer-local 'company-backends)
,(intern (format "company-backends-%S" mode))))
(add-hook ',mode-hook ',func)
(add-hook ',mode-hook 'company-mode)))))

(defun spacemacs/company-backend-with-yas (backend)
"Return BACKEND with support for yasnippet candidates."
backend
;; ------------------
;; syl20bnr: For now adding company-snippet to some backend like anaconda
;; has weird side effects, I need to investigate a little more on this
;; ------------------
;; (if (and (configuration-layer/package-declaredp 'yasnippet)
;; auto-completion-enable-company-yasnippet
;; (not (eq 'company-semantic backend)))
;; (unless (and (listp backend) (member 'company-yasnippet backend))
;; (append (if (listp backend) backend (list backend))
;; (list :with 'company-yasnippet)))
;; ;; (cons backend '(company-yasnippet)))
;; backend)
)

;; Auto-complete -------------------------------------------------------------

(defmacro spacemacs|enable-auto-complete (mode &optional hook)
"Enable auto-complete for the given MODE.
By default the initialization function is hooked to `MODE-hook', it is
possible to explicitly define a hook with HOOK."
(when (configuration-layer/layer-declaredp 'auto-completion)

This comment has been minimized.

Copy link
@trishume

trishume Apr 3, 2015

Contributor

Same thing about layer here.

(let ((mode-hook (if hook hook
(intern (format "%S-hook" mode))))
(func (intern (format "spacemacs//init-auto-complete-%S" mode))))
`(progn
(defun ,func ()
,(format "Initialize auto-complete for %S" mode)
(set (make-variable-buffer-local 'auto-completion-front-end)
'auto-complete)
(set (make-variable-buffer-local 'company-backends)
,(intern (format "company-backends-%S" mode))))
(add-hook ',mode-hook ',func)
(add-hook ',mode-hook 'auto-complete-mode)))))
122 changes: 122 additions & 0 deletions contrib/auto-completion/packages.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
;;; packages.el --- Auto-completion Layer packages File for Spacemacs
;;
;; Copyright (c) 2012-2014 Sylvain Benner
;; Copyright (c) 2014-2015 Sylvain Benner & Contributors
;;
;; Author: Sylvain Benner <sylvain.benner@gmail.com>
;; URL: https://github.com/syl20bnr/spacemacs
;;
;; This file is not part of GNU Emacs.
;;
;;; License: GPLv3

(defvar auto-completion-packages
'(
company
ac-ispell
auto-complete
))

;; company-quickhelp from MELPA is not compatible with 24.3 anymore
(unless (version< emacs-version "24.4")
(push 'company-quickhelp auto-completion-packages))

(defvar auto-completion-excluded-packages '()
"Packages that use auto-complete that are no longer necessary and might
conflict.")

(defun auto-completion/init-ac-ispell ()
(use-package ac-ispell
:defer t
:init
(progn
(setq ac-ispell-requires 4)
(eval-after-load "auto-complete"
'(ac-ispell-setup))
;; (add-hook 'markdown-mode-hook 'ac-ispell-ac-setup)
)))

(defun auto-completion/init-auto-complete ()
(use-package auto-complete
:defer t
:init
(setq ac-auto-start 0
ac-delay 0.2
ac-quick-help-delay 1.
ac-use-fuzzy t
ac-fuzzy-enable t
ac-comphist-file (concat spacemacs-cache-directory "ac-comphist.dat")
tab-always-indent 'complete ; use 'complete when auto-complete is disabled
ac-dwim t)
:config
(progn
(require 'auto-complete-config)
(ac-config-default)
(when (configuration-layer/package-declaredp 'yasnippet)
(push 'ac-source-yasnippet ac-sources))
(add-to-list 'completion-styles 'initials t)
(define-key ac-completing-map (kbd "C-j") 'ac-next)
(define-key ac-completing-map (kbd "C-k") 'ac-previous)
(define-key ac-completing-map (kbd "<S-tab>") 'ac-previous)
(spacemacs|diminish auto-complete-mode "" " A"))))

(defun auto-completion/init-company ()
(use-package company
:defer t
:init
(setq company-idle-delay 0.2
company-minimum-prefix-length 2
company-require-match nil
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)
:config
(progn
(spacemacs|diminish company-mode "" " A")

This comment has been minimized.

Copy link
@trishume

trishume Apr 3, 2015

Contributor

I'm not sure making this the same is a good idea. Sure it unifies it under an idea but it hides information. It will make debugging harder as we'll have to ask people to eval-expression. Generally I'm all for abstracting away backend concepts in a UI but Spacemacs is different in that it is a tool for developers where wanting to understand what is going on behind the scenes is a very common thing.

;; Set the completion key
(if auto-completion-use-tab-instead-of-enter
(progn
;; have tab stand in for enter
(define-key company-active-map (kbd "TAB") 'company-complete-selection)
(define-key company-active-map (kbd "<tab>") 'company-complete-selection)
(define-key company-active-map [tab] 'company-complete-selection)
;;disable enter
(define-key company-active-map [return] nil)
(define-key company-active-map (kbd "RET") nil))
;; Fix integration of company and yasnippet
(define-key company-active-map (kbd "TAB") nil)
(define-key company-active-map (kbd "<tab>") nil)
(define-key company-active-map [tab] nil))
;; key bindings
(define-key company-active-map (kbd "C-j") 'company-select-next)
(define-key company-active-map (kbd "C-k") 'company-select-previous)
(define-key company-active-map (kbd "C-/") 'company-search-candidates)
(define-key company-active-map (kbd "C-M-/") 'company-filter-candidates)
(define-key company-active-map (kbd "C-d") 'company-show-doc-buffer)
;; Nicer looking faces
(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)))))
;; Transformers
(defun spacemacs//company-transformer-cancel (candidates)
"Cancel completion if prefix is in the list
`company-mode-completion-cancel-keywords'"
(unless (and (member company-prefix company-mode-completion-cancel-keywords)
(not auto-completion-use-tab-instead-of-enter))
candidates))
(setq company-transformers '(spacemacs//company-transformer-cancel
company-sort-by-occurrence))
;; Backends
(setq company-backends
(mapcar 'spacemacs/company-backend-with-yas company-backends)))))

(defun auto-completion/init-company-quickhelp ()
(use-package company-quickhelp
:if (and auto-completion-enable-company-help-tooltip
(display-graphic-p))
:defer t
:init (add-hook 'company-mode-hook 'company-quickhelp-mode)))
49 changes: 0 additions & 49 deletions contrib/company-mode/README.md

This file was deleted.

Loading

1 comment on commit 769d54d

@trishume
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really like the idea of using whatever code completion mechanism is best and am happy company-mode is now basically the default.

However this PR does break a few things which I have created issues for:
#1043 #1045 #1046 #1047

These are mostly minor and easy to fix though. Lots of small issues nothing huge. Overall good thing 👍

Please sign in to comment.