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]