aglew@crhc.uiuc.edu (Andy Glew) (10/05/90)
I am writing LaTeX using BiBTeX under GNU EMACS.
LaTeX \cite{}s require the keyword that I attached to the bibliography
entry. Since these frequently get long and mesy, does anyone have a
citation-name completion command (like filename completion).
Similarly for \ref{}s.
I may have missed this in the existing GNU EMACS TeX modes.
--
Andy Glew, a-glew@uiuc.edu [get ph nameserver from uxc.cso.uiuc.edu:net/qi]aglew@crhc.uiuc.edu (Andy Glew) (10/08/90)
One suggestion for cite and reference name completion has been to use the elisp from the vortex distribution. While not providing filename completion, it does provide searches. -- Andy Glew, a-glew@uiuc.edu [get ph nameserver from uxc.cso.uiuc.edu:net/qi]
aglew@crhc.uiuc.edu (Andy Glew) (10/10/90)
A while back I asked if there was a \cite-name completion package for
TeX/LaTeX/BiBTeX under GNU Emacs. Vortex has a search function, but
quickly tiring of vortex, I wrote the following code today to do
BiBTeX \cite name completion.
In fact, the package is generic, and can be used to do expansion on
any reasonably short list that can be grepped by a shell command. I
have so far instantiated the macros for BiBTeX \cite, TeX \ref, and MH
mail aliases.
People will undoubtedly want to change my key bindings,
and make this into a hook.
I call this "completion.el". Probably conflicts.
;;; Generic completion functions
;;; This macro and its helpers extend completing-read
;;; by creating a system of functions and variables
;;; to do completing reads on various lists of things
;;; which can be grepped by shell commands.
;;; I provide examples for BiBTeX, \cite keys,
;;; TeX/LaTeX \ref labels
;;; and MH aliases (I can never remember my "easy to rember"
;;; MH aliases.
;;; To use, load from your .emacs.
;;; Sane people will almost undoubtedly want to change my key bindings
;;; (really, all packages should separate functionality and key bindings).
;;; You probably will also want to make these definitions mode specific
;;; and/or buffer local -- I don't, because I prefer modelessness --
;;; by calling them in your hooks instead of inline.
;;; $Header: /home/dwarfs/aglew/gnu/RCS/completion.el,v 1.3 90/10/09 17:46:22 aglew Exp $
;;; aglew@uiuc.edu Tue Oct 9 17:45:38 1990
(defmacro make-completion-stuff (
XXcompletionXX
XXshellcommandXX
XXfilesXX
XXfilespromptXX
XXpromptXX
XXkeybindingXX
XXtmpbufXX
)
"
Macro defining a family of variables and functions for completion based on a list
of targets obtained by executing a shell command.
Produces:
XXcompletionXX-files
List of files to scan.
XXcompletionXX-shell-command
Command used to grep out targets.
build-XXcompletionXX-alist
Manually build or replace the target expansion list when it
is changed externally (interim: should be automatic).
complete-XXcompletionXX
Perform a completing read on the list of targets, and insert
the result into the local buffer.
Arguments are all strings (symbols, etc. created by macro concatenation):
XXcompletionXX
A generic \"root name\" for the functions to be created.
Eg. BiBTeX \cite key expansion sets this to \"bibtex-key\"
XXshellcommandXX
A format pattern for the shell command to be executed that
will produce a list of targets for expansion, one per line.
Usually contains a %s that the XXfilesXX variable will
be substituted into.
XXfilesXX
Shell pattern (wildcard and/or list) that is substituted into
XXshellcommandXX as an argument. Broken out for ease of modification.
Eg. BiBTeX \cite key expansion sets this to \"*.bib\".
XXfilespromptXX
Prompt to use when asking user to change XXfilesXX.
XXpromptXX
Prompt to use when asking user to complete a target.
XXkeybindingXX
Keybinding that the complete-XXcompletionXX command will
be globally bound to.
XXtmpbufXX
Temporary buffer to work in.
"
(`(progn
(defvar (, (intern(concat XXcompletionXX "-files"))) (, XXfilesXX)
(, (concat "*List of " XXfilespromptXX " for " XXcompletionXX "(string substituted in " XXcompletionXX "-shell-command)")))
(defvar (, (intern(concat XXcompletionXX "-shell-command"))) (, XXshellcommandXX)
(, (concat "*Format of shell command used to grep " XXpromptXX " --- " XXcompletionXX "-files is substituted")))
(defvar (, (intern(concat XXcompletionXX "-alist"))) nil
(, (concat "Alist of " XXpromptXX " used by complete-" XXcompletionXX)))
(defun (, (intern(concat "validate-" XXcompletionXX "-alist"))) ()
(if (, (intern(concat XXcompletionXX "-alist")))
(, (intern(concat XXcompletionXX "-alist")))
((, (intern(concat "build-" XXcompletionXX "-alist"))))))
(defun (, (intern(concat "build-" XXcompletionXX "-alist"))) ()
(, (concat "*Build alist of " XXpromptXX " used by complete-" XXcompletionXX))
(interactive)
(setq (, (intern(concat XXcompletionXX "-alist")))
((, (intern(concat "get-" XXcompletionXX "-alist")))
(read-from-minibuffer (concat (, XXfilespromptXX) ": ")
(, (intern(concat XXcompletionXX "-files")))))))
(make-global-binding (, XXkeybindingXX) (quote (, (intern(concat "complete-" XXcompletionXX)))))
(defun (, (intern(concat "complete-" XXcompletionXX))) ()
(, (concat "*Completing read of " XXpromptXX))
(interactive)
(insert (completing-read (concat (, XXpromptXX) ": ")
((, (intern(concat "validate-" XXcompletionXX "-alist"))))
nil nil nil)))
(defun (, (intern(concat "get-" XXcompletionXX "-alist"))) (files)
(save-excursion
(let ((cd default-directory))
(set-buffer (get-buffer-create (, XXtmpbufXX)))
(erase-buffer)
(setq default-directory cd)
(shell-command (format (, (intern(concat XXcompletionXX "-shell-command"))) (, (intern(concat XXcompletionXX "-files")))) t)
(list-to-alist (list-of-lines-in-buffer (current-buffer))))))
)))
(make-completion-stuff "bibtex-key"
"grep '@.*{.*,' %s | sed -e 's/.*{//' -e 's/,.*//'"
"*.bib"
"BiBTeX databases"
"BiBTeX keys"
"\^c\^cb"
"*bibtex-tmp*"
)
(make-completion-stuff "tex-label"
"grep 'newlabel' %s | sed -e 's/.*newlabel{//' -e 's/}.*//'"
"*.aux"
"TeX .aux files"
"TeX labels"
"\^c\^cl"
"*tex-tmp*"
)
(make-completion-stuff "mh-alias"
"grep ':' %s | sed -e 's/:.*//'"
(expand-file-name (substitute-in-file-name "~/Mail/mh-aliases"))
"MH alias file(s)"
"MH alias"
"\^c\^cm"
"*mh-tmp*"
)
(make-completion-stuff "mh-alias-expansion"
"grep ':' %s | sed -e 's/.*:[ ]*//'"
(expand-file-name (substitute-in-file-name "~/Mail/mh-aliases"))
"MH alias file(s)"
"MH alias-expansion"
"\^c\^cM"
"*mh-tmp*"
)
;;;; Helper functions
(defun list-to-alist (list)
"Convert a list to an alist, where each list element is car of each alist element"
(mapcar 'list list))
(defun list-of-lines-in-buffer (buf)
"Create a list from the lines in a buffer"
(save-excursion
(set-buffer buf)
(let ((list nil))
(goto-char (point-min))
(while (not (eobp))
(re-search-forward ".*" (point-max) t)
(setq list (append list (list (buffer-substring (match-beginning 0) (match-end 0)))))
(re-search-forward "\n" (point-max) t))
list)))
--
Andy Glew, a-glew@uiuc.edu [get ph nameserver from uxc.cso.uiuc.edu:net/qi]aglew@crhc.uiuc.edu (Andy Glew) (10/11/90)
Ooops... bug in previously posted code: =================================================================== RCS file: RCS/completion.el,v retrieving revision 1.3 diff -c5 -r1.3 completion.el *** /tmp/,RCSt1a11387 Wed Oct 10 13:24:33 1990 --- completion.el Wed Oct 10 12:30:03 1990 *************** *** 105,115 **** (save-excursion (let ((cd default-directory)) (set-buffer (get-buffer-create (, XXtmpbufXX))) (erase-buffer) (setq default-directory cd) ! (shell-command (format (, (intern(concat XXcompletionXX "-shell-command"))) (, (intern(concat XXcompletionXX "-files")))) t) (list-to-alist (list-of-lines-in-buffer (current-buffer)))))) ))) --- 105,115 ---- (save-excursion (let ((cd default-directory)) (set-buffer (get-buffer-create (, XXtmpbufXX))) (erase-buffer) (setq default-directory cd) ! (shell-command (format (, (intern(concat XXcompletionXX "-shell-command"))) files) t) (list-to-alist (list-of-lines-in-buffer (current-buffer)))))) ))) -- Andy Glew, a-glew@uiuc.edu [get ph nameserver from uxc.cso.uiuc.edu:net/qi]