From ab419665caa6e2ad7465cf59ef902cc4ad1d2117 Mon Sep 17 00:00:00 2001 From: Xue Fuqiao Date: Sun, 4 Aug 2013 10:55:45 +0800 Subject: [PATCH] Cleanup for vc-ignore. * vc/vc.el (vc-ignore): Rewrite. (vc-default-ignore-completion-table): (vc--read-lines): (vc--add-line, vc--remove-regexp): New functions. * vc/vc-svn.el (vc-svn-ignore): Doc fix. (vc-svn-ignore-completion-table): New function. * vc/vc-hg.el (vc-hg-ignore): Rewrite. (vc-hg-ignore-completion-table): (vc-hg-find-ignore-file): New functions. * vc/vc-git.el (vc-git-ignore): Rewrite. (vc-git-ignore-completion-table): (vc-git-find-ignore-file): New functions. * vc/vc-dir.el (vc-dir-menu-map): Add menu for vc-dir-ignore. * vc/vc-bzr.el (vc-bzr-ignore): Rewrite. (vc-bzr-ignore-completion-table): (vc-bzr-find-ignore-file): New functions. --- lisp/ChangeLog | 24 ++++++++++++++++ lisp/vc/vc-bzr.el | 22 +++++++++++++-- lisp/vc/vc-dir.el | 3 ++ lisp/vc/vc-git.el | 30 +++++++++++++------- lisp/vc/vc-hg.el | 30 +++++++++++++------- lisp/vc/vc-svn.el | 10 +++++-- lisp/vc/vc.el | 72 +++++++++++++++++++++++++++++++++++++++++------ 7 files changed, 158 insertions(+), 33 deletions(-) diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 4f63206212c..d914582c280 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,27 @@ +2013-08-04 Xue Fuqiao + + * vc/vc.el (vc-ignore): Rewrite. + (vc-default-ignore-completion-table): + (vc--read-lines): + (vc--add-line, vc--remove-regexp): New functions. + + * vc/vc-svn.el (vc-svn-ignore): Doc fix. + (vc-svn-ignore-completion-table): New function. + + * vc/vc-hg.el (vc-hg-ignore): Rewrite. + (vc-hg-ignore-completion-table): + (vc-hg-find-ignore-file): New functions. + + * vc/vc-git.el (vc-git-ignore): Rewrite. + (vc-git-ignore-completion-table): + (vc-git-find-ignore-file): New functions. + + * vc/vc-dir.el (vc-dir-menu-map): Add menu for vc-dir-ignore. + + * vc/vc-bzr.el (vc-bzr-ignore): Rewrite. + (vc-bzr-ignore-completion-table): + (vc-bzr-find-ignore-file): New functions. + 2013-07-30 Xue Fuqiao * vc/vc-svn.el (vc-svn-ignore): Remove `interactive'. Use `*vc*' diff --git a/lisp/vc/vc-bzr.el b/lisp/vc/vc-bzr.el index 9d2adde8554..e59a7dc5214 100644 --- a/lisp/vc/vc-bzr.el +++ b/lisp/vc/vc-bzr.el @@ -651,9 +651,25 @@ REV non-nil gets an error." (vc-bzr-command "cat" t 0 file "-r" rev) (vc-bzr-command "cat" t 0 file)))) -(defun vc-bzr-ignore (file) - "Ignore FILE under Bazaar." - (vc-bzr-command "ignore" t 0 file)) +(defun vc-bzr-ignore (file &optional directory remove) + "Ignore FILE under Bazaar. +If DIRECTORY is non-nil, the repository to use will be deduced by +DIRECTORY; if REMOVE is non-nil, remove FILE from ignored files." + (if remove + (if directory + (vc--remove-regexp file (vc-bzr-find-ignore-file directory)) + (vc--remove-regexp file + (vc-bzr-find-ignore-file default-directory))) + (vc-bzr-command "ignore" t 0 file))) + +(defun vc-bzr-ignore-completion-table (file) + "Return the list of ignored files." + (vc--read-lines (vc-bzr-find-ignore-file file))) + +(defun vc-bzr-find-ignore-file (file) + "Return the root directory of the repository of FILE." + (expand-file-name ".bzrignore" + (vc-bzr-root file))) (defun vc-bzr-checkout (_file &optional _editable rev) (if rev (error "Operation not supported") diff --git a/lisp/vc/vc-dir.el b/lisp/vc/vc-dir.el index 6f03cba1f75..441b3725968 100644 --- a/lisp/vc/vc-dir.el +++ b/lisp/vc/vc-dir.el @@ -215,6 +215,9 @@ See `run-hooks'." (define-key map [register] '(menu-item "Register" vc-register :help "Register file set into the version control system")) + (define-key map [ignore] + '(menu-item "Ignore Current File" vc-dir-ignore + :help "Ignore the current file under current version control system")) map) "Menu for VC dir.") diff --git a/lisp/vc/vc-git.el b/lisp/vc/vc-git.el index 4716d13da13..472c42840af 100644 --- a/lisp/vc/vc-git.el +++ b/lisp/vc/vc-git.el @@ -680,16 +680,26 @@ It is based on `log-edit-mode', and has Git-specific extensions.") nil "cat-file" "blob" (concat (if rev rev "HEAD") ":" fullname)))) -(defun vc-git-ignore (file) - "Ignore FILE under Git." - (with-temp-buffer - (insert-file-contents - (let ((gitignore (concat (file-name-as-directory (vc-git-root - default-directory)) ".gitignore"))) - (unless (search-forward (concat "\n" file "\n") nil t) - (goto-char (point-max)) - (insert (concat "\n" file "\n")) - (write-region (point-min) (point-max) gitignore)))))) +(defun vc-git-ignore (file &optional directory remove) + "Ignore FILE under Git. +If DIRECTORY is non-nil, the repository to use will be deduced by +DIRECTORY; if REMOVE is non-nil, remove FILE from ignored files." + (let (gitignore) + (if directory + (setq gitignore (vc-git-find-ignore-file directory)) + (setq gitignore (vc-git-find-ignore-file default-directory))) + (if remove + (vc--remove-regexp file gitignore) + (vc--add-line file gitignore)))) + +(defun vc-git-ignore-completion-table (file) + "Return the list of ignored files." + (vc--read-lines (vc-git-find-ignore-file file))) + +(defun vc-git-find-ignore-file (file) + "Return the root directory of the repository of FILE." + (expand-file-name ".gitignore" + (vc-git-root file))) (defun vc-git-checkout (file &optional _editable rev) (vc-git-command nil 0 file "checkout" (or rev "HEAD"))) diff --git a/lisp/vc/vc-hg.el b/lisp/vc/vc-hg.el index bc125e2cfa6..68d98a60f98 100644 --- a/lisp/vc/vc-hg.el +++ b/lisp/vc/vc-hg.el @@ -459,16 +459,26 @@ REV is ignored." (vc-hg-command buffer 0 file "cat" "-r" rev) (vc-hg-command buffer 0 file "cat")))) -(defun vc-hg-ignore (file) - "Ignore FILE under Mercurial." - (with-temp-buffer - (insert-file-contents - (let ((hgignore (concat (file-name-as-directory (vc-hg-root - default-directory)) ".hgignore"))) - (unless (search-forward (concat "\n" file "\n") nil t) - (goto-char (point-max)) - (insert (concat "\n" file "\n")) - (write-region (point-min) (point-max) hgignore)))))) +(defun vc-hg-ignore (file &optional directory remove) + "Ignore FILE under Mercurial. +If DIRECTORY is non-nil, the repository to use will be deduced by +DIRECTORY; if REMOVE is non-nil, remove FILE from ignored files." + (let (hgignore) + (if directory + (setq hgignore (vc-hg-find-ignore-file directory)) + (setq hgignore (vc-hg-find-ignore-file default-directory))) + (if remove + (vc--remove-regexp file hgignore) + (vc--add-line file hgignore)))) + +(defun vc-hg-ignore-completion-table (file) + "Return the list of ignored files." + (vc--read-lines (vc-hg-find-ignore-file file))) + +(defun vc-hg-find-ignore-file (file) + "Return the root directory of the repository of FILE." + (expand-file-name ".hgignore" + (vc-hg-root file))) ;; Modeled after the similar function in vc-bzr.el (defun vc-hg-checkout (file &optional _editable rev) diff --git a/lisp/vc/vc-svn.el b/lisp/vc/vc-svn.el index 743a4d5cb67..0e020614fd2 100644 --- a/lisp/vc/vc-svn.el +++ b/lisp/vc/vc-svn.el @@ -352,10 +352,16 @@ This is only possible if SVN is responsible for FILE's directory.") (concat "-r" rev)) (vc-switches 'SVN 'checkout)))) -(defun vc-svn-ignore (file) - "Ignore FILE under Subversion." +(defun vc-svn-ignore (file &optional directory remove) + "Ignore FILE under Subversion. +If DIRECTORY is non-nil, the repository to use will be deduced by +DIRECTORY; if REMOVE is non-nil, remove FILE from ignored files." (vc-svn-command t 0 file "propedit" "svn:ignore")) +(defun vc-svn-ignore-completion-table (file) + "Return the list of ignored files." + ) + (defun vc-svn-checkout (file &optional editable rev) (message "Checking out %s..." file) (with-current-buffer (or (get-file-buffer file) (current-buffer)) diff --git a/lisp/vc/vc.el b/lisp/vc/vc.el index 210e647ba65..9757d4a43be 100644 --- a/lisp/vc/vc.el +++ b/lisp/vc/vc.el @@ -486,6 +486,7 @@ ;; default implementation always returns nil. ;; ;; - root (file) +;; ;; Return the root of the VC controlled hierarchy for file. ;; ;; - repository-hostname (dirname) @@ -496,6 +497,18 @@ ;; This function is used in `vc-stay-local-p' which backends can use ;; for their convenience. ;; +;; - ignore (file &optional remove) +;; +;; Ignore FILE under the current VCS. When called interactively and +;; with a prefix argument, remove an ignored file. When called from +;; Lisp code, if REMOVE is non-nil, remove FILE from ignored files." +;; +;; - ignore-completion-table +;; +;; Return the completion table for files ignored by the current +;; version control system, e.g., the entries in `.gitignore' and +;; `.bzrignore'. +;; ;; - previous-revision (file rev) ;; ;; Return the revision number that precedes REV for FILE, or nil if no such @@ -576,9 +589,6 @@ ;; ;; - deal with push/pull operations. ;; -;; - add a mechanism for editing the underlying VCS's list of files -;; to be ignored, when that's possible. -;; ;;;; Primitives that need changing: ;; ;; - vc-update/vc-merge should deal with VC systems that don't @@ -1332,11 +1342,57 @@ first backend that could register the file is used." (let ((vc-handled-backends (list backend))) (call-interactively 'vc-register))) -(defun vc-ignore (file) - "Ignore FILE under the current VCS." - (interactive "fIgnore file: ") - (let ((backend (vc-backend file))) - (vc-call-backend backend 'ignore file))) +(defun vc-ignore (file &optional directory remove) + "Ignore FILE under the VCS of DIRECTORY (default is `default-directory'). +When called interactively and with a prefix argument, remove FILE +from ignored files. +When called from Lisp code, if DIRECTORY is non-nil, the +repository to use will be deduced by DIRECTORY; if REMOVE is +non-nil, remove FILE from ignored files." + (interactive + (if (null current-prefix-arg) + (list (read-file-name "The file to ignore: ")) + (list + (completing-read + "The file to remove: " + (vc-call-backend + (vc-backend default-directory) + 'ignore-completion-table default-directory))))) + (let (backend) + (if directory + (progn (setq backend (vc-backend default-directory)) + (vc-call-backend backend 'ignore file directory remove)) + (setq backend (vc-backend directory)) + (vc-call-backend backend 'ignore file default-directory remove)))) + +(defun vc-default-ignore-completion-table (file) + "Return the list of ignored files." + ;; Unused lexical argument `file' + nil) + +(defun vc--read-lines (file) + "Return a list of lines of FILE." + (with-temp-buffer + (insert-file-contents file) + (split-string (buffer-string) "\n" t))) + +;; Subroutine for `vc-git-ignore' and `vc-hg-ignore'. +(defun vc--add-line (string file) + "Add STRING as a line to FILE." + (with-temp-buffer + (insert-file-contents file) + (unless (re-search-forward (concat "^" (regexp-quote string) "$") nil t) + (goto-char (point-max)) + (insert (concat "\n" string)) + (write-region (point-min) (point-max) file)))) + +(defun vc--remove-regexp (regexp file) + "Remove all matching for REGEXP in FILE." + (with-temp-buffer + (insert-file-contents file) + (while (re-search-forward regexp nil t) + (replace-match "")) + (write-region (point-min) (point-max) file))) (defun vc-checkout (file &optional writable rev) "Retrieve a copy of the revision REV of FILE. -- 2.39.2