* 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-08-04 Xue Fuqiao <xfq.free@gmail.com>
+
+ * 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 <xfq.free@gmail.com>
* vc/vc-svn.el (vc-svn-ignore): Remove `interactive'. Use `*vc*'
(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")
(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.")
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")))
(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)
(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))
;; default implementation always returns nil.
;;
;; - root (file)
+;;
;; Return the root of the VC controlled hierarchy for file.
;;
;; - repository-hostname (dirname)
;; 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
;;
;; - 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
(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.