;;;;;;;;;;;;;;;;;;;;;;;;;;; -*- Mode: Emacs-Lisp -*- ;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 
;; tex-cpl.el - completion for TeX/LaTeX modes
;; 
;; Copyright (C) 1991 Kresten Krab Thorup (krab@iesd.auc.dk).
;; 
;; 
;; 
;; $Id: tex-cpl.el,v 1.6 1992/03/18 17:34:35 krab Exp $
;; 
;; LCD Archive Entry:
;; tex-cpl.el|Kresten Krab Thorup|krab@iesd.auc.dk
;; | ...description...
;; |$Date: 1992/03/18 17:34:35 $|$Revision: 1.6 $|iesd.auc.dk:/pub/emacs-lisp/tex-cpl.el
;; 
;; Author          : Kresten Krab Thorup
;; Created On      : Sun Sep  1 22:11:35 1991
;; Last Modified By: Kresten Krab Thorup
;; Last Modified On: Wed Mar 18 17:31:23 1992
;; Update Count    : 108
;; 
;; HISTORY
;; 9-Dec-1991  (Last Mod: Mon Dec  9 10:11:04 1991 #102)  Kresten Krab Thorup
;;    Fixed TeX-complete-symbol, so that it can complete even "empty"
;;    control sequences, as suggested by by smith@pell.anu.edu.au
;;    (Michael Smith) 
;; 

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; This file depends on the file tex-symb.el , which is generated
;; by the perl script "extract_tex_symbols.pl". You need to run
;; to make these files.
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; THE GOOD GUYS:
;;
;; Michael Smith                     <smith@pell.anu.edu.au>
;;
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(provide 'tex-cpl)

(defun get-symbols (files)
"Returns a list of symbols defined in FILES"
(require 'tex-misc)
(require 'tex-symb)

(let ((visited '())
      (symbols '())
      (yet-to-visit files))
  (while (not (equal nil yet-to-visit))
    (recursive-add-symbols (car yet-to-visit))
    (setq yet-to-visit (cdr yet-to-visit)))
  symbols))

(defun recursive-add-symbols (file)
  (if (not (memq file visited))
      ;; if we have not already been here
      (progn
	;; add this file to the list of visited.
	(setq visited (cons file visited))
	
	;; and add the associated symbols to the symbols variable
	(setq symbols (append symbols (car (cdr (assoc file TeX-symb)))))

	;; now loop over the files to visit
	(let ((yet-to-visit (get-subfiles file)))
	  (while (not (equal nil yet-to-visit))
	    (recursive-add-symbols (car yet-to-visit))
	    (setq yet-to-visit (cdr yet-to-visit)))))))


(defun TeX-complete-symbol ()
  "Perform completion on TeX/LaTeX symbol preceding point.
That symbol is compared against the symbols that exist
and any additional characters determined by what is there
are inserted."
  (interactive)
  (TeX-update-completion)
  (let* ((end (point))
	 (TeX-command-p nil)
         (beg (save-excursion
		(if (= (preceding-char) (string-to-char TeX-esc)) 
		    (progn					  
		      (setq TeX-command-p t)			  
		      (point))
		  (backward-sexp 1)
		  (while (= (following-char) (string-to-char TeX-esc))
		    (forward-char 1)
		    (setq TeX-command-p t))
		  (point))))
         (pattern (buffer-substring beg end))
         (completion (try-completion pattern TeX-names nil)))
    (if TeX-command-p
	(cond ((eq completion t))
	      ((null completion)
	       (message "Can't find completion for \"\\%s\"" pattern)
	       (ding))
	      ((not (string= pattern completion))
	       (delete-region beg end)
	       (insert completion))
	      (t
	       (message "Making completion list...")
	       (let ((list (all-completions pattern TeX-names nil)))
		 (with-output-to-temp-buffer "*Completions*"
		   (display-completion-list list)))
	       (message "Making completion list...done")))
      (funcall TeX-complete-word))))

(defun TeX-update-completion ()
  "Update the completion list (TeX-names)"
  (interactive)
  (let ((fmt TeX-format-package)
	(sty (list (LaTeX-document-style)))
	(opt (split-string "," (LaTeX-style-options))))
    (if
	;; if none of the lists has changed - do nothing.
	;; otherwise do the actual update. and set the new values
	;; for the `last' variables.
	(not
	 (and (equal TeX-last-fmt (if fmt fmt '("")))
	      (equal LaTeX-last-sty (if sty sty '("")))
	      (equal LaTeX-last-opt (if opt opt '("")))))
	(let ((sty-pt (list (concat
			     (cond ((string= "article" (car sty))
				    "art")
				   ((string= "book" (car sty))
				    "bk")
				   ((string= "report" (car sty))
				    "rep")
				   (t
				    (car sty)))
			     (cond ((assoc "11pt" opt)
				    "11")
				   ((assoc "12pt" opt)
				    "12")
				   (t
				    "10"))))))
	  (require 'vir-symb)
	  ;; I sort the completions now. This is to make it easyer for
	  ;; the `completion' function to sort them (it's a build-in,
	  ;; which always sorts...)
	  (setq TeX-names (sort (append
				 TeX-virgin-symbols
				 (get-symbols (append fmt sty opt sty-pt)))
				'string-list-sorter))
	  (setq TeX-last-fmt (if fmt fmt '("")))
	  (setq LaTeX-last-sty (if sty sty '("")))
	  (setq LaTeX-last-opt (if opt opt '("")))))
    )
  )

(defun string-list-sorter (a b)
  (string< (car a) (car b)))

(defvar TeX-names (get-symbols TeX-format-package)
  "List of currently available symbols for LaTeX-complete-symbol")

