aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRoland Winkler2011-06-05 00:46:43 -0500
committerRoland Winkler2011-06-05 00:46:43 -0500
commit34699b85fd84223412b39dc2e455d43756903671 (patch)
tree3bc5e7f7b5bc5fee910c5f37720871f650e3b9d5
parent004dedd364f5944b51b61acf90c4976f9c974ba9 (diff)
downloademacs-34699b85fd84223412b39dc2e455d43756903671.tar.gz
emacs-34699b85fd84223412b39dc2e455d43756903671.zip
lisp/textmodes/bibtex.el: new command bibtex-search-entries
-rw-r--r--etc/NEWS2
-rw-r--r--lisp/ChangeLog6
-rw-r--r--lisp/textmodes/bibtex.el120
3 files changed, 128 insertions, 0 deletions
diff --git a/etc/NEWS b/etc/NEWS
index 9b1bb99eb1b..e657b791505 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -438,6 +438,8 @@ Just set shell-dir-cookie-re to an appropriate regexp.
438 438
439** BibTeX mode 439** BibTeX mode
440 440
441*** New command `bibtex-search-entries' bound to C-c C-a.
442
441*** New `bibtex-entry-format' option `sort-fields', disabled by default. 443*** New `bibtex-entry-format' option `sort-fields', disabled by default.
442 444
443*** New variable `bibtex-search-entry-globally'. 445*** New variable `bibtex-search-entry-globally'.
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 8a7b9f4f822..2e0352a7bdf 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,11 @@
12011-06-05 Roland Winkler <winkler@gnu.org> 12011-06-05 Roland Winkler <winkler@gnu.org>
2 2
3 * textmodes/bibtex.el (bibtex-search-buffer): New variable.
4 (bibtex-search-entries): New command bound to C-c C-a.
5 (bibtex-display-entries): New function.
6
72011-06-05 Roland Winkler <winkler@gnu.org>
8
3 * textmodes/bibtex.el (bibtex-generate-url-list): Fix docstring. 9 * textmodes/bibtex.el (bibtex-generate-url-list): Fix docstring.
4 (bibtex-insert-kill): After yanking insert newline if necessary. 10 (bibtex-insert-kill): After yanking insert newline if necessary.
5 (bibtex-initialize): Call bibtex-string-files-init only once. 11 (bibtex-initialize): Call bibtex-string-files-init only once.
diff --git a/lisp/textmodes/bibtex.el b/lisp/textmodes/bibtex.el
index 6d07a6e3950..12094887f38 100644
--- a/lisp/textmodes/bibtex.el
+++ b/lisp/textmodes/bibtex.el
@@ -968,6 +968,11 @@ Set this variable before loading BibTeX mode."
968 :group 'bibtex 968 :group 'bibtex
969 :type 'boolean) 969 :type 'boolean)
970 970
971(defcustom bibtex-search-buffer "*BibTeX Search*"
972 "Buffer for BibTeX search results."
973 :group 'bibtex
974 :type 'string)
975
971;; `bibtex-font-lock-keywords' is a user option, too. But since the 976;; `bibtex-font-lock-keywords' is a user option, too. But since the
972;; patterns used to define this variable are defined in a later 977;; patterns used to define this variable are defined in a later
973;; section of this file, it is defined later. 978;; section of this file, it is defined later.
@@ -1025,6 +1030,7 @@ Set this variable before loading BibTeX mode."
1025 (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry) 1030 (define-key km "\C-c\C-rn" 'bibtex-narrow-to-entry)
1026 (define-key km "\C-c\C-rw" 'widen) 1031 (define-key km "\C-c\C-rw" 'widen)
1027 (define-key km "\C-c\C-l" 'bibtex-url) 1032 (define-key km "\C-c\C-l" 'bibtex-url)
1033 (define-key km "\C-c\C-a" 'bibtex-search-entries)
1028 (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT) 1034 (define-key km "\C-c\C-o" 'bibtex-remove-OPT-or-ALT)
1029 (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings) 1035 (define-key km "\C-c\C-e\C-i" 'bibtex-InProceedings)
1030 (define-key km "\C-c\C-ei" 'bibtex-InCollection) 1036 (define-key km "\C-c\C-ei" 'bibtex-InCollection)
@@ -1102,6 +1108,8 @@ Set this variable before loading BibTeX mode."
1102 ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex 1108 ["View Cite Locations (RefTeX)" reftex-view-crossref-from-bibtex
1103 (fboundp 'reftex-view-crossref-from-bibtex)]) 1109 (fboundp 'reftex-view-crossref-from-bibtex)])
1104 ("Operating on Buffer or Region" 1110 ("Operating on Buffer or Region"
1111 ["Search Entries" bibtex-search-entries t]
1112 "--"
1105 ["Validate Entries" bibtex-validate t] 1113 ["Validate Entries" bibtex-validate t]
1106 ["Sort Entries" bibtex-sort-buffer t] 1114 ["Sort Entries" bibtex-sort-buffer t]
1107 ["Reformat Entries" bibtex-reformat t] 1115 ["Reformat Entries" bibtex-reformat t]
@@ -4789,6 +4797,118 @@ Return the URL or nil if none can be generated."
4789 (message "No URL known.")) 4797 (message "No URL known."))
4790 url))) 4798 url)))
4791 4799
4800;; We could combine multiple seach results with set operations
4801;; AND, OR, MINUS, and NOT. Would this be useful?
4802;; How complicated are searches in real life?
4803;; We could also have other searches such as "publication year newer than...".
4804(defun bibtex-search-entries (field regexp &optional global display)
4805 "Search BibTeX entries for FIELD matching REGEXP.
4806REGEXP may be a regexp to search for.
4807If REGEXP is a function, it is called for each entry with two args,
4808the buffer positions of beginning and end of entry. Then an entry
4809is accepted if this function returns non-nil.
4810If FIELD is an empty string perform search for REGEXP in whole entry.
4811With GLOBAL non-nil, search in `bibtex-files'. Otherwise the search
4812is limited to the current buffer.
4813If DISPLAY is non-nil, display search results in `bibtex-search-buffer'.
4814When called interactively, DISPLAY is t.
4815Also, GLOBAL is t if `bibtex-search-entry-globally' is non-nil.
4816A prefix arg negates the value of `bibtex-search-entry-globally'.
4817Return alist with elements (KEY FILE ENTRY),
4818where FILE is the BibTeX file of ENTRY."
4819 (interactive
4820 (list (completing-read
4821 "Field: "
4822 (delete-dups
4823 (apply 'append
4824 bibtex-user-optional-fields
4825 (mapcar (lambda (x)
4826 (append (mapcar 'car (nth 0 (nth 1 x)))
4827 (mapcar 'car (nth 1 (nth 1 x)))))
4828 bibtex-entry-field-alist))) nil t)
4829 (read-string "Regexp: ")
4830 (if bibtex-search-entry-globally
4831 (not current-prefix-arg)
4832 current-prefix-arg)
4833 t))
4834 (let ((funp (functionp regexp))
4835 entries text file)
4836 ;; If REGEXP is a function, the value of FIELD is ignored anyway.
4837 ;; Yet to ensure the code below does not fail, we make FIELD
4838 ;; a non-empty string.
4839 (if (and funp (string= "" field)) (setq field "unrestricted"))
4840 (dolist (buffer (if (and global bibtex-files)
4841 (bibtex-initialize t)
4842 (list (current-buffer))))
4843 (with-current-buffer buffer
4844 (setq file (if buffer-file-name
4845 (file-name-nondirectory buffer-file-name)
4846 (buffer-name buffer)))
4847 (save-excursion
4848 (goto-char (point-min))
4849 (if (string= "" field)
4850 ;; Unrestricted search.
4851 (while (re-search-forward regexp nil t)
4852 (let ((beg (bibtex-beginning-of-entry))
4853 (end (bibtex-end-of-entry))
4854 key)
4855 (if (and (<= beg (match-beginning 0))
4856 (<= (match-end 0) end)
4857 (save-excursion
4858 (goto-char beg)
4859 (and (looking-at bibtex-entry-head)
4860 (setq key (bibtex-key-in-head)))))
4861 (add-to-list 'entries
4862 (list key file
4863 (buffer-substring-no-properties
4864 beg end))))))
4865 ;; The following is slow. But it works reliably even in more
4866 ;; complicated cases with BibTeX string constants and crossrefed
4867 ;; entries. If you prefer speed over reliability, perform an
4868 ;; unrestricted search.
4869 (bibtex-map-entries
4870 (lambda (key beg end)
4871 (if (cond (funp (funcall regexp beg end))
4872 ((and (setq text (bibtex-text-in-field field t))
4873 (string-match regexp text))))
4874 (add-to-list 'entries
4875 (list key file
4876 (buffer-substring-no-properties
4877 beg end))))))))))
4878 (if display
4879 (if entries
4880 (bibtex-display-entries entries)
4881 (message "No BibTeX entries %smatching `%s'"
4882 (if (string= "" field) ""
4883 (format "with field `%s' " field))
4884 regexp)))
4885 entries))
4886
4887(defun bibtex-display-entries (entries &optional append)
4888 "Display BibTeX ENTRIES in `bibtex-search-buffer'.
4889ENTRIES is an alist with elements (KEY FILE ENTRY),
4890where FILE is the BibTeX file of ENTRY.
4891If APPEND is non-nil, append ENTRIES to those already displayed."
4892 (pop-to-buffer (get-buffer-create bibtex-search-buffer))
4893 ;; It would be nice if this buffer was editable, though editing
4894 ;; can be meaningful only for individual existing entries
4895 ;; (unlike reordering or creating new entries).
4896 ;; Fancy workaround: Editing commands in the virtual buffer could
4897 ;; jump to the real entry in the real buffer.
4898 (let (buffer-read-only)
4899 (if append (goto-char (point-max)) (erase-buffer))
4900 (dolist (entry (sort entries (lambda (x y) (string< (car x) (car y)))))
4901 (insert "% " (nth 1 entry) "\n" (nth 2 entry) "\n\n")))
4902 ;; `bibtex-sort-buffer' fails with the file names associated with
4903 ;; each entry. Prior to sorting we could make the file name
4904 ;; a BibTeX field of each entry (using `bibtex-make-field').
4905 ;; Or we could make it a text property that we unfold afterwards.
4906 ;; (bibtex-sort-buffer)
4907 (bibtex-mode)
4908 (set-buffer-modified-p nil)
4909 (setq buffer-read-only t)
4910 (goto-char (point-min)))
4911
4792 4912
4793;; Make BibTeX a Feature 4913;; Make BibTeX a Feature
4794 4914