]> git.siccegge.de Git - dotfiles/emacs.git/commitdiff
Update irony-mode foo master
authorChristoph Egger <christoph@christoph-egger.org>
Tue, 28 Nov 2017 22:53:02 +0000 (23:53 +0100)
committerChristoph Egger <christoph@christoph-egger.org>
Tue, 28 Nov 2017 22:53:02 +0000 (23:53 +0100)
config/irony.el
lisp/company-irony.el [new file with mode: 0644]

index c00ab4571b5b0f3911de10e4a4a3642b231966bb..3abe2280af02c75ba7eeeef3e4f390b3b60fa872 100644 (file)
@@ -1,3 +1,5 @@
+;; cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
+
 (if (locate-library "irony")
     (progn
       (require 'irony)
@@ -5,11 +7,10 @@
       (add-hook 'c-mode-hook 'irony-mode)
       (add-hook 'objc-mode-hook 'irony-mode)
 
-      ;; replace the `completion-at-point' and `complete-symbol' bindings in
-      ;; irony-mode's buffers by irony-mode's function
-      (defun my-irony-mode-hook ()
-        (define-key irony-mode-map [remap completion-at-point]
-          'irony-completion-at-point-async)
-        (define-key irony-mode-map [remap complete-symbol]
-          'irony-completion-at-point-async))
-      (add-hook 'irony-mode-hook 'my-irony-mode-hook)))
+      (add-hook 'c++-mode-hook 'company-mode)
+      (add-hook 'c-mode-hook 'company-mode)
+      (add-hook 'objc-mode-hook 'company-mode)
+
+      (eval-after-load 'company
+        '(add-to-list 'company-backends 'company-irony))
+      (add-hook 'irony-mode-hook 'irony-cdb-autosetup-compile-options)))
diff --git a/lisp/company-irony.el b/lisp/company-irony.el
new file mode 100644 (file)
index 0000000..74d6f2c
--- /dev/null
@@ -0,0 +1,156 @@
+;;; company-irony.el --- company-mode completion back-end for irony-mode  -*- lexical-binding: t -*-
+
+;; Copyright (C) 2014  Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: convenience
+;; Version: 1.1.0
+;; URL: https://github.com/Sarcasm/company-irony/
+;; Package-Requires: ((emacs "24.1") (company "0.8.0") (irony "1.1.0") (cl-lib "0.5"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Usage:
+;;
+;;     (eval-after-load 'company
+;;       '(add-to-list 'company-backends 'company-irony))
+
+;;; Code:
+
+(require 'irony-completion)
+
+(require 'company)
+(require 'company-template)
+
+(require 'cl-lib)
+
+(defgroup company-irony nil
+  "Company-mode completion back-end for Irony."
+  :group 'company
+  :group 'irony)
+
+(defcustom company-irony-ignore-case nil
+  "If t, ignore case when collecting completion candidates.
+If this value is `smart', ignore case only when there is no
+uppercase letters."
+  :type '(choice (const :tag "off" nil)
+                (const smart)
+                (other :tag "on" t)))
+
+(defsubst company-irony--irony-candidate (candidate)
+  (get-text-property 0 'company-irony candidate))
+
+(defun company-irony-prefix ()
+  (pcase-let ((`(,symbol-start . ,symbol-end) (irony-completion-symbol-bounds)))
+    (if (and symbol-end (> symbol-end (point)))
+        'stop
+      (when symbol-start
+        (let ((prefix (buffer-substring-no-properties symbol-start (point))))
+          (save-excursion
+            (goto-char symbol-start)
+            (if (irony-completion-at-trigger-point-p)
+                (cons prefix t)
+              prefix)))))))
+
+(defun company-irony--make-candidates (candidates)
+  (cl-loop for candidate in candidates
+           collect (propertize (car candidate) 'company-irony candidate)))
+
+(defun company-irony--get-matching-style ()
+  (cl-case company-irony-ignore-case
+    (smart 'smart-case)
+    (nil 'exact)
+    (t 'case-insensitive)))
+
+(defun company-irony--candidates (prefix)
+  (cons :async
+        (lambda (callback)
+          (irony-completion-candidates-async
+           (lambda (candidates) ;; closure, lexically bound
+             (funcall callback
+                      (company-irony--make-candidates candidates)))
+           prefix
+           (company-irony--get-matching-style)))))
+
+(defun company-irony--annotation (candidate)
+  (concat
+   (irony-completion-annotation candidate)
+   (let ((type (irony-completion-type candidate)))
+     (when (not (zerop (length type)))
+       (concat " -> " type)))))
+
+(defun company-irony--post-completion (candidate)
+  ;; This check is necessary because Company triggers a 'post-completion even if
+  ;; the candidate has just been typed without relying on the completion, but it
+  ;; doesn't provide the full candidate information.
+  (when candidate
+    (let ((point-before-post-complete (point)))
+      (if (irony-snippet-available-p)
+          (irony-completion-post-complete candidate)
+        (let ((str (irony-completion-post-comp-str candidate)))
+          (insert str)
+          (company-template-c-like-templatify str)))
+      ;; Here we set this-command to a `self-insert-command' so that company may
+      ;; retrigger idle completion after the snippet expansion
+      ;; (~`company-post-command'). This is a bit of a hack and maybe that will
+      ;; change in the future. This is useful for example when the completed
+      ;; candidate is a namespace and the annotation text (inserted snippet) is
+      ;; the scope operator.
+      ;;
+      ;; std| -> std::   (=> idle completion desired here)
+      ;;         stderr
+      ;;         ...
+      ;;
+      ;; See https://github.com/company-mode/company-mode/issues/143
+      (unless (eq (point) point-before-post-complete)
+        (setq this-command 'self-insert-command)))))
+
+;;;###autoload
+(defun company-irony (command &optional arg &rest ignored)
+  (interactive (list 'interactive))
+  (cl-case command
+    (interactive (company-begin-backend 'company-irony))
+    (prefix (and irony-mode (company-irony-prefix)))
+    (candidates (company-irony--candidates arg))
+    (annotation (company-irony--annotation
+                 (company-irony--irony-candidate arg)))
+    (meta (irony-completion-brief
+           (company-irony--irony-candidate arg)))
+    (post-completion (company-irony--post-completion
+                      (company-irony--irony-candidate arg)))
+    (ignore-case (eq company-irony-ignore-case t))
+    (no-cache (eq company-irony-ignore-case 'smart))
+    (sorted t)))
+
+;;;###autoload
+(defun company-irony-setup-begin-commands ()
+  "Include irony trigger commands to `company-begin-commands'.
+
+This allow completion to be automatically triggered after member
+accesses (obj.|, obj->|, ...).
+
+This may be useful to company < `0.8.4', newer version of company
+include these commands by default."
+  (if (listp company-begin-commands)
+      (set (make-local-variable 'company-begin-commands)
+           (delete-dups
+            (append company-begin-commands irony-completion-trigger-commands)))
+    (display-warning 'company-irony
+                     "`company-irony-setup-begin-commands' expects \
+`company-begin-commands' to be a list!")))
+
+(provide 'company-irony)
+;;; company-irony.el ends here