--- /dev/null
+;;; backend-completion.el --- Let external tools control completion style -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2018-2022 Free Software Foundation, Inc.
+
+;; Version: 0.1
+;; Author: Stefan Monnier <monnier@iro.umontreal.ca>
+;; Maintainer: João Távora <joaotavora@gmail.com>
+;; Keywords:
+
+;; 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 <https://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Written by Stefan Monnier circa 2016. Variants of this code have
+;; been working stably in SLY and other packages for a long time.
+
+;; This completion style is meant to be used with a "programmable
+;; completion" table that interfaces with an external tool provinding
+;; completions, such as a shell utility, an inferior process, an http
+;; server. The table and external tool are tasked to do the matching
+;; of the pattern string to the potential candidates of completion,
+;; and as such it fully controls the style.
+
+;; When this completion style is in use, the usual styles configured
+;; by the user or other in `completion-styles' are completely
+;; overriden. This can be seen as a drawback, but, on the other hand,
+;; the regular the full data set to be available in Emacs' addressing
+;; space, which is often not feasible.
+;;
+;; The programmable completion table amounts to a function taking
+;; (PATTERN PRED ACTION) as arguments respond to at least three values
+;; for ACTION:
+;;
+;; * The symbol `metadata', where the table should reply with a list
+;; that looks like:
+;;
+;; (metadata (category . backend-completion) MORE...)
+;;
+;; where MORE... can be other "metadata" items like
+;; `cycle-sort-function'.
+;;
+;; Other categories can be used in place of `backend-completion',
+;; as long as the `styles' property of such categories contains the
+;; sole element `backend-completion-backend-style'.
+
+;; * (backend-completion-tryc . POINT) where the reply should be:
+;;
+;; (backend-completion-tryc . (PATTERN . POINT))
+;;
+;; * (backend-completion-allc . POINT) where the reply should be
+;;
+;; (backend-completion-allc COMPS...)
+;;
+;; Where COMPS... is a list of strings which are all the completions
+;; that the external tool has found for PATTERN and POINT. If the
+;; style that the external tool is using to match PATTERN is known,
+;; elements of COMPS can be propertized with
+;; 'completions-common-part' in the relevant sections.
+
+;; Note: the "tryc", "allc" suffixes are made akward on purpose, so
+;; it's easy to pick them apart from the jungle of combinations of
+;; "try" and "all" and "completion" that inhabit Emacs's completion
+;; logic.
+
+;;; Code:
+(add-to-list 'completion-styles-alist
+ '(backend-completion-backend-style
+ backend-completion--try-completion
+ backend-completion--all-completions
+ "Ad-hoc completion style provided by the completion table."))
+
+(add-to-list 'completion-category-defaults
+ '(backend-completion (styles . (backend-completion-backend-style))))
+
+;; (add-to-list 'completion-category-overrides
+;; '(backend-completion (styles . (backend-completion-backend-style))))
+
+(defun backend-completion--call (op string table pred point)
+ (when (functionp table)
+ (let ((res (funcall table string pred (cons op point))))
+ (when (eq op (car-safe res))
+ (cdr res)))))
+
+(defun backend-completion--try-completion (string table pred point)
+ (backend-completion--call 'backend-completion-tryc string table pred point))
+
+(defun backend-completion--all-completions (string table pred point)
+ (backend-completion--call 'backend-completion-allc string table pred point))
+
+(provide 'backend-completion)
+;;; backend-completion.el ends here
;; Maintainer: João Távora <joaotavora@gmail.com>
;; URL: https://github.com/joaotavora/eglot
;; Keywords: convenience, languages
-;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23"))
+;; Package-Requires: ((emacs "26.3") (jsonrpc "1.0.14") (flymake "1.2.1") (project "0.3.0") (xref "1.0.1") (eldoc "1.11.0") (seq "2.23") (backend-completion "0.1"))
;; This is a GNU ELPA :core package. Avoid adding functionality
;; that is not available in the version of Emacs recorded above or any
(require 'filenotify)
(require 'ert)
(require 'array)
+(require 'backend-completion)
;; ElDoc is preloaded in Emacs, so `require'-ing won't guarantee we are
;; using the latest version from GNU Elpa when we load eglot.el. Use an
. ,(lambda (completions)
(cl-sort completions #'> :key #'score)))
(category . eglot-indirection-joy)))
- (`(eglot--lsp-tryc . ,point) `(eglot--lsp-tryc . (,string . ,point)))
- (`(eglot--lsp-allc . ,_point) `(eglot--lsp-allc . ,(lookup string)))
+ (`(backend-completion-tryc . ,point)
+ `(backend-completion-tryc . (,string . ,point)))
+ (`(backend-completion-allc . ,_point)
+ `(backend-completion-allc . ,(lookup string)))
(_ nil))))))
(defun eglot--recover-workspace-symbol-meta (string)
eglot--workspace-symbols-cache)))
(add-to-list 'completion-category-overrides
- '(eglot-indirection-joy (styles . (eglot--lsp-backend-style))))
+ '(eglot-indirection-joy (styles . (backend-completion-backend-style))))
(cl-defmethod xref-backend-identifier-at-point ((_backend (eql eglot)))
(let ((attempt
'eglot-managed-mode-hook "1.6")
(provide 'eglot)
-\f
-;;; Backend completion
-
-;; Written by Stefan Monnier circa 2016. Something to move to
-;; minibuffer.el "ASAP" (with all the `eglot--lsp-' replaced by
-;; something else. The very same code already in SLY and stable for a
-;; long time.
-
-;; This "completion style" delegates all the work to the "programmable
-;; completion" table which is then free to implement its own
-;; completion style. Typically this is used to take advantage of some
-;; external tool which already has its own completion system and
-;; doesn't give you efficient access to the prefix completion needed
-;; by other completion styles. The table should recognize the symbols
-;; 'eglot--lsp-tryc and 'eglot--lsp-allc as ACTION, reply with
-;; (eglot--lsp-tryc COMP...) or (eglot--lsp-allc . (STRING . POINT)),
-;; accordingly. tryc/allc names made akward/recognizable on purpose.
-
-(add-to-list 'completion-styles-alist
- '(eglot--lsp-backend-style
- eglot--lsp-backend-style-try-completion
- eglot--lsp-backend-style-all-completions
- "Ad-hoc completion style provided by the completion table."))
-
-(defun eglot--lsp-backend-style-call (op string table pred point)
- (when (functionp table)
- (let ((res (funcall table string pred (cons op point))))
- (when (eq op (car-safe res))
- (cdr res)))))
-
-(defun eglot--lsp-backend-style-try-completion (string table pred point)
- (eglot--lsp-backend-style-call 'eglot--lsp-tryc string table pred point))
-
-(defun eglot--lsp-backend-style-all-completions (string table pred point)
- (eglot--lsp-backend-style-call 'eglot--lsp-allc string table pred point))
-
;; Local Variables:
;; bug-reference-bug-regexp: "\\(github#\\([0-9]+\\)\\)"