Emacs Workflow - 文件管理

Geekinney 说: "文件管理"是每个操作系统最基本的功能。当我们使用计算机时,不可避免的要和文件打交道,比如:文件的创建、重命名、拷贝、移动、删除、搜索… 通常,我们通过鼠标来完成这些操作。但你有没有想过,这种鼠标点击和拖动的操作实际是非常低效的,我们在鼠标上浪费了大量的时间!

此刻,Linux用户加入了会话:“我们不用鼠标,我们用命令行。” 诚然,Linux命令行确实比鼠标高效很多。但你有没有想过存在一种更加便捷的方式, 结合了GUI的直观和TUI的高效,将每种命令换成一个或简单的几个按键来完成 ?这就是我要介绍的emacs文件管理系统。

在阅读下文之前,请先在 .emacs.d 目录下的 elisp 文件夹中创建 init-filemanage.el 文件, 我们将用这个文件来存储所有与文件管理相关的配置。

1 基础

1.1 文件目录结构

Emacs中浏览文件目录结构主要使用内置的 dired-mode 及其拓展 dired-x

由于是内置的package,无需额外安装。在emacs中直接通过按键 C-x d (调用 dired 命令)后输入要打开的目录后回车,即可打开对应的目录结构。默认情况下,emacs将当前buffer的所在的目录作为打开的目录。在改变目录路径时可以使用 TAB 键补全。

或者,通过按键 C-x C-j (调用 dired-jump 命令,这是dired-x的功能)直接打开当前buffer文件所在的目录。dired目录结构如下图:

dired-mode.png

1.1.1 文件导航

打开目录结构后,使用 n/pC-n/C-p 或方向键都可以在文件和目录间移动。在目录上按回车键会打开新的目录,在文件上按回车键会打开该文件。在 .. 上按回车键可以跳转到上级目录。除了这种方式,还可以按 C-x C-j 回到上级目录。其他的按键操作:

  • SPC: 向下移动一行
  • ^: 跳转到上一目录级
  • <: 移到上一个目录行,跳过文件行
  • >: 移到下一个目录行,跳过文件行
  • j: 移到指定文件行

1.1.2 文件浏览

  • A: 按照正则搜索文件,列出搜索结果
  • v: 以view-mode(只读)浏览文件内容
  • o: 在另一个窗口打开文件或目录
  • i: 在当前窗口插入子目录
  • s: 对列表按名字或日期排序

一些文件在emacs中的浏览体验不是很好,可以使用系统默认程序浏览文件,将下面这段代码(来自xah-emacs)加入 init-filemanage.el 文件中:

(defun xah-open-in-external-app (&optional @fname)
  "Open the current file or dired marked files in external app.
The app is chosen from your OS's preference.
When called in emacs lisp, if @fname is given, open that.
URL `http://ergoemacs.org/emacs/emacs_dired_open_file_in_ext_apps.html'
Version 2019-11-04"
  (interactive)
  (let* (($file-list
          (if @fname
              (progn (list @fname))
            (if (string-equal major-mode "dired-mode")
                (dired-get-marked-files)
              (list (buffer-file-name)))))
         ($do-it-p (if (<= (length $file-list) 5)
                       t
                     (y-or-n-p "Open more than 5 files? "))))
    (when $do-it-p
      (cond
       ((string-equal system-type "windows-nt")
        (mapc
         (lambda ($fpath)
           (w32-shell-execute "open" $fpath))
         $file-list))
       ((string-equal system-type "darwin")
        (mapc
         (lambda ($fpath)
           (shell-command
            (concat "open " (shell-quote-argument $fpath))))
         $file-list))
       ((string-equal system-type "gnu/linux")
        (mapc
         (lambda ($fpath) (let ((process-connection-type nil))
                            (start-process "" nil "xdg-open" $fpath)))
         $file-list))))))

(define-key dired-mode-map (kbd "<C-return>") 'xah-open-in-external-app)

使用方法:按键 C-return 调用这个命令可以使用系统默认应用打开dired中光标所在文件或被标记的多个文件。

1.1.3 文件选择

选择多个文件的目的是批量操作,比如批量移动、批量删除等。选择文件的操作我们称为标记(mark),相关按键如下:

  • m: 标记光标所在的文件或目录,并将光标下移一行
  • DEL: 删除上一行标记,并将光标上移一行
  • u: 取消光标所在文件或目录的标记
  • U: 取消所有文件或目录的标记
  • t: 反选所有文件或目录的标记
  • #: 标记所有以 # 结尾的emacs临时文件
  • ~: 标记所有以 结尾的emacs自动备份文件
  • d: 给文件或目录加“待删除”标记(按'x'执行删除)

1.1.4 文件操作

按下快捷键时,dired优先操作有mark标记的文件,多个标记则为批量操作,没有标记则只对当前光标下的文件操作。常用的操作有:

  • +: 创建子目录
  • C: 拷贝文件或目录
  • R: 重命名/移动 文件或目录
  • D: 直接删除文件或目录
  • x: 删除带有“待删除”标记(d)的文件或目录
  • c: 压缩文件,默认可使用的后缀有 .zip, .tar.gz, .tar.bz2, .tar.xz, .tar.zst
  • Z: 使用gzip压缩或解压缩文件
  • g: 刷新dired buffer

1.2 文件侧边栏

Emacs中浏览文件侧边栏目录树的插件有好几个,比较常用的有 内置的speedbar、neotreetreemacs 等。这里我们介绍neotree。Neotree侧边栏效果如下图:

neotree.png

1.2.1 安装

将如下安装代码粘贴到 init-filemanage.el 文件中:

(use-package neotree
  :ensure t
  :init (setq neo-window-fixed-size nil
              neo-theme (if (display-graphic-p) 'icons 'arrow))
  :bind (("<f8>" . neotree-toggle)))

1.2.2 使用

  • <f8>: 打开neotree
  • p, n: 文件目录间上下移动
  • SPC/RET/TAB: 这三个快捷键都可以打开文件或展开目录
  • U: 跳转到上一级目录
  • g: 刷新
  • H: 显示或隐藏 隐藏文件(dotfiles)
  • O: 打开目录下的所有目录结构
  • A: 最大化/最小化neotree窗口
  • C-c C-n: 创建文件或目录(以"/"结尾)
  • C-c C-d: 删除文件或目录
  • C-c C-r: 重命名文件后目录
  • C-c C-c: 设置当前目录为展示的根目录
  • C-c C-p: 复制文件或目录

1.3 文件Tab栏

文件的Tab栏用于快速切换最近打开的文件,我们介绍 centaur-tabs 。centaur-tabs效果如下图:

tabs.png

1.3.1 安装

将如下安装代码粘贴到 init-filemanage.el 文件中:

(use-package centaur-tabs
  :ensure t
  :config
  (setq centaur-tabs-style "bar"
        centaur-tabs-height 22
        centaur-tabs-set-icons t
        centaur-tabs-plain-icons t
        centaur-tabs-gray-out-icons t
        centaur-tabs-set-close-button t
        centaur-tabs-set-modified-marker t
        centaur-tabs-show-navigation-buttons t
        centaur-tabs-set-bar 'left
        centaur-tabs-cycle-scope 'tabs
        x-underline-at-descent-line nil)
  (centaur-tabs-headline-match)
  ;; (setq centaur-tabs-gray-out-icons 'buffer)
  ;; (centaur-tabs-enable-buffer-reordering)
  ;; (setq centaur-tabs-adjust-buffer-order t)
  (centaur-tabs-mode t)
  (setq uniquify-separator "/")
  (setq uniquify-buffer-name-style 'forward)
  (defun centaur-tabs-buffer-groups ()
    "`centaur-tabs-buffer-groups' control buffers' group rules.
 Group centaur-tabs with mode if buffer is derived from `eshell-mode' `emacs-lisp-mode' `dired-mode' `org-mode' `magit-mode'.
 All buffer name start with * will group to \"Emacs\".
 Other buffer group by `centaur-tabs-get-group-name' with project name."
    (list
     (cond
      ((ignore-errors
         (and (string= "*xwidget" (substring (buffer-name) 0 8))
              (not (string= "*xwidget-log*" (buffer-name)))))
       "Xwidget")
      ((or (string-equal "*" (substring (buffer-name) 0 1))
           (memq major-mode '(magit-process-mode
                              magit-status-mode
                              magit-diff-mode
                              magit-log-mode
                              magit-file-mode
                              magit-blob-mode
                              magit-blame-mode
                              )))
       "Emacs")
      ((derived-mode-p 'prog-mode)
       "Editing")
      ((derived-mode-p 'dired-mode)
       "Dired")
      ((memq major-mode '(helpful-mode
                          help-mode))
       "Help")
      ((memq major-mode '(org-mode
                          org-agenda-clockreport-mode
                          org-src-mode
                          org-agenda-mode
                          org-beamer-mode
                          org-indent-mode
                          org-bullets-mode
                          org-cdlatex-mode
                          org-agenda-log-mode
                          diary-mode))
       "OrgMode")
      (t
       (centaur-tabs-get-group-name (current-buffer))))))
  :hook
  (dashboard-mode . centaur-tabs-local-mode)
  (term-mode . centaur-tabs-local-mode)
  (calendar-mode . centaur-tabs-local-mode)
  (org-agenda-mode . centaur-tabs-local-mode)
  (helpful-mode . centaur-tabs-local-mode)
  :bind
  ("C-c b" . centaur-tabs-backward)
  ("C-c n" . centaur-tabs-forward)
  ("C-c m" . centaur-tabs-forward-group)
  ("C-c v" . centaur-tabs-backward-group))

1.3.2 使用

  • C-c n: 切换到下一个tab
  • C-c b: 切换到上一个tab
  • C-c v: 切换到上一个分组
  • C-c m: 切换到下一个分组

1.4 文件(内容)搜索

1.4.1 搜索当前文件内容

在当前文件中快速搜索内容,使用 swiper ,将下面代码粘贴到 init-filemanage.el 中:

(use-package swiper
  ;; 快捷搜索
  :ensure nil
  :bind (("C-s" . swiper)))

按键 C-s 就可以搜索内容啦。

1.4.2 搜索最近访问的文件

定位最近访问的文件最快的方法就是切换buffer,使用 ivy-switch-buffercounsel-switch-buffer 。区别是,后者在buffer选项间移动时会实时的显示buffer的内容。读者可以尝试一下这两个命令,然后选择自己喜欢的方式绑定到快捷键。我用 ivy-switch-buffer 。将下面的代码粘贴到init-filemanage.el文件中:

(global-set-key (kbd "C-x b") 'ivy-switch-buffer)

这段按键绑定的代码应该不难理解吧,相信你也应该知道怎么修改来使用另一个命令。哈哈,其实emacs-lisp也没有那么难啦~

当然也可以在之前ivy的配置中使用bind参数来绑定快捷键,就像前面的centaur-tabs。我们后面也将使用这种方式。

1.4.3 搜索经常访问的文件

对于经常需要访问的文件,使用 bookmark ,下次访问时直接从bookmark列表打开。将下面的代码粘贴到 init-filemanage.el 文件中:

(use-package bookmark
  :ensure nil
  :bind (("C-x r m" . bookmark-set)
         ("C-x r d" . bookmark-delete)
         ("C-x r j" . bookmark-jump)))

按键 C-x r m 将当前文件加入bookmark,默认名称为文件名,也可以自己重命名。按键 C-x r d 选择一个bookmark删除。按键 C-x r j 选择一个bookmark打开。或者,使用 counsel-bookmark ,结合了创建和跳转bookmark两个功能,代码见下文。

1.4.4 搜索当前目录下文件内容

在当前目录内按照文件的内容查找,使用 counsel-rg 。由于该命令通过 rg 来实现搜索,所以在使用前需要先安装命令行工具 rg(ripgrep) 。MacOS下直接使用homebrew安装(其他系统请使用各自的包管理器安装):

$ brew install ripgrep

1.4.5 搜索当前目录下文件

在当前目录下按照文件名称查找文件,使用 counsel-fzf 。由于该命令通过 fzf 来实现搜索,所以在使用前需要先安装命令行工具 fzf

$ brew install fzf

1.4.6 搜索当前git仓库下文件

在当前git代码仓库中查找文件,使用 counsel-git 。当前文件若不在git仓库中则无法使用该命令。

以上三种搜索方式,基本可以满足在emacs中快速定位和查找文件的需求。将下面的代码粘贴到 init-filemanage.el 文件中,相应快捷键的使用不再赘述。

(use-package counsel
  :ensure t
  :bind (("M-x" . counsel-M-x)
         ("C-x C-f" . counsel-find-file)
         ("C-c c t" . counsel-load-theme)
         ("C-c c b" . counsel-bookmark)
         ("C-c c r" . counsel-rg)
         ("C-c c f" . counsel-fzf)
         ("C-c c g" . counsel-git)))

额外地, C-c c t 用于切换内置主题。

2 附加

2.1 Dired额外功能

与文件系统相关的操作:

  • H: 建立硬链接
  • S: 建立软链接
  • G: 改变文件Group
  • O: 改变文件Owner
  • M: 改变文件权限
  • P: 打印

Dired中除了使用标记来批量操作文件外,还可以使用正则表达式。正则操作的快捷键一般以 % 开头。

  • % m: 标记正则匹配的文件
  • % d: 给正则匹配的文件添加“待删除标记”(按键'x'执行删除)
  • % g: 根据正则表达式,搜索所有文件的内容,标记内容中有正则匹配的文件
  • % u: 所有标记的文件名称转化为大写
  • % l: 所有标记的文件名称转化为小写

对于已经标记的文件,我们可以不用打开文件,而对多个文件的内容进行搜索或替换操作。

  • A: 根据正则表达式搜索已标记的文件的内容,并列出所有匹配行
  • Q: 对标记的文件逐一进行正则替换,按键 "y" 替换,按键 "n" 跳过

dired还可以通过调用外部命令来操作文件。

  • !: 以同步的方式调用shell命令来操作文件,命令运行的工作目录就是dired的当前目录
  • &: 以异步的方式调用shell命令来操作文件,命令运行的工作目录就是dired的当前目录

2.2 Dired美化

嫌dired-mode颜色太单调?下面我们就给dired变个妆:

(use-package diredfl
  :ensure t
  :config (diredfl-global-mode t))

(use-package all-the-icons-dired
  :ensure t
  :config
  (add-hook 'dired-mode-hook 'all-the-icons-dired-mode))

all-the-icons-dired 会自动安装其依赖的 all-the-icons package,安装成功后通过按键 M-x all-the-icons-install-fonts 安装必要的字体(此操作需要科学上网)。 没办法科学上网的同学可以直接将 字体 下载到本地后添加到系统的字体目录中,如何添加自行搜索。

美化后的效果:

beautiful-dired.png

3 结语

断断续续,花了一周的时间梳理文件管理的工作流。希望大家能够积极留言,说说有哪些对于新手难以理解的地方,有哪些其他的文件管理方面的需求。有不合理的地方也敬请指出,我将根据大家的反馈不断完善文章的内容。

At last, happy hacking emacs!

发布于 2020-07-05

Emacs Workflow - 准备工作

众所周知,emacs以学习曲线陡峭著称,所以在开始介绍workflow前,得做些准备工作。这篇文章主要介绍emacs的安装、基础概念、基础配置和使用emacs的基础知识。

安装

Emacs的安装非常简单,各个平台的安装方法详见官网。我使用的是MacOS,通过homebrew安装 emacs-plus 27,支持xwidget webkit。安装代码如下:

$ brew tap d12frosted/emacs-plus
$ brew install emacs-plus@27 --with-xwidgets

MacOS Homebrew 的安装方法见 brew.sh

快捷键

Emacs和其他编辑器的相比一个重要的优势就是全键盘操作。所以在使用emacs之前,先通过按键 C-h t 查看内置的快捷键教程是一个较好的开端。下面对基本快捷键做简要介绍:

Emacs的快捷键都是组合键,由前缀键加上字母或数字组成。常见的前缀键有:

  • M 对应 Alt
  • C 对应 Control
  • S 对应 Shift

形如 C-x C-f 的快捷键表示按住 Ctrl 键时按下字母 X , 再按住 Ctrl 键同时按下字母 F

下面是一些常用快捷键:

快捷键 功能 快捷键 功能
C-x C-c 关闭Emacs 编辑  
C-g 取消当前按键输入 C-@C-SPC 设置mark
    M-w 复制
移动   C-w 剪切
C-p 光标上移 C-y 粘贴
C-n 光标下移 C-x h 全选
C-b 光标左移 C-x C-q 切换只读/编辑模式
C-f 光标右移 C-/ 撤销上一步操作
C-a 光标移到行首    
C-e 光标移到行尾 缓冲区  
M-b 光标前移一个单词 C-x b 切换buffer
M-f 光标后移一个单词 C-x k 关闭buffer
C-v 向下翻页 C-x C-b 查看所有打开的缓冲区
M-v 向上翻页    
C-l 光标移到屏幕上/中/下部 窗口  
C-x [ 光标跳到文首 C-x 2 在下面分割一个窗口
C-x ] 光标跳到文末 C-x 3 在右边分割一个窗口
    C-x 0 关闭当前窗口
文件   C-x 1 关闭其它窗口
C-x C-f 打开(创建)文件 C-x o 依次切换窗口
C-x C-s 保存文件    

最小配置

Emacs使用Emacs-Lisp作为配置语言,通过添加配置可以使emacs符合个人的使用习惯和实现各种功能。通常,emacs的配置文件放置在用户根目录的 .emacs.d 文件夹中。其中的 init.el 作为配置的入口文件。

下面提供了一段最小配置(参考 better-defaults ),直接将它复制粘贴到 init.el 文件中后,重启emacs。

  ;;; better defaults
(unless (or (fboundp 'helm-mode) (fboundp 'ivy-mode))
  (ido-mode t)
  (setq ido-enable-flex-matching t)) ;; 使用ido补全

(unless (eq window-system 'ns)
  (menu-bar-mode -1)) ;; 禁用菜单栏
(when (fboundp 'tool-bar-mode)
  (tool-bar-mode -1)) ;; 禁用工具栏
(when (fboundp 'scroll-bar-mode)
  (scroll-bar-mode -1)) ;; 禁用垂直滚动条
(when (fboundp 'horizontal-scroll-bar-mode)
  (horizontal-scroll-bar-mode -1)) ;; 禁用水平滚动条

(require 'uniquify)
(setq uniquify-buffer-name-style 'forward)

;; https://www.emacswiki.org/emacs/SavePlace
(save-place-mode 1) ;; 保存光标文位置

(global-set-key (kbd "C-s") 'isearch-forward)
(global-set-key (kbd "C-r") 'isearch-backward)
(global-set-key (kbd "C-c C-/") 'comment-or-uncomment-region) ;; 代码块注释和反注释

(show-paren-mode 1) ;; 显示括号匹配
(setq-default indent-tabs-mode nil)
(setq save-interprogram-paste-before-kill t
      apropos-do-all t
      mouse-yank-at-point t
      require-final-newline t
      load-prefer-newer t
      ediff-window-setup-function 'ediff-setup-windows-plain)

(require 'dired-x)
(delete-selection-mode 1) ;; 选择后插入,删除原字符。
(recentf-mode 1) ;; 保存最近访问
(global-auto-revert-mode 1) ;; 自动加载更新内容
(fset 'yes-or-no-p 'y-or-n-p) ;; 使用 'y/n' 代替 'yes/no'
(setq custom-file (concat user-emacs-directory "custom.el"))
(setq inhibit-startup-message t) ;; 禁止启动信息
(setq ring-bell-function 'ignore) ;; 禁止发出声音警告
(setq make-backup-files nil) ;; 不允许备份
(setq auto-save-default nil  ;; 不允许默认自动保存
      auto-save-silent t))   ;; 自动保存时不显示消息
(setq scroll-step 1 scroll-margin 3 scroll-conservatively 10000) ;; 连续滚动
(setq confirm-kill-emacs
      (lambda (prompt) (y-or-n-p-with-timeout "Whether to quit Emacs:" 10 "y"))) ;; 防误操作退出
(setq dired-recursive-deletes 'always
      dired-recursive-copies 'always) ;; 全部递归拷贝、删除文件夹中的文件

包管理

Emacs的package(也就是我们通常说的"包"或"插件")可以为emacs拓展丰富多样的功能。为了能够使用这些package,需要配置获取package的源。在init.el的最后加上以下代码:

(setq package-enable-at-startup nil)
(setq package-archives '(("gnu" . "http://mirrors.cloud.tencent.com/elpa/gnu/")
                         ("melpa" . "http://mirrors.cloud.tencent.com/elpa/melpa/")))

配置好源后,按键 M-x list-packages 可以查看所有已发布的package。按键 M-x package-install 后输入package名字可以直接安装,同理使用 package-delete 删除。使用package,需要先在配置文件中写入 (require '<package-name>) 这个过程相当于导入(import)。再加上必要的自定义配置便可使用该package所有的功能。

以上的包管理方案由emacs内置的 package.el 提供。但内置的不一定是最好的。因此,有一些package专门提供了更加灵活、自动化的包管理方案。常用的有 use-package quelpa straight el-get 等,我使用的是 use-package 结合 git submodule 。下面的代码用于初始化 use-package ,加入init.el结尾。

(unless (package-installed-p 'use-package)
  (package-refresh-contents)
  (package-install 'use-package))

写完配置代码后,在最后一个括号后面按键 C-x C-e (eval-last-sexp)即可执行配置,安装package。也可以重启emacs,再次打开时emacs会自动加载所有配置。

配置管理

值得注意的是,我们将上面的配置代码统统写入了init.el文件中。可以预见,当安装许多package时,配置代码将会增多,init.el的内容会变得复杂无比,难以阅读和维护。我们需要一种合理的组织配置文件的方式。

解决方法是将每一种workflow的配置代码写在单独的文件中,然后在init.el中引入该文件。操作如下:

  1. 在.emacs.d文件夹下创建elisp文件夹。
  2. 在init.el中添加代码 (add-to-list 'load-path (concat user-emacs-directory "elisp"))
  3. 在elisp文件夹下创建 init-better.el ,将“最小配置”的代码粘贴进去。
  4. init-better.el 最后加上代码 (provide 'init-better)
  5. init.el 最后加上代码 (require 'init-better)

根据字面意思也不难理解:步骤2的代码将elisp文件夹下的所有文件加入配置加载路径;步骤4的provide提供文件名,使其可以被引入;步骤5的require引入了该文件。这样我们就将最小配置的代码引入到init.el中了。以后的各种workflow我们也将使用这种方式来组织配置文件。

实用package

介绍一些对于新手实用的package,直接将下面的配置粘贴到elisp文件夹下的 init-utils.el 文件中。

(use-package super-save
  ;; 自动保存,用于替换默认的自动保存
  :ensure t
  :config
  (super-save-mode +1)
  (setq super-save-auto-save-when-idle t))

(use-package which-key
  ;; emacs按键提示
  :ensure t
  :config
  (which-key-mode))

(use-package ivy
  ;; emacs补全框架
  :ensure t
  :init
  (setq ivy-use-virtual-buffers t
        enable-recursive-minibuffers t)
  :config
  (ivy-mode 1))

同理,在配置init-utils.el文件结尾加上 (provide 'init-utils) ,然后在init.el中引入 (require 'init-utils)

emacs主题

选择一个简洁、美观的主题不仅可以缓解眼睛疲劳,还可以提高使用emacs的效率。emacs的主题分为亮色和暗色两种,我的使用习惯是白天使用亮色主题,晚上使用暗色主题。也可以选择喜欢的第三方主题安装。我最喜欢的亮色主题是leuven(内置),暗色主题是dracula(第三方)。

全部配置代码

我建议你按照教程的步骤,一步步拷贝、粘贴、执行代码。这个过程中,你会了解到如何从零配置一个功能强大的emacs编辑器,如何像搭积木一样通过添加配置文件使emacs充满无限的可能性。所有的配置代码我也会放在 emacs-workflow-config 这个代码仓库,读者可以直接把它克隆到 .emacs.d 文件夹下使用。

结语

如何配置一个舒适易用的emacs环境是一个大话题,有很多非常nice的package,但考虑到这大多数是与“提高编程的体验”相关,并不是Emacs Workflow的重点。所以,这一篇中我只介绍一个最小配置和部分实用(必要)的package,更多的优化配置不多讲解。好啦,以上就是使用emacs前的准备工作,接下来就可以愉快的学习各种工作流啦!

发布于 2020-06-25

Emacs Workflow - 开门见山

Emacs Workflow 顾名思义 “emacs工作流”。这一系列的文章主要介绍emacs中的常用的工作流,比如:文件管理、日程管理、笔记管理、听音乐、网页浏览、收发邮件、版本控制、字典查阅、快捷搜索、代数计算、telegram… 每一种工作流都可以替代一种额外的app或系统应用。最终,我们逐渐向 "live in emacs" 的目标靠近。

在介绍具体的emacs workflow之前,我觉得有必要先搞清楚下面几个问题。

什么是Emacs?

官网的介绍是 "An extensible, customizable, free/libre text editor — and more"。这里有5个关键词:可拓展、可定制、自由、编辑器、更多。

emacs本质上是一个 编辑器 ,从这个意义上来说,它和办公中经常使用的 MS word,程序员使用的vim, notepad别无二致。 可拓展 意味着我们可以通过程序来实现新的功能、特性。 可定制 意味着我们可以通过配置使emacs符合个人使用习惯。 自由 说的是emacs是一个自由软件(非商业)。 更多 包含了不计其数的可能性。

上面的解释可以总结为一句话: "If related data, nothing is impossible in Emacs."。你可能觉得这有点夸张,但我可以解释给你听:

这是个物质的世界,也是个数据的世界。物质的联系产生了数据,数据的改变塑造了物质。数据的种类有很多:简单的阿拉伯数字、数学公式、化学方程式、计算机程序、历史资料、软件密码、基因序列、社会信息…这些都是数据。因此,我们可以简单的得出一个结论,改变数据就可以改变一切。

编辑器的作用是编辑数据,处理文本。普通的编辑器只能对数据进行简单的处理,比如插入、删除、改变样式、公式计算等等。而Emacs的高度可拓展性为数据处理提供了无限的可能。使用elisp,调用外部程序,emacs可以为数据之间创造复杂的逻辑,实现各种功能,满足各种需求,从而无所不能。

我们可以随便举一个看似不可能在emacs中完成的例子,看看emacs如何把不可能变成可能。比如:用emacs来煮咖啡。值得注意的是,使用emacs的前提是 "data related",即能够与emacs交换数据信息。所以,假设我们有一个智能咖啡机,可以通过外部指令控制。现在我们可以编写一个 make-coffee 函数执行煮咖啡的指令,然后 M-x make-coffee ,大功告成!这是一个看似很简单的例子,但却揭示了emacs的本质: Emacs是一个使用程序来处理数据的万能前端 。这一点和操作系统很像。

以上就是我对Emacs的理解。

什么样的人适合使用Emacs?

很多人认为Emacs是程序员、hacker的专利,我不认同。我觉得Emacs可以是大众的编辑器,可以服务于我们每一个普通人。无论你的职业为何,只要生活和工作离不开计算机,Emacs都可以成为你提升效率的大杀器。从这个以上意义上来说, Emacs适合每一个经常和计算机打交道的人

为什么我推荐你使用Emacs?

我曾经向很多熟悉的,不熟悉的人安利过emacs,但成功的情况很少。原因在于,我总是会像上面"什么是Emacs?"中一样,把它介绍的很牛逼,因此让人望而生畏。事实上,emacs确实很牛逼,但牛逼的东西也是由简单的事物构成的,就像一个复杂的计算机系统是由简单的 0、1 组成。

不同职业、不同身份的人使用计算机的需求和程度不一样,学习的计算机知识的难度也不同。用计算机办公、处理邮件的人只需要学习office办公软件,学会收发邮件;用计算机制作和处理图片、音视频的人只需要学习诸如PS、PR、AE等专业软件;普通程序员需要了解计算机运行的原理,学习如何通过特定的程序语言与计算机交互;高级黑客需要学习计算机底层架构和原理,了解程序语言背后的逻辑 ……

很少人因为计算机是个复杂的东西就放弃使用它,因为你不需要了解它的全部,只需学习你需要使用的部分;因为只要你用它,就会给工作和生活带来极大的便利。这句话用在Emacs上也再合适不过了!

这就是我推荐你使用Emacs的全部理由。

这是怎样的Emacs教程?

Emacs Workflow 系列的文章会更关注新手,因此概念解释会比较详细。一个完整的工作流包含与之相关的方方面面,我将在我知识所及的情况下尽可能的介绍全面。工作流的不同方面可能会使用不同的emacs package或我自己编写的elisp代码,对于package或代码的内容,新手无需理解,拷贝粘贴后掌握如何使用即可。工作流的介绍分为“基础”和“附加”两部分。附加部分介绍不常用的或与程序相关的功能,这部分新手可以直接跳过。实现某一特定功能的package可能不只一个,我的解决方案可能不是最优解,欢迎留言补充。

最后,希望我的工作对你有所帮助,希望emacs伴你走过每一个春夏秋冬~

发布于 2020-06-14