minad / corfu

:desert_island: corfu.el - COmpletion in Region FUnction
GNU General Public License v3.0
1.11k stars 43 forks source link

cape-reftex ? #442

Closed paquiteau closed 6 months ago

paquiteau commented 6 months ago

Hi there,

I was relying on company-reftex for doing completion of LaTeX references. I recently made the switch to corfu/cape for the completion, and I miss the context that company-reftex provided. LaTeX-mode provides a basic completion but only with label name information, reftex brings more context.

company-reftex is simple enough for the Elisp-Padawan I am to understand, so I started to adapt it to an independent capf function:

(defvar cape-reftex-max-annotation-length 20)
(defvar cape-reftex-ref-regexp
  (rx "\\"
      ;; List taken from `reftex-ref-style-alist'
      (or "autoref"
          "autopageref"
          "Cpageref"
          "cpageref"
          "Cref"
          "cref"
          "eqref"
          "Fref"
          "fref"
          "pageref"
          "Ref"
          "ref"
          "vpageref"
          "Vref"
          "vref")
      "{"
      (group (* (not (any "}"))))
      (regexp "\\="))
  "Regular expression to use when looking for the ref prefix.
Group number 1 should be the prefix itself."
  )

(defun cape-reftex-prefix (regexp)
  "Return the prefix for matching given REGEXP."
  (and (derived-mode-p 'latex-mode)
       reftex-mode
       (when (looking-back regexp nil)
         (match-string-no-properties 1))))

(defun cape-reftex-annotate (key annotation)
  "Annotate KEY with ANNOTATION if the latter is not nil.
Obeys the setting of `company-reftex-max-annotation-length'."
  (cond
   ((not annotation) key)
   ((not cape-reftex-max-annotation-length)
    (propertize key 'reftex-annotation annotation))
   (t (propertize key 'reftex-annotation
                  (s-truncate cape-reftex-max-annotation-length annotation)))))

(defun cape-reftex-label-candidates (prefix)
  "Find all label candidates matching PREFIX."
  (reftex-access-scan-info)
  (reftex-parse-all)
  (cl-loop for entry in (symbol-value reftex-docstruct-symbol)
           if (and (stringp (car entry)) (string-prefix-p prefix (car entry)))
           collect
           ;; TODO (cape-reftex-annotate (car entry) (cl-caddr entry))))
           (car entry)))

(defun cape-reftex-label ()
  (interactive "*")
  (when-let*
      ((trig (and reftex-mode (looking-back cape-reftex-ref-regexp nil)))
       (prefix (match-string-no-properties 1))
       (beg (match-beginning 1))
       (end (match-end 1))
       (candidate (-uniq (cape-reftex-label-candidates prefix)))
       )
    (list beg end  candidate . nil )))
;; add
(add-hook 'LaTeX-mode-hook #'(lambda () (add-hook 'completion-at-point-functions #'cape-reftex-label 0 t)))

However I have several question regarding completion framework that I could not answer on my own:

Thank you for all your contribution to the emacs ecosystem.