diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2009-11-19 22:55:41 +0000 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2009-11-19 22:55:41 +0000 |
commit | eff77808b45d25ad6afd10df5616db9c5c9c7f1c (patch) | |
tree | 31497a69e8ced84de38eba57984eaaba5977c450 /lisp | |
parent | 8ab1650ee30cf51b9756f093975d4f58b7839688 (diff) | |
download | emacs-eff77808b45d25ad6afd10df5616db9c5c9c7f1c.tar.gz |
(latex-complete-bibtex-cache, latex-complete-alist): New vars.
(latex-string-prefix-p, latex-complete-bibtex-keys, latex-complete-data)
(latex-complete-envnames, latex-complete-refkeys): New functions.
(latex-complete, latex-indent-or-complete): New commands.
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ChangeLog | 7 | ||||
-rw-r--r-- | lisp/textmodes/tex-mode.el | 110 |
2 files changed, 117 insertions, 0 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index f14e545a5de..b868ce22626 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,5 +1,12 @@ 2009-11-19 Stefan Monnier <monnier@iro.umontreal.ca> + * textmodes/tex-mode.el (latex-complete-bibtex-cache) + (latex-complete-alist): New vars. + (latex-string-prefix-p, latex-complete-bibtex-keys) + (latex-complete-envnames, latex-complete-refkeys) + (latex-complete-data): New functions. + (latex-complete, latex-indent-or-complete): New commands. + * window.el (display-buffer-mark-dedicated): New var. (display-buffer): Obey it. * minibuffer.el (minibuffer-completion-help): Use it. diff --git a/lisp/textmodes/tex-mode.el b/lisp/textmodes/tex-mode.el index 9f7ff975e56..3cbd6e19e73 100644 --- a/lisp/textmodes/tex-mode.el +++ b/lisp/textmodes/tex-mode.el @@ -1420,6 +1420,116 @@ Puts point on a blank line between them." \n "\\item " >) +;;;; LaTeX completion. + +(defvar latex-complete-bibtex-cache nil) + +(defun latex-string-prefix-p (str1 str2) + (eq t (compare-strings str1 nil nil str2 0 (length str1)))) + +(defvar bibtex-reference-key) +(declare-function reftex-get-bibfile-list "reftex-cite.el" ()) + +(defun latex-complete-bibtex-keys () + (when (bound-and-true-p reftex-mode) + (lambda (key pred action) + (let ((re (concat "^[ \t]*@\\([a-zA-Z]+\\)[ \t\n]*\\([{(][ \t\n]*\\)" + (regexp-quote key))) + (files (reftex-get-bibfile-list)) + keys) + (if (and (eq (car latex-complete-bibtex-cache) + (reftex-get-bibfile-list)) + (latex-string-prefix-p (nth 1 latex-complete-bibtex-cache) + key)) + ;; Use the cache. + (setq keys (nth 2 latex-complete-bibtex-cache)) + (dolist (file files) + (with-current-buffer (find-file-noselect file) + (goto-char (point-min)) + (while (re-search-forward re nil t) + (goto-char (match-end 2)) + (when (and (not (member-ignore-case (match-string 1) + '("c" "comment" "string"))) + (looking-at bibtex-reference-key)) + (push (match-string-no-properties 0) keys))))) + ;; Fill the cache. + (set (make-local-variable 'latex-complete-bibtex-cache) + (list files key keys))) + (complete-with-action action keys key pred))))) + +(defun latex-complete-envnames () + (append latex-block-names latex-standard-block-names)) + +(defun latex-complete-refkeys () + (when (boundp 'reftex-docstruct-symbol) + (symbol-value reftex-docstruct-symbol))) + +(defvar latex-complete-alist + ;; TODO: Add \begin, \end, \ref, ... + '(("\\`\\\\\\(short\\)?cite\\'" . latex-complete-bibtex-keys) + ("\\`\\\\\\(begin\\|end\\)\\'" . latex-complete-envnames) + ("\\`\\\\[vf]?ref\\'" . latex-complete-refkeys))) + +(defun latex-complete-data () + "Get completion-data at point." + (save-excursion + (let ((pt (point))) + (skip-chars-backward "^ {}\n\t\\\\") + (case (char-before) + ((nil ?\s ?\n ?\t ?\}) nil) + (?\\ + ;; TODO: Complete commands. + nil) + (?\{ + ;; Complete args to commands. + (let* ((cmd + (save-excursion + (forward-char -1) + (skip-chars-backward " \n") + (buffer-substring (point) + (progn + (skip-chars-backward "a-zA-Z@*") + (let ((n (skip-chars-backward "\\\\"))) + (forward-char (* 2 (/ n 2)))) + (point))))) + (start (point)) + (_ (progn (goto-char pt) (skip-chars-backward "^," start))) + (comp-beg (point)) + (_ (progn (goto-char pt) (skip-chars-forward "^, {}\n\t\\\\"))) + (comp-end (point)) + (table + (funcall + (let ((f (lambda () t))) + (dolist (comp latex-complete-alist) + (if (string-match (car comp) cmd) + (setq f (cdr comp)))) + f)))) + (if (eq table t) + ;; Unknown command. + nil + (list comp-beg comp-end table)))))))) + +(defun latex-complete () + "Perform completion at point for LaTeX mode. +Return non-nil if we found what to complete." + (interactive) + (let ((data (latex-complete-data))) + (when data + (apply 'completion-in-region data) + t))) + +(defun latex-indent-or-complete () + "Perform completion at point or indentation, according to DWIM. +The heuristic is to try indentation, if that fails try completion, +if that fails insert a tab." + (interactive) + (let ((undo buffer-undo-list) + (pos (point))) + (indent-according-to-mode) + (or (not (and (eq pos (point)) (eq undo buffer-undo-list))) + (latex-complete) + (insert-tab)))) + ;;;; ;;;; LaTeX syntax navigation ;;;; |