Skip to content

Commit

Permalink
improved custom REPL setup
Browse files Browse the repository at this point in the history
  • Loading branch information
juerg committed Jan 15, 2024
1 parent f6bd318 commit b96a083
Show file tree
Hide file tree
Showing 6 changed files with 131 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public DocGenerator(final boolean runExamples) {
null);

// make REPL specific functions available (e.g: 'repl/info')
final Env env = ReplFunctions.register(docEnv, null, null, false, ReplDirs.notavail());
final Env env = ReplFunctions.register(docEnv, null, null, null, false, ReplDirs.notavail());

this.diBuilder = new DocItemBuilder(
env,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ public DocSection section() {
dirs.addItem(diBuilder.getDocItem("repl/home-dir", false));
dirs.addItem(diBuilder.getDocItem("repl/libs-dir", false));

final DocSection config = new DocSection("Config", "repl.config");
all.addSection(config);
config.addItem(diBuilder.getDocItem("repl/prompt", false));
config.addItem(diBuilder.getDocItem("repl/handler", false));

return section;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,9 @@ private Env loadEnv(
.setStdinReader(in);

return ReplFunctions.register(
env, terminal, config, macroexpand, ReplDirs.create());
env,
this, terminal, config,
macroexpand, ReplDirs.create());
}

private PrintStream createPrintStream(final String context, final Terminal terminal) {
Expand Down
4 changes: 3 additions & 1 deletion src/main/java/com/github/jlangch/venice/impl/repl/REPL.java
Original file line number Diff line number Diff line change
Expand Up @@ -1231,7 +1231,9 @@ private Env loadEnv(
.setStdinReader(in);

return ReplFunctions.register(
env, terminal, config, venice.isMacroExpandOnLoad(), replDirs);
env,
this, terminal, config,
venice.isMacroExpandOnLoad(), replDirs);
}

private void reconfigureVenice(
Expand Down
131 changes: 114 additions & 17 deletions src/main/java/com/github/jlangch/venice/impl/repl/ReplFunctions.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,16 @@

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

import org.jline.terminal.Terminal;
import org.jline.utils.InfoCmp.Capability;

import com.github.jlangch.venice.IRepl;
import com.github.jlangch.venice.VncException;
import com.github.jlangch.venice.impl.env.Env;
import com.github.jlangch.venice.impl.env.Var;
import com.github.jlangch.venice.impl.javainterop.DynamicInvocationHandler;
import com.github.jlangch.venice.impl.types.Constants;
import com.github.jlangch.venice.impl.types.VncFunction;
import com.github.jlangch.venice.impl.types.VncJavaObject;
Expand All @@ -38,22 +41,26 @@
import com.github.jlangch.venice.impl.types.VncString;
import com.github.jlangch.venice.impl.types.VncSymbol;
import com.github.jlangch.venice.impl.types.VncVal;
import com.github.jlangch.venice.impl.types.collections.VncHashMap;
import com.github.jlangch.venice.impl.types.collections.VncList;
import com.github.jlangch.venice.impl.types.collections.VncOrderedMap;
import com.github.jlangch.venice.impl.types.util.Coerce;
import com.github.jlangch.venice.impl.util.ArityExceptions;
import com.github.jlangch.venice.impl.util.callstack.CallFrame;


public class ReplFunctions {

public static Env register(
final Env env,
final Terminal terminal,
final IRepl repl,
final Terminal terminal,
final ReplConfig config,
final boolean macroExpandOnLoad,
final ReplDirs replDirs
) {
Env e = env;
for(VncFunction fn : createFunctions(terminal, config, macroExpandOnLoad, replDirs)) {
for(VncFunction fn : createFunctions(repl, terminal, config, macroExpandOnLoad, replDirs)) {
e = registerFn(e,fn);
}
return e;
Expand All @@ -65,6 +72,7 @@ private static Env registerFn(final Env env, final VncFunction fn) {
}

private static List<VncFunction> createFunctions(
final IRepl repl,
final Terminal terminal,
final ReplConfig config,
final boolean macroExpandOnLoad,
Expand All @@ -73,11 +81,13 @@ private static List<VncFunction> createFunctions(
final List<VncFunction> fns = new ArrayList<>();

fns.add(createReplInfoFn(terminal, config));
fns.add(createReplRestartFn(terminal, config, macroExpandOnLoad));
fns.add(createReplRestartFn(config, macroExpandOnLoad));
fns.add(createTermRowsFn(terminal));
fns.add(createTermColsFn(terminal));
fns.add(createReplHomeDirFn(replDirs));
fns.add(createReplLibsDirFn(replDirs));
fns.add(createPromptFn(repl));
fns.add(setHandlerFn(repl));

return fns;
}
Expand Down Expand Up @@ -113,18 +123,30 @@ private static VncFunction createReplInfoFn(
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 0);

try {
return VncOrderedMap.of(
new VncKeyword("term-name"), new VncString(terminal.getName()),
new VncKeyword("term-type"), new VncString(terminal.getType()),
new VncKeyword("term-cols"), new VncLong(terminal.getSize().getColumns()),
new VncKeyword("term-rows"), new VncLong(terminal.getSize().getRows()),
new VncKeyword("term-colors"), new VncLong(terminal.getNumericCapability(Capability.max_colors)),
new VncKeyword("term-class"), new VncKeyword(terminal.getClass().getName()),
new VncKeyword("color-mode"), new VncKeyword(config.getColorMode().toString().toLowerCase()));
if (terminal != null) {
try {
return VncOrderedMap.of(
new VncKeyword("term-name"), new VncString(terminal.getName()),
new VncKeyword("term-type"), new VncString(terminal.getType()),
new VncKeyword("term-cols"), new VncLong(terminal.getSize().getColumns()),
new VncKeyword("term-rows"), new VncLong(terminal.getSize().getRows()),
new VncKeyword("term-colors"), new VncLong(terminal.getNumericCapability(Capability.max_colors)),
new VncKeyword("term-class"), new VncKeyword(terminal.getClass().getName()),
new VncKeyword("color-mode"), new VncKeyword(config.getColorMode().toString().toLowerCase()));
}
catch(Exception ex) {
throw new VncException("Failed to get the REPL terminal info", ex);
}
}
catch(Exception ex) {
throw new VncException("Failed to get the REPL terminal info", ex);
else {
return VncOrderedMap.of(
new VncKeyword("term-name"), new VncString("unknown"),
new VncKeyword("term-type"), new VncString("unknown"),
new VncKeyword("term-cols"), new VncLong(0),
new VncKeyword("term-rows"), new VncLong(0),
new VncKeyword("term-colors"), new VncLong(0),
new VncKeyword("term-class"), new VncKeyword("unknown"),
new VncKeyword("color-mode"), new VncKeyword("unknown"));
}
}

Expand All @@ -133,7 +155,6 @@ public VncVal apply(final VncList args) {
}

private static VncFunction createReplRestartFn(
final Terminal terminal,
final ReplConfig config,
final boolean macroExpandOnLoad
) {
Expand Down Expand Up @@ -183,7 +204,7 @@ private static VncFunction createTermRowsFn(final Terminal terminal) {
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 0);

return new VncLong(terminal.getSize().getRows());
return new VncLong(terminal == null ? 0 : terminal.getSize().getRows());
}

private static final long serialVersionUID = -1L;
Expand All @@ -209,7 +230,7 @@ private static VncFunction createTermColsFn(final Terminal terminal) {
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 0);

return new VncLong(terminal.getSize().getColumns());
return new VncLong(terminal == null ? 0 : terminal.getSize().getColumns());
}

private static final long serialVersionUID = -1L;
Expand Down Expand Up @@ -267,4 +288,80 @@ public VncVal apply(final VncList args) {
private static final long serialVersionUID = -1L;
};
}

private static VncFunction createPromptFn(final IRepl repl) {
return
new VncFunction(
"repl/prompt",
VncFunction
.meta()
.arglists("(repl/prompt s)")
.doc(
"Sets the REPL prompt string!")
.examples(
"(repl/prompt \"venice> \")")
.seeAlso(
"repl?", "repl/handler", "repl/info")
.build()
) {
@Override
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 1);

final String prompt = Coerce.toVncString(args.first()).getValue();

if (repl != null) {
repl.setPrompt(prompt);
}

return Constants.Nil;
}

private static final long serialVersionUID = -1L;
};
}

private static VncFunction setHandlerFn(final IRepl repl) {
return
new VncFunction(
"repl/handler",
VncFunction
.meta()
.arglists("(repl/handler f)")
.doc(
"Sets the REPL command handler!")
.examples(
"(do \n" +
" (defn handle-command [cmd] \n" +
" ;; run the command 'cmd' \n" +
" (println \"Demo:\" cmd)) \n" +
" \n" +
" (repl/handler handle-command)) ")
.seeAlso(
"repl?", "repl/prompt", "repl/info")
.build()
) {
@Override
@SuppressWarnings("unchecked")
public VncVal apply(final VncList args) {
ArityExceptions.assertArity(this, args, 1);

final VncFunction handlerFn = Coerce.toVncFunction(args.first());

if (repl != null) {
final Object handler =
DynamicInvocationHandler.proxify(
new CallFrame("proxify(:" + Consumer.class.getName() +")", args.getMeta()),
Consumer.class,
VncHashMap.of(new VncString("accept"), handlerFn));

repl.setHandler((Consumer<String>)handler);
}

return Constants.Nil;
}

private static final long serialVersionUID = -1L;
};
}
}
8 changes: 5 additions & 3 deletions src/main/resources/com/github/jlangch/venice/venice.venice
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

(load-module :gradlew)
(load-module :ansi)
(load-module :java)

(import :java.util.function.Consumer)
(import :com.github.jlangch.venice.EofException)
Expand Down Expand Up @@ -56,7 +57,7 @@
(defonce java-11-home (str/strip-end (system-env :JAVA_11_HOME) "/"))
(defonce java-home java-8-home)

(defonce sonatype-user "jlangch")
(defonce sonatype-user "xxxxxx")

(defonce cmd-line-prompt (str proj-name "> "))

Expand Down Expand Up @@ -294,8 +295,9 @@
(fatal-error-and-exit "The JAVA home '~{java-home}' does not exist!"))


(. *REPL* :setPrompt "shell> ")
(. *REPL* :setHandler (proxify :Consumer { :accept handle-command }))
;; configure the REPL
(repl/prompt "shell> ")
(repl/handler handle-command)

(display-welcome-msg)
(display-status)

0 comments on commit b96a083

Please sign in to comment.