Hacker News new | past | comments | ask | show | jobs | submit login
What's new in Emacs 29.1 (masteringemacs.org)
236 points by User23 on Sept 7, 2023 | hide | past | favorite | 142 comments



This little project of mine made the front page here a few days ago, so I’m not trying to beat a dead horse or anything, but I just want to surface it here again in case anybody finds it useful.

I have made a starter kit at leverages many of the now built-in features of Emacs 29.1. You can get very far with regards to completion, project management, language, server, etc. just by tweaking a few defaults. I have put some of these nice tweaks together in a starter kit called “Emacs bedrock“: https://sr.ht/~ashton314/emacs-bedrock/

Let me know if you find it useful, or if you have any comments or suggestions. :-) I’m still working on incorporating some feedback I got earlier.


It's incredibly useful to me. I love it. I find it nicely curated and true to the word 'starter' (kit). If I knew more about Emacs, this is definitely what I would have created, and in a similar manner.

It's that lil' layer of configuration that's missing that makes the first clash with emacs sane. I like the structure. I also like the fact that there's a 'researcher' mixin. Would absolutely love to see your opinionated inclusion of org-roam, and general.el.

I recently dabbled into System Crafters' 'Emacs from Sratch' series [0], which is incredibly well thought-out. After 5 hours of following it, you kinda get feature parity between his config and this; but in Berock's case it's done more natively which is really, really neat. I only miss some basic config with general.el.

I feel super lucky to have started in Emacs when they finally added LSP and Treesitter support, and with System Crafters' help and yours!

[0] https://www.youtube.com/watch?v=74zOY-vgkyw&list=PLEoMzSkcN8...


I saw this and finally after 15 years of using emacs I will be recommending it to people and getting them to use this starter kit. Previously I just couldn't explain to people what I love about emacs without thinking about the huge barrier they have to overcome to make it nice. I also couldn't in good faith recommend a "batteries included" starter kit like doom because I don't use it and I'm not sure if it has what I love about emacs which is it sets you free.

I've also read the linked blog post about avy and forced myself to get familiar with it. Jumping all over the screen is great (I set it up jump across all visible frames in my tiling wm). I'm going to investigate consult et al next (already use vertico and orderless).


I’ve used Emacs for quite a few years now, but I had a look at emacs-bedrock when it was posted, and discovered a whole bunch of interesting settings and packages I’d never seen before. I’ve now switched my config over from Ivy to Vertico (and associated packages), and am much happier with it. Thank you so much for making this!


Daniel Mendler (minad on GitHub) et al. have some seriously awesome packages. The latest one I’ve fallen in love with that I haven’t yet added to bedrock is Jinx [1]: a fast spell-checker that supports multiple languages in the same buffer, checks spelling of words based off of font-lock class (read: spell checking in doc strings and comments but not in actual code) and a slick interface that makes correcting words a breeze.

I’m so happy to hear you’ve found some helpful things from bedrock! Happy hacking!


> Daniel Mendler (minad on GitHub) et al. have some seriously awesome packages.

Absolutely! What I like about them is how they each focus on doing one thing well, making use of built-in functionality so they all work well with the rest of Emacs. It makes a nice change from the bigger packages which are so featureful they become hard to understand.


`flyspell-prog-mode' can spell check comments and strings just fine, too.


A link to that discussion for those of us who missed it - https://news.ycombinator.com/item?id=37385716


Really tempted to try out emacs 29.1. I wish someone would compare Neovim with all the bling aginst Emacs with all the bling - with all the pros/cons along with startup-times and performance (intellisense, etc). Want to get out of vscode.


I left emacs around 2018 or 2019 after 8 years of use as my main. A couple weeks ago I started configuring neovim to use it as my main editor outside of work. I'm doing mostly what I did back when I started with emacs which was copy and pasting the code that the plugin creaters advised and go from there. My main takeaway is that Lua is an immensely better language than Lisp for this use case, and when something goes wrong I feel the same about the stack trace.

I've had a better experience tweaking the configuration in Lua as well. I never tried neovim's starter frameworks (NVChad, LunarVim, etc) so I can't compare them to emacs's. I was never able to use well emacs's frameworks because either they were too convoluted ann hard to customize or kept crashing.

Also when opening or formatting large files (sometimes not so large) emacs would freeze for a very long time. Also, LSP was not around, or was in its infancy, so my experience with code completion and intellisense was very poor, but perhaps that has changed.

Finally, emacs's plugin called "Magit" is a godsend and I lack a similar tool ever since.

With all that said emacs was very special for me because it fueled my passion for open software and being able to control and customize the tools I use. I really hope it got better and keeps kicking!


Try neogit plugin for neovim. Its a work in progress.

https://github.com/NeogitOrg/neogit


Good to hear, thank you!


Did you try fugitive as a Magic replacement?

https://github.com/tpope/vim-fugitive


Haven't done a full writeup, but Doom Emacs is _really_ nice.

Takes a little while to acclimate, but it's very useful once you're used to it.


Ya I am a fan of Doom Emacs too. It is the world of Vim wrapped in world of Emacs. Best of both worlds.


I can share my perspective, as doom emacs user for some years (3, I think) who after some back and forth switched to neovim (I've had some vim experience before). If I had to summarize my emacs experience I would say that I like the idea, but I do not like the implementation. It is undoubtedly a cool project with an enormous scope, but while vim is a sharp tool complementing the terminal and usage of other tools, emacs is a kitchesink, which tries to pull everything in. There is no problem with it per se, but the quality of emacs solutions is often hit & miss. These are very generic (ideological) complains, I can name some concrete issues I've uncounted.

- The ecosystem is sometimes difficult. There is always a lot going on in terms of various completion frameworks and spellchecking. It is cool, but often you choice will have some consequences down the line. You like eglot, as a simple and faster alternative? Fine. But it does not support DAP, now you have to pull heavy LSP, treemacs and other 30 packages.

- Treesitter is a chance missed, they've introduced alternative mods for it, with a separate names, which makes it necessary to rewrite the hooks and generally makes a huge mess for no good reason. I guess, the reasoning was like "we do not want to force an external dependency", but there is simply no good reason to regex parsing if you have treesitter and it will be the standard, I am quite sure. Some kind of config switch for a mode would be a better solution.

- It is notably slower than neovim. I cannot describe it, it is more of a "micro-stutter here, micro-stutter there" feeling. It is more visible if you intend to use it for everything or as an IDE replacement, as an advanced editor emacs has a fine performance.

- The UI is... I don't know, I can never predict where a buffer will appear. Emacs in general will pop up a lot of buffers. Sometimes you can close them with q, sometimes you will have to hide them. "Inconsistent" is the word which comes into my mind.

- Org is outstanding as a technical outliner, so-so as a GTD tool. Sync problems and lack of good mobile clients shows.

- Configuring and introspection are good. I still have no idea how to debug my neovim config, for example, it is a non-issue in elisp, you don't even need to restart it, just eval parts of you elisp code!

- Embark is also a very very cool idea.

- Modern completion frameworks are good, vertico, marginalia, orderless - they are easy to configure and very performant. I just like Telescope in neovim more, since it looks better and shows a bigger code preview.

- Evil is a very good vim-like layer, but also quite heavy and sometimes you will have to deal with emacs keybindings. They are not bad, though, it makes sense to learn at least the basics. Due to evil I will leave the keybindings out in general, you can have it either way in emacs. Evil is the best vim implementation outside of vim/neovim.

I've settled on neovim with fish shell, git in console and occasionally lazygit and it is fine. It is hard to describe, but a focused, fast and composing editor is very pleasant to use. I also find neovim more aesthetically pleasant, although it is really just a personal perspective. But what is certainly is, is being simpler. Maybe it is just a natural consequence of aging, but I recognize a lot of value in simple tools: A lever espresso machine instead of a microcontroller-ridden monstrosity with a tablet attached, go instead of rust, console tooling instead of an IDE. Neovim just fits in.


> the reasoning was like "we do not want to force an external dependency"

It was not the optimal solution, agreed. The reason was actually that a significant technical complexity was found while trying to adapt the existing modes. The syntax table vs. tree-sitter parse tree was simply too divergent for a mode to be just switched from one to the other. So the decision which I don't think anybody was completely happy with, but considered the only feasible way to move forward, to have new modes with tree-sitter.

You can see some discussion here: https://old.reddit.com/r/emacs/comments/15g9cna/why_is_emacs... and quick link to the mailing list thread: https://lists.gnu.org/archive/html/emacs-devel/2022-12/msg01...


> - The UI is... I don't know, I can never predict where a buffer will appear. Emacs in general will pop up a lot of buffers. Sometimes you can close them with q, sometimes you will have to hide them. "Inconsistent" is the word which comes into my mind.

I fixed that by redefining in my config split-window-preferred-function to my own function, which is responsible for the placement of new windows in a way that makes sense to me (which is something that no other piece of software does actually).


> The UI is... I don't know, I can never predict where a buffer will appear. Emacs in general will pop up a lot of buffers. Sometimes you can close them with q, sometimes you will have to hide them. "Inconsistent" is the word which comes into my mind.

In my workflow I embrace the chaos: commands/mode open windows as needed and I use winner-mode to restore my layout.

For example, if I have two side-by-side code windows open and I open magit with c-x g, it will create a new vertical split. Once I'm done with magit, I can use winner-undo once (or thrice depending on what magit ops I did) and it restores the original layout.


This is the most balanced and relatable criticism of Emacs that I've read. The points about Org is an outliner vs. a task manager, the package ecosystem, the UI stand out and integration with external toolings stand out.


The "bling" depends on the use case, emacs has many packages not all of which can be installed and in use at the same time.


Your starter kit inspired me to finally bite the bullet and write my own emacs config from scratch instead of using doom. I'm not sure yet if I'm thankful for that, time will tell ;)


Heh, people are still putting up their config files online and blogging about them, eh?

Some things in Emacs never change, no matter how many bells and whistles are in the latest version. :)


Yes, we are :)

I just published my newly hand-rolled config https://github.com/adityaathalye/dotemacs

At some point if/when I upgrade to 29.1, I will be able to delete some lines such as the ones that install use-package. :)


It's the whole point of Emacs that it's malleable and can (should) be tailored to the own personal users needs.


Wait until you learn about users of that editor called vim.


It amazes me that it took so long for emacs to have this kind of started kit. And I haven’t thought of it either. Thank you and please support it!


Finally decided to try out Emacs for a couple of days. (after years of vim and Jetbrains). Vanilla Emacs without batteries included.

I've found the configuration is surprisingly easy to read even tho I haven't seen lisp for 10 years. I think it's atrocious that many keybindings start with <C-x>, but it's easy to set it to another key (mine is <C-j> with capslock as <C>) so not a big deal.

My biggest complain so far is that the whole ecosystem is Unix-first. People say once they get used to Emacs they almost stay in it all day long. And even as an Emacs newbie I can confidently say these people all use Unix-like systems.

On Windows magit is really slow. Like much slower than any git GUI I've seen. And while eshell is usable, it feels rather primitive and not like a proper terminal. The default spellchecker option doesn't work on Windows either, but hunspell seems ok-ish (still a bit slow).

I understand that no one is oblige to write any software for my OS, but stil...

Edit:

The reason I don't use WSL: the last time I tried it, it was really slow when a windows process read from/wrote to a file living in linux file system, and vice versa. One obvious solution is to move as many file as possible to WSL, but I'm just not mentally ready to change my workflow that much.

Edit 2:

For people who like to try Emacs, I'd suggest to turn `which-key` on and install helpful-key. It's a software with the premise that you need to learn obscure key combinations.


To be fair, improving performance on Windows is not really a priority for GNU. From the GNU downloads page for emacs (https://www.gnu.org/software/emacs/download.html#nonfree):

> To improve the use of proprietary systems is a misguided goal. Our aim, rather, is to eliminate them. We include support for some proprietary systems in GNU Emacs in the hope that running Emacs on them will give users a taste of freedom and thus lead them to free themselves.


I fully understand GNU's ideology and I understand no one owes me an Emacs that runs smoothly on Windows. I'm just sharing my experience so far.


So how does the slow tasting freedom help achieve that goal?


So how does slow tasting freedom help achieve the goal?

It doesn't. Stallman hand-waved the "taste of freedom" nostrum to avoid throwing away the man-years supporting emacs on Windows and Mac. The same stupid argument was made to justify the new Android port.


Emacs runs perfectly on macos though


I'm one of those people that stays in emacs all day, and you're right that the Windows port is basically useless on it's own. I use the emacs-w32 package from Cygwin (it is a real GUI emacs that doesn't require an X server but also integrates with the Cygwin environment) though, and that has gotten me productive on lots of corporate workstations where running desktop Linux is out of the question.


I can't speak for emacs performance on windows (you surely have very good reasons to put yourself through devving on windows), but if you're a big vim user I'd highly recommend looking into evil mode, to bring vim bindings into emacs. I find emacs native key bindings kinda stupid, and modal editing to be superior. There's also full emacs config suites around this, such as spacemacs and doom, if you want to explore how they integrate vim-ness into emacs.

Emacs + evil mode has been my primary text editing environment for 7 years now.


Installing evil mode was surely one of the first things I did :) Right after set a dark theme ofc.


Emacs-eat is supposed to work on windows, and may give you a faster e-shell.

Note that you can use things like `pcomplete` and `eshell-syntax-highlighting` to make eshell fairly smart. The fact that my shell can use corfu and the same completion, filtering, and ordering as the rest of my emacs is great.


I became persuaded of the superiority of eshell when I could use corfu for completions. So. Cool.


Thanks, I'll take a look at these eshell batteries.


I hear WSL is snappier. Sadly NTFS optimizes for a completely different file usage pattern than extfs and the native win emacs has poor performance.


I ran Emacs on Windows and used it every day for most of the past year, first natively and then in WSL. I can confirm that performance is many, many times better on WSL, in lots of ways.

Unfortunately, WSL's GUI support is extremely buggy on multimonitor setups (and maybe elsewhere), so you may have to restart your Emacs session often to get window management or even just clicking around to work right.


Have MS managed to figure out window snapping for WSLg yet? From what I've heard (maybe this is dated) there are a bunch of limitations that come from them using a primitive compositor for their Wayland setup.

Xpra (or even a full X server, if you don't mind losing X clients on sleep) has been a lot better on the integration front.


If magit is slow, its likely because of your filesystems performance profile with gits data structures on-disk.

Source: I benchmarked git on windows and decided it wasn't worth trying to fix it.


Could FAT be actually better than NTFS in this regard?


It could be, however I also never tried it.


On remapping C-x -> C-j:

You are meant to press Ctrl with your right hand when you press C-x. Those who came up with these keybindings had this way of using in mind. If you remap it to C-j, it becomes inconvenient because you need to switch between left and right Ctrl in the middle of a chord (though, in some cases this is inevitable). Also, many keybindings are configured so that you can do both C-x (some key) and C-x C-(some key). That is you don't need to release Ctrl in the middle. But, if you change to C-j, then this becomes difficult to execute. Imagine pressing C-j C-m (or C-jm) for example.

Bottom line: not a good idea.

As for Windows: (I haven't used it roughly since Windows 7, and even then only in one work place that required it). How does the OS affect whether you close Emacs between sessions or not? Or is it still the case that you need to reboot Windows a lot?

Also: Magit wasn't always very slow on Windows (although both Git and Magit are and were always slower on Windows, but the magnitude varied at times). As someone who used Magit long before current maintainers took over: it evolved, but not always in the ways that I would like it to. The original Magit is quite a bit less organized (internally, in the way it's coded), but it's a lot simpler and in some ways more intuitive to use.

Modern Magit went through a cycle where they tried to do some performance optimizations, but then they added more features, and the performance gains were lost. Today, Magit is plagued with performance issues, and is a very complex (and a very unfriendly) program to debug: it's neigh impossible to get to the source of errors or trace the performance offenders. But, it's still better (at least on Linux) than anything else I tried by a large margin. So, I'm ranting about performance, but will keep using it anyways.


> You are meant to press Ctrl with your right hand when you press C-x.

I've been using Emacs for several years now, and I think the real solution is to turn Caps Lock into another Ctrl.

The right Ctrl key is in a very uncomfortable position whether I press it with my pinky or with the base of my hand, so in practice I basically never use it. The left Ctrl key is not as bad, but it's still not comfortable if I need to press it often. Caps Lock, however, only requires a slight adjustment of my left pinky finger to press. Simultaneously pressing x with my left ring finger is slightly weird, but not uncomfortable. There are some other keys on the left side that don't really comfortably combine with left Ctrl or Caps Lock, but I don't run into them often enough for it to be a problem.


I use Kinesis Advantage 2, and have been doing so for about 10 years now. So it's hard for me to relate. But, in a rare event that I need to use a more conventional keyboard, I press right Ctrl with my thumb.

In the beginning of my exposure to Emacs I did rebind CapsLock, but that offered little relief. The true quality of life improvement comes from not pressing Ctrl+<anything> with the same hand. Anything that requires Meta or Ctrl -- automatically use both hands.


> The right Ctrl key is in a very uncomfortable position whether I press it with my pinky or with the base of my hand

When I used a traditional keyboard I rebound ctrl to be next to space so I could easily hit it with my thumb so the layout was like:

    [super][alt][ctrl][----space----][ctrl][alt][super]
But now I use a split keyboard(Kinesis Advantage) with ctrl/alt/super in thumb clusters that make hitting those modifiers really easy.


Yep. I do that same key remapping too. IIRC original suggestion was from Xah Lee


> You are meant to press Ctrl with your right hand when you press C-x.

Nothing's stopping you from doing it that way, but since Steele and Moon started writing EMACS in 1976 on the PDP-6 and the PDP-10 and probably used VT52 terminals to access those systems, you're probably expected to have a control key on the home row to the left of the caps lock. The VT52 does not have a control key on the right side of the keyboard. I've found that Emacs's ergonomics are greatly improved by swapping the caps lock and left control keys on modern, IBM Model M-inspired keyboard layouts.


I believe this was / is still believed to be the "best historical keyboard" to be used with Emacs: https://en.wikipedia.org/wiki/Space-cadet_keyboard#/media/Fi... it has Ctrl on both sides.

Even if the 76's Emacs wasn't designed for it, most people with decades of Emacs experience would start salivating just from looking at this keyboard. I believe, that when anyone using Emacs is designing key bindings, be it today, ten or twenty years ago -- they think about something like Space Cadet.


> Imagine pressing C-j C-m (or C-jm) for example.

I'm not sure what it means since I just pressed <C-j> <C-m> and I had zero issue about this. I stated in the first post that I use capslock as ctrl.

> How does the OS affect whether you close Emacs between sessions or not?

I didn't say that I close Emacs between sessions. I meant (I supposed) some Unix people use tools like vterm and magit so they don't even switch to another terminal app. I instead constantly switch between Emacs and Windows Terminal.


I guess, it depends on the physical keyboard layout. The point about C-j C-m is that you'd have to crunch your index finger too much. Well, maybe that's not the best example, as that still seems possible. Try maybe C-j C-/ to really feel the strain.

> Windows Terminal

Why not use shell from Emacs instead? Emacs has a bunch of terminal emulators. One of those ought to work decently on Windows...

If you do it the way you describe, you will set yourself up for a painful experience. Because Windows Terminal (most likely) doesn't have the editing capabilities of Emacs, and (most likely) it doesn't use the same navigation / editing scheme as Emacs, you will have to switch between the two and make mistakes in both of them. It's really annoying to work like that, and it causes people who chose Vi or Emacs to use or to configure other tools to work in the same way their preferred text editor does it. But, ideally, they'd just want the other tools to be embedded in their editor (because any customizations they make for the editor will automatically extend to those tools).

Having to deal with switches in how you write or navigate text is similar to having a crying baby nearby or a loud pub etc. Most people wouldn't willingly put themselves in that position.


You didn't say it was Emacs's fault, but to make the point clear to others, Magit is slow on Windows because of how Windows spawns processes:

https://magit.vc/manual/magit/Microsoft-Windows-Performance....


While WSL might be "slow" relative to linux, emacs with lots of plugins is exponentially slower under standard windows. Also since emacs launches lots of processes and accesses a lot of files the windows virus scanners, including microsoft, slow things down a lot more. I don't use live virus scanning though and have my downloads folder automatically scanned and a nightly scan set up for my windows machine to avoid that.


The reason eshell doesn’t feel like a proper terminal is because it’s a shell that doesn’t run in a terminal but in an emacs buffer. A down side is programs meant to display output in a terminal emulator won’t render properly in eshell. An up side is emacs commands meant to display output in an emacs buffer will work beautifully in eshell and the entire output will be editable.


I’ve been trying to use emacs and vim/nvim on and off for a several years now but it always seems like a task in vain. Half of it works and it’s a real pain to get something usable.

I wish I could use Linux but I work in the gaming industry ina company that solely creates windows games so it’s not really an option…


I've had good results with wsl2. The only thing that frustrates me is magit performance on a big project with literally twenty years of commits. (It was originally an SVN repo.)


Windows gained support for pseudoterminals only in the last few years. I'd guess that eshell hasn't been updated to take advantage.


Incredible work; I’ve cut down my config immensely by deleting external packages, using built-ins as much as possible, and emacs gives you a lot more out of the box now.

That said, magit is the star of the show.


Has anyone figured out how to pair magit with git-sim (https://github.com/initialcommit-com/git-sim) so that you can use magit's controls but then get a picture of what you're about to do before you do it?


Just do it, and learn to use the reflog ("l r" from magit buffer). Although of course be aware of the few things that can trample your workdir like reset --hard. If in doubt, commit/stash everything, to the thing, then see what it did.


Same here. Really happy with eglot as well. I tried it with Go and all I needed in my config was:

    (use-package go-mode :ensure t
        :hook ((go-mode . (lambda () (setq tab-width 4)))))
And it works the emacs way, not trying to be something more "modern" (i.e. VS Code), which to me is so much nicer than all the lsp-ui nonsense that I was using before (no popups, docs show up in the minibuffer as it ought to).


For extended docs beyond the minibuffer, I've found that M-x eldoc works very nicely with eglot and follows the Emacs way.


Ok that does it. Going to finally cave in and recreate init from scratch this weekend. Thanks.


Did that this morning. Been using Doom for years as my config base and got tired of not really "knowing" emacs and not being able to quickly solve problems. Finished my own mostly vanilla emacs conf this morning.


A much less thorough round-up of 29.1 was discussed here a little while ago¹, with many of great comments².

¹ https://emacsredux.com/blog/2023/07/30/emacs-29-1-released/

² https://news.ycombinator.com/item?id=36929514


> "As much as we like to delude ourselves into thinking that unstructured orgmode text, or even s-expressions, represent the pinnacle of text editing and the acme of scrappy hackerdom, that mantra does come with a significant penalty to performance."

Love this in the context of native SQLite support.


Is the SQLite support documented anywhere? What is it? I searched for “SQLite” in the Emacs manual and the Emacs Lisp reference and got nothing.


With Vertico in Doom Emacs (via the Helpful package), I find a lot of stuff like this by doing `SPC h f` and then "vertico" and a list of functions containing that string in the name pops up.

It looks like it's in Text > Database in the "Emacs Lisp" manual, not the "Emacs" manual.


M-x pixel-scroll-precision-mode

This is the best thing since idk. Thank you so much, folks!


Really makes reading mail with inline images or org files etc. sooooooo much nicer.


It's a nice release. Headliners aside, a lot of little improvements that make a big difference. `mouse-drag-and-drop-region-cross-program` and `dnd-indicate-insertion-point` might be my favorites that category. Making dragging text into GUI Emacs work as it does for other programs.


Anyone have a good recipe for proper color coding and autocompletion for mixed language files? js, html, css, php. I love spacemacs but couldn't get it to work right until I bailed for vscode which had everything working out of the box...


I'm not really happy with the number of times I have recently had to resort to sending it SIGUSR2 to force it to stop whatever it's doing when I re-indent some code in a file of Typescript. It happens about once a day. When it does I quickly save all my work and restart. I haven't looked too closely at it yet but from what I've seen in backtraces I suspect there's a bad pattern match situation in there somewhere, like what you might get from the exponential behavior of a poorly written regex.

I'm also not happy about the fact that I can no longer open large C++ files like https://github.com/ASDAlexander77/TypeScriptCompiler/blob/ma... in C++ mode without scrolling becoming so sluggish as to be unusable. I either have to disable C++ mode or open them in an older version.

It's good that emacs is getting some long needed attention, but I'm sad the latest version isn't as usable for me.


> I'm also not happy about the fact that I can no longer open large C++ files

Regex-based syntax highlighting is usually the culprit in these cases. There’s probably a new RegEx inside c++ mode that burns too many cpu cycles.

You might want to try out the treesitter mode „c++—ts-mode“ that does the syntax highlighting based on a real static parser written in C: https://medium.com/really-learn-programming/setting-up-tree-...

Disclaimer: I’m not a C++ dev so I have never tried that.


> https://medium.com/really-learn-programming/setting-up-tree-...

The author made this story available to Medium members only. Sign up to read this one for free.

/sigh


Yeah, sorry, I was hastily looking for a tutorial. But I got "c++-ts-mode" working for me now, see my other comment below: https://news.ycombinator.com/item?id=37466899

I am still not a competent C++ programmer but this is how your basic tree sitter C++ mode is supposed too look with "C-h m":

  Minor modes enabled in this buffer: Auto-Save Flycheck Flyspell
  Font-Lock Yas

  The major mode is C++// mode defined in c-ts-mode.el:

  Major mode for editing C++, powered by tree-sitter.

  This mode is independent from the classic cc-mode.el based
  ‘c++-mode’, so configuration variables of that mode, like
  ‘c-basic-offset’, don’t affect this mode.

  To use tree-sitter C/C++ modes by default, evaluate

      (add-to-list 'major-mode-remap-alist '(c-mode . c-ts-mode))
      (add-to-list 'major-mode-remap-alist '(c++-mode . c++-ts-mode))
      (add-to-list 'major-mode-remap-alist
                   '(c-or-c++-mode . c-or-c++-ts-mode))


> when I re-indent some code in a file of Typescript

What typescript mode are you using? Emacs 29.1 comes with "typescript-ts-mode" providing parser based syntax highlighting and navigation. Traditionally, re-indentation is implemented using regex based syntax tables, too, so you might enhance your experience by switching over to that newer mode.


For reference, here are my versions

    ________________ M-x emacs-version
    GNU Emacs 29.1 (build 1, x86_64-apple-darwin18.7.0,
    NS appkit-1671.60 Version 10.14.6 (Build 18G9323)) of 2023-07-30
    
    ________________ M-x describe-mode (for C++)
    Minor modes enabled in this buffer: Font-Lock Tree-Sitter-Hl Tree-Sitter
    The major mode is C++//l mode defined in cc-mode.el:
    
    Major mode for editing C++ code.
    Using CC Mode version 5.35.2
    
    ________________ M-x describe-mode (for ts)
    Minor modes enabled in this buffer: Font-Lock Tree-Sitter-Hl Tree-Sitter
    
    The major mode is TypeScript mode defined in typescript-mode.el:
    Major mode for editing typescript.
    
    ;;; typescript-mode.el --- Major mode for editing typescript
    ;; URL: http://github.com/ananthakumaran/typescript.el
    ;; Version: 0.4
    ;; Keywords: typescript languages
    ;; Package-Requires: ((emacs "24.3"))

    ________________ os
    % uname -srm
    Darwin 19.6.0 x86_64

    % sw_vers
    ProductName:        Mac OS X
    ProductVersion:     10.15.7
    BuildVersion:       19H15


Sorry, was AFK over the weekend.

> Minor modes enabled in this buffer: Font-Lock Tree-Sitter-Hl Tree-Sitter

> The major mode is TypeScript mode defined in typescript-mode.el:

> Major mode for editing typescript.

This actually indicates that you are in fact using some tree sitter extension for doing "font-locking". Do you happen to have installed "elisp-tree-sitter" in the past? Perhaps this setup has some bugs. Or your font-locking is still running regexes in your mix.

This is how typescript mode looks for me using Emacs 29.1's built-in tree sitter support:

  Minor modes enabled in this buffer: Auto-Revert Auto-Save Company
  Eldoc Flycheck Flyspell Font-Lock Lsp-Headerline-Breadcrumb
  Lsp-Modeline-Workspace-Status Lsp-Ui-Doc Lsp-Ui Lsp-Ui-Sideline Yas

  The major mode is TypeScript mode defined in typescript-ts-mode.el:

  Major mode for editing TypeScript.
(I am also running "lsp-mode.el" so there are more minor modes running than perhaps in your case.)

So, I would remove any tree sitter extension you may have installed in the past. Then to activate the new "typescript-ts-mode" you need to do the following:

1. Clone this repository: https://github.com/casouri/tree-sitter-module/

2. run "./build typescript" (you'll need build-essentials and a C++ compile but I gathered you are programming in C++, so)

3. Copy the resulting shared library "dist/libtree-sitter-typescript.so" into "~/.emacs.d/tree-sitter/".

4. Open a random typescript file and try "M-x typescript-ts-mode" which should not give you any error but nice syntax highlighting.

5. Of course, you'll need some tweaking to make it your default. Basically, you'll have to add "'typescript-ts-mode" to your "'auto-mode-list".

You'll have to do the same for your C++ setup. U̶n̶f̶o̶r̶t̶u̶n̶a̶t̶e̶l̶y̶,̶ ̶t̶h̶e̶ ̶c̶o̶n̶v̶e̶n̶i̶e̶n̶c̶e̶ ̶"̶t̶r̶e̶e̶-̶s̶i̶t̶t̶e̶r̶-̶m̶o̶d̶u̶l̶e̶"̶ ̶b̶u̶i̶l̶d̶ ̶s̶c̶r̶i̶p̶t̶ ̶d̶o̶e̶s̶ ̶n̶o̶t̶ ̶s̶u̶p̶p̶o̶r̶t̶ ̶C̶+̶+̶ ̶o̶u̶t̶ ̶o̶f̶ ̶t̶h̶e̶ ̶b̶o̶x̶.̶ ̶B̶u̶t̶ ̶i̶t̶ ̶d̶o̶e̶s̶ ̶n̶o̶t̶ ̶l̶o̶o̶k̶ ̶c̶o̶m̶p̶l̶i̶c̶a̶t̶e̶d̶ ̶t̶o̶ ̶e̶x̶t̶e̶n̶d̶ ̶i̶t̶ ̶f̶o̶r̶ ̶y̶o̶u̶r̶ ̶p̶u̶r̶p̶o̶s̶e̶s̶.̶ Nonsense, it is supported: Just run "./build cpp". You also seem to need "./build c". This way, I was able to activate the new C++ treesitter mode.

If you do not want to go ahead and migrate to built-in treesitter yet -- as you see it's still a bit fiddly to setup as it is brand new -- I would tackle your C++ performance problem first by using Emacs' profiler:

1. M-x profiler-start (select "CPU")

2. Open your C++ file slowing your Emacs down.

3. M-x profiler-stop

4. M-x profiler-report

and see what it gives you. Perhaps post an issue with the Emacs maintainers and they can give a clue where your issue comes from. But usually something like this is caused by a run-a-way regex.

Good luck!


Thank you for the recommendation. I will look into building my own tree sitter grammars using https://github.com/casouri/tree-sitter-module as you suggest.

Some time ago I followed this guide https://vxlabs.com/2022/06/12/typescript-development-with-em... and added this to my .emacs

    (use-package tree-sitter
      :ensure t
      :config
      ;; activate tree-sitter on any buffer containing code for which it has a parser available
      (global-tree-sitter-mode)
      ;; you can easily see the difference tree-sitter-hl-mode makes for python, ts or tsx
      ;; by switching on and off
      (add-hook 'tree-sitter-after-on-hook #'tree-sitter-hl-mode))
    
    (use-package tree-sitter-langs
      :ensure t
      :after tree-sitter)
Regarding C++, I tried a simpler experiment starting emacs with

   % open -n -a Emacs --args "-q"
and I think my C++ slowness issue is due to fontlock https://www.gnu.org/software/emacs/manual/html_node/emacs/Fo...

Even without a startup file, I can't open https://github.com/ASDAlexander77/TypeScriptCompiler/blob/ma... and scroll through the file unless I also manually do

    ESC : (global-font-lock-mode 0)
I'm sorry if I gave the impression I'm a regular C++ developer. I only use it occasionally. I just happened to remember finding myself unable to use Emacs for that particular file.


Mickey Peterson is doing gods work, but it would be great if this book-sized article could have a table of contents.


Yeah, it's amazing work, but the amount of information here is really hard to digest.


I'm a bit disappointed at the features of the included lsp client. I went back to lsp-mode.

Also I feel like performance could be improved a lot, but that's probably an issue in my particular setup.

If someone has an efficient lsp-mode + typescript-mode + eslint checks, I'd be happy to see how you achieved that.


While lsp has brought the best utilities that used to be locked away inside IDEs. I just don't see how you can build upon it when its been shown to struggle pretty much since the beginning.

JSON is okay if you need a format that is human readable but how did the engineers at microsoft ever think that it was a good choice for interprocess communication?. Most of the work is wasted on decoding the json itself. We should not have to increase the interval between request and batch calls in order to make it usable.


LSP as a protocol feels like somebody documented IDE features, then exposed those directly at the protocol level. It's absurd. When last I checked, I could register a function to be used to apply syntax highlighting when the LSP server identifies a change, but you couldn't make any explicit queries against the known parts of the syntax.

I wanted to query the LSP server to tell whether the point was currently located within a string, but as far as I could tell, the LSP server couldn't be queried for the syntax type. You can ask for "selection suggestions", you can ask for "semantic tokens" within a specific range, but you cannot ask for the semantic token containing a single specific point.


VS Code can achieve much more performant editing with the same server, so there is no excuse for emacs to be slow.


My experience is that VS Code has a tremendous amount of input lag, to the point that I need to wait for a search prompt to focus before I can start my query. Emacs, on the other hand, is incredibly responsive, and even when running over a slow SSH connection has properly buffered inputs so I don’t need to wait.

Emacs can achieve much more performant editing with the same server, so there’s no excuse for VS Code to be so slow.


VS Code in its current state has no perceptible input latency on modern hardware, easily verifiable.

If you invested the time to configure Emacs to mimic VS code's completion- instantaneous fuzzy autocompletion on every keystroke- the GUI would lock up every time autocompletion is engaged, i.e. the entire editor stutters on every keystroke, because the garbage collector is constantly blocking the UI thread. The performance limitations are widely known. It's the reason yyoncho, the creator of LSP-mode, forked Emacs to explore adding multithreading to address the issue [0].

But I can't see this being fixed anytime soon, because there are a fleet of intellectually dishonest zealots on the internet that refuse to acknowledge it's an issue, and will flame anyone who brings it up.

As a result, when new users try out Emacs and see that the performance sucks, many of them will instantly uninstall and return to VS code, and the userbase suffers.

[0] https://www.reddit.com/r/emacs/comments/ymrkyn/async_nonbloc...


> VS Code in its current state has no perceptible input latency on modern hardware, easily verifiable.

"easily verifiable"?!!? This is a ridiculous statement - lots of VSCode responsiveness is dependent on which language servers you're using, and some are definitely faster than others. Sounds like you're extrapolating from the languages that you personally use?

The golang LSP has had widely documented performance problems on large codebases on and off over the past 2ish years (mostly resolved at the moment AFAIK), but it was severe enough that a large percentage of my group at work switched to Goland (Go IDE from Jetbrains) because it was much, much less laggy on our larger projects than VSCode.


> instantaneous fuzzy autocompletion on every keystroke- the GUI would lock up every time autocompletion is engaged,

I am using lsp-mode enhanced autocompletion (using company.el) and I have never observed such a problem. I set the autcompletion delay to 0.0 in my case and work on 1k LOC modules.

If you enjoy VS code, I am glad for you. It is certainly a good editor. But don't post generalized slurs against Emacs if you obviously haven't used it for long.

Performance issues can happen but that highly depends on the context. What combination of language server, language server client and what language is causing this?

Edit:

If you are new to "lsp-mode" and you have performance issues, take a look here:

https://emacs-lsp.github.io/lsp-mode/page/performance/#json-...

Also consider trying other LSP servers if available. For popular languages there are usually several alternatives to choose from:

https://langserver.org/


I mentioned that bringing up performance issues will bring you insults and dismissal, and you saw fit to reply with:

> I have never observed such a problem

> don't post generalized slurs against Emacs

> If you enjoy VS code, I am glad for you.

> you obviously haven't used it for long

I guess it did not occur to you that you are immediately proving my point.

To answer your question, the context is literally every single language server. Not only with autocompletion delay to 0.0, but also setting the minimum prefix to 1, so that it activates on every keystroke; the default is 3. The fuzzy completion cannot be configured out of the box, of course, it requires another extension. I posted a thread with much detail on why it occurs.

You can downplay all you'd like, but a non-issue does not spur a productive maintainer to fork the entire codebase to implement changes, or alternative clients (LSP-bridge) that manage out-of-process connections to servers in order to work around Elisp limitations.


Well, Emacs has indeed a problem with blocking because it is single-threaded. To resolve that issue internally it also maintains an event loop being used to drive async. functions calls. But not all extensions leverage that yet. But I doubt the problem described in that reddit thread you cited is really caused by that. It sounds more likely the author of that Emacs fork experienced an issue with inter process communication. Who knows because there is no detailed context given.

I am using "lsp-mode" for Javascript, Typescript (including React) and even on a huge Perl repository and I don't find it to be too slow for me. I am running a five year old mediocre laptop using Ubuntu. But perhaps I don't have the same standards as the author of that Emacs fork.

> You can downplay all you'd like, but a non-issue does not spur a productive maintainer to fork the entire codebase to implement changes, or alternative clients (LSP-bridge) that manage out-of-process connections to servers in order to work around Elisp limitations.

Well, it's an impressive feat, for sure. But I don't know anyone actually using that person's fork. So I wonder whether that really is such a huge problem as the author implies.

And -- why do you care anyway since you seem to be happy using VSCode?


I'm not the one you are directly replying to, but I love other aspects of emacs too much to switch (magit, org-mode, macros, code navigation, eshell, etc.) But everything can and should be improved.


> Not only with autocompletion delay to 0.0, but also setting the

> minimum prefix to 1, so that it activates on every keystroke;

> the default is 3.

There, from my config:

  (use-package company
    :after lsp-mode
    :hook (lsp-mode . company-mode)
    :bind
    (:map company-active-map
          ("<tab>" . company-complete-selection))
    (:map lsp-mode-map
          ("<tab>" . company-indent-or-complete-common))
    :custom
    (company-minimum-prefix-length 1)
    (company-idle-delay 0.0))
I had no performance issues whatsoever with it. The suggestions tend to be better in quality when coding in Typescript due to the type hints compared to, say, Perl being designed around dynamic typing. But that's a limitation of the language.


Thanks for pointing out the lsp performance page. I'll definitely be trying all of that today.

If it works, then I wonder why these adjustments are not in default emacs.


Not sure why you are getting downvoted, I think this is exactly the issue I'm seeing.


I didn't downvote this post, but I don't find it hard to see why someone would:

* making incredibly general hand-wavy statements implying vscode is always perfectly lag-free and emacs is terrible

* generally condescending and hostile tone: "if you invested the time.." "you saw fit to reply with"

* some ranting and name-calling about a previous negative experience this person has had, which has nothing to do with anyone in this thread. (given the general tone of this post, i'd say there's a good chance that it was just this person deciding to abuse some unpaid emacs/lsp volunteer/maintainer and they rightfully said "go fuck yourself")

* sadly, there is actually useful information contained in this post, but it's sort of structured as an inverse "shit sandwich" - some ranting and negativity, some useful and relevant information, and then more ranting and name-calling. which, i think, tends to mean most people are just going to ignore it or downvote. not really a constructive contribution to the discussion, despite actually having something useful to say


Yeah, makes sense. Parts of it resonated with me, but it's also a bit too rude.


Similarly you cannot use LSP to query the type of a symbol, something I do all the time in OCaml and other typed languages.


That's exactly what LSP is. Notice that it was invented by Microsoft and it becomes a lot less surprising.


Have you profiled things and have data to show JSON handling is the root of the performance issues?


Not the person you are replying to, but the JSON performance of Emacs was a well-known thorn in the side for using LSP.

Further details...

... from the same source as the top post: https://www.masteringemacs.org/article/speed-up-emacs-libjan...

... from lsp-mode: https://emacs-lsp.github.io/lsp-mode/page/performance/#json-...


Ah, ok, I get what you mean, but those are not inherent JSON issues. After all, VS Code & co use the exact same protocol in a speedy fashion.

It's Emacs needing to be configured to use faster JSON libraries.

The original comment was complaining about JSON as a format itself, and my argument is that unless you need super high performance, JSON is more than enough. And it's not like LSP is passing around GB of data every second, let's be real here :-)


Treesitter will make LSP servers obsolete at some point I believe. The parser framework also comes with query API you can use for semantic analysis of code — it’s about more than just syntax highlighting. Therefore, with treesitter you should be able to do everything what a language server does for you — inside the editor‘s process.


It's only a parser though, right? So it won't know about derived properties of code like types. I think you still need something like LSP because if the language has type inference, which all modern languages do, you need exactly the same type inference algorithm as the compiler otherwise you'll get incorrect inferences in corner cases.


Most LSP server implementations I've seen are just parsing the source or even stop at just tokenizing it. They don't do anything magical inside the source language (unless a language exposes parsing/compiler internals e.g. like Raku's language server does). So I don't think most LSP servers leverage anything from inside the source language's compiler including performing type inference on your code snippets. Also note: If your code snippet is incomplete because you are just about typing it, this also cannot work in principle. That's exactly why treesitter was invented: To have a robust static parser able to process incomplete or erroneous code.

> if the language has type inference, which all modern languages do

Well, only if your "modern" language is a statically typed language ... And again: Unless your code is correct and complete, you really can not just run "eval" in your source language and obtain type checking out of the box.


Rust-analyzer provides plenty semantics-level functionality, and it deals with incorrect code gracefully.


I am not a Rust dev. It surely looks great.

However, from what I understand it seems to supply just a parser separate from the Rust compiler (https://github.com/rust-lang/rust-analyzer/tree/master/crate...) trying to keep up with Rust‘s development. So, in principle, it could have been just another treesitter parser plugin, too.

So, again, the LSP framework does not directly provide any magical benefit over a static parsing framework. All the semantic analysis capabilities stem from a good parser.


One benefit is that you don’t have to write a complex tree sitter mode for every editor. You can write an LSP server once and plug it into every editor.

Rust analyzer also provides compilation errors, lints, and code actions. It would be a lot of unnecessary work to implement and maintain these functionalities five times in five different editors.


Treesitter knows nothing about your code outside of current file, no? Not to mention all of the project dependencies starting for stdlib.


But a tree sitter mode could parse the related files in the background. That’s exactly what an LSP server does, too.


> Treesitter will make LSP servers obsolete at some point I believe.

that seems extremely unlikely, Treesitter is a vibe-based parser framework for syntax highlighting and indentation of single files, LSP is arbitrary language-specific processes doing full-project parsing and analysis and introspection.


> LSP is arbitrary language-specific processes doing full-project parsing and analysis and introspection

No. LSP is a way of separating the job of parsing and static analysis of a source file from the editor and doing it out of process. It's a neat concept for sure moving the burden of implementation from the editor's maintainers over to the language project.

But all language servers really do is performing static parsing and analysis. Some language servers even skip full parsing and just use the plain tokens from the input file (which still works okay for many languages). I suggest people actually take a look into the implementations of various language servers. It is quite disillusioning. When I first heard about LSP I was under the impression it was hooking into the actual language's implementation. But this is really not the case. For example, the deno-based JavaScript language server does not even leverage V8's javascript interpreter but comes with a full re-implementation of a static JavaScript parser written in Rust.

My argument is: You could all have that also using just the treesitter framework because the editor only needs to load the grammar for any language from an external plugin and provide a generic querying API (the treesitter even comes with that and e.g. Emacs just provides Elisp bindings for that AFAIU). The language modes could then leverage the parser to do all the hefty work that currently language servers do but inside the editor's process and, hence, without the overhead of IPC. There is also no single-file limitation. Nothing stops a language mode from parsing include statements and open the corresponding files.


> Also I feel like performance could be improved a lot

Would you mind to share your setup?

I am using „lsp-mode.el“ on a Perl project with >100k LOC (including huge single modules) and never had a problem. I am using cperl-mode together with lsp-mode and Perl::LanguageServer and it works like charm. I also never had an issue with React or TypeScript but in those cases the projects were a lot smaller.

Perhaps you also got an issue with JSON parsing performance. Edit: From someone a couple of threads below: https://emacs-lsp.github.io/lsp-mode/page/performance/#json-...


I recently updated to Emacs 29.1. I found that Emacs is now behaving erratically when it comes to modifier keys. Here's a post about someone seeing phantom hyper keys: https://emacs.stackexchange.com/questions/78135/why-does-ema... In my case I experienced phantom meta keys when I press the super key. I spent hours debugging and gave up by redefining my key bindings to include these meta keys.


What is the significance of TreeSitter? Emacs has syntax highlighting already- so how is it an improvement?


Syntax highlighting now runs on regex, which means that it is slower and prone to errors. In the end, it understands nothing about the code it highlights. Tresitter, on the other end, makes a proper syntax tree.


it's faster, builds a proper parse tree so is more reliable, it's shared between editors so will have greater opportunity for improvement, and exposes related things like indentation and code movement from the same system.

it's very very cool that this late in the world of computers we ~suddenly get cross-editor analysis system (LSP) and cross-editor highlighting/indentation/rough parsing support.


Cross-editor? Who runs multiple editors? The only thing you need is Emacs. Why are they breaking apart Emacs' functionality into separate things? Is TreeSitter even written in Lisp? If not, then how would this be hackable in the same way?


I think this is a pretty good article that highlights the benefits of TreeSitter in Emacs: https://www.masteringemacs.org/article/tree-sitter-complicat...

I'm happy that TreeSitter is in Emacs Core rather than elisp, it'll run faster.


Any improvement with "one long-running thing blocks all the buffers"?


Many functions have acquired an async variant. For example, „shell-command“ runs shell scripts and redirects their output to a buffer. If you add the ampersand „&“ at the end of your command it won’t block your UI.

On the other hand, package upgrades are still blocking with Emacs‘ built-in package manager. I hear „straight.el“ is a good replacement capable capable of running async but it’s an advanced sub system.

Do you have some examples?


elpaca.el is asynchronous, try it out!


Yeah, elpaca is pretty good, it was made by the author of blimpy mode.


Can someone elaborate on the Wayland warning? I've been waiting for wayland support for a very long time. Does this warning imply that if I add or remove an external monitor emacs will crash?


I run emacs on wayland, removing external monitors regularly, emacs jumps between them.


I have been hearing about emacs and vim also intending to learn Emacs for a while, from the comments it seems like a good time to start.


Funny one for the emacs-aware (lovers and haters).

https://www.youtube.com/watch?v=urcL86UpqZc


The long line support improvement could be a game changer. I’m less interested in tree sitter and pixel-scroll seems like a nightmare - emacs users know how screwed up scrolling is already especially in large buffers.

I’m just glad that you can still compile a minimal emacs without dbus.


I don’t like how you can’t reason about commands. It’s all like do-magic-spell-etc without an intuition.


Emacs is literally the best self-documenting system in the world - zero exceptions. You can easily see the documentation of every function which usually explains what it does and what each parameter is for. And in case you are not satisfied with that, you can quickly jump into the definition and see the code for yourself.


„C-h f“ (help on function) or „C-h k“ (help on keybinding) at least gives you some quick information on any function in Emacs. I also recommend „which-key.el“ showing you which commands are bound when you typed in an incomplete key combo. You probably also want some improved completion engine like ivy/counsel showing you the key bindings in the command list after hitting „M-x“.

This way I discovered a lot of helpful stuff.


Or if you want to see exactly what a command is doing simple turn edebug on for it and step through it.


$50 and I don't even get a real book? that's too steep, man.


The book is worth every penny. I bought mine years ago for like $25, and since then the author has published multiple new revisions and I still can download them for free.

Mickey doesn't do this for profit. There's a word in Japanese - "Ikigai" (you better google it, I'm typing this on my phone).

For Mickey Petersen, explaining Emacs is his ikigai.

If you're thinking of using Emacs for longer than two weeks, buy the book, you will never regret it.


Doesn't do it for profit but sells it for $50, make it make sense? I don't care about the price because he does great work, but he really should allow those who want it in printed form to have the option.


There are continual updates, I bought it a few years ago and hope the author continues.


I might spring for it if the author had a pre-packaged "You want a printed copy? Click here for a pre-set on-demand copy." Trying to figure how to have one printed and bound, for those of us who aren't self-publishers, is a non-starter. Many of us prefer a real copy, one you can read without batteries, one you can scribble notes in the margin, one you have a spatial feel for where you are in the text, one you can put little color sticky flags and paper clips on the edges of interesting bits. One you can put on your special little shelf by your desk. O well.


I would buy a printed book, I think.

I'm not the kind of person that can read a manual cover to cover, but I pick one up occasionally, open a random page and find something interesting/useful.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: