Using local jar files with emacs clojure/cider mode and REPL - emacs

I'm trying to use functions from other jar files.
Creation of local jar file
I downloaded sample sources from the book Programming Clojure 2nd Ed, and created a jar file with lein jar command.
Use the local jar file
From the hints in this post, I copied the jar file in lib/ directory, then I could add
:resource-paths ["lib/programming-clojure-1.3.0.jar"] in the project.clj.
Test in REPL
With lein classpath command, I could check that the jar file is in class path.
With lein repl, I could use the functions in the jar file.
mire=> (require '[examples.introduction :as e])
nil
mire=> (take 10 examples.introduction/fibs)
(0 1 1 2 3 5 8 13 21 34)
Isses with emacs/cider
I created a t.clj source in the src/ directory, launched emacs with emacs src/t.clj &, and started REPL with M-x cider-jack-in.
I wrote this code, and executed it with C-x C-e.
(ns t
(:require '[examples/introduction :as ex]))
However, I got a message that the file is not found.
java.io.FileNotFoundException: Could not locate introduction__init.class or introduction.clj on
classpath:
What might be wrong?

The namespace is examples.introduction. Also, you don't need to quote the vector inside the ns macro. Try:
(ns t
(:require [examples.introduction :as ex]))
See some examples of use for the ns macro here.
Also, it's customary to have at least two segments in namespaces. Yours could be mynamespace.t for example.

Related

ASDF not finding package in custom directory

I'm new to Common Lisp, I'm using Emacs/SLIME on Windows 10, and I'm trying to wrap my head around how CL and ASDF/packaging works.
I have a custom package 'my-pack' in a directory 'D:\Dropbox\my-packages'.
I have created a .conf file in:
%LOCALAPPDATA%\config\common-lisp\source-registry.conf.d\
And added this line:
(:tree "D:\\Dropbox\\my-packages\\")
I opened Emacs, started SLIME and made the project via the REPL:
(cl-project:make-project #p"D:/Dropbox/my-packages/my-pack)
I verified that the project is in the directory and then loaded the system with asdf (version 3.3.1):
(asdf:load-system :my-pack)
And it worked fine.
But when I quit and restart Emacs, I get the following error when trying to the load the system:
Component :MY-PACK not found
[Condition of type ASDF/FIND-COMPONENT:MISSING-COMPONENT]
As far as I can tell I've followed the steps in the manual. Any help appreciated.
cl-project's make-project ends with this line:
(push dir asdf:*central-registry*)
it adds your new project's directory to this list that tells ASDF where to look for projects. What is its value when you restart CL?
2.
\config\common-lisp\
Shouldn't it be .config?
However, I don't encourage to use this conf file with :tree. The doc says:
tell ASDF to recursively scan all the subdirectories
So, imagine that just once, you try yourself at web development and you install, for example, JavaScript dependencies with npm or equivalent, you'll end up with a gigantic node_modules/ and your Lisp will now take a few seconds to start up.
I suggest to put your projects under ~/common-lisp/ or ~/quicklisp/local-projects, or to create symlinks, or to add yourself your projects in asdf:*central-registry* from your Lisp startup file:
;; .sbclrc
(pushnew "/home/me/projects/ciel/" asdf:*central-registry* :test #'equal)

On Using clojure.tools.namespace

In emacs cider repl, now I know how to use clojure.tools.namespace in a leiningen project. However, when I use it on a single clj file which doesn't belong to any project, it seems clojure.tools.namespace doesn't work on the file:
=> #<FileNotFoundException java.io.FileNotFoundException: Could not locate com/foo__init.class or com/foo.clj on classpath: >
I have declared clojure.tools.namespace in .lein/profile.clj and require it in the clj file. How should I make clojure.tools.namespace work on a single clj file?
My profile.clj
{:user
{:repl-options {:timeout 128000}
:plugins [;; REPL
[cider/cider-nrepl "0.9.0-SNAPSHOT"]
[refactor-nrepl "0.2.2"]
;; Application server
[lein-immutant "2.0.0-SNAPSHOT"]
;; Automated testing
[lein-cloverage "1.0.2"]
[lein-test-out "0.3.1"]
;; Package management
[lein-ancient "0.6.2"]
[lein-clojars "0.9.1"]
;; Documentation
[codox "0.6.8"]
[lein-clojuredocs "1.0.2"]
;; Static analysis
[lein-typed "0.3.4"]
;; [jonase/eastwood "0.1.2"]
[lein-bikeshed "0.1.6"]
[lein-kibit "0.0.8"]]
:jvm-opts ["-Dapple.awt.UIElement=true"]
:dependencies [[org.clojars.gjahad/debug-repl "0.3.3"]
[difform "1.1.2"]
[spyscope "0.1.4"]
[org.clojure/tools.trace "0.7.8"]
[org.clojure/tools.namespace "0.2.9"]
[im.chit/vinyasa "0.2.0"]
[slamhound "1.5.5"]
[criterium "0.4.3"]]
:injections [(require 'spyscope.core)
(require 'alex-and-georges.debug-repl)
(require 'com.georgejahad.difform)
(require '[vinyasa.inject :as inj])
(inj/inject 'clojure.core '>
'[[clojure.repl apropos dir doc find-doc pst source]
[clojure.tools.trace trace trace-forms trace-ns trace-vars
untrace-ns untrace-vars]
[clojure.test run-tests run-all-tests]
[clojure.pprint pprint pp]
[com.georgejahad.difform difform]
[alex-and-georges.debug-repl debug-repl]
[vinyasa.pull pull]])]}}
While this doesn't answer your specific question, it might provide some ideas on
alternative workflows which may help.
lein-exec This is a lein plugin that
lets you write clojure scripts or evaluate clojure expressions on the command line
in a similar way to what can be done with shells, python, ruby, perl etc. Of
course, startup time is a bit high, but this plugin will help you deal with
dependencies etc inside your single clj script file. (there are other possible
solutions to improve the startup speed). See this blog post for some examples
http://charsequence.blogspot.in/2012/04/scripting-clojure-with-leiningen-2.html
A scratch project. I have a fairly generic project called scratch. It just allows
me to create a new file within the src directory of the project which I can use for
experiments or demonstrations. For example, I have a file called stackoverflow.clj
within this scratch project which I use when working out the answer to a clojure
question on stack overflow. In fact, I have a lot of individual clj files in this
directory, each just representing a simple idea, test, experiment etc. It isn't
really a project i.e. I couldn't do a lein run at the root of the project and
expect anything meaningful. However, I can go to the source directory in emacs,
open a file and then run cider.

ENSIME not finding the correct project definition

I'm using an Emacs 24 snapshot on Ubuntu 12.04 with Scala 2.9.2 and ensime_2.9.2-RC1-0.9.3.RC4.
Basically I did the same thing as described in https://groups.google.com/forum/?hl=en&fromgroups#!topic/ensime/HvvvFr5gSwg
I generate .ensime file using sbt ensime generate.
I start ENSIME on Emacs with M-x ensime.
It parses all libraries and so on correctly (auto-complete works properly etc.)
However when I try to start the SBT console within Emacs using C-c C-v s, it displays the following error:
[info] Loading project definition from /home/ximyu/.sbt/plugins
[info] Updating {file:/home/ximyu/.sbt/plugins/}default-86f483...
[error] a module is not authorized to depend on itself: default#default-86f483;0.0
[error] {file:/home/ximyu/.sbt/plugins/}default-86f483/*:update:
java.lang.IllegalArgumentException: a module is not authorized to depend on itself: default#default-86f483;0.0
Obviously ENSIME is looking at the wrong directory for project definition. Instead of looking at my project directory it is actually looking at ~/.sbt. Any solution to this?
I have the same issue. I just started with ensime, so I don't really know why this is the case either. Also, my knowlegde on scala & ensime is very limited, so this is only a work-around to something that might be more obvious.
Anyway, this is the problematic ensime function:
(defun ensime-sbt-project-dir-p (path)
"Is path an sbt project?"
(or (not (null (directory-files path nil "\\.sbt$")))
(file-exists-p (concat path "/project/Build.scala" ))
(file-exists-p (concat path "/project/boot" ))
(file-exists-p (concat path "/project/build.properties" ))))
Basically ensime will use above function to search for a folder above the buffer where you hit C-c C-v s to determine the root project folder. As such, an easy fix is to simply add a (empty) .sbt folder into the folder that contains your .ensime project description.

How to use clojure doc function?

I'm just starting with Clojure and can't access to the doc function.
I'm using clojure 1.3 with emacs24 and swank-clojure.
user> *clojure-version*
{:major 1, :minor 3, :incremental 0, :qualifier nil}
But when I try:
(doc doc)
I get:
Unable to resolve symbol: doc in this context
[Thrown class java.lang.RuntimeException]
I've read Why does REPL treat clojure.core/doc as a var? and as suggested:
(clojure.repl/doc doc)
But then, I receive:
clojure.repl
[Thrown class java.lang.ClassNotFoundException]
It seems I am not "importing" the usual namespaces, but really doesn't know how to do it.
Thanks.
UPDATE
Using clojure from java (java -jar ...) it works well, so it's a problem with the emacs setup.
You need to grab the clojure.repl namespace one way or another:
From the REPL
user> (use 'clojure.repl)
user> (doc doc)
or in your program
(ns foobar
(:use [clojure.repl]))
Add the following to your Leiningen user.clj file (on Mac / Linux, it's ~/.lein/user.clj):
;; ~/.lein/user.clj
(if (>= (.compareTo (clojure-version) "1.3.0") 0)
(do (use 'clojure.repl)
(use 'clojure.java.javadoc)))
This will cause Leiningen to automatically import those two namespaces at startup for projects using Clojure 1.3.0 and later (but not for projects using Clojure 1.2.1 or earlier - where doc and source were always available).
Credit goes to Matthew Boston for this. Note also Phil Hagelberg's reply which points out most of the REPL-specific functionality is accessible directly in Emacs / Slime without needing the functions directly in the REPL.
As of Lein 2, namespaces can be automatically imported at startup using :injections, e.g:
;; ~/.lein/profiles.clj
{:user {:plugins [[lein-swank "1.4.4"]
[lein-noir "1.2.1"]
[lein-pprint "1.1.1"]]
:injections [(use 'clojure.repl)
(use 'clojure.java.javadoc)
(use 'clojure.pprint)] }}
But see other responses for SLIME equivalents.
I'm unsure of when this became the case, but as of lein 2.2 doc is available at the repl by default.

Error using Perforce within Emacs

I've obtained p4.el and put the following in my .emacs, running under cygwin:
(setq p4-executable "p4")
(load-library "p4")
p4.exe is the cygwin version.
On running M-x p4-info I get the following error:
/path/to/p4.exe: error while loading shared libraries: ?: cannot open shared object file: No such file or directory
Yet running M-! p4 info works fine. Probably I'm missing an env variable. Apologies if this is a basic question - I'm new to emacs.
Try adding (p4-set-p4-executable "/my/path/to/p4") to your .emacs.