Skip to content

Commit

Permalink
Merge pull request #312 from expez/improve-clojure-expected-ns
Browse files Browse the repository at this point in the history
[Fix #310,#311] clojure-expected-ns with src/cljc
  • Loading branch information
bbatsov committed Jul 29, 2015
2 parents ba273c5 + 4be6843 commit 1fde668
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 12 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,7 @@

### Bugs fixed

* [#310](https://github.com/clojure-emacs/clojure-mode/issues/310) and [#311](https://github.com/clojure-emacs/clojure-mode/issues/311) Fix `clojure-expected-ns` in multi-source projects.
* [#307](https://github.com/clojure-emacs/clojure-mode/issues/307): Don't highlight `handle` and `handler-case` as keywords.

## 4.1.0 (20/06/2015)
Expand Down
37 changes: 25 additions & 12 deletions clojure-mode.el
Expand Up @@ -979,18 +979,31 @@ nil."



(defun clojure-expected-ns ()
"Return the namespace name that the file should have."
(let* ((project-dir (file-truename
(or (locate-dominating-file default-directory
"project.clj")
(locate-dominating-file default-directory
"build.boot"))))
(relative (substring (file-truename (buffer-file-name))
(length project-dir)
(- (length (file-name-extension (buffer-file-name) t))))))
(replace-regexp-in-string
"_" "-" (mapconcat 'identity (cdr (split-string relative "/")) "."))))
(defun clojure-project-dir ()
"Return the absolute path to the project's root directory."
(file-truename
(or (locate-dominating-file default-directory
"project.clj")
(locate-dominating-file default-directory
"build.boot"))))

(defun clojure-project-relative-path (path)
"Denormalize PATH by making it relative to the project root."
(file-relative-name path (clojure-project-dir)))

(defun clojure-expected-ns (&optional path)
"Return the namespace matching PATH.
PATH is expected to be an absolute file path.
If PATH is nil, use the path to the file backing the current buffer."
(let* ((relative (clojure-project-relative-path
(or path (file-truename (buffer-file-name)))))
(sans-file-type (substring relative 0 (- (length (file-name-extension path t)))))
(sans-file-sep (mapconcat 'identity (cdr (split-string sans-file-type "/")) "."))
(sans-underscores (replace-regexp-in-string "_" "-" sans-file-sep)))
;; Drop prefix from ns for projects with structure src/{clj,cljs,cljc}
(replace-regexp-in-string "\\`clj[scx]?\\." "" sans-underscores)))

(defun clojure-insert-ns-form-at-point ()
"Insert a namespace form at point."
Expand Down
53 changes: 53 additions & 0 deletions test/clojure-mode-util-test.el
@@ -0,0 +1,53 @@
;;; clojure-mode-util-test.el --- Clojure Mode: util test suite -*- lexical-binding: t; -*-

;; Copyright (C) 2014-2015 Bozhidar Batsov <bozhidar@batsov.com>

;; This file is not part of GNU Emacs.

;; This program is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation, either version 3 of the License, or
;; (at your option) any later version.

;; This program is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with this program. If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; The unit test suite of Clojure Mode

;;; Code:
(require 'clojure-mode)
(require 'cl-lib)
(require 'ert)

(let ((project-dir "/home/user/projects/my-project/")
(clj-file-path "/home/user/projects/my-project/src/clj/my_project/my_ns/my_file.clj")
(project-relative-clj-file-path "src/clj/my_project/my_ns/my_file.clj")
(clj-file-ns "my-project.my-ns.my-file"))

(ert-deftest project-relative-path ()
:tags '(utils)
(cl-letf (((symbol-function 'clojure-project-dir) (lambda () project-dir)))
(should (string= (clojure-project-relative-path clj-file-path)
project-relative-clj-file-path))))

(ert-deftest expected-ns ()
:tags '(utils)
(cl-letf (((symbol-function 'clojure-project-relative-path)
(lambda (&optional current-buffer-file-name)
project-relative-clj-file-path)))
(should (string= (clojure-expected-ns clj-file-path) clj-file-ns)))))

(provide 'clojure-mode-util-test)

;; Local Variables:
;; indent-tabs-mode: nil
;; End:

;;; clojure-mode-util-test.el ends here

0 comments on commit 1fde668

Please sign in to comment.