标签 EMACS 下的文章

之前就觉得我的 Emacs 启动好慢,查看启动日志会发现启动到一般的时候会有一个比较长时间的卡顿。 之前一直没有理会它,今天花了点时间探索了一下,发现罪魁祸首居然是 exec-path-from-shell 这个包。

现将探索的过程记录如下: 由于使用了 spacemacs 的配置,配置上比较复杂,不太想通过实验缩减配置的方式来摸索出问题的地方。刚好最近在学习使用 strace 工具,因此决定使用 strace 来看看 Emacs 到底卡在哪里。

strace emacs --fg-daemon

输出的内容特别多,这里只截取卡顿前的部分内容

readlinkat(AT_FDCWD, "/home", 0x7ffd1d3abb50, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972", 0x7ffd1d3abf00, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d", 0x7ffd1d3ac2b0, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa", 0x7ffd1d3ac660, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa/exec-path-from-shell-20180323.1904", 0x7ffd1d3aca10, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elc", 0x7ffd1d3acdc0, 1024) = -1 EINVAL (无效的参数)
lseek(7, -2655, SEEK_CUR)               = 1441
read(7, "\n(defvar exec-path-from-shell-de"..., 4096) = 4096
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
brk(0x7507000)                          = 0x7507000
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
lseek(7, 5537, SEEK_SET)                = 5537
read(7, "230\\205\26\0\t\22\\307\\310\t!\vC\\\"\\211\24\\2"..., 4096) = 2430
lseek(7, 7967, SEEK_SET)                = 7967
lseek(7, 7967, SEEK_SET)                = 7967
lseek(7, 7967, SEEK_SET)                = 7967
lseek(7, 7967, SEEK_SET)                = 7967
read(7, "", 4096)                       = 0
close(7)                                = 0
getpid()                                = 10818
faccessat(AT_FDCWD, "/home/lujun9972/bin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/local/sbin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/local/bin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/bin/printf", X_OK) = 0
stat("/usr/bin/printf", {st_mode=S_IFREG|0755, st_size=51176, ...}) = 0
openat(AT_FDCWD, "/dev/null", O_RDONLY|O_CLOEXEC) = 7
faccessat(AT_FDCWD, "/proc/5070/fd/.", F_OK) = 0
faccessat(AT_FDCWD, "/proc/5070/fd/.", F_OK) = 0
faccessat(AT_FDCWD, "/bin/bash", X_OK)  = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=903440, ...}) = 0
pipe2([8, 9], O_CLOEXEC)                = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
vfork()                                 = 10949
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9)                                = 0
close(7)                                = 0
read(8, "bash: \346\227\240\346\263\225\350\256\276\345\256\232\347\273\210\347\253\257\350\277\233\347\250\213\347\273"..., 16384) = 74
read(8, "bash: \346\255\244 shell \344\270\255\346\227\240\344\273\273\345\212\241\346\216\247\345"..., 16310) = 35
read(8, "setterm: \347\273\210\347\253\257 xterm-256color \344"..., 16275) = 51
read(8, "Couldn't get a file descriptor r"..., 16224) = 56
read(8, "bash: [: \357\274\232\351\234\200\350\246\201\346\225\264\346\225\260\350\241\250\350\276\276\345\274"..., 16168) = 34
read(8, "Your display number is 0\n", 16134) = 25
read(8, "Test whether fcitx is running co"..., 16109) = 53
read(8, "Fcitx is running correctly.\n\n==="..., 16056) = 87
read(8, "Launch fbterm...\n", 15969)    = 17
read(8, "stdin isn't a tty!\n", 15952)  = 19
read(8, "__RESULT\0/home/lujun9972/bin:/ho"..., 15933) = 298
read(8, 0x7ffd1d39ce9d, 15635)          = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=10949, si_uid=1000, si_status=0, si_utime=10, si_stime=7} ---
rt_sigreturn({mask=[]})                 = -1 EINTR (被中断的系统调用)
read(8, "", 15635)                      = 0
wait4(10949, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 10949
close(8)                                = 0
getpid()                                = 10818
faccessat(AT_FDCWD, "/home/lujun9972/bin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/local/sbin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/local/bin/printf", X_OK) = -1 ENOENT (没有那个文件或目录)
faccessat(AT_FDCWD, "/usr/bin/printf", X_OK) = 0
stat("/usr/bin/printf", {st_mode=S_IFREG|0755, st_size=51176, ...}) = 0
openat(AT_FDCWD, "/dev/null", O_RDONLY|O_CLOEXEC) = 7
faccessat(AT_FDCWD, "/proc/5070/fd/.", F_OK) = 0
faccessat(AT_FDCWD, "/proc/5070/fd/.", F_OK) = 0
faccessat(AT_FDCWD, "/bin/bash", X_OK)  = 0
stat("/bin/bash", {st_mode=S_IFREG|0755, st_size=903440, ...}) = 0
pipe2([8, 9], O_CLOEXEC)                = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
vfork()                                 = 11679
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9)                                = 0
close(7)                                = 0
read(8, "setterm: \347\273\210\347\253\257 xterm-256color \344"..., 16384) = 51
read(8, "Couldn't get a file descriptor r"..., 16333) = 56
read(8, "/home/lujun9972/.bash_profile: \347"..., 16277) = 72
read(8, "Your display number is 0\nTest wh"..., 16205) = 78
read(8, "Fcitx is running correctly.\n\n==="..., 16127) = 104
read(8, "stdin isn't a tty!\n", 16023)  = 19
read(8, "__RESULT\0b269cd09e7ec4e8a115188c"..., 16004) = 298
read(8, 0x7ffd1d39cba6, 15706)          = ? ERESTARTSYS (To be restarted if SA_RESTART is set)
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=11679, si_uid=1000, si_status=0, si_utime=1, si_stime=1} ---
rt_sigreturn({mask=[]})                 = -1 EINTR (被中断的系统调用)
read(8, 

很容易就可以看出,当 Emacs 卡顿时,它在尝试从 8 号文件句柄中读取内容。

那么 8 号文件句柄在哪里定义的呢?往前看可以看到:

pipe2([8, 9], O_CLOEXEC)                = 0
rt_sigprocmask(SIG_BLOCK, [INT CHLD], [], 8) = 0
vfork()                                 = 11679
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
close(9)                                = 0

可以推测出,Emacs 主进程 fork 出一个子进程(进程号为 11679),并通过管道读取子进程的内容。

然而,从

--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=11679, si_uid=1000, si_status=0, si_utime=1, si_stime=1} ---
rt_sigreturn({mask=[]})                 = -1 EINTR (被中断的系统调用)
read(8, 

可以看出,实际上子进程已经退出了(父进程收到 SIGCHLD 信号),父进程确依然在尝试从管道中读取内容,导致的阻塞。

而且从

read(8, "setterm: \347\273\210\347\253\257 xterm-256color \344"..., 16384) = 51
read(8, "Couldn't get a file descriptor r"..., 16333) = 56
read(8, "/home/lujun9972/.bash_profile: \347"..., 16277) = 72
read(8, "Your display number is 0\nTest wh"..., 16205) = 78
read(8, "Fcitx is running correctly.\n\n==="..., 16127) = 104
read(8, "stdin isn't a tty!\n", 16023)  = 19
read(8, "__RESULT\0b269cd09e7ec4e8a115188c"..., 16004) = 298
read(8, 0x7ffd1d39cba6, 15706)          = ? ERESTARTSYS (To be restarted if SA_RESTART is set)

看到,子进程的输出似乎是我的交互式登录 bash 启动时的输出(加载了 .bash_profile

在往前翻发现这么一段信息:

readlinkat(AT_FDCWD, "/home", 0x7ffd1d3abb50, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972", 0x7ffd1d3abf00, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d", 0x7ffd1d3ac2b0, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa", 0x7ffd1d3ac660, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa/exec-path-from-shell-20180323.1904", 0x7ffd1d3aca10, 1024) = -1 EINVAL (无效的参数)
readlinkat(AT_FDCWD, "/home/lujun9972/.emacs.d/elpa/exec-path-from-shell-20180323.1904/exec-path-from-shell.elc", 0x7ffd1d3acdc0, 1024) = -1 EINVAL (无效的参数)
lseek(7, -2655, SEEK_CUR)               = 1441
read(7, "\n(defvar exec-path-from-shell-de"..., 4096) = 4096

这很明显是跟 exec-path-from-shell 有关啊。

通过查看 exec-path-from-shell 的实现,发现 exec-path-from-shell 的实现原理是通过实际调启一个 shell,然后输出 PATHMANPATH 的值的。 而且对于 bash 来说,默认的启动参数为 -i -l(可以通过exec-path-from-shell-arguments来设置)。也就是说 bash 会作为交互式的登录shell来启动的,因此会加载 .bash_profile.bashrc

既然发现跟 exec-path-from-shell 这个包有关,而且据说这个包对 Linux 其实意义不大,那不如直接禁用掉好了。

dotspacemacs-excluded-packages '(exec-path-from-shell)

再次重启Emacs,发现这次启动速度明显快了许多了。

最近我注意到 Emacs 25.1 增加了一个名为 global-eldoc-mode 的模式,它是流行的 eldoc-mode 的一个全局化的变体。而且与 eldoc-mode 不同的是,global-eldoc-mode 默认是开启的!

这意味着你可以删除 Emacs 配置中为主模式开启 eldoc-mode 的代码了:

;; That code is now redundant
(add-hook 'emacs-lisp-mode-hook #'eldoc-mode)
(add-hook 'ielm-mode-hook #'eldoc-mode)
(add-hook 'cider-mode-hook #'eldoc-mode)
(add-hook 'cider-repl-mode-hook #'eldoc-mode)

有人说 global-eldoc-mode 在某些不支持的模式中会有性能问题。我自己从未遇到过,但若你像禁用它则只需要这样:

(global-eldoc-mode -1)

现在是时候清理我的配置了!删除代码就是这么爽!


via: https://emacsredux.com/blog/2018/11/13/eldoc-goes-global/

作者:Bozhidar Batsov 选题:lujun9972 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我天天用 Emacs,但我却从意识到。但是每当我用 Emacs 时,它都给我带来了很多乐趣。

如果你是个职业作家……Emacs 与其它的编辑器的相比就如皓日与群星一样。不仅更大、更亮,它轻而易举就让其他所有的东西都消失了。

我用 Emacs 已有二十多年了。我用它来写几乎所有的东西(我用 IntelliJ 编辑 Scala 和 Java )。看邮件的话我是能在 Emacs 里看就在里面看。

尽管我用 Emacs 已有数十年,我在新年前后才意识到,在过去十几年里,我对 Emacs 的使用几乎没有什么变化。当然,新的编辑模式出现了,我就会选一两个插件,几年前我确实是用了 Helm,但大多数时候,它只是完成了我需要的所有繁重工作,日复一日,没有抱怨,也没有妨碍我。一方面,这证明了它有多好。另一方面,这是一个邀请,让我深入挖掘,看看我错过了什么。

于此同时,我也决定从以下几方面改进我的工作方式:

  • 更好的议程管理 我在工作中负责几个项目,这些项目有定期和临时的会议;有些我是我主持的,有些我只要参加就可以。

我意识到我对参加会议变得有些敷衍。往会议室里一坐很简单,但实际上我是在阅读电子邮件或处理其他事情。(我强烈反对在会议中“禁止携带笔记本电脑”的这条规定,但这是另一个话题。)

敷衍地去参加会议有几个问题。首先,这是对主持会议的人和其他参会者的不尊重。实际上这是不应该这么做的充分理由,但我还有意识到另一个问题:它掩盖了会议的成本。

如果你在开会,但同时回复了一封电子邮件,也许修复了一个 bug,那么这个会议就没什么成本(或没那么多)。如果会议成本低廉,那么会议数量将会更多。

我想要更少、更短的会议。我不想掩盖它们的成本,我想让开会变得很有价值,除非绝对必要,否则就干脆不要开。

有时,开会是绝对有必要的。而且我认为一个简短的会有时候能够很快的解决问题。但是,如果我一天要开十个短会的话,那我觉得还是不要假装取得了什么效果吧。

我决定在我参加的所有的会上做笔记。我并不是说一定要做会议记录,但是我肯定会花上几分钟。这会让我把注意力集中在开会上,而忽略其他事。

  • 更好的时间管理 无论是工作的或私人的,我有很多要做和想做的事。我一直在问题列表中跟踪其中的一些,一些在保存的电子邮件线索中(Emacs 和 Gmail 中,用于一些稍微不同的提醒),还有一些在日历、手机上各种各样的“待办事项列表”和小纸片上。可能还有其他地方。

我决定把它们放在一起。不是说我认为放到一个一致的地方就更好,而是我想完成两件事:首先,把它们都集中在一个地方,我能够更好更全面地了解我在哪里投入了更多的精力;其次,我想养成一个记录、跟踪并保存它们的习惯(习惯指“固定或规律的倾向或做法,尤指难以放弃的倾向或做法”)。

  • 更好的问责制 如果你在某些科学或工程领域工作,你就会养成记笔记的习惯。唉,我没有。但我决定这么做。

我对法律上鼓励使用装订页面或用永久记号笔涂抹并不感兴趣。我感兴趣的是养成做记录的习惯。我的目标是有一个地方记下想法和设计草图等。如果我突然有了灵感,或者我想到了一个不在测试套件中的边缘情况,我希望我的直觉是把它写在我的日志中,而不是草草写在一张小纸片上,或者自己觉得自己会记住它。

这些决心让我很快或多或少指向了 Org 模式。Org 模式有一个庞大的、活跃的、忠诚的用户社区。我以前也用过它(顺带一提,我都写过关于它的文章,在几年前),我花了很长的一段时间(将 MarkLogic 集成到其中。(这在过去的一两个星期里得到了回报!)

但我从没正经用过 Org 模式。

我现在正在用它。我用了几分钟,我把所有要做的事情都记录下来,我还记了日记。我不确定我争论或列表它的所有功能能有多大价值,你可以通过网页快速地搜索找到很多。

如果你用 Emacs,那你也应该用 Org 模式。如果没用过 Emacs,我相信你不会是第一个因 Org 模式而使用 Emacs 的人。Org 模式可以做很多。它需要一点时间来学习方法和快捷键,但我认为这是值得的。(如果你的口袋中有一台 iOS 设备,我推荐你在路上使用 beorg 来记录。)

当然,我想出了如何将 XML 从其中提取出来(“working out” 确实是“用 elisp 来编程”的一种有趣的魔法)然后,如何将它转换回我的博客用的标记(当然,在 Emacs 中按下一个按钮就可以做到)。这是用 Org 模式写的第一篇帖子。这也不会是最后一次。

附注:生日快乐,小博客


via: https://so.nwalsh.com/2019/03/01/emacs

作者:Norman Walsh 选题:lujun9972 译者:oneforalone 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我总是使用 Eshell 来与操作系统进行交互,因为它与 Emacs 无缝整合、支持处理 (远程) TRAMP 文件,而且在 Windows 上也能工作得很好。

启动 shell 命令后 (比如耗时严重的构建任务) 我经常会由于切换缓冲区而忘了追踪任务的运行状态。

多亏了 Emacs 的 钩子 机制,你可以配置 Emacs 在某个外部命令完成后调用一个 elisp 函数。

我使用 John Wiegleys 所编写的超棒的 alert 包来发送桌面通知:

(require 'alert)

(defun eshell-command-alert (process status)
  "Send `alert' with severity based on STATUS when PROCESS finished."
  (let* ((cmd (process-command process))
       (buffer (process-buffer process))
       (msg (format "%s: %s" (mapconcat 'identity cmd " ")  status)))
    (if (string-prefix-p "finished" status)
      (alert msg :buffer buffer :severity  'normal)
    (alert msg :buffer buffer :severity 'urgent))))

(add-hook 'eshell-kill-hook #'eshell-command-alert)

alert 的规则可以用程序来设置。就我这个情况来看,我只需要当对应的缓冲区不可见时得到通知:

(alert-add-rule :status   '(buried)     ;only send alert when buffer not visible
          :mode     'eshell-mode
          :style 'notifications)

这甚至对于 TRAMP 也一样生效。下面这个截屏展示了失败的 make 命令产生的 Gnome 桌面通知。


via: https://blog.hoetzel.info/post/eshell-notifications/

作者:Jürgen Hötzel 选题:lujun9972 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

昨天,一名推特用户“EmacsTW”发布了一条新的推文,告诫希望使用 Emacs 的人放弃 Emacs,转用一些现代化的编辑器比如 VSCode。

一时间,技术圈炸了锅,尤其是在 Emacs 用户群体,大家议论纷纷:

  • “中出了个叛徒”
  • “什么鬼?虽然我现在 VSCode 用的也比 Emacs 多,但说 Emacs 害人有点过了”
  • “哼哼哼… VSCode 又不能煮咖啡、不能玩遊戲”
  • “哈哈哈哈太突然了。作为一个 Emacs 使用者觉得他说的很有道理,我也从来不向他人推荐 Emacs,太浪费时间了。”
  • “我司如果只看 Vim vs. Emacs 的话,Vim 完胜,但是大部分还是 VSCode……”

一个 Emacs 忠实粉丝眼中的 Emacs 背刺事件

由于笔者本人并不是 Emacs 的粉丝(Vim 更合我的口味,XD),所以我去采访了 LCTT 翻译组内的 Emacs 铁粉,我们的选题负责人 DarkSun(lujun9972),问一问他的看法。

当我问起这个背刺的事件时,DarkSun 给我的第一个反应是:

欢迎背叛,舒服就成

在我表现出了不解之后,DarkSun 又进一步详细的解释了一下他的意思:

我觉得如果只是把 Emacs 当成写代码的工具,那真的不如用 IDE 了。

我把 Emacs 当成是工具信息交流的平台,类似终端那样的东西。Emacs 插件可以看成是 UNIX 工具,它们之间可以通过文本或 lisp 对象进行交流,只不过 Emacs 可以比普通终端更方便的利用这些文本(谁让它本来就是编辑器呢)。 举个例子说,我可以用 Emacs 看 PDF 文档,然后看到不懂的单词可以用有道词典进行翻译,翻译的结果可以直接存到 Anki 里当做背单词的素材。在这个过程中,Emacs 本身起的是信息交流平台的作用,至于解释 PDF、请求有道翻译,请求 anki 添加卡片都是由第三方程序或第三方的包来实现的。

一百个人有一百零一种使用 Emacs 的方法,我想 Emacs 的这种多样性才是其魅力所在吧。

在看了他对 Emacs 的理解以后,再联想到“Emacs煮咖啡”的梗,我对他的话深以为然。

Emacs 是什么?
目前我们所熟悉和使用的 Emacs 是由自由软件领袖 Richard Matthew Stallman (RMS)于 1984 年开发的,并维护至 2008 年。

Emacs 追求大的哲学,它希望在一个编辑器中去完成所有的功能,希望用户只需要借助快捷键与无处不在的宏,就可以完成任何事情,也正因为如此,Emacs 常常被戏称为“被误以为编辑器的操作系统”,而不是一个编辑器。

新旧技术的更迭

不可否认,近年来 VSCode 的良心功能和 Sublime Text 3 的舒适好用,使得越来越多的人开始使用这些现代化的开发工具。而对于一些比较重型的语言(比如 C/C++、Java、Golang 等),会借助 IDE 来完成开发的工作。

对于 Emacs 这样一个似乎是文本编辑器但好像又不是文本编辑器的工具来说,现代化的开发工具显然更能获取年轻人的喜爱。

不过,如果可以,我更希望说 “Emacs 不是一个工具,而是代表了一种生活方式”,在 Emacs 里,你可以完成任何事情,它就好像融入你的生活一般,改变了你的生活。从这个层面来看,Emacs 无人能敌。

被钉在耻辱柱上的社群背叛者 —— azazabc123

抛开 Emacs 和 VScode 的孰优孰劣不谈,就该推特维护者本身的行为来说,这是一种非常不妥的行为,这让 Emacs TW 社群蒙羞于整个技术社群。这种公器私用毫无疑问是背叛了整个社群,作为社群对外窗口的维护者,发布一条与本社群背道而驰的内容难免会让人觉得不妥。而且,这种行为使得对于 Emacs 的背叛行为从个人行为上升到了群体行为,Emacs TW 中的其他人是否同意这样的行为,还不甚明了——但笔者对该社团的管理能力和未来的前途不报什么期望。

笔者非常不支持这种公器私用的行为,固然其可能存在一定的吐槽、任性的想法,但对于整个社群而言,这种无脑行为只会损伤社群整体的信用度,也降低了对其个人的品行评价。

英雄迟暮?

诞生于 1984 年的 Emacs,迄今已经走过了 35 个年头。Emacs 从曾经的风头正劲,到如今已经略显包罗庞杂。不过,虽然经过了这么多年发展,Emacs 已经足够好用,但依然在坚持不断地更新。在刚刚过去的四月份,Emacs 发布了它的 26.2 版本。

Emacs 依然好用,但时代已经变了,对于如今的 Hacker 们,工具不是最重要的,工具所产生的价值要更加重要。在这种观念下,学习成本极高的 Emacs 难免不受欢迎,简单易用易上手的 VSCode、Sublime 就成为了必然的选择。

但无论如何,虽然我们欢迎新技术,也拥抱新变化,但是该推特维护者的这种让社区蒙羞的行为,依然让我们非常遗憾,表以谴责。

借助这些 Emacs 模式轻松记录信息。

不管你从事哪种工作,你都无可避免地需要记笔记。而且可能还不是一点点。现在这年头,大家都开始以数字的形式来记笔记了。

开源软件爱好者有多种途径来以电子的方式记下他们的创意、想法和研究过程。你可以使用 网页工具,可以使用 桌面应用,或者你也可以 使用命令行工具

如果你使用 Emacs(伪装成文本编辑器的强力操作系统),有多个 模式 mode 可以帮你有效地记录笔记。我们这里列举三个例子。

Deft

在少数情况下,我只能使用 Mac时,有一个工具是我不能缺少的:nvALT 笔记应用。Deft 模式 为 Emacs 带来了 nvALT 式的体验。

Deft 将你的笔记以文本文件的形式存储在电脑中的某个文件夹中。当你进入 Deft 模式,你会看到一系列的笔记及其摘要。这些摘要其实就是文本文件的第一行。若第一行是 Markdown、LaTeX,甚至 Emacs Org 模式的格式的话,Deft 会忽略掉这些格式而只显示文本内容。

要打开笔记,只需要向下滚动到该笔记的位置然后按下回车即可。然而 Deft 不仅仅只是这样。根据 Deft 开发者 Jason Blevins 的说法,它的主要操作是搜索和过滤。Deft 的实现方式简单而有效。输入关键字然后 Deft 会只显示标题中包含关键字的笔记。这在你要从大量笔记中找到某条笔记时非常有用。

Org 模式

如果本文没有包含 Org 模式 的话,那么我可能会被人所诟病。为什么?它可以说是 Emacs 中最灵活、使用最广泛的记录笔记的方式了。以正确的方式使用它,Org 模式可以极大地增强记笔记的能力。

Org 模式的主要优势在于它组织笔记的方式。在 Org 模式中,一个笔记文件会被组织成一个巨大的大纲。每个章节就是大纲里的一个节点,你可以对它进行展开和折叠。这些章节又可以有子章节,这些子章节也可以展开和折叠。这不仅使你一次只关注于某个章节,而且可以让你浏览整个大纲。

你可以在多个章节之间 进行互联,无需通过剪切和复制就能快速移动章节,以及 附加文件 到笔记中。Org 模式支持带格式的字符和表格。如果你需要转换笔记到其他格式,Org 模式也有大量的导出选项

Howm

当我使用 Emacs 已经成为一种习惯时,howm 马上就成为我严重依赖的模式之一了。虽然我特别喜欢使用 Org 模式,但 howm 依然占有一席之地。

Howm 就好像是一个小型维基。你可以创建笔记和任务列表,还能在它们之间创建链接。通过输入或点击某个链接,你可以在笔记之间跳转。如果你需要,还可以使用关键字为笔记添加标签。不仅如此,你可以对笔记进行搜索、排序和合并。

Howm 不是最漂亮的 Emacs 模式,它的用户体验也不是最佳。它需要你花一点时间来适应它,而一旦你适应了它,记录和查找笔记就是轻而易举的事情了。


via: https://opensource.com/article/18/7/emacs-modes-note-taking

作者:Scott Nesbitt 选题:lujun9972 译者:lujun9972 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出