How to programmatically create/update a TAGS file with emacs?

为君一笑 提交于 2019-12-31 08:51:46

问题


Is there any plugin for emacs to automatically update the TAGS file in my C project (for example on buffer save or access) or create a new one if there is no TAGS file present?

I am running on Windows (without Cygwin), so all the fancy shell scripting does not help. I was hoping for a native emacs solution not using any external scripting.

I already tried build-tags.el and etags-table.el but none of these really worked (the way I wanted).

Any other ideas?


回答1:


etags-update may help in your case. I didn't test it, but according to the readme:

etags-update.el is a Emacs global minor mode that updates your TAGS when saving a file.

I found it on the Emacswiki page for building TAGS files




回答2:


Here is how I generate a TAGS file for a C project:

  1. M-x cd YOUR_DIRECTORY
  2. M-x compile
  3. find . -name "*.[chCH]" -print | etags -

That will create a TAGS file in the current directory for all sub directories and files.

Here is a emacs function that does the exact same thing:

(defun compile-tags ()
  "compile etags for the current project"
  (interactive)
  (cd "YOUR_DIRECTORY")
  (compile "find . -name \"*.[chCH]\" -print | etags -"))

NOTE: if you are on windows you'll need to install cygwin and make sure c:\cygwin\bin is in your path so that you get find in your path. Also make sure the emacs bin directory is in your path so that you can get etags as well.




回答3:


Why not add an execution of ctags to your build script? You really only need a new tags file when you compile (at the most). I tend to just write a scheduled task to build the tags file every night. Seems to work pretty well.




回答4:


I use combination of semantic + gnu global for my day-to-day work. GNU Global's databases are updated once per day, while semantic use them for basic navigation, and re-parse changed files on the fly.

You can find more about these packages in my article about Cedet




回答5:


Try out my `ctags.el'[1] module.

Configuration example:

(setq tags-revert-without-query t)
(global-set-key (kbd "<f5>") 'ctags-create-or-update-tags-table)

Then just press <f5> to update or create your TAGS file. That function look for a file TAGS in the current and its parent directories, if a TAG file is not found it ask you where create a new one.

It is a new library and probably has bugs, etc, so any help is welcome.

[1] https://bitbucket.org/semente/ctags.el/




回答6:


This might get you close (untested):

(defvar my-auto-update-tags-alist
  (list '("/some/path/to/TAGS" "command_to_build_tags")
        '("/another/path/to/TAGS" "another_build_command")))

(defun my-auto-update-tags ()
  "Automatically update TAGS files"
  (tags-table-check-computed-list)
  (let ((filename (buffer-file-name))
        build-cmd)
    (mapc (lambda (tag-file)
            (set-buffer tag-file)
            (when (member filename (tags-table-files))
              (setq build-cmd (cdr (assoc tag-file my-auto-update-tags-alist)))
              (when build-cmd
                (call-process build-cmd nil 0))))
          tags-table-computed-list)))

(add-hook 'after-save-hook 'my-auto-update-tags)

It will only work (did I mention it's untested?) on files that are in TAGS files already. If you add a new file you'd have to regenerate the TAGS file the first time yourself. The call-process part should work asynchronously, so it might be a few moments until the TAGS file is actually rebuilt (if this even works ;)




回答7:


Install find-and-ctags (https://github.com/redguardtoo/find-and-ctags), then insert below code into ~/.emacs,

(defun my-setup-develop-environment ()
  (interactive)

  ;; you can use `find-and-ctags-current-full-filename-match-pattern-p' instead
  (when (find-and-ctags-current-path-match-pattern-p "/MYPROJ")
    (setq-local tags-table-list
                (list (find-and-ctags-run-ctags-if-needed "~/workspace/MYPROJ" ; project directory
               '(("-not -size +64k" "--exclude=*.min.js") ; (find-opts ctags-opts)
                                                            ;; you may add more find-opts ctags-opts pair HERE to run find&ctags again to APPEND to same TAGS file
                                                            ;; ctags-opts must contain "-a" to append
                                                            ;; (find-opts "-a")
                                                            )))))

  ;; for other projects
  ;; insert NEW `when' statements here
  )
(add-hook 'prog-mode-hook 'my-setup-develop-environment) ; prog-mode require emacs24+
(add-hook 'lua-mode-hook 'my-setup-develop-environment) ; lua-mode does NOT inherit from prog-mode

;; OPTIONAL
(add-hook 'after-save-hook 'find-and-ctags-auto-update-tags)

It works on windows, all you need is replace "~/workspace/MYPROJ" with "C:/workspace/MYPROJ". CTags executable could be any version, because produced TAGS contains only relative path.



来源:https://stackoverflow.com/questions/548414/how-to-programmatically-create-update-a-tags-file-with-emacs

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!