Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Detect the root of Subversion checkouts. #291

Merged
merged 1 commit into from Mar 28, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion CHANGELOG.md
Expand Up @@ -26,7 +26,9 @@ for git projects.
bound to `C-c p 4 t`.
* New defcustoms `projectile-test-prefix-function` and `projectile-test-suffix-function`
allow users to customize how projectile identifies test files by project type.
* `projectile-grep` will ask for a file pattern if invoked with a prefix argument.
* `projectile-grep` will ask for a file pattern if invoked with a
prefix argument.
* Subversion checkouts are now automatically detected.

### Changes

Expand Down
53 changes: 43 additions & 10 deletions projectile.el
Expand Up @@ -424,19 +424,52 @@ Returns nil if no window configuration was found"


;;; Project root related utilities
(defun projectile-parent (path)
"Return the parent directory of PATH.
PATH may be a file or directory and directory paths may end with a slash."
(directory-file-name (file-name-directory (directory-file-name path))))

(defun projectile-locate-ancestor-containing (directory name)
"Look up the directory hierarchy, starting at DIRECTORY, for a directory containing NAME.
If multiple directories are found, return the parentmost (i.e. closest to /)."
(let ((current-dir-matches (file-exists-p (concat directory "/" name))))
(if (equal directory "/")
(if current-dir-matches
;; / contains NAME, so return this directory.
directory
;; / does not contain NAME, we're done.
nil)
(or
;; If there's an ancestor directory that contains this NAME, return it.
(projectile-locate-ancestor-containing
(projectile-parent directory)
name)
;; Otherwise, return this directory if it contains NAME.
(if current-dir-matches (file-name-as-directory directory))))))

;; In Subversion v1.7 only the root has a .svn directory, whereas
;; previously every subdirectory has a .svn directory. We support
;; both.
(defun projectile-svn-project-root (file)
"Find the root path of the Subversion repository that contains FILE."
(projectile-locate-ancestor-containing
(if (file-regular-p file)
(projectile-parent file)
(directory-file-name file))
".svn"))

(defun projectile-project-root ()
"Retrieves the root directory of a project if available.
The current directory is assumed to be the project's root otherwise."
(let ((project-root
(or (->> projectile-project-root-files
(--map (locate-dominating-file (file-truename default-directory) it))
(-remove #'null)
(car)
(projectile-file-truename))
(if projectile-require-project-root
(error "You're not in a project")
default-directory))))
project-root))
(or (->> projectile-project-root-files
(--map (locate-dominating-file (file-truename default-directory) it))
(-remove #'null)
car
projectile-file-truename)
(projectile-svn-project-root default-directory)
(if projectile-require-project-root
(error "You're not in a project")
default-directory)))

(defun projectile-file-truename (file-name)
"Return the truename of FILE-NAME.
Expand Down