Custom source path #152

wants to merge 6 commits into


None yet

5 participants


Added support for custom source path under the src and test directory. It fixes inserting/updating the namespace and switching between test and implementation if the project has a different source layout (e.g. sources in src/clojure and tests in test/clojure).

I'm a complete noob with elisp and this is only a first draft. Here are some thoughts I have:

  • clojure-source-nested-directory - need a better name (maybe clojure-path-inner-directory?) :(
  • Should clojure-source-nested-directory be defined with defvar instead of with defcustom? I don't think there's much use for it in the customization window. It's mainly for .dir-locals.el.
  • Is there a way to reject the configured value with some predicate? (e.g. make sure it starts with a "/" or not allow ".." in it?

I will happily invest more time in it if required. I need the functionality and I'll be happy to learn elisp :)



babysnakes added some commits Mar 28, 2013
@babysnakes babysnakes Insert and update ns now works for custom source paths.
It's possible to configure source and test inner directories to add
support for hierarchy like 'src/clojure' and 'test/clojure'. Currently
only works on inserting and updating ns.
@babysnakes babysnakes Jumping between test and code works for nested directories.
I think there are no more issues with custom source/test directories.
Time will tell :)
@babysnakes babysnakes Set clojure-source-nested-directory safe.
Hope it's ok :)

I too have needed this functionality. However, I can't help but think that maybe there's an easier way to do it.

Would there be a way to get the ns management code to detect this automatically? That might be better for working with multiple clojure projects simultaneously. I think at least for the jump functions it seems possible.


While I certainly don't object to having this automated, I couldn't think of a way to do it (actually I think my solution is far from elegant but I'm waiting for some indication that it's interesting to the maintainers before I invest more time in learning elisp).

In the meantime If you need to work on multiple projects (I do) just use .dir-locals.el file. Here's mine:

  (clojure-source-nested-directory . "/clojure"))
  (ffip-find-options . "-not -regex \".*node_modules.*\" -not -regex \".*target.*\" -not -regex \".*vendor.*\" -not -regex \".*resources/public/js/.*\"")))



I'm a maintainer. :)


clojure-mode is a clown car of maintainers




aha :)

In this case I'll start looking for a nicer solution. Any pointers?



I was just thinking that once you find the dominating file you have a left bracket, and you know that the right bracket is going to be the directories and file name derived from the namespace, so there should be a way to get that middle chunk.

So for example, if you have "/src/alice/src/clojure/alice/core.clj" finding the the dominating directory should get you "/src/alice/src/" and you know the namespace is alice.core, so you can get "alice/core.clj" and in between is this "clojure" thing. Taking the pieces you could then reassemble them as "~/src/alice/test/clojure/alice/core_test.clj" Perhaps this is all applicable only to the jump functions? And maybe your solution works better because it works for inserting/updating the namespace?

What do you think about this?


Well, for jumping between tests and implementation you're right. However, I constantly use the clojure-insert-ns-form and clojure-update-ns helpers and I would hate to lose this functionality. I can of-course do something more hybrid. I can use your idea for jumping between test and implementation, but if you want to insert and update functions to work you'll need to add setting for it. isn't this going to be too confusing?


Thanks for the contribution. I've tested out the code and I think it's good the way it is. I'm noodling over the name. Glad to hear any opinions.


Thanks. Before you accept it I want to change one thing. Currently its required to add "/" to the beginning of clojure-source-nested-directory setting. I want to extract the access to this setting to a function so it'll add a leading slash if one is missing. I'll do my best to make this change tomorrow.

As for the naming I'm terrible with names and on top of that, english is not my mother's tongue so please change the names to whatever you think it's appropriate.


babysnakes added some commits May 19, 2013
@babysnakes babysnakes Improved safe-local-variable predicate. 1eb8910
@babysnakes babysnakes Normalizing clojure-source-nested-directory.
Following advice from #emacs irc, I created a function with the same
name as the custom for accessing the normalized version of the
clojure-source-nested-directory value.


I've added 2 changes:

  • A better safe-local-variable function - Not allowing ".." in the path.
  • I've added a normalization function so it'll overcome missing or redundant slashes. Following an advice I got from the #emacs irc channel I called this function with the same name as the custom variable. If you modify the custom name please modify the name of the function as well.

Should I add some documentation for it in



Yes, please add some documentation to the README. Thanks!



I've added documentation. Please take a look at it and fix if required :)




This is great! Thanks. I had a similar issue but solved it by using eproject. You can easily configure eprojects to overwrite, e.g. clojure-test-implementation, for projects that use a different directory layout. . Use define-project-type to do so:

 (require 'clojure-mode)

 (require 'eproject)
 (define-project-type clojure (generic)
   (look-for ".clojure")
   :irrelevant-files ("target/" ".*" "lib/"))
 (add-hook 'clojure-project-file-visit-hook
                   (lambda ()
                      (setq clojure-test-implementation-for-fn 'clojure-test-implementation-for-mvn)
                      (setq clojure-test-for-fn 'clojure-test-for-mvn)))

You might want to change (look-for ".clojure") to something else, for instance (look-for "pom.xml"), and bind clojure-test-implementation-for-fn and/or clojure-test-for-fn to different lookup functions. Here it's bound to 'clojure-test-implementation-for-mvn that will lookup the sources and test-sources according to standard maven directory layout.



Sorry about this, but I've come to the conclusion that this functionality is better provided in a separate mode that can focus on doing one thing well rather than being bundled in clojure-mode; please see the discussion at #196.

@technomancy technomancy closed this Dec 2, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment