clojure.contrib.repl-ln is a repl that supports lines and line
numbers. Here's a session that demonstrates it.
--Steve
% java -cp clojure.jar:clojure-contrib.jar clojure.main -e "(use
'clojure.contrib.repl-ln)" -e "(repl)"
1:1 user=> ; clojure.contrib.repl-ln provides a repl that supports
lines and line numbers in the input stream
1:2 user=> ; every input line is counted. Every input line that's not
within a clojure object generates a prompt
1:3 user=>
1:4 user=>
1:5 user=> ; even blank lines
1:6 user=> 1 2 3 ; multiple objects on one line are all printed, but
only produce one prompt
1
2
3
1:7 user=> jkl ; exceptions show the repl name and line number where
they happened
java.lang.Exception: Unable to resolve symbol: jkl in this context
(repl-1:7)
1:8 user=> (/ 1 0)
java.lang.ArithmeticException: Divide by zero (repl-1:8)
1:9 user=> (defn greet [] "
hello"
)
#'user/greet
1:12 user=> (meta (var greet)) ; metadata for definitions include repl
name and line number
{:file "repl-1", :line 9, :ns #<Namespace user>, :name
greet, :arglists ([])}
1:13 user=> ; the repl name is configurable. It defaults to: "repl-%S"
where %S is the repl serial number
1:14 user=> (repl) ; creating a new repl produces a nested repl with a
new serial number
2:1 user=> ; and a fresh set of line numbers
2:2 user=> ; the default prompt is "%S:%L %N=> ", serial number, line
number, and namespace name
2:3 user=> (in-ns 'cool)
#<Namespace cool>
2:4 cool=> ; quitting a repl pops namespace as well
2:5 cool=> ^D
nil
1:15 user=> (repl) ; creating a new repl produces a nested repl with a
new serial number
3:1 user=> ; if the prompt is too busy for your taste, you can set it
to something more familar:
3:2 user=> (set-repl-prompt "%N=> ")
nil
user=> (repl) ; nested repls inherit their name format and prompt
format from their parent
user=> ; this one is serial number 4, but if it's not in the prompt,
how can we know?
user=> (repl-info) ; repls have properties accessible this way
{:name "repl-4", :started #<Date Wed Dec 03 09:02:59 EST 2008>, :name-
fmt "repl-%S", :prompt-fmt "%N=> ", :serial 4, :thread 1, :depth
3, :line 2}
user=> (print-repl-info) ; or this way
Name: repl-4
Started: Wed Dec 03 09:02:59 EST 2008
Name-fmt: "repl-%S"
Prompt-fmt: "%N=> "
Serial: 4
Thread: 1
Depth: 3
Line: 3
nil
user=> ; thread id and nesting level are also available for use in the
prompt and repl name.
user=> ; a long running clojure could create many of them, say, over
sockets.
user=> (set-repl-prompt "%S:%T:%D:%L %N=> ") ; a big ol' prompt
nil
4:1:3:7 user=>
4:1:3:8 user=>
4:1:3:9 user=>
4:1:3:10 user=> (set-repl-name "clojure-%S:%T:%D")
nil
4:1:3:11 user=> kjd
java.lang.Exception: Unable to resolve symbol: kjd in this context
(clojure-4:1:3:11)
4:1:3:12 user=> ; end-of-stream (^D at the beginning of the line on
Unix/Mac OS X) quits the repl
4:1:3:13 user=> ^D
nil
user=> ^D
nil
1:16 user=> ^D
%
Yeah, I'm both nosey and impatient...
> clojure.contrib.repl-ln is a repl that supports lines and line
> numbers. Here's a session that demonstrates it.
Thanks. That looks pretty cool. Do I understand from your example that
if I just hit return I get another prompt? I've been meaning to ask for
that.
I'm curious how it interacts with rlwrap in general?
Also, does anybody know how gain any degree or kind of control over
signal handling in Java? Preferably pure Java, but since everything I do
is on Linux, a native-code solution for that platform would be
acceptable.
Rlwrap is quite nice, but aside from handling, say SIGINT (CTRL-C) for
its own purposes, it then passes that on to the wrapped program, and
that ends up just killing the JVM.
Anyway, this happened:
user=> (use 'clojure.contrib.repl-ln)
java.lang.IllegalArgumentException: No matching method: repl (repl_ln.clj:213)
The Clojure invocation I used was:
% java -cp /repo/JT/clojure-svn/clojure/clojure.jar:/repo/JT/clojure-svn/clojure-contrib/trunk/src:... \
clojure.lang.Repl
I'm running Clojure SVN 1141 on java version "1.6.0_10-rc2".
> --Steve
Randall Schulz
Thanks. That looks pretty cool. Do I understand from your example that
if I just hit return I get another prompt? I've been meaning to ask for
that.
I'm curious how it interacts with rlwrap in general?
Anyway, this happened:
user=> (use 'clojure.contrib.repl-ln)
java.lang.IllegalArgumentException: No matching method: repl (repl_ln.clj:213)
The Clojure invocation I used was:
% java -cp /repo/JT/clojure-svn/clojure/clojure.jar:/repo/JT/clojure-svn/clojure-contrib/trunk/src:... \
clojure.lang.Repl
Detailed, eh?
Anyway, that did it and I gotta' say, very cool. And so far it seems
there's no adverse interaction with rlwrap. I've modified my Clojure
launcher script to have an option for easy launching with this REPL.
Thanks again.
> --Steve
Randall Schulz
Not in a portable way, but if you're running a Sun JDK, there's
sun.misc.Signal and sun.misc.SignalHandler.
:dudley
Good information. Thanks.
Perhaps Steve would consider applying them to making his fancy REPL more
robust for terminal users?
> :dudley
Randall Schulz
Would it make sense to add a :gen-class declaration and have the -main function automatically call the repl function? This would make launching the repl less painful for new-comers.- Drew
I recently switched from JLine to rlwrap. I think the latter is
preferable, but I'm sure there are matters of taste involved.
> ...
>
> -- KD
Randall Schulz
Am 03.12.2008 um 18:24 schrieb Stephen C. Gilardi:
>> Would it make sense to add a :gen-class declaration and have the
>> -main function automatically call the repl function? This would make
>> launching the repl less painful for new-comers.
> It is a good idea and I'll work on it. What I do at the moment is have
> a small script that does what the "-e" commands do in my post. I give
> the path to that script as an argument to clojure.main.
I tried to trace down, what happens before we enter the Repl.
The only points I noticed were setting the namespace to user
and setting the command-line-args. I wrote a simple main to
do this. Patch attached. To be started with clojure.contrib.repl_ln.
Note: _ instead of -.
Sincerely
Meikel
I made the same switch. The big sell for me is support for vi
keystrokes in the REPL. I feel much more productive with rlwrap than
JLine.
--
R. Mark Volkmann
Object Computing, Inc.
I tried to trace down, what happens before we enter the Repl.
The only points I noticed were setting the namespace to user
and setting the command-line-args. I wrote a simple main to
do this. Patch attached. To be started with clojure.contrib.repl_ln.
Note: _ instead of -.
There are other things. E.g., JLine gets confused after suspending the
REPL (using SIGTSTP / CTRL-Z) and it does not support completion or (a
personal favorite) CTRL+LEFT-ARROW and +RIGHT-ARROW. Rlwrap also has
incremental search (CTRL-R and SHIFT+CTRL-R).
The only real down-side of CTRL+ARROW is that I get in the habit of
using them (previously only in BASH) and then out of habit I type them
in Vim, which causes bad things to happen...
Randall Schulz
Perhaps Steve would consider applying them to making his fancy REPL more
robust for terminal users?
I'm not acquainted with this, since Dudley's reply was the first I'd
heard of sun.misc.Signal et. al.
However, with that in hand I found what looks like a pretty good
tutorial / how-to article:
- Google: Ringlord "POSIX Signal Handling in Java"
"POSIX Signal Handling in Java"
<http://ringlord.com/publications/jsignals-howto/jsignals.pdf>
> --Steve
Randall Schulz
By the way, Sun excludes the sun.* packages from the JavaDoc HTML they
publish, so you'll have to generate it yourself or avail yourself of
whatever local tool / IDE / ingenuity you have to see the documentation
and / or source for these classes.
> However, with that in hand I found what looks like a pretty good
> tutorial / how-to article:
>
> - Google: Ringlord "POSIX Signal Handling in Java"
> "POSIX Signal Handling in Java"
> <http://ringlord.com/publications/jsignals-howto/jsignals.pdf>
RRS