]> code.delx.au - gnu-emacs-elpa/blob - company-capf.el
company-capf: Perform sorting before prefix adjustment
[gnu-emacs-elpa] / company-capf.el
1 ;;; company-capf.el --- company-mode completion-at-point-functions back-end -*- lexical-binding: t -*-
2
3 ;; Copyright (C) 2013 Free Software Foundation, Inc.
4
5 ;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
6
7 ;; This file is part of GNU Emacs.
8
9 ;; GNU Emacs is free software: you can redistribute it and/or modify
10 ;; it under the terms of the GNU General Public License as published by
11 ;; the Free Software Foundation, either version 3 of the License, or
12 ;; (at your option) any later version.
13
14 ;; GNU Emacs is distributed in the hope that it will be useful,
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ;; GNU General Public License for more details.
18
19 ;; You should have received a copy of the GNU General Public License
20 ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
21
22
23 ;;; Commentary:
24 ;;
25
26 ;;; Code:
27
28 (defun company--capf-data ()
29 (let ((data (run-hook-wrapped 'completion-at-point-functions
30 ;; Ignore misbehaving functions.
31 #'completion--capf-wrapper 'optimist)))
32 (when (consp data) data)))
33
34 (defun company-capf (command &optional arg &rest _args)
35 "`company-mode' back-end using `completion-at-point-functions'.
36 Requires Emacs 24.1 or newer."
37 (interactive (list 'interactive))
38 (pcase command
39 (`interactive (company-begin-backend 'company-capf))
40 (`prefix
41 (let ((res (company--capf-data)))
42 (when res
43 (if (> (nth 2 res) (point))
44 'stop
45 (buffer-substring-no-properties (nth 1 res) (point))))))
46 (`candidates
47 (let ((res (company--capf-data)))
48 (when res
49 (let* ((table (nth 3 res))
50 (pred (plist-get (nthcdr 4 res) :predicate))
51 (meta (completion-metadata
52 (buffer-substring (nth 1 res) (nth 2 res))
53 table pred))
54 (sortfun (cdr (assq 'display-sort-function meta)))
55 (boundaries (completion-boundaries arg table pred ""))
56 (candidates (all-completions arg table pred)))
57 (when sortfun
58 (setq candidates (funcall sortfun candidates)))
59 (if (not (zerop (car boundaries)))
60 (let ((before (substring arg 0 (car boundaries))))
61 (mapcar (lambda (candidate)
62 (concat before candidate))
63 candidates))
64 candidates)))))
65 (`sorted
66 (let ((res (company--capf-data)))
67 (when res
68 (let ((meta (completion-metadata
69 (buffer-substring (nth 1 res) (nth 2 res))
70 (nth 3 res) (plist-get (nthcdr 4 res) :predicate))))
71 (cdr (assq 'display-sort-function meta))))))
72 (`duplicates nil) ;Don't bother.
73 (`no-cache t) ;FIXME: Improve!
74 (`meta
75 (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-docsig)))
76 (when f (funcall f arg))))
77 (`doc-buffer
78 (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-doc-buffer)))
79 (when f (funcall f arg))))
80 (`location
81 (let ((f (plist-get (nthcdr 4 (company--capf-data)) :company-location)))
82 (when f (funcall f arg))))
83 (`require-match
84 (plist-get (nthcdr 4 (company--capf-data)) :company-require-match))
85 (`init nil) ;Don't bother: plenty of other ways to initialize the code.
86 (`post-completion
87 (let* ((res (company--capf-data))
88 (exit-function (plist-get (nthcdr 4 res) :exit-function)))
89 (if exit-function
90 (funcall exit-function arg 'finished))))
91 ))
92
93 (provide 'company-capf)
94
95 ;;; company-capf.el ends here