Skip to content

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lsp-mode feature wishlist #515

Closed
yyoncho opened this issue Dec 7, 2018 · 134 comments
Closed

lsp-mode feature wishlist #515

yyoncho opened this issue Dec 7, 2018 · 134 comments

Comments

@yyoncho
Copy link
Member

yyoncho commented Dec 7, 2018

Update

Please use the discussion issue for the wishlist now: https://github.com/emacs-lsp/lsp-mode/discussions/2891

@innerout
Copy link
Contributor

innerout commented Dec 8, 2018

I believe that lsp-mode needs to enhance it's lsp-rename function because that will get Emacs closer to being a full featured IDE. For example we could get some ideas from what intellij provides.Also i think the flymake integration will be a huge + but i think that is closer to be complete as @yyoncho has started working on it.

@yyoncho
Copy link
Member Author

yyoncho commented Dec 8, 2018

@innerout can you elaborate on rename improvements?

@innerout
Copy link
Contributor

innerout commented Dec 8, 2018

An example from intellij
image
image
images taken from here https://www.jetbrains.com/help/idea/refactoring-source-code.html .
Also another interesting feature would be this https://www.jetbrains.com/help/idea/find-and-replace-code-duplicates.html .

@yyoncho
Copy link
Member Author

yyoncho commented Dec 9, 2018

@innerout we are limited by the lsp protocol and the language servers so features that are not supported by the server(s) are out of scope.

@kaiwk
Copy link

kaiwk commented Dec 12, 2018

Hey, thank you for the great work!

I think it's good to have a set of customization option and a better default, because some users may not need so much powerful functionality. For instance, most of them just want a fast way to completion, find references and maybe check doc. It's sure that we may turn on some options as default for user to test and whom really want to use.

It may too early to say that easy to configure is also an important feature, but it should be taken into consideration : )

@tam5
Copy link

tam5 commented Dec 12, 2018

Would have to be thought about a bit, but in light of the new session system, would be nice to be able to persist a session across emacs reboots.

I work on fairly large, enterprisey projects that take forever to get fully processed by my language server (php). Sometimes I end up restarting emacs for whatever reason, and then have to start the process all over again.

@tam5
Copy link

tam5 commented Dec 12, 2018

Getting started / specific language server installation instructions could be made more obvious, instead of making user go to specific language server docs, understand them properly, and then translate back to getting it to work with emacs.

For me, I generally like to just copy and paste instructions..

@tam5
Copy link

tam5 commented Dec 12, 2018

Not sure if this falls within lsp, or lsp-ui, or company, but:

Would be great to see parameter hints (and/or ability to auto-fill them) when completing with lsp.

For example, VsCode would do the following:

@yyoncho
Copy link
Member Author

yyoncho commented Dec 12, 2018

@kaiwk thanks for the suggestion. For now I will add quick start section similar to the one in https://github.com/emacs-lsp/lsp-java which you could just copy/paste and then start coding. We may investigate creating a meta package which joins all the packages that are needed for normal development similar to spacemacs layers. Also, if you have concrete proposals, please go ahead and file an issue or provide a PR.

@yyoncho
Copy link
Member Author

yyoncho commented Dec 12, 2018

@tam5

Would have to be thought about a bit, but in light of the new session system, would be nice to be able to persist a session across emacs reboots.

I work on fairly large, enterprisey projects that take forever to get fully processed by my language server (php). Sometimes I end up restarting emacs for whatever reason, and then have to start the process all over again.

can you elaborate a bit more? Unless there is a but the session should be persisted in lsp-session-file and then you won't be asked for root selection any more in any of the already imported projects, or you mean something else?

@yyoncho
Copy link
Member Author

yyoncho commented Dec 12, 2018

@tam5

Getting started / specific language server installation instructions could be made more obvious, instead of making user go to specific language server docs, understand them properly, and then translate back to getting it to work with emacs.

For me, I generally like to just copy and paste instruct

I believe we can do better: #506 . I will try to let lsp-mode directly consume the VSCode packages so you can just open the file and it will automatically download server, autoconfigure itself and so on.

About the signature feature: we have some code in, but I have never had a time to test it whether it works fine but in general this feature should work out of the box(currently it doesn't). Here it is a bug tracking the issue: #214

@tam5
Copy link

tam5 commented Dec 12, 2018

@yyoncho Awesome, thanks for your responses, and thanks for all your hard work!

I'll respond to the features that already seem to have issues in their rightful place, sorry for not searching first.

Regarding the session persistence:

The session is indeed persisted, to a degree, in the lsp-session-file which gives two very nice features regarding persistence:

  1. No more asking for project root
  2. Deleting all buffers within a project, does not shut down my language server, which is great

What I would like to potentially add:
Depending on some customization of course, when exiting emacs, do not shut down my language server. This way, I can come right back to emacs and continue my work without waiting for my language server to boot up and do all its file parsing.

This would mean preventing shut down of language server on exit, as well as reconnecting to the existing server on startup.

The only issue I see is potentially having dangling language server processes if they are not cleaned up properly.

@yyoncho
Copy link
Member Author

yyoncho commented Dec 12, 2018

Depending on some customization of course, when exiting emacs, do not shut down my language server. This way, I can come right back to emacs and continue my work without waiting for my language server to boot up and do all its file parsing.

I believe that this is not feasible due to multiple reasons - in general re-connection is not possible in LSP protocol, Re-connection to STDOUT is not technically possible(or at least I don't know how to do that). The only way to implement this feature is either to have some kind of server support for that or implement a proxy in front of the language server which is separate project itself.

@yyoncho yyoncho closed this as completed Dec 12, 2018
@yyoncho yyoncho reopened this Dec 12, 2018
@innerout
Copy link
Contributor

innerout commented Dec 13, 2018

You can read stdout and write to stdin of any process if you know its pid.

For stdin

cat main.c > /proc/<pid>/fd/0

For stdout

tail -f /proc/<pid>/fd/1

@tam5
Copy link

tam5 commented Jan 9, 2019

Here's another one:

Would it be possible to generate doc-blocks (i.e. be able to read a method signature and insert proper doc block including relevant things like param names/types, return type, etc. ?

There are different styles and conventions for this, so I'm not sure how the customization of that would be handled.

@blasut
Copy link
Contributor

blasut commented Jan 11, 2019

Making a mode for show-documentation-at-point and maybe other future "transient" or "help" buffers. That way we can create key-maps for the help-buffers.

@yyoncho
Copy link
Member Author

yyoncho commented Jan 11, 2019

@tam5
for doc-blocks we should have support from the server. For example, JDT LS supports them although it is not exposed in lsp-java. If you want that functionality for particular language go and file a bug on the server side and then we can expose in lsp-mode.

@blasut
Make sense - in general, doc buffers functionality is not polished(e. g. links does not work all the time). Currently, we are using view-mode and I have bound q to exit it.

@yyoncho yyoncho pinned this issue Mar 8, 2019
@yyoncho yyoncho unpinned this issue May 19, 2019
@vibhavp vibhavp pinned this issue Jun 30, 2019
@muffinmad
Copy link

According to specification rootPath and rootUri can be null on initialization request if no folder is open.

It allows to open the file in the home folder and not make lsp server to treat home folder as a project.

Is it possible with lsp-mode?

@yyoncho
Copy link
Member Author

yyoncho commented Jul 9, 2019

@muffinmad currently we do not support that. IIRC some of the servers crash if there is no associated project(e. g. rls) so before jumping into implementing this we should investigate whether the servers are following the spec.

Can you share your usecase?

@muffinmad
Copy link

I want to be able to open files outside project directory.
Opening ~/test.py and passing home folder as rootPath makes Microsoft pyls analyze my whole home folder which is little annoying.

@seagle0128
Copy link
Collaborator

@muffinmad Did you try (setq lsp-auto-guess-root nil)?

@yyoncho
Copy link
Member Author

yyoncho commented Jul 9, 2019

@muffinmad I tested mspyls and it works fine if you do not pass rootUri/root in initialization options. We have to figure out what should be the flow to enable this feature. In vscode the folder selection is not interactive and user has to add the folders upfront in order to start the language server for that folder. We could have a setting which enables that same behaviour in lsp-mode or we could have a different flow like -

"Add one more option to lsp menu which will be - Connect/start rootless language server."

This flow will work, but the result will be that you will be asked that question each time you open a file and you do not want to add it as a root(which btw could be avoided by adding a dir local variable which will mark the files in the directory as rootless).

WDYT?

@seagle0128

@muffinmad Did you try (setq lsp-auto-guess-root nil)?

This will start a language server in the home dir or it won't start a server at all. I think that OP is looking for different solution.

@muffinmad
Copy link

@seagle0128 After setting lsp-auto-guess-root to nil lsp gives me options to:

  • do nothing
  • blackist folder and do nothing
  • run server but pass some folder as rootPath

So it's lsp-mode in first place who won't let me go without specifying the project :)

@muffinmad
Copy link

@yyoncho How about not to require project but give option to specify it if user not satisfied with one guessed by lsp-mode?

I think the question that lsp asks first is little discouraging.
I'm opening file in VC controlled project and Emacs asks me "foo.py is not part of any project. Select action: ". After hitting TAB I see that project is guessed correctly in the first completion option: "add ~/workspace/project/ to blacklist".

What about this:

  1. Make lsp-mode-default-get-root-function function which will:
  • Look for some variable like lsp-mode-project-root. It can be set in .dir-locals.el
  • Try determine project by project-current, some-projectile-function, etc.
  • Here can be option like lsp-mode-ask-if-no-project. If it is set then ask question about project root else nil or default-directory
  1. Make customizable variable like lsp-mode-get-root-function so user can (cdr (project-current)) instead of default one

This way new lsp-mode users will recieve working lsp server instantly.
And there will be options to configure some exotic project roots :)

@mohkale
Copy link
Contributor

mohkale commented Jan 10, 2021

@yyoncho Thanks for pointing me to it (I kept trying to check for a command like lsp.*help.* but couldn't find this command). Binding [remap display-local-help] 'lsp-describe-thing-at-point in lsp-mode-map is a decent workaround. Of course the *lsp-help* buffer doesn't update as you move around the original buffer and eldoc is still active which doesn't make it a perfect translation, but it's a good workaround. Thank you.

@laurynas-biveinis
Copy link
Contributor

Is there any way to get automatic formatting for yanked regions but never their surroundings?

Now it seems there are two suboptimal options:

  • turn off lsp-enable-indentation, paste (unformatted), fix up if needed, reformat the whole buffer or defun with a keyboard shortcut, or
  • turn on lsp-enable-indentation, paste, observe in the case of the region having i.e. a missing trailing semicolon, that its surroundings are reformatted in ugly ways that will need undoing.

Is it possible to have lsp-enable-indentation that never reformats outside of the yanked region?

@nbfalcon
Copy link
Member

nbfalcon commented Mar 7, 2021

@laurynas-biveinis I've been working on a package to do various "smart" editing, but it is currently not on github:
The following function will do what you want

(defun smartedit-yank-with-indent (&optional arg)
  (interactive "*P")
  (let ((start (point)))
    (yank arg)
    (indent-region start (point))))

@rakllie
Copy link

rakllie commented Apr 2, 2021

It would be nice if lsp-mode has a command to choose from available clients for current session.
Currently it seems that we can only do that by changing lsp-clients variable manually?

@yyoncho
Copy link
Member Author

yyoncho commented Apr 2, 2021

Currently it seems that we can only do that by changing lsp-clients variable manually?

You can use M-x customize-variable and set lsp-enabled-clients/lsp-disabled-clients.

@rakllie
Copy link

rakllie commented Apr 2, 2021

Currently it seems that we can only do that by changing lsp-clients variable manually?

You can use M-x customize-variable and set lsp-enabled-clients/lsp-disabled-clients.

Thanks, that's much more convenient!
I still think offering an interactive command to choose clients for current session is worth considering though, since it's easier to discover.

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

This is less a feature suggestion and more a request for help but here goes anyways.

In my config I've got a option that I use to decide whether to start a language server or not in a new buffer (based on whether or not one is already running):

(defvar +lsp-maybe-connect `((python-mode . :global)
                             (sh-mode . nil)
                             (t . :local)))

So with this setup if I open any new python buffers, lsp-mode is enabled only when my lsp server (pyls) is running in any workspace managed by emacs. If no server is running lsp-mode isn't enabled. With sh-mode it's never automatically connected and instead you have to always manually connect. And with any other modes you connect if there's a server already running in the current workspace.

I have some predicates setup for eglot (eglot-mode-server-p+, eglot-mode-server-all-p+) to check these conditions, and I'd like to have equivalent ones for lsp-mode.

So could someone help me implement a function to check whether a server needed by a given major-mode is currently running in the current workspace or any workspace?

@yyoncho
Copy link
Member Author

yyoncho commented Apr 4, 2021

@mohkale

(lsp--filter-clients
                             (-andfn #'lsp--matching-clients?
                                     #'lsp--server-binary-present?))

This will give you the clients that match the current file.

(lsp-session) structure contains the info for all running servers.

(lsp-workspace-root) will give the project root for the current file.

Ping us here, gitter/discord if you need more help.

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

@yyoncho

Thank you for the help, managed to get what I needed working 😄.

(defun lsp-mode-server-exists-p+ (mode &optional all-workspaces)
  (when (buffer-file-name) ; Needed for lsp--matching-clients?
    (let ((major-mode mode))
      (seq-intersection
       (lsp--filter-clients #'lsp--matching-clients?)
       (when-let ((workspaces
                   (if all-workspaces
                       (-flatten (hash-table-values (lsp-session-folder->servers (lsp-session))))
                     (gethash (lsp-workspace-root) (lsp-session-folder->servers (lsp-session))))))
         (mapcar #'lsp--workspace-client workspaces))
       #'equal))))

(defun lsp-mode-server-p+ (mode)
  (lsp-mode-server-exists-p+ mode))

(defun lsp-mode-server-all-p+ (mode)
  (lsp-mode-server-exists-p+ mode t))

I do seem to be running into some annoying eldoc issues with lsp-mode. It seems lsp-mode aggressively clears the eldoc echo area even when there's nothing new for it to show. For example I goto a python buffer in a comment. Eldoc shows nothing, I run M-: (* 5 10) and the result flashes briefly before it's immeaditely cleared (I suspect by lsp-mode). eglot on the other hand doesn't seem to ever clear the echo area itself, which I actually prefer. Is there a way to change this behaviour.

Eldoc also appears to be slightly slower than eglot, as in there's a slight lag from when I move point to when an eldoc message shows up. It can't be no more than a fraction of a second although I'd rather not have the delay if possible.

@yyoncho
Copy link
Member Author

yyoncho commented Apr 4, 2021

I do seem to be running into some annoying eldoc issues with lsp-mode. It seems lsp-mode aggressively clears the eldoc echo area even when there's nothing new for it to show. For example I goto a python buffer in a comment. Eldoc shows nothing, I run M-: (* 5 10) and the result flashes briefly before it's immeaditely cleared (I suspect by lsp-mode). eglot on the other hand doesn't seem to ever clear the echo area itself, which I actually prefer. Is there a way to change this behaviour.

I guess this might be fixed if we check if the currently showed text by the message area is equal to the eldoc displayed by lsp-mode previously. I think that eglot is using some of the new eldoc functionality to support async stuff. We should migrate to that API as well.

Eldoc also appears to be slightly slower than eglot, as in there's a slight lag from when I move point to when an eldoc message shows up. It can't be no more than a fraction of a second although I'd rather not have the delay if possible.

Changing eldoc-idle-delay should fix that?

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

Changing eldoc-idle-delay should fix that?

I have the same value for that 0.1 for both eglot and lsp-mode so I don't think that's the cause.

In retrospect I think this might be the same as my first issue, when I change point (eg: flycheck-next-error) eldoc briefly flashes and then is cleared. Then when I move forward or backward point the message is actually shown. If I try jumping to something lsp-mode can highlight (eg. an identifier instead of a diagnostic error) there's no delay at all (also no flashing).

I'll try to create an asciicast/recording to demonstrate.

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

@yyoncho

Here's an asciicast. Observe that when I jump to the first flycheck error E501 line too long (171 > 150 characters) [E501] is briefly shown, cleared and then only re-appears when I move point around the area and wait a brief period. However when I jumped to the location of the StopIteration identifier it showed the eldoc message immeadiately without delay.

@yyoncho
Copy link
Member Author

yyoncho commented Apr 4, 2021

Seems like this is the same issue related to lsp-mode eldoc message handling. As a side note, there are alternative packages like flycheck-postip which most likely will fix that issue or at least improve the experience.

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

flycheck-postip

Thanks for the suggestion, I tried it out a while back but the positioning of the tooltip always seemed so weird to me so I disabled it. If I need more verbose error information I've taken to just running flycheck-list-errors or the flymake equivalent. For now everything seems to be working fine (eldoc aside). Thanks for your help 😄.

@yyoncho
Copy link
Member Author

yyoncho commented Apr 4, 2021

If I need more verbose error information I've taken to just running flycheck-list-errors or the flymake equivalent.

you can then disable flycheck echo?

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

you can then disable flycheck echo?

I could but I don't think I have before. I don't think it's disabled by default like eldoc-doc-buffer.

In this case if I disabled the flycheck/flymake eldoc backends it would fix the current issue but I still think lsp-mode should be a little more friendly with other eldoc backends. At least so that users can debug using M-: in lsp-mode managed buffers without having to keep the messages buffer open to the side.

@yyoncho
Copy link
Member Author

yyoncho commented Apr 4, 2021

In this case if I disabled the flycheck/flymake eldoc backends it would fix the current issue but I still think lsp-mode should be a little more friendly with other eldoc backends.

Agreed. The lsp-mode implementation is adhoc async implementation which does everything to avoid blicking. As I mentioned in the previous comment this implementation is out of date. You may open an issue to track that effort.

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

You may open an issue to track that effort.

Will do. Thank you for your continued dedication to this project. 😆

@mohkale
Copy link
Contributor

mohkale commented Apr 4, 2021

@yyoncho

I can't seem to reproduce with emacs -q so I think something else might be to blame for this. I'll investigate some more when I get a chance, but put off making a new issue until then. Apologies if I've ended up wasting your time 😓.

@Aaronzinhoo
Copy link
Contributor

Something like this for helm template files one day? Haha (helm intellisense/completion)

https://github.com/tim-koehler/Helm-Intellisense

@yyoncho
Copy link
Member Author

yyoncho commented Apr 9, 2021

Something like this for helm template files one day? Haha (helm intellisense/completion)

https://github.com/tim-koehler/Helm-Intellisense

@Aaronzinhoo I checked that repo and it uses vscode directly vscode extension API thus it cannot be used by lsp-mode. Creating elisp package is out of scope for lsp-mode.

@Aaronzinhoo
Copy link
Contributor

A man can dream Cant he @yyoncho 😂 thanks for the clarification.

@factyy
Copy link
Contributor

factyy commented Apr 15, 2021

I don't know where to place this, hopefully @yyoncho will help with it.

I was wondering if it is possible to have experience similar to VSCode remote-containers. What is really required:

  1. To have a dockerized environment. All the tools (compiler/interpreter, language server, debug server) must reside inside the container. Currently it is partly possible with lsp-docker but only for a language server;
  2. To have an ability to choose whether you want a dockerized environment or just plain old local development projectwise. Currently if you configure your environment to use a dockerized lang server, you end up needing to disable it by hand (as I remember) if you don't need it for another project you are planning to open;
  3. To replace the GIANT lang-servers image with a granular per-project-type set of images.

As I said, I don't know where to place this comment, as I see it, it is coupled with lsp-mode, dap-mode, lsp-docker and maybe projectile. I'm thinking of starting a new project, but can't decide if it is right to do so or try helping with the existing (lsp-mode, dap-mode, lsp-docker) ones.

@yyoncho
Copy link
Member Author

yyoncho commented Apr 15, 2021

@factyy

  1. yes, we need to fix dap-mode to work with remote paths.
  2. Should be possible via different configuration options(:priority parameter of the language server, lsp-enabled-clients/lsp-disabled-clients) or via wrapper of lsp function.
  3. Creating granular containers is a good idea but it requires a lot of work to be acomplished.

Check this as well - emacs-lsp/lsp-docker#34

@factyy
Copy link
Contributor

factyy commented Apr 16, 2021

Do you think we need an umbrella project for such integration? I see that it is partly possible to have such features, but at the same time I think that we have to take a more integrated approach. For example, we have to determine the project type, guess (or get from our specific config) the tools needed and so guess the container needed.

@ericdallo
Copy link
Member

Moving this issue to a new format for a better standard: https://github.com/emacs-lsp/lsp-mode/discussions/2891

@emacs-lsp emacs-lsp locked and limited conversation to collaborators May 26, 2021
@yyoncho yyoncho unpinned this issue Jun 19, 2021

This issue was moved to a discussion.

You can continue the conversation there. Go to discussion →

Projects
None yet
Development

No branches or pull requests