Emacs has builtin etags
ant its portable, on MacOS there are a default one: ctags
at /usr/bin/ctags
(but it is not exuberant). Emacs
accepts etags
generated TAG file, on other side ctags
exuberant or not, you can add -e
option to let ctags
to generate the TAG file that Emacs can accept.
When the Emacs accepted TAG file had been generated, you can add it to Emacs' tags-table-list
, not the exec-path
:
(add-to-list 'tags-table-list tags-dir t #'string=)
tags-table-list is a variable defined in ‘etags.el’.
Its value is
("~/.emacs.d/.tags/home/g_25.3.1/" "~/.emacs.d/.tags/source/g_25.3.1/" "~/.emacs.d/.tags/c/g_25.3.1/" "~/.emacs.d/.tags/os/g_25.3.1/")
Documentation:
List of file names of tags tables to search.
An element that is a directory means the file "TAGS" in that directory.
To switch to a new list of tags tables, setting this variable is sufficient.
If you set this variable, do not also set ‘tags-file-name’.
Use the ‘etags’ program to make a tags table file.
There are a working example at more reasonable Emacs
(defun make-tags (home tags-file file-filter dir-filter &optional renew)
"Make tags."
(when (file-exists-p home)
(let ((tags-dir (file-name-directory tags-file)))
(if (file-exists-p tags-file)
(when renew (delete-file tags-file))
(when (not (file-exists-p tags-dir))
(make-directory tags-dir t)))
(dir-iterate home
file-filter
dir-filter
(lambda (f)
(eshell-command
(format "etags -o %s -l auto -a %s ; echo %s"
tags-file f f))))
(when (file-exists-p tags-file)
(add-to-list 'tags-table-list tags-dir t #'string=)))))
(defun make-emacs-home-tags (tags-file &optional renew)
"Make TAGS-FILE for Emacs' home directory."
(let ((lisp-ff (lambda (f _) (string-match "\\\.el$" f)))
(home-df
(lambda (d _)
(not
(string-match
"^\\\..*/$\\|^theme/$\\|^g_.*/$\\|^t_.*/$\\|^private/$" d)))))
(make-tags emacs-home tags-file lisp-ff home-df renew)))
make-tags
function need dir-iterate
function to iterate directories:
(defun dir-iterate (dir ff df fn)
"Iterating DIR, if FILE-FILTER return T then call FN,
and if DIR-FILTER return T then iterate into deeper DIR.
(defun FILE-FILTER (file-name absolute-name))
(defun DIR-FILTER (dir-name absolute-name))
\(FN DIR FILE-FILTER DIR-FILTER FN\)"
(dolist (f (file-name-all-completions "" dir))
(unless (member f '("./" "../"))
(let ((a (expand-file-name f dir)))
(if (directory-name-p f)
(when (and df (funcall df f a)
(dir-iterate a ff df fn)))
(when (and ff (funcall ff f a)
(funcall fn a))))))))
/usr/bin/ctags
is nothing but a wrapper to run the one inside the Xcode bundle. One reason I believe this, is the fact that a great many developer oriented programs in/usr/bin
are exactly the same length: 14160 bytes. (Addendum:execsnoop
disagrees, but maybe Apple has ways to fool dtrace sometimes.) – Harald Hanche-Olsen Aug 16 '15 at 8:25--version
argument. The GNU Emacs versions says so, as does Exuberant Ctags (which I invariably use instead). I imagine whatever Xcode is using would provide some similar output. – phils Sep 16 '15 at 6:17