Tutkain is a zero-dependency Sublime Text package for interactive Clojure development.
Note:
To start using Tutkain, you must:
If you already know how to start a Clojure socket REPL, you can jump straight to connecting to a socket REPL.
To start a socket REPL using the Clojure CLI tools:
Change to the root directory of your Clojure project:
cd /my/clojure/project
Run:
clj -J-Dclojure.server.repl="{:port 5555 :accept clojure.core.server/repl}"
To make it easier to start a socket server using Clojure CLI tools, you can add an alias like this your user profile in ~/.clojure/deps.edn
:
{:aliases
{:socket-repl {:exec-fn clojure.core.server/start-server
:exec-args {:name "server"
:port 5555
:accept clojure.core.server/repl
:server-daemon false}}}}
Then, to start a socket REPL, run:
clj -X:socket-repl
For more information on aliases, see the Clojure Deps and CLI Rationale.
Open ~/.lein/profiles.clj
in Sublime Text.
Under the :user
key, add a :socket-repl
entry like this:
{:user {:socket-repl {:jvm-opts ["-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"]}}}
Then, to start a socket REPL using Leiningen:
Change to the root directory of your Clojure project:
cd /my/clojure/project
Run:
lein with-profiles +socket-repl repl :headless
Note: Tutkain requires shadow-cljs v2.22.10 or newer.
To connect to a shadow-cljs socket REPL, you must start a shadow-cljs watch. You can start a shadow-cljs watch from the command line or from the REPL.
To start a shadow-cljs watch for build ID :app
from the command line with npx
:
Start the shadow-cljs watch from the command line:
npx shadow-cljs watch app
To start a shadow-cljs watch from the Clojure REPL:
Start a Clojure REPL with shadow-cljs in the classpath.
In the Clojure REPL, evaluate:
(require '[shadow.cljs.devtools.server :as server])
(require '[shadow.cljs.devtools.api :as shadow])
(server/start!)
(shadow/watch :app)
Note: Tutkain requires Babashka v1.1.171 or newer.
On the command line, to start a Babashka socket REPL, run:
bb socket-repl
There's now a Babashka socket REPL listening on port 1666.
Once you've started a socket REPL (see above), you can connect to it from Tutkain:
(Optional) In Sublime Text, open your Clojure project, either via File » Open or Project » Open Project.
Choose Tools » Command Palette.
Choose Tutkain: Connect.
Choose the type of socket REPL you want to connect to (Clojure, ClojureScript, or Babashka).
Enter the name of the host where your socket REPL server is running (by default, localhost
) and press Enter.
Enter the port number of the socket REPL server (for example, 5555) and press Enter.
If connecting to a shadow-cljs socket REPL, choose the shadow-cljs build ID you want to work on.
Wait for Tutkain to print your runtime version information into your REPL window in Sublime Text. For example:
Clojure 1.10.3
You can then start using Tutkain to evaluate code. If you're already familiar with another Clojure editor, you might want to jump straight into configuring key bindings instead.
You almost certainly want to configure a key binding to connect to a runtime instead of going through the command palette every time. For example, here's a key binding to connect to a Clojure runtime:
{
"keys": ["ctrl+c", "ctrl+x"],
"command": "tutkain_connect",
"args": {
"dialect": "clj",
"host": "localhost",
"port": 5555,
"output": "panel",
}
},
When you invoke this key binding, Tutkain immediately connects to a Clojure runtime listening on port 5555.
To do things like automatically require namespaces or set dynamic variables such as *print-length*
, you can use the init
argument to the tutkain_connect
command.
With the init
argument,you can pass the fully-qualified name of a function that accepts no arguments to have Tutkain call that function when it connects to a socket server.
For example, given this function in the classpath of your Clojure runtime:
(ns my.repl)
(defn init
[]
(require '[my.awesome.ns :as awyiss])
(set! *print-namespace-maps* false)
(set! *print-length* 16)
(set! *print-level* 8))
You can define a key binding that looks like this:
{
"keys": ["ctrl+c", "ctrl+x"],
"command": "tutkain_connect",
"args": {
"init": "my.repl/init",
// ...
}
},
Then, once you connect to a socket server using that key binding, Tutkain calls my.repl/init
.
If you use tools.deps, to add a function into the classpath of your Clojure runtime, you can add an alias like this into your ~/.clojure/deps.edn
:
:user {:extra-deps {my.repl/my.repl {:local/root "/Users/me/repl"}}}
Then, when you start the socket server for Tutkain to connect to, enable the :user
tools.deps alias.
For more information, see the Deps and CLI Guide.
Once you're connected to a socket REPL, you can start using Tutkain to evaluate code. You can evaluate code at a number of different scopes. Here's a list of the available scopes:
If you have text selected and use any of the first three scopes, Tutkain evaluates the selection instead.
Note: The examples that follow use the Tutkain: Evaluate command via the Sublime Text command palette. If you choose to continue using Tutkain, you ought to configure a key binding for every evaluation scope you find useful.
In a view that contains Clojure code, move your caret such that it immediately precedes or follows any form.
Note that a form is not necessarily an S-expression. For example, 42
is a form, but not an S-expression. (inc 42)
is both a form and an S-expression.
Open the Command Palette and choose Tutkain: Evaluate.
Choose Adjacent form and press Enter.
Tutkain prints the value of the form adjacent to your caret into the REPL view.
In a view that contains Clojure code, move your caret such that it immediately precedes or follows any S-expression.
An S-expression is anything surrounded by parentheses, brackets, or braces.
Open the Command Palette and choose Tutkain: Evaluate.
Choose Innermost S-expression and press Enter.
Tutkain prints the value of the S-expression that immediately precedes or follows your caret into the REPL view.
Here's how the Innermost S-expression scope determines what to evaluate:
In a view that contains Clojure code, move your caret such that it is anywhere on top of an S-expression.
Open the Command Palette and choose Tutkain: Evaluate.
Choose Outermost S-expression and press Enter.
Tutkain the value of the outermost S-expression into the REPL view.
The Outermost S-expression scope evaluates the form enclosed by the outermost set of brackets. There's one exception: if the outermost form is a (comment)
form, Tutkain evaluates the second-to-outermost form instead. For example, given a view like this:
(comment
(inc 41)
)
If your caret is anywhere on top of (inc 41)
, instead of (comment ,,,)
, Tutkain evaluates (inc 41)
. The reason for that is to support a common way of writing Clojure: writing forms inside a (comment)
form and evaluating them. No one ever wants to evaluate the (comment)
form itself.
Note: Tutkain does not currently support evaluating the active view for ClojureScript. As a workaround, you can select the entire view and use Tutkain: Evaluate » Outermost S-expression.
Evaluating the active view evaluates all code in the active view.
In a view that contains Clojure code, open the Command Palette and choose Tutkain: Evaluate.
Choose Active view and press Enter.
Tutkain prints the value of the last Clojure expression in the active view into the REPL view.
You can use Tutkain to evaluate every namespace declaration in the active view.
In a view that contains Clojure code, open the Command Palette and choose Tutkain: Evaluate.
Choose Namespace declarations and press Enter.
Tutkain evaluates every namespace declaration (ns
form) in the active view.
Instead of evaluating the entire form, you can use Tutkain to evaluate a form up to the point where the caret currently is.
For example, given that the pipe character (|
) represents the caret, and given:
(-> 1 inc| dec)
If you run tutkain_evaluate
with up_to_point
scope, Tutkain evaluates (-> 1 inc)
instead of the entire form.
If your caret is not inside an S-expression, up_to_point
evaluates every top-level form up to that point. For example, given:
(inc 1)
(inc 2)|
(inc 3)
If you run tutkain_evaluate
with up_to_point
scope, Tutkain evaluates (inc 1)
and (inc 2)
. This can be useful when you want to evaluate every top-level form in the namespace up to a certain point.
To evaluate code up to a point:
In a view that contains Clojure code, open the Command Palette and choose Tutkain: Evaluate.
Choose Up to Point and press Enter.
To mark a form and (repeatedly) evaluate it later:
Then, to evaluate the marked form:
Optionally, specify a key binding like this:
{
"keys": ["ctrl+a", "ctrl+a"],
"command": "tutkain_evaluate",
"args": {"scope": "mark"},
"context": [{"key": "selector", "operator": "equal", "operand": "source.clojure"}]
},
To have Tutkain ask you to input a Clojure form and evaluate it:
In Sublime Text, open the Command Palette.
Choose Tutkain: Evaluate.
Choose Input.
In the prompt that appears, type in some Clojure code and press Enter.
Tutkain prints the evaluation result in the REPL view.
Tutkain keeps a history the forms you evaluate using the Input scope. To browse the history, run Tutkain: Evaluate, select Input, and press the up or down arrow keys. The REPL history is transient; don't rely on it to save your history indefinitely.
In general, prefer using (comment)
forms and evaluating the outermost or the innermost S-expression over Tutkain: Evaluate Input. That way you can control whether to retain a permanent record of what you evaluate.
You can assign a key binding that lets you evaluate snippet of code. That is, you can write a snippet and have Tutkain ask you to fill in the blanks. For example, you can assign a key binding that lets you def
the symbol under the caret.
Here's a key binding that lets you do that:
{
"keys": ["ctrl+p", "ctrl+e"],
"command": "tutkain_evaluate",
"args": {"scope": "input", "snippet": "(def $FORMS[0] ${1})$0"},
"context": [{"key": "selector", "operator": "equal", "operand": "source.clojure"}],
},
When you invoke that key binding, this happens:
$FORMS[0]
with the value under the first caret.${1}
.When you press Enter, tutkain evaluates the snippet with all the blanks filled in.
Here's a video that demonstrates how this works:
When you evaluate Clojure code, you always do it in the context of a namespace. When you send a form for evaluation, before evaluating the form, Tutkain sets your current Clojure namespace to the namespace indicated by the first (usually only) ns
form in that view.
To disable automatic namespace switching, choose Tutkain: Edit Settings and set auto_switch_namespace
to false
.
Note: Tutkain currently does not support interrupting evaluations for ClojureScript.
To interrupt an evaluation, use Tutkain: Interrupt Evaluation.
When you do that, Tutkain calls the .interrupt
method on the REPL thread. That means you can only interrupt things that are explicitly interruptible.
In other words, Tutkain will not try to forcefully kill the REPL thread. For example, if you evaluate (range)
without doing (set! *print-length* 1024)
first, you'll have to restart your REPL.
The Tutkain: Prompt command opens an input panel at the bottom of the screen that prompts you for things to evaluate. It is intended to be used with nested clojure.main REPLs. For "regular" evaluation needs, you should continue to prefer comment
forms etc.
Note: Tutkain: Prompt is currently not compatible with using a panel for REPL output. If you need to use Tutkain: Prompt, you might want to use a regular view for REPL output instead.
By default, Tutkain prints evaluation output into the REPL output panel or view. You can tell Tutkain to show evaluation result inline; to copy evaluation result into the clipboard; or to replace the current selection with the evaluation results.
To show evaluation results inline, add a key binding for the tutkain_evaluate
command and set the output
arg to "inline"
. For example:
{
"keys": ["..."],
"command": "tutkain_evaluate",
// Evaluate the innermost form, show evaluation results inline
"args": {"scope": "innermost", "output": "inline"},
// Only enable this key binding in a Clojure context
"context": [{"key": "selector", "operator": "equal", "operand": "source.clojure"}]
},
Inline evaluation results currently have these limitations:
To have Tutkain copy evaluation results into the clipboard, define a key binding like this:
{
"keys": ["..."],
"command": "tutkain_evaluate",
"args": {
// ...
"output": "clipboard"
},
// ...
},
To have Tutkain replace the current selection with the evaluation result, define a key binding like this:
{
"keys": ["..."],
"command": "tutkain_evaluate",
"args": {
// ...
"output": "selection"
},
// ...
},
The selection
output is useful when you want to replace (random-uuid)
with its result, for example.
When you evaluate something that throws an exception, Tutkain only shows you the exception message.
To see the exception stack trace, evaluate *e
. You'll be using it often, so it's useful to assign a key binding to evaluate *e
. For example:
{
"keys": ["ctrl+c", "ctrl++"],
"command": "tutkain_evaluate",
"args": {"code": "((requiring-resolve 'clojure.repl/pst) *e)"}
}
When your evaluation throws an exception, you can use Tutkain: Explore Stack Trace to explore the stack trace for that exception (the current value of *e
).
When exploring the stack trace, Tutkain will also navigate to Java sources if it finds them. Tutkain looks for Java base module sources in $JAVA_HOME/src.zip
and $JAVA_HOME/lib/src.zip
. Alternatively, you can set the tutkain.java.src.zip
system property to point to the Java base module source ZIP file.
For Java dependencies, Tutkain will look for a file with the suffix *-sources.jar
next to the JAR file that contains the Java classes. If you have Maven installed, to download sources for all of the Java dependencies in your project, in the directory where your deps.edn
or project.clj
file is, run:
# with Clojure CLI
clj -A:my:aliases -Spom
# or with Leiningen
lein pom
# Then
mvn dependency:sources
You will have to redownload sources (run the mvn
command) again whenever you update your project dependencies.
Once you're connected to a socket REPL, you can run clojure.test tests directly from Tutkain. You can either run all tests in your current namespace or just the test that's under your caret.
deftest
form.Once the test run is complete, Tutkain adds markers into your view that indicate whether the test or assertion passed, failed, or caused an exception.
If a test assertion passes, Tutkain shows a green dot in the gutter on the left.
If a test assertion fails, Tutkain shows a red dot in the gutter on the left. In addition, Tutkain shows a link that says "diff" in the right-hand side of the view. If you click the link, Tutkain shows you a diff between the expected and the actual result of the assertion.
If your test throws an error, Tutkain shows an orange dot in the gutter on the left. In addition, Tutkain shows an orange outline around the test where the exception occurred. Tutkain also shows a link that says "show" in the right-hand side of the view. If you click that link, Tutkain shows you information about the exception.
After running tests, to show a list of all of the unsuccessful tests (tests that failed or threw an exception), use the Tutkain: Show Unsuccessful Tests command.
If you're not already familiar with ParEdit, the most useful command to get you started with editing Clojure is Tutkain: Expand Selection. It expands your current selection to include the entire form that's closest to your caret.
For example, given:
(dotimes [n 5] (println "Hello, world!"))
If your caret is on the left of [
and you run Tutkain: Expand Selection, Tutkain selects [n 5]
. If you run the command again, Tutkain expands the selection to cover the entire (dotimes ,,,)
form.
The easiest way to understand how Tutkain: Expand Selection works is to try it out. Run Tutkain: New Scratch View and paste some Clojure code into it. Then move your caret to different positions and run Tutkain: Expand Selection.
The basic rule is that the command first expands the selection to the nearest form. The next invocation expands to the innermost set of brackets, the next to next set of brackets, and so on until there are no more forms to expand to.
Tutkain comes with a ParEdit implementation. ParEdit is a tool that manages parentheses for you and adds commands for moving things in and out of brackets.
As of v0.12.0 of Tutkain, you must explicitly enable all ParEdit key bindings. At the very least, you probably want Tutkain to help keep your parentheses balanced. To do that, enable this set of key bindings.
Documentation for the Tutkain ParEdit implementation is forthcoming.
For now, see Dan Midwood's Animated Guide to Paredit and the fantastic Calva Paredit documentation for the kinds of things you can do with ParEdit. If you're already a dab hand at ParEdit, run Tutkain: Edit Key Bindings to see the ParEdit commands Tutkain supports.
Tutkain does its best to support multiple carets. That includes ParEdit. If you spot something that doesn't work, please file an issue.
When you're connected to a socket REPL and type something into a view that uses the Clojure syntax, Tutkain tries to guess what you want to type.
The completion list only suggests symbols your REPL knows about. Before you have evaluated anything, Tutkain typically only suggests symbols in the clojure.core namespace and possible other namespaces that Clojure has loaded when starting the REPL process.
Once you start evaluating things, Tutkain starts suggesting those things as well. Given a function like this:
(defn square
[n]
(* n n))
Once you evaluate that function using one of Tutkain's commands, Tutkain starts suggesting that function, too, when you type sq
.
Tutkain does no static analysis of your code. It is only aware of the current state of your REPL. If you restart your runtime, that state resets.
When you're connected to a runtime, move your caret onto a Clojure symbol or a keyword that names a Clojure spec, and use the Tutkain: Show Information command, Tutkain shows you the definition of that symbol or clojure.spec-naming keyword.
Tutkain only shows you the definition for symbols your REPL knows about. Before you have evaluated anything, Tutkain only shows definitions for symbols in the clojure.core namespace and possible other namespaces that Clojure has loaded when starting the REPL process.
Tutkain also supports navigating to the definition of a symbol. That includes Clojure symbols defined in the clojure.core namespace and other symbols your project depends on.
To navigate to the definition of a symbol, click the name of the symbol in the information popup.
You can (and probably should) assign a key binding for both information lookup and goto definition. Run Tutkain: Edit Key Bindings and look for tutkain_show_information
and tutkain_goto_definition
.
Tutkain comes with no key bindings enabled by default. This is to avoid key binding conflicts and to avoid interfering with other packages that offer the same functionality as Tutkain.
Important: Prior to v0.12.0 (alpha), Tutkain had a small number of key bindings enabled by default. v0.12.0 of Tutkain removes all of those default key bindings. For instructions on how to restore those key bindings, see the Package Control installation message for v0.12.0.
Instead, Tutkain comes with a set of example key bindings. You can pick and choose the key bindings you want to enable and adjust them to your liking.
To see the example key bindings, run the Tutkain: Edit Key Bindings command. Tutkain will open its list of example key bindings in the left-hand column and your current key bindings in the right-hand column. To take an example key binding into use, copy the key binding from the column on the left into the column on the right. Alternatively, to take the entire set of example key bindings into use, copy-paste everything from the left-hand column into the right-hand column.
A Sublime Text key binding looks like this:
{
"keys": ["ctrl+c", "ctrl+c"],
"command": "tutkain_evaluate",
"args": {"scope": "outermost", "ignore": ["comment"]},
"context": [{"key": "selector", "operator": "equal", "operand": "source.clojure"}]
},
The context
key specifies that you can only use the key binding in a view that uses the Clojure syntax.
The example key binding file Tutkain comes with has a section with commands you likely want to add key bindings for.
Feel free to change the key bindings themselves to whatever you feel comfortable with, of course.
After you're comfortable with using all of the above, you can configure key bindings for the rest of the commands (ParEdit commands in particular) as you go.
To have Tutkain indent your Clojure according to the rules outlined by Nikita Prokopov in his article Better Clojure formatting when you press Enter in a Clojure or ClojureScript view, add a key binding like this:
{
"keys": ["enter"],
"command": "tutkain_insert_newline",
"context": [
{
"key": "selector",
"operator": "equal",
"operand": "source.edn | source.clojure"
},
{
"key": "auto_complete_visible",
"operator": "equal",
"operand": false
},
{
"key": "panel_has_focus",
"operator": "equal",
"operand": false
},
]
},
To configure Tutkain to indent your code for you when you press Tab, add a key binding like this:
{
"keys": ["tab"],
"command": "tutkain_indent_sexp",
"args": {"scope": "outermost"},
"context": [
{"key": "selector", "operator": "equal", "operand": "source.edn | source.clojure"},
{"key": "auto_complete_visible", "operand": false},
{"key": "has_next_field", "operand": false},
]
},
If you want Tutkain to only indent the innermost S-expression in relation to your caret, use "scope": "innermost"
instead.
You currently cannot configure how Tutkain indents your code. Ideally, we'd have something like gofmt and you'd never need to think about it.
Until then, if you want your code indented differently, I suggest using something like SublimeLinter-contrib-joker or configure a Git hook for the Clojure formatter of your choice to indent your code after editing it.
When debugging Clojure code, you'll often want to know the value of a local or a global definition in certain context. A common approach is to use prn
(or equivalent) to print the value.
With Tutkain, you can also use tap>
to pretty-print a value. To do that, you must first set Tutkain's tap_panel
setting to true
. Once that's done, you can begin using tap>
for debugging.
For example, given a function like this:
(defn f
[x]
(tap> x)
,,,)
Now, whenever f
is called, Tutkain will pretty-print the value of x
in either a separate panel dedicated to tapped values or, if you're using a panel for REPL output, directly in your output panel.
Note: Connection modes require Tutkain v0.18.0 or newer. Connection modes only pertain to the Clojure and Babashka runtimes. ClojureScript connections always use the RPC mode.
By default, Tutkain operates over two connections: one for the REPL, and one for everything else. This lets you use things like nested REPLs with Tutkain.
However, if you need Tutkain to operate over a single connection (e.g. if you're connecting over an SSH tunnel), you can tell Tutkain to use a Remote Procedure Call (RPC) style to communicate with the runtime using a single connection.
To use the RPC mode, either:
default_connection_mode
to "rpc"
.Or add "mode": "rpc"
into your key binding. For example:
{
"keys": ["ctrl+c", "ctrl+x"],
"command": "tutkain_connect",
"args": {"mode": "rpc"}
},
Both the RPC and REPL connection mode have limitations.
(read)
and (read-line)
are not supported.By default, Tutkain prints evaluation results, standard input, and standard output into a Sublime Text output panel. You can also tell Tutkain to print them into a regular Sublime Text view instead. To do that, define a key binding like this:
{
"keys": ["ctrl+c", "ctrl+x"],
"command": "tutkain_connect",
"args": {"host": "localhost", "output": "view"}
},
The panel
setting is useful on smaller displays (like a laptop screen, for example), if you prefer using inline evaluation results, or if you prefer to use a separate tool like Tab, Reveal, Portal to display REPL output.
The view
setting is useful if you want to use a vertical layout, or if you never want to automatically hide the REPL output.
Here's a list of differences between using a view and a panel for REPL output:
tap_panel
setting enabled, Tutkain prints both REPL output and any values you tap>
in the same panel.When working with a Clojure Common (.cljc
) file, you can choose whether to use the Clojure or ClojureScript REPL for evaluating code.
By default, Tutkain evaluates Clojure Common files as Clojure. You can use Tutkain: Choose Evaluation Dialect to switch between Clojure and ClojureScript evaluation.
You can have multiple REPL views for each Sublime Text window.
When you evaluate code, Tutkain always sends your evaluation to the REPL view that has focus in your current Sublime Text window.
To use multiple REPL views:
Note: This feature requires Clojure 1.12.0-alpha2 or newer.
To add a new dependency into the runtime without having to restart it:
You can now use the dependency you added.
Note: This feature requires Clojure 1.12.0-alpha2 or newer.
To use a dependency you've added into deps.edn
without having to restart the runtime:
You can now use the dependency you added into deps.edn
.
To start a nested REPL via clojure.main/repl
and retain syntax highlighting in the REPL view, pass tutkain.repl/*print*
as the :print
option. For example:
(clojure.main/repl :print tutkain.repl/*print*)
Note: This feature is currently not supported for ClojureScript.
To search the current runtime for vars, functions, and macros whose name or docstring match a given pattern:
Tutkain will show you a quick panel with items that match the given regular expression. You can type into the quick panel to further filter the results.
Note: This feature is currently not supported for ClojureScript.
If your caret is on top of a symbol naming a var (e.g. clojure.set/project
), Tutkain lists all public vars in the namespace of that symbol (e.g. clojure.set
).
If your caret is not on top of a qualified symbol, Tutkain prompts you for the namespace whose public vars to list.
Tutkain will then show you a quick panel with information about the public vars in that namespace. You can type into the quick panel to further filter the results.
To list all libs that have been loaded into the runtime:
Tutkain will show you a quick panel with a list of all the libs loaded into the current runtime. You can type into the quick panel to further filter the results.
Note: This feature is experimental and subject to change or removal.
Starting from Tutkain v0.9.0 (alpha), if you have clojure.tools.analyzer.jvm (or clojure.tools.analyzer for ClojureScript) in your classpath, Tutkain will highlight local usages whenever you move your caret on top of a local. For example:
If you move your caret on top of x
, Tutkain highlights all usages of that local. You can also define a key binding to select all usages of a local. For example:
{
"keys": ["ctrl+x", "ctrl+r"],
"command": "tutkain_select_locals"
},
Once selected, to rename the local, type the new name.
To remove a namespace mapping (ns-unmap
):
To remove a namespace alias (ns-unalias
):
To remove a namespace:
To edit settings:
Tutkain is a tool I've made for myself. In the exceedingly unlikely event that you actually want to use it, you will inevitably find it lacking in one respect or another. Once that happens, feel free to open an issue or a pull request on GitHub.
I make no promises to implement the feature or merge your pull request. One of my main goals with Tutkain was to make it lightweight (for some value of lightweight), and I'd like to keep it that way.
You are, of course, always free to fork Tutkain and implement the feature yourself, if all else fails.
I recommend the wonderful Pep or SublimeLSP and clojure-lsp for static analysis.
Why?
I like Sublime Text. See also Rationale.
Nothing seems to work.
Tutkain only works with the Clojure syntax definition it ships with. To make sure you're using Tutkain's Clojure syntax definition:
If that doesn't fix the problem, please open an issue.
Why doesn't Tutkain support starting a REPL?
Integrating an editor with a Clojure build tool is hard. I don't think I really want to do it. Also, this way Tutkain is not tied to the build tool du jour. As long as it has a socket REPL server to connect to, it's happy.
Besides, when you start the socket REPL outside the editor, you can restart the editor without killing your REPL. Sublime Text is very good for people like me who like restarting their text editor a lot.
If you really want to start a socket REPL from Sublime Text, you can use a Sublime Text build system like this:
"build_systems": [{
"name": "tools.deps",
"cmd": ["clojure", "-X:socket-repl"],
"selector": "source.clojure",
"working_dir": "$folder",
"keyfiles": ["deps.edn"],
}]
Alternatively, use something like Terminus to run the tool of your choice in a terminal inside Sublime Text.
I get ERR: Not connected to a Clojure REPL
when evaluating from a ClojureScript file, even though I'm connected to a ClojureScript REPL.
Make sure the syntax of your current view is set to ClojureScript (Tutkain)
.
Tutkain has these aims:
When evaluating code, Tutkain operates on a plain character stream. That means that if you want to do things like start nested REPLs, Tutkain won't get in you way. Tutkain uses a separate channel for chatter related to editor tooling (auto-completion, interrupts etc.)
If you decide to give Tutkain a try, be prepared for breaking changes. That's in addition to the usual cavalcade of bugs you'll see in alpha-quality software.
Either open an issue or ask for help in the #tutkain channel over at the Clojurians Slack server.
For programming Clojure using Sublime Text, Clojure Sublimed is a great alternative.