Fork me on GitHub
#emacs
<
2016-03-20
>
aiba01:03:59

When I create a new clojure file in emacs, it automatically puts a (ns foo.bar.baz) line at the top of the file. Cool. Unfortunately, the namespace path is wrong because my lein profile specifies custom :source-paths. Anyone know any emacs settings related to this? I'm not even sure if it's clojure-mode or cider or refactor-nrepl that is doing it.

malabarba04:03:58

Clj-refactor is adding the form. But I think it uses some function in clojure-mode to decide the namespace.

aiba05:03:59

@malabarba: Thanks, that’s very helpful! sure enough, (clojure-expected-ns) of clojure-mode.el returns the wrong ns. Now to see what that function is doing...

aiba05:03:39

OK, looks like clojure-expected-ns splits the path relative to project.clj or build.boot, then drops the first directory (usually “src”), then drops the next dir if it matches #"clj[scx]?”. So if your project’s :source-paths have “src“ or “src/clj” it works, but if it’s “src/client” or “src/server” then you get an extra “client.” or “server.” prefix to the generated namespaces.

aiba05:03:53

Not sure what could be done about this without knowing about the runtime classpath or build tool config

benedek07:03:34

Both cider-nrepl and refactor-nrepl know about the classpath. Perhaps an opportunity for a PR? ;)

benedek07:03:10

You can also opt out of this behaviour if I remember right..

benedek07:03:01

cljr-add-ns-to-blank-clj-files is the defcustom

aiba07:03:40

@benedek I like the behavior, just want the correct ns to be added simple_smile. I posted an issue with an idea for a kludgy fix on clojure-mode https://github.com/clojure-emacs/clojure-mode/issues/372

aiba07:03:44

It would be awesome if there was a way to use cljr’s or cider’s knowledge of classpath to do it better

benedek08:03:32

I agree. Check out cider-nrepl or refactor-nrepl. These would be right places. You can also find examples there which work with the classpath

aiba08:03:27

cool, i hacked together a function that returns the expected ns using cider classpath (please excuse the elisp, not as familiar with elisp as clojure):

aiba08:03:32

(defun clojure-expected-ns-from-classpath ()
  (let* ((file-path (buffer-file-name))
         (relpath (reduce (lambda (r p)
                            (let ((relpath (when (string/starts-with file-path p)
                                             (substring file-path (length p)))))
                              (cond ((not relpath) r)
                                    ((not r) relpath)
                                    ((< (length relpath) (length r)) relpath)
                                    (t r))))
                          (cider-sync-request:classpath)
                          :initial-value nil)))
    (when relpath
      (let* ((sans-type (substring
                         relpath 0 (- (length (file-name-extension relpath
                                                                        t)))))
             (ns (mapconcat 'identity (cdr (split-string sans-type "/")) "."))
             (ns (replace-regexp-in-string "_" "-" ns)))
        ns))))

aiba08:03:23

i’m not sure if this should belong in clojure-mode, cider, or cljr

benedek08:03:42

Clojure mode does not have a nrepl middleware component afaik. I would say cider but @bozhidar @malabarba may think otherwise

benedek08:03:45

re elisp: don't worry if you create a PR it will be reviewed in a nice way

benedek08:03:58

Btw nice work! :)

aiba08:03:04

Thanks! It’s fun learning some elisp, and also making me grateful I spend most of my time writing in clojure simple_smile

aiba08:03:08

Putting a function like this in cider makes sense. Then cljr could call cider-expected-ns rather than clojure-expected-ns.

benedek09:03:26

I guess if it is in cider, cider can take over this feature from cljr

benedek09:03:03

Again @bozhidar opinion will probably decide here :)

aiba09:03:51

Yeah, might be nice to retire the feature from clojure-mode in favor of cider.

aiba09:03:10

cljr could call cider’s insert-expected-ns rather than clojure-mode’s. (cider would know better what ns to insert)

bozhidar09:03:05

obviously clojure-mode has 0 knowledge about the classpath

bozhidar09:03:15

so doing a bit of guesswork

bozhidar09:03:21

was the best we could do

aiba09:03:40

Oh yeah makes total sense. i wonder how often clojure-expected-ns is used when there is not a cider connection present. Personally my only use case is cljr-add-ns-to-blank-clj-files.

benedek09:03:30

So @bozhidar would a classpath based feature make sense in cider?

benedek09:03:58

Or you rather have such a feature in cljr?

bozhidar10:03:26

yeah, it makes sense in cider

bozhidar10:03:55

as I mentioned on the ticket my only reservation is that such a feature might be useful for users of inf-clojure as well

bozhidar10:03:06

but I guess this is not a big concern

bozhidar10:03:40

I've a few times that I wouldn't mind moving simple useful features from cljr to clojure-mode and cider

bozhidar10:03:50

and this might be an opportunity to start doing so

aiba11:03:51

Awesome, I can submit a PR to cider. My only question is whether I get to use ->>, -map, and -filter. They help express this function and cljr uses them, but cider currently does not. Are these built into elisp or some dependency? (I assume we don’t want to add new dependencies to cider just for this)

bozhidar11:03:35

cider uses similar functions

bozhidar11:03:43

but the names are different

bozhidar11:03:50

->> is thread-last

bozhidar11:03:09

-map is mapcar or seq-map

bozhidar11:03:18

-filter -> seq-filter

aiba11:03:50

awesome, thanks!

bozhidar11:03:02

instead of reduce you should use seq-reduce

bozhidar11:03:14

basically seq.el is modern Elisp library

bozhidar11:03:30

that replaces both cl.el and dash.el

bozhidar11:03:33

and we rely on it

bozhidar11:03:56

most likely cljr will drop dash.el at some point as well

bozhidar12:03:50

when this is done you can move the relevant functionality to cider

benedek13:03:53

Sounds good