Emacs 是一个 Lisp 板。
Emacs Is a Lispboard

原始链接: https://en.andros.dev/blog/06bfd107/emacs-is-a-lispboard/

Emacs 常被误解为仅仅是一个文本编辑器或集成开发环境(IDE)。实际上,它是一个“Lisp 平台”——一个复杂的框架和跨平台运行时,作为一个完整、统一的工作环境而存在。通过嵌入 Lisp 解释器,Emacs 允许用户将终端、电子邮件客户端、文件管理器和代码编辑器等迥异的工具集成到一个单一的、内聚的空间中,使每个模块都能共享一个公共总线。 与同样作为跨平台环境但将应用程序封闭在受控孤岛中的现代网络浏览器不同,Emacs 提供了真正的主权。其核心力量在于能够使用一种共享语言(Elisp)无缝地连接和自动化工作流。无论是管理任务、为系统脚本编写自定义图形界面,还是处理通信,Emacs 都提供了一个连贯的接口,使配置和快捷键在所有活动中保持一致。 归根结底,Emacs 并非操作系统的替代品,而是构建于操作系统之上、高度可定制的接口。它之所以长盛不衰,是因为它实现了其他软件尚无法企及的工作流集成与个人控制水平,让用户能够构建一个随自身需求不断演进的栖息地。

```Hacker News 最新 | 过往 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 Emacs 是一个 Lisp 平台 (andros.dev) 14 分,由 andros 发布于 2 小时前 | 隐藏 | 过往 | 收藏 | 2 条评论 帮助 xvilka 11 分钟前 | 下一条 [–] 像 Lem[1][2] 这样的项目可以走得更远,因为相比 Elisp,Common Lisp 的生态系统更为丰富。 [1] https://lem-project.github.io/ [2] https://github.com/lem-project/lem 回复 behnamoh 13 分钟前 | 上一条 [–] 这关乎哲学理念;你更倾向于使用多个各司其职的小型应用,还是一个无所不能的“超级应用”? 讽刺的是,我最初倾向于前者,但现在我已经把我的 tmux 改造成了后者,集成了太多的实用工具。不过现在我也能看出这两种方式各自的优缺点。由于大量组件彼此耦合,维护“超级应用”更具挑战性。 回复 考虑申请 YC 2026 年秋季批次!申请截止日期为 7 月 27 日。 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请 YC | 联系 搜索:```
相关文章

原文

What would have happened if Emacs' default buffer had been a terminal emulator? Conceptually, from the outside, it would be perceived as a terminal on steroids with Lisp as its scripting language. Maybe we would be talking about iTerm2 vs Emacs, or Kitty vs Emacs, or even Bash vs Emacs. And what if the default buffer had been Dired, the file manager? History might have created rivalries such as Total Commander vs Emacs, or Finder vs Emacs.

But history took another path. We already know that if you launch an Emacs instance without any configuration whatsoever, what you see is a buffer with the following message:

;; This buffer is for text that is not saved, and for Lisp evaluation.
;; To create a file, visit it with ‘C-x C-f’ and enter text in its buffer.

A notepad with an embedded Lisp interpreter. Its natural rival is Vim with an embedded interpreter (Vimscript). However, the editor that made us all memorize :q! stayed in the buffer, while Emacs kept expanding with more and more software until it became an interface to the operating system.

I'm an Emacs enthusiast, and maybe that costs this article some credibility. However, I'm not here to tell you how fantastic the GNU editor is, nor to convince you to use it. My goal is to explain why the web browser is its true natural rival, and why Emacs is a Lispboard where you build the way you want to work.

Let's imagine a perfect working environment

To set the stage, let's do a little thought experiment.

Suppose I want to work in a single place for all my contexts, both personal and professional. That way I memorize my shortcuts, apply my configurations and never have to switch contexts. Everything lives under the same window.

It's a problem, because it means merging programs that have nothing to do with each other but need to collaborate. For example, a terminal emulator, an email client and a code editor (or IDE). With a layout system, inside the same window, I could have one column with my email inbox, another with the terminal and a third with my IDE ready to write whatever I need. In this space, it would be easy to write a bash script, launch it from the terminal and receive an email with the result. All in the same window, without switching context, with the same shortcuts, the same typography and the same theme. I could even add a fourth column with a Git client to version the script and push it to a remote repository. Or while we're at it, a fifth column with my favorite AI agent, able to read both my code and the rest of the panels.

We have just created an interface.

But this wouldn't be the most useful part: the programs would be integrated with each other, each one living in its own scope and, at the same time, in a global one. That means that if I enable the spell checker in the code editor with a certain configuration, it also becomes active in the terminal, in the email client when composing messages, or when I write commits. All with the same interactivity and configuration. They are not four isolated binaries connected with pipes: they are programs written in the same language, running on the same runtime and sharing the same event bus.

We have just created a connector.

Now let's remove an unnecessary layer: the bash script. If I already have an interpreter embedded in this very window, I can create my own scripts. I don't need an external binary. I no longer need to leave the window, nor touch the operating system. All my scripts, prototypes and workflows can live together.

We have just created a habitat.

There's only one problem left with the runtime: tomorrow I'll change laptops, or I'll want to work from a server, and I have no intention of rebuilding my environment from scratch. I want my scripts to work exactly the same regardless of the operating system and the hardware. A script should behave the same way on Windows, on a Raspberry Pi or on a cheap Android device. I need the whole environment to be a cross-platform runtime with bytecode that runs anywhere.

We have just created a virtual machine.

Now, to round off the idea, we'll use Lisp as the scripting language and we'll call the whole thing Emacs. Although I prefer to call it something else: a Lispboard. Like an electronics breadboard, a board where every module you plug in shares a bus with all the others, except here the modules are written in Lisp.

And if during this exercise you thought "this sounds familiar: tabs, applications and a cross-platform virtual machine... that's my browser", hold on to that intuition. We'll come back to it at the end of the article.

What is Emacs not?

With everything mentioned so far, I want to debunk some myths surrounding Emacs:

  • It's not a text editor: it's a complete working environment, with an embedded scripting language, its own software and a cross-platform runtime. The editor is just one more program inside that environment, as are the terminal, the email client, IRC, the file manager or the web browser (yes, Emacs ships with one).
  • It's not an operating system: it's a working environment that runs on top of an operating system, and that can replace many of the programs it offers. But it has no drivers, no kernel, no low-level tools. It cannot run without an operating system.
  • It's not an IDE: there is no default set of tools focused on programming in a specific language. For that you need LSP backends, debuggers and linters, which are installed as packages. But you can certainly get there; it's one of its most common uses.

What it is: a Lisp interpreter and a framework that run on top of the operating system in the most agnostic way possible, and that reimplement a good part of the programs it offers.

My workflow

Scripting and prototyping

When you think: "I'm going to write a simple bash script to automate a task", I think: "I'm going to write an Elisp function". And on top of that, I'll give it a graphical interface if I need flags or text input.

For example, suppose you need to create a script for yourself, not for a CI/CD process or cron. The goal is to back up a specific folder (maybe to the cloud). You could end up with a command like this:

./backup.sh /home/user/folder /home/user/backup

But you also include a flag to create a zip:

./backup.sh -z /home/user/folder /home/user/backup

Well, instead of going through the terminal, I create an Elisp function that does the same thing, and I add a small panel to it.

I run:

M-x my/backup RET

And a buffer will show up with an interface like this:

Folder backup

Folder: [ /home/user/folder ]
Target: [ /home/user/backup ]
[ ] Compress into zip

[ Cancel ] [ Run ]

With inputs, checkboxes and buttons. Without having to remember where it was, or its parameters, or their order.

If you have worked with Lisp before, you'll see the code is very basic:

(require 'widget)

;; Logic

(defun my/backup-run (folder target zip)
  "Sync FOLDER into TARGET with rsync, or compress it to a zip when ZIP."
  (let* ((folder (expand-file-name folder))
         (target (expand-file-name target))
         (command
          (if zip
              (format "zip -r %s %s"
                      (shell-quote-argument
                       (expand-file-name
                        (format-time-string "backup-%Y-%m-%d.zip") target))
                      (shell-quote-argument folder))
            (format "rsync -a %s/ %s"
                    (shell-quote-argument folder)
                    (shell-quote-argument target)))))
    (async-shell-command command "*Backup log*")))

;; UI

(defun my/backup ()
  "Open a panel to back up a folder."
  (interactive)
  (switch-to-buffer "*Backup*")
  (kill-all-local-variables)
  (let ((inhibit-read-only t))
    (erase-buffer))
  (remove-overlays)
  (widget-insert "Folder backup\n\n")
  (let* ((folder (widget-create 'editable-field
                                :format "Folder: %v\n"
                                "/home/user/folder"))
         (target (widget-create 'editable-field
                                :format "Target: %v\n"
                                "/home/user/backup"))
         (zip (widget-create 'checkbox nil)))
    (widget-insert " Compress into zip\n\n")
    (widget-create 'push-button
                   :notify (lambda (&rest _) (kill-buffer))
                   "Cancel")
    (widget-insert " ")
    (widget-create 'push-button
                   :notify (lambda (&rest _)
                             (my/backup-run (widget-value folder)
                                            (widget-value target)
                                            (widget-value zip))
                             (kill-buffer))
                   "Run"))
  (use-local-map widget-keymap)
  (widget-setup))

And this scales beyond toys. With this same approach I have built systems of all kinds. For example, this blog's newsletter: I manage subscribers, generate the emails' HTML from org files, send them out, send myself previews and analyze the data. All in Elisp, local, and with a simple control panel integrated with other tools.

The key of the example is that I'm not writing a script for an operating system or an interpreter, but a function for my working environment. I'm building a new workflow, in a space where I can program my own tools, connect them to each other or build one on top of another. I could create an asynchronous notification system to alert me when something finishes, and later connect it to the previous tool at no cost.

And I can do all of this because I have an embedded scripting language, a set of libraries (like widget.el to build graphical interfaces) and a cross-platform runtime that guarantees my scripts will work the same on any operating system. That is a Lispboard.

Programming and development

I want to stress that I separate tasks or environments by tabs. And inside each tab I have a layout with the buffers (or software) I need.

In the IDE tab I usually open:

  • A text editor with some LSP backend and debugger (dap-mode, Eglot, etc.).
  • An AI pair programming partner (chatgpt-shell connected to Claude).
  • A Git client (Magit) to version and review the AI's changes.

Although I keep weaving in temporary ones such as the file manager (Dired, with or without TRAMP), the terminal (vterm), the HTTP client (verb), Docker (docker.el), the web browser (eww) or the project manager (Projectile).

Working in Emacs with this level of integration is a pleasure that's hard to describe. You understand why it makes those who program in it fall in love.

Notes and study

Everything I think, plan or study ends up in plain text. The foundation is org-mode: notes, tasks and planning. On top of it, I manage my study notes with Denote: each note is a file with the metadata in its own name, all linked to each other. And when the study material is a PDF or an EPUB, I read it without leaving, with pdf-tools or nov.

Around them orbit small pieces that complete the routine, like jit-spell underlining my mistakes on the fly (remember the spell checker you configure once and it works everywhere? This is it) and wallabag to read or save articles I want to study later, calmly.

Communication: chats, email and social networks

Although it may not seem like it, over the decades the community has built an excellent pack of communication tools. Even for the same protocol there are several implementations, and each one has its advantages.

In my case, I have a tab exclusively for email with mu4e. It covers every need I can expect from an email client: composing, replying, forwarding, filtering, searching, tagging, marking as read/unread, etc. And it had better do it well, because it's the most important communication channel I have: mailing lists, discussions around a Pull Request, messages from other developers, service notifications, and everything that comes with a personal and professional life.

In another tab I keep a set of chats:

  • IRC with ERC connected to Libera.Chat. Curiously, this is where I've met the most people and been able to talk with many free software developers. I don't understand the eagerness to consider it obsolete.
  • Mastodon with mastodon.el for the Fediverse.
  • Org Social with org-social.el to read the posts on my favorite social network (I'm not impartial, I know, and I don't care).
  • Telegram with telega.el, which lets me read and reply to messages from groups and channels.

I only leave for Teams and Discord, both communication channels at my job. And WhatsApp, whose use in Emacs still doesn't convince me.

News and reading

My main source of information is RSS with Elfeed, almost all personal blogs. I use clients for the aggregators, hackernews-modern and lobsters (both made by me). With Gnus I read some Usenet newsgroups (it's still alive, and it reads wonderfully) and with Elpher I wander around Gemini and Gopher. When I want to open a web link, I give eww, the Emacs web browser, a chance. If it's unreadable, then I go to Firefox or the like (I have a shortcut).

Leisure

The workday is more pleasant with some music playing, hence EMMS backed by mpv. And when I want to disconnect for a while, I like playing chess with chess, either alone or with a friend online. After all, the board is also there to have fun.

Emacs is a Lispboard

The community has an expression for this way of working: living in Emacs. People have been writing about it for decades, and at the end of the article I leave you the readings that have marked me the most. But notice that living in Emacs describes a habit; what I have tried to show you is the consequence. Everything you've seen is not a collection of programs, it's a single board where every module shares a bus with the rest. An interface, a connector, a habitat and a virtual machine (literally: Elisp compiles to bytecode). A Lispboard to play with, or to make your work more efficient.

Its rival is the web browser. It meets more of the requirements than we like to admit: it's a cross-platform virtual machine (for JavaScript) and half of humanity lives inside it, with their email, their chat, their music and their office suite. But it fails at the essential part: tabs are silos that don't share a bus, you can't wire your email to your chat, and no module is yours: each one belongs to a third party that can change it, fill it with ads or shut it down tomorrow. On top of that, access to the host itself is limited: it's not easy to touch the disk or talk to the operating system. The browser is a rented Lispboard, with a landlord. Emacs is the only one you can own.

To wrap up, I want to make clear that using Emacs is not nostalgia: it's that nothing comparable has appeared yet. The 0.1% of us who use it and squeeze it daily do so because it lets us work in a way no other software allows. We will probably have a lifelong relationship with our configuration. There's always something to tweak, improve or automate. And if there isn't, we create it. Emacs is not free because of its GPL license, but because it's the only place where you can live and work your way.

References

联系我们 contact @ memedata.com