;;; etags.el --- etags facility for Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1985-1986, 1988-1989, 1992-1996, 1998, 2000-2014 Free
+;; Copyright (C) 1985-1986, 1988-1989, 1992-1996, 1998, 2000-2015 Free
;; Software Foundation, Inc.
;; Author: Roland McGrath <roland@gnu.org>
(save-excursion
(or (visit-tags-table-buffer file)
(signal 'file-error (list "Visiting tags table"
- "file does not exist"
+ "No such file or directory"
file)))
;; Set FILE to the expanded name.
(setq file tags-file-name)))
Contrast this with the ring of marks gone to by the command.
See documentation of variable `tags-file-name'."
+ (declare (obsolete xref-find-definitions-other-window "25.1"))
(interactive (find-tag-interactive "Find tag other window: "))
;; This hair is to deal with the case where the tag is found in the
Contrast this with the ring of marks gone to by the command.
See documentation of variable `tags-file-name'."
+ (declare (obsolete xref-find-definitions-other-frame "25.1"))
(interactive (find-tag-interactive "Find tag other frame: "))
(let ((pop-up-frames t))
(find-tag-other-window tagname next-p)))
Contrast this with the ring of marks gone to by the command.
See documentation of variable `tags-file-name'."
+ (declare (obsolete xref-find-apropos "25.1"))
(interactive (find-tag-interactive "Find tag regexp: " t))
;; We go through find-tag-other-window to do all the display hair there.
(funcall (if other-window 'find-tag-other-window 'find-tag)
interesting (it returns non-nil if so) and `tags-loop-operate' is a form to
evaluate to operate on an interesting file. If the latter evaluates to
nil, we exit; otherwise we scan the next file."
+ (declare (obsolete "use `xref-find-definitions' interface instead." "25.1"))
(interactive)
(let (new
;; Non-nil means we have finished one file
;;;###autoload
(defun tags-apropos (regexp)
"Display list of all tags in tags table REGEXP matches."
+ (declare (obsolete xref-find-apropos "25.1"))
(interactive "sTags apropos (regexp): ")
(with-output-to-temp-buffer "*Tags List*"
(princ "Click mouse-2 to follow tags.\n\nTags matching regexp `")
;; we hit the limit rarely.
(defconst etags--xref-limit 1000)
+(defvar etags-xref-find-definitions-tag-order '(tag-exact-match-p
+ tag-implicit-name-match-p
+ tag-symbol-match-p)
+ "Tag order used in `etags-xref-find' to look for definitions.")
+
;;;###autoload
(defun etags-xref-find (action id)
(pcase action
(`definitions (etags--xref-find-definitions id))
+ (`references
+ (let ((dirs (if tags-table-list
+ (mapcar #'file-name-directory tags-table-list)
+ ;; If no tags files are loaded, prompt for the dir.
+ (list (read-directory-name "In directory: " nil nil t)))))
+ (cl-mapcan
+ (lambda (dir)
+ (xref-collect-references id dir))
+ dirs)))
(`apropos (etags--xref-find-definitions id t))))
(defun etags--xref-find-definitions (pattern &optional regexp?)
(while (visit-tags-table-buffer (not first-time))
(setq first-time nil)
(dolist (order-fun (cond (regexp? find-tag-regexp-tag-order)
- (t find-tag-tag-order)))
+ (t etags-xref-find-definitions-tag-order)))
(goto-char (point-min))
(while (and (funcall search-fun pattern nil t)
(< (hash-table-count marks) etags--xref-limit))
(when (funcall order-fun pattern)
(beginning-of-line)
- (cl-destructuring-bind (hint line &rest pos) (etags-snarf-tag)
+ (pcase-let* ((tag-info (etags-snarf-tag))
+ (`(,hint ,line . _) tag-info))
(unless (eq hint t) ; hint==t if we are in a filename line
(let* ((file (file-of-tag))
(mark-key (cons file line)))
(unless (gethash mark-key marks)
- (let ((loc (xref-make-file-location
- (expand-file-name file) line 0)))
+ (let ((loc (xref-make-etags-location
+ tag-info (expand-file-name file))))
(push (xref-make hint loc) xrefs)
(puthash mark-key t marks)))))))))))
(nreverse xrefs)))
+(defclass xref-etags-location (xref-location)
+ ((tag-info :type list :initarg :tag-info)
+ (file :type string :initarg :file
+ :reader xref-location-group))
+ :documentation "Location of an etags tag.")
+
+(defun xref-make-etags-location (tag-info file)
+ (make-instance 'xref-etags-location :tag-info tag-info
+ :file (expand-file-name file)))
+
+(cl-defmethod xref-location-marker ((l xref-etags-location))
+ (with-slots (tag-info file) l
+ (let ((buffer (find-file-noselect file)))
+ (with-current-buffer buffer
+ (etags-goto-tag-location tag-info)
+ (point-marker)))))
+
+(cl-defmethod xref-location-line ((l xref-etags-location))
+ (with-slots (tag-info) l
+ (nth 1 tag-info)))
+
\f
(provide 'etags)