Emacs之衣带渐宽终不悔

Table of Contents

使用 Emacs 第一阶段, 这个过程短则数月长则数载, 全看个人对于: "你始终是个白痴" 这句话的耐受力.

1. 你感觉自己是个白痴          <---+
2. 你感觉自己不是个白痴            |
3. 你感觉已经和 Emacs 相伴相知 ----+

耐受力越强这个过程越短, 以下是我自己总结的关于 Emacs(尤其是Spacemacs) 的常用 mode(mode 之于 emacs <=> app 之于 OS)用法及其快捷键, 大部分都使用英文记录, 因为当你在 Emacs 中遇到问题时你大概只能找到英文文档, 算是小学二年级教程(本人大概也在这个级别, 但无法确定, 也许某一天突然发现…), 记住 你始终是个白痴, 但你不寂寞, 因为至少我也是. mail to me if exhausted :)

function definition under certain mode.

hooks

hook is a collection of funcions will execute after certain mode start.

(add-hook 'org-mode-hook '())

WARNING : I enter the edit table of org mode by press C-c `, but failed to enter the major-mode related to the type of source code.

hotkeys

dired

<spe:dired>open dired-mode in current file SPC f j file-jump
<spe:dired>open spacemacs configuration file SPC f e d open init.el
<spe:dired>enter zshell in dired-mode(need zsh installed) `  
<spe:dired> dired-mode hide tetail )  
<spe:dired>dired-mode omit-mode (  
<spe:dired> preview a file with cursor locate in o  
<spe:dired> preview a file, cursor stay C-o  
<spe:dired> edit mode, modify file name directly in dired C-x C-q  

global

<spe>discover major-mode key bindings Spc ?  
<spe>save and apply new configuration SPC f e r file-refresh
<spe>search in document SPC s j search jump
<spe>open/closed debug info buffer spc t D  
<spe>list all the layers installed SPC h SPC pkgs of this layer
<spe>reload a mode by diminish-undo (M-x:)dimish-undo  
<spe>kill-ring paste C-n/p copy next/previous
<spe>switch input-method C-\  
<spe>toggle rainbow-mode spc t C c display color instead of color unicode
     

helm

<helm> helm-find-files spc-f-f  
<helm> helm-ag search all func-name variable in proj spc-s-p  

evil & vim

<evil>move backward/forward a word " " e/b  
<evil>move backward/forward a word with dash " " E/B  
<evil>move line up/down (vim-c):m +/- num  
<evil>paste after/before selected char (vim-n) p/P  
<evil>narrow a function (vim-n)z-a  
<evil>narrow all functions (vim-n)z-m  
<evil>modify a char (vim-n)r  
<evil>mark the current line as <num>th mark (vim-n)m <num>  
<evil>goto <num>th mark (vim-n)` <num>  
<evil>evil-find-char: find next occurance of typed char (vim-n) f  
<evil>goto the location last modified (vim-n)g;  
<evil:format> let rest chars of a line to next line C j  
<evil:format>let rest chars of next line to current line shift j  
<evil:format>scroll window to make current line middle of window z z  
<evil:elisp> find the doc of current function K  
<vim>delete all the blank line :g/^$/d  
<vim>delete all the line with only blank space in it :g/^\s*$/d  
<vim>wrap a selected(by v) word by a character <selected> s <char>  

org

<spe:org>capture org tempalte spc C c  
<spe:org>some org-mode handler ,  
<spe:org>org-mode clock in , I  
<spe:org>org-mode clock out , O  
<spe:org>org-mode switch index 1) + - 1. -  
<spe:org>org-mode add TODO tag t  
<spe:org> quick insert todo items F9  
<spe:org>indent ONE line text to proper number of lines M-q  
<spe:org>narrow a branch of org file , n  
<spe:org>widden a branch of org file , N  
<spe:org>move org branch up/down M-j/k  
<em:org>toggle org todo dependency C-c C-x o  
<em:org> jump to clocked task (can jump out from current file) C-C C-x C-j  
<em:org>org column view C-c C-x C-c  
<em:org>org attachment C-c C-a  
<em:org>org clock reporting(position on headline) C-c C-x C-r  
<em:org>Org make id (M-x:)org-id-get-create  
<em:org>Org attanch file C-c C-a  
<em:org>org change state of a task C-c C-t  
<em:org>org take note in LOGBOOK C-c C-z  
<em:org>toggle a org entry and set archive tag C-c C-x a  
<em:org>archive this branch file to achive org file C-c C-x C-a  
<spe:org> add a footnote ref , i f  
<org> display latex formula directly in org file C-c C-x C-l  
<org> screenshot by org-download C-c g  

avy

<spe:avy:format>avy-goto-char, a very handy way to locate cursor spc j j  
<spe:avy:format>avy-goto-line, spc j l  

misc

<spe:misc> YouDao dict Spc o y  

file

spc f f find file from current directory(C-h to gu up-level of directory)
spc p f 在当前项目中查找文件 三种主要 pkg counsel-git / projectile/ ido-find-file
spc f L counsel-locate :find file across the whole ubuntu system
spc f l find file literally (对编码格式不是本系统的有用)
spc f h find file in hex mode
spc f o 使用外部文件打开,必须先用 spacemacs 打开之后方可使用
spc f E sudo edit
spc f D delete current file and buffer
spc f j file jump the current file
spc f r recent files
spc f R rename file
spc f v add local variable
spc f y yank current buffer's full path
spc f a d find the current visited directory with fasd(from chenbin)
spc f C d/u conver file between unix and dos
spc f e d find the .spacemacs/init.el
spc f e i find .emacs.d/init.el
spc f e l helm locate library file(all .el file)
spc f c copy file
spc f b show bookmarsk
spc f s save/create buffers

buffer

  1. spc b . buffer micro state, allways active until enter(supported by hydra)
  2. spc b b switch buffers
  3. spc b d kill buffer
  4. spc b f find buffer file in finder(only for MAC)
  5. spc b B/i I bind it to ibuffer
  6. spc b k kill matching buffers
  7. spc b N new empty buffer
  8. spc b m kill others
  9. spc b h go to home
  10. spc b R safe revert buffer
  11. spc b s switch to scratch buffer
  12. spc b w toggle buffer readonly
  13. spc b Y copy the whole buffer to clipboard
  14. spc b p paste to the whole buffer
  15. spc <tab> switch between the current buffer and the last opened buffer

layout

WORKFLOW:

  1. use spc l L to choose a layout file from directory, in which store a num of layout, then you will load all the layout(include all the buffer) in emacs.
  2. use spc l l to choose a layout by name from the layous in the layout file
  3. use spc l n/p to switch the layout between all the layout in the layout file
  4. use spc l r to remove a buffer from a layout
  5. use spc l d to delete current layout from layout file
  6. use spc l D to delete a layout by name from the layout file
  7. use spc l R to rename a layout
  8. use spc l s to save all the modification of all the layouts of current layout file

ATTENTION: your layout file will be saved in .emacs.d/.cache/layouts/ Most important facility is: you can save and switch freely between your different layouts.

  1. spc l L load layout file
  2. spc l l to switch between layouts
  3. spc l s to save layout to file
  4. spc l <tab> switch between the last layout and the current one
  5. spc l o custom layout
  6. spc l R rename layout
  7. spc l ? to open the help window, learn more operations about layout

window

  1. spc w - split window below
  2. spc w / split window right
  3. spc w . window micro state
  4. =spc w 2/3 = use predefined window layout
  5. spc w = balance window
  6. spc w b switch to minibuffer
  7. spc w d delete current buffer
  8. spc w m maximize window
  9. spc w u/U window undo/redo
  10. spc w h/j/k/l move to window
  11. spc w H/J/K/L move window to position left/down/up/right
  12. spc w F make a new frame
  13. spc w o switch to other frame
  14. spc w 1/2/3/4 goto window with num
  15. spc w w goto other window one by one
  16. spc w W ace window
  17. spc t g toggle golden ratio
  18. spc t - make current always the center of this window

project

  1. spc p f visit files in project
  2. spc p b visit buffers in project
  3. spc p p switch to project
  4. spc p l switch to project and create a new layout
  5. find-file-in-project is a really handy package

elisp-function

compress current function z-c
open function z-o
ONLY open current, compress others z-s
   

book mark

set bookmark Spc-b-m-s
display all bookmarks Spc-b-m-j

calc

'ln' – natural logarithm of num on top of stack shift-l
'exp' – exponential of num on the stack shift-e
'log10' – base-10 logarithm of num on top of stack shift-h shift-l
'log' – base-<num> logarithm of num on top of stack <num> shift-B
   

package

TODO org-download

URL: https://github.com/abo-abo/org-download setting file: org-download 在配置文件中的位置 drag picture directly to your org file

lispy

Introduction to lispy

  1. lispy: vi-like paredit
  2. it even has some IDE features
    1. jump-to-def
    2. debug
  3. how to install

Basic usage of lispy

  1. barf and slurp move bracket () very smartly,
    1. by d switch between '(' and ')'
    2. by [ ] you can move '(' ')'
  2. raise sexp
    1. r make left-bracket of sexp you want to raise heightlight selected,press 'r',then amazing happen.
    2. u lisp undo
  3. kill/copy/yank
    1. C-k redefined in lispy-mode ,only will kill the pair-bracket content after cursor
    2. m to select and highlight the content in pair-bracket
    3. C-w to kill the selected content and the matched pair-backet, use C-y to yank
    4. c locate the right bracket, and press c, it will copy pair-bracket and content in it to a new line
  4. ace, like vi-extension in chrome
    1. a use d to locate the right bracket, and press a, and press the char he mark,you can go there directly.
    2. if only one pair of bracket, a means select
    3. i press to select content or content with brackets where amazing happens.
  5. swipe
    1. w s can switch the position between same level sexp. like (let ((sexp1)(sexp2)) when cursor
  6. navigate: h/j/k/l/ f/b :move cursor between brakets
    1. f/b will go further and backward to the same half of bracket,like a flow of right-half or left-half: 1st ( -f-> ( -f-> (
    2. j/k will go up and down between the same level brackets
    3. h/l will go left and right of brakctes, the largest range is – function range
  7. doc: display the documment of this function
    1. C-1 display doc
    2. C-2 display base structure
  8. split
    1. M-j locate cursor head of sexp, can split inner-sexp from outter-sexp
    2. s-j can delete the brackets of inner-sexp
  9. wrap
    1. s-( locate cursor head of a word, can wrap the whole word by brackts,both sides
  10. format
    1. M format func to muli-line
    2. O format func to one-line
  11. sexp goto
    1. t triger a map, which mark many places, you can cut the sexp nearest the cursor to anywhere
  12. jump to def
    1. F jump to the definition
    2. C-o jump back
  13. [ ] jump to tag need study
    1. G jump to the tags file
  14. debug
    1. F locate cursor to one bracket of the sexp(which will call a func), press F to jump to its definition.
    2. xe locate cursor to the one of bracket of the function, and press xe
    3. C-o esc to normal-state, and press C-o to jump back to the sexp(which will call a func).
    4. e press e, enter debug window.
    5. n press n to go next

restclient

This is a tool to manually explore and test HTTP REST webservices. Runs queries from a plain-text query sheet, displays results as a pretty-printed XML, JSON and even images.

video introduction

ctags and etags

why use ctags auto completion?

how to make ctags available for some source file?

$ ctags -e a.js ctags for a file of emacs $ ctags -eR filename ctags for a directory of emacs etags has no -R argument for recursive search directory. so we can handle it ,with 3 methods: use regex file as etags' argument use find command to pipline to etags

  1. add --regex"<regex>"= directly after etags command
  2. add regex to a file, and add this file as argument of etags command
  3. use find to find the targets and pipline to find XXX -print | etags
how to know where is the tags list file the current buffer used?
  1. by spc h d v , find the variable description of tags-table-list, it will show you the path of the tags file.
  2. spc o ( you can enter a ELisp ELPA
  3. by elisp ELPA (steq-default tags-table-list "some-path"), you can set your own ctags file temporary.
what's the defect of tags in emacs?
how set the tags file for current buffer?

tags-table-list don't make a tags file respectively for different language. so you must set it by your own. M-x visit-tags-table can let you do it. but there is some annoying error when build TAGS in terminal About error when input: ctags -e

etags is short for "Emacs tags", not "exuberant ctags". It sounds like you have Emacs' etags command installed, not exuberant-ctags'.

its better to try etags file to build TAGS file instead of ctags -e

when open a source code file ,emacs will find TAGS file automatically from current file-path to root.

how to configure ctags and auto completion?

  1. project wide configurations for auto generating the Tags file.
  2. Configure the ctags rules for generate more tags
  3. use etags-select to quickly navigate a large code base

    it's inconvinent for everytime you update/modify your code, you must build Tags file again. here is a tricks from CHEN BIN.

  4. ~/.spacemacs.d/layers/zilongshanren-programming/funcs.el in which defined a lot of functions to automatically rebuild TAGS files

how to jump-to-definition place in zilong'configurations?

g ] -> etags-select-find-tag-at-point

how to enable etags or ctags of other major-mode?

the source code of company : company-etags.el defined a variable : company-etags-mode , it is a list of major-modes ,in which will funcional the etags for complemention. you can add some major-mode to it

comany-mode

how company-mode works?

  1. backend for the completion sources and front end to display the condidates

    Its value is (company-bbdb company-nxml company-css company-eclim company-semantic company-clang company-xcode company-cmake company-capf company-files
       (company-dabbrev-code company-gtags company-etags company-keywords)
       company-oddmuse company-dabbrev)
    
    • 从前到后,依次查看所有 backend 是否适合当前输入的文字
    • 可以从 buffer 状态栏查看当前使用的 backend (会根据文本自动切换 backend)
    • 也可以手动通过 M-x <input backend-name> 来手动激活该 backend 的自动补全
  2. C-h v company-bakends
  3. try company-file and company-ispell, M-x
  4. C-h C-f to view the backend implementation
company-frontends 是指前端補全框架
company-backends 有很多.其中最后一个,就是前面都匹配不到了,最后一个是 compnay-Deabbre ,他会匹配你当前打开的所有 buffer 中的词项.
  company-File 这是另一个 backend, 是负责输入文件目录.'/' 触发.

why my company sucks

为什么我的 company 会失效?
  1. 失效如何定位?

首先看补全 package 是否需要 server 端,还是只有本地 backends. 我的 ubuntu 就是因为没有安装 python-pip,所以一直显示 "can't install anaconda-server" 安装之后,又提示 jedi 有什么问题.

  1. 然后确定自己是否使用了正确的 backends
如何指定某个 backend

我们可以自己写个函数来给某些 mode 添加 backend 比如默认 python 中可能是没有 company-anaconda backend 的我们可以这样

(add-hook 'python-mode-hook
  (lambda()
    (set (make-local-variable 'company-bakcends)  '(company-anaconda))))
两种补全方式
  1. [本地]就是在本地存有很多 backends.然后根据本地 backends 补全.
  2. [远程]就是 company-(anaconda/jedi/ycmd/tern) 的补全方式,需要安装服务器端.

cask

[cask] 目前学习了两种安装方式,一个是 cask 一个是非 cask 的. 非 cask 是首先检查 initpackage 列表中的 pkg 是否都安装了?如果没有会安装他们,之后才开始进行一些列的 init.el 配置. cask 的方式,是要通过设定你的 export path 来设置 emacs 默认启动版本和 cask 的安装路径,来通过 cask install 来安装. 这之后才会执行一些 init.el 配置. 这里都是先装包,再配置. 这样做的目的只有一个: 再一个新的环境中,下载我们的配置,直接使用. 或称: 配置,正确迁移. [progn] 是将多条语句捆绑成一条. 经常用在只允许一条语句的地方. [pp] 是 pretty print . [macroexpand] 用来展开一个宏,注意在后面加 quote— '

如何通过 cask 回退 older-version pkg?

  1. melpa 是通过 pkg 源码的 github,抓取最新 release.github 上每个 release 都有自己的 commit 号和 MD5 码.
  2. 可以通过 ~/.emacs.d/cask 文件来管理 下载源 每个包的下载 commit 号

格式: (depends-on "pkg-name" :git "pkgpage-in-github" :reg "commit-code")

  • pkgpage 是 melpa 中每个 pkg 的 github 页;
  • commit-code 可以在该 github 页上通过 release 找到稳定版, 通过 commit 找到提交版. eg: (depends-on "monokai-theme" :git "https://github.com/oneKelvinSmith/monokai-emacs" :ref "61c0ff7")
    1. (不要通过 emacs package 删除) 通过 terminal 删除要回退的包
    2. 通过 terminal cask install 安装 cask 文件中指定的版本

这样是可以安装回任意版本的 pkg.但是重启 emacs 之后, 不要 去 package-list 中更新.因为还是会更新最新的.

usa-package

use-package 是更安全的 require

上面是 use-package 通过 macroexpand 展开的内容. 注意提示符 message Cannot load %s.这个经常在 emacs 编译 init.el 时出现.

use-package a-pkg 分成多个部分

  • :init 是表示在 require a-pkg 之前定义
  • :config 是表示在 require a-pkg 之后定义 [tips] 我们尽量少的使用 require 整个 pkg,而是应当通过 autoload 来事先加载一部分功能,从而使用需要的命令
  • :commands 是 usepackage 声明 autoload 的方法.
  • :bind 用来绑定快捷键,甚至可以制定 mode-map
  • :ensure 保证在 use-packge 执行之前,从源中下载最新版
  • :pin 如果想下载另一个源,可以在这里指定

anaconda-mode

通過 pip install anaconda-mode 會直接安裝三個依賴包

  • anaconda 是一个用于数据分析的 py 包的库,维护了几百个可用的 py 包.
  • anaconda-mode 是专门为 emacs 的 python-mode 编写的自动补全 pkg,专门用来从一个本地服务器匹配补全.
    • anaconda-mode:其工作需要本地端有 factory-service 的支持,用于获取自动补全的内容(可以通过 pip 安装)
    • Jedi:是一个自动补全和静态分析 python 库的工具,anaconda-mode 依赖了这个包(可以通过 pip 安装)
  • company-mode 提供了更好的 ui 和更多的补全设置,eg 很多类型的 backends. 可以配合 anaconda-mode 提供的 backends 使用

安装过程出现的问题

  1. Server error: ValueError('need more than 0 values to unpack',) 有人提出这个问题,但是 anaconda-mode 作者说,这是 jedi 的 bug jedi 的 bug?

multiple-cursor-mode and cua-mode ?

it is so annoying to make this list of checkboxes, I refer cua-mode , multiple-cursor-mode , but both are not execute very well in evil edit-mode ,so i frequently swich emacs-mode and evil-mode by C-z .

  1. I copy all the text from onenote from the chrome;
  2. I get how to toggle the check-box between SOLVED and UNSOLVED, by C-z ;
  3. I add '[]' to the head of all lines by cua-mode in evil-mode, FAILED!
  4. I googled a mode which pre-installed in zilong'configurations— multiple-cursor-mode ;
  5. it also sucks in evil-mode.
  6. I find the configuration and hotkey re-defined by zilong ,in /.spacemacs.d/layers/zilongshanren-misc/packages.el
    1. switch to emacs-mode
    2. C-spc to select several chars , then C-s-f to mark all the identical highlight
    3. C-spc again to cancel the highlight state, then you get MULTIPLE CURSOR
    4. now, its your fasion time!

configuration

如何安装不在 melpa 的包(自己写的包)

  1. 查看该包 github 网站,获得其.el 文件中的 provide 值–>也就是具体包名
  2. 自己 layer 的 packages 函数中包含该名,并加参数

    (<pkgName> :location (recipe :fetch github :repo "<URLofpkgInGithub>"))
    
  3. 配置该包的 init 函数

layers.el—如何大量配置包参数

通过自定义的 layer->packages.el->post-init-pkgname()去进行简单的 pkg 参数调教是没问题的,但是如果我对大部分参数都不满意,参数又多达几百个,这种方法不适用.

  1. 自己 layer 下,定义 layer.el,用于移除掉一些 layer.
  2. 比如 Chinese layer 下有个 youdao 字典的包,我不想要.

    (configuration-layer/remove-layer 'youdao-dictionary)
    

set all customize settings in one file

最好通过下面的语句,这样会在 init.el 同层目录生成一个 custom.el 文件,用来存放这些个性化配置 (setq custom-file (expand-file-name "custom.el" dotspacemacs-directory)) (load custom-file 'no-error 'no-message)

where other settings locate

spc f e d 下面 dotspacemacs/user-congfig() 函数里

install package not included in spacemacs

spc f e d 下面 dotspacemacs-additional-packages '() 列表中

find README of any layer in spacemacs

(通过 SPC h SPC 进入) 每一个 layer 的配置文件的同层目录中(spc f j) 都存放了一个 readme 文件,详细介绍了这个 layer 中所有包的说明及安装方式/hotkeys

每一个 layer 都有很多变量, 这些变量都在 readme 里面有介绍. 每一个 layer 的文件夹内,都存有 config.el, 其中的配置可以在(layer 层配置的 variables 配置), 当加载这个 layer 的时候,会配置 config.el

直接在 init.el 文件的 configuration-layer 中的 layer 对应位置:

(better-defaults :variable better-defaults-move-to-end-of-code-first t)

exclude some unwanted packages

  • 我想查看 SPC fed congfig 下某个 layer 都安装了哪些 package.怎么做? 在 dotspacemacs-configuration-layers 下面的某个 layer 名字上 SPC-h-SPC 查询到 package 后, SPC-fed ,配置文件里有个 "dotspacemacs-exclude-packages '()" 名字放到括号里即可然后选择一个进去,可以看到整个 layer 的配置.
  • 如果 spacemacs 启动的时候某个 pkg 报错,实在找不到原因,也可以通过上面的方法删除之.

debug

hotkeys for debug

emacs is frozen

use a comman in terminal to display the call stack in emacs

pkill -SIGUSR2 -i emacs
=M-x: toggle-debug-on-quit=

emacs is slow

use the following two commands to profile the CPU

profiler-start
profiler-report

emacs start-up time is long

use the following command

$PAHT_TO_EMACS/emacs --timed-requires --profile

spc b b to find a buffer called "load time", can you find the threshold package

hack tip

I want a feature from other editors, how could i implement it in emacs?

emacs is a collection of packages, every package is a collection of tools. she also gives you the way to re-organize them to fit you well.

  • FIRST RULE, you must know what are the tools in your bag read all the doc of packages, get the knowledge of all the core functions. these functions are the tools,gears to composite your weapon.
  • SECOND RULE, you must know how to combine them in emacs emacs is like a traslator to transport information between different packages. you need to know the node and tube, the methods how to use them.

Author: yiddishkop (yiddishkop@163.com)

Date:

Emacs 26.1 (Org mode 9.1.13)

Validate