reddit / emacs

Lsp-Bridge is Good

pajuch · 2022-06-21 23:14
Haven't seen much buzz around this but it is definitely out of it's infancy now. Been using it the past couple of days and it is excellent. The speed of eglot/lsp-mode were real annoyances for me before, and I know emacs' (supposedly slow) speed is an issue for many. It just works pretty well out of the box too, which is wonderful since these are the features that attract people to make emacs their IDE. Has anyone else tested it more intensely? Anyone had any dealbreaking issues with it? [https://github.com/manateelazycat/lsp-bridge](https://github.com/manateelazycat/lsp-bridge)
adouzzy · 2022-06-21 23:53
It recently added an acm-mode to replace corfu. It is an auto-complete mode like company that supports async but much lighter. It is still a very young package, but very fast.
ndpian · 2022-06-22 00:23
Interesting, does it work on TRAMP?
adouzzy · 2022-06-22 00:47
I don't think so. I require python epc process as the backend. I won't expect high performance on TRAMP.
arthurno1 · 2022-06-22 00:57
Andy has developed lots of Emacs packages, so I trust him to know what he is doing :). > lsp-bridge is design for out the box. After installing the LSP server command corresponding to the open file, you can write the code directly without additional settings. > > There are two modes in lsp-bridge: > > When detecting the .git directory (to judge by command git rev-parse-is-inside-work-tree), lsp-bridge scan the entire directory files to provide completion > When the .git directory was not detected, lsp-bridge only provided a single file complementary to the open file > > If you expect lsp-bridge to automatically scan the files of the entire project, please execute the git init command in the project root directory. How does it work with C/C++ in regard to compilation database? Do we still need to create a compilation database with bear or something else manually for lsp to find correct paths, or do you handle that automatically? Sorry I ask, I haven't had time to install and try it yet.
ndpian · 2022-06-22 01:10
Thats a bummer :( I hope the authors include TRAMP in the development process, till now I am unable to make any lsp client work for pyright server.
WallyMetropolis · 2022-06-22 01:34
Will definitely check this out, thanks. What language servers have you explored this with?
wyuenho · 2022-06-22 01:45
I don’t understand what this is. Is this another lsp mode?
FluentFelicity · 2022-06-22 02:34
Yep, basically. It deliberately offers fewer features (see https://github.com/manateelazycat/lsp-bridge#features-that-wont-be-supported), but it is **blazingly** fast. Definitely lives up to its promise of being the fastest LSP client.
FluentFelicity · 2022-06-22 02:34
Eglot (not from personal experience but I've heard around)?
FluentFelicity · 2022-06-22 02:38
Question: what are the benefits to acm-mode over corfu? Is it speed via asynchrony? Also, as far as I can tell, only acm mode can be used for completion, or am I wrong?
adouzzy · 2022-06-22 02:45
With latest build, Yes only ACM. But it worked out of box. ACM is async, UI won't be freezed while waiting for the LSP server. Anyway, Bridge is optimized for speed. If you don't care about speed then just ignore, its quite basic in terms of functionality.
FluentFelicity · 2022-06-22 03:01
I'm not sure how I feel about an entirely new completion system being used, especially since it seems like another completion system can't be used in its place
IterativeSieve · 2022-06-22 03:32
I tend to agree. I switched to Corfu because capfs just work everywhere, much like the rest of the new hotness with other completion frameworks based on completing-read. My emacs life has gotten a lot easier having focused on retreading the wheel instead of replacing it. I don’t miss the three dozen helm-x glue packages in various stages of usability I used to have to contend with. Then again, I suppose it makes sense in the context of lsp-specific functionality unobtainable with capfs.
FluentFelicity · 2022-06-22 03:56
I have the same thoughts. I really wonder why there was a move from corfu to acm. The author started this transition around June 3 (I checked the commits), and the completion with corfu in that version of the package seems fine (I just checked out that revision to test it). I can see the reason to create asm, but to have it as the only usable completion system and a hard dependency...
IterativeSieve · 2022-06-22 04:14
Off the top of my head, corfu’s logic probably doesn’t play all that nicely with real time async completion tables. Once it has a completion table it won’t dump it, which means completion styles can actually work. Downside is that fuzzy matching might produce drastically different candidate sets on each keypress, but corfu is usually only going to work with the first table it gets. I still prefer corfu’s more emacs-y drivetrain though.
FluentFelicity · 2022-06-22 04:27
You're probably right given that acm stands for "asynchronous completion menu" and that there wasn't any discussion (as far as I can tell) on the github about the switch (suggesting its necessity). Perhaps this is just necessary for proper asynchronous behavior
xqianliu · 2022-06-22 04:55
Have explored it with java, typescript and bash, all very fast and out of the box working
cradlemann · 2022-06-22 05:15
I have no speed problems with lsp-mode at all. Native-compilation together with new json lib give me instant results even on big projects
LeOtaku · 2022-06-22 05:28
This seems really cool, but I think it's kinda unfortunate that a second interpreted programming language, and python at that, is required for this to work. I'd much prefer it if I could just compile the required external executable and then not have to worry about another thing depending on [some version of python](https://xkcd.com/1987/) on my system.
snippins1987 · 2022-06-22 05:45
Just a question, since I already turned of lsp auto-popup for completion and manually trigger them, I imagine this package would not help me much, isn't it?
aramus92 · 2022-06-22 08:02
Where can I find acm-mode?
zelphirkaltstahl · 2022-06-22 08:34
Wow, I am surprised to find such a nice diagram on the github repository! Looks like there is an actual software engineering process behind the whole thing!
adouzzy · 2022-06-22 09:24
Implementation here https://github.com/manateelazycat/lsp-bridge/blob/master/acm/acm.el I think it is automatically loaded
hvis · 2022-06-22 09:45
Native `company-mode` backends support async.
adouzzy · 2022-06-22 10:00
Yes, I mentioned this in one of my reply. But if you want extreme speed, give lsp bridge a try. It also implemented a dabbreve using python backend for the sake of speed.
pajuch · 2022-06-22 11:23
It seems there are a few unfortunate trade offs to optimise for speed. For me, if I need lsp on a machine then I already have python, so I think it is a pragmatic solution
pajuch · 2022-06-22 11:27
I thought the same. It helps so much with a hackable application such as emacs and makes everyone's lives easier.
[deleted] · 2022-06-22 12:00
[deleted]
pajuch · 2022-06-22 12:49
It's probably not worth it for that use case. However the experience is much better now that it is instant for me, similar to vscode. Would recommend it if that's what made you turn to manual triggering
SureYeaah · 2022-06-22 13:12
If you are using clangd, then the answer is most likely yes.
ireallywantfreedom · 2022-06-22 13:14
The GIL releases during IO though, which is probably the majority of what this does. Python multi threading certainly gives speed advantages in heavy IO scenarios.
WallyMetropolis · 2022-06-22 13:34
That's great, thanks. I'll give Python, Scala, and Clojure a shot.
Icommentedtoday · 2022-06-22 15:22
Damn it's really quick for me. I never got a comfortable and fast setup with lsp-mode and Company/Corfu (probably my fault?). This works great for me out of the box. A little tip, if you use a direnv setup (e.g. with nix-shell), make sure to use a hook like this (this is for the envrc package): ``` (add-hook 'envrc-mode-hook 'lsp-bridge-restart-process) ``` This restarts the lsp bridge when your environment gets updated. Probably something smarter can be done with https://github.com/purcell/inheritenv. Without this it won't pick up on your language servers.
Icommentedtoday · 2022-06-22 15:32
This is probably it. Having hacked a bit on asynchronous completion systems myself, the built in completion systems are definitely not made for it. Imo providing a separate completion system for this use case makes sense. Not that it can't be done with Corfu though
Then-Way8331 · 2022-06-22 16:04
Both company and corfu support asynchronous company backends (corfu via cape). Capfs can also be implemented such that they are interruptible. It seems there shouldn't be a fundamental reason why lsp-bridge is significantly faster than capf-based setups. Probably the eglot and lsp-mode backends are just somewhat inefficient. In the case of lsp-bridge, one should ask if the intermediate python layer of lsp-bridge rather hurts than helps. cc /u/FluentFelicity /u/Icommentedtoday
Icommentedtoday · 2022-06-22 16:17
Yeah it can obviously be done, but from what I've seen they are just one big hack to get async to work. Dynamic completion tables are a mess in emacs, the amount of issues and bugs I've seen in GitHub issue threads is insane. Corfu is a really good package though, not trying to be negative about that. Maybe someone could make a lsp-bridge plugin that allows you to keep using Corfu. I really don't get the hate with python. Some things are just easier to develop in python than elisp (for some). And on top of that I doubt python is slower than elisp (even with native compilation). It would indeed be cool if this was written with a Go/C/Rust backend but if it works, it works. For me, I just use the python dependencies in a direnv and don't have to worry about "bloat" system-wide.
Ghosty141 · 2022-06-22 16:55
I agree. This is helm all over again.
Then-Way8331 · 2022-06-22 17:10
> Yeah it can obviously be done, but from what I've seen they are just one big hack to get async to work. Dynamic completion tables are a mess in emacs, the amount of issues and bugs I've seen in GitHub issue threads is insane. The problem is that the details of the completion tables and completion styles are complicated and not well documented. Most people don't understand how they are supposed to work. This leads to a lot of broken code. But as soon as you understand how this part of emacs is designed, it does not seem too unreasonable. I don't see the big hack you are seeing. In cape-company-to-capf the translation between asynchronous company backends and capfs is relatively direct. Now you could argue that asynchronous company backends are also not up to the job (they are also more limited than capfs), but I doubt that the completion api complexity can be pushed down much further. > I really don't get the hate with python. Some things are just easier to develop in python than elisp (for some). Python is certainly much more widespread. It is really slow in comparison to other interpreted languages, but elisp even tops that (at least as long as the code is not optimized heavily for nativecomp). I just wonder if is really a need for an additional layer. The amount of data transferred between the lsp server and emacs shouldn't be large and the communication between the server and emacs will be asynchronous anyway.
Icommentedtoday · 2022-06-22 18:02
I get your points, especially on the part about corfu. I agree with you that it could possibly be implemented with that. However, as I said it's not a big deal. You could make a plugin for it so that you can keep using corfu. Probably elisp is faster with native compilation than python in some scenarios. But without native compilation? I'm not buying that. The different reddit posts about elisps' speed also seem to say that python is faster. I think it would then be interesting to see what makes lsp-mode and eglot so much slower and contribute to these projects. But to dismiss this project (that some do) because it doesn't use the tools that they use is a bit unfortunate.
Then-Way8331 · 2022-06-22 18:39
> Probably elisp is faster with native compilation than python in some scenarios. But without native compilation? I'm not buying that. The different reddit posts about elisps' speed also seem to say that python is faster. Elisp (interpreted or bytecompiled) is slower than Python, no doubt about that. With nativecomp I am not so sure. But this is not the point - I only wonder if there is really a need for an intermediate processing layer. From what I understand, it shouldn't be necessary given the small volume of data. > I think it would be then interesting to see what makes lsp-mode and eglot so much slower and contribute to these projects. But to dismiss this project (that some do) because it doesn't use the tools that they use is a bit unfortunate. Indeed. I agree with you that all different directions should be explored. Ideally the issues with eglot/lsp-mode should be sorted out, but from what I've read here, some people use these already successfully without performance issues. One can also be critical about the approach taken by lsp-bridge. Since it conflates backends and frontends it won't result in a consistent UI across different modes, since it does not take advantage of the standard capfs. Company and in particular corfu should be better in that regards. Also the author manateelazycat seems to be famous to do things his own way, see eaf, snails, nox, now lsp-bridge. He stated before that he dislikes melpa/elpa, doesn't distribute his packages through these channels and follow his own special development practices. Many of those packages use python and glue things together in wild ways - this is not a criticism of python, but it isn't obvious that the intermediate layers are really needed. The style gives certainly a lot of room for creativity and new and interesting approaches. On the other hand some users may prefer a more conservative approach. I guess I belong to that category of users. In the end it boils down to personal preference.
FluentFelicity · 2022-06-22 19:38
I'll add: if you're using straight.el, you'll need to use a custom value for the :files keyword. Something like: :files (:defaults ".py" "langserver" "acm") should get the job done.
zelphirkaltstahl · 2022-06-23 11:15
A shame, that so few projects seem to care much about proper diagrams. Many projects would be much more approachable, if they invested some time into diagrams for documentation. I guess not everyone has gone through software modelling lectures. It is a skill like many other things, that one can build over time through application.
pajuch · 2022-06-23 21:04
I feel most people could produce a flow chart, or a short explanation of the structure of the project, without any need for lectures. I'm not a computer scientist by trade so this is the kind of thing that makes me far more likely to contribute to projects and engage with the community
MatthewZMD · 2022-06-25 18:30
You are right. As far as what ManateeLazycat told me (I'm more involved with him on the EAF project, I don't know much about lsp, tho I have been closely watching the project mature), the existing Emacs completion systems, by their own designs, do not suit well with the async design of lsp-bridge. They initially tried company-mode, then moved on to corfu. Apparently company was 'terrible' at doing what they wanted, corfu was better, but still not enough. He told me that they spend hours and hours trying to make lsp-bridge work with corfu. At the end of May he said, “about 50% of my time developing lsp-bridge is trying to fix bugs related to corfu, whether it's on the lsp-bridge side, or the corfu side, it was really painful.” (almost direct quote from our chat history). He spent a long time reading the corfu source code, and even tried forking it to adjust to the lsp-bridge design. But at the end he realized he doesn't want to waste time fighting corfu to meet lsp-bridge's needs, “it's much better to make a new completion system dedicated for asynchronous from the ground up, that is simple & gets the job done & I understand all the code”. And that's what happened. As u/Then-Way8331 noted, both company and corfu support async, but apparently there are subtle but important design choices that make the way how they expect receiving responses & sending responses very incompatible with lsp backends. Although Lazycat has tried to twist lsp-bridge to work with company & corfu's designs, there are bugs popping up in many places that's rooted in this design differences, and hence his own completion system. Anyways, I don't have much involvement in this project, I am transcribing what I know and what he had told me, it is prone to error. If you folks have any questions, ask me and I can bring it to him, due to the language barrier (he's not good at English). cc /u/FluentFelicity /u/IterativeSieve
FluentFelicity · 2022-06-25 18:33
Thank you for the insight!
JDRiverRun · 2022-06-26 12:28
>He told me that they spend hours and hours trying to make lsp-bridge work with corfu. At the end of May he said, “about 50% of my time developing lsp-bridge is trying to fix bugs related to corfu, whether it's on the lsp-bridge side, or the corfu side, it was really painful.” ... He spent a long time reading the corfu source code, and even tried forking it to adjust to the lsp-bridge design. This does not give me a lot of confidence in this developer. Corfu is pretty simple: only \~1300 LOC (cf. company: >8000, including some built-in backends). If they encountered corfu bugs, the right thing to do is make a test case and report the bugs upstream. The developer opened no corfu issues, and submitted [one PR](https://github.com/minad/corfu/pull/165) which had to do with changing font size; nothing about async, etc.
JDRiverRun · 2022-06-26 12:39
>Perhaps this is just necessary for proper asynchronous behavior Do you have a sense of what special async behavior this is? Does ACM pop-up and then, after some time, get populated with more results? Corfu just shows candidates. Putting async capability in a front-end UI is... a very strange design choice. That capability should reside *in the CAPF*. I have an async, interruptible CAPF that I'm working on for which corfu works wonderfully. Although it is complex, there is nothing about the CAPF API which limits async behavior. Admittedly, elisp's async capabilities are less convenient than asyncio in Python, but they function \~similarly (using a "callback" style).
JDRiverRun · 2022-06-26 13:35
Response from the author of corfu (+vertico, etc.). >This does not sound right to me. There was no reaching out. The author of lsp-bridge did not report bugs related to Corfu, except for the formatting/resizing issue, for which he presented an insufficient hack as "fix". It could be that the problem is more pronounced if you use backends producing Chinese text, since my focus has been on fixed-pitch fonts (originally Corfu started with overlays where fixed-pitch was the only option anyway). You probably recall that we discussed about pixel-based resizing and alignment. If you look at all the Elisp projects of mine, the bug count is low. > >However I acknowledge that the Capf situation is difficult. When I started Corfu, I expected the Capf backends to be of higher quality (comparable to completion backends for completing-read as used by Vertico). I also fixed (or reported bugs) in lsp-mode related to their Capf. Furthermore there are (or were, fixed in Emacs 29?) bugs in the Eshell/Pcomplete mechanism. One reason was that Company was (and still is) the dominating completion UI for Capfs, which led to implementations which didn't follow the API precisely enough. But the situation is improving, also thanks to Corfu/Cape. > >The second issue could be that the completion/capf machinery is non-trivial with the completion styles etc. We use that in Corfu and Vertico since it allows us to integrate with all the existing completion tables in Emacs. I like to use the completion system across various modes and it works great for me (Eshell/Pcomplete, Elisp, programming modes, Cape, Dabbrev, Tempel, ...). If you want to use this with Lsp it is possible, but it is non-trivial. There is an impedance mismatch between Lsp and the Emacs completion machinery. > >Third, the idea to use a Python middleman sounds dubious. I don't see a reason why this would improve anything. We still need asynchronous communication with the middleman. We could as well communicate directly with the Lsp server. > >Fourth, the lsp-bridge author basically copied parts of Corfu, Cape etc verbatim without acknowledging it. I fought quite a bit with the child frame API in Corfu, so he profited from the work which has been put into that. By then throwing away all the completion related machinery, one will end up with a simpler system, but it will be less coherent across Emacs and it won't be as flexible. It is basically another monolith, the antithesis to the components I've made.
FluentFelicity · 2022-06-26 15:08
u/MatthewZMD gave some insight on his comment here: https://www.reddit.com/r/emacs/comments/vhqewj/comment/idprpt2/?utm\_source=share&utm\_medium=web2x&context=3
MatthewZMD · 2022-06-26 15:48
The author lazycat just wrote an article explaining the decision of not using capf, however it is in Chinese so you have to use some translation tool: https://manateelazycat.github.io/emacs/2022/06/26/why-lsp-bridge-not-use-capf.html The following are some of my personal replies in response to corfu's author, although I completely understand the author's need to defend his own package and I fully respect his contributions to the emacs community: >There was no reaching out Did I mention that there is a language barrier? It would be exponentially harder to explain technical things in a non-native language, please understand that the author of lsp-bridge just wanted to get the work done in a way that doesn't burden his own free time. Anyways, I agree with you that he could've done better in communciations with the English-speaking community. >I don't see a reason why this would improve anything. Just *try* it out and see if it improves anything or not... *(facepalm)* If you don't want to try it, ask the people who have tried it already. The users will tell if this package is providing anything helpful than exisiting lsp solutions. >copied >profited from the work Is this GPL that we are talking about? Or am I missing something here. lsp-bridge is already releasing under GPL3, if lazycat needed additional things done to comply to GPL, let me know and I will tell him.
MatthewZMD · 2022-06-26 16:29
>This does not give me a lot of confidence in this developer. Related comments regarding this from Lazycat's own blog post (translated): > I believe that I have written more elisp code than most Emacsers in the past 17 years. I love Emacs deeply, and I am very aware of the strengths and weaknesses of Emacs. ... Emacs is a powerful productivity tool that allows us to have more time to enjoy life. Emacs serves us, not us to serve tools. Also, [ManateeLazycat's profile on Emacs-Wki](https://www.emacswiki.org/emacs/AndyStewart) (not updated since 2018).
JDRiverRun · 2022-06-26 18:49
Not sure if this is directed to minad, but he's not on Reddit any longer. Language barrier is understandable for sure. > Just try it out and see if it improves anything or not... (facepalm) No facepalm needed. The more nuanced point you might have missed is that Elisp's async, though definitely clunkier, should be quite comparable to Python's, so a hypothetical well-written Elisp package should be able to yield similar improvements, without the need of an external package and the associated double-hop overhead. Of course, that package doesn't actually exist. >Is this GPL that we are talking about? Though I hate to speak for him, I suspect his final comment doesn't relate to licensing at all, rather that it just cuts against his substantial investment of energy in reducing "one-off monoliths" and trying to reinvest in core Emacs API's. But admittedly, sometimes those don't suffice. This may be one of those cases. It's also a common courtesy to reference the sources of your inspiration/borrowed code, though again language barriers may be at play here.
JDRiverRun · 2022-06-26 18:57
>The author lazycat just wrote an article explaining the decision of not using capf, This is actually a very impressive article with a lot of good reasoning; definitely recommend reading if interested in the details. [English translation](https://manateelazycat-github-io.translate.goog/emacs/2022/06/26/why-lsp-bridge-not-use-capf.html?_x_tr_sl=auto&_x_tr_tl=en&_x_tr_hl=en&_x_tr_pto=wapp). Concerns withdrawn.
JDRiverRun · 2022-06-26 19:24
Not sure which comment you mean, but I think the author's blog post gives a good overview.
Sad_Entry9267 · 2022-08-05 12:33
lsp-bridge-complete-manually: Only popup completion menu when user call lsp-bridge-popup-complete command, default is nil
Sad_Entry9267 · 2022-09-22 12:26
lsp-bridge support TabNine now.
FreeAd7233 · 2022-09-25 20:03
The most controversial part is that lsp-bridge doesn't use completion-at-point-functions to provide completions. It implements its own framework: acm to provide completions. The author of lsp-bridge had written a Chinese blog to explain his decision, [link](https://manateelazycat.github.io/emacs/2022/06/26/why-lsp-bridge-not-use-capf.html), for people who don't read English and don't want to use a machine translation. Briefly the main reasons are two: 1. The API of capf is not optimal for completion items returned by LSPs, you need to write a lot of ugly workaround code to transform. 2. capf asks you to store all the candidates. at every time you are rendering the popup menu, you need to do the query on all the completion items to get all the information to render the popup menu. For some lsps like volar which may return thousands of completion items at time. Such operation can cost large computing resources. Acm just uses memory-time tradeoff, to get quicker response. Currently, backends supported by acm includes: lsp, deabbrev, tabine, citre(ctags), English dictionary, Chinese input method, files, which covers at least 90% of the useful completion sources I believe. And there is a third party plugin for supporting acm in terminal mode. For anyone who wants a extreme performance LSP (just as fast as vscode) and as easy configuration as vscode, and doesn't rely on some highly-customized completion sources, just give lsp-bridge a try!
ManateeLazyCat · 2022-10-09 15:34
Thanks for your kind words. ;)