Hi all,

I think I have a working setup for in-buffer completion of arguments of
\usepackage and/or \RequirePackage.  It needed some preparation (commit
28aa6b99e4) but it seems to work.  I could apply the same idea to
\documentclass.

Patch is attached.  Any comments welcome.

Best, Arash
diff --git a/latex.el b/latex.el
index cf2518b2..0db89aed 100644
--- a/latex.el
+++ b/latex.el
@@ -7597,6 +7597,76 @@ COLLECTION is an list of strings."
                    (lambda (_)
                      collection)))))
 
+(defvar LaTeX--completion-global-package-files nil
+  "List of LaTeX package files for in-buffer completion.
+Initialized once at the first time in-buffer completion for a
+package name is requested.  May be reset with
+`\\[universal-argument] \\[TeX-normal-mode]'.  Note that this
+variable exists in parallel with `LaTeX-global-package-files'
+which cannot be used for the purposes of in-buffer completion
+without breaking the setting of `TeX-arg-input-file-search'.")
+
+;; Add the variable to `TeX-normal-mode-reset-list':
+(add-to-list 'TeX-normal-mode-reset-list
+             'LaTeX--completion-global-package-files)
+
+(defun LaTeX-completion-candidates-usepackage (entry)
+  "Return completion candidates for arguments of \\usepackage macro.
+ENTRY is the value returned by `LaTeX-what-macro'.  This function
+provides completion for package names if point is inside the
+mandatory argument and package options if inside the first
+optional argument."
+  (cond ((eq (nth 3 entry) 'mandatory)
+         (unless LaTeX--completion-global-package-files
+           (let ((TeX-file-extensions '("sty")))
+             (message "Searching for LaTeX packages...")
+             (setq LaTeX--completion-global-package-files
+                   (TeX-search-files-by-type 'texinputs 'global t t))
+             (message "Searching for LaTeX packages...done")))
+         (LaTeX-completion-candidates-completing-read-multiple
+          LaTeX--completion-global-package-files))
+        ;; We have to be more careful for the optional argument since
+        ;; the macro can look like this:
+        ;; \usepackage[opt1]{mand}[opt2].  So we add an extra check if
+        ;; we inside the first optional arg:
+        ((and (eq (nth 3 entry) 'optional)
+              (= (nth 2 entry) 1))
+         (let ((syntax (TeX-search-syntax-table ?\[ ?\]))
+               package package-opts)
+           ;; We have to find out about the package name:
+           (save-excursion
+             (with-syntax-table syntax
+               (condition-case nil
+                   (let ((forward-sexp-function nil))
+                     (up-list))
+                 (error nil)))
+             (skip-chars-forward "^[:alnum:]")
+             (setq package (thing-at-point 'symbol t)))
+           ;; Load the style file; may fail but that's Ok for us
+           (TeX-load-style package)
+           ;; Now we have to find out how the options are available:
+           ;; This is usually a variable called
+           ;; `LaTeX-<package>-package-options'.  If it is a function,
+           ;; then the options are stored either in a variable or a
+           ;; function called `LaTeX-<package>-package-options-list:'
+           (when (setq package-opts
+                       (intern-soft (format "LaTeX-%s-package-options" package)))
+             (cond ((and (boundp package-opts)
+                         (symbol-value package-opts))
+                    (LaTeX-completion-candidates-completing-read-multiple
+                     (symbol-value package-opts)))
+                   ((and (setq package-opts
+                               (intern-soft (format "LaTeX-%s-package-options-list" package)))
+                         (boundp package-opts)
+                         (symbol-value package-opts))
+                    (LaTeX-completion-candidates-key-val
+                     (symbol-value package-opts)))
+                   ((fboundp package-opts)
+                    (LaTeX-completion-candidates-key-val
+                     (funcall package-opts)))
+                   (t nil)))))
+        (t nil)))
+
 (defun LaTeX-completion-parse-args (entry)
   "Return the match of buffer position ENTRY with AUCTeX macro definitions.
 ENTRY is generated by the function `LaTeX-what-macro'.  This
@@ -7811,7 +7881,10 @@ function `TeX--completion-at-point' which should come first in
   (when (and (LaTeX-completion-find-argument-boundries)
              (not (nth 4 (syntax-ppss))))
     (let ((entry (LaTeX-what-macro)))
-      (cond ((or (and entry
+      (cond ((and entry
+                  (member (car entry) '("usepackage" "RequirePackage")))
+             (LaTeX-completion-candidates-usepackage entry))
+            ((or (and entry
                       (eq (nth 1 entry) 'mac)
                       (assoc (car entry) (TeX-symbol-list)))
                  (and entry

Reply via email to