Fix typos.
[bpt/emacs.git] / lisp / textmodes / reftex-ref.el
CommitLineData
3afbc435 1;;; reftex-ref.el --- code to create labels and references with RefTeX
f2e3589a 2
73b0cd50 3;; Copyright (C) 1997-2011 Free Software Foundation, Inc.
3ba2590f 4
6fbeb429 5;; Author: Carsten Dominik <dominik@science.uva.nl>
ce545621 6;; Maintainer: auctex-devel@gnu.org
5d2a58e0 7;; Version: 4.31
bd78fa1d 8;; Package: reftex
3ba2590f
RS
9
10;; This file is part of GNU Emacs.
11
1fecc8fe 12;; GNU Emacs is free software: you can redistribute it and/or modify
3ba2590f 13;; it under the terms of the GNU General Public License as published by
1fecc8fe
GM
14;; the Free Software Foundation, either version 3 of the License, or
15;; (at your option) any later version.
3ba2590f
RS
16
17;; GNU Emacs is distributed in the hope that it will be useful,
18;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20;; GNU General Public License for more details.
21
22;; You should have received a copy of the GNU General Public License
1fecc8fe 23;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
1a9461d0 24
3afbc435
PJ
25;;; Commentary:
26
27;;; Code:
28
7c4d13cc 29(eval-when-compile (require 'cl))
1a9461d0
CD
30(provide 'reftex-ref)
31(require 'reftex)
3a1e8128 32(require 'reftex-parse)
1a9461d0
CD
33;;;
34
35(defun reftex-label-location (&optional bound)
36 "Return the environment or macro which determines the label type at point.
37If optional BOUND is an integer, limit backward searches to that point."
38
39 (let* ((loc1 (reftex-what-macro reftex-label-mac-list bound))
40 (loc2 (reftex-what-environment reftex-label-env-list bound))
3666daf6 41 (loc3 (reftex-what-special-env 1 bound))
1a9461d0
CD
42 (p1 (or (cdr loc1) 0))
43 (p2 (or (cdr loc2) 0))
3666daf6
CD
44 (p3 (or (cdr loc3) 0))
45 (pmax (max p1 p2 p3)))
1a9461d0
CD
46
47 (setq reftex-location-start pmax)
48 (cond
49 ((= p1 pmax)
50 ;; A macro. Default context after macro name.
51 (setq reftex-default-context-position (+ p1 (length (car loc1))))
52 (or (car loc1) "section"))
53 ((= p2 pmax)
54 ;; An environment. Default context after \begin{name}.
55 (setq reftex-default-context-position (+ p2 8 (length (car loc2))))
56 (or (car loc2) "section"))
57 ((= p3 pmax)
58 ;; A special. Default context right there.
59 (setq reftex-default-context-position p3)
60 (setq loc3 (car loc3))
61 (cond ((null loc3) "section")
3666daf6
CD
62 ((symbolp loc3) (symbol-name loc3))
63 ((stringp loc3) loc3)
64 (t "section")))
1a9461d0
CD
65 (t ;; This should not happen, I think?
66 "section"))))
67
68(defun reftex-label-info-update (cell)
69 ;; Update information about just one label in a different file.
70 ;; CELL contains the old info list
71 (let* ((label (nth 0 cell))
72 (typekey (nth 1 cell))
73 ;; (text (nth 2 cell))
74 (file (nth 3 cell))
75 (comment (nth 4 cell))
76 (note (nth 5 cell))
77 (buf (reftex-get-file-buffer-force
78 file (not (eq t reftex-keep-temporary-buffers)))))
79 (if (not buf)
80 (list label typekey "" file comment "LOST LABEL. RESCAN TO FIX.")
9a529312 81 (with-current-buffer buf
1a9461d0
CD
82 (save-restriction
83 (widen)
84 (goto-char 1)
85
86 (if (or (re-search-forward
3666daf6
CD
87 (format reftex-find-label-regexp-format
88 (regexp-quote label)) nil t)
89 (re-search-forward
90 (format reftex-find-label-regexp-format2
91 (regexp-quote label)) nil t))
1a9461d0
CD
92
93 (progn
94 (backward-char 1)
95 (append (reftex-label-info label file) (list note)))
96 (list label typekey "" file "LOST LABEL. RESCAN TO FIX.")))))))
97
98(defun reftex-label-info (label &optional file bound derive env-or-mac)
99 ;; Return info list on LABEL at point.
f3c18bd0
CD
100 (let* ((prefix (if (string-match "^[a-zA-Z0-9]+:" label)
101 (match-string 0 label)))
102 (typekey (cdr (assoc prefix reftex-prefix-to-typekey-alist)))
1a9461d0 103 (file (or file (buffer-file-name)))
f3c18bd0 104 (trust reftex-trust-label-prefix)
3666daf6 105 (in-comment (reftex-in-comment)))
f3c18bd0
CD
106 (if (and typekey
107 (cond ((eq trust t) t)
108 ((null trust) nil)
109 ((stringp trust) (string-match trust typekey))
110 ((listp trust) (member typekey trust))
111 (t nil)))
112 (list label typekey
113 (reftex-nicify-text (reftex-context-substring))
114 file in-comment)
115 (let* ((env-or-mac (or env-or-mac (reftex-label-location bound)))
116 (typekey (nth 1 (assoc env-or-mac reftex-env-or-mac-alist)))
117 (parse (nth 2 (assoc env-or-mac reftex-env-or-mac-alist)))
118 (text (reftex-short-context env-or-mac parse reftex-location-start
119 derive)))
120 (list label typekey text file in-comment)))))
1a9461d0
CD
121
122;;; Creating labels ---------------------------------------------------------
123
124(defun reftex-label (&optional environment no-insert)
125 "Insert a unique label. Return the label.
126If ENVIRONMENT is given, don't bother to find out yourself.
127If NO-INSERT is non-nil, do not insert label into buffer.
128With prefix arg, force to rescan document first.
129When you are prompted to enter or confirm a label, and you reply with
130just the prefix or an empty string, no label at all will be inserted.
131A new label is also recorded into the label list.
132This function is controlled by the settings of reftex-insert-label-flags."
133
134 (interactive)
135
136 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4).
137 (reftex-access-scan-info current-prefix-arg)
138
139 ;; Find out what kind of environment this is and abort if necessary.
140 (if (or (not environment)
141 (not (assoc environment reftex-env-or-mac-alist)))
142 (setq environment (reftex-label-location)))
143 (unless environment
144 (error "Can't figure out what kind of label should be inserted"))
145
146 ;; Ok, go ahead.
147 (catch 'exit
148 (let* ((entry (assoc environment reftex-env-or-mac-alist))
3666daf6
CD
149 (typekey (nth 1 entry))
150 (format (nth 3 entry))
151 (macro-cell (reftex-what-macro 1))
152 (entry1 (assoc (car macro-cell) reftex-env-or-mac-alist))
153 label naked prefix valid default force-prompt rescan-is-useful)
1a9461d0 154 (when (and (or (nth 5 entry) (nth 5 entry1))
3666daf6
CD
155 (memq (preceding-char) '(?\[ ?\{)))
156 ;; This is an argument of a label macro. Insert naked label.
157 (setq naked t format "%s"))
1a9461d0
CD
158
159 (setq prefix (or (cdr (assoc typekey reftex-typekey-to-prefix-alist))
3666daf6 160 (concat typekey "-")))
1a9461d0
CD
161 ;; Replace any escapes in the prefix
162 (setq prefix (reftex-replace-prefix-escapes prefix))
163
164 ;; Make a default label.
165 (cond
166
167 ((reftex-typekey-check typekey (nth 0 reftex-insert-label-flags))
3666daf6
CD
168 ;; Derive a label from context.
169 (setq reftex-active-toc (reftex-last-assoc-before-elt
170 'toc (car (reftex-where-am-I))
171 (symbol-value reftex-docstruct-symbol)))
172 (setq default (reftex-no-props
173 (nth 2 (reftex-label-info " " nil nil t))))
174 ;; Catch the cases where the is actually no context available.
175 (if (or (string-match "NO MATCH FOR CONTEXT REGEXP" default)
5181ff9f 176 (string-match "INVALID VALUE OF PARSE" default)
3666daf6
CD
177 (string-match "SECTION HEADING NOT FOUND" default)
178 (string-match "HOOK ERROR" default)
179 (string-match "^[ \t]*$" default))
180 (setq default prefix
181 force-prompt t) ; need to prompt
c8f3bf36
GM
182 (setq default
183 (concat prefix
3666daf6
CD
184 (funcall reftex-string-to-label-function default)))
185
186 ;; Make it unique.
187 (setq default (reftex-uniquify-label default nil "-"))))
1a9461d0
CD
188
189 ((reftex-typekey-check typekey (nth 1 reftex-insert-label-flags))
3666daf6
CD
190 ;; Minimal default: the user will be prompted.
191 (setq default prefix))
1a9461d0
CD
192
193 (t
3666daf6
CD
194 ;; Make an automatic label.
195 (setq default (reftex-uniquify-label prefix t))))
1a9461d0
CD
196
197 ;; Should we ask the user?
198 (if (or (reftex-typekey-check typekey
3666daf6
CD
199 (nth 1 reftex-insert-label-flags)) ; prompt
200 force-prompt)
201
202 (while (not valid)
3a1e8128 203 ;; iterate until we get a valid label
3666daf6
CD
204
205 (setq label (read-string
206 (if naked "Naked Label: " "Label: ")
207 default))
208
c7015153 209 ;; Let's make sure that this is a valid label
3666daf6
CD
210 (cond
211
212 ((string-match (concat "\\`\\(" (regexp-quote prefix)
213 "\\)?[ \t]*\\'")
214 label)
215 ;; No label at all, please
216 (message "No label inserted.")
217 (throw 'exit nil))
218
219 ;; Test if label contains strange characters
220 ((string-match reftex-label-illegal-re label)
5181ff9f 221 (message "Label \"%s\" contains invalid characters" label)
3666daf6
CD
222 (ding)
223 (sit-for 2))
224
225 ;; Look it up in the label list
226 ((setq entry (assoc label
227 (symbol-value reftex-docstruct-symbol)))
228 (ding)
c8f3bf36 229 (if (y-or-n-p
3666daf6
CD
230 (format "Label '%s' exists. Use anyway? " label))
231 (setq valid t)))
232
233 ;; Label is ok
234 (t
235 (setq valid t))))
236 (setq label default))
1a9461d0
CD
237
238 ;; Insert the label into the label list
c799747b 239 (let* ((here-I-am-info
3666daf6 240 (save-excursion
c799747b 241 (if (and (or naked no-insert)
3666daf6
CD
242 (integerp (cdr macro-cell)))
243 (goto-char (cdr macro-cell)))
244 (reftex-where-am-I)))
245 (here-I-am (car here-I-am-info))
246 (note (if (cdr here-I-am-info)
247 ""
248 "POSITION UNCERTAIN. RESCAN TO FIX."))
249 (file (buffer-file-name))
250 (text nil)
251 (tail (memq here-I-am (symbol-value reftex-docstruct-symbol))))
252
253 (or (cdr here-I-am-info) (setq rescan-is-useful t))
254
255 (when tail
256 (push (list label typekey text file nil note) (cdr tail))
257 (put reftex-docstruct-symbol 'modified t)))
1a9461d0
CD
258
259 ;; Insert the label into the buffer
260 (unless no-insert
3666daf6
CD
261 (insert
262 (if reftex-format-label-function
263 (funcall reftex-format-label-function label format)
264 (format format label)))
265 (if (and reftex-plug-into-AUCTeX
266 (fboundp 'LaTeX-add-labels))
267 ;; Tell AUCTeX about this
268 (LaTeX-add-labels label)))
1a9461d0
CD
269
270 ;; Delete the corresponding selection buffers to force update on next use.
271 (when reftex-auto-update-selection-buffers
3666daf6
CD
272 (reftex-erase-buffer (reftex-make-selection-buffer-name typekey))
273 (reftex-erase-buffer (reftex-make-selection-buffer-name " ")))
1a9461d0
CD
274
275 (when (and rescan-is-useful reftex-allow-automatic-rescan)
3666daf6 276 (reftex-parse-one))
1a9461d0
CD
277
278 ;; return value of the function is the label
279 label)))
280
281(defun reftex-string-to-label (string)
282 "Convert a string (a sentence) to a label.
283Uses `reftex-derive-label-parameters' and `reftex-label-illegal-re'. It
284also applies `reftex-translate-to-ascii-function' to the string."
285 (when (and reftex-translate-to-ascii-function
3666daf6 286 (fboundp reftex-translate-to-ascii-function))
1a9461d0
CD
287 (setq string (funcall reftex-translate-to-ascii-function string)))
288 (apply 'reftex-convert-string string
3666daf6
CD
289 "[-~ \t\n\r,;]+" reftex-label-illegal-re nil nil
290 reftex-derive-label-parameters))
1a9461d0
CD
291
292(defun reftex-latin1-to-ascii (string)
293 ;; Translate the upper 128 chars in the Latin-1 charset to ASCII equivalents
294 (let ((tab "@@@@@@@@@@@@@@@@@@'@@@@@@@@@@@@@ icLxY|S\"ca<--R-o|23'uq..1o>423?AAAAAAACEEEEIIIIDNOOOOOXOUUUUYP3aaaaaaaceeeeiiiidnooooo:ouuuuypy")
3666daf6 295 (emacsp (not (featurep 'xemacs))))
c8f3bf36 296 (mapconcat
1a9461d0
CD
297 (lambda (c)
298 (cond ((and (> c 127) (< c 256)) ; 8 bit Latin-1
3666daf6
CD
299 (char-to-string (aref tab (- c 128))))
300 ((and emacsp ; Not for XEmacs
301 (> c 2175) (< c 2304)) ; Mule Latin-1
302 (char-to-string (aref tab (- c 2176))))
303 (t (char-to-string c))))
1a9461d0
CD
304 string "")))
305
306(defun reftex-replace-prefix-escapes (prefix)
307 ;; Replace %escapes in a label prefix
308 (save-match-data
309 (let (letter (num 0) replace)
310 (while (string-match "\\%\\([a-zA-Z]\\)" prefix num)
311 (setq letter (match-string 1 prefix))
312 (setq replace
f3c18bd0
CD
313 (save-match-data
314 (cond
315 ((equal letter "f")
316 (file-name-sans-extension
317 (file-name-nondirectory (buffer-file-name))))
318 ((equal letter "F")
319 (let ((masterdir (file-name-directory (reftex-TeX-master-file)))
320 (file (file-name-sans-extension (buffer-file-name))))
321 (if (string-match (concat "\\`" (regexp-quote masterdir))
322 file)
323 (substring file (length masterdir))
324 file)))
325 ((equal letter "m")
326 (file-name-sans-extension
327 (file-name-nondirectory (reftex-TeX-master-file))))
328 ((equal letter "M")
329 (file-name-nondirectory
330 (substring (file-name-directory (reftex-TeX-master-file))
331 0 -1)))
332 ((equal letter "u")
333 (or (user-login-name) ""))
334 ((equal letter "S")
335 (let* (macro level-exp level)
336 (save-excursion
337 (save-match-data
338 (when (re-search-backward reftex-section-regexp nil t)
339 (setq macro (reftex-match-string 2)
340 level-exp (cdr (assoc macro reftex-section-levels-all))
341 level (if (symbolp level-exp)
342 (abs (save-match-data
343 (funcall level-exp)))
344 (abs level-exp))))
345 (cdr (or (assoc macro reftex-section-prefixes)
346 (assoc level reftex-section-prefixes)
347 (assq t reftex-section-prefixes)
348 (list t "sec:")))))))
349 (t ""))))
1a9461d0
CD
350 (setq num (1- (+ (match-beginning 1) (length replace)))
351 prefix (replace-match replace nil nil prefix)))
352 prefix)))
353
354(defun reftex-uniquify-label (label &optional force separator)
355 ;; Make label unique by appending a number.
356 ;; Optional FORCE means, force appending a number, even if label is unique.
357 ;; Optional SEPARATOR is a string to stick between label and number.
358
359 ;; Ensure access to scanning info
360 (reftex-access-scan-info)
361
362 (cond
363 ((and (not force)
364 (not (assoc label (symbol-value reftex-docstruct-symbol))))
365 label)
366 (t
367 (let* ((label-numbers (assq 'label-numbers
368 (symbol-value reftex-docstruct-symbol)))
369 (label-numbers-alist (cdr label-numbers))
370 (cell (or (assoc label label-numbers-alist)
371 (car (setcdr label-numbers
372 (cons (cons label 0)
373 label-numbers-alist)))))
374 (num (1+ (cdr cell)))
375 (sep (or separator "")))
376 (while (assoc (concat label sep (int-to-string num))
377 (symbol-value reftex-docstruct-symbol))
378 (incf num))
379 (setcdr cell num)
380 (concat label sep (int-to-string num))))))
381
382;;; Referencing labels ------------------------------------------------------
383
384;; Help string for the reference label menu
385(defconst reftex-select-label-prompt
386 "Select: [n]ext [p]revious [r]escan [ ]context e[x]tern [q]uit RET [?]HELP+more")
387
388(defconst reftex-select-label-help
389 " n / p Go to next/previous label (Cursor motion works as well)
390 C-c C-n/p Go to next/previous section heading.
391 b / l Jump back to previous selection / Reuse last referenced label.
70d797cd 392 z Jump to a specific section, e.g. '3 z' jumps to section 3.
1a9461d0
CD
393 g / s Update menu / Switch label type.
394 r / C-u r Reparse document / Reparse entire document.
395 x Switch to label menu of external document (with LaTeX package `xr').
396 F t c Toggle: [F]ile borders, [t]able of contents, [c]ontext
397 # % Toggle: [#] label counters, [%] labels in comments
398 SPC / f Show full context in other window / Toggle follow mode.
399 . Show insertion point in other window.
400 v / V Toggle \\ref <-> \\vref / Rotate \\ref <=> \\fref <=> \\Fref
401 TAB Enter a label with completion.
402 m , - + Mark entry. `,-+' also assign a separator.
403 a / A Put all marked entries into one/many \\ref commands.
404 q / RET Quit without referencing / Accept current label (also on mouse-2).")
405
406(defun reftex-reference (&optional type no-insert cut)
407 "Make a LaTeX reference. Look only for labels of a certain TYPE.
408With prefix arg, force to rescan buffer for labels. This should only be
409necessary if you have recently entered labels yourself without using
410reftex-label. Rescanning of the buffer can also be requested from the
411label selection menu.
412The function returns the selected label or nil.
413If NO-INSERT is non-nil, do not insert \\ref command, just return label.
414When called with 2 C-u prefix args, disable magic word recognition."
415
416 (interactive)
417
418 ;; check for active recursive edits
419 (reftex-check-recursive-edit)
420
3666daf6 421 ;; Ensure access to scanning info and rescan buffer if prefix are is '(4)
1a9461d0
CD
422 (reftex-access-scan-info current-prefix-arg)
423
424 (unless type
425 ;; guess type from context
426 (if (and reftex-guess-label-type
427 (setq type (reftex-guess-label-type)))
3666daf6
CD
428 (setq cut (cdr type)
429 type (car type))
1a9461d0
CD
430 (setq type (reftex-query-label-type))))
431
c8f3bf36 432 (let* ((reftex-refstyle
3666daf6
CD
433 (cond ((reftex-typekey-check type reftex-vref-is-default) "\\vref")
434 ((reftex-typekey-check type reftex-fref-is-default) "\\fref")
435 (t "\\ref")))
436 (reftex-format-ref-function reftex-format-ref-function)
437 (form "\\ref{%s}")
438 label labels sep sep1)
1a9461d0
CD
439
440 ;; Have the user select a label
441 (set-marker reftex-select-return-marker (point))
442 (setq labels (save-excursion
3666daf6 443 (reftex-offer-label-menu type)))
1a9461d0
CD
444 (reftex-ensure-compiled-variables)
445 (set-marker reftex-select-return-marker nil)
3b919c9f 446 ;; If the first entry is the symbol 'concat, concat all labels.
1a9461d0
CD
447 ;; We keep the cdr of the first label for typekey etc information.
448 (if (eq (car labels) 'concat)
3666daf6
CD
449 (setq labels (list (list (mapconcat 'car (cdr labels) ",")
450 (cdr (nth 1 labels))))))
1a9461d0 451 (setq type (nth 1 (car labels))
3666daf6
CD
452 form (or (cdr (assoc type reftex-typekey-to-format-alist))
453 form))
c8f3bf36 454
1a9461d0
CD
455 (cond
456 (no-insert
457 ;; Just return the first label
458 (car (car labels)))
459 ((null labels)
460 (message "Quit")
461 nil)
462 (t
463 (while labels
3666daf6
CD
464 (setq label (car (car labels))
465 sep (nth 2 (car labels))
466 sep1 (cdr (assoc sep reftex-multiref-punctuation))
467 labels (cdr labels))
c8f3bf36 468 (when cut
3666daf6
CD
469 (backward-delete-char cut)
470 (setq cut nil))
471
472 ;; remove ~ if we do already have a space
473 (when (and (= ?~ (string-to-char form))
f3c18bd0 474 (member (preceding-char) '(?\ ?\t ?\n ?~)))
3666daf6
CD
475 (setq form (substring form 1)))
476 ;; do we have a special format?
477 (setq reftex-format-ref-function
478 (cond
c8f3bf36
GM
479 ((string= reftex-refstyle "\\vref") 'reftex-format-vref)
480 ((string= reftex-refstyle "\\fref") 'reftex-format-fref)
481 ((string= reftex-refstyle "\\Fref") 'reftex-format-Fref)
3666daf6
CD
482 (t reftex-format-ref-function)))
483 ;; ok, insert the reference
484 (if sep1 (insert sep1))
485 (insert
486 (if reftex-format-ref-function
487 (funcall reftex-format-ref-function label form)
488 (format form label label)))
489 ;; take out the initial ~ for good
490 (and (= ?~ (string-to-char form))
491 (setq form (substring form 1))))
1a9461d0
CD
492 (message "")
493 label))))
494
495(defun reftex-guess-label-type ()
496 ;; Examine context to guess what a \ref might want to reference.
497 (let ((words reftex-words-to-typekey-alist)
3666daf6
CD
498 (case-fold-search t)
499 (bound (max (point-min) (- (point) 35)))
500 matched cell)
1a9461d0
CD
501 (save-excursion
502 (while (and (setq cell (pop words))
c8f3bf36 503 (not (setq matched
3666daf6 504 (re-search-backward (car cell) bound t))))))
1a9461d0 505 (if matched
3666daf6 506 (cons (cdr cell) (- (match-end 0) (match-end 1)))
1a9461d0
CD
507 nil)))
508
509(defvar reftex-select-label-map)
510(defun reftex-offer-label-menu (typekey)
511 ;; Offer a menu with the appropriate labels.
512 (let* ((buf (current-buffer))
3666daf6
CD
513 (xr-data (assq 'xr (symbol-value reftex-docstruct-symbol)))
514 (xr-alist (cons (cons "" (buffer-file-name)) (nth 1 xr-data)))
515 (xr-index 0)
1a9461d0 516 (here-I-am (car (reftex-where-am-I)))
3666daf6 517 (here-I-am1 here-I-am)
1a9461d0
CD
518 (toc (reftex-typekey-check typekey reftex-label-menu-flags 0))
519 (files (reftex-typekey-check typekey reftex-label-menu-flags 7))
520 (context (not (reftex-typekey-check
521 typekey reftex-label-menu-flags 3)))
522 (counter (reftex-typekey-check
523 typekey reftex-label-menu-flags 2))
524 (follow (reftex-typekey-check
525 typekey reftex-label-menu-flags 4))
526 (commented (nth 5 reftex-label-menu-flags))
3666daf6
CD
527 (prefix "")
528 selection-buffers
1a9461d0
CD
529 offset rtn key data last-data entries)
530
531 (unwind-protect
532 (catch 'exit
533 (while t
534 (save-window-excursion
3666daf6
CD
535 (delete-other-windows)
536 (setq reftex-call-back-to-this-buffer buf
537 reftex-latex-syntax-table (syntax-table))
d63eb0e7
GM
538 (if reftex-use-multiple-selection-buffers
539 (switch-to-buffer-other-window
9a529312 540 (with-current-buffer buf
d63eb0e7
GM
541 (reftex-make-selection-buffer-name typekey)))
542 (switch-to-buffer-other-window "*RefTeX Select*")
543 (reftex-erase-buffer))
3666daf6
CD
544 (unless (eq major-mode 'reftex-select-label-mode)
545 (reftex-select-label-mode))
546 (add-to-list 'selection-buffers (current-buffer))
1a9461d0 547 (setq truncate-lines t)
3666daf6
CD
548 (setq mode-line-format
549 (list "---- " 'mode-line-buffer-identification
550 " " 'global-mode-string " (" mode-name ")"
c8f3bf36 551 " S<" 'reftex-refstyle ">"
3666daf6
CD
552 " -%-"))
553 (cond
554 ((= 0 (buffer-size))
555 (let ((buffer-read-only nil))
556 (message "Creating Selection Buffer...")
557 (setq offset (reftex-insert-docstruct
558 buf
559 toc
560 typekey
561 nil ; index
562 files
563 context
564 counter
565 commented
c8f3bf36 566 (or here-I-am offset)
3666daf6 567 prefix
c8f3bf36 568 nil ; no a toc buffer
3666daf6
CD
569 ))))
570 (here-I-am
571 (setq offset (reftex-get-offset buf here-I-am typekey)))
572 (t (setq offset t)))
573 (setq buffer-read-only t)
574 (setq offset (or offset t))
1a9461d0
CD
575
576 (setq here-I-am nil) ; turn off determination of offset
577 (setq rtn
578 (reftex-select-item
579 reftex-select-label-prompt
580 reftex-select-label-help
3666daf6 581 reftex-select-label-map
1a9461d0
CD
582 offset
583 'reftex-show-label-location follow))
584 (setq key (car rtn)
585 data (nth 1 rtn)
586 last-data (nth 2 rtn)
3666daf6 587 offset t)
1a9461d0
CD
588 (unless key (throw 'exit nil))
589 (cond
3666daf6
CD
590 ((eq key ?g)
591 ;; update buffer
592 (reftex-erase-buffer))
1a9461d0
CD
593 ((or (eq key ?r)
594 (eq key ?R))
595 ;; rescan buffer
3666daf6
CD
596 (and current-prefix-arg (setq key ?R))
597 (reftex-erase-buffer)
1a9461d0
CD
598 (reftex-reparse-document buf last-data key))
599 ((eq key ?c)
600 ;; toggle context mode
3666daf6 601 (reftex-erase-buffer)
1a9461d0
CD
602 (setq context (not context)))
603 ((eq key ?s)
604 ;; switch type
3666daf6 605 (setq here-I-am here-I-am1)
1a9461d0
CD
606 (setq typekey (reftex-query-label-type)))
607 ((eq key ?t)
7c4d13cc 608 ;; toggle table of contents display, or change depth
3666daf6
CD
609 (reftex-erase-buffer)
610 (if current-prefix-arg
611 (setq reftex-toc-max-level (prefix-numeric-value
612 current-prefix-arg))
613 (setq toc (not toc))))
1a9461d0
CD
614 ((eq key ?F)
615 ;; toggle display of included file borders
3666daf6 616 (reftex-erase-buffer)
1a9461d0
CD
617 (setq files (not files)))
618 ((eq key ?#)
619 ;; toggle counter display
3666daf6 620 (reftex-erase-buffer)
1a9461d0
CD
621 (setq counter (not counter)))
622 ((eq key ?%)
623 ;; toggle display of commented labels
3666daf6 624 (reftex-erase-buffer)
1a9461d0
CD
625 (setq commented (not commented)))
626 ((eq key ?l)
627 ;; reuse the last referenced label again
628 (setq entries reftex-last-used-reference)
629 (throw 'exit t))
3666daf6
CD
630 ((eq key ?x)
631 ;; select an external document
632 (setq xr-index (reftex-select-external-document
633 xr-alist xr-index))
634 (setq buf (or (reftex-get-file-buffer-force
635 (cdr (nth xr-index xr-alist)))
636 (error "Cannot switch document"))
637 prefix (or (car (nth xr-index xr-alist)) ""))
1a9461d0 638 (set-buffer buf)
3666daf6
CD
639 (reftex-access-scan-info))
640 ((stringp key)
641 (setq entries
642 (list
643 (list
644 (or (assoc key (symbol-value reftex-docstruct-symbol))
645 (list key typekey)))))
1a9461d0 646 (throw 'exit t))
3666daf6
CD
647 ((memq key '(?a ?A return))
648 (cond
649 (reftex-select-marked
650 (setq entries (nreverse reftex-select-marked)))
651 (data
652 (setq entries (list (list data))))
653 (t (setq entries nil)))
654 (when entries
655 (if (equal key ?a) (push 'concat entries))
656 (setq reftex-last-used-reference entries))
657 (set-buffer buf)
658 (throw 'exit t))
659 (t (error "This should not happen (reftex-offer-label-menu)"))))))
1a9461d0 660 (save-excursion
3666daf6
CD
661 (while reftex-buffers-with-changed-invisibility
662 (set-buffer (car (car reftex-buffers-with-changed-invisibility)))
fe2ca5ec 663 (setq buffer-invisibility-spec
3666daf6 664 (cdr (pop reftex-buffers-with-changed-invisibility)))))
fe2ca5ec
GM
665 (mapc (lambda (buf) (and (buffer-live-p buf) (bury-buffer buf)))
666 selection-buffers)
1a9461d0
CD
667 (reftex-kill-temporary-buffers))
668 ;; Add the prefixes, put together the relevant information in the form
7ac7387b 669 ;; (LABEL TYPEKEY SEPARATOR) and return a list of those.
1a9461d0 670 (mapcar (lambda (x)
3666daf6
CD
671 (if (listp x)
672 (list (concat prefix (car (car x)))
673 (nth 1 (car x))
674 (nth 2 x))
675 x))
676 entries)))
1a9461d0
CD
677
678(defun reftex-reparse-document (&optional buffer data key)
679 ;; Rescan the document.
680 (save-window-excursion
681 (save-excursion
682 (if buffer
683 (if (not (bufferp buffer))
684 (error "No such buffer %s" (buffer-name buffer))
685 (set-buffer buffer)))
686 (let ((arg (if (eq key ?R) '(16) '(4)))
687 (file (nth 3 data)))
688 (reftex-access-scan-info arg file)))))
689
690(defun reftex-query-label-type ()
691 ;; Ask for label type
c8f3bf36 692 (let ((key (reftex-select-with-char
3666daf6 693 reftex-type-query-prompt reftex-type-query-help 3)))
1a9461d0
CD
694 (unless (member (char-to-string key) reftex-typekey-list)
695 (error "No such label type: %s" (char-to-string key)))
696 (char-to-string key)))
697
c8f3bf36 698(defun reftex-show-label-location (data forward no-revisit
3666daf6 699 &optional stay error)
1a9461d0
CD
700 ;; View the definition site of a label in another window.
701 ;; DATA is an entry from the docstruct list.
702 ;; FORWARD indicates if the label is likely forward from current point.
703 ;; NO-REVISIT means do not load a file to show this label.
704 ;; STAY means leave the new window selected.
705 ;; ERROR means throw an error exception when the label cannot be found.
706 ;; If ERROR is nil, the return value of this function indicates success.
707 (let* ((this-window (selected-window))
3666daf6 708 (errorf (if error 'error 'message))
1a9461d0
CD
709 label file buffer re found)
710
711 (catch 'exit
712 (setq label (nth 0 data)
3666daf6 713 file (nth 3 data))
1a9461d0
CD
714
715 (unless file
3666daf6
CD
716 (funcall errorf "Unknown label - reparse might help")
717 (throw 'exit nil))
1a9461d0
CD
718
719 ;; Goto the file in another window
c8f3bf36 720 (setq buffer
3666daf6
CD
721 (if no-revisit
722 (reftex-get-buffer-visiting file)
723 (reftex-get-file-buffer-force
724 file (not reftex-keep-temporary-buffers))))
1a9461d0
CD
725 (if buffer
726 ;; good - the file is available
727 (switch-to-buffer-other-window buffer)
728 ;; we have got a problem here. The file does not exist.
729 ;; Let' get out of here..
3666daf6
CD
730 (funcall errorf "Label %s not found" label)
731 (throw 'exit nil))
1a9461d0
CD
732
733 ;; search for that label
734 (setq re (format reftex-find-label-regexp-format (regexp-quote label)))
735 (setq found
3666daf6
CD
736 (if forward
737 (re-search-forward re nil t)
738 (re-search-backward re nil t)))
1a9461d0
CD
739 (unless found
740 (goto-char (point-min))
3666daf6
CD
741 (unless (setq found (re-search-forward re nil t))
742 ;; Ooops. Must be in a macro with distributed args.
743 (setq found
744 (re-search-forward
745 (format reftex-find-label-regexp-format2
746 (regexp-quote label)) nil t))))
1a9461d0 747 (if (match-end 3)
3666daf6
CD
748 (progn
749 (reftex-highlight 0 (match-beginning 3) (match-end 3))
750 (reftex-show-entry (match-beginning 3) (match-end 3))
751 (recenter '(4))
752 (unless stay (select-window this-window)))
753 (select-window this-window)
754 (funcall errorf "Label %s not found" label))
1a9461d0
CD
755 found)))
756
757(defvar font-lock-mode)
758(defun reftex-show-entry (beg-hlt end-hlt)
759 ;; Show entry if point is hidden
760 (let* ((n (/ (reftex-window-height) 2))
761 (beg (save-excursion
762 (re-search-backward "[\n\r]" nil 1 n) (point)))
763 (end (save-excursion
764 (re-search-forward "[\n\r]" nil 1 n) (point))))
765 (cond
766 ((and (boundp 'buffer-invisibility-spec) buffer-invisibility-spec
3666daf6 767 (get-char-property (1+ beg-hlt) 'invisible))
1a9461d0
CD
768 ;; Invisible with text properties. That is easy to change.
769 (push (cons (current-buffer) buffer-invisibility-spec)
3666daf6 770 reftex-buffers-with-changed-invisibility)
1a9461d0
CD
771 (setq buffer-invisibility-spec nil))
772 ((string-match "\r" (buffer-substring beg end))
773 ;; Invisible with selective display. We need to copy it.
774 (let ((string (buffer-substring-no-properties beg end)))
3666daf6
CD
775 (switch-to-buffer "*RefTeX Context Copy*")
776 (setq buffer-read-only nil)
777 (erase-buffer)
778 (insert string)
779 (subst-char-in-region (point-min) (point-max) ?\r ?\n t)
780 (goto-char (- beg-hlt beg))
781 (reftex-highlight 0 (1+ (- beg-hlt beg)) (1+ (- end-hlt beg)))
782 (if (reftex-refontify)
783 (when (or (not (eq major-mode 'latex-mode))
784 (not font-lock-mode))
785 (latex-mode)
c8f3bf36 786 (run-hook-with-args
3666daf6
CD
787 'reftex-pre-refontification-functions
788 reftex-call-back-to-this-buffer 'reftex-hidden)
789 (turn-on-font-lock))
790 (when (or (not (eq major-mode 'fundamental-mode))
791 font-lock-mode)
792 (fundamental-mode)))
793 (run-hooks 'reftex-display-copied-context-hook)
794 (setq buffer-read-only t))))))
1a9461d0
CD
795
796(defun reftex-varioref-vref ()
70d797cd 797 "Insert a reference using the `\\vref' macro from the varioref package."
1a9461d0
CD
798 (interactive)
799 (let ((reftex-format-ref-function 'reftex-format-vref))
800 (reftex-reference)))
801(defun reftex-fancyref-fref ()
70d797cd 802 "Insert a reference using the `\\fref' macro from the fancyref package."
1a9461d0
CD
803 (interactive)
804 (let ((reftex-format-ref-function 'reftex-format-fref)
3666daf6
CD
805 ;;(reftex-guess-label-type nil) ;FIXME do we want this????
806 )
1a9461d0
CD
807 (reftex-reference)))
808(defun reftex-fancyref-Fref ()
70d797cd 809 "Insert a reference using the `\\Fref' macro from the fancyref package."
1a9461d0
CD
810 (interactive)
811 (let ((reftex-format-ref-function 'reftex-format-Fref)
3666daf6
CD
812 ;;(reftex-guess-label-type nil) ;FIXME do we want this????
813 )
1a9461d0
CD
814 (reftex-reference)))
815
816(defun reftex-format-vref (label fmt)
817 (while (string-match "\\\\ref{" fmt)
818 (setq fmt (replace-match "\\vref{" t t fmt)))
819 (format fmt label label))
820(defun reftex-format-Fref (label def-fmt)
821 (format "\\Fref{%s}" label))
822(defun reftex-format-fref (label def-fmt)
823 (format "\\fref{%s}" label))
824
3b919c9f
CD
825(defun reftex-goto-label (&optional other-window)
826 "Prompt for a label (with completion) and jump to the location of this label.
827Optional prefix argument OTHER-WINDOW goes to the label in another window."
828 (interactive "P")
829 (reftex-access-scan-info)
830 (let* ((wcfg (current-window-configuration))
3666daf6 831 (docstruct (symbol-value reftex-docstruct-symbol))
c799747b
TH
832 ;; If point is inside a \ref{} or \pageref{}, use that as
833 ;; default value.
834 (default (when (looking-back "\\\\\\(?:page\\)?ref{[-a-zA-Z0-9_*.:]*")
835 (reftex-this-word "-a-zA-Z0-9_*.:")))
836 (label (completing-read (if default
837 (format "Label (default %s): " default)
838 "Label: ")
839 docstruct
840 (lambda (x) (stringp (car x))) t nil nil
841 default))
3666daf6
CD
842 (selection (assoc label docstruct))
843 (where (progn
844 (reftex-show-label-location selection t nil 'stay)
845 (point-marker))))
3b919c9f
CD
846 (unless other-window
847 (set-window-configuration wcfg)
848 (switch-to-buffer (marker-buffer where))
c8f3bf36 849 (goto-char where))
3b919c9f
CD
850 (reftex-unhighlight 0)))
851
852
1a9461d0 853;;; reftex-ref.el ends here