11 ms·
I'd love to see this someday, as an Emacs user. One of my biggest frustrations with Emacs is how it can simply just hang while waiting for anything IO bound (li
by Kaze404 4y ago
I'd love to see this someday, as an Emacs user. One of my biggest frustrations with Emacs is how it can simply just hang while waiting for anything IO bound (like a response from LSP). It mostly only happens when opening a new file, while in VSCode for example the file is opened immediately and things like LSP and syntax highlighting are loaded in the background.
- metroholografix 4y agoThat multi-threading will solve this issue, is a common misconception. Emacs already supports asynchronous I/O and has sentinels for exactly that. However, not everything that runs on Emacs is taking advantage of that functionality. It is therefore up to you, to use the proper package (or not use the wrong one) / configure Emacs in such a way, so that this sort of issue is avoided. I can definitely say that if you're experiencing I/O hangs, it's either misconfiguration or bad code in a package that you loaded. Finally for LSP, I always recommend Eglot over LSP Mode, as Eglot is written by an Emacs contributor that has deep knowledge of Emacs and Emacs Lisp. LSP Mode is written by volunteers on Github, and the code is nowhere near as good. Given the (enormous amount / ever-increasing number) of Emacs Lisp packages out there, a lot of them being substandard, being able to make these sort of qualitative calls (and also increasingly dive into Emacs internals) will pay off. Assuming moderate effort, this will come with experience and time spent using Emacs.
- jonpalmisc 4y agoAnother vouch for Eglot here. Seems smoother and just nicer overall compared to lsp-mode, not to mention better integration with Emacs. I switched to Eglot a while back and haven’t looked back.
- Kaze404 4y agoWow, I had no idea! I'll give Eglot a try, thank you :)
- Athas 4y agoJoining the eglot choir. It behaves like I expect Emacs modes to behave and hooks into other Emacs functionality (xref, eldoc). Actually, it behaves better than that: it often works with zero configuration, which is much better than I expect.
- chrsig 4y agoThis is putting a lot of blame on the user, who likely has no clue how emacs i/o behaves. > if you're experiencing I/O hangs, it's either misconfiguration or bad code in a package that you loaded I mean...yes. That's the issue. The issue is that it's possible to have i/o hangs caused by misconfiguration or elisp packages. The solution isn't to tell the user to do something different, it's to make it so that elisp execution can't cause i/o hangs. edit: to a be a bit more precise with language: "i/o hang" should be interpreted as "making the UI unresponsive or preventing other tasks from completing".
- medstrom 4y agoHow would you make it impossible to make the UI unresponsive? Given that lots of packages directly want to do stuff with UI?
- chrsig 4y agoI'm not going to have a great answer for how, especially in something with as much legacy as emacs. And I certainly don't mean to imply that solving the problem is easy (or possible for 100% of cases), or otherwise detract from efforts that the community has made. My intent was to highlight on what a good solution looks like from a user perspective. Off the top of my head, in an incredibly hand-wavey fashion: A quick win would be to set a timeout on every single i/o action, with the default timeout being quite low. That doesn't remove the problem, but it'd probably be a good start towards easing the user pain. Bringing an indefinitely long hang down to 1s is a win. For a total solution, I'd consider looking into implementing a concurrency model with a preemptive scheduler, probably using erlang as inspiration. have updates to the ui becoming a message sent to the ui inbox, and the routine for rendering the ui just reading from the inbox and applying the given command. This is without thought to how to actually implement that, and what implications it would have on legacy elisp, or how legacy elisp could be brought into a CSP world without breakage. So just some armchair architecting on a day off for a project I've never worked on :)
- jrockway 4y ago> This is putting a lot of blame on the user I think you're missing the point. Emacs already contains all the support necessary to make LSP not lock up the UI, LSP simply doesn't use it. So if you say "LSP is a great use case for multi-threaded Emacs", that's not correct. The problem with LSP specifically is that Emacs doesn't really know what the language server is going to do, and if it let you update the text while the language server was also updating the text, it would have to have some way to merge the changes that you made while the language server was busy. There would need to be some spec for that, or more likely, another trip to the language server to figure out what to do. You could, of course, edit the text while that second trip was happening, and this algorithm never converges to a finished state. So, it locks the UI so you can't make any edits until the text from the language server comes back. That's the easy way out, but at least it results in an algorithm that terminates. The way to fix this is to figure out where the time is being spent. If it's on JSON marshaling/unmarshaling, speed that up. If it's because the language server is slow, speed that up. The only compromise right now would be to let you edit buffers in a different project while the language server is processing something. I don't think anyone wants to do that; "I don't want LSP to lock up Emacs" really means "I want my language server to perform all operations instantly." So get out that profiler for your language server, I think.
- rprospero 4y agoWhile I appreciate the comments on Eglot vs LSP, the number one package that hangs my system is Gnus. It's still my favourite e-mail client, but I'm cut off from coding for twenty seconds every time I check my e-mail. Are we really ready to declare that Lars Magne Ingebrigtsen is a substandard Emacs Lisp coder?
- alex_smart 4y agoGnus has been around since the mid 90s (and predates the addition of asynchronous url-retrieve api to emacs). It is unfair to compare it with packages that written in the last couple of years. I don't use Gnus so I have never bothered looking at its internals, but if it is locking your emacs for twenty seconds checking email, it is probably not doing much asynchronously. It is notoriously hard to convert existing synchronous code to asynchronous without using threads. Promises/futures/continuations/whatever-you-want-to-call-them are a pretty all in affair. Not having the time investment that would take to convert a 100k line codebase to async does not make Lars Magne Ingebrigtsen a substandard Emacs Lisp coder.
- metroholografix 4y agoThis. Gnus is a behemoth, has been around for decades and is also the result of many contributions from many different people. It will take time for it to evolve (it's slowly happening). Lars is amazing by the way, his relentless Emacs work and prolific bug killing in the last few years should be praised to high heavens.
- kwhitefoot 4y agoNot only that but he is incredibly responsive to random people (including me in the past) reporting bugs in Gnus. Years ago I reported something on a Friday morning and he replied directly to me with a workaround by the afternoon.
- michaelmrose 4y agoI use mu4e so I don't know if the workflow converts but I watch for new email outside of Emacs entirely and upon new email run offlineimap and after sync have it run mu4e-update-index via emacsclient. This means Emacs always has an up to date view of my email within a ~30 second window of the email being received and all I'm asking it to do is query mu which takes ms.
- light_hue_1 4y ago> I can definitely say that if you're experiencing I/O hangs, it's either misconfiguration or bad code in a package that you loaded. As an emacs user and package developer of 20 years I can definitely say you are totally wrong. This is the kind of dismissive, unhelpful, and frankly extremely discouraging attitude that is slowly killing emacs. Instead of taking responsibility for the fact that emacs is incredibly slow because of poor architectural decisions (like an insistence to not using fast native libraries and an incredibly slow language), the solution is apparently to blame the people who create packages. If developers they are creating packages that are slow, it is not their fault. It is the fault of emacs developers in refusing to modernize the architecture in a way that enables people to make efficient code.
- jhgb 4y ago> and an incredibly slow language Languages are not slow or fast; their implementations are. There's absolutely nothing wrong with Emacs being programmed in Lisp and it sure as hell isn't "a poor architectural decision". If Emacs is slow because of its implementation of Emacs Lisp, it's time to fix its implementation of Emacs Lisp.
- light_hue_1 4y ago> There's absolutely nothing wrong with Emacs being programmed in Lisp and it sure as hell isn't "a poor architectural decision" I love Scheme and Lisp. I've probably written several million lines of code in both Scheme and Lisp and I've contributed code to several Lisp and Scheme compilers. But languages are absolutely slow or fast! There are fast Schemes and Lisps and there are slow ones. Emacs has probably the slowest one by far. For example, Emacs still relies on dynamic binding after all of this time. That's a performance disaster. There is simply no efficient implementation of Elisp possible as it stands and as it is used today. Even with JIT compiling Elisp performance is simply wretched.
- jhgb 4y agoThen the codebase needs to fully (or as much as feasible) transition to the use of lexical bindings. It's not like we don't know if it will work; Common Lisp supports dynamic variables but you don't pay for them unless you actually use them, and good implementations of CL are fast enough. So what exactly is it that prevents the Emacs Lisp code base from becoming fast enough by abandoning dynamic variables wherever it can? By all rights it should not be any slower than Common Lisp at that point, unless some other obstacle has somehow eluded my attention.
- mdkdkdk 4y agoI've seen you post this criticism before, but the line "volunteers on GitHub" is pure FUD. Is the Eglot guy paid for writing Eglot, or he hosts somewhere else, so it's better? "The code is nowhere near as good" according to you? Give a concrete example of where the LSP code has real deficiencies; Eglot isn't as fully featured, is more opinionated, and its stans are more annoying. Sounds to me like the LSP project is helping new hackers learn Emacs, and Eglot is one bus accident from being unmaintained, frankly.
- chlorion 4y agoYup, I have seen this person post something similar at least once before as well and it's pure misinformation at best. Both projects are very good and everyone should give both a shot and see which they prefer, but spreading misinformation about one project because you prefer another is stupid and childish. A quick peek at the github contributors insights also shows that the overwhelming majority of code is contributed by 3 people and not "volunteers on github", but even if it was mostly worked on by volunteers it would make no difference at all. Code quality is not something that can be trivially disproved like the volunteer thing, but as someone who has spent a bit of time poking around in both projects, neither look any better code quality wise to me. The main thing is that lsp-mode is just much, much larger and prefers to use non-native APIs and packages at times. This is purely a difference in style and opinion rather than "quality".
- dotancohen 4y agoI just got into emacs last year, for Org mode. Startup times drive me crazy. What would be the correct way to configure my .emacs file to e.g. check for package updates in a background process?
- alex_smart 4y agoDon't check for package updates during startup? Setup a cron job to upgrade the packages while you are asleep?
- dotancohen 4y agoIt seems that Emacs does the check automatically, no? I have looked briefly on how to disable that but I didn't have the prerequisite knowledge at the time to understand what was happening. I'll look at that again, thank you.
- alex_smart 4y ago>It seems that Emacs does the check automatically, no? Nope, it for sure does not.
- unhammer 4y agoMaybe you're using (use-package foo :ensure t) or something similar? I did that before, and if there was some package that simply wasn't available it would of course check and not find anything every time I started emacs. I don't use :ensure t any more (I check the elpa folder into git along with my init file for keeping it in sync across machines)
- NeutralForest 4y agoYou should use `use-package` to manage your packages and defer their loading to when you use them. I have over 100 packages in my init.el and my Emacs loads in less than a second.
- dotancohen 4y ago
- jhoechtl 4y agoAs an innocent user I tell you that LSP mode just works whereas Eglot needs tailoring to be a joy to use.
- hadjian 4y agoHm, strange. As I remember, eglot’s design goal was zero configuration. Could you elaborate a bit? For context, I use go, had gopls installed and just had to start eglot. All xref shortcuts worked immediately.
- ghosty141 4y agoLsp comes with preconfigured flycheck for example.
- ParetoOptimal 4y agoI just switched to eglot from lsp-mode, flymake worked by default.
- zdragnar 4y ago> It is therefore up to you, to use the proper package This is the single biggest reason I don't use emacs. I have yet to get a stable installation with the necessary behaviors and tools I need to make memorizing all the chords worth the effort. I've tried spacemacs, doom and from scratch, and have never been satisfied or gotten to the point where coding is as productive as VScode for me.
- yakubin 4y agoFor me the most frequent source of freezes was Tramp. It led me to ditch Emacs for VSCode (with the remote editing extension) at least for my dayjob (I still use Emacs for my own projects). Tramp is an official built-in package, so it's not as if I downloaded a random package from GitHub.
- deleted 4y ago[deleted]
- hierandthere 4y agoWhile I did not ditch Emacs nor do I plan to do so, I agree, that TRAMP is a constant source of grief. It is great in its functionality, but frequent freezing is annoyingly cold.
- fantispug 4y agoThese issues are often interactions between packages. I use TRAMP daily without freezing, but only when I disable company mode in shell modes. VSCode certainly requires much less of this tweaking, even with a variety of extensions installed.
- taeric 4y agoGlad to see this as the top response here. I was rushing to click reply so that I could point out that async has been a thing for Emacs for a long long time. Compilation mode is my goto example for how that can work.
- chlorion 4y ago>Finally for LSP, I always recommend Eglot over LSP Mode, as Eglot is written by an Emacs contributor that has deep knowledge of Emacs and Emacs Lisp. LSP Mode is written by volunteers on Github, and the code is nowhere near as good. This isn't really true at all, but even if it was, lsp-mode has a larger scope and has many more features than eglot. It's also much more actively maintained/developed than eglot is. Anyways, most FOSS code is written by volunteers. I really don't think that's a great argument against a FOSS project. Also see: https://github.com/emacs-lsp/lsp-mode/graphs/contributors https://github.com/emacs-lsp/lsp-mode/graphs/contributors https://github.com/emacs-lsp/lsp-mode/pulse/monthly https://github.com/emacs-lsp/lsp-mode/pulse/monthly https://github.com/joaotavora/eglot/pulse/monthly https://github.com/joaotavora/eglot/pulse/monthly
- alex_smart 4y ago> Emacs already supports asynchronous I/O and has sentinels for exactly that. However, not everything that runs on Emacs is taking advantage of that functionality. It is therefore up to you, to use the proper package (or not use the wrong one) >Finally for LSP, I always recommend Eglot over LSP Mode As far as I can tell, Eglot also just blocks waiting for the server response. Unfortunately, that is the current state of the emacs package ecosystem. Org mode freezes emacs. Magit freezes emacs. Most package writers just don't bother writing their packages with asynchronous I/O in mind. There is no point blaming the user.
- SoftTalker 4y agoI use Emacs all day, every day at work for the last 20 years. I'd like to see these changes too, but honestly it's not even close to being on my top 10 of frequent frustrations. The average web app is way less responsive, suffers random hangs, HTTP 500 errors, browser freezes, etc. than I experience in Emacs.
- TacticalCoder 4y ago> ... while in VSCode for example the file is opened immediately and things like LSP and syntax highlighting are loaded in the background. I'm not saying you're not experiencing what you're describing but I find that weird because I use Emacs with LSP and the system is responsive while LSP loads up. And I'm using lsp-mode, not Eglot (I should really try Eglot). I mostly use it for Clojure: I'm using both Cider and lsp-mode and they work fine together. And as soon as I open any Clojure source file, I can keep using Emacs while LSP starts (which is not that slow btw: only about three seconds I'd say). LSP is one of those things that runs in another process, so it's one of those case, for me at least, where Emacs acts like if it was multithreaded. I haven't seen this lock up / freeze while waiting for some LSP server answer. For example I'll typically open a Cojure file, lsp-mode shall begin loading automatically and then I manually launch Cider: everything happens "simultaneously" and I'm not blocked. I'll play more attention with other LSP servers (like the CSS one) but nothing strikes me as slow or frozen. If there's one thing I could complain about is that when I'm busy doing other things (because my Emacs ain't blocked), I see spurious LSP messages telling me where it's at kinda distracting me. Now I take you're using a native-comp Emacs? And a fast JSON parsing lib? Emacs 28, native comp, lsp-mode, AMD 3700X, NVMe SSD, 16 GB of RAM. A good machine but nothing crazy fast.
- taeric 4y agoI have seen some folks that don't realize they are bypassing the native-json parser by having debug logging turned on. So, could be that?
- NeutralForest 4y agoMy biggest pet-peeve is Org freezing when I'm exporting to PDF.
- OrderlyTiamat 4y agoI've had that fixed in the past by simply adding an ampersand to org's compile command. This does make it run in the background but makes it ring the bell a number of times. Now when I'm editing and want to see the compiled pdf side by side I just start a bash while loop that recompiles continually with latexmk.
- anotherevan 4y ago> I just start a bash while loop that recompiles continually with latexmk. There's the -pvc option in latexmk that[1], "continuously check all input files for changes and re-compile the whole thing if needed and always display the result," depending on if your PDF viewer will refresh. That may obviate the need for a bash while loop. [1] https://mg.readthedocs.io/latexmk.html https://mg.readthedocs.io/latexmk.html
- OrderlyTiamat 4y agoNeat, thanks!
- NeutralForest 4y agoThat makes sense, I don't need to recompile that often but when recompiling relatively large notes (~50 pages) with lots of minted code blocks and the like, it's annoying.
- burtness 4y agoYou can change it to export in the background: (setq org-export-in-background 't) https://orgmode.org/manual/The-Export-Dispatcher.html https://orgmode.org/manual/The-Export-Dispatcher.html
- 4y ago
- d0mine 4y agoYou don't need multiple threads to perform IO asynchronously. And in reverse, using threads won't prevent lock-ups: the opposite is likely. [Pre-emptive] threads compared to external processes require much more careful coordination that is hard to achieve if you are installing dozen of emacs packages written by different people that manipulate the same state. unrelated, it is one of the arguments in favor of GIL such as in CPython--it is easier to get right than fine-grained locks.
- KMag 4y agoAgreed. Raw threads are almost always the wrong application-level concurrency abstraction. Actors/Erlang-style concurrency and futures are both much better abstractions for application programmers. I'm also a big fan of threads with compile-time proofs against data races, a la Rust, but I can appreciate it's a lot to learn for many application programmers.
- kazinator 4y agoThis kind of problem can be solved without threads. Single threaded programs can do things instead of waiting for I/O to complete. In a Lisp you should have continuations and whatnot to be able to the event-driven programming for that without the inconvenience of having to express all the background tasks as transitions in a state machine.
- billfruit 4y agoAlso large 100mb+ text files seems to bring scrolling to a crawl in Emacs.