emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Generalizing find-definition


From: Stefan Monnier
Subject: Re: Generalizing find-definition
Date: Thu, 11 Dec 2014 10:07:42 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/25.0.50 (gnu/linux)

> To be honest, now I can better see the appeal of using the classes here.
> For instance, in the modified API a backend has to return `:none' in its
> identifier-at-point implementation if not found, because otherwise the
> default implementation will be called (and it's hard to implement the
> overriding otherwise).

You don't need :none.
You can do:

   (add-function :around (local xref-backend) #'elisp-xref-backend)

and then in elisp-xref-backend you do:

   (defun elisp-xref-backend (orig action ...)
     (pcase action
       ...
       (_ (apply orig args))))

> +;; For now, make the etags backend the default.
> +(defvar xref-backend #'etags-xref-backend

This should be called `xref-backend-function', to follow usual practice.

> +  "The current xref-backend.
> +This function can be called with different sets of arguments, as
> +described below.
> +
> +Required:
> +
> + (definitions IDENTIFIER): Find definitions of IDENTIFIER.  The
> +result must be a list of `xref--xref' objects.  If no definition
> +can be found, return nil.

Rename xref--xref to xref-xref, since it's clearly part of the API.

> + (references IDENTIFIER): Find references of IDENTIFIER.  The
> +result must be a list of `xref--xref' objects.  If no reference
> +can be found, return nil.
> +
> +Optional:
> +
> + (read-identifier INIT PROMPT): Read an identifier from the
> +minibuffer.  PROMPT is a string used for prompting.  INIT is
> +either an identifier to use as the initial value or nil.
> +
> + (identifier-at-point): Search and return the identfier near
> +point.  If no identifier can be found, return `:none'.
> +
> + (identifier-to-string IDENTIFIER): Return a string representing
> +IDENTIFIER.")

A few comments:
- As discussed earlier, `read-identifier' is probably a bad idea.
  Replace it with a `completion-table' method, so the completing-read is
  not in the backend but in xref.el.
- identifier-at-point should document more clearly that the return value
  may be something else than a string.  AFAIK the only interesting
  non-string non-nil case is to return a special value (e.g. a marker
  or just `t' to stand to (point)) which stands for "let the
  find-definitions code figure out the identifier at that place".
- If we restrict identifier to "a string or nil or t", then we can get
  rid of identifier-to-string.
- The first two methods use sufficiently similar (actual, identical)
  calling conventions, so it's perfectly fine to make them share
  a single backend function, but adding the other methods makes it
  scream "I want to use OO", just like completion-tables do.
  IOW, I think if we don't want to use EIEIO for the `xref-backend' objects,
  then we need to split `xref-backend' into several variables:
  - xref-find-function (can be used both for the `definitions' and for
    the `references').
  - xref-identifier-at-point-function.
  - xref-identifier-completion-table.


-- Stefan



reply via email to

[Prev in Thread] Current Thread [Next in Thread]