Download
(defconst etags-u-revative-names t)
(defun etags-u-update-tags-file()
"Updates current file in current TAGS file. Current tags file is `tags-file-name'.
If file was not in TAGS file, it is created."
(interactive)
(flet ((message (&rest args) args))
(etags-u-remove-from-tags-file)
(etags-u-append-to-tags-file))
nil)
(defun etags-u-append-to-tags-file()
"Appends to current file to current TAGS file. Current tags file is `tags-file-name'.
Warning, it's not update function. If file was already tagged, it will create dublicate of current file."
(unless (and (stringp tags-file-name) (file-exists-p tags-file-name))
(error "`tags-file-name' does not point to TAGS file. Use m-x visit-tags-table to set it."))
(save-excursion
(let ((file (buffer-file-name)))
(unless file (error "No buffer-file!"))
(set-buffer (find-file-noselect tags-file-name t))
(find-buffer-visiting tags-file-name)
(flet ((y-or-n-p (&rest args) t) (yes-or-no-p (&rest args) t))
(shell-command (format "etags -a %s" (if etags-u-revative-names (file-relative-name file) file)) (get-buffer-create " *etags-u*") (get-buffer-create " *etags-u*")))))
nil)
(defun etags-u-remove-from-tags-file (&optional file)
"Removes current file from current TAGS file. Current tags file is `tags-file-name'."
(interactive)
(unless (and (stringp tags-file-name) (file-exists-p tags-file-name))
(error "`tags-file-name' does not point to TAGS file. Use m-x visit-tags-table to set it."))
(save-excursion
(unless file (setq file (buffer-file-name)))
(unless file (error "No buffer-file!"))
(assert (file-exists-p file) "File not exist: %S" file)
(set-buffer (find-file-noselect tags-file-name))
(goto-char (point-min))
(while (etags-u-test-and-remove file))
(save-buffer))
nil)
(defun etags-u-test-and-remove (file)
"Started in TAGS file; T if we need to quit."
(let (start filename-in-tags-file)
(if
(search-forward " \n" nil t)
(let ((beg (point)))
(setq start (match-beginning 0))
(search-forward ",")
(goto-char (match-beginning 0))
(setq filename-in-tags-file
(buffer-substring-no-properties beg (point)))
(when (file-equal-p
file
filename-in-tags-file)
(goto-char
(if (search-forward " " nil t)
(match-beginning 0)
(point-max)))
(delete-region start (point)))
t)
nil)))
(defvar etags-u-map (make-sparse-keymap))
(define-minor-mode etags-u-mode
"docstring"
:init-value nil
:lighter " etags-U"
:keymap etags-u-map
(progn
(if etags-u-mode (etags-u-update-tags-file))))
(defadvice save-buffer (after etags-u)
"Autoupdate TAGS file"
(if etags-u-mode (etags-u-update-tags-file)))
(ad-activate 'save-buffer)
(defadvice delete-file (before etags-u)
"Delete entries from TAGS file. Cuz dired works with `delete-file' too, works nice with dired!"
(etags-u-remove-from-tags-file filename))
(ad-activate 'delete-file)
(provide 'etags-u)