etags - Build a TAG for Multiple R Packages04 May 2016
Here is what tried to build a TAG for multiple R packages. It enable me to jump to a location where the function/variable is defined and modify if I want to.
Useful variable and functions
- default path to find packages, should be a list
- if the folder has DESCRIPTION file, then the folder is a R package.
- (ess-build-tags-for-directory DIR TAGFILE)
- build tag on DIR to TARGET.
- List of file names of tags tables to search.
- (visit-tags-table FILE &optional LOCAL)
- Tell tags commands to use tags table file.
;; new variable (defvar ess-r-package-library-tags nil "A TAG file for multiple R packages.") (setq ess-r-package-library-path '("~/tmp/feather/R" "~/tmp/RPostgres/")) (setq ess-r-package-library-tags "~/tmp/all_tags") (dolist (pkg-path ess-r-package-library-path) (let ((pkg-name (ess-r-package--find-package-name pkg-path))) (unless (and pkg-name pkg-path (file-exists-p (expand-file-name ess-r-package-root-file pkg-path))) (error "Not a valid package. No '%s' found in `%s'." ess-r-package-root-file pkg-path)) (ess-build-tags-for-directory pkg-path ess-r-package-library-tags) ))
Note the workhorse is
ess-build-tags-for-directory which does what
it means. The core of this function use
find program will find files with extension .cpp, R, nw etc, and
then feed to (using pipe) to the
etags program which generate a TAG
table. These two steps are demonstrated in the following snippet,
which is grabbed from the source code of
(setq find-cmd (format "find %s -type f -size 1M \\( -regex \".*\\.\\(cpp\\|jl\\|[RsrSch]\\(nw\\)?\\)$\" \\)" (car ess-r-package-library-path))) (setq regs (delq nil (mapcar (lambda (l) (if (string-match "'" (cadr l)) nil ;; remove for time being (format "/%s/\\%d/" (replace-regexp-in-string "/" "\\/" (nth 1 l) t) (nth 2 l)))) imenu-generic-expression))) (setq tags-cmd (format "etags -o %s --regex='%s' -" "~/lala" (mapconcat 'identity regs "' --regex='"))) (setq sh-cmd (format "%s | %s" find-cmd tags-cmd)) (shell-command sh-cmd)
Note when they are used in Emacs, the tags-table-list variable is
appended with the path to the new TAG table. So that the user can use
xref-find-definitions (M-.) to jump (if the point is under a word) or
select which function/variable to jump to. The users then check the
function/variable definition, or modify it if it is necessary. Then
xref-pop-marker-stack (~M-,) to jump back.