Closed daslu closed 3 years ago
Interesting! A PR is welcome.
Related discussion: https://clojureverse.org/t/extending-calva-with-a-repl-function/
Maye a simple approach could be that the snippets for configuring the custom commands can have some "special character sequences" which get replaced by Calva before calling the snippet:
"calva.customREPLCommandSnippets": [
{
"name": "print-line-number",
"snippet": "(println $line)",
"repl": "clj"
},
]
For the case of notespace we would only need 2:
$line - current line number
$ns - current name space // true ? The notespace functions work on "*ns*"
-> a kind of editing context
https://github.com/scicloj/notespace/blob/a3758b631420d093ff2d342dd5ee3b98feba3905/emacs-config.el#L14 would become
{
"name": "eval-and-realize-note-at-line",
"snippet": "(notespace.api/eval-and-realize-note-at-line $line)",
"repl": "clj"
},
]
Not sure, if something else makes sense (current column ?, current xxx ?)
Somewho information on the current "state" of calva, which a Clojure function itself cannot get from nowhere else.
Not sure, if something else makes sense (current column ?, current xxx ?)
- current file name ?
- cider port ?
- cider host ? ...
It works in principle with a trivial change to Calva:
@@ -375,11 +375,13 @@ async function evaluateCustomCommandSnippetCommand(): Promise<void> {
saveAs: "runCustomREPLCommand"
});
if (pick && snippetsDict[pick] && snippetsDict[pick].snippet) {
- const command = snippetsDict[pick].snippet;
+ var command = snippetsDict[pick].snippet;
const editor = vscode.window.activeTextEditor;
+ var currentLine = editor.selection.active.line
const editorNS = editor && editor.document && editor.document.languageId === 'clojure' ? namespace.getNamespace(editor.document) : undefined;
const ns = snippetsDict[pick].ns ? snippetsDict[pick].ns : editorNS;
const repl = snippetsDict[pick].repl ? snippetsDict[pick].repl : "clj";
+ command = command.replace("$line",currentLine);
await evaluateInOutputWindow(command, repl ? repl : "clj", ns);
}
} catch (e) {
and a custom command setting like thgis:
{
"name": "eval-and-realize-note-at-line",
"snippet": "(notespace.api/eval-and-realize-note-at-line $line)",
"repl": "clj"
}
@daslu This change would be enough for all commands here: https://github.com/scicloj/notespace/blob/master/emacs-config.el
A namespace is not really needed. But it would be as well available in variable editorNS
.
Your example Emacs configuration saves as well the file.
VS code has a built-in autosave feature instead.
Both together would bring (nearly) the same notespace experience to Calva.
The custom commands can not be bound freely to keystrokes, but are all available as 'Ctrl-Alt-c 1 " 2 / 3 /...
@behrica that looks wonderful. I will try it soon.
@behrica this works beautifully.
It seems kind of analogous to the Cursive substitutions in REPL commands: https://cursive-ide.com/userguide/repl.html
@bpringe what do you think?
@behrica this works beautifully.
It seems kind of analogous to the Cursive substitutions in REPL commands: https://cursive-ide.com/userguide/repl.html
Indeed the same idea. But Cursive does not have "line number". But we took take inspiration from there, which substitutions can be useful, more general then for notespace only
Awesome, @behrica! Care to provide a PR with those changes? I can pick up the torch from here, but it is more fun if you PR it. 😄
I'm thinking all your suggestions are good. Maybe start with line
, column
, file
? And ns
for convenience? $1
-$9
for arguments that Calva will prompt for?
I also suspect Calva currently messes up *1
-*3
for the snippets. Would be nice to be able to use those reliably too.
I will do an initial change request, as you proposed. But I am an absolute beginner in Typescript / Javascript... (and Calva ...)
Do you have a preference for the "special character" to mark the text substitutions ? "$" vs "~" ?
It should be something, which is "impossible" to be part of any normal Clojure syntax. "$" is valid in Clojure to denote inner classes, while "~" is only valid as part of macro definitions.
So maybe "~" is even less likely to be used for an other purpose in the substitution.
I will document this as well somewhere then: https://github.com/BetterThanTomorrow/calva/blob/master/docs/site/custom-commands.md
Christmas comes early! 🎄 Awesome that you are planning to include docs. Both @bpringe and I will be ready to answer any Calva dev questions. Extra quickly if you're on the Clojurian Slack and the #calva
channel there. As for TypeScript, I'm no expert, but of course ready to help with those questions as well, should they arise. Not a total beginner, at least. 😄 Same goes for vscode. Also if you find gaps in the How to Hack on Calva stuff, please let us know. We truly want Calva to be contributor friendly.
As for special character. This is always tricky with templating, right? As for those two alternatives.
~
can be used outside macros, right? unquote-splicingMaybe go for something that is not just ”impossible”. Like 0_
, even if that could look a bit weird...
What I sometimes do is work Documentation first, so I write the docs and see if they make sense to me and others. Then implement. Maybe that could help here as well.
Another thing that has been bothering me regarding the snippets is that they are pretty cumbersome to write inside JSON settings. Would make more sense with an EDN file in the .calva
directory. But maybe that is stuff for a separate PR. 😄
@daslu This looks good to me, taking into account what @PEZ said above for the special character. We definitely don't want to have to change it later because of some conflict with Clojure, because that seems like an unavoidable breaking change.
Another thing that has been bothering me regarding the snippets is that they are pretty cumbersome to write inside JSON settings. Would make more sense with an EDN file in the .calva directory. But maybe that is stuff for a separate PR.
That's a good idea, but I agree, another PR. :smile:
Christmas comes early! Awesome that you are planning to include docs. Both @bpringe and I will be ready to answer any Calva dev questions. Extra quickly if you're on the Clojurian Slack and the
#calva
channel there. As for TypeScript, I'm no expert, but of course ready to help with those questions as well, should they arise. Not a total beginner, at least. Same goes for vscode. Also if you find gaps in the How to Hack on Calva stuff, please let us know. We truly want Calva to be contributor friendly.As for special character. This is always tricky with templating, right? As for those two alternatives.
- Would inner classes be used in snippets? (I don't know enough about it to have a guess)
~
can be used outside macros, right? unquote-splicingMaybe go for something that is not just ”impossible”. Like
0_
, even if that could look a bit weird...I propose to stick to the "$line".
In any case the subsitution sequence would be "$line", so a single "$" would not be touched.
This would mean, it only fails if somebody refers to a Java inner class which is called "line...." This is pretty unlikely to exist. On top it would fail with an obvious error message
Java naming conventions dictate that class names should begin with an upper case letter
How about people using things like $
and $something
for binding in as->
threading? Not sure if anything else but $
is used. In any case, this would be documented, and to instruct people to refrain from using such binding names in their snippet code is pretty OK, I think. I now vote for $line
, etcetera.
Thanks for your kind help, @PEZ @bpringe @behrica .
Many thanks for Calva!
Background (you can skip reading this part)
In the last few weeks, a few of us started using Notespace for literate programming. In Emacs+Cider, it is easy to interact with Notespace, as we can comfortably bind keys to Notespace API function calls, and even provide these calls with the important information of what line the cursor is in. We want to create a more complete Notespace story for Calva as well. This brings us to the following need.
A feature request
(f)
in the REPL, for a pre-configured functionf
.(f nsp line)
in the REPL, for a pre-configured functionf
, wherensp
andline
are external parameters passed by Calva, with the information of the current namespace and the current line where the cursor lies in the edited file.