alexeyr / company-auctex

company-mode autocompletion for auctex
49 stars 18 forks source link

Support completion of LaTeX labels within \cite, \ref, etc #17

Open swarnendubiswas opened 8 years ago

swarnendubiswas commented 8 years ago

It seems company-auctex currently does not support completing label names in LaTeX. I am not talking about LaTeX commands, but rather the labels within macros like \cite{a-seminal-paper}, \label{chap1:introduction}, etc. I think it would be extremely useful to add support for such an feature where labels such as chap1:introduction and a-seminal-paper would be completed.

ac-tex-ref provides similar functionality.

LindyBalboa commented 7 years ago

I've been working on this. Here is a prototype script to walk all .tex files given a dir and return all items in a \label{...}. This could be easily converted for .bib files and bib entries. I just don't have the focus to handle it right now. If anyone has an idea how best to incorporate this (see company-auctex-label-candidates), please make suggestions or whip up a branch yourself if you feel so inclined. This is my very first attempt at any elisp so apologies if it is a bit ham-fisted.

;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with C-x C-f and enter text in its buffer.

(defun get-string-from-file (filePath)
  "Return filePath's file content."
  (with-temp-buffer
    (insert-file-contents filePath)
    (buffer-string)))

(defun regexp-list (regex string)
  "Return a list of all REGEXP matches in STRING."
  ;; source: http://emacs.stackexchange.com/questions/7148/get-all-regexp-matches-in-buffer-as-a-list
  (let ((pos 0)        ; string marker
        (matches ()))  ; return list
    (while (string-match regex string pos)
      (push (match-string 0 string) matches)
      (setq pos (match-end 0)))
    (setq matches (reverse matches))
    matches))

(defun strip-labels (list)
  (let ((result))
    (dolist (label list result)
      (setq result (cons (substring label 7 -1) result)))))

(defun filter-tex-files (list)
  (let ((result))
    (dolist (file list result)
      (if (string-match "^[^_].*\\.tex$" file)
        (setq result (cons file result))))))

(defun find-all-labels (dir)
  (let ((result))
    (progn
      (setq tex-files (filter-tex-files (directory-files dir)))
      (dolist (file tex-files result)
        (progn 
          (setq file-string (get-string-from-file (concat dir file)))
          (setq labels (strip-labels (regexp-list "\\\\label{.*}" file-string) ))
          (setq result (append labels result)))))))

(find-all-labels "your_test_file.tex")