From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: "Roland Winkler" Newsgroups: gmane.emacs.bugs Subject: bug#10254: 24.0.92; Local variable bibtex-dialect has no effect Date: Sat, 28 Jan 2012 02:17:07 -0600 Message-ID: <20259.44803.707795.246320@gargle.gargle.HOWL> References: <844nxakxtd.fsf@tum.de> <4EE32275.26106.E38FFC3@uwe.siart.tum.de> <2rfwfoz6w2.fsf@fencepost.gnu.org> <20242.38530.735318.867329@gargle.gargle.HOWL> <20244.41728.921399.487290@gargle.gargle.HOWL> <20245.56795.932415.683301@gargle.gargle.HOWL> NNTP-Posting-Host: lo.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit X-Trace: dough.gmane.org 1327738711 5241 80.91.229.12 (28 Jan 2012 08:18:31 GMT) X-Complaints-To: usenet@dough.gmane.org NNTP-Posting-Date: Sat, 28 Jan 2012 08:18:31 +0000 (UTC) Cc: Uwe Siart , 10254@debbugs.gnu.org To: Stefan Monnier Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Sat Jan 28 09:18:26 2012 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane.org Original-Received: from lists.gnu.org ([140.186.70.17]) by lo.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1Rr3UP-0005bb-RN for geb-bug-gnu-emacs@m.gmane.org; Sat, 28 Jan 2012 09:18:26 +0100 Original-Received: from localhost ([::1]:58003 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rr3UP-0004v2-A1 for geb-bug-gnu-emacs@m.gmane.org; Sat, 28 Jan 2012 03:18:25 -0500 Original-Received: from eggs.gnu.org ([140.186.70.92]:38761) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rr3UL-0004um-RZ for bug-gnu-emacs@gnu.org; Sat, 28 Jan 2012 03:18:23 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rr3UJ-0001dm-Qf for bug-gnu-emacs@gnu.org; Sat, 28 Jan 2012 03:18:21 -0500 Original-Received: from debbugs.gnu.org ([140.186.70.43]:42069) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rr3UJ-0001di-NT for bug-gnu-emacs@gnu.org; Sat, 28 Jan 2012 03:18:19 -0500 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.72) (envelope-from ) id 1Rr3Uz-00040y-MP for bug-gnu-emacs@gnu.org; Sat, 28 Jan 2012 03:19:01 -0500 X-Loop: help-debbugs@gnu.org Resent-From: "Roland Winkler" Original-Sender: debbugs-submit-bounces@debbugs.gnu.org Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Sat, 28 Jan 2012 08:19:01 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 10254 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: Original-Received: via spool by 10254-submit@debbugs.gnu.org id=B10254.132773868515370 (code B ref 10254); Sat, 28 Jan 2012 08:19:01 +0000 Original-Received: (at 10254) by debbugs.gnu.org; 28 Jan 2012 08:18:05 +0000 Original-Received: from localhost ([127.0.0.1]:47456 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Rr3U4-0003zq-LL for submit@debbugs.gnu.org; Sat, 28 Jan 2012 03:18:05 -0500 Original-Received: from fencepost.gnu.org ([140.186.70.10]:41264 ident=Debian-exim) by debbugs.gnu.org with esmtp (Exim 4.72) (envelope-from ) id 1Rr3U1-0003zX-Jt for 10254@debbugs.gnu.org; Sat, 28 Jan 2012 03:18:02 -0500 Original-Received: from 82.red-80-32-229.staticip.rima-tde.net ([80.32.229.82]:37436 helo=regnitz) by fencepost.gnu.org with esmtpsa (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1Rr3TG-0005fV-4J; Sat, 28 Jan 2012 03:17:17 -0500 In-Reply-To: X-Mailer: VM 8.2 trial under 24.0.92.1 (x86_64-unknown-linux-gnu) X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.13 Precedence: list X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 140.186.70.43 X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Original-Sender: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane.org@gnu.org Xref: news.gmane.org gmane.emacs.bugs:56114 Archived-At: On Tue Jan 17 2012 Stefan Monnier wrote: > All I'm saying is that using explicit make-local-variable calls when you > set the variable buffer-locally, instead of using a global > make-variable-buffer-local will eliminate this potential problem, no > matter how remote. OK, here is a new version of the patch that uses by default a plain (set var val) to make all the relevant settings. But if bibtex-set-dialect is called interactively or bibtex-dialect is already buffer-local (for example, as a file-local variable), then it uses (set (make-local-variable var) val) I think this should cover all possibilities. If that's what you had in mind, the patch below could go into the next pretest. 2012-01-28 Roland Winkler * textmodes/bibtex.el (bibtex-entry-alist): New function. (bibtex-set-dialect): Use it. Either set global values of dialect-dependent variables or bind these variables buffer-locally (Bug#10254). (bibtex-mode): Call bibtex-set-dialect via hack-local-variables-hook. (bibtex-dialect): Update docstring. Add safe-local-variable predicate. (bibtex-entry-alist, bibtex-field-alist): Initialize via bibtex-set-dialect. (bibtex-mode-map): Define menu for each dialect. (bibtex-entry): Fix docstring. --- bibtex.el~ 2012-01-20 17:11:00.000000000 +++ bibtex.el 2012-01-28 00:43:24.000000000 @@ -826,7 +826,7 @@ (defcustom bibtex-dialect 'BibTeX "Current BibTeX dialect. For allowed values see `bibtex-dialect-list'. -During a session change it via `bibtex-set-dialect'." +To interactively change the dialect use the command `bibtex-set-dialect'." :group 'bibtex :set '(lambda (symbol value) (set-default symbol value) @@ -836,6 +836,7 @@ :type '(choice (const BibTeX) (const biblatex) (symbol :tag "Custom"))) +(put 'bibtex-dialect 'safe-local-variable 'symbolp) (defcustom bibtex-no-opt-remove-re "\\`option" "If a field name matches this regexp, the prefix OPT is not removed. @@ -1442,11 +1443,13 @@ ;; Internal Variables -(defvar bibtex-entry-alist bibtex-BibTeX-entry-alist - "Alist of currently active entry types.") +(defvar bibtex-entry-alist nil + "Alist of currently active entry types. +Initialized by `bibtex-set-dialect'.") -(defvar bibtex-field-alist bibtex-BibTeX-field-alist - "Alist of currently active field types.") +(defvar bibtex-field-alist nil + "Alist of currently active field types. +Initialized by `bibtex-set-dialect'.") (defvar bibtex-field-braces-opt nil "Optimized value of `bibtex-field-braces-alist'. @@ -3376,104 +3379,124 @@ (setq imenu-generic-expression (list (list nil bibtex-entry-head bibtex-key-in-head)) imenu-case-fold-search t) - (bibtex-set-dialect bibtex-dialect)) + ;; Allow `bibtex-dialect' as a file-local variable. + (add-hook 'hack-local-variables-hook 'bibtex-set-dialect nil t)) -(defun bibtex-set-dialect (dialect) - "Select BibTeX mode DIALECT. -This sets the variable `bibtex-dialect' which holds the currently active -dialect. Dialects are listed in `bibtex-dialect-list'." +(defun bibtex-entry-alist (dialect) + "Return entry-alist for DIALECT." + (let ((var (intern (format "bibtex-%s-entry-alist" dialect))) + entry-alist) + (if (boundp var) + (setq entry-alist (symbol-value var)) + (error "BibTeX dialect `%s' undefined" dialect)) + (if (not (consp (nth 1 (car entry-alist)))) + ;; new format + entry-alist + ;; Convert old format of `bibtex-entry-field-alist' + (unless (get var 'entry-list-format) + (put var 'entry-list-format "pre-24") + (message "Old format of `%s' (pre GNU Emacs 24). +Please convert to the new format." + (if (eq (indirect-variable 'bibtex-entry-field-alist) var) + 'bibtex-entry-field-alist var)) + (sit-for 3)) + (let (lst) + (dolist (entry entry-alist) + (let ((fl (nth 1 entry)) req xref opt) + (dolist (field (copy-tree (car fl))) + (if (nth 3 field) (setcar (nthcdr 3 field) 0)) + (if (or (not (nth 2 entry)) + (assoc-string (car field) (car (nth 2 entry)) t)) + (push field req) + (push field xref))) + (dolist (field (nth 1 fl)) + (push field opt)) + (push (list (car entry) nil (nreverse req) + (nreverse xref) (nreverse opt)) + lst))) + (nreverse lst))))) + +(defun bibtex-set-dialect (&optional dialect local) + "Select BibTeX DIALECT for editing BibTeX files. +This sets the user variable `bibtex-dialect' as well as the dialect-dependent +internal variables. Allowed dialects are listed in `bibtex-dialect-list'. +If DIALECT is nil use current value of `bibtex-dialect'. +If LOCAL is non-nil make buffer-local bindings for these variables rather than +setting the global values. The dialect-dependent internal variables +are also bound buffer-locally if `bibtex-dialect' is already buffer-local +in the current buffer (for example, as a file-local variable). +LOCAL is t for interactive calls." (interactive (list (intern (completing-read "Dialect: " (mapcar 'list bibtex-dialect-list) - nil t)))) - (unless (eq dialect (get 'bibtex-dialect 'dialect)) - (put 'bibtex-dialect 'dialect dialect) - (setq bibtex-dialect dialect) - - ;; Bind variables - (setq bibtex-entry-alist - (let ((var (intern (format "bibtex-%s-entry-alist" dialect))) - entry-alist) - (if (boundp var) - (setq entry-alist (symbol-value var)) - (error "BibTeX dialect `%s' undefined" dialect)) - (if (not (consp (nth 1 (car entry-alist)))) - ;; new format - entry-alist - ;; Convert old format - (unless (get var 'entry-list-format) - (put var 'entry-list-format "pre-24") - (message "Old format of `%s' (pre GNU Emacs 24). -Please convert to the new format." - (if (eq (indirect-variable 'bibtex-entry-field-alist) var) - 'bibtex-entry-field-alist var)) - (sit-for 3)) - (let (lst) - (dolist (entry entry-alist) - (let ((fl (nth 1 entry)) req xref opt) - (dolist (field (copy-tree (car fl))) - (if (nth 3 field) (setcar (nthcdr 3 field) 0)) - (if (or (not (nth 2 entry)) - (assoc-string (car field) (car (nth 2 entry)) t)) - (push field req) - (push field xref))) - (dolist (field (nth 1 fl)) - (push field opt)) - (push (list (car entry) nil (nreverse req) - (nreverse xref) (nreverse opt)) - lst))) - (nreverse lst)))) - bibtex-field-alist - (let ((var (intern (format "bibtex-%s-field-alist" dialect)))) - (if (boundp var) - (symbol-value var) - (error "Field types for BibTeX dialect `%s' undefined" dialect))) - bibtex-entry-type - (concat "@[ \t]*\\(?:" - (regexp-opt (mapcar 'car bibtex-entry-alist)) "\\)") - bibtex-entry-head (concat "^[ \t]*\\(" - bibtex-entry-type - "\\)[ \t]*[({][ \t\n]*\\(" - bibtex-reference-key - "\\)") - bibtex-entry-maybe-empty-head (concat bibtex-entry-head "?") - bibtex-any-valid-entry-type - (concat "^[ \t]*@[ \t]*\\(?:" - (regexp-opt (append '("String" "Preamble") - (mapcar 'car bibtex-entry-alist))) "\\)")) - ;; Define entry commands - (dolist (elt bibtex-entry-alist) - (let* ((entry (car elt)) - (fname (intern (concat "bibtex-" entry)))) - (unless (fboundp fname) - (eval (list 'defun fname nil - (format "Insert a new BibTeX @%s entry; see also `bibtex-entry'." - entry) - '(interactive "*") - `(bibtex-entry ,entry)))))) - ;; Define menu - ;; We use the same keymap for all BibTeX buffers. So all these buffers - ;; have the same BibTeX dialect. To define entry types buffer-locally, - ;; it would be necessary to give each BibTeX buffer a new keymap that - ;; becomes a child of `bibtex-mode-map'. Useful?? - (easy-menu-define - nil bibtex-mode-map "Entry-Types Menu in BibTeX mode" - (apply 'list "Entry-Types" - (append - (mapcar (lambda (entry) - (vector (or (nth 1 entry) (car entry)) - (intern (format "bibtex-%s" (car entry))) t)) - bibtex-entry-alist) - `("---" - ["String" bibtex-String t] - ["Preamble" bibtex-Preamble t] - "---" - ,(append '("BibTeX dialect") - (mapcar (lambda (dialect) - (vector (symbol-name dialect) - `(lambda () (interactive) - (bibtex-set-dialect ',dialect)) - t)) - bibtex-dialect-list)))))))) + nil t)) t)) + (let ((setfun (if (or local (local-variable-p 'bibtex-dialect)) + (lambda (var val) (set (make-local-variable var) val)) + 'set))) + (if dialect (funcall setfun 'bibtex-dialect dialect)) + + ;; Set internal variables + (funcall setfun 'bibtex-entry-alist (bibtex-entry-alist bibtex-dialect)) + (funcall setfun 'bibtex-field-alist + (let ((var (intern (format "bibtex-%s-field-alist" + bibtex-dialect)))) + (if (boundp var) + (symbol-value var) + (error "Field types for BibTeX dialect `%s' undefined" + bibtex-dialect)))) + (funcall setfun 'bibtex-entry-type + (concat "@[ \t]*\\(?:" + (regexp-opt (mapcar 'car bibtex-entry-alist)) "\\)")) + (funcall setfun 'bibtex-entry-head + (concat "^[ \t]*\\(" bibtex-entry-type "\\)[ \t]*[({][ \t\n]*\\(" + bibtex-reference-key "\\)")) + (funcall setfun 'bibtex-entry-maybe-empty-head + (concat bibtex-entry-head "?")) + (funcall setfun 'bibtex-any-valid-entry-type + (concat "^[ \t]*@[ \t]*\\(?:" + (regexp-opt + (append '("String" "Preamble") + (mapcar 'car bibtex-entry-alist))) "\\)")))) + +;; Entry commands and menus for BibTeX dialects +;; We do not use `easy-menu-define' here because this gets confused +;; if we want to have multiple versions of the "same" menu. +(let ((select-map (make-sparse-keymap))) + ;; Submenu for selecting the dialect + (dolist (dialect (reverse bibtex-dialect-list)) + (define-key select-map (vector dialect) + `(menu-item ,(symbol-name dialect) + (lambda () (interactive) (bibtex-set-dialect ',dialect t)) + :button (:radio . (eq bibtex-dialect ',dialect))))) + ;; We define a menu for each dialect. + ;; Then we select the menu we want via the :visible keyword + (dolist (dialect bibtex-dialect-list) + (let ((entry-alist (bibtex-entry-alist dialect)) + (menu-map (make-sparse-keymap))) + (define-key menu-map [select] + `(menu-item "BibTeX dialect" ,select-map)) + (define-key menu-map [nil-2] '(menu-item "--")) + (define-key menu-map [bibtex-preamble] + '(menu-item "Preamble" bibtex-Preamble)) + (define-key menu-map [bibtex-String] + '(menu-item "String" bibtex-String)) + (define-key menu-map [nil-1] '(menu-item "--")) + (dolist (elt (reverse entry-alist)) + ;; Entry commands + (let* ((entry (car elt)) + (fname (intern (format "bibtex-%s" entry)))) + (unless (fboundp fname) + (eval (list 'defun fname nil + (format "Insert a template for a @%s entry; see also `bibtex-entry'." + entry) + '(interactive "*") + `(bibtex-entry ,entry)))) + ;; Menu entries + (define-key menu-map (vector fname) + `(menu-item ,(or (nth 1 elt) (car elt)) ,fname)))) + (define-key bibtex-mode-map + (vector 'menu-bar dialect) + `(menu-item "Entry-Types" ,menu-map + :visible (eq bibtex-dialect ',dialect)))))) (defun bibtex-field-list (entry-type) "Return list of allowed fields for entry ENTRY-TYPE. @@ -3505,7 +3528,7 @@ (cons required optional))) (defun bibtex-entry (entry-type) - "Insert a new BibTeX entry of type ENTRY-TYPE. + "Insert a template for a BibTeX entry of type ENTRY-TYPE. After insertion call the value of `bibtex-add-entry-hook' if that value is non-nil." (interactive