Don't get me wrong, I'm not planning on creating an Emacs killer, nor suggest anyone do that. But, hypothetically, what are some fundamental pitfalls of this foundational application?
Almost all the comments here are about things that really possible to do in current Emacs i.e. 'feature-requests' and not "fundamental pitfalls of this foundational application". For me, it would be just:
- Redesigned with concurrency in mind.
- Common Lisp, Scheme, or anything else other than Elisp. [Just the same way Neovim adapted Lua instead of VimScript]
Someone created lem [0] which is basically an Emacs in Common Lisp. I don't know for concurrency but I hope it is designed to do so. Also there isn't org-mode.
There have been several recreations of Emacs in Common Lisp over the years, including Hemlock, CEDAR, and Climacs. They never catch on, because they’re not compatible enough with the existing base of emacs lisp software. This also applies to Scheme, although it did get closer to compatibility once or twice.
This is also closely tied to why emacs hasn’t been made much more parallelized - fundamentally, the design of emacs is too close to “a giant ball of global state”, mirroring an early Lisp Machine. It’s a high hill to design around, and it will violate basic assumptions made by most medium-plus interesting elisp code.
Do not let this dissuade you from trying! It would be a great if difficult accomplishment!
I enjoy using Lem sometimes, but mostly use Emacs. Lem is a very cool idea, and with Roswell it is easy to install and manage.
All that said, it seems like Emacs has been improving rapidly the last few years: native compilation of Elisp, LSP support, good integrations with LLMs.
More than org-mode, it needs a Texinfo viewer. Once you can access SBCL's documentation (and internal docs), now you have an almost complete Common Lisp editor with the basic features from Emacs.
Hard agree that these are true ‘fundamental pitfalls’ of Emacs’ design. However I may go further on your third point. I would like to see a dedicated new user/learner mode that in addition to saner defaults would be pretty fully configured and pre-loaded with the most common extensions/plug-ins/etc. This could then lead to development of dedicated documentation/tutorials that assist the new user in becoming proficient in the common style/habits of Emacs usage.
This could provide a much simpler full featured ‘base’ state for the app, that can then be customized from that point or can be stripped back by removing the more common add-ons and customized from the ground up.
It would in some ways necessitate a strongly opinionated set of defaults and an additional focus on documentation, but I think in the long run the app would benefit from higher retention.
I’m on the strong opinion that most highly configurable software should come with strongly opinionated defaults. “It’s infinitely configurable so you can do anything you want” is just… so annoying. You could implement an LLM using punchcards if you were mad enough. The thing that makes a tool effective is the fact that it constrains and specializes.
I'm against that. Some random user would use Org-Mode and it wouldn't need any IDE related extensions. Also, another programmer might just use Org-Babel and code in Common Lisp with org-babel and a REPL doing literary programming. Another one would use Emacs for IRC, Email and math with M-x calc and/or iMaxima and AucTex.
I'd make cursors be positioned within the document instead of on the screen. Currently, Emacs does not support off-screen cursors. If you attempt to scroll a cursor off screen, it will move within the document to stay on screen. This behavior is contrary to all modern text editors, and there is no good workaround. I once made a serious effort to start using Emacs, but ultimately stopped because of the annoying cursor behavior. (There were other annoyances, but none so fundamental and unfixable.)
It (kinda) has multiple cursors per document if you split the frame and display the buffer twice. For longer source files I find myself splitting horizontally, editing in the left pane, and using the right pane for secondary movement and reference.
I have a buffer manager that can switch the displayed buffer quickly, when I switch to a different buffer and back again, it retains it's "secondary" cursor position that is separate from the other view.
It is possible to emulate this in Emacs Lisp. I've created a package to that extent, see http://ankarstrom.se/~john/etc/emacs/scroll-without-point.el. (I've made a few changes to it the last couple of weeks that I have yet to upload, though.) I should probably publish it somewhere else eventually, but I've always felt it to be a bit of a hack. Still, I use it and it works well 99% of the time.
This might be a dumb question, but how would an off-screen cursor work in a terminal? According to my understanding of the way terminal emulators/ncurses work, the cursor must be positioned somewhere in the screen, even if it isn't visible.
ncurses lets you move the cursor to arbitrary positions, and also lets you hide it. And you can disable echo, so you can type without the cursor having any influence on what you see. This means you can treat the terminal cursor as though it's a software-rendered cursor in a GUI app and apply all the same rules. But nobody considered doing this when Emacs was first written (maybe it wasn't possible then), so the assumption that the cursor is always on screen is difficult to change.
This is a really interesting case of Emacs being so old that its default (and only in this case) behavior is just unable to comprehend current computer technology and usage. I think I am correct in saying that the lack of capabilities to have horizontal scrolling of a screen was an absolute hard limit of the teletype and terminal era. It should not be difficult to add such capability, but more than the obviously connected portions of Emacs’ code could implicitly rely on the assumptions that come from the impossibility of horizontally extending text.
I'll try to use the more common Windows/MacOS terms for it, but in emacs I often have the same file opened in two different panes within one window or two separate windows. I do this when I want to be looking at one part of a file while editing another.
Markers are used to mark a different point in the file and one can pop their location to a previous mark.
This still annoys me slightly after nearly 20 years of using Emacs.
In response to keypresses, it doesn't bother me too much, as I'm used to the Windows-style behaviour of PgUp/PgDn/etc. moving the caret, much as the Mac behaviour of not doing that is sometimes useful. But for mouse wheel scrolling, which I do a lot - precisely because on Windows this typically does not move the caret! - having point follow along has never felt right.
> But for mouse wheel scrolling, which I do a lot - precisely because on Windows this typically does not move the caret! - having point follow along has never felt right.
Iam pretty sure you can customzize that if you want.
> scroll-preserve-screen-position is a variable defined in ‘C source code’.
> Its value is ‘keep’
> Original value was nil
> Controls if scroll commands move point to keep its screen position unchanged.
> A value of nil means point does not keep its screen position except
> at the scroll margin or window boundary respectively.
> A value of t means point keeps its screen position if the scroll
> command moved it vertically out of the window, e.g. when scrolling
> by full screens. If point is within ‘next-screen-context-lines’ lines
> from the edges of the window, point will typically not keep its screen
> position when doing commands like ‘scroll-up-command’/‘scroll-down-command’
> and the like.
You’re misunderstanding. In those other apps the behavior is this: you open a document. You put the cursor on line 3 column 3. You use the mouse wheel or trackpad to scroll down to line 600. You hit cursor right. The cursor is now on line 3 column 4.
In emacs the cursor would be somewhere around line 600 instead.
It should be possible to save the cursor position, hide it if it moves away from view during scrolling, and restore it back on any command but scrolling, or at least at the firs cursor-movement command.
Conversely, I curse heavily at Mac programs where I can page down or scroll for a while, only to have an arrow press jump way the heck back in the document.
When you scroll away you can jump back by hitting anything on your keyboard. Also you can stay where you are, by clicking anywhere. It is a useful feature, that enables you to scroll to your heart's content.
The exact behavior isn't hugely important (although I think off-screen cursors are a useful feature). What matters is consistency between applications. There's no realistic scenario where I do everything in Emacs, so Emacs has to behave in the same way as other applications. If not, I risk data loss or corruption because I might fail to notice the cursor ending up somewhere I didn't expect. This is especially likely to happen with a feature like off-screen cursors that I use only occasionally.
You might know, but you can set marks to go back when you scroll off. I have to admit it's not as convenient as the cursor just behaving like that automatically, though.
One thing about Emacs, is it's not really just an editor anymore. Comparing it to other editors kind of misses the mark. It's more like an integrated Lisp development and runtime environment. It reminds me of Smalltalk environments, say Squeak or Pharo, albeit in a very text oriented way.
The world could probably make room for an integrated Lisp development environment that makes GUI programming more of a first class citizen. Maybe something like Medley Interlisp?
Emacs runs on terminals too. If you want GUI's, you can choose Common Lisp with Lem and MCCLIM, or that newish web oriented GUI with a similar environment.
And so? Emacs GUI already does tons of things that don't work in terminal:
- It can render different fontsets
- PDFs
- SVG and images
- Emojis and file icons
- Tooltips
- Drag&Drop and better mouse support (scrolling, selection, etc.)
I think it would be great to have a better GUI layer and native web-browser integration. Emacs' evolution doesn't have to be constrained by terminal limitations, and so far it doesn't seem that it was.
With xterm (Kitty, WezTerm, Alacritty) you can have good mouse support, hence you can have tooltip-like popups (AFAICT eldoc or lsp-ui-doc do it), and likely even drag and drop (never used it).
I suspect that with sixel support, and kitty image protocol support, images could be shown, too. At least, Eat, the elisp-based terminal.emulator, manages to show sixel graphics inside Emacs.
I don't care that much about the implementation, but I would like to see an emacs environment with:
- instant startup
- blazingly fast scrolling
- minimal keypress-to-display latency
I have written a lot of elisp (and had to deal with with buffer variables, dynamic scope, etc.), but aligning with modern scheme or lisp (if it can be kept compact and efficient) probably makes sense at this point. (Current emacs should provide backward compatibility as needed.)
Since so many people use emacs as an IDE, I think having an official emacs co-project/subproject focusing on a standard, extensible IDE framework (perhaps for other apps as well) would make sense.
It still seems like a pain to display graphics in emacs in various terminal apps. This should be easy, fast, and standardized.
As others have noted, supply chain attacks against open source are rampant, so vetting and sandboxing packages seems to be more important now.
I'm confused. On the modern devices I've recently used emacs on (including very low-powered raspberry pi devices), all of your three criteria are already true.
What kind of HW are you running emacs on where this isn't the case?
If you have better numbers and comparisons for emacs keypress-to-pixel latency, etc. I'd be interested.
Note classic vi started up faster than vim.
Device makes little to no difference: Raspberry Pi 5, MacBook Pro M1, ThinkPad P1, etc. - emacs is clunky on all of them. I like emacs and it's my daily driver. But it isn't fast.
I have often see some fellow coworkers start up their fairly complex vim/neovim/other-vim setups and quite frankly… they ended up recreating a poor emacs implementation.
Yeah it’s faster at starting up but it’s worse in pretty much everything else.
Oh and they end up typing Ctrl-this Ctrl-that anyway.
Emacs pauses are almost always due to some operation blocking in the main thread. It's pretty annoying and is mostly a consequence to a lot of things effectively being single-threaded. Stock emacs doesn't do this very often, but third party packages that might do expensive tasks often do
Receiving output from a process, as is done for example by shell mode and (I guess, but have not verified) compilation mode, is slow in Emacs because all output is run through comint-carriage-motion and ansi-color-filter-region (which does nothing but throw color information away IIRC) which are written in Elisp.
If you don't run the output through those 2 functions, then non-printing characters remain in the output that severely undermine legibility.
C programmers tend to develop the ability to glean information from the voluminous output of build processes as it goes whizzing by on a terminal, so they find compilation mode frustratingly slow. Or at least that is my guess as to what happens.
For instant startup I recommend daemon mode and emacsclient. Start emacs via emacs --daemon, open windows (in the terminal or otherwise) via `emacsclient` / `emacsclient -nc` (I use aliases for these).
The solution to "this text editor takes too long to start up" is poorly addressed by the solution to "just leave it running in the background all the time".
It really is not poorly addressed, as it's a reasonable solution to the issue which also brings about it's own benefits. If you have your system configured such that the Emacs server starts up when you log in, by the time you actually start Emacs it will long have already loaded completely. If you actually use your Emacs for several things throughout the day, including but not limited to reading and editing text and documents, then it is likely you will have it always running during that time with several files open, and will find it useful to be using Emacs in the same state it was in the last time you opened it.
As an aside, having it running in the background was actually the way the original EMACS that ran on ITS was intended to be used: When you C-x C-c out of it, it does not kill the program, it simply puts it in the background, and the next time you invoke EMACS it brings it back up. This is similar in effect to hitting C-z, then using 'fg' to bring it up again, but this only really works in a terminal. The Emacs server achieves the intended effect better, especially on a graphical display.
It's not a "solution"; you still need to solve your undesirably slow startup, but if you're having to kill and restart Emacs multiple times a day, something is wrong with your workflow. Normally, Emacs doesn't require restart - for weeks and months in some cases.
emacsclient is useful on its own. For example, I use it to edit just about any text, in any input box in any app, delegating the task to Emacs, or when I want to open some URL in Emacs, while browsing a web page in my browser, or to send some selected text to Emacs.
Well, if you see someone launching a browser, visiting website, then quitting it, and then later launching it again to visit another webpage, you'd tell them it ain't right, no?
Though trying to run Emacs like vi is a pitfall in itself. Clunking around the terminal summoning Emacs to edit files is really not a particularly effective way to use it. Emacs is not vi, and using Emacs like Emacs makes more sense. Most users explore your filesystem and spawn and monitor processes from within Emacs, rather than from a terminal.
Not that you can't work that way (and using `emacsclient` is the way to do it), but you're losing out by trying to shoe-horn usage patterns familiar from other toolchains onto Emacs. Emacs is not a text editor, it's a text manipulation platform that includes an editor - a number of editors in fact, including a vim clone.
I think running daemon mode has significant advantages. You can have frames running on multiple virtual desktops for different uses. You can also step away from a buffer, and return to it, maybe from some other location on a different computer.
My config is Doom-based. I use about 300 different third-party packages, and I don't even know how many built-in ones. It takes about 1.3s to start. Wishing for it to start even faster is like wanting my microwave to warm my tortilla in 5 seconds instead of 30. I don't restart Emacs every day, nor do I eat tortillas daily. Use a modern package-manager, and defer the loading of packages, it will start very fast - just like 'emacs -q' does.
> minimal keypress-to-display latency
A lot of times, setting keyboard rate is all it takes to make it nice,
> - Implement better sandboxing and security measures for extensions.
Why, pray tell, should this be of any concern at all?
Sandboxing is used when the host is concerned about running programs that he doesn't trust. There is no reason that an Emacs package would require security measures around it, unless it were knowingly potentially malware. The only reality in which I could see this is if people were using proprietary Emacs extensions, in which case I would entirely understand it, because then people would be willingly running malware inside their editor. Perhaps this the stance VS Code users like to take towards extensions?
> Sandboxing is used when the host is concerned about running programs that he doesn't trust.
Trust? Trusting criminals doesn't stop them from committing crime.
You may trust your emacs color theme author. Pretty colors from an innocent artist. You run the theme code without any sandboxing. Everything is going well. Then the author adds a keyloger, project code scrapper, and phone-home feature in his theme.
You update all your emacs packages automatically without any code review. Then you start getting emails from your companies security team asking why you uploaded sensitive projects to a 3rd party.
Wouldn't it make more sense to restirct color themes to color and font related tasks? Why should a color theme be allowed to scrape sensitive code from your disk and upload it to a 3rd party without your consent?
> You update all your emacs packages automatically without any code review. Then you start getting emails from your companies security team asking why you uploaded sensitive projects to a 3rd party.
If you do not trust the author or maintainers of a random program and refuse to review any code updates before installing it, then you are a moron.
I think if there is a concern that people would upload malicious packages, then there would be a level of trust put into the repositories that accept and offer them to review submissions before accepting them. This is still imperfect, but it shifts some responsibility off of you.
> Wouldn't it make more sense to restirct color themes to color and font related tasks? Why should a color theme be allowed to scrape sensitive code from your disk and upload it to a 3rd party without your consent?
Why SHOULDN'T a color theme be allowed to scrape code from your disk? Maybe the color theme is sophisticated enough to want to do that, or talk to some network. Something like a seasonal color theme that responds to the local weather might have a lot of hack value; and that is precisely the point you are missing. Emacs is not about restricting what you can and can't do, because the designers of Emacs understand that restricting what the user is allowed to do ultimately hinders freedom and creativity. It is one of the very few platforms left that's still like that, and I believe it should stay that way. If people want to use an editor that's very safe and tells them what to do rather than vice versa, then they should probably consider VS Code, or something like it which DOES upload your data to a third party without your consent, because it is smarter and knows better than you what you should be doing with your computer.
> refuse to review any code updates before installing it, then you are a moron.
I personally do review every line of Emacs code I run. But I'd wager only a small handful of Emacs users do that.
> Why SHOULDN'T a color theme be allowed to scrape code from your disk?
Security.
> precisely the point you are missing.
Not missing it. nabla9's suggested security measures for extensions. You then asked why security is a concern. You seemed to imply there wasn't any reason for limiting extensions if you trust the author. That's simply not true, as you can easily be sabotaged by the most trusted color theme author.
> You seemed to imply there wasn't any reason for limiting extensions if you trust the author.
That may be implied but the precedent is not important. The bigger consequent point I am trying to make is that there is no good reason for limiting extensions at all, and my reasoning for that will follow.
> you can easily be sabotaged by the most trusted color theme author.
Okay. Let's say that we solved the hypothetical issue of colour theme authors sabotaging their themes by requiring color themes to use a format that can't evaluate arbitrary code, only dictate UI options.
Now what about all of the other packages that aren't color themes, that do more useful things and require greater breadth of functionality? I am not trying to separate things into functional and non-functional, as it is futile to do so--there are an infinite number of separations between the degrees of utility packages have, and once you have "solved" the issue of their insecurity by restricting one class of them, there are always more. And every time you do this you only degrade the freedom and extensibility of the entire system; you do not gain anything by it, you only lose.
This phenomena can be explained because it's really an application of Gödel's Incompleteness Theorem. For any program running on any computer, it will always be possible to induce conditions that the program was never designed to handle. Thus it is my belief that the entire field of computer security is really a joke, and anyone who sacrifices freedom for safety ultimately ends up with neither.
In practical terms a bit of security is useful, however Emacs is not the kind of program that benefits from it. It is not useful to waste time reasoning about which methods of security should be applied to a text editor. If you were using Emacs to run an air traffic control system then this type of thinking might make sense, but not as a reasonable or common case.
Well, Emacs does ship with a browser (because of course it does, that kind of thing is what makes Emacs so amazing) and we all remember the XZ Utils near-backdoor, so I think that security measures would be useful for people who decide to use a less trustworthy archive like MELPA or who install extensions with package-vc.
The biggest security nightmare that web browsers have to deal with is that they are always continuously running random JavaScript. Emacs' browser doesn't handle JS, which is a good thing for a simple browser. Emacs doesn't share this problem in that the Elisp that you run is all chosen by you, and it's always free and never obfuscated.
I don't really see how the XZ backdoor is relevant to this conversation, since these types of exploits are the fear of server operators, and generally not people who run user programs like Emacs on their desktop. A rogue Elisp function could delete all of the files in your home directory if it wanted to, but people don't really complain about that because being able to delete files is a desirable function.
If you ask me, Emacs is a program where user freedom is and should be the ultimate goal. Adding security features that the user has to jump around 'for his own good' and only really serve as idiot nets are dubiously effective and only hinder this freedom. If someone wants to install a package from a source other than the official archives, then the trust is placed in him to actually look at the source code he's received. Even if you install an official package you should still look at the code, as it's quite useful to know what's going on inside it when you want to configure it or add functionality. The vast majority of packages I use are a single file and tend to not take up more than a few screens, so they are easily understandable.
A lot emacs usage today consists of running programs you shouldn't trust. And the rest of it is hard because you are either reviewing other people's libraries a lot, or simply not using other people's libraries, or updating infrequently.
For the Common Lisp part, someone created lem [0], but for the other points I can't tell. I know there is an extension manager being developped, but am not able to judge the robustness. Also that there isn't org-mode.
Scheme is smaller, has more static and less interactive philosophy. CL has most things you need straight out of the box. It's more like operating system than programming language. Exactly what Emacs wants to be.
elisp is more like CL than it is like Scheme; RMS was aware of CL when he was working on emacs, but was suspicious of some of its new features (like lexical binding).
Emacs' Elisp it's pretty close to Common Lisp, any CL user can learn Elisp in days (and the opposite it's true too). There's even a port of PAIP exercises into Elisp:
> If you were rewriting Emacs from scratch, what would you do differently?
UI: Electron, of course.
Json to represent the edit buffer in RAM. Each utf8 code point base64 encoded, in a json array, it itself, as a blob, base64 encoded. Now, before you complain that that is gonna blow up the data too much, don’t forget that 1. “Ram is cheap” and 2. “gzipped base64 is about the same size as binary”. So, of course, we’ll gzip the data in RAM.
Plugins should be JavaScript, as should be self-evident. And you’ll need a few installations of python (both 2 and 3) and node.js (each in its own docker container, obviously) to glue it all together and provide reproduceability.
With some care and work, it’ll run even on a modest machine taking up merely 60GB of disk, 32GB of RAM, a 4090ti GPU, and 8 CPU cores.
Every key press should be passed through an LLM, to add some intelligence to the editor. The user will, of course, supply a ChatGPT api key when they register for their mandatory myNewEmacs.ai account that they’ll need to subscribe to the editor for only the cost of a few lattes a month.
It is 2024, after all. One must use modern tools and technologies.
Support prettier typography (if the user is not interacting with Emacs through a terminal, in which case of course the typography is up to the terminal-emulation app). If text in Emacs looked as pretty as text on the web does, it would be less of a struggle for me to stay focused on the Emacs text. (Text on the web was already much above average in pleasantness to look at and to read in the 1990s.)
Get rid of any keybinding or UI convention that is there because that is the way they did it the AI Lab in 1967. Make the UI as familiar to the average computer user as possible (but keep the general design of a large rectangle of text) by using mainstream conventions (which come mainly from the Mac and Windows) for how to respond to this or that keypress or to clicking or dragging with this or that mouse button.
Inside Emacs is a cross-platform toolkit (where the platforms are MacOS, other Unix derivatives, Windows and the terminal) I would split Emacs into 2 projects: a toolkit and an app that uses the toolkit. That way, if someone wants to create an "standalone" org-mode app, Magit app or Gemini browser designed to appeal to people who do not want to spend any time learning to use Emacs the app or "Emacs the generalized interface to information", they have a straightforward way to do so. (These "standalone" apps that are as easy to learn as any other GUI app will I hope help popularize the Emacs ecosystem.)
One thing I definitely would not change is I would not make Emacs dependent on or closely integrated with a browser engine.
> If text in Emacs looked as pretty as text on the web does
Do you have an example of this? I can't tell any difference for the fonts that I use (with emacs-pgtk). I believe Emacs uses Harfbuzz (same as Chrom{e|ium}).
Most of the text on the web for example is in a proportional-pitch typeface.
Does your Emacs usually use a proportional-pitch typeface? If so and you're on Linux, I'll install the font you are using.
I've tried using proportional typefaces in Emacs (on Mac), but there was something off, so I went back to monospaced. I could try again now that I have a Linux machine.
The text in my Emacs looks almost exactly like the text in my Gnome Terminal. (A slight difference in size is the only thing I notice. To be painfully precise, (window-system) evals to 'pgtk on my Emacs.)
The text in Gnome Terminal is not terrible, for sure, but text on the web is a nicer in my experience.
Pardon me if you're ahead of me on this, but it sounds like you might be using a proportional typeface as the default or fixed-pitch face. You should get nice-looking proportional type if you set the variable-pitch face to your desired typeface and enter variable-pitch-mode in the buffer. E.g.,
I use IBM Plex Sans (proportional) as my default Emacs font, with variable-pitch as a no-op (i.e., defined as "(variable-pitch ((t nil)))" in custom.el), and use IBM Plex Mono as fixed-pitch.
Tips for using a variable pitch font as the default:
0. Choose default fixed and variable pitch fonts with identical baseline-to-baseline heights for a given size; this makes everything described below work better (e.g., this is true for all fonts in the IBM Plex family across all platforms I regularly run GUI Emacs on [Linux, Mac, Windows]).
1. Define a fixed-pitch-mode by copy-pasting the built-in variable-pitch-mode and making the obvious changes (both are trivial applications of buffer-face-mode).
2. Add fixed-pitch-mode to hooks for modes that don't play nicely with variable-pitch fonts (calc, dired, hexl, magit, terminal and shell modes, etc.), or where you just prefer fixed-pitch modes (hint: define your fixed-pitch-mode in a package so you can use use-package's ":hook ((foo-mode bar-mode … baz-mode) . function)" syntax to manage this).
3. Some modes that pop up windows (frames in Emacs parlance) within editing buffers require extensions (e.g., company-posframe-mode for company-mode) to work properly in variable pitch buffers.
4. Last, but certainly not least: assign a convenient key binding to toggle fixed-pitch-mode. I can't emphasize this enough! In fact, I've found that variable pitch is fantastic for coding in most languages if and only if fixed pitch can be quickly toggled on and off with a keystroke, iff this setting is per file rather than global (and iff both fonts have identical line heights, but this is a feature of font families rather than editors).
For this reason alone, I'd argue that Emacs supports variable pitch fonts better than most text editors.
I use IBM Plex across the board and I was trying to understand the font issue because I do not have it. I default to fixed-pitch mode for everything, and use variable pitch for UI elements.
Thanks for the info, but the result of that is not any better than the result of what I had already done. (I wrote a command that put an overlay on the buffer to change the typeface.)
It's not as good text on the web IMHO. Typography is very complicated, and I think the people who did the typographical details of Chrome and Firefox were very skilled, is my guess.
I used to use proportional pitch fonts for telega.el and certain document buffers, but I stopped because I find that with Jetbrains Mono (for me personally) there isn't any benefit even for longer text. I'd rather have everything be uniform.
Emacs is perfectly capable of rendering other fonts, too, though.
I have never tried but I assume you can do as well as a browser. But I would never use VSCode for writing generic notes. There is so much distracting mess in it.
I did setup Obsidian for a friend to write in Urdu, and that worked almost perfectly modulo some minor stuff.
Instead of using ctrl and meta modifiers, use a leader key like escape or semicolon or comma or some such thing as the prefix key for key bindings. In fact, this desire for leader-key-based, non-modal text editing led me to write devil-mode for Emacs: <https://susam.github.io/devil/>.
I know many people like to remap Caps Lock to function as Ctrl. However that setup does not quite work for me. There is only one Caps Lock key on the left side of the keyboard. I need Ctrl on both sides of the keyboard, so that I can use the left Ctrl key while typing Ctrl+P but the right one while typing Ctrl+A.
There are other options as well, like remapping the Enter key to act as Ctrl when chorded or using sticky modifiers. I think using an ergonomic keyboard with two large Ctrl keys on both sides of the keyboard is probably the best solution. I've discussed some of these alternatives in more detail <https://susam.github.io/devil/#why>.
I just leave Ctrl where it is and press it with the knuckle of my little finger. I do it just like the guy in the pic on this page, pressing the control key with his little finger: http://xahlee.info/kbd/how_to_press_control_key.html - because that pic is of my hand. (Xah might not recommend doing this all the time, but I've been doing this for nearly 20 years now and I've had no problems.)
For the past 3 years I’ve done the following remap Caps -> lctrl/esc, enter -> rctrl/enter, tab -> lalt/tab, backslash -> ralt/ backslash. Also have the physical right alt mapped to multi key/dead greek.
It works really well, and makes emacs much more comfortable to type in.
Downside is this keeps me locked to X11 and fighting the occasional app that reads the key codes directly.
Instead of making it an additional Ctrl key, you can also make it a new separate modifier key with XKB[1]. I've found this very useful over the years for WM-related key bindings, leaving the other modifiers for applications.
Tangentially, I really loathe how Wayland has no alternative to this. I'm expected to configure keyboard layouts in every DE or WM I use, which is a much worse UX.
I was very disappointed that Apple gave up that fight.
They also at some point joined the PC world in moving the nubs on their keyboard from "d" and "k", where you were more likely to notice if your fingers are not in their proper place on the home row. Now if your right hand is offset slightly to the right, you won't feel anything, which is less immediately noticeable than if the nub were under the wrong finger.
emacs is not its keybindings. you can bind your emacs keyboard to do what you are asking for; as you said, you wrote a mode for emacs that works the way you want, and it wasn't necessary to rewrite Emacs.
Making modal editing with a leader key the default rather than an option it currently is, is a pretty trivial thing to bring up as the stand-out "feature" a rewrite could provide.
I have actually done some work on a rewrite of the Emacs core in rust[1], so I have thought a lot about this question. Most of the things you would want to change could be fairly easily added to the existing Emacs. The biggest ones that are hard to do with the current core is concurrency and collaborative editing. My particular core is focused on concurrency[2].
Unlike a lot of commenters here, I am trying to stay backwards compatible with elisp. It is not the best, but huge body of existing code is one of the strengths of Emacs. Unlike vimscript, elisp isn’t painful enough to be worth replacing.
Have never tried it personally, but this talk made me think collaborative editing is a solved or close-to-solved problem in Emacs: https://emacsconf.org/2023/talks/collab/
1. I would like higher-level datatypes for key abstractions, such as
(1.1) Marks -> StableRegions
- reference specified text within a buffer
- continue to reference same text despite insertions or deletions
(1.2) Strings & characters -> StringBuffers
- lightweight immutable buffers (no branches or versions)
- able to hold any content a subset of a buffer can hold
- could be StableRegions of an Arena Buffer
(1.3) AbstractBuffers
- immutable buffers + a tree of deltas
- some special delta types for, e.g. indentation
- AbstractBuffers support transactions and versioning
- can support collaborative editing
- specific versions can be written to textfiles
- all versions can be stored in git or in relational database
2. Use WebAssembly instead of a specific programming language.
- This was the vision for Guile.
- Scheme one of several languages.
- ELisp supported but Emacs port efforts keep failing!
- The Racket ecosystem has captured this pretty well
- if only it supported ELisp!
3. Prefer languages at least as simple as Scheme, but with monotonic semantics!
Non-mutable operations would appear as transactions appearing as branches/versions.
An editing session would automatically follow the latest transaction in the current branch.
Concurrent edits of the same "file" create different branches as with git, et al.
4. Separate monolithic Emacs process into SessionProcesses, DisplayProcesses and WorkerProcesses.
Multiple DisplayProcesses would allow for tightly-coupled collaborative editing. A WorkerProcess would interface buffers with processes, files, git repositories, etc. on a specific account@host giving functionality like Tramp. A user would start with one DisplayProcess connected to a SessionProcess. A SessionProcess would provide the interface between DisplayProcesses, WorkerProcesses and any co-SessionProcesses of collaborators. WorkerProcesses could be scripted without any other overhead.
I want ALL of what Emacs provides, much more than any other "editor" - actually text-centric programmable productivity platform. And I want more than what Emacs provides, e.g. non-destructive editing and collaboration. So yes, there are other interesting editors out there such as Zed. And no, it's not about adding 1 important feature. I'm greedy!
I'd really prefer for emacs' implementation language to have been a lisp-1 rather than a lisp-2. It's annoying to have to do different things to treat a function as a value (put it into a list, assign it to a variable, etc.), as opposed to all other kinds of data. Any benefit you get from allowing name collisions (i.e. function named f, related but distinct variable also named f) seems very small in all elisp code I've seen and promotes confusion more than it enables desirable programming patterns.
I'd make lexical scope the default and dynamic scope opt-in on a per-variable basis. This one is probably less controversial. I think the devs are moving in that direction (e.g. by changing emacs core code to use lexical scope and adding warnings for code that doesn't opt into it), but I don't see how they will actually be able to change the default without breaking a whole bunch of user code.
My introduction to Lisp was through SICP and Scheme so I used to be in favour of Lisp-1, but having used Common Lisp for a while now I've changed my mind. Treating a function as a value is easy enough:
(mapcar #'list list)
It's like how if you want to treat a symbol as data you have to quote it:
The core should be in rust, verfied in lean, and the runtime should be in guile. Literate programming in org-mode should be a hard requirement. Package management should require patch algebra. Macros should be submitted to a leaderboard in a blockchain and yield flair in EUDC. M-x measure-beard-length should require 10000 hours of logged usage and unlock the major mode infinity-categorization.
Tongue-no-longer-in-cheek:
I reckon the C core of Emacs is some of the most battle-hardened code out there. Verification, a-la SEL4, is probably irrelevant but still nice. Guile is modern and performant but Elisp is still its own little joy. Literate programming is always nice until it gets in the way. Straight is good enough for me now. Macros are always cool and a leaderboard would be fun, but patch algebra is really nice, see jujutsu nowadays. And beard length is gendered and so only partially admissable. Infinity categories are way out there and always good for a reference.
Implemented mostly in Guile, with just some native primitives/kernel bits in Rust, makes a lot of sense, for a programmer's application platform in the spirit of Emacs.
> The core should be in rust, verfied in lean, and the runtime should be in guile. Literate programming in org-mode should be a hard requirement. Package management should require patch algebra.
Since I agreed with all of these, I’ll add some more non-ironic, idealistic wishes:
Plugins must be written in sandboxed WebAssembly so you can know what a plugin is capable of without reading the source code. The runtime must be portable so it can run in wasm32-wasi.
When I saw “should be in rust” my instinct was to flame like nobody’s business, glad I kept reading. Lmao. Good slow burn.
Though, not to put too fine a point on it, I know it was in jest, but the core implementation language is the least of my concerns. As long as it is extremely portable, compiles fast, and runs on virtually anything, then whatever the core is, doesn’t matter much to me.
I'd start with the core TECO editor I've written in Free Pascal[1].
Free Pascal does gigabyte strings you don't even have to allocate. Then I'd read the Emacs manual, and start writing code and tweaking TECO to make it all impedance match better.
But I'm old and weird, so maybe not the best way to get there.
I would change the development platform. Doing everything by mail makes things more difficult for people that are not used to the older mail+patch workflow. Having something like GitLab or sourcehut would be nice, as it would also bring a more modern bug tracker.
Personally I find following email conversations much harder than just a single conversation thread like in a GitHub issue, for example.
Yes, the Gmail web client does this. However my (personal) problem comes more from reading the emacs-devel archives, where the thread view takes the shape of something more like a tree (maybe I'm not configuring something correctly). I was subscribed to emacs-devel at some point (which made reading easier) but it started filling up my account storage so I un-subscribed.
Use https://yhetil.org/emacs-devel to browse the threads. If you use mu4e or notmuch and often delete some older emails locally, but still want to read the whole thread, you can write some elisp helpers that would find the thread on point (based on email-id) or even download the whole thread.
I recently learned FSF does have a GL instance but it seems to be locked down to just "approved" emails and also only used for its CI capabilities: https://emba.gnu.org/emacs/emacs/-/pipelines
I agree, and I've been observing this for years. It's now becoming a generational problem - younger programmers know and understand PR model, they don't want to deal with mailing threads and patches. These days, young people are like: "You sent me what? an email? Are you joking?" People shouldn't be catering for the comfort of the maintainers, no matter how arguably mailing threads are techologically more superior, it should be the opposite.
Biggest issue w/ emacs is once you start adding packages everything is half-broken. Ideal emacs replacement would preserve the ease of extension and flexibility but have more of a static time verification systems (types and ...?) to prevent bugs (and bonus, make easier to achieve speed too).
create an efficient async api for plugins. it’s kind of a kernel+apps situation. an extensible editor has to have a scripted plugin system, and they should be hosted by a core that is fast, can preempt plugins, and provides “ipc” btw plugins for advanced functionality.
I like emacs for its flexibility and its ability to be a platform for people to build just about any extension. So for this you'd need a solid scripting language. I was never sold on Lisp but it's fine. I'd prefer to see lua; it just makes more sense.
The repo-reference stuff works pretty well all things considered. If it were python it would be hell.
Crazy side of me would like to see it fully written in a safe(r) language like rust, swift or zig. Basically your config would be a recompiled subsystem, loaded at runtime, or you'd recompile the whole editor.
It wouldn't hurt if the config had a bit more structure. Forcing people to set fonts etc. BEFORE loading other things; essentially enforcing an order in which things get loaded. It can get hairy after years of working in emacs.
I love that it's keyboard driven and I'd keep that for sure.
The config should automatically be a git repository and any change should generate a meaningful commit (thinking out loud).
Better key handling and none c-x nonsense. Switching between keyboard combos and straight up shortcut should be a defined choice not overwritten by x. Every 'plugins' should expose their shortcuts override clearly. Have sane defaults that aren't 30 years of cruft. This means you'd have to consider running on mac just as well as windows, and in and out of the terminal makes this extremely tricky.
Better plugin system and discovery. Often the best and only way to find how to solve a problem in emacs was by finding some random gray-beard post on some forum by sheer luck.
> Crazy side of me would like to see it fully written in a safe(r) language like rust, swift or zig.
Emacs Lisp is a very safe language. Even though the Emacs core is written in C, that is immaterial and impalpable to Emacs users as they only interact with Emacs Lisp. What benefits would Rust / Swift / Zig bring to an average Emacs user?
> Basically your config would be a recompiled subsystem, loaded at runtime, or you'd recompile the whole editor.
elisp -> bytecode compilation in Emacs… predates humanity?
The entire stash of Emacs packages compiles into the byte code at the package installation time, anyway. Personally, I even byte-compile-file my ~/.emacs to eke out an imperceptible speed improvement at the startup time, which is slightless less than entirely useless but it warms my heart that I can do it.
Recent versions of Emacs can also compile Elisp into the native code:
The pseudo-JIT provided by gccjit is really quite good. I’ve been using emacs for a pretty long time and it is definitely the most noticeable improvement they’ve added so far (and it even works seamlessly out of the box on windows!)
It is exceptionally good, indeed. Emacs now starts up in an instant (< than 1 sec) from the cold to a fully working state, which includes loading a hefty .emacs
> I'd prefer to see lua; it just makes more sense.
To you. To me it wouldn't. If it was Lua, I'd still use Fennel. If it was Javascript, I'd do it in Clojurescript; If it was in C, I'd probably find a way to use Common Lisp or Jannet; If it was Python I'd probably use Hylang or something; if it for whatever reason used JVM (like IntelliJ) or .Net CLR, I'd do it in Clojure.
You see, once you actually grok Lisp, at some point you do become a true "polyglot programmer" - for me switching between different runtimes - JVM, Node, Browser, Native, Lua, etc., is as simple as picking up a different Lisp dialect. Even switching between JS and TS for most programmers is not as simple as for me jumping between different Lisp dialects.
I'm not some indentured servant of one particular programming language, your favorite bits of syntactic sugar and "design patterns" made for one particular PL don't amaze me, don't annoy me, don't make me feel bad or good, I simply don't care. I just want to build shit, and I want it to work. I'm sure if there's an actual God, and he had to explain the universe in written form, it would be in homoiconic scripture - anything, yes, just about anything can be explained in functions, neatly wrapped between parentheses, anything beyond that is fluff made by human pride, simplicity requires less not more.
There's something about it where it doesn't feel quite right when using the mouse as a GUI app. Compare it to something like Sublime Text. I can't quite describe it exactly. It just feels off. It feels like you are supposed to use the keyboard shortcuts to navigate around, and the mouse is sort of bolted on secondarily or something. So I would try to make it feel more like a modern GUI app, where using the mouse feels right.
Disclaimer: my experience with Emacs is limited. I've only used it because it's the path of least resistence to learn Lisp.
So for me it would be: everything that makes Lisp programming easier, like:
- Use a Lisp implementation that's not tied to the editor.
- Slime/Sly + Quicklisp functionality out of the box.
- Integrated syntax awareness, preferably "syntax directed" for programming.
There is more, but it'll be obvious (like updated defaults and looks) unless you want to make an outright clone, or at least a direct replacement option, I wonder if that's what you mean: "rewriting Emacs" seems to suggest it is.
It's difficult. These big old projects like Emacs, and Lisp itself, have both succeeded and failed. There are features that made them last decades and others that made them stop attracting new users. How to capture the appealing parts without reproducing the quirks?
I used to do a lot of consulting work using Common Lisp on remote servers and would frequently need to set up tmux, Emacs, SBCL, Slime, etc. on remote servers to do my work. Keep good notes, and it gets much easier and faster.
Past month I setup ssh accounts to access a remote server using Laravel. The guys doing the programming absolutely hate the console, but it turns out VS Code can work through ssh connections just fine. Not sure if it can also debug, but editing was seamless. I wonder if it uses sftp or escape codes.
It’s interesting the divide we see here between particular implementation choices, and very general design principles. FWIW I think this exposes some of the tensions in Emacs’ design itself. The fact that everything is customisable is both great and the source of many problems, and it depends on which direction you want to go how you want to move that particular needle.
I’m not totally sure what I’d do. The semantics of multithreaded or async alteration of buffers are not easy and so, even though they would be great in many ways, might make simple customisation just too painful.
More to the point, emacs already has been rewritten substantially. There’s the initial rewrite from TECO to lisp, there’s the 80s implementations like uemacs (famously used by Linus), we had a major fork with xemacs in the 90s, there’s guile emacs (ready any day now), lem is almost but not quite a Common Lisp emacs, and it’s been making a lot of progress recently. So go ahead with your rewrite, you’re in fine company!
Also, there were other emacses that preceded GNU Emacs and were written from scratch: Bernard Greenberg's MULTICS Emacs, written in MacLisp [1], James Gosling's Unix Emacs, mostly written in C [2], and Daniel Weinreb's Zwei, written in Lisp Machine Lisp [3].
I wish it were built with a very small, minimal core, that was just the TUI with the lisp machine like functionality, scriptable using R7RS scheme instead of elisp. And then everything else is built on top in a more modular fashion, with "battery packs" that install many modular components into one higher level functionality, like an IDE.
I'd like to eventually write something like this, there are a lot of things it would enable that you just can't do with emacs. It would be an emacs killer if implemented well, but it would also open up a whole new set of possibilities.
I don't know how far I'd get just working on it on my free time, which is competing for time with other projects. I'm looking for funding for these sorts of projects. If anyone reading this is an investor and interested in funding this sort of thing, please reach out.
What are you talking about? Emacs has incredibly good window control. It is in fact so good, people decided to build window managers on top of Emacs - see EXWM. Yes, the customization is complex and very confusing for beginners, but the levels of control are all there.
That was 12 years ago. Are you complaining that Emacs got sane window management "only" twelve years ago? Please don't ever get into Node.js ecosystem, the pace of accretion would make you cry, standing in the shower, rocking back and forth.
Buddy I started using Emacs at version 1.8, and no display-buffer-alist is not "sane". Just maintaining a stable window arrangement in the frame is not something easily possible.
I'm not sure what you exactly talking about, I'm having hard time separating "facts" from "personal opinion" here. I'm not sure what you mean by "stable window arrangement" to be honest. As a practical example I can only think of "jumping between places" feature, where If I, for example to have multiple windows and tabs open in the same Emacs frame (well technically speaking, tabs kinda make separate pseudo frames, but anyway), I currently don't have good mechanism of finding "the place", there's no good way to build "the breadcrumbs path" where you can traverse through all the places visited, Emacs afaik doesn't have good mechanism of finding exact tab/window/buffer/location, I don't know how much of it is related to your idea of "stable window arrangement".
Overall, I'm personally happy with Emacs window management, it's highly customizable and extensible, it gives you powerful keyboard-centric control, it supports complex layouts, it is deeply integrated within Emacs' vast ecosystem. There are packages like ace-window, winum, winner-mode, golden-ratio, shackle, popwin, eyebrowse, perspective, window-purpose, etc. I don't know what you're complaining about, I guess because I have not seen something even better than that.
he goes by the moniker 'prot' and has tons of very very good emacs information (both on his website, and youtube). always worthwhile to check them out !
as someone would say, if you like that kind of thing, this the is kind of thing you will like :o)
After years of vim and windows parkour, I started using Emacs, and while the windows management was a bit irritating at first, I made my peace with it and use them in a more focused manner and rely more on the buffer list. I use register if I need a particular configuration.
Vim feels like working on a moodboard while Emacs is more a study desk.
I've been using Emacs for 25 years daily and this is still the thing that I think hasn't been really thought through. Yes there are hacks to mitigate that but there are still many rough edges with them.
>Get rid of any keybinding or UI convention that is there because that is the way they did it the AI Lab in 1967. Make the UI as familiar to the average computer user as possible (but keep the general design of a large rectangle of text) by using mainstream conventions (which come mainly from the Mac and Windows) for how to respond to this or that keypress or to clicking or dragging with this or that mouse button.
- throw away c language mode and and rewrite it from scratch
- make dired more usable like a normal file manager. opening a file with the associated program that would persist after emacs closes should be its primary feature. ideally i want something like a mix of ranger/lf with dired
- make it have fully-featured terminal, not dumb terminal. make it easy to open lots of terminal windows. add a way to change terminal directory with fido or dired
I would use Python as the extension language since it is omnipresent. ELisp has lots of terrible misfeatures that makes building large software in it difficult. I would also add better support for the services model. E.g., rather than adding spell-checking and syntax-highlighting modes you could defer those tasks to LSP servers.
Take a look at the Mac editor Alpha. It is arguably emacs-in-tcl and did a very nice job of balancing cua-style keybindings with emacs-style. Better, if I remember correctly, than things like cua-mode. It’s been literally decades since I’ve used it though, and it might be impossible to square that circle in a way that’s really frictionless.
The main quality I remember Emacs having compared to something like VSCode is its ease of extendability - but I don't know how to balance the liveness/messyness of a personal Emacs setup and wanting to package some of those bits to third parties. I think its a tension there...
I think others have hinted at it, but for me any foundational application must be written in a statically typed language, but cannot be C nor C++ /me glares at Chromium
The bad news is that I don't currently have enough free energy to help the remacs nor emacs-ng projects, but I am glad they exist
I would
1. Make it more capable as a full GUI - currently I have trouble displaying jupyter notebooks with images/progress bars etc in it.
2. Make an 'emacs app store' where you can get paid plugins (I'm going for Cursor).
3. Make collaborative editing possible.
I would use a more mainstream dynamic language like python or lua rather than emacs lisp. It has to be dynamic and maintain the flavor of repl-driven development (the whole point of emacs is that it’s one big X repl where today X is emacs lisp). It doesn’t have to be a lisp though.
It feels to me, people suggesting using anything other than Lisp haven't had sufficient, heartfelt experience with Lisps. Give me a Lisp any day, sure, Elisp might not be a best of Lisps, but it's a Lisp nonetheless, there's simply nothing better for evaluating things on the fly, there's no better language for rapid prototyping, for structural editing, for metaprogramming.
One has to experience the flow, the fluidity, the functional constructs of Lisp to truly appreciate its elegance and expressiveness. Lisp's code-as-data philosophy enables seamless metaprogramming, where code can be treated as data and manipulated with the same ease as data structures. This unlocks a level of abstraction and composability that is unmatched by most other languages. The functional nature of Lisp, combined with its homoiconicity, encourages a declarative and modular programming style, promoting code reuse and maintainability. Once one immerses themselves in the Lisp way of thinking, the flow of writing code becomes a harmonious dance, where complex problems are broken down into simple, composable functions that can be effortlessly combined and transformed. It's a paradigm that fosters creativity and empowers developers to build robust and extensible systems with remarkable ease.
Sure, Python, Lua, Javascript, etc. They all may seem more familiar, and yet they lack the profound simplicity and expressiveness that lies at the heart of Lisp. While these languages have their own merits and widespread adoption, they are ultimately constrained by their rigid syntax and imperative nature. Lisp, on the other hand, transcends these limitations with its minimal yet powerful syntax, allowing code to be treated as data and data as code seamlessly. It fosters an unparalleled level of metaprogramming capabilities, enabling developers to write code that writes code, unlocking a realm of abstractions and transformations that are challenging or impossible in other languages.
Yes, very challenging, see the examples of using Hyperfiddle/Electric, here's one: [SpreadSheesh! talk by Dennis Heihoff - YouTube](https://www.youtube.com/watch?v=nEt06LLQaBY)
When you say "It's one big X REPL... and it doesn't have to be Lisp", it's already conflicting because you need Lisp to have the proper REPL experience. Those non-homoiconic languages that promise a REPL don't actually provide the "real REPL" experience. Their interactive shells are more limited in comparison to the true REPL provided by Lisp dialects, where code and data are seamlessly interchangeable.
upd: darn, I guess I didn't scroll too far, all the people complaining about Lisp are at the bottom, downvoted and I guess angry because they don't understand why. It's like someone moving from China to US and complaining why everyone refuses to even try Mandarin, after all it's the most widely spoken language in the world, why wouldn't it make sense to use it instead?
> Do you have a concrete example of something you can do in a lisp repl like emacs that would be impossible to build into a python repl?
This is a challenging question, it's difficult to answer in a short few sentences. One practical example that immediately comes to mind is the advising system of Emacs, where you can modify specific parts of any given function, which isn't easily achievable with Python.
In a Lisp REPL, you can modify the behavior of the REPL itself on the fly, e.g. advising it to print the execution time of each expression sent to the REPL. The homoiconic nature of Lisp allows us to treat the REPL's evaluation function as data, modify it, and immediately see the results. This level of runtime modification of language constructs is not possible in Python's REPL.
You can get very specific and start challenging that statement. We can talk about bytecode execution, and how you'd need to modify the bytecode at runtime or alter the interpreter's execution loop, or Python's function object structure, or method resolution order. We can talk about descriptor protocol which handles method binding, we can speculate about JIT complications, thread safety, garbage collection, etc. At the end, it all boils down to homoiconicity. The homoiconic nature of Lisp - Code As Data, Uniform representation, Meta-circular Evaluator, etc., all that makes the difference for the things that aren't realistically achievable in non-Lisp languages.
That opens up many interesting practical possibilities, like creating interesting DSLs with minimal syntactic overhead and runtime efficiency.
People love their favorite programming languages for their specific features. They get used to them, it's a matter of familiarity, they get attached to their language of choice. Almost every language book offers you some unprecedented magic with their language.
And often programmers look at Lisp as just another programming language, missing the main point about Lisp, which is not one concrete language implementation but the idea as a whole.
Learning Lisp offers something fundamentally different. It's not just about acquiring a new syntax or set of features, but about gaining a new perspective on programming itself. Lisp provides insights into the nature of code and computation that are hard to fully grasp in other languages. The benefit of learning Lisp isn't necessarily in using it for every project, but in how it reshapes your thinking about programming. It can make you a better programmer in any language by deepening your understanding of abstraction, metaprogramming, and the relationship between code and data. Many concepts that originated in Lisp have influenced modern languages. Understanding Lisp can help you appreciate and more effectively use features in other languages that were inspired by Lisp, and that is a pretty much every PL in the TIOBE list.
I still don’t understand what advising has to do with homoiconicity. When you advise a function in emacs you’re not traversing its code as data, you’re adding some code to run at a predefined hook like :before, :after, etc., and I don’t see any reason why you couldn’t write a python interpreter that also lets you do the same thing. You could also have a repl implemented on top of this interpreter in python itself and advise and modify the running repl — just like you can with emacs.
So I’m again asking for a specific, concrete example of something you can do in emacs lisp that you couldn’t make a python interpreter do — not just waxing lyrical about how great lisp is.
Right, advising itself on the surface doesn't seem to be inherently tied to homoiconicity, here's the concrete example in Elisp, this would print how long it took to evaluate a form.
Now every lambda expression will print a message when called.
To implement something like that in Python, you'd have to modify the parser and complier, alter the runtime, reimplement core language constructs, but most importantly, you will have to change Python's syntax to make all code easily representable as data structures. Which then will become not Python but entirely different language.
I mean, if a function that uses lambda has already been parsed and compiled, I’m guessing it won’t magically be updated to use the new definition of lambda. Not sure if I’m correct about that.
In this case it would't care. Since it's basically redefining what (lambda) means to the Reader. That is where that notorious distinction of Read-Eval-Print-Loop comes to play.
1. Read:
- In Python, the read phase must parse text into an intermediate representation (AST) that is distinct from Python's data structures. During the read phase, Python using built-in tokenizer and parser, parses its infamous indent-based syntax, handles literals, identifiers, keywords, operators, decorators, docstrings, comments, etc. Finally, it builds an AST.
- In Lisp, the read phase produces a data structure (s-expressions) that is directly usable as code. The syntax and the abstract syntax tree are essentially the same thing. Lisp uses built-in Reader - parses s-expressions while handling special syntax elements - quotes, backticks, commas, hash-quotes, handles reader macros, parses numbers strings, other literals, comments. But! No need to build an AST - the code already is.
2. Eval:
- Lisp can evaluate the s-expressions directly. The code is data, and data is code. That's where macros get expanded before the evaluation, function calls are resolved, symbols are looked up, tail calls optimized, byte-code compilation is available but not mandatory.
- Python must compile its AST into bytecode before execution. Python uses stack-based VM, figures out scoping and class namespaces, special forms (if, for, def) handled by specific bytecode instructions. Decorators are applied, reference counting and GC, tail call optimization (if runtime has it, standard CPython doesn't). It always has to compile bytecode before execution.
- Lisp macros operate on the code structure directly, allowing for powerful metaprogramming. Python's metaclasses and decorators are more limited in comparison.
3. Print:
- Elisp's printed representation of data is often directly readable as code. What you see is what you can evaluate. Eisp has built-in circular structure handling, Python doesn't. Elisp's printing is more focused on producing readable/evaluable Lisp expressions
- Python's printed representation, especially for complex objects, is often not directly executable code. Python's object-oriented approach allows for more customization through methods
4. Loop:
The Loop phase in both cases ensures that the REPL continues to accept and process input, making interactive development and experimentation possible.
- In Lisp, you can easily manipulate the environment, even the REPL itself, using the same language constructs.
- Python's REPL is more of a black box from the language's perspective.
I think you're mixing up other Lisps with Elisp. In this particular thread I'm specifically talking about Elisp, even though, in retrospect, I should've been more explicit about it and not dropped the 'E'.
AFAIK, Elisp is an interpreted language by design and always has the ability to evaluate s-expressions directly at runtime, there's no compiler-only implementation of Elisp. There's native compilation introduced in Emacs 28, but it just adds a layer of optimization, the interpreter still exists and can evaluate s-expressions directly, it doesn't turn Elisp into a "compiler-only" implementation.
But yes, there are other Lisps that compile code to machine lang, without an interpreter.
Especially since many compiler-only implementations can evaluate Lisp code at runtime, just fine, even though they don't execute s-expressions in an Interpreter. Thus an compiler-only Lisp can be used to implement Emacs just fine.
I used for many years an Emacs on top of a compiler-only Common Lisp.
Many of the non-sarcastic responses here are subjective changes (scripting language, core plugins, alternative control schemes) that will change what Emacs is for other people.
But I think we can find a lot of agreement around launch speeds, latency, typography and similar.
Just use Acme under Plan9port. What you said it's the idea the plan9 guys had under to create a Unix 2.0 based 'Emacs' editor instead of vi and the pseudo graphical Sam.
> where you can interpret any language and have them with together.
You can have multiple different source blocks in a single Org-mode document. All in different languages, and they can be passing results between one another. e.g., you can run a piece of bash that runs curl, then send the results of it to Python block, where it calculates something, then to Javascript block that uses some npm package and and then send the results to a SQL block that queries a database and generates a report.
Let us write plugins in whatever programming language we want and provide some simple interface like Unix sockets or something for us to communicate with the editor process.
Instead of making the first class installable extensions plugins create a primitive called modes that encapsulate groups of plugins with extra configurations so that instead of having to pick every plugins for our setup we just pick the most popular javascript or ruby etc. mode and then add a couple of our own plugins on top.
Add some system that suggests hotkeys based on usage. If I hit l 20 times instead of just hitting f’ to get to the end of the line show a popup. Gamify the key maps and suggest key maps and features even from my plugins.
Instead of having a package manager for your editor just use homebrew and integrate it deeply into the editor.
Improve performance handling large files and large numbers of buffers. Emacs has been my daily driver for the last 10+ years and yeah perf could use some help. Everything else is superb.
is it me or is emacs just incredibly slow on machines which have endpoint security installed? O/c it's not emacs' fault directly, but all the compiling and loading in of small files really hurts the cold start scenario.
So I wish the compilation would just be done once in somebody else's pipeline not in every client.
It's not just you, and it's especially painful on Windows, where working with lots of small files is already painfully slow under the best circumstances.
I bet you're talking about Mac. I hate coming back to Mac after using Emacs in Linux. It feels so sluggish. Even on my Android tablet Emacs works faster than on a M1 Mac.
Their version of Lisp is clearly not suited for any large-scale development. (This trickles down hard into user experience, i.e., lack of parallelism or multithreading.)
Is this so obvious as to go without examples? I'm no Emacs power user, nor even really an Emacs user, but it certainly conflicts with my understanding of core Emacs.
I'd trade my dog to have Clojure-like maps and destructuring in Elisp. Comparing workflow with maps in Clojure and alist/plist in Elisp won't get any points to Elisp side.
None of the main selling points of emacs have anything to do with its shortcuts or using it in the terminal. Plenty of emacs users (including me) rarely or never use it in the terminal. It’s a GUI editor just like vscode is.
I think this misconception comes from the fact that (1) people often compare emacs and vim, and (2) vim is usually used in the terminal. But emacs and vim are really categorically different things so I think the “emacs vs. vim” meme kinda doesn’t make sense.
While Emacs is recognisable for its shortcuts, it is hardly a defining feature. Example: Doom Emacs adds Vim shortcuts, and it is still distinctly Emacs.
I think of VSCode as “Emacs, but JavaScript instead of Elisp.” That’s one thing I would not choose, in spite of the good things VSCode brings to the table.
Can I hit one key combination to edit the JavaScript corresponding to any vscode command, debug it and possibly modify it however I want? If not, it’s not really comparable to emacs IMO.
I hope not. Watching the Emacs ecosystem evolving over the years, I'd wish that most things were not default or built-in but came in packages, and Emacs was a tiny, extremely small core. Packages outside of the Emacs core develop faster, evolve better, foster communities around them, have greater flexibility of choice - where to host them, how to license them, how to structure them, etc. Evil-mode, Magit, Projectile, CIDER, etc., they are all great because they were developed outside of the Emacs' core. I can only imagine how Evil+plugins would've slowly decayed with endless email threads on the Emacs-devel mailing list, where RMS would've annoyed everyone asking "why are we trying to build Vim in Emacs instead of Microsoft Word, I've dreamed about WYSIWYG, and you guys are ruining it...".
Realize that VI was the superior editor, give up on the endeavor, print out the code I had already written for emacs, shred it, then set the shredder unceremoniously on fire.
That just means you have not reached the point of understanding the philosophy of Emacs. Comparing Emacs and Vim with a one-sided perspective like yours is like saying that motorcycles are better than trains. Sure, they both serve the purpose of reaching from point A to point B, but there's a lot more to it than just that. Similarly, Emacs is far more than just a text editor. Vim's model of navigation is an amazing, beautiful, powerful, and pragmatic idea. Have you ever used it anywhere else than Vim/Neovim? You see, the thing is, there's no such thing as a "vim-plugin", and I'm saying this with confidence of a die-hard vimmer. I've tried them all - different ones - IdeaVim for IntelliJ, Sublime Vim plugins, VSCode extensions, etc. All of them are pretty much filled with laughable deficiencies; they are not even shadows of the actual Neovim experience. With one notable exception, and that is the vim-implementation in Emacs. In Emacs, Evil-mode doesn't even feel like an extension, an afterthought; it feels like it's a baked-in, major feature of the editor. More than that, it can do certain things even better than you can do it in Neovim.
If someone had built a passenger plane with vertical take-off/landing capability, a mere accidental feature of the aircraft that nobody was even supposed to use, I would still respect the heck out of it because the mere presence of it would be proof of ingenious engineering. If you think that "VI is a superior editor than Emacs", I'm afraid you still have a shallow understanding of both.
> Thank you for your long and thoughtful prose, so fitting for an emacs user.
Are you hinting at the fact that I used Emacs to help me write that? Sure I did.
Why wouldn't I use Emacs for writing, if all the tools I need are at my fingertips? I have a thesaurus, spellchecking, Google Translate and search, dictionaries, etymology lookup, word counter, Flesch-Kincaid reading ease tester, ChatGPT, Anthropic and other models, dictation, formatter, and many more. Why would anyone ever exposed to that power willingly part with it?
> One day, when you value productivity, might I suggest
What point of "I'm saying this with confidence of a die-hard vimmer" was unclear? I already use both Emacs and Vim - they serve different purpose for me. And trust, me if YOU value productivity, one day you may wake up with realization - Emacs actually vims better than Vim.
Look. In our field of software crafting and Computer Science, conflicting ideas and principles frequently arise, especially when balancing competing concerns. We often need to weigh out performance against readability, abstraction and efficiency, flexibility over simplicity, security vs. usability, consistency over pragmatism, etc.
Yet, it's relatively rare for ideas (especially good ones) to become completely invalidated or rendered totally obsolete. Because ideas often retain their value in specific contexts.
I already told you my take on the idea of Vim and modality, it's a wonderful, beautiful, powerful, and pragmatic model. Now, Emacs builds on the cornerstone of another incredibly powerful idea - the idea of practical notation for lambda calculus, which is known as Lisp. Lisp probably can be crowned as one of the most important ideas in computer science. It's just hard to think of anything more influential than Lisp. Any programmer who dismisses the idea of Lisp based on one concrete implementation of it is misguided.
At some point, after many cycles of frustration, amazement, inspiration and awe you will learn to appreciate certain ideas. I'm not selling you Emacs or Vim here - not one concrete implementation of a concept. I'm just trying to tell you - some ideas are worth learning more, before dismissing them as needless or impractical.
Hmm, I don't really have a "go-to" programming language. Depending on the problem, context, constraints, and team preference, I use whatever.
For personal projects, my preference for the past few years invariably has been Lisp dialects. I prefer Clojure-like lightweight PLs - Fennel if I need to deal with a Lua-compatible runtime, Clojurescript for JS-engines. For bash scripting - Babashka. If I need to be close to metal, Common Lisp is great, but it's been a while since I had the need. I've been trying to fix this asynchronous pipeline in nbb that uses Redis and BullMQ, among some other things (for some of them, I'm thinking I may have to brush up on my Python - hopefully, I wouldn't have to), but it's taking longer than desired, been procrastinating with it a lot.
Why do you ask? You can't decide what to pick to start with or something?
I just always meant to dabble more in a lisp style dialect and was curious what an emacs enthusiast enjoys. Clojure has been mentioned before and I’ve heard good things about Clojurescript. I never heard of Common Lisp for being close to the metal, more so that it was a bit memory heavy in those applications, but I’ll have to take another look. What’s NBB? Python is undeniably a workhorse for most applications and aside from Java probably the easiest to hire for.
babashka was created to mitigate JVM slow startup. It's great for system scripting, automation, etc., basically a lightweight Clojure.
I think any programmer would benefit from learning a bit of Clojure. It's really nice for dealing with data, automation, etc.
I once had to scrape hundreds of videos from a website, and I was pleasantly surprised how quickly I was able to get it right, after setting up Puppetter and Cljs REPL, I interactively, from the REPL "clicked through" things controlling the browser, and created an async pipeline that opened hundreds of pages, looking up for video metadata and delegating the task of fetching videos to yt-dlp.
After learning Clojure and Clojurescript, I felt like all these - Python, JS, and Java are overrated and needlessly messy. I'm so glad I don't really have to directly deal with them daily. Even Lua, which before I had no problems whatsoever, and really enjoyed using, suddenly felt like "meh," and I'm glad there's now Fennel, which is not Clojure, but is very similar to it.
It's been years since I made anything mobile-native. I'll have to be choosing between React Native via Clojurescript and Clojure-Dart - which is very nice.
I am very excited about Jank-lang, can't wait for it to hit the first production-ready release, it will open some new possibilities.
So, I guess, I wasn't completely honest in answering what my "go-to" language is - I really don't care, it's just a matter of picking up a Clojure dialect for it, which itself being a Lisp dialect, is a choice among many other flavors of Lisp. Want to be a true "polyglot" coder? Just grab a Lisp.
I can understand why Lispers are often perceived as "crazy ones", it does sound crazy - "How is it possible for a single language to get absolutely everything right?". Well, no, it doesn't get "everything right", but at the very least the ideas it exposes you to can shield you from having to memorize the weirdness of tons of other languages.
That’s fair, one of the big things I always enjoyed about languages was the communities that form around them, I actually think that’s more important than the language itself. I will say that the Clojure community has to be one of the better ones that exists.
Yeah, the Clojure community is definitely full of great people who are always eager to help. Many times when I've asked seemingly straightforward questions in the Clojurians Slack, I've often received more than I asked for - deep, thought-provoking answers. People genuinely try to give you good direction and guidance.
Emacs has an amazingly nice editor, especially for writing in plain language. It even supports right-to-left languages and things like Sanskrit. There are frequent posts in /r/emacs about using it for writing. Many novelists use Emacs for writing, some of them are well-known names - Cory Doctorow, Neal Stephenson, Vernor Vinge, Charles Stross, et al.
There are a number of nice packages that help you with writing - spellchecking, thesaurus, dictionaries, translation, definition and etymology lookup, LLM integration, export capabilities, distraction-free modes, various text manipulation tools and more.
The joke that Emacs is an operating system that simply needs a decent editor has not aged well. It's not even funny in the slightest; it's laughable in the face of the joke teller, telling more about them than Emacs and its editing capabilities.
Dear Cooking Show, I really liked your recipe for the shrimp-avocado salad, and I tried to make it, but since I was out of avocados I just substituted them with potatoes. Also, it turns out I didn't have any shrimp, so I just used some hot dogs I found in my freezer. OMG, this recipe is amazing. You just made my day.
---
That's what using X instead of Lisp to make "a better Emacs" sounds like, okay? Emacs is a Lisp-machine, it's built on top of Lisp, it needs Lisp to be Emacs. Otherwise it wouldn't be Emacs. Like at all. Don't be stupid, stop saying stupid shit like "python instead of lisp"...
GNU Emacs is a Lisp implementation with an abstraction layer over the hardware and OS. I would like to reserve "Lisp Machine" to computers with an actual Lisp operating system or emulations of those.
Of course. I understand that calling Emacs "a Lisp Machine" is quite a stretch, but due to the lack of any actual prominent hardware-based Lisp machines these days, I think it is a permissible simplification for the orange-site discussions. Yet it is, indeed, an important clarification, I appreciate it.
These are interesting from historical educational point of interest, but they rather don't have practical use for modern software development, do they?
> I do understand that for you Emacs is a Lisp development environment first
It's not "for me", it is what it is. Emacs first and foremost is a Lisp machine, with a text-editor built into it, not the other way around, it's not a text-editor that uses Lisp as its configuration language.
"user experience of Emacs" is to be able to send any expression and sub-expression without any preceding ceremony directly to the REPL. Everything what Emacs does stems from that. No, Python doesn't have the same REPL. Every single stage of it in Python is different. Lisp's Read, Eval, Print, Loop - they all have slightest differences. Those differences are possible because of Lisp's homoiconic nature. Because of that you get Lisp macros, because of that you get advising functions, because of that you can do source blocks in Org-mode that can interact with and modify their own execution environment. Lisp's homoiconicity allows code to be treated as data and vice versa, enabling powerful metaprogramming capabilities. This means you can:
1. Manipulate code at runtime
2. Create domain-specific languages easily
3. Extend the language itself
In Org-mode, this translates to source blocks that can:
1. Dynamically generate and execute code
2. Modify their own content or other blocks' content
3. Interact with the Emacs environment seamlessly
This level of flexibility and power isn't achievable in Python's REPL due to its more rigid separation between code and data. While Python is highly versatile, it lacks the deep introspection and self-modifying capabilities that Lisp's homoiconic nature provides, making Lisp uniquely suited for certain advanced metaprogramming tasks and interactive development paradigms.
So the bottom line is: you can imagine really hard, but it would remain just an imagination, if you want to build something like Emacs - a REPL that has a built-in text editor, you need a Lisp, because non-homoiconic languages DO NOT HAVE exactly same REPLs. Now, do you want me to get seriously pedantic and explain how every step in ReadEvalPrintLoop differs in Lisp and Python?
> if you want to build something like Emacs - a REPL that has a built-in text editor, you need a Lisp, because non-homoiconic languages DO NOT HAVE exactly same REPLs.
I don't think it makes sense. One can build programmable editors in many interactive languages. The language for an editor doesn't need to be Lisp. It could be Python, JavaScript, Ruby, PERL, Forth, ... Typically a form of EVAL or compile/load is enough to do so.
> One can build programmable editors in many interactive languages
Of course, one can - VSCode is a "programmable editor", no? Emacs is a bit different though, wouldn't you agree? It's rather a Lisp REPL that has a text-editor built on top of it.
Dired is a file browser, sure, it can be written in anything. But what about something like Org-mode - with all its source-block magic, code execution, etc. etc.?
You're just so full of yourself, aren't you? You know the one true way to do programming, it's lisp and everyone else is an idiot? This was old before you were even born.
Now, you're just being rude, I never said things you're implying I did, and I never claimed anything of being "one true way to do anything", I only tried to point out in a humorous way of your uninformed opinion, but I guess you lack basic sense of self-irony. Okay, if you rather remain sanctimonious, stiff-necked "professional", fine. I'm sorry if I hurt your tender feelings and I apologize if I angered you - I promise, my intentions were quite the opposite. Also, you have no idea when I was born, let's not get too personal, okay?
Maybe it's just personal preference, since I think it's easier for me to think in python over lisp (which I've known for longer, but I still fumble through)
I do think python would make emacs more accessible to a wider audience.
> I do think python would make emacs more accessible
It would not be Emacs anymore. Emacs is specifically tied to Lisp. Emacs is not a text editor that uses Lisp as the configuration language. Emacs is a Lisp machine that has a text editor built into it.
An "Emacs-like" editor built on Python might be interesting, but it wouldn't be a "better Emacs" or even "like Emacs", it would be a completely different thing.
You may dislike Lisp, you may even hate Lisp, but the fact remains unchanged - there is an emerging class of applications that is significantly more difficult to build around non-homoiconic languages. Emacs is one of them. Stop fetishizing your favorite programming language as the quintessence of Emacs. The best one can do is to build a compiler/transpiler to spit out Lisp code, and people have tried that. Yet somehow, in over forty years nobody has succeeded in dethroning Elisp from ruling Emacs.
GNU Emacs is tied to Elisp. But Emacs is a much wider family of editors written in a multitude of languages.
> Yet somehow, in over forty years nobody has succeeded in dethroning Elisp from ruling Emacs
That might have several reason. Maybe few people are interested to reimplement GNU Emacs in a different language. Like nobody has succeeded in dethroning C from the Linux kernel, using Lisp.
> Emacs is a much wider family of editors written in a multitude of languages.
Sure, there's Guile Emacs, there's MicroEmacs - both not Elisp-based, still built on top of Lisp dialects; there's XEmacs, Remacs - both still use Elisp, there's also mg which afaik completely not lisp-based, but I don't know how much of it still 'emacs-like'. In general though, GNU Emacs is what people usually mean when they speak about Emacs, unless they're explicitly talking about others.
If you say only Lisp can be used to implement Emacs, would you mean a specific Emacs or an editor belonging to the larger family of Emacs-like editors? When I would speak about how to implement "an Emacs", I would include the option to use different programming languages. For example I could imagine that C and Python is a valid combination, even Python alone would be an option. Python can be used interactively, which would be sufficient for an interactive extension language.
You can see that there is a multitude of editors in the Emacs category. The list also mentions the implementation and the extension language.
> GNU Emacs is what people usually mean when they speak about Emacs
That's a bit sad. It's like saying "Linux" and think that its the same as "Debian Linux". Similar there are a lot of different Emacs-like editors. Claiming that there is only a single way to implement Emacs goes against the evidence that there are a lot of Emacs-like editors, which are not implemented in C + Emacs Lisp, including the original first Emacs.
I would think that by far the most important Emacs is GNU Emacs, but I don't think its implementation language choice (C + Lisp) is necessary to implement an extensible Emacs-like editor. Also be aware even though GNU Emacs is a popular Emacs editor, there are some people who are using different Emacs-like editors instead. I typically use a Hemlock variant written in Common Lisp and Zmacs, written in ZetaLisp. Both core designs date back many decades, actually even before GNU Emacs existed.
> I typically use a Hemlock variant written in Common Lisp and Zmacs, written in ZetaLisp.
So, I still can't see how that doesn't prove my point even further. These Emacs variants are based on Lisps, like you just said. I don't see anything "Emacs-like" today that's hugely based on a non-homoiconic language. Please, if you know any editor that allows me to modify the behavior of any given function/procedure/command with the same level of granularity as the advising mechanism of GNU Emacs, I would love to know about it.
Look at the list of Emacs-type editors. Plenty of them were not written in Lisp.
> Please, if you know any editor that allows me to modify the behavior of any given function/procedure/command with the same level of granularity as the advising mechanism of GNU Emacs, I would love to know about it.
Zmacs did that before GNU Emacs existed. It also allowed ALL parts of the editor to be changed, not just the ones written in Emacs Lisp for GNU Emacs. Remember, the core of GNU Emacs - both the core Lisp implementation and some core editor and UI functionality - is written in C.
Btw., on a real Lisp Machine the editor (Zmacs) was not the main user interface. For example on a Symbolics (but also in Interlisp-D), the listener and a file browsers were their own applications. Zmacs in Genera has a Dired mode, but no listener. Also Genera can run multiple Zmacs windows in the same Lisp, running concurrently -> the Lisp supports multiple threads and the applications use that feature.. Something which GNU Emacs can't easily do. It's mostly blocking and single threaded. Something which can't be easily fixed in Emacs Lisp.
Run Lisp code in GNU Emacs in the REPL (m-x ielm) and it blocks the UI. That can't trivially fixed and is a major implementation fail of GNU Emacs.
Other Emacs-like editors can run multiple things, without blocking the user interface.
You could use MS Word of Photoshop if you want, we couldn't care less.
We're not talking here about a mere text editor, we're discussing a Lisp machine with level of extensibility and programmability deeply ingrained into its design, something that Vim or Sublime or any other traditional text editor can never achieve.
- Hmm... what about croutons, nuts, maybe sunflower seeds?
- No, just use meat. I like meat. Just make it with a bunch of meat pieces, alright?
- Well, that is not a salad...
> Not using lisp
Don't you folks realize the imbecility of such statements? Emacs is a Lisp machine that allows writing and loading custom extensions based on Lisp! This level of extensibility and programmability is so deeply ingrained into Emacs, specifically because it revolves around Lisp. Emacs wouldn't be possible without Lisp.
The downvotes are because "this reasonable point of view" is also an ignorant one.
Emacs just cannot be Emacs without Lisp. Emacs is a Lisp machine; it is tightly integrated with Lisp and needs Lisp to operate. Lisp is at its core principal model.
There are a number of different types of applications that are significantly more difficult to achieve with a non-homoiconic language; check out Hyperfiddle/Electric, there are some videos with demos. Why do you think there were so many attempts to re-create something like Org-mode, yet none of them were hugely successful?
For starters - the Lisp REPL has some significant differences; it just doesn't work the same way as a REPL in, e.g., Python. In Lisp, you can send any piece of code without any prelude or ceremony directly to the REPL. That REPL instance can even be on some remote computer, like a spacecraft millions of miles away (I'm not making up this shit, NASA did it at some point)
Anyway, Emacs is Emacs because of Lisp, not because someone on a whim decided to use Lisp instead of, I dunno, Pascal. Trying to build Emacs on top of some non-Lispy language is futile. It won't be Emacs. Sure, it might be to a certain degree even better, but it won't be even "like Emacs".
Actually, I love Emacs for its Lisp! Yes, Emacs Lisp is not the best Lisp out there, however, IMHO, it's miles ahead of VimScript. If I were really to rewrite Emacs, I'd use some modern Scheme.
Fennel is a better Lisp than elisp. Neovim is extensible, and to a large degree written in, Lua, which the target language of Fennel.
Most developers do not like writing Lisp. That's just a fact, slamming the downvote button won't change it. I am not among those developers, I like writing Lisp, but most, flatly put, do not.
So by choosing Scheme you are competing with a remarkable number of little-used editors which can be extended in Scheme or Common Lisp, as well as Emacs, far and away the top dog in the extensible-in-Lisp-editor niche. Neovim has achieved the best of both worlds, because it can be extended in a rather nice Lisp, and also in Lua, which, while some find the quirks of the language annoying, is at least Algolic in structure, matching the mode of thinking and writing used by the vast majority of devs.
No it has not. Fennel doesn't have the same level of integration into Neovim, like Elisp has in Emacs. Emacs is essentially a Lisp interpreter with a text editor built on top of it. This tight coupling allows Elisp to interact with and modify every aspect of Emacs, providing a level of customization and extensibility that is difficult to replicate with external languages.
While Neovim's approach with Lua and Fennel is commendable, it is unlikely that these languages will achieve the same level of seamless integration as Elisp within Emacs.
Then it wouldn't be Emacs. You're thinking of whatever, it could be a real nice picture in you head, whatever that you're thinking of, is not Emacs. Something like Emacs is not possible without Lisp.
If I leapfrog over my generally cold attitude towards Lisp-like languages and my habit of Vim keys, the main problem is Emacs's sluggishness, even if it is natively compiled. Neovim fully packed with plugins, LSPs, settings and etc without lazy loading (!) is so much faster.
And? GIMP is too, much faster to start than Photoshop, yet there are a number of things for which sometimes you just need the heavy cavalry.
I was doing some API testing today, I pressed a key, then a snippet expansion system added something like this into my notes:
#+begin_src http
GET http://localhost:5003/api/health
#+end_src
I ran the snippet, it sent the request and it failed.
I realized that I needed a token. It is stored in an env var - not very secure, but it's okay - I'm not testing the prod endpoint. I just had to change the header into this:
I ran that, and Emacs picked up the env-var, fed that into the snippet, sent http request, got me some results. Then, I changed the endpoint to get some more data, I realized that I would like to examine it closer. I could've done this in Python, Javascript, any other language, even Elisp, but I know Clojure, it's good for data manipulation - so I chose that. I just had to feed the http request results to another block in Clojure. I spun up a Clojure REPL, went through the data, looked at the results, typed some Clojure data manipulation functions, right there where my notes were, ran them against the data, added some more notes - documenting my findings.
I've tested some more endpoints, got some unfamiliar http error codes, so I just typed directly in my notes "RFC 2616", Emacs was smart enough to recognize what that was and it opened the RFC document, where I searched for the error code, read about it, refreshing my knowledge.
Then I found the Jira ticket number in my yesterday's notes, copied over to my notes of today - Org-mode has a nice way of organizing daily notes in so-called date-trees. It's just a plain string - "TDL-26478", and once again, Emacs was smart enough to know what that was, I was able to read the description of the Jira ticket, without switching to the browser, without opening any pages, right there, from where I was composing my notes.
And this is all within less than an hour. I was able to send http requests, analyze results, study relevant RFC document, work with Jira, all that while taking extensive notes, without opening a single web-page, without typing a single command in the terminal, all that done inside Emacs. Emacs basically within less than an hour in a single window was able to substitute for me - a note taking app like Obsidian or Notion; API client like Postman; Interactive computing platform like Jupyter; Project management client for Jira; RFC documentation site; Web-browser and the Terminal app. So tell, me which one of any of these activities do you normally do in Neovim? And btw, this is not even remotely "esoteric" stuff I do in Emacs. This is just an ordinary Tuesday for me.
Don't get me wrong, I do get and appreciate the "complete package" and "customize everything" approaches followed by Emacs, but Emacs is often not the best tool for the job, if you work in a team. You've mentioned Jupyter notebooks and project management. Yes, Org and interactive modes are excellent, well-polished, full of goodies. The problem is that features like these require other people to either do the same as you do or to be able to integrate via an API/protocol. Having lots of people being fond of Emacs is a bit of a stretch, while integration features rely a lot on the community, which, as I've already said, isn't that wide, so plugins aren't always well maintained, unless you do it yourself, of course... And as a editor with LSP (a built-in) Neovim is simply put extremely responsive, I'd say it's closer to Unix philosophy of having a single thing doing its job really well.
You're missing the crux of the matter. It's not about comparing the quality of two distinct tools. It's erroneous to claim that a power drill is inherently superior to an oscillating spindle sander - these are tools from different categories, each excelling in its intended purpose. Certainly, tools can sometimes be repurposed for tasks they weren't designed for, and occasionally this leads to the creation of a more suitable tool, but that's the exception rather than the rule.
I use both Vim and Emacs daily, and while your observation about Emacs generally being slower than Vim isn't incorrect, it doesn't necessarily make Vim a better all-purpose tool for everything. Emacs isn't either, for certain things, Vim is indeed excellent.
I suggest you reconsider your perspective on Emacs users as mere dorks who misunderstand Vim or are too lazy to learn it. Instead, explore their motivations, question your own "cold attitude towards Lisp-like languages" - "know thy enemy", if you will. You might uncover some surprising insights. Trust me on this, from one die-hard Vimmer to another: it's never "Vim vs. Emacs for everything", it's rather "Vim or Emacs for the task at hand".
I don't hate on Emacs in general, even more so I'm quite happy to learn about it's features and great plugins, but that'd mean a decent time investment. From my side, I'm generally a slow learner too, it took me a few years to be productive in Vim/Neovim, configuring it to my liking, polishing the motions. Maybe if I get some more free time with the new job, I'll finally go about making my Emacs config work well.
I’d get rid of the text editor and swap in neovim or hx code as a mode, I’d chuck emacs lisp and use Common Lisp instead, I’d definitely keep org mode and ditch old stuff like mail and news reader as core and let them be add ons written in CL . Rewrite it all in rust. That’s probably enough for today.
Don't use lisp. Normal people don't like it, it looks weird. I wonder how many projects failed because they were lisp. Normal people: Visits a project page. Sees it's a lisp. Closes page.
Don't use Math. Normal people don't like it, it looks weird. I wonder how many projects failed because they wanted to use a lot of math notation. Normal people: Visits a project website. Sees it has equations and formulas. Closes page immediately.
That's how it sounds to me. Dismissing Lisp solely based on its syntax (that you're unfamiliar with), is equally irrational as rejecting projects that incorporate mathematical notation.
Parentheses scare away anyone who shouts "bro!" and fist-bumps each other, before they can insist "the first thing Emacs needs is a package manager, to hide code as much as possible from casual users" (missing half the point of Emacs).
"A friction" you say? You can run Emacs, open a scratch buffer and extend it right away. You don't even have to save the damn code, you can try it out immediately. Folks complaining about Emacs being hard without even trying to understand any Lisp, is on the same level of whining about how web-development is so much harder compared to building shit in Squarespace (or something), only because you can't figure out HTML, CSS and Javascript.
You clearly don't know what you're talking about. You simply don't argue over customizability of Emacs, nobody does, because they know it's futile. If you think anything else has even some slightly better ergonomics to extend the thing, you just have not seen the bonkers level of extensibility what's possible with Emacs.
In Emacs, you can seamlessly integrate a function from a third-party package, say, a command that fetches a url, parses it, performs processing, and displays the results in a browser. Remarkably, you can modify it to send the results to an LLM or another function instead, without altering any other aspects. This level of granular control is complete bananas and only possible in Emacs. For VSCode, you'd likely need to create a new extension, while in Vim, you'd have to rewrite the entire function. Emacs, on the other hand, allows you to precisely specify and override only the desired part of the function. And once again, you don't even have to save a damn file to try it out.
So, yeah, I don't have to compare it with nothing. Nothing else comes even close.
My point was that I see a lot of people now who aren't getting the advantage that I had, of seeing "here's some Emacs Lisp code that does X", right up in their face, from the start, and constantly.
So they have more friction, to even knowing what Emacs Lisp looks like, and knowing how close they are to extending Emacs themselves.
I'm now utterly confused, even than before. From the start I thought you were saying "Emacs is hard to extend [for a newbie]", or something like that, and I've been arguing that it is not. Now I'm not sure what you're talking about at all - all the packages anyone uses come with their source code, the body of any function is a keystroke away.
Sure, yes, a graphical layer would be nice, I would love to be able to draw some arrows and other elements in some sort of an overlay, something like DrRacket does. And yes, better integration with an actual web browser would be splendid. I would love that.
- Redesigned with concurrency in mind.
- Common Lisp, Scheme, or anything else other than Elisp. [Just the same way Neovim adapted Lua instead of VimScript]
- More sane defaults for new users.