   (when spec
     (cl-destructuring-bind (fn . plist)
         (doom-enlist spec)
-      (put fn '+lookup-plist (plist-put plist :async async))
+      (put fn '+lookup-async (or (plist-get plist :async) async))
       (add-hook functions-var fn nil t))))
 
 (defun +lookup--symbol-or-region (&optional initial)
+  "Grab the symbol at point or selected region."
   (cond ((stringp initial)
          initial)
         ((use-region-p)
          (buffer-substring-no-properties (region-beginning)
                                          (region-end)))
         ((require 'xref nil t)
+         ;; A little smarter than using `symbol-at-point', though in most cases,
+         ;; xref ends up using `symbol-at-point' anyway.
          (xref-backend-identifier-at-point (xref-find-backend)))))
 
 (defun +lookup--run-handler (handler identifier)

      (call-interactively handler)
    (funcall handler identifier)))

(defun +lookup--run-handlers (handler identifier origin &optional other-window)
  (doom-log "Looking up '%s' with '%s'" identifier handler)
  (condition-case e
      (let ((plist (get handler '+lookup-plist)))
        (cond ((plist-get plist :async)
               (when other-window
                 ;; If async, we can't catch the window change or destination
                 ;; buffer reliably, so we set up the new window ahead of time.
                 (switch-to-buffer-other-window (current-buffer))
                 (goto-char (marker-position origin)))
               (+lookup--run-handler handler identifier)
               t)
              ((save-window-excursion
                 (and (or (+lookup--run-handler handler identifier)
                          (null origin)
                          (/= (point-marker) origin))
                      (point-marker))))))
    ((error user-error debug)
     (message "Lookup handler %S: %s" handler e)
     nil)))

(defun +lookup--jump-to (prop identifier &optional other-window)
  (let ((result
         (run-hook-wrapped
          (plist-get (list :definition '+lookup-definition-functions
                           :references '+lookup-references-functions
                           :documentation '+lookup-documentation-functions
                           :file '+lookup-file-functions)
                     prop)
          #'+lookup--run-handlers
          identifier
          (point-marker)
          other-window)))
    (if (not (markerp result))
        (ignore (message "No lookup handler could find %S" identifier))
      (funcall (if other-window
                   #'switch-to-buffer-other-window
                 #'switch-to-buffer)
               (marker-buffer result))
      (goto-char result)
      (better-jumper-set-jump)
      result)))


;;
;;; Lookup backends

(defun +lookup-xref-definitions-backend (identifier)
  "Non-interactive wrapper for `xref-find-definitions'"
  (xref-find-definitions identifier))

(defun +lookup-xref-references-backend (identifier)
  "Non-interactive wrapper for `xref-find-references'"
  (xref-find-references identifier))

(defun +lookup-dumb-jump-backend (_identifier)
  "Look up the symbol at point (or selection) with `dumb-jump', which conducts a

;;; tools/lookup/autoload/lookup.el -*- lexical-binding: t; -*-

;;;###autodef
(cl-defun set-lookup-handlers!
    (modes &rest plist &key definition references documentation file xref-backend async)
  "Define jump handlers for major or minor MODES.

A handler is either an interactive command that changes the current buffer
and/or location of the cursor, or a function that takes one argument: the
identifier being looked up, and returns either nil (failed to find it), t
(succeeded at changing the buffer/moving the cursor), or 'deferred (assume this
handler has succeeded, but expect changes not to be visible yet).

There are several kinds of handlers, which can be defined with the following
properties:

:definition FN
  Run when jumping to a symbol's definition. Used by `+lookup/definition'.
:references FN
  Run when looking for usage references of a symbol in the current project. Used
  by `+lookup/references'.
:documentation FN
  Run when looking up documentation for a symbol. Used by
  `+lookup/documentation'.
:file FN
  Run when looking up the file for a symbol/string. Typically a file path. Used
  by `+lookup/file'.
:xref-backend FN
  Defines an xref backend for a major-mode. A :definition and :references
  handler isn't necessary with a :xref-backend, but will have higher precedence
  if they exist.
:async BOOL
  Indicates that *all* supplied FNs are asynchronous. Note: lookups will not try
  any handlers after async ones, due to their nature. To get around this, you
  must write a specialized wrapper to await the async response, or use a
  different heuristic to determine, ahead of time, whether the async call will
  succeed or not.

  If you only want to specify one FN is async, declare it inline instead:

    (set-lookup-handlers! 'rust-mode
      :definition '(racer-find-definition :async t))
