Now with clojure-lsp
in, we can add some of the refactoring commands it makes available. Please help test https://9288-125431277-gh.circle-artifacts.com/0/tmp/artifacts/calva-2.0.138-pez-refactorings-2737e79b.vsix some, where these are added:
• ‘clean-ns’
• ‘add-missing-libspec’
• ‘cycle-coll’
• ‘cycle-privacy’
• ‘expand-let’
• ‘thread-first’
• ‘thread-first-all’
• ‘thread-last’
• ‘thread-last-all’
• ‘unwind-all’
• ‘unwind-thread’
I’ve noticed that clean-ns
is a bit crazy. See this issue: https://github.com/snoe/clojure-lsp/issues/217 and please add more clues/better repros if you too experience strange behaviour with this command.
Also noticing that expand-let
is even crazier some times. Will see if I can figure out a repro…
ref how :emacs: lsp-mode
call those: https://github.com/emacs-lsp/lsp-mode/blob/master/clients/lsp-clojure.el#L84-L162
Thanks! It is similar to how I call them:
type ClojureLspCommand = {
command: string,
extraParamFn?: () => Thenable<string>;
}
function makePromptForInput(placeHolder: string) {
return async () => {
return await vscode.window.showInputBox({
value: '',
placeHolder: placeHolder,
validateInput: (input => input.trim() === '' ? 'Empty input' : null)
})
}
}
const clojureLspCommands: ClojureLspCommand[] = [
{
command: 'clean-ns'
},
{
command: 'add-missing-libspec'
},
// This seems to be similar to Calva's rewrap commands
//{
// command: 'cycle-coll'
//},
{
command: 'cycle-privacy'
},
{
command: 'expand-let'
},
{
command: 'thread-first'
},
{
command: 'thread-first-all'
},
{
command: 'thread-last'
},
{
command: 'thread-last-all'
},
{
command: 'unwind-all'
},
{
command: 'unwind-thread'
},
{
command: 'introduce-let',
extraParamFn: makePromptForInput('Bind to')
},
{
command: 'move-to-let',
extraParamFn: makePromptForInput('Bind to')
},
{
command: 'extract-function',
extraParamFn: makePromptForInput('Function name')
}
]
function registerLspCommand(client: LanguageClient, command: ClojureLspCommand): vscode.Disposable {
const vscodeCommand = `calva.refactor.${command.command.replace(/-[a-z]/g, (m) => m.substring(1).toUpperCase())}`;
return vscode.commands.registerCommand(vscodeCommand, async () => {
const editor = vscode.window.activeTextEditor;
const document = util.getDocument(editor.document);
if (document && document.languageId === 'clojure') {
const line = editor.selection.active.line;
const column = editor.selection.active.character;
const params = [document.uri.toString(), line, column];
const extraParam = command.extraParamFn ? await command.extraParamFn() : undefined;
if (!command.extraParamFn || command.extraParamFn && extraParam) {
client.sendRequest('workspace/executeCommand', {
'command': command.command,
'arguments': extraParam ? [...params, extraParam] : params
}).catch(e => {
console.error(e);
});
}
}
});
}
Here’s a new VSIX with clojure-lsp refactorings added for introduce-let
, move-to-let
and extract-function
. The common theme for these is that they prompt for input to know what to bind to/name of new function. https://9293-125431277-gh.circle-artifacts.com/0/tmp/artifacts/calva-2.0.138-pez-refactorings-3c4b9247.vsix
Nice! we also have a custom command: server-info
which return some server info and settings user passed on startup, it's really useful for debugging 🙂
I noticed that. Will check out.
So, before I report this expand-let thing as an issue. Maybe it is just that I don’t know what it is supposed to do. If I expand-let
with the cursor in the let form here:
(fn [foo]
(let [state (create-state "# ")]
(is (cell-alive? state [0 0]))
(is-not (cell-alive? state [1 0]))
(is-not (cell-alive? state [-10 -20]))))
I get this:
(let [state (create-state "# ")]
[foo])
Whereas if I do not have any params in the fn
, like so:
(fn []
(let [state (create-state "# ")]
(is (cell-alive? state [0 0]))
(is-not (cell-alive? state [1 0]))
(is-not (cell-alive? state [-10 -20]))))
It does this:
(let [state (create-state "# ")]
(fn []
(is (cell-alive? state [0 0]))
(is-not (cell-alive? state [1 0]))
(is-not (cell-alive? state [-10 -20]))))
Hi all. Happy Christmas and thanks for Calva to all the team 🙂
I have a question about the debugger. I have a project using a dependency from a project in my local disk (Clojure source code). When I debug the code in Emacs (function instrumented) and I go IN the function I can step by step debug in the source code of the dependency
When I do the same in calva (F11) I cannot
The dependency is installed by lein install in the local .m2 maven cache
And the original source code is accessible. The behavior is different but both are installed in the same laptop...
Please file an issue with more details and we can look into it later. I think this should work. @seralbdev
Also note the dep, function trying to step into, and if this happens for any dep/function that you've tried.
Actually, your exact repro case would be best 😄
Issue filled in github => https://github.com/BetterThanTomorrow/calva/issues/893
curious about the outcome...thx a lot in advance!
Thanks!
Hi, yep I'll try to fill a description. I have realized that instrumenting the function of the dependency (apart from the one calling it in my main project) makes the Calva debugger allow step in and step by step debug it. If I am not wrong, this is not needed in Emacs and I can directly go in from the main project. I'll test this in more detail to be sure about both behaviors. Cheers!
The expand-let
code is kinda tricky, so it may be a bug indeed, the issue is that with args, it removes the fn
synbol, right?
It removes the fn symbol and all of the fn body.
oh, didn't notice it 😅 Yeah, a bug indeed, could you open a issue to track that? I'm working in other features/bug fixes ATM
Is it possible to customize the clojure formatter used? I’m wondering if I could swap for https://github.com/greglook/cljstyle.