auctex-diffs
[Top][All Lists]
Advanced

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

[AUCTeX-diffs] feature/capf 255ba0c2: * latex-capf.el: New file.


From: auctex-commit
Subject: [AUCTeX-diffs] feature/capf 255ba0c2: * latex-capf.el: New file.
Date: Fri, 6 May 2022 07:51:42 -0400 (EDT)

branch: feature/capf
commit 255ba0c29975061ead5ac19aab3e947c8104494d
Author: Arash Esbati <arash@gnu.org>
Commit: Arash Esbati <arash@gnu.org>

    * latex-capf.el: New file.
---
 latex-capf.el | 264 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 264 insertions(+)

diff --git a/latex-capf.el b/latex-capf.el
new file mode 100644
index 00000000..2b65bbd4
--- /dev/null
+++ b/latex-capf.el
@@ -0,0 +1,264 @@
+;;                                          -*- lexical-binding: t; -*-
+
+(eval-when-compile
+  (require 'cl-lib))
+
+(defun TeX-move-to-previous-arg (&optional bound)
+  "Move backward to the closing parenthesis of the previous argument.
+This happens under the assumption that we are in front of a macro
+argument.  This function understands the splitting of macros over
+several lines in TeX."
+  (cond
+   ;; Just to be quick:
+   ((memq (preceding-char) '(?\] ?\})))
+   ;; Do a search
+   ((re-search-backward
+     "[]}][ \t]*[\n\r]?\\([ \t]*%[^\n\r]*[\n\r]\\)*[ \t]*\\=" bound t)
+    (goto-char (1+ (match-beginning 0)))
+    t)
+   (t nil)))
+
+(defun LaTeX-what-macro (&optional bound)
+  "Find out if point is within the arguments of any TeX-macro.
+The return value is
+
+  (\"name\" mac-or-env integer type)
+
+\"name\" is the name of the macro (without backslash) or
+  environment as a string.
+mac-or-env is one of the symbols `mac' or `env'.
+integer is the number of the argument where we started.
+type is one of the symbols `mandatory' or `optional'.
+
+If the optional BOUND is an integer, bound backwards directed
+searches to this point.  If it is nil, limit to the previous 15
+lines."
+  (catch 'exit
+    ;; Exit if we're not inside a list or inside a nested list:
+    (when (/= (car (syntax-ppss)) 1)
+      (throw 'exit nil))
+    (let ((bound (or bound (line-beginning-position -15)))
+          (env-or-mac 'mac)
+          cmd cnt cnt-opt type)
+      (save-excursion
+        (save-restriction
+          (narrow-to-region (max (point-min) bound) (point-max))
+          ;; Move back out of the current parenthesis
+          (while (condition-case nil
+                     (let ((forward-sexp-function nil))
+                       (up-list -1) t)
+                   (error nil))
+            ;; Set the initial value of argument counter
+            (setq cnt 1)
+            ;; Note that we count also the right opt. or man. arg:
+            (setq cnt-opt (if (= (following-char) ?\{) 0 1))
+            ;; Record if we're inside a mand. or opt. argument
+            (setq type (if (= (following-char) ?\{) 'mandatory 'optional))
+            ;; move back over any touching sexps
+            (while (and (TeX-move-to-previous-arg bound)
+                        (condition-case nil
+                            (let ((forward-sexp-function nil))
+                              (backward-sexp) t)
+                          (error nil)))
+              (if (eq (following-char) ?\[) (cl-incf cnt-opt))
+              (cl-incf cnt))
+            (when (and (or (= (following-char) ?\[)
+                           (= (following-char) ?\{))
+                       (re-search-backward "\\\\[*a-zA-Z]+\\=" nil t))
+              (setq cmd (TeX-match-buffer 0))
+              (when (looking-at "\\\\begin{\\([^}]+\\)}")
+                (setq cmd (TeX-match-buffer 1))
+                (setq env-or-mac 'env)
+                (cl-decf cnt))
+              (if (and cmd (not (string= cmd "")))
+                  (throw 'exit
+                         (list (if (eq env-or-mac 'mac)
+                                   ;; Strip leading backslash from
+                                   ;; the macro
+                                   (substring cmd 1)
+                                 cmd)
+                               env-or-mac cnt type))
+                (throw 'exit nil)))))))))
+
+(defun LaTeX-completion-candidates-key-val (key-vals)
+  ;; First find out if we're looking for a key or a value: If we're
+  ;; after a '=', then a value, otherwise a key:
+  (let ((end (point))
+        (func (lambda (kv &optional k)
+                (if k
+                    (cadr (assoc k kv))
+                  kv)))
+        beg key)
+    (save-excursion
+      (re-search-backward "[[{,=]" (line-beginning-position 0) t))
+    (if (string= (match-string 0) "=")
+        ;; We have to look for a value:
+        (save-excursion
+          ;; Matching the value is easy, just grab everything before the
+          ;; '=' and ...
+          (re-search-backward "=\\([^=]*\\)" (line-beginning-position) t)
+          ;; ... then move forward over any tabs and spaces:
+          (save-excursion
+            (forward-char)
+            (skip-chars-forward " \t" end)
+            (setq beg (point)))
+          ;; Matching the key is less fun: `re-search-backward'
+          ;; doesn't travel enough, so we have to use
+          ;; `skip-chars-backward' and limit the search to the
+          ;; beginning of the previous line:
+          (skip-chars-backward "^,[{" (line-beginning-position 0))
+          ;; Make sure we're not looking at a comment:
+          (when (looking-at-p (concat "[ \t]*" TeX-comment-start-regexp))
+            (forward-line))
+          ;; Now pick up the key, if available:
+          (setq key (string-trim
+                     (buffer-substring-no-properties (point)
+                                                     (match-beginning 0))
+                     "[ \t\n\r%]+" "[ \t\n\r%]+"))
+          ;; This caters also for the case where nothing is typed yet:
+          (list beg end (completion-table-dynamic
+                         (lambda (_)
+                           (funcall func key-vals key)))))
+      ;; We have to look for a key:
+      (save-excursion
+        ;; Find the beginning
+        (skip-chars-backward "^,[{" (line-beginning-position 0))
+        ;; Make sure we're not looking at a comment:
+        (when (looking-at-p (concat "[ \t]*" TeX-comment-start-regexp))
+          (forward-line))
+        ;; Now go until the first char or number which would be the
+        ;; start of the key:
+        (skip-chars-forward "^a-zA-Z0-9" end)
+        (setq beg (point))
+        ;; This caters also for the case where nothing is typed yet:
+        (list beg end (completion-table-dynamic
+                       (lambda (_)
+                         (funcall func key-vals))))))))
+
+(defun LaTeX-completion-candidates-completing-read (collection)
+  (let ((end (point))
+        beg key)  ))
+
+(defun LaTeX-completion-candidates-completing-read-multiple (table)
+  nil)
+
+(defun LaTeX-completion-parse-arg (arg)
+  "Prepare ARG suitable for further completion processing."
+  (when (and (or (vectorp arg)
+                 (listp arg))
+             (symbolp (elt arg 0))
+             (fboundp (elt arg 0)))
+    ;; Turn a vector into a list:
+    (when (vectorp arg)
+      (setq arg (append arg nil)))
+    (let ((head (car arg))
+          (tail (cadr arg)))
+      (cond ((eq head #'TeX-arg-key-val)
+             (LaTeX-completion-candidates-key-val
+              (cond ((symbolp tail)
+                     ;; It is a variable name
+                     (symbol-value tail))
+                    ;; It is a function call ...
+                    ((and (listp tail)
+                          (symbolp (car tail))
+                          (fboundp (car tail)))
+                     ;; ... w/ or w/o args:
+                     (if (= (length tail) 1)
+                         (funcall (car tail))
+                       (eval tail t)))
+                    ;; It is a plain list of strings:
+                    (t tail))))
+            )  )))
+
+(defun LaTeX-completion-calculate-candidates ()
+  (catch 'exit
+    ;; Exit if not inside a list or a nested list or in a comment:
+    (when (or (/= (car (syntax-ppss)) 1)
+              (TeX-in-comment))
+      (throw 'exit nil))
+    (let ((entry (LaTeX-what-macro))
+          mac env arg head)
+      (cond ((eq (nth 1 entry) 'mac)
+             ;; Feed 'arg' to `LaTeX-completion-parse-arg' only when
+             ;; we find one:
+             (and (setq mac (assoc (car entry) (TeX-symbol-list)))
+                  (setq arg (nth (nth 2 entry) mac))
+                  (LaTeX-completion-parse-arg arg)))
+            ((eq (nth 1 entry) 'env)
+             ;; Feed 'arg' to `LaTeX-completion-parse-arg' only when
+             ;; we find one:
+             (and (setq env (assoc (car entry) (LaTeX-environment-list)))
+                  ;; Shift the number of arg if `LaTeX-env-args' is present:
+                  (setq arg (if (eq (cadr env) 'LaTeX-env-args)
+                                (nth (1+ (nth 2 entry)) env)
+                              (nth (nth 2 entry) env)))
+                  (LaTeX-completion-parse-arg arg)))
+            ;; Any other constructs?
+            (t nil)))))
+
+
+
+
+;; (defun LaTeX-calculate-candidates ()
+;;   (catch 'exit
+;;     ;; Exit if not inside a list or a nested list or in a comment:
+;;     (when (or (/= (car (syntax-ppss)) 1)
+;;               (TeX-in-comment))
+;;       (throw 'exit nil))
+;;     (let ((entry (LaTeX-what-macro))
+;;           mac env arg head) ;; tail
+;;       (cond ((eq (nth 1 entry) 'mac)
+;;              (setq mac (assoc (car entry) (TeX-symbol-list)))
+;;              (setq arg (nth (nth 2 entry) mac))
+;;              (cond ((or (vectorp arg)
+;;                         (listp arg))
+;;                     (when (vectorp arg)
+;;                       (setq arg (append arg nil)))
+;;                     (setq head (car arg))
+;;                     (cond ((functionp head)
+;;                            (cond ((eq head #'TeX-arg-key-val)
+;;                                   (LaTeX-completion-candidates-key-val 
(eval (cadr arg) t)))
+;;                                  ;; ((eq head #'TeX-arg-completing-read) 
...)
+;;                                  ;; ((eq head #'TeX-arg-crm) ...)
+;;                                  (t nil)))
+;;                           (t nil)))
+;;                    ((and (symbolp arg)
+;;                          (functionp arg)
+;;                          (fboundp arg))
+;;                     (LaTeX-completion-candidates-single arg))
+;;                    (t nil)))
+;;             ((eq (nth 1 entry) 'env)
+;;              (setq env (assoc (car entry) (LaTeX-environment-list)))
+;;              ;; Shift the number of arg if `LaTeX-env-args' is present:
+;;              (setq arg (if (eq (cadr env) 'LaTeX-env-args)
+;;                            (nth (1+ (nth 2 entry)) env)
+;;                          (nth (nth 2 entry) env)))
+;;              (cond ((or (vectorp arg)
+;;                         (listp arg))
+;;                     (when (vectorp arg)
+;;                       (setq arg (append arg nil)))
+;;                     (setq head (car arg))
+;;                     (cond ((functionp head)
+;;                            (cond ((eq head #'TeX-arg-key-val)
+;;                                   (LaTeX-completion-candidates-key-val 
(eval (cadr arg) t)))
+;;                                  ;; ((eq head #'TeX-arg-completing-read) 
...)
+;;                                  ;; ((eq head #'TeX-arg-crm) ...)
+;;                                  (t nil)))
+;;                           (t nil)))) )
+;;             ;; Any other constructs?
+;;             (t nil)))))
+
+
+
+;; (defun LaTeX-completion-candidates-single (func)
+
+;;   (let ((end (point))
+;;         beg)
+;;     (cond ((eq func #'TeX-arg-pagestyle)
+;;            (save-excursion
+;;              (skip-chars-backward "a-zA-Z0-9")
+;;              (setq beg (point)))
+;;            (list beg end (completion-table-dynamic
+;;                           (lambda (_) (LaTeX-pagestyle-list)))))
+;;           (t nil))
+;;     ))



reply via email to

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