放弃 Zshell,选择 Emacs Shell (2014)
Eschewing Zshell for Emacs Shell (2014)

原始链接: https://www.howardism.org/Technical/Emacs/eshell-fun.html

Eshell 是一个 Lisp REPL,专为类似 shell 的交互设计,优先考虑速度和简洁性。它允许在简单函数调用中省略括号,例如 `message "hello world"`,而以 `eshell/` 开头的函数则需要在括号内使用完整名称(例如 `(eshell/echo "hello world")`)。 Eshell 处理字符串和列表,但将 Lisp 语法与 shell 命令混合使用需要小心。虽然 `echo` 可以接受多个字符串参数,但直接将 Lisp 函数(如 `car`)应用于这些参数会失败。 `listify` 函数将参数转换为字符串列表,并使用花括号 `{}` 可以将此列表传递给 Lisp 函数(如 `car`)。`listify` 和 `list` 经常产生相同的结果,但当输入为列表时,`listify` 避免了不必要的嵌套——这在处理潜在的基于列表的数据时是一个有用的区别。

## Emacs Eshell 与传统 Shell 的对比 这次黑客新闻的讨论集中在使用 Emacs Shell (Eshell) 代替 Zsh 等传统 Shell,在 Emacs 环境中工作。虽然 Eshell 有其优势,尤其是在 Windows 环境(包括 WSL)中保持稳定,但对于习惯于标准 Shell 键绑定(如 Ctrl-P 和 Ctrl-R 用于历史搜索)的用户来说,它也带来挑战。 用户建议重新映射按键——利用 Emacs 绑定,如 M-n/p/r,或使用 `consult-history` 和模糊查找器 (fzf) 来解决这个问题。Eshell 的一个关键优势是它与 Emacs 键绑定在所有模式下更紧密的集成。 有几位用户推荐 “Eat” 包,它为 Eshell 添加了终端模拟,允许更流畅地运行基于终端的应用程序,如 Vim。但有人指出 Vterm 速度可能更快。另一些人认为 Eshell 对于当前目录下的快速任务已经足够,而更复杂的终端工作仍然更喜欢 Zsh。 讨论强调了理解 Eat 的输入模式以及阅读其文档以达到最佳使用的重要性。
相关文章

原文

EShell is a Lisp REPL. The following works as you’d expect from such a REPL:

$ (message "hello world")
"hello world"

However, in a shell, we care more for simplicity and speed of typing that we do for semantic clearness, so we can, in this case, drop the parens with the same results:

$ message "hello world"
"hello world"

Functions that begin with eshell/ are available in Eshell without the prefix, so calling the eshell/echo function makes the shell experience less surprising:

$ echo "hello world"
"hello world"

If you put it in parens, you need to give it the full name:

$ (eshell/echo "hello world")
"hello world"

What about types? In a normal shell, everything is a string, but EShell has a foot in both worlds:

$ echo hello world
("hello" "world")

A list of two strings. However, you can NOT attempt to pass that echo to car… at least not directly:

$ car echo hello world

Returns an error, as does:

$ car (list hello world)

You see, once you bring in parens, you also bring in syntactic specific-ness, so you would need to do this:

$ car (list "hello" "world")

EShell has a listify that converts its arguments to a list of strings:

$ listify hello world
("hello" "world")

But if you want to pass that data to something like car, you need to surround it in curly braces, which is EShell’s way of saying, call some shell-like-goodness, but return it like Lisp:

$ car { listify hello world }
hello

Upon a cursory review, it appears little difference between a simple list and using listify, as under certain circumstance, they have the same behavior:

$ listify hello world
("hello" "world")

$ list hello world
("hello" "world")

$ listify 1 2 3
(1 2 3)

$ list 1 2 3
(1 2 3)

$ list "hello world"
(#("hello world" 0 11
   (escaped t)))

$ listify "hello world"
(#("hello world" 0 11
   (escaped t)))

However, I got the following message from David, who said:

The difference between listify and a ’list’ appears to be that calling listify on a list will not nest it in another list, e.g.

(eshell/listify '(1 2 3)) 
(list '(1 2 3)) 

Seems useful for a context where input may be a list, or not.

联系我们 contact @ memedata.com