1. 基本控制命令

c - v, m - v, c - l, 前滚,后滚,居中或者顶部或者底部 c - p, c - n, 上一行,下一行 c - b, c - f, m - b, m - f, 下一个,上一个, 下一词,上一词 c - a, c - e, m - a, m - e, 行首,行尾,句首,句尾 m - <, m - >, 文首,文尾

c - u 数值 c - v 这样的命令用于重复执行数值次数的命令. 如果重复的是 c-n,那么只是光标下移多少行,如果是 c-v,那么不是翻多少页,而是页面整体滚动多少行。 c - g 停止并取消命令 c-x k 关闭当前的buffer

c-x 1 只保留一个窗口。

删除以下3种 del, c-d, 删除前一个,删除后一个 m-del, m-d, 删除前一个词,删除后一个词语 c-k, m-k, 删除到行尾,删除到句尾

粘贴 c-y, m-y, 粘贴, 粘贴之后的文本选择

c-@ 选中 c-w 剪切 m-w 复制 c-/ 撤销

c-x c-f 打开文件 c-x c-s 保存当前文件 c-x s 保存所有改变了的文件 c-x c-c 退出 emacs c-x c-b 列出所有当前 buffer c-x b 输入 buffer 名字,然后跳转buffer c-z 在命令行界面停止 emacs,然后可以执行其他命令, %emacs 恢复 emacs c-x u 撤销 c-x, m-x, 单个按键命令,命令词命令

m-x 额外命令,输入的时候,输入几个字母后,按空格,会补充命令到 ‘-’ 字符, 按 tab 按键可以补充完整。比如 replace-string, 可以输入 repl 然后空格,再输入 s,然后 tab。

2. 替换

replace-string 输入需要替换的和新的字符串,然后输入回车。

3. 自动保存

如果修改 hello.c 文件,那么会自动保存文件为 #hello.c#,如果系统崩溃,那么下次开机,使用 c-x c-f 打开 hello.c 文件,然后 m-x recover-file <return>,询问确定的时候,输入 yes<return> 就可以恢复自动保存的文件了。

4. emacs 对于文件都有一个主模式,可以通过 m-x fundamental-mode 这样切换到 fundamental 模式。或者 m-x text-mode 切换到 text-mode

text-mode 下 撇号是单词的一部分, fundamental中撇号是用来分隔单词的。

5. c-h k c-w 这样的命令可以用来查看 c-w 这条命令的帮助信息。

c-h m 可以用来查看当面的 文件模式信息。 比如 fundamental-mode。 c-h ? 搜索总览,使用 c-g 退出 c-h c 是命令的基本帮助信息, c-h c c-p 会再下方显示出简单的提示信息,而不是打开一个专门的窗口来显示完整信息。 c-h f 用来显示功能函数的帮助 c-h v 用来显示变量的帮助 c-h a 输入命令的一部分,查看完整命令 c-h i 进入 info 的界面,输入 m emacs 就可以查看 manual,按 h 可以查看相应的帮助 c-h r 查看 manual

6. m-x auto-fill-mode 这个次模式可以把长的单词放到下一行,但是分离的时候,是从空格的地方开始分离的。

但是如果是再一个段落的中间插入很多字符, auto-fill-mode 不会自动分隔,需要手动使用 m-q 来对这个段落重新分隔。

7. 设置边界 c-x f, 默认是 70个字符。

c-u 20 c-x f 设置边界 为 20个字符, 或者 c-x f <return> 20 也是一种办法。

8. 搜索

c-s 向前搜索, c-r 向后搜索。<del> 返回上一个搜索的地方,如果没有上一个,就删除搜索的字符 。 可以输入 c-g 或者 结束搜索。

9. 打开一个新的窗口

c-x 2 再下面打开一个新的窗口 c-m-v 下面一个窗口向下滚动,并保持光标再上面窗口 c-m-shift-v 下面一个窗口向上滚动,并保持光标再上面窗口 c-x o 移动光标到另外一个窗口 c-x 4 c-f 文件名称, 再下方打开一个文件,并且光标移动到新文件里面。

10. 打开一个新的 frame

c-x 5 2 或者 m-x make-frame 打开一个新的frame c-x 5 0 或者 m-x delete-frame 关闭这个 frame

11. 小心递归模式, 当 下方显示 [(fundamental)] 这样的,就是递归了,不能通过 c-g 来退出,只能通过 <esc><esc><esc> 来退出这种模式。

剩余需要关注的帮助中的内容

completion,自动补完 Dired,显示目录

12. 在文档中使用 lisp 功能,需要使用 m-x 开启 lisp-interaction-mode,然后在 (+ 1 1) 这个右括号的右边 c-j 就可以在下一行获得结果。使用 c-x c-e 结果会显示在 minibuffer 里面。

(setq my-name "bb") 这个会把 "bb" 保存到 my-name 这个变量里面。
(insert "Hello!") 在鼠标处插入 "hello!"
(insert "Hello" " world!")  "Hello world!"
(insert "Hello, I am " my-name)  "Hello, I am bb"

无参数函数
(defun hello () (insert "Hello, I am " my-name))
(hello)

带参数函数
(defun hello (name) (insert "Hello " name))
(hello "you")

(switch-to-buffer-other-window "*test*")

多条语句
(progn
  (switch-to-buffer-other-window "*test*")
  (hello "you"))

(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello "there"))

返回前面窗口。
(progn
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello "you")
  (other-window 1))

也可以用 let 来把数值绑定在变量上面,并且这时候,就不需要 progn 来组合多条语句了。
(let ((local-name "you"))
  (switch-to-buffer-other-window "*test*")
  (erase-buffer)
  (hello local-name)
  (other-window 1))

格式化字符串
(format "Hello %s!\n" "visitor")

(defun hello (name)
  (insert (format "Hello %s!\n" name)))
(hello "you")

定义函数,使用 let 语句
(defun greeting (name)
  (let ((your-name "Bastien"))
    (insert (format "Hello %s!\n\nI am %s."
                    name       ; the argument of the function
                    your-name  ; the let-bound variable "Bastien"
                    ))))
(greeting "you")

获得输入
(read-from-minibuffer "Enter your name: ")

获得输入,然后格式化字符串输出
(defun greeting (from-name)
  (let ((your-name (read-from-minibuffer "Enter your name: ")))
    (insert (format "Hello!\n\nI am %s and you are %s."
                    from-name ; the argument of the function
                    your-name ; the let-bound var, entered at prompt
                    ))))
(greeting "Bastien")

获取输入,并输出到另一个窗口
(defun greeting (from-name)
  (let ((your-name (read-from-minibuffer "Enter your name: ")))
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    (insert (format "Hello %s!\n\nI am %s." your-name from-name))
    (other-window 1)))
(greeting "Bastien")

设置名称列表,输出第一个名字,输出除了第一个名字以外的名字
(setq list-of-names '("Sarah" "Chloe" "Mathilde"))
(car list-of-names)
(cdr list-of-names)

在列表最前面增加一个名字
(push "Stephanie" list-of-names)
输出每个名字,并在名字之前增加 hello
(mapcar 'hello list-of-names)

(defun greeting ()
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    (mapcar 'hello list-of-names)
    (other-window 1))
(greeting)

回到 buffer 的开头 goto-char (point-min)
(defun replace-hello-by-bonjour ()
    (switch-to-buffer-other-window "*test*")
    (goto-char (point-min))
    (while (search-forward "Hello")
      (replace-match "Bonjour"))
    (other-window 1))
(replace-hello-by-bonjour)

search-forward "Hello" nil t, 可以不输出搜索到结尾的报错信息。;; The `nil' argument says: the search is not bound to a position.;; The `'t' argument says: silently fail when nothing is found.
(defun hello-to-bonjour ()
    (switch-to-buffer-other-window "*test*")
    (erase-buffer)
    ;; Say hello to names in `list-of-names'
    (mapcar 'hello list-of-names)
    (goto-char (point-min))
    ;; Replace "Hello" by "Bonjour"
    (while (search-forward "Hello" nil t)
      (replace-match "Bonjour"))
    (other-window 1))

;; The regular expression is "Bonjour \\(.+\\)!" and it reads:
;; the string "Bonjour ", and
;; a group of            | this is the \\( ... \\) construct
;;   any character       | this is the .
;;   possibly repeated   | this is the +
;; and the "!" string.
(defun boldify-names ()
    (switch-to-buffer-other-window "*test*")
    (goto-char (point-min))
    (while (re-search-forward "Bonjour \\(.+\\)!" nil t)
      (add-text-properties (match-beginning 1)
                           (match-end 1)
                           (list 'face 'bold)))
    (other-window 1))

参考: https://learnxinyminutes.com/docs/zh-cn/elisp-cn/ https://learnxinyminutes.com/docs/elisp/

13. 显示行号。

M-x linum-mode

14. 简单 elisp

;; 2 + 2
(+ 2 2)

;; 2 + 3 * 4
(+ 2 (* 3 4))

;; 定义变量
(setq name "username")
(message name) ; -> "username"

;; 定义函数
(defun func ()
  (message "Hello, %s" name))

;; 执行函数
(func) ; -> Hello, username

;; 设置快捷键
(global-set-key (kbd "<f1>") 'func)

;; 使函数可直接被调用可添加 (interactive)
(defun func ()
  (interactive)
  (message "Hello, %s" name))

15. 配置文件,保存在 ~/.emacs.d/init.el 里面,确保把 ~/.emacs 这个删除掉。

;; 显示行号
(global-linum-mode 1)

;; 快速打开配置文件
(defun open-init-file()
  (interactive)
  (find-file "~/.emacs.d/init.el"))

; 开启全局 Company 补全
(global-company-mode 1)

在每次编辑配置文件后,刚刚做的修改并不会立刻生效。这时你需要重启编辑器或者重新加 载配置文件。重新加载配置文件你需要在当前配置文件中使用 M-x load-file 双击两次 回车确认默认文件名,或者使用 M-x eval-buffer 去执行当前缓冲区的所有 Lisp 命令。 你也可以使用 C-x C-e 来执行某一行的 Lisp 代码,如果要全部执行,那还是用 M-x eval-buffer 更加方便。这些可使刚刚修改的配置文件生效。 当然你也可以将这些函数绑定为快捷键。

16. 安装软件时报错: Failed to verify signature archive-contents.sig:

配置文件中增加 (setq package-check-signature nil) 然后 c-x c-e 执行,然后在去安装软件就可以了,后面恢复即可。 参考: https://emacs.stackexchange.com/questions/233/how-to-proceed-on-package-el-signature-check-failure https://emacs-china.org/t/spacemacs-gnu-key/10627/4

17. org-mode, 标题使用 * ,使用 tab 可以展开和收起段落。 C-c C-t 可以转化为 todo 条目。

18. setq 设置当前缓冲区(Buffer)中的变量值, setq-default 设置的为全局的变量的值.

但是注意有些变量时 buffer-local 的,这时候, setq 和 setq-default 是不一样的,但是有些变量不是 buffer-local 的,这时候, setq 和 setq-default 是一样的。 参考: https://stackoverflow.com/questions/18172728/the-difference-between-setq-and-setq-default-in-emacs-lisp

19. fancy-comment 在 lisp 文件中,当使用 ";" 这样一个分号的时候,会造成很远的缩进,但是使用 ";;" 这样两个分号的时候,就没有问题,所以 electric-indent-mode 和 fancy-comment 配合的时候,使用 两个分号。

参考: https://emacsredux.com/blog/2014/01/19/a-peek-at-emacs-24-dot-4-auto-indentation-by-default/ http://book.emacs-china.org/#orgheadline1

20. error: Symbol's function definition is void: global-company-mode

解决很简单,配置文件中的 (global-company-mode 1) 改为 (global-company-mode) 即可。 https://emacs-china.org/t/emacs-company-mode/408 https://stackoverflow.com/questions/26991036/symbols-function-definition-is-void-global-auto-complete-mode https://github.com/company-mode/company-mode/issues/5

21. 关闭自动备份,也就是 后缀是 ~ 的文件。

(setq make-backup-files nil)

22. 窗口分屏

c-x 1 仅仅保留当前窗口 c-x 2 当前窗口在上面 c-x 3 当前窗口在右边。 参考: https://www.gnu.org/software/emacs/manual/html_node/emacs/Split-Window.html

23. 增加 最近打开的文件 功能

(require 'recentf)
(recentf-mode 1)
(setq recentf-max-menu-item 10)

;; 这个快捷键绑定可以用之后的插件 counsel 代替
;; (global-set-key (kbd "C-x C-r") 'recentf-open-files)

开启了 recentf 模式后,可以在 menu -> file -> open recent 中找到最近打开的文件。

24. 选择一段文字,然后输入字符,原来那一段文字就都会被替换掉

(delete-selection-mode 1)

25. 增加一些查找源文件的快捷键。

(global-set-key (kbd "C-h C-f") 'find-function)
(global-set-key (kbd "C-h C-v") 'find-variable)
(global-set-key (kbd "C-h C-k") 'find-function-on-key)

26. 给 emacs 增加插件。

 (when (>= emacs-major-version 24)
     (require 'package)
     (package-initialize)
     (setq package-archives '(("gnu"   . "http://elpa.emacs-china.org/gnu/")
              ("melpa" . "http://elpa.emacs-china.org/melpa/"))))

;; 注意 elpa.emacs-china.org 是 Emacs China 中文社区在国内搭建的一个 ELPA 镜像

 ;; cl - Common Lisp Extension
 (require 'cl)

 ;; Add Packages
 (defvar my/packages '(
        ;; --- Auto-completion ---
        company
        ;; --- Better Editor ---
        hungry-delete
        swiper
        counsel
        smartparens
        ;; --- Major Mode ---
        js2-mode
        ;; --- Minor Mode ---
        nodejs-repl
        exec-path-from-shell
        ;; --- Themes ---
        monokai-theme
        ;; solarized-theme
        ) "Default packages")

 (setq package-selected-packages my/packages)

 (defun my/packages-installed-p ()
     (loop for pkg in my/packages
       when (not (package-installed-p pkg)) do (return nil)
       finally (return t)))

 (unless (my/packages-installed-p)
     (message "%s" "Refreshing package database...")
     (package-refresh-contents)
     (dolist (pkg my/packages)
       (when (not (package-installed-p pkg))
     (package-install pkg))))

 ;; Find Executable Path on OS X
 (when (memq window-system '(mac ns))
   (exec-path-from-shell-initialize))

这段配置文件中用到了 loop for ... in ,它来自 cl 即 Common Lisp 扩展。 for , in, collect 均为 cl-loop 中的 保留关键字。

;; 下面两行的效果完全相同的
(quote foo)
'foo

quote 的意思是不要执行后面的内容,返回它原本的内容

参考: https://github.com/lujun9972/emacs-document/blob/master/emacs-common/Smartparens%E7%94%A8%E6%B3%95%E8%AF%A6%E8%A7%A3.org https://emacs-china.org/t/swiper-swiper-isearch/9007/18 https://ithelp.ithome.com.tw/articles/10200255 https://www.gnu.org/software/emacs/manual/html_mono/cl.html#Loop-Facility

27. 默认全屏

(setq initial-frame-alist (quote ((fullscreen . maximized))))

自动括号匹配

(add-hook 'emacs-lisp-mode-hook 'show-paren-mode)

高亮当前行

(global-hl-line-mode 1)

安装主题

(add-to-list 'my/packages 'monokai-theme)

加载主题

(load-theme 'monokai 1)

28. 自定义插件

M-x customize-group

然后输入插件名称,当选择 Save for future session 后,刚刚做的设计就会被保存在你的 配置文件( init.el )中。

29. 替换 javascript 默认 mode

(setq auto-mode-alist
      (append
       '(("\\.js\\'" . js2-mode))
       auto-mode-alist))
(("\\`/tmp/fol/" . text-mode)
 ("\\.texinfo\\'" . texinfo-mode)
 ("\\.texi\\'" . texinfo-mode)
 ("\\.el\\'" . emacs-lisp-mode)
 ("\\.c\\'" . c-mode)
 ("\\.h\\'" . c-mode)
 …)
(setq auto-mode-alist
  (append
   ;; File name (within directory) starts with a dot.
   '(("/\\.[^/]*\\'" . fundamental-mode)
     ;; File name has no dot.
     ("/[^\\./]*\\'" . fundamental-mode)
     ;; File name ends in ‘.C’.
     ("\\.C\\'" . c++-mode))
   auto-mode-alist))

参考: https://www.gnu.org/software/emacs/manual/html_node/elisp/Auto-Major-Mode.html

30. 添加 Org-mode 文本内语法高亮

(require 'org)
(setq org-src-fontify-natively t)

在 Org-mode 中重置有序列表序号可以直接使用 M-

31. Agenda 的使用

;; 设置默认 Org Agenda 文件目录
(setq org-agenda-files '("~/org"))

;; 设置 org-agenda 打开快捷键
(global-set-key (kbd "C-c a") 'org-agenda)

将你的 *.org 文件放入上面所指定的文件夹中就可以开始使用 Agenda 模式了

C-c C-s 选择想要开始的时间
C-c C-d 选择想要结束的时间
C-c a 可以打开 Agenda 模式菜单并选择不同的可视方式( r )

在 Org-mode 中你可以在代码块中使用 C-c ' 会直接打开对应模式的缓冲区(不仅限于 Lisp)。 可以在编辑完了之后再次使用 C-c '自动退出代码块,返回主文档模式,或者使用 <s 然后 Tab 可以直接插入代码块的代码片段(Snippet)。

#+BEGIN_SRC emacs-lisp
  ;; Your code goes here
  ;; 你的代码写在这里
#+END_SRC

参考: http://blog.lujun9972.win/blog/2018/04/03/%E5%A6%82%E4%BD%95%E6%B7%BB%E5%8A%A0%E8%87%AA%E5%B7%B1%E7%9A%84org-mode-easy-template/index.html

32. 配置文件分开管理。

├── init.el
└── lisp
    ├── custom.el
    ├── init-better-defaults.el
    ├── init-helper.el
    ├── init-keybindings.el
    ├── init-packages.el
    ├── init-ui.el
    └── init-org.el

在具体的配置文件末尾增加配置接口

;; 文件末尾
(provide 'init-packages)

在 init.el 里面调用这些接口

(package-initialize)

(add-to-list 'load-path "~/.emacs.d/lisp/")

;; Package Management
;; -----------------------------------------------------------------
(require 'init-packages)

更多配置参考: https://github.com/zilongshanren/Learning-Emacs/tree/day3

33. 模式命名

在每一个模式(mode)中它的名称与各个变量还有函数都是有特定的命名规则,比如所有的 模式都被命名为 ModeName-mode ,里面所设置的快捷键则为 ModeName-mode-key-map ,而所有的钩子则会被命名为 ModeName-mode-hook 。

34. 配置文件加载

简单来说, load-file 用于打开某一个指定的文件,用于当你不想让 Emacs 来去决定加 载某个配置文件时( .el 或者 .elc 文件)。 load 搜索 load-path 中的路径并打开第一个所找到的匹配文件名的文件。此方法用于 你预先不知道文件路径的时候。 require 加载还未被加载的插件。首先它会查看变量 features 中是否存在所要加载的 符号如果不存在则使用上面提到的 load 将其载入。(有点类似于其他编程语言中的 import ),require 从指定的文件中加载特性,如果省略文件名,那么就是在特性的同名文件中加载特性。具体内容可以通过 c-h f require 来查看。 autoload 用于仅在函数调用时加载文件,使用此方法可以大大节省编辑器的启动时间。

35. 更好的默认设置

Emacs 自动加载外部修改过的文件。 (global-auto-revert-mode 1) 可以关闭自己生产的保存文件 (setq auto-save-default nil) popwin 插件可以自动将光标移动到,新创建的窗口中。使用下面的代码将其启用 (require 'popwin) (popwin-mode 1)

不喜欢听到错误时的“哔哔”的警告提示音 (setq ring-bell-function 'ignore)

确认命令时需要输入 (yes or no) 比较麻烦,设置一个别名将其简化为只输入 (y or n) (fset 'yes-or-no-p 'y-or-n-p)

36. indent-region 一次重新缩进全部缓冲区的代码

(defun indent-buffer()
  (interactive)
  (indent-region (point-min) (point-max)))

(defun indent-region-or-buffer()
  (interactive)
  (save-excursion
    (if (region-active-p)
    (progn
      (indent-region (region-beginning) (region-end))
      (message "Indent selected region."))
      (progn
    (indent-buffer)
    (message "Indent buffer.")))))

(global-set-key (kbd "C-M-\\") 'indent-region-or-buffer)

37. 缩写补全,输入特定文字后,按空格按键就会展开。

(setq-default abbrev-mode t)
(define-abbrev-table 'global-abbrev-table '(
                        ;; Shifu
                        ("8zl" "zilongshanren")
                        ;; Tudi
                        ("8lxy" "lixinyang")
                       ))

38. Hippie Expand 补全

(setq hippie-expand-try-function-list '(try-expand-debbrev
                    try-expand-debbrev-all-buffers
                    try-expand-debbrev-from-kill
                    try-complete-file-name-partially
                    try-complete-file-name
                    try-expand-all-abbrevs
                    try-expand-list
                    try-expand-line
                    try-complete-lisp-symbol-partially
                    try-complete-lisp-symbol))

(global-set-key (kbd "s-/") 'hippie-expand)

39. Dired Mode

使用 C-x d 就可以进入 Dired Mode,

+ 创建目录
g 刷新目录
C 拷贝
D 删除
R 重命名
d 标记删除
u 取消标记
x 执行所有的标记

Dired Mode 自动递归操作设置

(setq dired-recursive-deletes 'always)
(setq dired-recursive-copies 'always)

让 emacs 重用唯一的缓冲区作为 Dired Mode 显示专用缓冲区

(put 'dired-find-alternate-file 'disabled nil)

;; 主动加载 Dired Mode
;; (require 'dired)
;; (defined-key dired-mode-map (kbd "RET") 'dired-find-alternate-file)

;; 延迟加载
(with-eval-after-load 'dired
    (define-key dired-mode-map (kbd "RET") 'dired-find-alternate-file))

启用 dired-x 可以让每一次进入 Dired 模式时,使用新的快捷键 C-x C-j 就可以进 入当前文件夹的所在的路径。 (require 'dired-x)

使用 (setq dired-dwin-target 1) 则可以使当一个窗口(frame)中存在两个分屏 (window)时,将另一个分屏自动设置成拷贝地址的目标。

40. 也可以使用 org 模式来管理,init.el 中增加

(package-initialize)

(require 'org-install)
(require 'ob-tangle)
(org-babel-load-file (expand-file-name "org-file-name.org" user-emacs-directory))

然后把所有 配置文件放入 Org 模式中的代码块即可,并使用目录 结构来表述你的配置文件再把它保存在与入口文件相同的目录中即可(文件名为 org-file-name.org )。Emacs 会提取其中的配置并使其生效。这样做的好处是可以使自 己和他人更直观的,理解你的配置文件或者代码。

41. 在 Emacs Lisp 中我们 有时候只需要一个 ' 但是 Emacs 很好心的帮我们做了补全,但这并不是我们需要的。init-default.el 配置文件 增加:

(sp-local-pair 'emacs-lisp-mode "'" nil :actions nil)
(sp-local-pair 'lisp-interaction-mode "'" nil :actions nil)

;; 也可以把上面两句合起来
(sp-local-pair '(emacs-lisp-mode lisp-interaction-mode) "'" nil :actions nil)

这个方法你也可以运用在其他的各个 Major Mode 中,如果你不想 Emacs 对某些符号进行类似的自动匹配补全。

42. 光标 在括号内时就高亮包含内容的两个括号

(define-advice show-paren-function (:around (fn) fix-show-paren-function)
  "Highlight enclosing parens."
  (cond ((looking-at-p "\\s(") (funcall fn))
    (t (save-excursion
         (ignore-errors (backward-up-list))
         (funcall fn)))))

43. 隐藏 dos 换行符

(defun hidden-dos-eol ()
  "Do not show ^M in files containing mixed UNIX and DOS line endings."
  (interactive)
  (unless buffer-display-table
    (setq buffer-display-table (make-display-table)))
  (aset buffer-display-table ?\^M []))

删除 dos 换行符

(defun remove-dos-eol ()
  "Replace DOS eolns CR LF with Unix eolns CR"
  (interactive)
  (goto-char (point-min))
  (while (search-forward "\r" nil t) (replace-match "")))

dos 换行符可以参考: https://unix.stackexchange.com/questions/32001/what-is-m-and-how-do-i-get-rid-of-it

44. web-mode

首先在插件列表里面增加 web-mode:

(defvar xinyang/packages '(
               ;; 你其他的插件在这里
               web-mode
               ) "Default packages")

然后配置相应后缀名关联:

(setq auto-mode-alist
      (append
       '(("\\.js\\'" . js2-mode))
       '(("\\.html\\'" . web-mode))
       auto-mode-alist))

参考: https://github.com/fxbois/web-mode

web-mode 自动缩进

(defun my-web-mode-indent-setup ()
  (setq web-mode-markup-indent-offset 2) ; web-mode, html tag in html file
  (setq web-mode-css-indent-offset 2)    ; web-mode, css in html file
  (setq web-mode-code-indent-offset 2)   ; web-mode, js code in html file
  )
(add-hook 'web-mode-hook 'my-web-mode-indent-setup)

切换缩进是 两个空格或者 4个 空格。

(defun my-toggle-web-indent ()
  (interactive)
  ;; web development
  (if (or (eq major-mode 'js-mode) (eq major-mode 'js2-mode))
      (progn
    (setq js-indent-level (if (= js-indent-level 2) 4 2))
    (setq js2-basic-offset (if (= js2-basic-offset 2) 4 2))))

  (if (eq major-mode 'web-mode)
      (progn (setq web-mode-markup-indent-offset (if (= web-mode-markup-indent-offset 2) 4 2))
         (setq web-mode-css-indent-offset (if (= web-mode-css-indent-offset 2) 4 2))
         (setq web-mode-code-indent-offset (if (= web-mode-code-indent-offset 2) 4 2))))
  (if (eq major-mode 'css-mode)
      (setq css-indent-offset (if (= css-indent-offset 2) 4 2)))

  (setq indent-tabs-mode nil))

(global-set-key (kbd "C-c t i") 'my-toggle-web-indent)

45. 前面自定义的 show paren when curson inside 会导致 cpu 上升,后来找到一个合适的 mode highlight-parentheses-mode.

(defvar xinyang/packages '(
               ;; 你其他的插件在这里
               highlight-parentheses
               ) "Default packages")

(require 'highlight-parentheses)

(add-hook 'emacs-lisp-mode-hook 'highlight-parentheses-mode)
(add-hook 'python-mode-hook 'highlight-parentheses-mode)
(add-hook 'c-mode-hook 'highlight-parentheses-mode)

参考: https://emacs-china.org/t/emacs-python-timer-event-handler-91/15467/3 https://emacs-china.org/t/company-mode-show-paren-when-cursor-inside-advice/13015 https://github.com/tsdh/highlight-parentheses.el

46. 有时候中文会卡

(set-language-environment 'utf-8)

参考: https://emacs-china.org/t/linux/12971/21

47. emacs 性能分析需要用 profiler,先 M-x profiler-start, 然后卡顿了 M-x profiler-report,就可以看报告了。

参考: https://blog.csdn.net/csfreebird/article/details/76037649

48. 跳转到指定行,是 goto-line 功能

可以两种方法: M+x goto-line 或者 M-g g 行号 参考: https://www.cnblogs.com/lishidefengchen/p/12196442.html https://blog.csdn.net/wild46cat/article/details/50807162

49. js2-refactor 是一个用于重构 JavaScript 的插件

(add-hook 'js2-mode-hook #'js2-refactor-mode)
(js2r-add-keybindings-with-prefix "C-c C-m")

我们可以使用 C-c C-m 然后输入功能前缀,例如 em 是 extract-method 的前缀。更多的功能和使用方法见参考链接 参考: https://github.com/magnars/js2-refactor.el https://github.com/magnars/js2-refactor.el#refactorings

50. 配置 Occur Mode 使其默认搜索当前被选中的或者在光标下的字符串

(defun occur-dwim ()
  "Call `occur' with a sane default."
  (interactive)
  (push (if (region-active-p)
        (buffer-substring-no-properties
         (region-beginning)
         (region-end))
      (let ((sym (thing-at-point 'symbol)))
        (when (stringp sym)
          (regexp-quote sym))))
    regexp-history)
  (call-interactively 'occur))
(global-set-key (kbd "M-s o") 'occur-dwim)

Occur 可以用于显示变量或函数的定义,我们可以通过 popwin 的 customize-group 将定 义显示设置为右边而不是默认的底部( customize-group > popwin > Popup Window Position 设置为 right),也可以在这里对其宽度进行调节。

Occur 与普通的搜索模式不同的是,它可以使用 Occur-Edit Mode (在弹出的窗口中按 e 进入编辑模式) 对搜索到的结果进行之间的编辑。

51. imenu 可以显示当前所有缓冲区的列表,下面的配置可以让其拥有更精确的跳转,

(defun js2-imenu-make-index ()
      (interactive)
      (save-excursion
    ;; (setq imenu-generic-expression '((nil "describe\\(\"\\(.+\\)\"" 1)))
    (imenu--generic-function '(("describe" "\\s-*describe\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
                   ("it" "\\s-*it\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
                   ("test" "\\s-*test\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
                   ("before" "\\s-*before\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
                   ("after" "\\s-*after\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
                   ("Function" "function[ \t]+\\([a-zA-Z0-9_$.]+\\)[ \t]*(" 1)
                   ("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*=[ \t]*function[ \t]*(" 1)
                   ("Function" "^var[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*=[ \t]*function[ \t]*(" 1)
                   ("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*()[ \t]*{" 1)
                   ("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*:[ \t]*function[ \t]*(" 1)
                   ("Task" "[. \t]task([ \t]*['\"]\\([^'\"]+\\)" 1)))))
(add-hook 'js2-mode-hook
          (lambda ()
        (setq imenu-create-index-function 'js2-imenu-make-index)))

(global-set-key (kbd "M-s i") 'counsel-imenu)

52. expand-region 可以使我们更方便的选中一个区域。

(global-set-key (kbd "C-=") 'er/expand-region)

参考: https://github.com/magnars/expand-region.el http://emacsrocks.com/e09.html

53. iedit 是一个可以同时编辑多个区域的插件,它类似 Sublime Text 中的多光标编辑。

我们将其绑定快捷键以便更快捷的使用这个模式( C-; 为默认快捷键)

(global-set-key (kbd "M-s e") 'iedit-mode)

我们可以使用 Customized-group 来更改其高亮的背景色,将 highlight 改为 region 参考: https://github.com/victorhge/iedit

54. Org 导出

使用 C-c C-e 可以将 Org-mode 文档导出为你需要的格式,例如 HTML 或者 PDF 文件。

55. 配置来在 Company-mode 中使用 C-n 与 C-p 来选择补全项

(with-eval-after-load 'company
  (define-key company-active-map (kbd "M-n") nil)
  (define-key company-active-map (kbd "M-p") nil)
  (define-key company-active-map (kbd "C-n") #'company-select-next)
  (define-key company-active-map (kbd "C-p") #'company-select-previous))

56. org-mode caputre

(setq org-capture-templates
      '(("t" "Todo" entry (file+headline "~/.emacs.d/gtd.org" "工作安排")
     "* TODO [#B] %?\n  %i\n"
     :empty-lines 1)))

(global-set-key (kbd "C-c r") 'org-capture)

获取将当前浏览器中的 URL(下面的例子只在 Mac OS X 平台有效)

(defun YOUR_NAME/retrieve-chrome-current-tab-url()
  "Get the URL of the active tab of the first window"
  (interactive)
      (let ((result (do-applescript
             (concat
              "set frontmostApplication to path to frontmost application\n"
              "tell application \"Google Chrome\"\n"
              " set theUrl to get URL of active tab of first window\n"
              " set theResult to (get theUrl) \n"
              "end tell\n"
              "activate application (frontmostApplication as text)\n"
              "set links to {}\n"
              "copy theResult to the end of links\n"
              "return links as string\n"))))
    (format "%s" (s-chop-suffix "\"" (s-chop-prefix "\"" result)))))

参考: https://orgmode.org/manual/Capture.html

57. Org-pomodoro 是一个番茄时间工作法的插件, 在init-package.el 中添加 org-pomodoro 和 (require 'org-pomodoro) 后可以通过 Customize-group 来对其进行设置,包括不同休息种类的时长。

GitHub 地址 https://github.com/lolownia/org-pomodoro

58. 保存中文的时候都需要选择解码,我们可以使用下面的配置将文本解码设置默认为 UTF-8,

(set-language-environment "UTF-8")

59. 当 org-mode 不能生效时,我们需要将与 Org 相关的配置放置于 with-eval-after-load 中,

(with-eval-after-load 'org
  ;; Org 模式相关设定
  )

60. 批量修改文件名

C-x C-q 就可以直接在 Dired Mode 中进行编辑,使用之前学的 iedit-mode 和区域选择 就可以直接对多个文件进行重命名编辑了。

61. 搜索与替换,快速程度: ag > pt > ack > grep,ag 需要先安装。

apt-get install silversearcher-ag

安装好 ag 之后,就可以安装 helm-ag 插件, 在 init-packages.el 中增加 helm-ag. 然后再 按键配置中增加

(global-set-key (kbd "C-c p s") 'helm-do-ag-project-root)

参考: http://book.emacs-china.org/#orgheadline31 https://github.com/emacsorphanage/helm-ag

62. 动态语法检查器 flycheck,需要先安装 eslint, 先按照 https://github.com/eslint/eslint 安装好 eslint,然后再根据 https://github.com/flycheck/flycheck 在 init-package.el 中增加 flycheck 来安装 flycheck,再增加 hook

(add-hook 'js2-mode-hook 'flycheck-mode)

使用 flycheck-verify-setup 可以进行语法检查器的选择, eslint 检查器的配置也可以使用项目目录下的 .eslintrc 来进行配置. 更多 eslint 配置参考 https://eslint.org/docs/user-guide/configuring

63. 代码块插件

yasnippet, 在 init-package.el 中增加 yasnippet, 然后配置其在所有 的编程语言的模式中激活。

(yas-reload-all)
(add-hook 'prog-mode-hook #'yas-minor-mode)

auto-yasnippet 也是一个非常好用代码块补全插件,在 init-package.el 中增加 auto-yasnippet。然后配置快捷键

(global-set-key (kbd "H-w") #'aya-create)
(global-set-key (kbd "H-y") #'aya-expand)

简单的使用方法就是使用 ~ 来定义模板,然后调用 aya-create 再使用 aya-expand 来使用模板。

参考: https://github.com/joaotavora/yasnippet https://github.com/abo-abo/auto-yasnippet

64. evil-mode 安装 和 简单使用

在 init-package.el 中增加 evil, 并设置

(require 'evil)
(evil-mode 1)

emacs 打开时,默认时 normal 模式,下方标注 ,按 C-z 可以切换到 emacs 模式,下方标注 , 这时候所有 vi 里面的快捷键全部失效。再次按 C-z 可以返回 vi 模式。

下面这个操作暂时感觉没有什么用,后面需要再使用。

(setcdr evil-insert-state-map nil)
(define-key evil-insert-state-map [escape] 'evil-normal-state)

参考: https://evil.readthedocs.io/en/latest/overview.html#installation-via-package-el

65. c 缩写 4个空格,使用 tab

;; cc mode style, table instead of spaces
(setq c-default-style "linux"
      c-basic-offset 4
      tab-width 4
      indent-tabs-mode t)

参考: https://www.emacswiki.org/emacs/IndentingC

66. company backend 'company-clang' could not be initialized: company found no clang executable. 这个错误是因为没有安装 clang,按照好了之后,就可以了。

67. 打开 lisp interaction,可以直接在菜单栏 -> buffer -> scratch, 在这个里面输入 elisp 相应的代码,然后 c-x c-e 就可以看到执行结果了。

如果注释之后换行,注释被自动向后移动了,那么使用 c-h m 来查看当前打开的 minor mode,发现里面的 Electric-Indent 处于打开状态。使用 m-x electric-indent-mode 就可以关闭这个模式了。 使用 c-x c-e 的时候,光标一定要在语句的末尾,否则就可以执行部分语句,而不是完整的这一行语句。

68. 想要快速学习一门新的语言,可以直接看 https://learnxinyminutes.com/ 在里面寻找对应的语言。

69. emacs 换成国内的源。

(setq package-archives '(
    ("melpa" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/melpa/") 
    ("gnu" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/gnu/")
    ("org" . "http://mirrors.tuna.tsinghua.edu.cn/elpa/org/")))

参考: https://zhuanlan.zhihu.com/p/341512250

70. 一个一个需要确认的替换,使用 m-%

参考: https://www.cnblogs.com/robertzml/archive/2010/03/03/1675870.html

71. 查看开启的模式,使用 c-h m,然后使用 m-x配合相应的 minor-mode 来开启或者关闭模式。

72. 定义函数的时候,增加 (interactive) 这个交互式的属性,就可以使用 m-x 来调用这个函数。注意使用 c-x c-e 的时候,每条完整的语句都要执行。

(setq my-name "xyz")
(message my-name)

(defun my-func()
(interactive)
(message "hello %s" my-name))

(my-func)
(global-set-key (kbd "<f1>") 'my-func)

73. 获取帮助的时候,可以先光标移动到需要查询的地方,如果是函数,那么就 c-h f,变量就用 c-h v 这样就省得自己输入了。

74. scratch buffer 里面可以测试各种配置,确定没有问题后,再写入配置文件。

;; 关闭工具栏
(tool-bar-mode -1)
;; 关闭滚动条
(scroll-bar-mode -1)
;; 关闭自动换行缩进
(electric-indent-mode -1)
;; 行号
(global-linum-mode t)
;; 关闭启动画面
(setq inhibit-splash-screen t)
;; 打开配置文件
(defun open-my-init-file()
  (interactive)
  (find-file "~/.emacs.d/init.el"))
;; 配置按键
(global-set-key (kbd "<f2>") 'open-my-init-file)
;; 开启全局补全
(global-company-mode t)
;; 光标改为 I
(setq cursor-type 'bar)

注意:配置中 t1 的意思一致,都代表开启的意思。 注意: company-mode,需要先 options -> manage emacs packages 中点击 company 在新页面中点击 install 安装完成之后,才能配置。也可以手动用 m-x company-mode 来开启或关闭补全模式。

75. org gtd 使用

在标题中按 c-c c-t 可以在 todo,done, 取消三者之间循环。 按 c-c c-d 可以增加 deadline 时间。

76. org 模式中#+BEGIN_SRC 的快捷键是输入 <s 然后按下 tab 按键,就可以自动补全了, 这种 src 的区域也是可以使用 tab 按键进行折叠和展开的。

77. emacs 额外安装的 package 可以去 https://melpa.org/#/ 这个网站上面去找,想找什么东西,直接在搜索栏里面输入就可以了,然后点击 source 里面对应的 github 就可以跳转到对应的 github 页面了。点击 dls 就可以按照下载量重新排序了。下载量高的可能只是被其他的包依赖的,并不一定是非常用户友好的。

78. 在 packages 里面增加了 monokai-theme 后, m-x eval-buffer 就会自动下载 monokai-theme 了,下载好了之后,可以 m-x load-theme monokai-theme 立即加载主题。

79. m-x package-list-packages 可以显示所有可安装的包。类似于菜单里面的 package 功能。在包选项上按 i 按键,就可以安装这个包,按 u 按键就取消安装。按 c-s 可以搜索包,按 d 可以标记需要删除的包,然后按 x 会有提示是否确定删除。 按 U 可以更新所有的包,旧的包会被标记为 d,新的包会被标记为 i, 然后按 x 执行,按y 确认。

(add-to-list 'package-archives
             '("melpa-stable" . "https://stable.melpa.org/packages/") t)

上面这个是用来替代 melpa 这样安装的就都是稳定版的,而不是最新版的。 m-x autoremove 可以自动移除不需要的包。 '(package-selected-packages (quote (company monokai-theme)))) 这一行是用来和 autoremove 进行配合的,所有不在这一行的,都会被 autoremove 认为是应该删除的包。这一行也可以用 (setq package-selected-packages my/packages) 这一句来替代。

80. smex

待阅读数目:

(Learn X in Y Minutes) https://learnxinyminutes.com/docs/elisp/ https://learnxinyminutes.com/docs/zh-cn/elisp-cn/ Emacs Lisp https://www.gnu.org/software/emacs/manual/html_mono/eintr.html Elisp: load, load-file, autoload http://ergoemacs.org/emacs/elisp_library_system.html MELPA https://melpa.org/#/getting-started Common Lisp: loop https://www.gnu.org/software/emacs/manual/html_mono/cl.html#Loop-Facility quote https://www.gnu.org/software/emacs/manual/html_node/elisp/Quoting.html https://stackoverflow.com/questions/134887/when-to-use-or-quote-in-lisp hooks https://www.gnu.org/software/emacs/manual/html_node/emacs/Hooks.html 选择 默认的 major mode https://www.gnu.org/software/emacs/manual/html_node/elisp/Auto-Major-Mode.html elisp AssociationList https://www.emacswiki.org/emacs/AssociationList org-mode https://orgmode.org/manual/ feature, provide http://ergoemacs.org/emacs/elisp_feature_name.html cc mode 配置 https://www.cnblogs.com/lance-ehf/p/4449410.html what-makes-lisp-macros-so-special https://stackoverflow.com/questions/267862/what-makes-lisp-macros-so-special web-mode https://web-mode.org/ emacs rocks 视频 http://emacsrocks.com/e09.html org-mode capture https://orgmode.org/manual/Capture.html Org-pomodoro https://en.wikipedia.org/wiki/Pomodoro_Technique

标签: Emacs

添加新评论