aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJuanma Barranquero2003-04-04 20:02:58 +0000
committerJuanma Barranquero2003-04-04 20:02:58 +0000
commit79e01623a7dd0b10a6f4fae41b1916cd9306046d (patch)
tree592f23133ba7d546bafa36278096630ca6d0096c
parenta9b4949e2dff2a6c4ae4f798a33c421deaccb0de (diff)
downloademacs-79e01623a7dd0b10a6f4fae41b1916cd9306046d.tar.gz
emacs-79e01623a7dd0b10a6f4fae41b1916cd9306046d.zip
(find-file-of-tag-noselect, find-file-of-tag): New helper functions.
(snarf-tag-function): Doc string is changed. Explained about new optional argument, `use-explicit'. (etags-snarf-tag): Added one optional argument `use-explicit'. (file-of-tag-function): Doc string is changed. Explained about new optional argument, `relative'. (file-of-tag): Doc string is changed. Explained about new optional argument, `relative'. Pass `relative' to `file-of-tag-function'. (etags-file-of-tag): Added new argument `relative`. (list-tags): Set `buffer-read-only' to t after making the major mode apropos-mode. (etags-list-tags): Used `make-text-button' instead of `add-text-properties'. Used `snarf-tag-function', `goto-tag-location-function' and `find-file-of-tag' instead of `find-tag-other-window' (it's too simple). (find-tag-in-order): Used `find-file-of-tag-noselect' instead of `find-file'. (etags-tags-apropos): Used `find-file-of-tag-noselect' instead of `find-file'. Do not use `etags-goto-tag-location` directly; use `goto-tag-location-function' instead. Print relative file paths instead of complete ones in *Tags List* buffer, so lines in the buffer become shorter. (etags-tags-apropos-additional): Use `make-text-button' instead of `add-text-properties'.
-rw-r--r--lisp/ChangeLog28
-rw-r--r--lisp/progmodes/etags.el233
2 files changed, 166 insertions, 95 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index f5928201fec..40621edea1c 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,31 @@
12003-04-04 Masatake YAMATO <jet@gyve.org>
2
3 * progmodes/etags.el (find-file-of-tag-noselect, find-file-of-tag):
4 New helper functions.
5 (snarf-tag-function): Doc string is changed. Explained about new
6 optional argument, `use-explicit'.
7 (etags-snarf-tag): Added one optional argument `use-explicit'.
8 (file-of-tag-function): Doc string is changed. Explained about new
9 optional argument, `relative'.
10 (file-of-tag): Doc string is changed. Explained about new optional
11 argument, `relative'. Pass `relative' to `file-of-tag-function'.
12 (etags-file-of-tag): Added new argument `relative`.
13 (list-tags): Set `buffer-read-only' to t after making the major mode
14 apropos-mode.
15 (etags-list-tags): Used `make-text-button' instead of
16 `add-text-properties'. Used `snarf-tag-function',
17 `goto-tag-location-function' and `find-file-of-tag' instead of
18 `find-tag-other-window' (it's too simple).
19 (find-tag-in-order): Used `find-file-of-tag-noselect' instead of
20 `find-file'.
21 (etags-tags-apropos): Used `find-file-of-tag-noselect' instead of
22 `find-file'. Do not use `etags-goto-tag-location` directly; use
23 `goto-tag-location-function' instead. Print relative file paths
24 instead of complete ones in *Tags List* buffer, so lines in the
25 buffer become shorter.
26 (etags-tags-apropos-additional): Use `make-text-button' instead of
27 `add-text-properties'.
28
12003-04-04 Andreas Schwab <schwab@suse.de> 292003-04-04 Andreas Schwab <schwab@suse.de>
2 30
3 * net/tramp.el (tramp-send-string): Handle empty string. 31 * net/tramp.el (tramp-send-string): Handle empty string.
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 471be32401a..f1f5e36c51e 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -222,13 +222,17 @@ until one returns non-nil. The function should make buffer-local bindings
222of the format-parsing tags function variables if successful.") 222of the format-parsing tags function variables if successful.")
223 223
224(defvar file-of-tag-function nil 224(defvar file-of-tag-function nil
225 "Function to do the work of `file-of-tag' (which see).") 225 "Function to do the work of `file-of-tag' (which see).
226One optional argument, a boolean specifying to return complete path (nil) or
227relative path (non-nil).")
226(defvar tags-table-files-function nil 228(defvar tags-table-files-function nil
227 "Function to do the work of `tags-table-files' (which see).") 229 "Function to do the work of `tags-table-files' (which see).")
228(defvar tags-completion-table-function nil 230(defvar tags-completion-table-function nil
229 "Function to build the `tags-completion-table'.") 231 "Function to build the `tags-completion-table'.")
230(defvar snarf-tag-function nil 232(defvar snarf-tag-function nil
231 "Function to get info about a matched tag for `goto-tag-location-function'.") 233 "Function to get info about a matched tag for `goto-tag-location-function'.
234One optional argument, specifying to use explicit tag (non-nil) or not (nil).
235The default is nil.")
232(defvar goto-tag-location-function nil 236(defvar goto-tag-location-function nil
233 "Function of to go to the location in the buffer specified by a tag. 237 "Function of to go to the location in the buffer specified by a tag.
234One argument, the tag info returned by `snarf-tag-function'.") 238One argument, the tag info returned by `snarf-tag-function'.")
@@ -703,11 +707,13 @@ Returns t if it visits a tags table, or nil if there are no more in the list."
703 tags-table-list-started-at nil 707 tags-table-list-started-at nil
704 tags-table-set-list nil)) 708 tags-table-set-list nil))
705 709
706(defun file-of-tag () 710(defun file-of-tag (&optional relative)
707 "Return the file name of the file whose tags point is within. 711 "Return the file name of the file whose tags point is within.
708Assumes the tags table is the current buffer. 712Assumes the tags table is the current buffer.
709File name returned is relative to tags table file's directory." 713If RELATIVE is non-nil, file name returned is relative to tags
710 (funcall file-of-tag-function)) 714table file's directory. If RELATIVE is nil, file name returned
715is complete."
716 (funcall file-of-tag-function relative))
711 717
712;;;###autoload 718;;;###autoload
713(defun tags-table-files () 719(defun tags-table-files ()
@@ -1143,45 +1149,53 @@ where they were found."
1143 1149
1144 ;; Get the local value in the tags table buffer before switching buffers. 1150 ;; Get the local value in the tags table buffer before switching buffers.
1145 (setq goto-func goto-tag-location-function) 1151 (setq goto-func goto-tag-location-function)
1146 1152 (find-file-of-tag-noselect file)
1147 ;; Find the right line in the specified file.
1148 ;; If we are interested in compressed-files,
1149 ;; we search files with extensions.
1150 ;; otherwise only the real file.
1151 (let* ((buffer-search-extensions (if (featurep 'jka-compr)
1152 tags-compression-info-list
1153 '("")))
1154 the-buffer
1155 (file-search-extensions buffer-search-extensions))
1156 ;; search a buffer visiting the file with each possible extension
1157 ;; Note: there is a small inefficiency in find-buffer-visiting :
1158 ;; truename is computed even if not needed. Not too sure about this
1159 ;; but I suspect truename computation accesses the disk.
1160 ;; It is maybe a good idea to optimise this find-buffer-visiting.
1161 ;; An alternative would be to use only get-file-buffer
1162 ;; but this looks less "sure" to find the buffer for the file.
1163 (while (and (not the-buffer) buffer-search-extensions)
1164 (setq the-buffer (find-buffer-visiting (concat file (car buffer-search-extensions))))
1165 (setq buffer-search-extensions (cdr buffer-search-extensions)))
1166 ;; if found a buffer but file modified, ensure we re-read !
1167 (if (and the-buffer (not (verify-visited-file-modtime the-buffer)))
1168 (find-file-noselect (buffer-file-name the-buffer)))
1169 ;; if no buffer found, search for files with possible extensions on disk
1170 (while (and (not the-buffer) file-search-extensions)
1171 (if (not (file-exists-p (concat file (car file-search-extensions))))
1172 (setq file-search-extensions (cdr file-search-extensions))
1173 (setq the-buffer (find-file-noselect (concat file (car file-search-extensions))))))
1174 (if (not the-buffer)
1175 (if (featurep 'jka-compr)
1176 (error "File %s (with or without extensions %s) not found" file tags-compression-info-list)
1177 (error "File %s not found" file))
1178 (set-buffer the-buffer)))
1179 (widen) 1153 (widen)
1180 (push-mark) 1154 (push-mark)
1181 (funcall goto-func tag-info) 1155 (funcall goto-func tag-info)
1182 1156
1183 ;; Return the buffer where the tag was found. 1157 ;; Return the buffer where the tag was found.
1184 (current-buffer)))) 1158 (current-buffer))))
1159
1160(defun find-file-of-tag-noselect (file)
1161 ;; Find the right line in the specified file.
1162 ;; If we are interested in compressed-files,
1163 ;; we search files with extensions.
1164 ;; otherwise only the real file.
1165 (let* ((buffer-search-extensions (if (featurep 'jka-compr)
1166 tags-compression-info-list
1167 '("")))
1168 the-buffer
1169 (file-search-extensions buffer-search-extensions))
1170 ;; search a buffer visiting the file with each possible extension
1171 ;; Note: there is a small inefficiency in find-buffer-visiting :
1172 ;; truename is computed even if not needed. Not too sure about this
1173 ;; but I suspect truename computation accesses the disk.
1174 ;; It is maybe a good idea to optimise this find-buffer-visiting.
1175 ;; An alternative would be to use only get-file-buffer
1176 ;; but this looks less "sure" to find the buffer for the file.
1177 (while (and (not the-buffer) buffer-search-extensions)
1178 (setq the-buffer (find-buffer-visiting (concat file (car buffer-search-extensions))))
1179 (setq buffer-search-extensions (cdr buffer-search-extensions)))
1180 ;; if found a buffer but file modified, ensure we re-read !
1181 (if (and the-buffer (not (verify-visited-file-modtime the-buffer)))
1182 (find-file-noselect (buffer-file-name the-buffer)))
1183 ;; if no buffer found, search for files with possible extensions on disk
1184 (while (and (not the-buffer) file-search-extensions)
1185 (if (not (file-exists-p (concat file (car file-search-extensions))))
1186 (setq file-search-extensions (cdr file-search-extensions))
1187 (setq the-buffer (find-file-noselect (concat file (car file-search-extensions))))))
1188 (if (not the-buffer)
1189 (if (featurep 'jka-compr)
1190 (error "File %s (with or without extensions %s) not found" file tags-compression-info-list)
1191 (error "File %s not found" file))
1192 (set-buffer the-buffer))))
1193
1194(defun find-file-of-tag (file)
1195 (let ((buf (find-file-of-tag-noselect file)))
1196 (condition-case nil
1197 (switch-to-buffer buf)
1198 (error (pop-to-buffer buf)))))
1185 1199
1186;; `etags' TAGS file format support. 1200;; `etags' TAGS file format support.
1187 1201
@@ -1222,11 +1236,14 @@ where they were found."
1222 ;; Use eq instead of = in case char-after returns nil. 1236 ;; Use eq instead of = in case char-after returns nil.
1223 (eq (char-after (point-min)) ?\f)) 1237 (eq (char-after (point-min)) ?\f))
1224 1238
1225(defun etags-file-of-tag () 1239(defun etags-file-of-tag (&optional relative)
1226 (save-excursion 1240 (save-excursion
1227 (re-search-backward "\f\n\\([^\n]+\\),[0-9]*\n") 1241 (re-search-backward "\f\n\\([^\n]+\\),[0-9]*\n")
1228 (expand-file-name (buffer-substring (match-beginning 1) (match-end 1)) 1242 (let ((str (buffer-substring (match-beginning 1) (match-end 1))))
1229 (file-truename default-directory)))) 1243 (if relative
1244 str
1245 (expand-file-name str
1246 (file-truename default-directory))))))
1230 1247
1231 1248
1232(defun etags-tags-completion-table () 1249(defun etags-tags-completion-table ()
@@ -1254,8 +1271,8 @@ where they were found."
1254 table))) 1271 table)))
1255 table)) 1272 table))
1256 1273
1257(defun etags-snarf-tag () 1274(defun etags-snarf-tag (&optional use-explicit)
1258 (let (tag-text line startpos) 1275 (let (tag-text line startpos explicit-start)
1259 (if (save-excursion 1276 (if (save-excursion
1260 (forward-line -1) 1277 (forward-line -1)
1261 (looking-at "\f\n")) 1278 (looking-at "\f\n"))
@@ -1271,8 +1288,14 @@ where they were found."
1271 (setq tag-text (buffer-substring (1- (point)) 1288 (setq tag-text (buffer-substring (1- (point))
1272 (save-excursion (beginning-of-line) 1289 (save-excursion (beginning-of-line)
1273 (point)))) 1290 (point))))
1274 ;; Skip explicit tag name if present. 1291 ;; If use-explicit is non nil and explicit tag is present, use it as part of
1275 (search-forward "\001" (save-excursion (forward-line 1) (point)) t) 1292 ;; return value. Else just skip it.
1293 (setq explicit-start (point))
1294 (when (and (search-forward "\001" (save-excursion (forward-line 1) (point)) t)
1295 use-explicit)
1296 (setq tag-text (buffer-substring explicit-start (1- (point)))))
1297
1298
1276 (if (looking-at "[0-9]") 1299 (if (looking-at "[0-9]")
1277 (setq line (string-to-int (buffer-substring 1300 (setq line (string-to-int (buffer-substring
1278 (point) 1301 (point)
@@ -1347,27 +1370,35 @@ where they were found."
1347 1370
1348(defun etags-list-tags (file) 1371(defun etags-list-tags (file)
1349 (goto-char (point-min)) 1372 (goto-char (point-min))
1350 (when (search-forward (concat "\f\n" file ",") nil t) 1373 (when (re-search-forward (concat "\f\n" "\\(" file "\\)" ",") nil t)
1374 (let ((path (save-excursion (forward-line 1) (file-of-tag)))
1375 ;; Get the local value in the tags table
1376 ;; buffer before switching buffers.
1377 (goto-func goto-tag-location-function)
1378 tag tag-info pt)
1351 (forward-line 1) 1379 (forward-line 1)
1352 (while (not (or (eobp) (looking-at "\f"))) 1380 (while (not (or (eobp) (looking-at "\f")))
1353 (let ((tag (buffer-substring (point) 1381 (setq tag-info (save-excursion (funcall snarf-tag-function t))
1354 (progn (skip-chars-forward "^\177") 1382 tag (car tag-info)
1355 (point)))) 1383 pt (with-current-buffer standard-output (point)))
1356 (props `(action find-tag-other-window mouse-face highlight 1384 (princ tag)
1357 face ,tags-tag-face)) 1385 (when (= (aref tag 0) ?\() (princ " ...)"))
1358 (pt (with-current-buffer standard-output (point)))) 1386 (with-current-buffer standard-output
1359 (when (looking-at "[^\n]+\001") 1387 (make-text-button pt (point)
1360 ;; There is an explicit tag name; use that. 1388 'tag-info tag-info
1361 (setq tag (buffer-substring (1+ (point)) ; skip \177 1389 'file-path path
1362 (progn (skip-chars-forward "^\001") 1390 'goto-func goto-func
1363 (point))))) 1391 'action (lambda (button)
1364 (princ tag) 1392 (let ((tag-info (button-get button 'tag-info))
1365 (when (= (aref tag 0) ?\() (princ " ...)")) 1393 (goto-func (button-get button 'goto-func)))
1366 (add-text-properties pt (with-current-buffer standard-output (point)) 1394 (find-file-of-tag (button-get button 'file-path))
1367 (cons 'item (cons tag props)) standard-output)) 1395 (widen)
1396 (funcall goto-func tag-info)))
1397 'face 'tags-tag-face
1398 'type 'button))
1368 (terpri) 1399 (terpri)
1369 (forward-line 1)) 1400 (forward-line 1))
1370 t)) 1401 t)))
1371 1402
1372(defmacro tags-with-face (face &rest body) 1403(defmacro tags-with-face (face &rest body)
1373 "Execute BODY, give output to `standard-output' face FACE." 1404 "Execute BODY, give output to `standard-output' face FACE."
@@ -1384,16 +1415,20 @@ where they were found."
1384 (princ "\n\n") 1415 (princ "\n\n")
1385 (tags-with-face 'highlight (princ (car oba))) 1416 (tags-with-face 'highlight (princ (car oba)))
1386 (princ":\n\n") 1417 (princ":\n\n")
1387 (let* ((props `(action ,(cadr oba) mouse-face highlight face 1418 (let* ((beg (point))
1388 ,tags-tag-face))
1389 (beg (point))
1390 (symbs (car (cddr oba))) 1419 (symbs (car (cddr oba)))
1391 (ins-symb (lambda (sy) 1420 (ins-symb (lambda (sy)
1392 (let ((sn (symbol-name sy))) 1421 (let ((sn (symbol-name sy)))
1393 (when (string-match regexp sn) 1422 (when (string-match regexp sn)
1394 (add-text-properties (point) 1423 (make-text-button (point)
1395 (progn (princ sy) (point)) 1424 (progn (princ sy) (point))
1396 (cons 'item (cons sn props))) 1425 'action-internal(cadr oba)
1426 'action (lambda (button) (funcall
1427 (button-get button 'action-internal)
1428 (button-get button 'item)))
1429 'item sn
1430 'face tags-tag-face
1431 'type 'button)
1397 (terpri)))))) 1432 (terpri))))))
1398 (when (symbolp symbs) 1433 (when (symbolp symbs)
1399 (if (boundp symbs) 1434 (if (boundp symbs)
@@ -1414,40 +1449,48 @@ where they were found."
1414 (goto-char (point-min)) 1449 (goto-char (point-min))
1415 (while (re-search-forward string nil t) 1450 (while (re-search-forward string nil t)
1416 (beginning-of-line) 1451 (beginning-of-line)
1417 (let* ((tag-info (save-excursion (funcall snarf-tag-function))) 1452
1453 (let* (;; Get the local value in the tags table
1454 ;; buffer before switching buffers.
1455 (goto-func goto-tag-location-function)
1456 (tag-info (save-excursion (funcall snarf-tag-function)))
1418 (tag (if (eq t (car tag-info)) nil (car tag-info))) 1457 (tag (if (eq t (car tag-info)) nil (car tag-info)))
1419 (file (if tag (file-of-tag) 1458 (file-path (save-excursion (if tag (file-of-tag)
1420 (save-excursion (next-line 1) 1459 (save-excursion (next-line 1)
1421 (file-of-tag)))) 1460 (file-of-tag)))))
1461 (file-label (if tag (file-of-tag t)
1462 (save-excursion (next-line 1)
1463 (file-of-tag t))))
1422 (pt (with-current-buffer standard-output (point)))) 1464 (pt (with-current-buffer standard-output (point))))
1423 (if tag 1465 (if tag
1424 (progn 1466 (progn
1425 (princ (format "[%s]: " file)) 1467 (princ (format "[%s]: " file-label))
1426 (princ tag) 1468 (princ tag)
1427 (when (= (aref tag 0) ?\() (princ " ...)")) 1469 (when (= (aref tag 0) ?\() (princ " ...)"))
1428 (with-current-buffer standard-output 1470 (with-current-buffer standard-output
1429 (make-text-button pt (point) 1471 (make-text-button pt (point)
1430 'tag-info tag-info 1472 'tag-info tag-info
1431 'file file 1473 'file-path file-path
1432 'action (lambda (button) 1474 'goto-func goto-func
1433 ;; TODO: just `find-file is too simple. 1475 'action (lambda (button)
1434 ;; Use code `find-tag-in-order'. 1476 (let ((tag-info (button-get button 'tag-info))
1435 (let ((tag-info (button-get button 'tag-info))) 1477 (goto-func (button-get button 'goto-func)))
1436 (find-file (button-get button 'file)) 1478 (find-file-of-tag (button-get button 'file-path))
1437 (etags-goto-tag-location tag-info))) 1479 (widen)
1438 'face 'tags-tag-face 1480 (funcall goto-func tag-info)))
1439 'type 'button))) 1481 'face 'tags-tag-face
1440 (princ (format "- %s" file)) 1482 'type 'button)))
1483 (princ (format "- %s" file-label))
1441 (with-current-buffer standard-output 1484 (with-current-buffer standard-output
1442 (make-text-button pt (point) 1485 (make-text-button pt (point)
1443 'file file 1486 'file-path file-path
1444 'action (lambda (button) 1487 'action (lambda (button)
1445 ;; TODO: just `find-file is too simple. 1488 (find-file-of-tag (button-get button 'file-path))
1446 ;; Use code `find-tag-in-order'. 1489 ;; Get the local value in the tags table
1447 (find-file (button-get button 'file)) 1490 ;; buffer before switching buffers.
1448 (goto-char (point-min))) 1491 (goto-char (point-min)))
1449 'face 'tags-tag-face 1492 'face 'tags-tag-face
1450 'type 'button)) 1493 'type 'button))
1451 )) 1494 ))
1452 (terpri) 1495 (terpri)
1453 (forward-line 1)) 1496 (forward-line 1))
@@ -1822,8 +1865,8 @@ directory specification."
1822 (or gotany 1865 (or gotany
1823 (error "File %s not in current tags tables" file))))) 1866 (error "File %s not in current tags tables" file)))))
1824 (with-current-buffer "*Tags List*" 1867 (with-current-buffer "*Tags List*"
1825 (setq buffer-read-only t) 1868 (apropos-mode)
1826 (apropos-mode))) 1869 (setq buffer-read-only t)))
1827 1870
1828;;;###autoload 1871;;;###autoload
1829(defun tags-apropos (regexp) 1872(defun tags-apropos (regexp)