标签 EMACS 下的文章

Trần Xuân Trường 写的 tmtxt-dired-async 是一个不为人知的 Emacs 包,它可以扩展 dired(Emacs 内置的文件管理器),使之可以异步地运行 rsync 和其他命令 (例如压缩、解压缩和下载)。

这意味着你可以拷贝上 GB 的目录而不影响 Emacs 的其他任务。

它的一个功能时让你可以通过 C-c C-a 从不同位置添加任意多的文件到一个等待列表中,然后按下 C-c C-v 异步地使用 rsync 将整个等待列表中的文件同步到目标目录中。光这个功能就值得一试了。

例如这里将 arduino 1.9 的 beta 存档同步到另一个目录中:

整个进度完成后,底部的窗口会在 5 秒后自动退出。下面是异步解压上面的 arduino 存档后出现的另一个会话:

这个包进一步增加了我 dired 配置的实用性。

我刚刚贡献了 一个拉取请求来允许 tmtxt-dired-async 同步到远程 tramp 目录中,而且我立即使用该功能来将上 GB 的新照片传输到 Linux 服务器上。

若你想配置 tmtxt-dired-async,下载 tmtxt-async-tasks.el(被依赖的库)以及 tmtxt-dired-async.el(若你想让它支持 tramp,请确保合并使用了我的拉取请求)到 ~/.emacs.d/ 目录中,然后添加下面配置:

;; no MELPA packages of this, so we have to do a simple check here
(setq dired-async-el (expand-file-name "~/.emacs.d/tmtxt-dired-async.el"))
(when (file-exists-p dired-async-el)
  (load (expand-file-name "~/.emacs.d/tmtxt-async-tasks.el"))
  (load dired-async-el)
  (define-key dired-mode-map (kbd "C-c C-r") 'tda/rsync)
  (define-key dired-mode-map (kbd "C-c C-z") 'tda/zip)
  (define-key dired-mode-map (kbd "C-c C-u") 'tda/unzip)

  (define-key dired-mode-map (kbd "C-c C-a") 'tda/rsync-multiple-mark-file)
  (define-key dired-mode-map (kbd "C-c C-e") 'tda/rsync-multiple-empty-list)
  (define-key dired-mode-map (kbd "C-c C-d") 'tda/rsync-multiple-remove-item)
  (define-key dired-mode-map (kbd "C-c C-v") 'tda/rsync-multiple)

  (define-key dired-mode-map (kbd "C-c C-s") 'tda/get-files-size)

  (define-key dired-mode-map (kbd "C-c C-q") 'tda/download-to-current-dir))

祝你开心!


via: https://vxlabs.com/2018/03/30/asynchronous-rsync-with-emacs-dired-and-tramp/

作者:cpbotha 选题:lujun9972 译者:lujun9972 校对:wxy

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

Emacs Start Up Profiler》 的作者教你六项减少 Emacs 启动时间的技术。

简而言之:做下面几个步骤:

  1. 使用 Esup 进行性能检测。
  2. 调整垃圾回收的阀值。
  3. 使用 use-package 来自动(延迟)加载所有东西。
  4. 不要使用会引起立即加载的辅助函数。
  5. 参考我的 配置

从 .emacs.d 的失败到现在

我最近宣布了 .emacs.d 的第三次失败,并完成了第四次 Emacs 配置的迭代。演化过程为:

  1. 拷贝并粘贴 elisp 片段到 ~/.emacs 中,希望它能工作。
  2. 借助 el-get 来以更结构化的方式来管理依赖关系。
  3. 放弃自己从零配置,以 Spacemacs 为基础。
  4. 厌倦了 Spacemacs 的复杂性,基于 use-package 重写配置。

本文汇聚了三次重写和创建 《Emacs Start Up Profiler》过程中的技巧。非常感谢 Spacemacs、use-package 等背后的团队。没有这些无私的志愿者,这项任务将会困难得多。

不过守护进程模式又如何呢

在我们开始之前,让我反驳一下优化 Emacs 时的常见观念:“Emacs 旨在作为守护进程来运行的,因此你只需要运行一次而已。”

这个观点很好,只不过:

  • 速度总是越快越好。
  • 配置 Emacs 时,可能会有不得不通过重启 Emacs 的情况。例如,你可能为 post-command-hook 添加了一个运行缓慢的 lambda 函数,很难删掉它。
  • 重启 Emacs 能帮你验证不同会话之间是否还能保留配置。

1、估算当前以及最佳的启动时间

第一步是测量当前的启动时间。最简单的方法就是在启动时显示后续步骤进度的信息。

;; Use a hook so the message doesn't get clobbered by other messages.
(add-hook 'emacs-startup-hook
    (lambda ()
        (message "Emacs ready in %s with %d garbage collections."
            (format "%.2f seconds"
                (float-time
                    (time-subtract after-init-time before-init-time)))
        gcs-done)))

第二步、测量最佳的启动速度,以便了解可能的情况。我的是 0.3 秒。

# -q ignores personal Emacs files but loads the site files.
emacs -q --eval='(message "%s" (emacs-init-time))' 

;; For macOS users:
open -n /Applications/Emacs.app --args -q --eval='(message "%s" (emacs-init-time))'  

2、检测 Emacs 启动指标对你大有帮助

Emacs StartUp Profiler》(ESUP)将会给你顶层语句执行的详细指标。

esup.png

图 1: Emacs Start Up Profiler 截图

警告:Spacemacs 用户需要注意,ESUP 目前与 Spacemacs 的 init.el 文件有冲突。遵照 https://github.com/jschaf/esup/issues/48 上说的进行升级。

3、调高启动时垃圾回收的阀值

这为我节省了 0.3 秒

Emacs 默认值是 760kB,这在现代机器看来极其保守。真正的诀窍在于初始化完成后再把它降到合理的水平。这为我节省了 0.3 秒。

;; Make startup faster by reducing the frequency of garbage
;; collection.  The default is 800 kilobytes.  Measured in bytes.
(setq gc-cons-threshold (* 50 1000 1000))

;; The rest of the init file.

;; Make gc pauses faster by decreasing the threshold.
(setq gc-cons-threshold (* 2 1000 1000))

~/.emacs.d/init.el

4、不要 require 任何东西,而是使用 use-package 来自动加载

让 Emacs 变坏的最好方法就是减少要做的事情。require 会立即加载源文件,但是很少会出现需要在启动阶段就立即需要这些功能的。

use-package 中你只需要声明好需要哪个包中的哪个功能,use-package 就会帮你完成正确的事情。它看起来是这样的:

(use-package evil-lisp-state ; the Melpa package name

  :defer t ; autoload this package

  :init ; Code to run immediately.
  (setq evil-lisp-state-global nil)

  :config ; Code to run after the package is loaded.
  (abn/define-leader-keys "k" evil-lisp-state-map))

可以通过查看 features 变量来查看 Emacs 现在加载了那些包。想要更好看的输出可以使用 lpkg explorer 或者我在 abn-funcs-benchmark.el 中的变体。输出看起来类似这样的:

479 features currently loaded
  - abn-funcs-benchmark: /Users/jschaf/.dotfiles/emacs/funcs/abn-funcs-benchmark.el
  - evil-surround: /Users/jschaf/.emacs.d/elpa/evil-surround-20170910.1952/evil-surround.elc
  - misearch: /Applications/Emacs.app/Contents/Resources/lisp/misearch.elc
  - multi-isearch: nil
  - <many more>

5、不要使用辅助函数来设置模式

通常,Emacs 包会建议通过运行一个辅助函数来设置键绑定。下面是一些例子:

  • (evil-escape-mode)
  • (windmove-default-keybindings) ; 设置快捷键。
  • (yas-global-mode 1) ; 复杂的片段配置。

可以通过 use-package 来对此进行重构以提高启动速度。这些辅助函数只会让你立即加载那些尚用不到的包。

下面这个例子告诉你如何自动加载 evil-escape-mode

;; The definition of evil-escape-mode.
(define-minor-mode evil-escape-mode
  (if evil-escape-mode
      (add-hook 'pre-command-hook 'evil-escape-pre-command-hook)
    (remove-hook 'pre-command-hook 'evil-escape-pre-command-hook)))

;; Before:
(evil-escape-mode)

;; After:
(use-package evil-escape
  :defer t
  ;; Only needed for functions without an autoload comment (;;;###autoload).
  :commands (evil-escape-pre-command-hook) 

  ;; Adding to a hook won't load the function until we invoke it.
  ;; With pre-command-hook, that means the first command we run will
  ;; load evil-escape.
  :init (add-hook 'pre-command-hook 'evil-escape-pre-command-hook))

下面来看一个关于 org-babel 的例子,这个例子更为复杂。我们通常的配置时这样的:

(org-babel-do-load-languages
 'org-babel-load-languages
 '((shell . t)
   (emacs-lisp . nil)))

这不是个好的配置,因为 org-babel-do-load-languages 定义在 org.el 中,而该文件有超过 2 万 4 千行的代码,需要花 0.2 秒来加载。通过查看源代码可以看到 org-babel-do-load-languages 仅仅只是加载 ob-<lang> 包而已,像这样:

;; From org.el in the org-babel-do-load-languages function.
(require (intern (concat "ob-" lang)))

而在 ob-<lang>.el 文件中,我们只关心其中的两个方法 org-babel-execute:<lang>org-babel-expand-body:<lang>。我们可以延时加载 org-babel 相关功能而无需调用 org-babel-do-load-languages,像这样:

;; Avoid `org-babel-do-load-languages' since it does an eager require.
(use-package ob-python
  :defer t
  :ensure org-plus-contrib
  :commands (org-babel-execute:python))

(use-package ob-shell
  :defer t
  :ensure org-plus-contrib
  :commands
  (org-babel-execute:sh
   org-babel-expand-body:sh

   org-babel-execute:bash
   org-babel-expand-body:bash))

6、使用惰性定时器来推迟加载非立即需要的包

我推迟加载了 9 个包,这帮我节省了 0.4 秒

有些包特别有用,你希望可以很快就能使用它们,但是它们本身在 Emacs 启动过程中又不是必须的。这些软件包包括:

  • recentf:保存最近的编辑过的那些文件。
  • saveplace:保存访问过文件的光标位置。
  • server:开启 Emacs 守护进程。
  • autorevert:自动重载被修改过的文件。
  • paren:高亮匹配的括号。
  • projectile:项目管理工具。
  • whitespace:高亮行尾的空格。

不要 require 这些软件包,而是等到空闲 N 秒后再加载它们。我在 1 秒后加载那些比较重要的包,在 2 秒后加载其他所有的包。

(use-package recentf
  ;; Loads after 1 second of idle time.
  :defer 1)

(use-package uniquify
  ;; Less important than recentf.
  :defer 2)

不值得的优化

不要费力把你的 Emacs 配置文件编译成字节码了。这只节省了大约 0.05 秒。把配置文件编译成字节码还可能导致源文件与编译后的文件不一致从而难以重现错误进行调试。


via: https://blog.d46.us/advanced-emacs-startup/

作者:Joe Schafer 选题:lujun9972 译者:lujun9972 校对:wxy

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

也许我所追求的究极 IDE 就是 Emacs 了。我的目标是使 Emacs 成为一款全能的 Python IDE。本文描述了如何在 Emacs 上配置 Anaconda。(LCTT 译注:Anaconda 自称“世界上最流行的 Python/R 的数据分析平台”)

我的配置信息:

  • OS:Trisquel 8.0
  • Emacs:GNU Emacs 25.3.2

快捷键说明(参见完全指南):

C-x = Ctrl + x
M-x = Alt + x
RET = ENTER

1、下载并安装 Anaconda

1.1 下载

从这儿 下载 Anaconda。你应该下载 Python 3.x 的版本,因为 Python 2 在 2020 年就不再支持了。你无需预先安装 Python 3.x。这个安装脚本会自动安装它。

1.2 安装

cd ~/Downloads
bash Anaconda3-2018.12-Linux-x86.sh

2、将 Anaconda 添加到 Emacs

2.1 将 MELPA 添加到 Emacs

我们需要用到 anaconda-mode 这个 Emacs 包。该包位于 MELPA 仓库中。Emacs25 需要手工添加该仓库。

2.2 为 Emacs 安装 anaconda-mode 包

M-x package-install RET
anaconda-mode RET

2.3 为 Emacs 配置 anaconda-mode

echo "(add-hook 'python-mode-hook 'anaconda-mode)" > ~/.emacs.d/init.el

3、在 Emacs 上通过 Anaconda 运行你第一个脚本

3.1 创建新 .py 文件

C-x C-f
HelloWorld.py RET

3.2 输入下面代码

print ("Hello World from Emacs")

3.3 运行之

C-c C-p
C-c C-c

输出为:

Python 3.7.1 (default, Dec 14 2018, 19:46:24)
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> python.el: native completion setup loaded
>>> Hello World from Emacs
>>>

我是受到 Codingquark 的影响才开始使用 Emacs 的。

有任何错误和遗漏请在评论中写下。干杯!


via: https://idevji.com/configure-anaconda-on-emacs/

作者:Devji Chhanga 选题:lujun9972 译者:lujun9972 校对:wxy

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

Eliza 是一个隐藏于某个 Linux 最流行文本编辑器中的自然语言处理聊天机器人。

欢迎你,今天时期 24 天的 Linux 命令行玩具的又一天。如果你是第一次访问本系列,你可能会问什么是命令行玩具呢。我们将会逐步确定这个概念,但一般来说,它可能是一个游戏,或任何能让你在终端玩的开心的其他东西。

可能你们已经见过了很多我们之前挑选的那些玩具,但我们依然希望对所有人来说都至少有一件新鲜事物。

今天的选择是 Emacs 中的一个彩蛋:Eliza,Rogerian 心理医生,一个准备好倾听你述说一切的终端玩具。

旁白:虽然这个玩具很好玩,但你的健康不是用来开玩笑的。请在假期期间照顾好你自己,无论时身体上还是精神上,若假期中的压力和焦虑对你的健康产生负面影响,请考虑找专业人士进行指导。真的有用。

要启动 Eliza,首先,你需要启动 Emacs。很有可能 Emacs 已经安装在你的系统中了,但若没有,它基本上也肯定在你默认的软件仓库中。

由于我要求本系列的工具一定要时运行在终端内,因此使用 -nw 标志来启动 Emacs 让它在你的终端模拟器中运行。

$ emacs -nw

在 Emacs 中,输入 M-x doctor 来启动 Eliza。对于像我这样有 Vim 背景的人可能不知道这是什么意思,只需要按下 escape,输入 x 然后输入 doctor。然后,向它倾述所有假日的烦恼吧。

Eliza 历史悠久,最早可以追溯到 1960 年代中期的 MIT 人工智能实验室。维基百科 上有它历史的详细说明。

Eliza 并不是 Emacs 中唯一的娱乐工具。查看 手册 可以看到一整列好玩的玩具。

 title=

你有什么喜欢的命令行玩具值得推荐吗?我们时间不多了,但我还是想听听你的建议。请在下面评论中告诉我,我会查看的。另外也欢迎告诉我你们对本次玩具的想法。

请一定要看看昨天的玩具,带着这个复刻版吃豆人来到 Linux 终端游乐中心,然后明天再来看另一个玩具!


via: https://opensource.com/article/18/12/linux-toy-eliza

作者:Jason Baker 选题:lujun9972 译者:lujun9972 校对:wxy

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

介绍

作为一名 Emacs 人,我尽可能让所有的工作流都在 Org 模式 Org-mode 上进行 —— 我比较喜欢文本。

我倾向于将书签记录在 Org 模式 代办列表中,而 Org 协议 Org-protocol 则允许外部进程利用 Org 模式 的某些功能。然而,要做到这一点配置起来很麻烦。(搜索引擎上)有很多教程,Firefox 也有这类 扩展,然而我对它们都不太满意。

因此我决定将我现在的配置记录在这篇博客中,方便其他有需要的人使用。

配置 Emacs Org 模式

启用 Org 协议:

(require 'org-protocol)

添加一个 捕获模板 capture template —— 我的配置是这样的:

(setq org-capture-templates
      (quote (...
              ("w" "org-protocol" entry (file "~/org/refile.org")
               "* TODO Review %a\n%U\n%:initial\n" :immediate-finish)
               ...)))

你可以从 Org 模式 手册中 捕获模板 章节中获取帮助。

设置默认使用的模板:

(setq org-protocol-default-template-key "w")

执行这些新增配置让它们在当前 Emacs 会话中生效。

快速测试

在下一步开始前,最好测试一下配置:

emacsclient -n "org-protocol:///capture?url=http%3a%2f%2fduckduckgo%2ecom&title=DuckDuckGo"

基于的配置的模板,可能会弹出一个捕获窗口。请确保正常工作,否则后面的操作没有任何意义。如果工作不正常,检查刚才的配置并且确保你执行了这些代码块。

如果你的 Org 模式 版本比较老(老于 7 版本),测试的格式会有点不同:这种 URL 编码后的格式需要改成用斜杠来分割 url 和标题。在网上搜一下很容易找出这两者的不同。

Firefox 协议

现在开始设置 Firefox。浏览 about:config。右击配置项列表,选择 “New -> Boolean”,然后输入 network.protocol-handler.expose.org-protocol 作为名字并且将值设置为 true

有些教程说这一步是可以省略的 —— 配不配因人而异。

添加 Desktop 文件

大多数的教程都有这一步:

增加一个文件 ~/.local/share/applications/org-protocol.desktop

[Desktop Entry]
Name=org-protocol
Exec=/path/to/emacsclient -n %u
Type=Application
Terminal=false
Categories=System;
MimeType=x-scheme-handler/org-protocol;

然后运行更新器。对于 i3 窗口管理器我使用下面命令(跟 gnome 一样):

update-desktop-database ~/.local/share/applications/

KDE 的方法不太一样……你可以查询其他相关教程。

在 FireFox 中设置捕获按钮

创建一个书签(我是在工具栏上创建这个书签的),地址栏输入下面内容:

javascript:location.href="org-protocol:///capture?url="+encodeURIComponent(location.href)+"&title="+encodeURIComponent(document.title||"[untitled page]")

保存该书签后,再次编辑该书签,你应该会看到其中的所有空格都被替换成了 %20 —— 也就是空格的 URL 编码形式。

现在当你点击该书签,你就会在某个 Emacs 框架中,可能是一个任意的框架中,打开一个窗口,显示你预定的模板。


via: http://www.mediaonfire.com/blog/2017_07_21_org_protocol_firefox.html

作者:Andreas Viklund 选题:lujun9972 译者:lujun9972 校对:wxy

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

OAuth 2.0 abstract protocol flow

看起来 OAuth 2.0 框架 已经越来越广泛地应用于 web (和 移动) 应用。太棒了!

虽然协议本身并不复杂,但有很多的使用场景、流程和实现可供选择。正如生活中的大多数事物一样,魔鬼在于细节之中。

在审查 OAuth 2.0 实现或编写渗透测试报告时我习惯画出 UML 图。这方便让人理解发生了什么事情,并发现潜在的问题。毕竟,一图抵千言。

使用基于 GPL 开源协议 Emacs 编辑器来实现,再加上基于 GPL 开源协议的工具 PlantUML (也可以选择基于 Eclipse Public 协议的 Graphviz) 很容易做到这一点。

Emacs 是世界上最万能的编辑器。在这种场景中,我们用它来编辑文本,并自动将文本转换成图片。PlantUML 是一个允许你用人类可读的文本来写 UML 并完成该转换的工具。Graphviz 是一个可视化的软件,这里我们可以用它来显示图片。

下载 预先编译好了的 PlantUML jar 文件Emacs 还可以选择下载并安装 Graphviz

安装并启动 Emacs,然后将下面 Lisp 代码(实际上是配置)写入你的启动文件中(~/.emacs.d/init.d),这段代码将会:

  • 配置 org 模式(一种用来组织并编辑文本文件的模式)来使用 PlantUML
  • plantuml 添加到可识别的 “org-babel” 语言中(这让你可以在文本文件中执行源代码)
  • 将 PlantUML 代码标注为安全的,从而允许执行
  • 自动显示生成的结果图片
;; tell org-mode where to find the plantuml JAR file (specify the JAR file)
(setq org-plantuml-jar-path (expand-file-name "~/plantuml.jar"))

;; use plantuml as org-babel language
(org-babel-do-load-languages 'org-babel-load-languages '((plantuml . t)))

;; helper function
(defun my-org-confirm-babel-evaluate (lang body)
"Do not ask for confirmation to evaluate code for specified languages."
(member lang '("plantuml")))

;; trust certain code as being safe
(setq org-confirm-babel-evaluate 'my-org-confirm-babel-evaluate)

;; automatically show the resulting image
(add-hook 'org-babel-after-execute-hook 'org-display-inline-images)

如果你还没有启动文件,那么将该代码加入到 ~/.emacs.d/init.el 文件中然后重启 Emacs。

提示:Control-c Control-f 可以让你创建/打开(新)文件。Control-x Control-s 保存文件,而 Control-x Control-c 退出 Emacs。

这就结了!

要测试该配置,可以创建/打开(Control-c Control-f)后缀为 .org 的文件,例如 test.org。这会让 Emacs 切换到 org 模式并识别 “org-babel” 语法。

输入下面代码,然后在代码中输入 Control-c Control-c 来测试是否安装正常:

#+BEGIN_SRC plantuml :file test.png
@startuml
version
@enduml
#+END_SRC

一切顺利的话,你会在 Emacs 中看到文本下面显示了一张图片。

注意:

要快速插入类似 #+BEGIN_SRC#+END_SRC 这样的代码片段,你可以使用内置的 Easy Templates 系统:输入 <s 然后按下 TAB,它就会自动为你插入模板。

还有更复杂的例子,下面是生成上面图片的 UML 源代码:

#+BEGIN_SRC plantuml :file t:/oauth2-abstract-protocol-flow.png
@startuml
hide footbox
title Oauth 2.0 Abstract protocol flow
autonumber
actor user as "resource owner (user)"
box "token stays secure" #FAFAFA
participant client as "client (application)"
participant authorization as "authorization server"
database resource as "resource server"
end box

group user authorizes client
client -> user : request authorization
note left
**grant types**:
# authorization code
# implicit
# password
# client_credentials
end note
user --> client : authorization grant
end

group token is generated
client -> authorization : request token\npresent authorization grant
authorization --> client :var: access token
note left
**response types**:
# code
# token
end note
end group

group resource can be accessed
client -> resource : request resource\npresent token
resource --> client : resource
end group
@enduml
#+END_SRC

你难道会不喜欢 Emacs 和开源工具的多功能性吗?


via: https://www.onwebsecurity.com/configuration/use-emacs-to-create-oauth-2-0-uml-sequence-diagrams.html

作者:Peter Mosmans 选题:lujun9972 译者:lujun9972 校对:wxy

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