Fork me on GitHub
#calva
<
2020-12-25
>
pez14:12:54

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.

💯 6
pez14:12:33

Also noticing that expand-let is even crazier some times. Will see if I can figure out a repro…

pez16:12:56

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);
                });    
            }
        }
    });
}

ericdallo16:12:47

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 🙂

pez17:12:41

I noticed that. Will check out.

pez17:12:51

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]))))

ericdallo21:12:44

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?

pez21:12:46

It removes the fn symbol and all of the fn body.

ericdallo21:12:13

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

pez00:12:08

Done. Now 💤 here. 😃

thanks 3
pez16:12:38

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

seralbdev18:12:38

Hi all. Happy Christmas and thanks for Calva to all the team 🙂

❤️ 6
calva 9
seralbdev18:12:29

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

seralbdev18:12:40

When I do the same in calva (F11) I cannot

seralbdev18:12:38

The dependency is installed by lein install in the local .m2 maven cache

seralbdev18:12:12

And the original source code is accessible. The behavior is different but both are installed in the same laptop...

bringe19:12:48

Please file an issue with more details and we can look into it later. I think this should work. @seralbdev

bringe19:12:48

Also note the dep, function trying to step into, and if this happens for any dep/function that you've tried.

bringe19:12:19

Actually, your exact repro case would be best 😄

seralbdev10:12:27

curious about the outcome...thx a lot in advance!

seralbdev19:12:36

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!

jstokes23:12:37

Is it possible to customize the clojure formatter used? I’m wondering if I could swap for https://github.com/greglook/cljstyle.