76 comments

[ 2.7 ms ] story [ 309 ms ] thread
Why not pass an extra argument to emacs and then check for that in the config? Pardon my vimgnorance.
Will emacs exit with error if you pass random arguments it doesn't understand?
No. And plugins/elisp has access to yet-unprocessed arguments.
With `emacs --eval '(setq some-var "some arg")'` one could inject any lisp variable to emacs and then react to that.
> Pardon my vimgnorance.

Why are you short-circuiting the opportunity to start a vim/emacs flamewar? The authorities should revoke your ability to use either editor. And perhaps block you from using rust and c++ as well.

Helix helix helix helix segfault helix helix helix panic index out of bounds helix segfualt
ha ha when you get into this mode you don't know how to exit!
I’m curious about whether the writer considered using emacsclient - it’s well suited for this application but I don’t see mention of it.
That's definitely the way. When I used to use Emacs, it was always running, and my $EDITOR was set to emacsclient. I had two monitors, one fully dedicated to Emacs, the other to the rest.
Yep, likewise. I'm using emacsclient as $EDITOR too and it works well.
I find it helpful also not just because of the startup speed, but because I usually have one or more org buffers open taking notes on what I'm doing.
> I find it helpful also not just because of the startup speed, but because I usually have one or more org buffers open taking notes on what I'm doing.

As someone who lives in org, this is the way. I'm still shell bound for a lot of things, but M-x shell is far superior, there's just no contest. Only thing that is annoying is stupid things like git diff that think they know better than you and want to do their own paging resulting in "WARNING: terminal is not fully functional". Thankfully I use EGG, but when I forget (and other things do it too), it's annoying.

Yeah, it's a seamless experience to run a program in shell-mode that invokes $EDITOR and it just pops into a new buffer. Edit, hit C-x #, and you're back at the shell.
Wait, I'm confused, because you might have found a solution to something that's bothered me for a long time. I use emacsclient -t as $EDITOR and editor is invoked at a normal emulator, it opens a new buffer in the terminal. Great. But if I'm using vterm inside emacs anything that invokes editor then tries to open a buffer inside vterm and I'm now in a weird recursive state that locks up. Having some lisp that checks if I'm in vterm when editor is invoked and instead opens it in my current client session would be great. I searched for this at some point but gave up.
Have you considered overriding the Emacs process EDITOR variable via setenv? i.e.:

    (setenv "EDITOR" "/usr/bin/emacsclient -c")
If you do that, it should cause any child processes (e.g.: vterm) to inherit the replaced EDITOR variable and properly open new editor frames instead of trying to do a terminal takeover.
Well,this is extremely clever and simple. I tried that out from vterm in 29.1 and it crashed emacs...
Personally, I got tired of weird quirks like this with vterm and now bind this command to the key I used to have vterm on to spawn my actual terminal (st) in my current directory. It's probably not what most people want from vterm, but I prefer it.

  (defun open-term-here ()
    "open st in `default-directory`"
    (interactive)
    (call-process-shell-command
     (concat "st bash -c \"cd "
      default-directory
      " && exec zsh\"")
     nil 0))
I also do this, C-x t to open a tmux tab to whatever directory the current buffer is:

  (defun tmux-here ()
    (interactive)
    (if (not (eq (getenv "TMUX") ""))
        (shell-command (format "tmux new-window -c %s" default-directory))
      (error "Not inside a tmux session.")))
I know, I know, tmux is slow and should never be used. I like it, OK.
I used emacsclient for many years but these days, TBH emacs with the right knobs twiddled starts up at usually an entirely reasonable speed.

But definitely out of the box with a stock emacs install it seems too interested in doing a bunch of stuff that gets in the way.

My EDITOR has been just regular "emacs" for years now.

Speed is not the only thing `emacsclient` addresses. When your $EDITOR is `emacsclient`, the newly spawned frame will share state (kill ring, buffer list etc.) with your Emacs server. This might be helpful e.g. when you (like me) are a heavy user of `dabbrev-expand`, and also with numerous other little things.
My relatively new stance is that sometimes having an Emacs process that doesn't share the state is a feature, not a flaw. Specifically I started using non-daemon Emacs processes alongside my main Emacs daemon to compartmentalize my work. Each non-trivial project, or "workspace", gets its own Emacs process, possibly with a persistent state with desktop-save & desktop-change-dir. The newish tab-bar-mode helps with that a lot as I cannot stand using multiple frames on a non-daemon Emacs due to it not always being obvious when I close just a frame and when I close the whole process.
Yeah I personally prefer to have the separation of buffer sets between tasks. Especially for something as transient as "write a git commit message" or do an interactive rebase, or write a quick note.
A personal preference is a personal preference, ofc, but what exactly are the actual benefits?
While project.el or projectile.el are good sometimes you don't want to see anything else except your current project. A new instance is an easy way to achieve that.
> My relatively new stance is that sometimes having an Emacs process that doesn't share the state is a feature, not a flaw.

That is a fair point, though not really fitting my workflow. (Also, my Emacs needs ~20 seconds to start, and I tend to have Emacs uptime of several days or sometimes even weeks.)

> I cannot stand using multiple frames on a non-daemon Emacs due to it not always being obvious when I close just a frame and when I close the whole process.

This is strange. In my Emacs, C-x 5 0 on the last frame results in "Attempt to delete the sole visible or iconified frame". (And I have `(setq confirm-kill-emacs #'yes-or-no-p)` in my init.el anyway.)

Yes, C-x 5 0 is safe, but I often use my window manager's keybinding for closing a window instead. Customizing confirm-kill-emacs sounds like a great idea, I'll consider it, thanks!
Depends on what you mean by entirely reasonable.

I’m by no means a package maniac, and I lazyload with use-package almost entirely, but a cold start still takes a second or two. To me, a choice between a second or two and instantly is a no brainer.

I like to use `emacsclient -t` as my $EDITOR (actually I have this in a small wrapper script in ~/bin/editor) so it runs a terminal-based frame rather than opening a new GUI frame. Also, setting alternate editor helps which will just run emacs if an emacs server isn't already running.

I run emacs as a daemon, but it doesn't have to be. You can also run `(server-mode)` from any emacs process. A nice snippet for the init.el is: `(or (server-running-p) (server-mode))` which works whether you run the daemon or not.

`(require 'server) (or (server-running-p) (server-mode))` :)
What's the difference between daemon and server-mode?
IIRC, daemon mode is a headless instance of the Emacs that the clients can connect to. Server-mode is just a standard, headful, user-session instance of Emacs that can also accept clients.
Daemon runs without a UI at all and can only be used with emacsclient. server-mode is used with a normal/non-daemon instance so emacsclients can connect to it. Combined with the --alternative option you can then run emacsclient without really thinking about it. The first one will start a full emacs instance and enable the server, subsequent ones will just connect to that server.
emacsclient is addressed in another post: https://magnus.therning.org/2023-10-01-how-i-use-emacs.html
Of course it is their right, however I don’t understand their argument in this text. They can start Emacs in daemon mode and issue emacsclient -c to have their main graphical session. I not sure I see the added complexity.. if they need multiple different setups that’s also fine. I wonder if perhaps the perceived complexity comes because the author has not experienced the simplicity of Emacs working in combined terminal/shell/graphical modes through the invocation of emacsclient. There is almost no drawback in being able to share buffers if ever needed, and then they are not needed they are out of the way.
yeah, this is what i use, along with a specific instance of the emacs server session to avoid cluttering up my actual editor. i think the invocation is something like `emacsclient -A “cli” -nw `
Oh that's a great idea, this is the way. I don't use emacsclient because it has weird interaction with Doom's workspaces, but your way might solve this problem. Thanks!
Does it not just start a new Doom workspace for the new frame? I’m curious because I use Doom workspaces a lot and might consider setting EDITOR=emacsclient
ok, here's my actual invocation per my .zshrc:

`alias ec="emacsclient -s console -a '' -nw -r"`

It doesn't start a new doom workspace /most/ of the time. Sometimes i'll get a new one if i've got multiple editors opening up the same file, I think. But the `-s` flag starts a console server that at least keeps those out of my main emacs window (I use the gui version from emacs-plus)

It only creates a new workspace if you're connecting to your main Emacs' server. If you have a separate daemon launched with `emacs --fg-daemon=cli`, then connecting with `emacsclient --socket-name=cli` won't pollute your main Emacs with a new workspace:)
(comment deleted)
Plenty of tools do not support arguments in `$EDITOR`. Might in some cases be better to make a small shell script wrapper.
There are many interesting use cases for `emacsclient' if you use it. Here's a quick shell script that turns your Emacs into the CLI tool `fzf'. Instead of fzf, you can use Emacs's advanced completion tools to do the filtering, and then return the selected matches to the shell. Around 20 lines of bash or so, plus a smattering of elisp:

https://www.masteringemacs.org/article/fuzzy-finding-emacs-i...

I wonder how practical (or not) would be to set it as your shell.

Not that much, as it is rather limited on the terminal.

This is definitely bait.
I thought it’d be polarising, but when you think Lisp Machines essentially had Emacs and a REPL for their shell, it’s not completely absurd.
I don't know why the author doesn't simply open a shell buffer in emacs, but that's their business.

Piece of fun trivia: EMACS used to have a mode for use on a printing terminal. It worked, as long as you had an idea of what your file looked like, same as any other non-visual editor (like ed before a display mode was grafted onto it to form vi). Of course this was as crazy as using vi on a printing terminal, since EMACS started out as an easier way to use TECO after a visual mode had been added to that. I guess the printing mode was worth it for EMACS users who never learned TECO.

More usefully it had a "slow terminal" mode. Printing terminals were slow, but many people connected to computers at 300 baud or even slower! So in slow terminal mode you could use the full display power of EMACS but it was very selective about how it updated your display. Back then most terminals had very limited cursor control, and you couldn't always change an arbitrary character. Still, avoiding a full screen repaint at 110 baud was a win.

I doubt either of these modes survived the relatively recent (1980s) ports of emacs (as it is now known) to C/Lisp. But a special line for single-line editing through an emacsclient could be a win in this case.

From the Emacs manual:

Searching incrementally on slow terminals, such as displays connected to remote machines over slow connection, could be annoying due to the need to redraw large portions of the display as the search proceeds. Emacs provides a special display mode for slow terminals, whereby search pops up a separate small window and displays the text surrounding the match in that window.

— <https://www.gnu.org/software/emacs/manual/html_node/emacs/Se...>

Nice! That a bit more advanced: old school EMACS used the line below the mode line because some old terminals supported update only there and not always elsewhere.
personally I don't use shell buffer because it doesn't do command line recall like I expect.

In a normal terminal control-r <characters> recalls the last command with those keys, and control-p/n will go back/forward in the history.

with the shell buffer I move upwards in the buffer to recall a command.

(is there a way to configure this differently?)

EDIT: ok it seems like meta-r and meta-p/n do the same thing - kind of.

hmmm, but meta-r doesn't seem to recall from the shell history? It is either a different history or truncated.

FYI, I use vterm with a few custom keys so that it operates exactly as if it were just a standard terminal emulator.
Why bother? Real question — seems like no advantage over a terminal window, except you can c-x b to it. Perhaps that's enough?
Ummm. It probably depends on the kind of work you do in the terminal but for me it was a game changer. Being able to pull in any of the text from a terminal into a buffer, easily, without copy paste or mouse is a massive game changer for the type of work I do. I can operate on any of the text in the terminal the same way I would emacs, and pull it into a code buffer. Selectively pulling in random long directory paths, etc etc. I can also drop anything from notes or code into a terminal without needing to dance around.

It also turns emacs (server-mode) into a really great replacement for tmux/screen. tmux behaves very strangely in how it instantiates the very first window, calling the process after that window and killing that window can kill all your tmux sessions. I run emacs as a daemon on my HPC clusters and have it monitor jobs and more via vterm.

Yeah, I guess my use case is completely different; shell mode is great and vterm goes the wrong way. But I never run even curses programs in the terminal, just text all the way.

The great thing about emacs is you can use what works for you!

You can use m-p/n as you mention, same as, say, in regular bash, or search. Or c-c c-p, c-c c-o etc.

But TBH I mostly just use the ordinary ! syntax (e.g. `!!` or `!bla:*` or !200 etc) because it’s even faster and works fine even when no editing is available at all.

So if I used find to search for an executable it’s just so effortless to type ./`!!|head -1` rather than searching up, selecting and copying a region, going back to the end, editing it, blah blah. Or even worse, reaching for the mouse.

I wonder what percentage of even frequent shell users are even aware of !! or ^subst^ - an informal polling of 5 workmates here (engineers, command line git users, people I would have thought would know) shows no takers.

To be fair, I'm old and was thrilled to go from 300 to 1200 baud at one point.

Wow, I assumed it was universal. Retyping things, or copying and editing is so tedious.
I recall that at University a lecturer showed this briefly in the early nineties. Most of us students stared in a mixture of awe and disbelief. I didn't learn those incantation from that brief introduction and never felt the need, even though I used a 2400 baud modem (already outdated, hence cheap) then.
I use control-r a LOT. It lets you look at and edit what you'll re-type. I use it for complicated commands I ran yesterday and the day before.

Unfortunately my hands are wired for control-r (caps lock = ctrl) and not meta-r.

Hard to figure out the ROI of re-learning.

(still emacs recall history doesn't seem to reflect bash history, which I routinely set to 10k commands)

Zsh's line editor is so flexible that it renders most uses of edit-command-line unnecessary. It does more than just let you rebind keys. It also lets you create your own text editing operations called widgets. The stock widgets covers almost all the text editing operations necessary for CLI editing, which even includes things like Vim's text objects and surround bindings. But I also define my own widgets where it falls short.
There's a long-tail of editor shortcuts I use. I find it a bit wasteful to try and re-implement them in every single program I use that takes text input. Now, if someone else has implemented it already, then I'm happy to use it, but 99% of the time they will have implemented at most the 100 most common shortcuts that they use, which is unlikely to make me happy.

I should point out that there is exactly one case of someone implemented enough of vim to make me happy, and that's evil-mode. Even there I had to tweak some settings because the defaults were too different from vim (specifically the + and * registers behave completely wrong by default).

But this is the shell we're talking about, one of the primary interface for development work, so I think the effort is worth it. By relying heavily on edit-command-line, you have to choose between coping with suboptimal keybindings and opening a text editor every time you want to run a command.

Also, zsh's vi bindings are surprisingly good. Obviously, it won't be useful as a full-fledged text editor. But it's more than good enough for command line editing. It even has visual mode and registers, which you rarely see implemented in an interpreter.

It's true that it requires some configuration though. At least around 20 lines. Zsh's vi mode inherits vi's quirks that are normally disabled in Vim, including the weird backspace behavior in insert mode. Those have to be overridden individually. Text objects and surround bindings need to be explicitly bound too.

I mean, pure emacs nerds just use eshell or similar. Then the keybindings match 100% and things like "more" get turned into "open this in a buffer" etc. Though you give up full bash compatibility. but there's "shell" if you want bash (or zsh for that matter) inside emacs itself, without the fancy stuff eshell gives you.

I've never fully made this transition, but have at times played with it, when I've been feeling extra-emacs-excited.

https://www.masteringemacs.org/article/running-shells-in-ema...

Eshell is neat, and I especially like the TRAMP integration. But I've yet to see anyone completely replace their terminal with it though. There are some usability problems like company mode hanging Emacs on every key input when used with Eshell on remote directories.

Also, Emacs in general can't replace tabbed terminals because there are so many blocking operations that make it unresponsive for a while.

Yeah, makes sense. And the blocking unresponsive thing, I guess I'm just flabbergasted we're still here after all these years.

I know every few months there's a new "I'm rewriting emacs/something-like-emacs" and it's, yeah, a nogo. But I'd actually just really like it if someone really really tried and addressed some of the architecture things :-(

This is fine and all, but in the old days we used to have a "simple" editor bound to $EDITOR and a more advanced editor bound to $VISUAL. But hey, it's YOUR system, so who am I to tell you what to do. Just a reminder that you might find people using $VISUAL instead of $EDITOR. I think common practice for a bazillion years has been setting BOTH $VISUAL and $EDITOR to the full path of your favorite screen editor since hardly anyone needs to worry about editing something on a feature-poor terminal.

And since we're all talking about our favorite uses of $VISUAL and/or $EDITOR, this is mine:

    tcv() {
      if [ "$#" -ge 1 ]; then
        touch $@
        chmod 755 $@
        ${VISUAL:-`which emacs` --color=never} $@
      fi
    }
I use this when I want to write a shell script that's instantaneously executable. I'm much too busy to issue the chmod command after editing the file for the first time.
emacs: where even the simplest of things is complicated enough that you wrote a blog post about it
That thereupon spawns 47 comments: 45 are from other users of emacs and provide 45 different ways of doing the same thing; 1 is from a vim user; and 1 is a comment about how meta the emacs community is.
Title should be "Using Emacs as $EDITOR" (all caps).
I prefer to use something more lightweight as $EDITOR, such as 'mg'. Almost all the same keybindings, unfortunately no syntax highlighting, but very fast startup.
Thats what I was doing until now.

Just today, from this thread, I learned about 'emacsclient -t'. This was exactly what I didn't know I needed.

It opens a frame in the terminal (very quickly..) still have everything that my running GUI emacs has.

Perfect.

I am using Emacs since 10 years, hence I feel like it is now impossible for me to switch back to any other editor.