aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Winkler2012-01-28 12:06:10 -0600
committerRoland Winkler2012-01-28 12:06:10 -0600
commitace88aa20f32b298e7f2e8e6115b5661504f8724 (patch)
tree9bdc93585e14c26266180dc5c9658379f082ca12
parent6e9bad1452282beabc27140cd83b6b8b17ec74d6 (diff)
downloademacs-ace88aa20f32b298e7f2e8e6115b5661504f8724.tar.gz
emacs-ace88aa20f32b298e7f2e8e6115b5661504f8724.zip
lisp/textmodes/bibtex.el: allow bibtex-dialect as file-local variable (Bug#10254)
-rw-r--r--lisp/ChangeLog15
-rw-r--r--lisp/textmodes/bibtex.el227
2 files changed, 140 insertions, 102 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e48f16ff8ce..51c56159688 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,18 @@
12012-01-28 Roland Winkler <winkler@gnu.org>
2
3 * textmodes/bibtex.el (bibtex-entry-alist): New function.
4 (bibtex-set-dialect): Use it. Either set global values of
5 dialect-dependent variables or bind these variables buffer-locally
6 (Bug#10254).
7 (bibtex-mode): Call bibtex-set-dialect via
8 hack-local-variables-hook.
9 (bibtex-dialect): Update docstring. Add
10 safe-local-variable predicate.
11 (bibtex-entry-alist, bibtex-field-alist): Initialize via
12 bibtex-set-dialect.
13 (bibtex-mode-map): Define menu for each dialect.
14 (bibtex-entry): Fix docstring.
15
12012-01-28 Chong Yidong <cyd@gnu.org> 162012-01-28 Chong Yidong <cyd@gnu.org>
2 17
3 * eshell/esh-arg.el (eshell-quote-argument): New function. 18 * eshell/esh-arg.el (eshell-quote-argument): New function.
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 955e148a2ab..292446ea24f 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -826,7 +826,7 @@ Predefined dialects include BibTeX and biblatex."
826 826
827(defcustom bibtex-dialect 'BibTeX 827(defcustom bibtex-dialect 'BibTeX
828 "Current BibTeX dialect. For allowed values see `bibtex-dialect-list'. 828 "Current BibTeX dialect. For allowed values see `bibtex-dialect-list'.
829During a session change it via `bibtex-set-dialect'." 829To interactively change the dialect use the command `bibtex-set-dialect'."
830 :group 'bibtex 830 :group 'bibtex
831 :set '(lambda (symbol value) 831 :set '(lambda (symbol value)
832 (set-default symbol value) 832 (set-default symbol value)
@@ -836,6 +836,7 @@ During a session change it via `bibtex-set-dialect'."
836 :type '(choice (const BibTeX) 836 :type '(choice (const BibTeX)
837 (const biblatex) 837 (const biblatex)
838 (symbol :tag "Custom"))) 838 (symbol :tag "Custom")))
839(put 'bibtex-dialect 'safe-local-variable 'symbolp)
839 840
840(defcustom bibtex-no-opt-remove-re "\\`option" 841(defcustom bibtex-no-opt-remove-re "\\`option"
841 "If a field name matches this regexp, the prefix OPT is not removed. 842 "If a field name matches this regexp, the prefix OPT is not removed.
@@ -1442,11 +1443,13 @@ Set this variable before loading BibTeX mode."
1442 1443
1443;; Internal Variables 1444;; Internal Variables
1444 1445
1445(defvar bibtex-entry-alist bibtex-BibTeX-entry-alist 1446(defvar bibtex-entry-alist nil
1446 "Alist of currently active entry types.") 1447 "Alist of currently active entry types.
1448Initialized by `bibtex-set-dialect'.")
1447 1449
1448(defvar bibtex-field-alist bibtex-BibTeX-field-alist 1450(defvar bibtex-field-alist nil
1449 "Alist of currently active field types.") 1451 "Alist of currently active field types.
1452Initialized by `bibtex-set-dialect'.")
1450 1453
1451(defvar bibtex-field-braces-opt nil 1454(defvar bibtex-field-braces-opt nil
1452 "Optimized value of `bibtex-field-braces-alist'. 1455 "Optimized value of `bibtex-field-braces-alist'.
@@ -3376,104 +3379,124 @@ if that value is non-nil.
3376 (setq imenu-generic-expression 3379 (setq imenu-generic-expression
3377 (list (list nil bibtex-entry-head bibtex-key-in-head)) 3380 (list (list nil bibtex-entry-head bibtex-key-in-head))
3378 imenu-case-fold-search t) 3381 imenu-case-fold-search t)
3379 (bibtex-set-dialect bibtex-dialect)) 3382 ;; Allow `bibtex-dialect' as a file-local variable.
3380 3383 (add-hook 'hack-local-variables-hook 'bibtex-set-dialect nil t))
3381(defun bibtex-set-dialect (dialect) 3384
3382 "Select BibTeX mode DIALECT. 3385(defun bibtex-entry-alist (dialect)
3383This sets the variable `bibtex-dialect' which holds the currently active 3386 "Return entry-alist for DIALECT."
3384dialect. Dialects are listed in `bibtex-dialect-list'." 3387 (let ((var (intern (format "bibtex-%s-entry-alist" dialect)))
3388 entry-alist)
3389 (if (boundp var)
3390 (setq entry-alist (symbol-value var))
3391 (error "BibTeX dialect `%s' undefined" dialect))
3392 (if (not (consp (nth 1 (car entry-alist))))
3393 ;; new format
3394 entry-alist
3395 ;; Convert old format of `bibtex-entry-field-alist'
3396 (unless (get var 'entry-list-format)
3397 (put var 'entry-list-format "pre-24")
3398 (message "Old format of `%s' (pre GNU Emacs 24).
3399Please convert to the new format."
3400 (if (eq (indirect-variable 'bibtex-entry-field-alist) var)
3401 'bibtex-entry-field-alist var))
3402 (sit-for 3))
3403 (let (lst)
3404 (dolist (entry entry-alist)
3405 (let ((fl (nth 1 entry)) req xref opt)
3406 (dolist (field (copy-tree (car fl)))
3407 (if (nth 3 field) (setcar (nthcdr 3 field) 0))
3408 (if (or (not (nth 2 entry))
3409 (assoc-string (car field) (car (nth 2 entry)) t))
3410 (push field req)
3411 (push field xref)))
3412 (dolist (field (nth 1 fl))
3413 (push field opt))
3414 (push (list (car entry) nil (nreverse req)
3415 (nreverse xref) (nreverse opt))
3416 lst)))
3417 (nreverse lst)))))
3418
3419(defun bibtex-set-dialect (&optional dialect local)
3420 "Select BibTeX DIALECT for editing BibTeX files.
3421This sets the user variable `bibtex-dialect' as well as the dialect-dependent
3422internal variables. Allowed dialects are listed in `bibtex-dialect-list'.
3423If DIALECT is nil use current value of `bibtex-dialect'.
3424If LOCAL is non-nil make buffer-local bindings for these variables rather than
3425setting the global values. The dialect-dependent internal variables
3426are also bound buffer-locally if `bibtex-dialect' is already buffer-local
3427in the current buffer (for example, as a file-local variable).
3428LOCAL is t for interactive calls."
3385 (interactive (list (intern (completing-read "Dialect: " 3429 (interactive (list (intern (completing-read "Dialect: "
3386 (mapcar 'list bibtex-dialect-list) 3430 (mapcar 'list bibtex-dialect-list)
3387 nil t)))) 3431 nil t)) t))
3388 (unless (eq dialect (get 'bibtex-dialect 'dialect)) 3432 (let ((setfun (if (or local (local-variable-p 'bibtex-dialect))
3389 (put 'bibtex-dialect 'dialect dialect) 3433 (lambda (var val) (set (make-local-variable var) val))
3390 (setq bibtex-dialect dialect) 3434 'set)))
3391 3435 (if dialect (funcall setfun 'bibtex-dialect dialect))
3392 ;; Bind variables 3436
3393 (setq bibtex-entry-alist 3437 ;; Set internal variables
3394 (let ((var (intern (format "bibtex-%s-entry-alist" dialect))) 3438 (funcall setfun 'bibtex-entry-alist (bibtex-entry-alist bibtex-dialect))
3395 entry-alist) 3439 (funcall setfun 'bibtex-field-alist
3396 (if (boundp var) 3440 (let ((var (intern (format "bibtex-%s-field-alist"
3397 (setq entry-alist (symbol-value var)) 3441 bibtex-dialect))))
3398 (error "BibTeX dialect `%s' undefined" dialect)) 3442 (if (boundp var)
3399 (if (not (consp (nth 1 (car entry-alist)))) 3443 (symbol-value var)
3400 ;; new format 3444 (error "Field types for BibTeX dialect `%s' undefined"
3401 entry-alist 3445 bibtex-dialect))))
3402 ;; Convert old format 3446 (funcall setfun 'bibtex-entry-type
3403 (unless (get var 'entry-list-format) 3447 (concat "@[ \t]*\\(?:"
3404 (put var 'entry-list-format "pre-24") 3448 (regexp-opt (mapcar 'car bibtex-entry-alist)) "\\)"))
3405 (message "Old format of `%s' (pre GNU Emacs 24). 3449 (funcall setfun 'bibtex-entry-head
3406Please convert to the new format." 3450 (concat "^[ \t]*\\(" bibtex-entry-type "\\)[ \t]*[({][ \t\n]*\\("
3407 (if (eq (indirect-variable 'bibtex-entry-field-alist) var) 3451 bibtex-reference-key "\\)"))
3408 'bibtex-entry-field-alist var)) 3452 (funcall setfun 'bibtex-entry-maybe-empty-head
3409 (sit-for 3)) 3453 (concat bibtex-entry-head "?"))
3410 (let (lst) 3454 (funcall setfun 'bibtex-any-valid-entry-type
3411 (dolist (entry entry-alist) 3455 (concat "^[ \t]*@[ \t]*\\(?:"
3412 (let ((fl (nth 1 entry)) req xref opt) 3456 (regexp-opt
3413 (dolist (field (copy-tree (car fl))) 3457 (append '("String" "Preamble")
3414 (if (nth 3 field) (setcar (nthcdr 3 field) 0)) 3458 (mapcar 'car bibtex-entry-alist))) "\\)"))))
3415 (if (or (not (nth 2 entry)) 3459
3416 (assoc-string (car field) (car (nth 2 entry)) t)) 3460;; Entry commands and menus for BibTeX dialects
3417 (push field req) 3461;; We do not use `easy-menu-define' here because this gets confused
3418 (push field xref))) 3462;; if we want to have multiple versions of the "same" menu.
3419 (dolist (field (nth 1 fl)) 3463(let ((select-map (make-sparse-keymap)))
3420 (push field opt)) 3464 ;; Submenu for selecting the dialect
3421 (push (list (car entry) nil (nreverse req) 3465 (dolist (dialect (reverse bibtex-dialect-list))
3422 (nreverse xref) (nreverse opt)) 3466 (define-key select-map (vector dialect)
3423 lst))) 3467 `(menu-item ,(symbol-name dialect)
3424 (nreverse lst)))) 3468 (lambda () (interactive) (bibtex-set-dialect ',dialect t))
3425 bibtex-field-alist 3469 :button (:radio . (eq bibtex-dialect ',dialect)))))
3426 (let ((var (intern (format "bibtex-%s-field-alist" dialect)))) 3470 ;; We define a menu for each dialect.
3427 (if (boundp var) 3471 ;; Then we select the menu we want via the :visible keyword
3428 (symbol-value var) 3472 (dolist (dialect bibtex-dialect-list)
3429 (error "Field types for BibTeX dialect `%s' undefined" dialect))) 3473 (let ((entry-alist (bibtex-entry-alist dialect))
3430 bibtex-entry-type 3474 (menu-map (make-sparse-keymap)))
3431 (concat "@[ \t]*\\(?:" 3475 (define-key menu-map [select]
3432 (regexp-opt (mapcar 'car bibtex-entry-alist)) "\\)") 3476 `(menu-item "BibTeX dialect" ,select-map))
3433 bibtex-entry-head (concat "^[ \t]*\\(" 3477 (define-key menu-map [nil-2] '(menu-item "--"))
3434 bibtex-entry-type 3478 (define-key menu-map [bibtex-preamble]
3435 "\\)[ \t]*[({][ \t\n]*\\(" 3479 '(menu-item "Preamble" bibtex-Preamble))
3436 bibtex-reference-key 3480 (define-key menu-map [bibtex-String]
3437 "\\)") 3481 '(menu-item "String" bibtex-String))
3438 bibtex-entry-maybe-empty-head (concat bibtex-entry-head "?") 3482 (define-key menu-map [nil-1] '(menu-item "--"))
3439 bibtex-any-valid-entry-type 3483 (dolist (elt (reverse entry-alist))
3440 (concat "^[ \t]*@[ \t]*\\(?:" 3484 ;; Entry commands
3441 (regexp-opt (append '("String" "Preamble") 3485 (let* ((entry (car elt))
3442 (mapcar 'car bibtex-entry-alist))) "\\)")) 3486 (fname (intern (format "bibtex-%s" entry))))
3443 ;; Define entry commands 3487 (unless (fboundp fname)
3444 (dolist (elt bibtex-entry-alist) 3488 (eval (list 'defun fname nil
3445 (let* ((entry (car elt)) 3489 (format "Insert a template for a @%s entry; see also `bibtex-entry'."
3446 (fname (intern (concat "bibtex-" entry)))) 3490 entry)
3447 (unless (fboundp fname) 3491 '(interactive "*")
3448 (eval (list 'defun fname nil 3492 `(bibtex-entry ,entry))))
3449 (format "Insert a new BibTeX @%s entry; see also `bibtex-entry'." 3493 ;; Menu entries
3450 entry) 3494 (define-key menu-map (vector fname)
3451 '(interactive "*") 3495 `(menu-item ,(or (nth 1 elt) (car elt)) ,fname))))
3452 `(bibtex-entry ,entry)))))) 3496 (define-key bibtex-mode-map
3453 ;; Define menu 3497 (vector 'menu-bar dialect)
3454 ;; We use the same keymap for all BibTeX buffers. So all these buffers 3498 `(menu-item "Entry-Types" ,menu-map
3455 ;; have the same BibTeX dialect. To define entry types buffer-locally, 3499 :visible (eq bibtex-dialect ',dialect))))))
3456 ;; it would be necessary to give each BibTeX buffer a new keymap that
3457 ;; becomes a child of `bibtex-mode-map'. Useful??
3458 (easy-menu-define
3459 nil bibtex-mode-map "Entry-Types Menu in BibTeX mode"
3460 (apply 'list "Entry-Types"
3461 (append
3462 (mapcar (lambda (entry)
3463 (vector (or (nth 1 entry) (car entry))
3464 (intern (format "bibtex-%s" (car entry))) t))
3465 bibtex-entry-alist)
3466 `("---"
3467 ["String" bibtex-String t]
3468 ["Preamble" bibtex-Preamble t]
3469 "---"
3470 ,(append '("BibTeX dialect")
3471 (mapcar (lambda (dialect)
3472 (vector (symbol-name dialect)
3473 `(lambda () (interactive)
3474 (bibtex-set-dialect ',dialect))
3475 t))
3476 bibtex-dialect-list))))))))
3477 3500
3478(defun bibtex-field-list (entry-type) 3501(defun bibtex-field-list (entry-type)
3479 "Return list of allowed fields for entry ENTRY-TYPE. 3502 "Return list of allowed fields for entry ENTRY-TYPE.
@@ -3505,7 +3528,7 @@ and `bibtex-user-optional-fields'."
3505 (cons required optional))) 3528 (cons required optional)))
3506 3529
3507(defun bibtex-entry (entry-type) 3530(defun bibtex-entry (entry-type)
3508 "Insert a new BibTeX entry of type ENTRY-TYPE. 3531 "Insert a template for a BibTeX entry of type ENTRY-TYPE.
3509After insertion call the value of `bibtex-add-entry-hook' if that value 3532After insertion call the value of `bibtex-add-entry-hook' if that value
3510is non-nil." 3533is non-nil."
3511 (interactive 3534 (interactive