acid.nvim icon indicating copy to clipboard operation
acid.nvim copied to clipboard

Require/eval fails when the folder hierarchy isn't typical for a Clojure project

Open daveyarwood opened this issue 6 years ago • 7 comments

Since updating recently, I am no longer seeing evaluation results in the buffer. Running :AcidRequire and then using cpp to evaluate a form has no visible effect.

I noticed that when I press cqp to get the prompt, the namespace is incorrect. In this particular project, I have a frontend folder and a backend folder, and acid appears to be incorrectly prefixing the namespace with backend.:

;; should be `geir-backend.main-class`
backend.geir-backend.main-class=>

From /tmp/acid-log-handler.log:

2019-03-25 10:58:58,436 - [acid.nvim :DEBUG] - fpath is None
2019-03-25 10:58:58,439 - [acid.nvim :DEBUG] - Hitting cache for ns 'backend.geir-backend.main-class'
2019-03-25 10:58:58,443 - [acid.session :INFO] - sending data -> {'id': '46e7cf434bb8400da8c54f61634ade04', 'op': 'eval', 'code': "(require '[backend.geir-backend.main-class :reload :all])"}
2019-03-25 10:58:58,516 - [acid :INFO] - {'session': '502fc4e3-4dd6-48c8-aa92-fc22efde7c2f', 'root-ex': 'class java.io.FileNotFoundException', 'id': '46e7cf434bb8400da8c54f61634ade04', 'ex': 'class java.io.FileNotFoundException', 'status': ['eval-error']}
2019-03-25 10:58:58,520 - [acid.session :INFO] - stopped watching key 46e7cf434bb8400da8c54f61634ade04-d557c178c25946b6aa8c6ae79f3de6a9-watcher
2019-03-25 10:58:58,522 - [acid :INFO] - {'id': '46e7cf434bb8400da8c54f61634ade04', 'session': '502fc4e3-4dd6-48c8-aa92-fc22efde7c2f', 'out': '\x1b[1;31mjava.io.FileNotFoundException\x1b[m: \x1b[3mCould not locate backend/geir_backend/main_class__init.class, backend/geir_backend/main_class.clj or backend/geir_backend/main_class.cljc on classpath. Please check that namespaces with dashes use underscores in the Clojure file name.\x1b[m\n'}
2019-03-25 10:58:58,524 - [acid :INFO] - {'status': ['done'], 'id': '46e7cf434bb8400da8c54f61634ade04', 'session': '502fc4e3-4dd6-48c8-aa92-fc22efde7c2f'}
2019-03-25 10:58:59,939 - [acid.nvim :DEBUG] - fpath is None
2019-03-25 10:58:59,943 - [acid.nvim :DEBUG] - Hitting cache for ns 'backend.geir-backend.main-class'
2019-03-25 10:58:59,947 - [acid.session :INFO] - sending data -> {'ns': 'backend.geir-backend.main-class', 'id': '9439db61023a4c2aa6db6c36b93c2cbc', 'op': 'eval', 'code': '(def stop-server! (constantly false))'}
2019-03-25 10:59:00,008 - [acid :INFO] - {'status': ['namespace-not-found', 'done', 'error'], 'ns': 'backend.geir-backend.main-class', 'id': '9439db61023a4c2aa6db6c36b93c2cbc', 'session': '435fa752-561c-4403-ae00-6a7d9657cc54'}
2019-03-25 10:59:00,010 - [acid.session :INFO] - stopped watching key 9439db61023a4c2aa6db6c36b93c2cbc-b9cc3943c497474db87c2f381dd63996-watcher
2019-03-25 10:59:00,019 - [acid :INFO] - {'status': ['done'], 'id': '9439db61023a4c2aa6db6c36b93c2cbc', 'session': '435fa752-561c-4403-ae00-6a7d9657cc54'}

I tried doing the same thing in another project with a "standard" Clojure folder hierarchy, and there is no problem, so this appears to be a bug where acid uses the file path to determine the namespace name. I think it should probably parse the ns declaration at the top of the file instead?

daveyarwood avatar Mar 25 '19 15:03 daveyarwood

@daveyarwood Did you try to specify g:acid_alt_paths like following?

let g:acid_alt_paths = ['src/backend', 'src/frontend']

After telling your paths to Acid, :AcidRequire will work fine, I think.

However, I agree with your opinion that it is better to parse the ns declarations. :laughing:

rinx avatar Mar 26 '19 03:03 rinx

Parsing the file for the ns, when I wrote acid, was probably more complicated than figuring out with the paths. Take for example this top part of a clojure file:

;; TODO This file should be merged with sample.utils
(ns sample.tools)

Or this sample from eftest:

(ns ^:eftest/synchronized foo.core-test (:require [clojure.test :refer :all] [foo.core :refer :all]))

Or even a hypothetical poorly formatted file:

(
  ns something)

None of those would reliably give me a ns unless I parse/interpret clojure, which is something that feels very hacky to do in Python.

I can give another shot. I won't remove the path-based ns finding since this is the most reliable way (obviously, when everything is configured), but I'm open to suggestions for the cases above.

Cheers

hkupty avatar Mar 26 '19 05:03 hkupty

You can use nrepl to query for the classpath, and use that as your roots (after filtering out jars).

SevereOverfl0w avatar Mar 26 '19 12:03 SevereOverfl0w

@rinx Specifying let g:acid_alt_paths = ['src/backend'] did the trick! Thanks, it wasn't obvious that there was a config option for that.

@hkupty I see your point about parsing the ns form being complicated. Seems like there ought to be a better way. @SevereOverfl0w 's idea sounds promising!

daveyarwood avatar Mar 26 '19 13:03 daveyarwood

@SevereOverfl0w Could you elaborate? I like the idea of outsourcing to the nrepl.

hkupty avatar Mar 26 '19 13:03 hkupty

I think cider provides a classpath op, it will return a list which is the classpath. If you filter it to just directories, it should give you back a list like /home/dominic/project/src/backend etc. it will also include test, resources and anything else.

You may have a few false-positives (e.g. /home/dominic/.gitlibs/edge/foo.bar) but they don't really matter for calculating the ns that should be used.

SevereOverfl0w avatar Mar 26 '19 13:03 SevereOverfl0w

Amazing! I'll try that.

hkupty avatar Mar 26 '19 15:03 hkupty