Skip to content

Commit 4ef2b67

Browse files
committed
Implement -P, --pre-eval=CODE
1 parent 1b5321e commit 4ef2b67

File tree

5 files changed

+50
-1
lines changed

5 files changed

+50
-1
lines changed

CHANGELOG.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ https://github.com/eraserhd/rep/compare/v0.2.2...HEAD[Unreleased]
77
* Support for Mingw
88
* Test on aarch64-darwin and aarch64-linux
99
10+
=== Added
11+
12+
* `-P`, `--pre-eval` allows session initialization code which can do things
13+
like connect to a Piggieback REPL.
14+
1015
https://github.com/eraserhd/rep/compare/v0.2.1...v0.2.2[v0.2.2]
1116
---------------------------------------------------------------
1217

README.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ $ rep '(clojure.tools.namespace.repl/refresh)'
1515
:ok
1616
....
1717

18+
....
19+
$ rep -P '(cider.piggieback/cljs-repl :app)' '(.clear js/localStorage)'
20+
nil
21+
....
22+
1823
Unlike other nREPL clients, `rep` does not try to maintain a persistent
1924
connection, meaning that thread-local variables and bindings like `*e` and
2025
`*1` will not persist across invocations of `rep`. Perhaps there are

rep.1.adoc

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ connection, meaning that thread-local variables and bindings like `*e` and
4949
contains 'FNAME' and reads that file. The default is '@.nrepl-port@.',
5050
which will find the running nREPL if it was invoked by Leiningen.
5151

52+
*-P, --pre-eval*=CODE::
53+
CODE is evaluated in the new session before the main operation, and
54+
output (except errors) is discarded. This is useful to connect to
55+
ClojureScript REPLs, for example
56+
`--pre-eval='(cider.piggieback/cljs-repl :app)'`.
57+
5258
*--print*=KEY[,FD[,FORMAT]]::
5359
Print response messages with KEY in them to FD, using FORMAT. In FORMAT,
5460
`%{key}` prints *key* from the response message, `%%` prints a literal

rep.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,7 @@ struct options
605605
_Bool help;
606606
struct print_option* print;
607607
_Bool verbose;
608+
char* pre_eval;
608609
};
609610

610611
struct sockaddr_in options_address(struct options* options, const char* port);
@@ -761,7 +762,7 @@ enum {
761762
};
762763

763764

764-
const char SHORT_OPTIONS[] = "hl:n:p:v";
765+
const char SHORT_OPTIONS[] = "hi:l:n:p:v";
765766
const struct option LONG_OPTIONS[] =
766767
{
767768
{ "help", 0, NULL, 'h' },
@@ -770,6 +771,7 @@ const struct option LONG_OPTIONS[] =
770771
{ "no-print", 1, NULL, OPT_NO_PRINT },
771772
{ "op", 1, NULL, OPT_OP },
772773
{ "port", 1, NULL, 'p' },
774+
{ "pre-eval", 1, NULL, 'P' },
773775
{ "print", 1, NULL, OPT_PRINT },
774776
{ "send", 1, NULL, OPT_SEND },
775777
{ "verbose", 0, NULL, 'v' },
@@ -790,6 +792,7 @@ struct options* new_options(void)
790792
options->send = strdup("");
791793
options->print = make_default_print_options();
792794
options->verbose = false;
795+
options->pre_eval = NULL;
793796
return options;
794797
}
795798

@@ -881,6 +884,11 @@ struct options* parse_options(int argc, char* argv[])
881884
free(options->port);
882885
options->port = strdup(optarg);
883886
break;
887+
case 'P':
888+
if (options->pre_eval)
889+
free(options->pre_eval);
890+
options->pre_eval = strdup(optarg);
891+
break;
884892
case 'v':
885893
options->verbose = true;
886894
break;
@@ -926,6 +934,8 @@ void free_options(struct options* options)
926934
if (options->send)
927935
free(options->send);
928936
free_print_options(options->print);
937+
if (options->pre_eval)
938+
free(options->pre_eval);
929939
free(options);
930940
}
931941

@@ -1052,6 +1062,22 @@ int nrepl_exec(struct nrepl* nrepl)
10521062

10531063
nrepl_send(nrepl, "d2:op5:clonee");
10541064

1065+
if (nrepl->options->pre_eval)
1066+
{
1067+
struct print_option *original_print = nrepl->options->print;
1068+
nrepl->options->print = make_print_option("err,2,%{err}");
1069+
1070+
nrepl_send(nrepl, "d2:op4:eval7:session%lu:%s4:code%lu:%se",
1071+
strlen(nrepl->session), nrepl->session,
1072+
strlen(nrepl->options->pre_eval), nrepl->options->pre_eval);
1073+
1074+
free_print_options(nrepl->options->print);
1075+
nrepl->options->print = original_print;
1076+
1077+
if (nrepl->exception_occurred)
1078+
return 1;
1079+
}
1080+
10551081
char extra_options[512] = "";
10561082
if (nrepl->options->line != -1)
10571083
sprintf(extra_options + strlen(extra_options), "4:linei%de", nrepl->options->line);
@@ -1091,6 +1117,7 @@ Options:\n\
10911117
--no-print=KEY Suppress output for KEY.\n\
10921118
--op=OP nREPL operation (default: eval).\n\
10931119
-p, --port=ADDRESS TCP port, host:port, @portfile, or @FNAME@RELATIVE.\n\
1120+
-P, --pre-eval=CODE Evaluated first, e.g. (cider.piggieback/cljs-repl :app).\n\
10941121
--print=KEY|KEY,FD,FORMAT Print FORMAT to FD when KEY is present.\n\
10951122
--send=KEY,TYPE,VALUE Send additional KEY of VALUE in request.\n\
10961123
-v, --verbose Show all messages sent and received.\n\

test/rep/core_test.clj

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,9 @@
7474

7575
(facts "about the examples in the documentation"
7676
(rep "--op=ls-sessions" "--print=sessions,1,%{sessions,session=%.%n;}") => (prints #"^session=[a-fA-F0-9]{6}"))
77+
78+
(facts "about pre-eval code"
79+
(rep "--pre-eval=42" "(+ 2 2)") => (prints "4\n")
80+
(rep "--pre-eval=42" "(+ 2 2)") => (exits-with 0)
81+
(rep "--pre-eval=blergh" "(+ 2 2)") => (prints #"Unable to resolve symbol: blergh" :to-stderr)
82+
(rep "--pre-eval=blergh" "(+ 2 2)") => (exits-with 1))

0 commit comments

Comments
 (0)