Fork me on GitHub
#lsp
<
2024-05-27
>
didibus05:05:53

lsp-describe-thing-at-point is nice, but there's a pattern now in libs where you implement in a impl ns, and then you just do something like:

(def ^{:doc (-> #'impl/error? meta :doc)
       :arglists (-> #'impl/error? meta :arglists)}
  error?
  impl/error?)
In the public namespace. This will fail to find the doc if you call lsp-describe-thing-at-point

seancorfield05:05:27

I have never seen anyone do that -- but I would imagine LSP to fail to determine any dynamically added metadata since it is a static code analyzer and doesn't load/run the code. A pattern I have seen is to do the def and then as the next form, use alter-meta! to add in selected metadata from the impl ns -- but that would also fail to be seen in LSP.

didibus05:05:49

Ya, the alter-meta! is another option. I think it could be taught to recognize one or the other or both just with a hard-coded-ish pattern it can recognize.

didibus05:05:57

I never noticed, but I guess the clojure layer switched to lsp-describe-thing-at-point, where before it was cider-doc, the latter uses the REPL and picks up the real meta. I had notice for a while many things were missing doc for some reason when I looked it up in emacs, now I think it's due to this.

seancorfield05:05:30

In VS Code, you can choose the order of lookup: LSP first or REPL first. Can you do that in Emacs/CIDER?

seancorfield05:05:45

I have REPL then LSP:

didibus05:05:10

You can do anything you want in emacs 😛. Probably would need to write the function, or update the spacemacs layer to do it.

didibus05:05:01

But, that's good to know. So maybe it doesn't matter. If Calva does this by default, most people using the lib would see the doc, and if you're only using lsp, too bad maybe

seancorfield05:05:56

(just checked: default is repl,lsp like I have it, so yeah if folks have a REPL running and have loaded the file, they'll see the doc).

👍 1
didibus05:05:57

That'll do for now

didibus07:05:03

Another issue is that if you def a function from another namespace, the LSP auto-complete shows it as a Variable and not a Function.

Noah Bogart12:05:52

i believe alex miller has said this only accidentally works

seancorfield15:05:38

> Another issue is that if you def a function from another namespace, the LSP auto-complete shows it as a Variable and not a Function. That's another reason to use defn wrappers as opposed to any def trick...

didibus15:05:54

Ya, I guess I find the double fn call hop annoying. Macro work, and show as functions (for some reason, I guess lsp does not distinguish?), and I think that's cause it sees the :macro meta. But fn's don't have meta to indicate they are an fn, so I guess it relies on seeing defn/

didibus15:05:29

Hum, I guess I could defn it where it gets inlined

didibus15:05:30

It also gets annoying with overloaded arities 😄, I feel like there should be an official core solution to this, as this pattern of defining your public interface in a separate ns is becoming quite common. Is there an ask I can go upvote?

seancorfield15:05:44

Go look -- and create a new Ask if there isn't one.

seancorfield15:05:03

I consider it a feature, not a bug, so it wouldn't get my vote 🙂

didibus15:05:27

Why do you think that?

seancorfield16:05:49

Because I think it's better to use defn wrappers and explicit metadata (for API users), as I said. OTOH, you're convoluting things to avoid doing that, and then finding it doesn't work properly, and adding more complexity. There's a reason a lot of people think import-vars from Potemkin is a bad idea 🙂

didibus16:05:07

Ya, but if this was a core feature, it wouldn't be convoluted or break things. I don't find copy/pasting a feature. It can be a source of bugs as well, if I mess up an arity or forget one as I copy/paste. Or if I by mistake call the wrong impl function. I also don't find an extra unnecessary var lookup+function call a feature. Now even if I direct link, I've got an extra hop.