lsp

Harold 2025-11-19T16:14:02.445529Z

ooo - I just created a new file and the system added the right ns form for me automatically. Truly we live in a gilded age. 😀

😂 4
ericdallo 2025-11-19T16:15:05.244439Z

wait to see what you can do with https://clojure-lsp.io/features/#execute-command

JR 2025-11-19T18:18:05.195929Z

I'm working on the https://github.com/clojure-lsp/clojure-lsp/issues/2118 (slowly!). Question about the user experience: What if a user has a selection that straddles different depth expressions? For example (| is the beginning and end of the selection)

(defn e2 [x]
 (|let [y 1]
   (println "x,y:" (str x "," y))|)
 (println))
They've got the first println and its parent let, which are at different levels. Right now I'm promoting the expressions to be extracted up to be the entire let. But if it were
(defn e2 [x]
 (let [y 1]
   |(println "x,y:" (str x "," y)))
 (println)|)
then I'd extract the whole let and the last println. But should this sort of thing be allowed, or should all expressions be required to be at the same level? (more thoughts in thread)

JR 2025-12-05T01:17:06.323969Z

@ericdallo I submitted a draft pull request. It's only for you to review right now, I might have to do some more work. One issue is that this new extract-function requires changes to the client, so I created a new extract-function-2. That's not ideal, but I'm looking for your feedback. I've made the required changes to calva and they are working OK for me so far. https://github.com/clojure-lsp/clojure-lsp/pull/2169

JR 2025-11-19T18:19:56.926129Z

Ergonomically, it feels nice to aim my selection at the general area I want extracted. But... sometimes it can be surprising. And a selection that spans multiple defns would have to be disallowed I think.

ericdallo 2025-11-19T18:21:39.781239Z

yeah, I believe most users using this will know that is expected to select a valid range, so I'd go with that

👍 1
JR 2025-12-05T14:17:45.545689Z

I see that the Windows build failed on github with a AccessDeniedException, but it looks like at least some (that I checked) PRs fail for Windows with the same error

JR 2025-12-05T15:19:15.183069Z

This is the "Extract Function 2" running

ericdallo 2025-12-05T15:22:39.000889Z

hey @john.t.richardson.dev, that looks awesome! I'm a little bit busy this week but I will take a look at your PR and think on an approach for us to deliver that, meanwhile, maybe you can elaborate why we need changes on client just to make sure we should go with this approach and think how to offer as the default for users in a non breaking change way

JR 2025-12-05T15:53:12.173779Z

Sure, no rush. I should take some time to look at the emacs situation anyway. In the meantime... The issue in Calva is that it changes the default function name by changing the arguments array entry in the LSP communication. Here's what Calva is sending back when the original extract-function is invoked:

{
    "command": "extract-function",
    "arguments": [
        "file:///home/john/Projects/clojure-lsp/lib/src/clojure_lsp/refactor/mytest3.clj",
        15,
        2,
        "new-fn"    <--- arguments[3] is the new fn name, as changed by Calva in lsp-commands.ts
    ]
}
I'm not sure why it does this rather than "new-function" that clojure-lsp provides as the default:
(defn ^:private extract-function-action [uri line character]
  {:title   "Extract function"
   :kind    :refactor-extract
   :command {:title     "Extract function"
             :command   "extract-function"
             :arguments [uri line character "new-function"]}})
Anyway, my change adds two additional params, so the new function name is shifted down to position 5:
{
    "command": "extract-function-2",
    "arguments": [
        "file:///home/john/Projects/clojure-lsp/lib/src/clojure_lsp/refactor/mytest3.clj",
        15,
        0,
        16,
        19,
        "new-fn"   <--- now at argument[5]
    ]
}
So if I left it alone, it might overwrite the 16 above with the function name. I made some simple changes to Calva like this:
-      args[3] = command.defaultName;
+      args[command.namePosition ?? namePositionDefault] = command.defaultName;
This still hardcodes 3, and now 5. I think the Calva code could be simplified, but I'm not sure why it is the way it is. Maybe @pez could provide insight?

JR 2025-12-05T15:55:47.630739Z

Doh! I just realized I might be able to put the additional selection location arguments at the end of the list. This might work around the problem with the Calva client modifying the arguments array at a hardcoded position. I should try that!

ericdallo 2025-12-05T15:57:36.911519Z

Ah got it, the LSP arguments spec kinda sucks in that aspect, not being able to increase and improve a command Question: can we avoid a breaking change keeping the existing arguments order and just add new ones as the later? so we can in server control if that is a new extract-function or not keeping old behavior

ericdallo 2025-12-05T15:57:49.926669Z

ah yeah, that's what I meant :)

JR 2025-12-05T15:58:04.888069Z

Right, good idea. I'll look into it

ericdallo 2025-12-05T15:58:23.089649Z

thanks! looking good

JR 2025-12-06T20:02:56.338199Z

@ericdallo I got this working and yeah, no Calva changes are required now. Should I add a (perhaps undocumented?) feature flag to revert back to the old extract-function code, or should I just replace it?

ericdallo 2025-12-06T20:05:03.029389Z

That's awesome! I'm pretty ok to replace it if we add tests testitng old and new behavior

JR 2025-12-06T20:07:44.512099Z

OK. I've repurposed the existing extract-function tests and added a bevy of new ones. I'll send a new PR in a day or two. I just want to live with the changes for a few days myself.

ericdallo 2025-12-06T20:10:09.003789Z

Cool, Sounds like a good idea!

👍 1