Emacs Intro

Table of Contents

intro

你大概听说过:

  • 世界上只有两种人,懂10进制的和不同10进制的; 同样世界上只有两种程序员, 用vi的,用emacs的.
  • vi是神一样的编辑器, emacs是给神用的编辑器.
  • emacs是什么? 它是一个操作系统.

熟练使用emacs是相当繁琐和费脑子的, 数不尽的快捷键, 无穷的配置…总之就是折腾, 如果不能体验折腾乐趣的人, 也许不应该在这个上面浪费生命.

全局变量按键声明

  • C = Control
  • M = Meta = Alt | Esc
  • Del = Backspace
  • Ret = return
  • S = Shift

基本快捷键(Basic)

  • C-x C-f "find"文件, 即在缓冲区打开/新建一个文件
  • C-x C-s 保存文件
  • C-x C-w 使用其他文件名另存为文件
  • C-x C-v 关闭当前缓冲区文件并打开新文件
  • C-x i 在当前光标处插入文件
  • C-x b 新建/切换缓冲区
  • C-x C-b 显示缓冲区列表
  • C-x k 关闭当前缓冲区
  • C-z 挂起emacs
  • C-x C-c 关闭emacs

移动基本快捷键(Basic Movement)

  • C-f 后一个字符
  • C-b 前一个字符
  • C-p 上一行
  • C-n 下一行
  • M-f 后一个单词
  • M-b 前一个单词
  • C-a 行首
  • C-e 行尾
  • C-v 向下翻一页
  • M-v 向上翻一页
  • M-< 到文件开头
  • M-> 到文件末尾

编辑(Edit)

  • M-n 重复执行后一个命令n次
  • C-u 重复执行后一个命令4次
  • C-u n 重复执行后一个命令n次
  • C-d 删除(delete)后一个字符
  • M-d 删除后一个单词
  • Del 删除前一个字符
  • M-Del 删除前一个单词
  • C-k 移除(kill)一行

C-Space 设置开始标记 (例如标记区域)

  • C-@ 功能同上, 用于C-Space被操作系统拦截的情况
  • C-w 移除(kill)标记区域的内容
  • M-w 复制标记区域的内容
  • C-y 召回(yank)复制/移除的区域/行
  • M-y 召回更早的内容 (在kill缓冲区内循环)
  • C-x C-x 交换光标和标记
  • C-t 交换两个字符的位置
  • M-t 交换两个单词的位置
  • C-x C-t 交换两行的位置
  • M-u 使从光标位置到单词结尾处的字母变成大写
  • M-l 与M-u相反
  • M-c 使从光标位置开始的单词的首字母变为大写

重要快捷键(Important)

  • C-g 停止当前运行/输入的命令
  • C-x u 撤销前一个命令
  • M-x revert-buffer RETURN (照着这个输入)撤销上次存盘后所有改动
  • M-x recover-file RETURN 从自动存盘文件恢复
  • M-x recover-session RETURN 如果你编辑了几个文件, 用这个恢复

在线帮助(Online-Help)

  • C-h c 显示快捷键绑定的命令
  • C-h k 显示快捷键绑定的命令和它的作用
  • C-h l 显示最后100个键入的内容
  • C-h w 显示命令被绑定到哪些快捷键上
  • C-h f 显示函数的功能
  • C-h v 显示变量的含义和值
  • C-h b 显示当前缓冲区所有可用的快捷键
  • C-h t 打开emacs教程
  • C-h i 打开info阅读器
  • C-h C-f 显示emacs FAQ
  • C-h p 显示本机Elisp包的信息

搜索/替换(Seach/Replace)

  • C-s 向后搜索
  • C-r 向前搜索
  • C-g 回到搜索开始前的位置(如果你仍然在搜索模式中)
  • M-% 询问并替换(query replace)
  • Space或y 替换当前匹配
  • Del或n 不要替换当前匹配
  • . 仅仅替换当前匹配并退出(替换)
  • , 替换并暂停(按Space或y继续)
  • ! 替换以下所有匹配
  • ^ 回到上一个匹配位置
  • RETURN或q 退出替换

使用正则表达式(Regular expression)搜索/替换

  • 可在正则表达式中使用的符号:
  • ^ 行首
  • $ 行尾
  • . 单个字符
  • .* 任意多个(包括没有)字符
  • \< 单词开头
  • \> 单词结尾
  • [] 括号中的任意一个字符(例如[a-z]表示所有的小写字母)
  • M C-s RETURN 使用正则表达式向后搜索
  • M C-r RETURN 使用正则表达式向前搜索
  • C-s 增量搜索
  • C-s 重复增量搜索
  • C-r 向前增量搜索
  • C-r 重复向前增量搜索
  • M-x query-replace-regexp 使用正则表达式搜索并替换

窗口命令(Window Commands)

  • C-x 2 水平分割窗格
  • C-x 3 垂直分割窗格
  • C-x o 切换至其他窗格
  • C-x 0 关闭窗格
  • C-x 1 关闭除了光标所在窗格外所有窗格
  • C-x ^ 扩大窗格
  • M-x shrink-window 缩小窗格
  • M C-v 滚动其他窗格内容
  • C-x 4 f 在其他窗格中打开文件
  • C-x 4 0 关闭当前缓冲区和窗格
  • C-x 5 2 新建窗口(frame)
  • C-x 5 f 在新窗口中打开文件
  • C-x 5 o 切换至其他窗口
  • C-x 5 0 关闭当前窗口

书签命令(Bookmark commands)

  • C-x r m 在光标当前位置创建书签
  • C-x r b 转到书签
  • M-x bookmark-rename 重命名书签
  • M-x bookmark-delete 删除书签
  • M-x bookmark-save 保存书签
  • C-x r l 列出书签清单
  • d 标记等待删除
  • Del 取消删除标记
  • x 删除被标记的书签
  • r 重命名
  • s 保存列表内所有书签
  • f 转到当前书签指向的位置
  • m 标记在多窗口中打开
  • v 显示被标记的书签(或者光标当前位置的书签)
  • t 切换是否显示路径列表
  • w 显示当前文件路径
  • q 退出书签列表
  • M-x bookmark-write 将所有书签导出至指定文件
  • M-x bookmark-load 从指定文件导入书签

Shell

  • M-x shell 打开shell模式
  • C-c C-c 类似unix里的C-c(停止正在运行的程序)
  • C-d 删除光标后一个字符
  • C-c C-d 发送EOF
  • C-c C-z 挂起程序(unix下的C-z)
  • M-p 显示前一条命令
  • M-n 显示后一条命令

Dired

  • C-x d 打开dired
  • C(大写C) 复制
  • d 标记等待删除
  • D 立即删除
  • e或f 打开文件或目录
  • g 刷新当前目录
  • G 改变文件所属组(chgrp)
  • k 从屏幕上的列表里删除一行(不是真的删除)
  • m 用*标记
  • n 光标移动到下一行
  • o 在另一个窗格打开文件并移动光标
  • C-o 在另一个窗格打开文件但不移动光标
  • P 打印文件
  • q 退出dired
  • Q 在标记的文件中替换
  • R 重命名文件
  • u 移除标记
  • v 显示文件内容
  • x 删除有D标记的文件
  • Z 压缩/解压缩文件
  • M-Del 移除标记(默认为所有类型的标记)
  • ~ 标记备份文件(文件名有~的文件)等待删除
  • # 标记自动保存文件(文件名形如#name#)等待删除
  • */ 用*标记所有文件夹(用C-u */n移除标记)
  • = 将当前文件和标记文件(使用C-@标记而不是dired的m标记)比较
  • M-= 将当前文件和它的备份比较
  • ! 对当前文件应用shell命令
  • M-} 移动光标至下一个用*或D标记的文件
  • M-{ 移动光标至上一个用*或D标记的文件
  • % d 使用正则表达式标记文件等待删除
  • % m 使用正则表达式标记文件为*
  • + 新建文件夹
  • > 移动光标至后一个文件夹
  • < 移动光标至前一个文件夹
  • s 切换排序模式(按文件名/日期)
  • 或许把这个命令归入这一类也很合适:
  • M-x speedbar 打开一个独立的目录显示窗口

Telnet

  • M-x telnet 打开telnet模式
  • C-d 删除后一个字符或发送EOF
  • C-c C-c 停止正在运行的程序(和unix下的C-c类似)
  • C-c C-d 发送EOF
  • C-c C-o 清除最后一个命令的输出
  • C-c C-z 挂起正在运行的命令
  • C-c C-u 移除前一行
  • M-p 显示前一条命令

Text

只能在text模式里使用

  • M-s 使当前行居中
  • M-S 使当前段落居中
  • M-x center-region 使被选中的区域居中

宏命令(Macro-commands)

  • C-x ( 开始定义宏
  • C-x ) 结束定义宏
  • C-x e 运行最近定义的宏
  • M-n C-x e 运行最近定义的宏n次
  • M-x name-last-kbd-macro 给最近定义的宏命名(用来保存)
  • M-x insert-kbd-macro 将已命名的宏保存到文件
  • M-x load-file 载入宏

Programming

  • M C-\ 自动缩进光标和标记间的区域
  • M-m 移动光标到行首第一个(非空格)字符
  • M-^ 将当前行接到上一行末尾处
  • M-; 添加缩进并格式化的注释
  • C, C++和Java模式
  • M-a 移动光标到声明的开始处
  • M-e 移动光标到声明的结尾处
  • M C-a 移动光标到函数的开始处
  • M C-e 移动光标到函数的结尾处
  • C-c RETURN 将光标移动到函数的开始处并标记到结尾处
  • C-c C-q 根据缩进风格缩进整个函数
  • C-c C-a 切换自动换行功能
  • C-c C-d 一次性删除光标后的一串空格(greedy delete)

为了实现下面的一些技术, 你需要在保存源代码的目录里运行"etags *.c *.h *.cpp"(或者源代码的其他的扩展名)

  • M-.(点) 搜索标签
  • M-x tags-search ENTER 在所有标签里搜索(使用正则表达式)
  • M-,(逗号) 在tags-search里跳至下一个匹配处
  • M-x tags-query-replace 在设置过标签的所有文件里替换文本

GDB(调试器)

  • M-x gdb 在另一个的窗格中打开gdb

版本控制(Version Control)

  • C-x v d 显示当前目录下所有注册过的文件(show all registered files in this dir)
  • C-x v = 比较不同版本间的差异(show diff between versions)
  • C-x v u 移除上次提交之后的更改(remove all changes since last checkin)
  • C-x v ~ 在不同窗格中显示某个版本(show certain version in different window)
  • C-x v l 打印日志(print log)
  • C-x v i 标记文件等待添加版本控制(mark file for version control add)
  • C-x v h 给文件添加版本控制文件头(insert version control header into file)
  • C-x v r 获取命名过的快照(check out named snapshot)
  • C-x v s 创建命名的快照(create named snapshot)
  • C-x v a 创建gnu风格的更改日志(create changelog file in gnu-style)

列操作

emacs列操作有两种方式: 1.原始列模式(矩形区域操作) 2.可视化列模式(cua-mode)

原始列模式

以C-x r开头的命令来进行矩形操作。 C-x r C-h 几乎可以查到所有的列操作命令,

先用C-space或者C-@设一个mark,移动光标到另一点,用以下命令进行列操作:

  • C-x r C-@ point-to-register
  • C-x r SPC point-to-register
  • C-x r + increment-register
  • C-x r b bookmark-jump
  • C-x r c clear-rectangle
  • C-x r d delete-rectangle
  • C-x r f frame-configuration-to-register
  • C-x r g insert-register
  • C-x r i insert-register
  • C-x r j jump-to-register
  • C-x r k kill-rectangle
  • C-x r l bookmark-bmenu-list
  • C-x r m bookmark-set
  • C-x r n number-to-register
  • C-x r o open-rectangle
  • C-x r r copy-rectangle-to-register
  • C-x r s copy-to-register
  • C-x r t string-rectangle
  • C-x r w window-configuration-to-register
  • C-x r x copy-to-register
  • C-x r y yank-rectangle
  • C-x r C-SPC point-to-register

可视化列操作(cua-mode)

cua- mode下,按[C-Ret]会进入cua rectangle模式。 可以通过鼠标点击确认起点,然后通过光标键来选中一个范围,这个rect会用另外的颜色显示出来。 之后就可以方便进行矩形操作。比如[M-up],[M-down],[M-left],[M-right]可以移动这个rect, [C-Ret]可以取消这个rect,[C-space]可以退出cua-rect模式并激活普通模式下的选择。 cua-mode下可以用以下命令进行列操作: 接输入字符: 在每行前(或后)都插入这个字符

  • M-b 用空格(tabs或者spaces)替换所有rect中的字符
  • M-c 去掉所有行左侧的空格
  • M-f 用单个字符替换所有rect中的字符(提示输入一个字符)
  • M-i 对每行中第一个找到的数字进行加1操作(自动把0x开头的当作十六进制数字)
  • M-k 剪切rect
  • M-l 把rect中的内容全部转换为小写
  • M-m 拷贝rect
  • M-n 用一串自增的数字替换rect中的每一行(这个功能可以用来给每行编号)
  • M-o rect的内容右移,选中的rect用空格填充
  • M-r 用字符串替换符满足正则表达式的字符串
  • M-R 上下反转
  • M-s 把rect中的每一行替换为一个字符串(提示输入)
  • M-t 把rect整个替换为一个字符串(提示输入)
  • M-u 把rect中的内容全部转换为大写
  • M-| 对rect执行一个shell命令

org-mode

table

内建表格的基本操作
1. C-c 将选定区域制成表格,如果每行都有tab,那将假定以tab来区分材料,如果每行有逗号,按一都好分割,否则以空格分隔表格域,或者加前缀以强制分割符,C-u逗号;C-u C-u Tab;数字n表示连续n个空格,如果无激活区域,则创建空表,会提示行列。
2. C-c C-c 不移动鼠标情况下重新对齐表格
3. <tab> 对齐表格,并将光标移入下一域,如果需要则创建新行
4. S-<tab> 重新对齐,并移入前一域
5. <RET> 重新对其表格并移入下一行,或者创建新行。在一行的开头或结尾,仍然创建新航,所以可用来分割表格。
6. M-a 移到当前域的开头,或者前一域
7. M-e 移到当前域结尾或下一域
8. M-<left>  

TODO Muse-mode

TODO gnuplot-mode

TODO ecb-mode

各种mode

org-mode

intro

org是EMACS的一种主模式,主要用来撰写文档,但是它远不止于此。

Org mode 一些资料

org-mode用于写作的快捷方式

org 官网主页 所有文档都有,很详细哦。

org发布的例子

官网关于发布html的教程

使用org做GTD

table

创建表格
  • 输入的时候创建表格

    最简单的方式就是在一行的开头(前面有空格也没关系)直接敲一个"|",然后你就是在表格第一个栏里面输入了。

    | 这个是表格第一个格子
    

    编辑完一个表格单元以后,你可以按TAB跳到下一个,因为刚刚输入的行只有一个单元,所以下个单元就变下一行了。

    | 这个是表格第一个格子 |
    | <按了TAB就跑这里来了>        |
    
  • 创建表格结构然后填入内容

    也可以从头创建一个空表格,命令:C-c | 。将会问你表格结构,默认5*2 (org-table-default-size),例如:

    | 1 | 2 | 3 | 5 | 6 |
    |---+---+---+---+---|
    |   |   |   |   |   |
    |   |   |   |   |   |
    |   |   |   |   |   |
    

    然后就可以用TAB键从一个格子跳到另一个格子,或者S-<TAB>前一个,RET(回车)跳到同一列的下一个,如果下一列没有(或者不同比如是标题栏跳到普通栏) 同列下一行隔了个空行,那就创建新行并跳入。

  • 将某个区域转换为表格

    也可以将一个区域转换成表格,选择一个区域然后C-c |。例如在次区域

    some, comma, separated, value

    就会自动生成

    some comma separated value

    一般来说这个命令会猜你的分隔符,

    • 如果要强制,做分隔符,则C-u C-c |
    • 如果要强制<TAB>做分隔符,则C-u C-u C-c |
    • 如果要强制空格做分隔符,比如三个空格,则C-u 3 C-c |
编辑表格
  • 移动行列

    假设初始表格如下:

    | A | B | C |
    | 1 | 2 | 3 |
    | a | b | c |
    

    将光标放在A格子里,按M-<right>就会将A列换到右边

    | B | A | C |
    | 2 | 1 | 3 |
    | b | a | c |
    

    光标放在A,按M-<down> 会将第一行下移

    | 1 | 2 | 3 |
    | A | B | C |
    | a | b | c |
    
  • 插入行列

    跟上面移动的命令一样,但是在前面加上<shift> 这些命令就变成插入一个新行或者列了,比如光标在B S-M-<right>会在A B直接插入列

    | A |   | B | C |
    | 1 |   | 2 | 3 |
    | a |   | b | c |
    

    同理,S-M-<down>

    |   |   |   |
    | A | B | C |
    | 1 | 2 | 3 |
    | a | b | c |
    
将一列变窄

有时候一些格子太宽了,如果你想限制列宽,就要新增一行,如下:

| <10>             | <15>                        |
| A very wide cell | Another very very wide cell |

然后在表格上按C-c C-c ,表格就会按尖括号设置宽度显示,如

A very wide cell Another very very wide cell

但是变窄了就看不见了怎么办?要临时看看某个格子内容,可以C-c <TAB>(C-u C-c ') 或者在独立的窗口编辑C-c '

准备输出表格

例如要将表格

| A | B |
| 1 | 2 |

输出成

A B
1 2
  • 加个表头

    而这种表格

    | A | B |
    |---+---|
    | 1 | 2 |
    

    会输出成

    A B
    1 2

    水平线告诉表格处理器,第一行是表头

  • 将列分组

    可以这样分组

    |   |  N | N^2 | N^3 | N^4 | sqrt(n) | sqrt(N)    |
    |---+----+-----+-----+-----+---------+------------|
    | / | <> |   < |     |   > |       < |          > |
    | # |  1 |   1 |   1 |   1 |       1 |          1 |
    | # |  2 |   4 |   8 |  16 |  1.4142 |     1.1892 |
    | # |  3 |   9 |  27 |  81 |  1.7321 |     1.3161 |
    |---+----+-----+-----+-----+---------+------------|
    

    输出就是

    N N2 N3 N4 sqrt(n) sqrt(N)
    1 1 1 1 1 1
    2 4 8 16 1.4142 1.1892
    3 9 27 81 1.7321 1.3161

tags

tips
  1. 可以在.emacs里面预定义一些全局使用的标签.(即使没有预定义,在文档中使用过的tags也会自动被收集,并可以在下次补齐.
           (setq org-tag-alist '(
                    (:startgroup . nil)
                    ("@life" . ?L)
                    ("@tech" . ?t)
                    (:newline . nil)
                    ("mac" . ?m)
                    ("linux" . ?l)
                    ("git" . ?g)
                    ("simulation" . ?s)
                    ("RoR" . ?r)
                    ("javascript" . ?j)
                    ("web" . ?w)
                    ("emacs" . ?e)
                    (:newline . nil)
                    ("gnus" . ?g)
                    ("org" . ?o)
                    ("babel" . ?b)
                    (:endgroup . nil)
                    ("@misc" . ?M)
                    )
    )
    

    注意标签名要是字符,双引号括起来.

  2. 如果想动态增加, 又使用预设标签,则在文件头加入空tags如:
    #+TAGS:
    

    所以可以将这个空标签加入公共的文档模板中.

  3. 如何设置层级标签, 就是一组标签属于某个大标签的子标签.

    知道了,原来也没什么特殊的方法,就是不要让他们在一个组里面就可以重复选了, 就是没什么必然的关联而已, 修改以后的如:

    ;; org-tags
    ;;----------------------------------------
    (setq org-tag-alist '(
             (:startgroup . nil)
             ("@life" . ?L)
             ("@tech" . ?t)
             ("@misc" . ?M)
             (:endgroup . nil)
             (:newline . nil)
             (:startgroup . nil)
             ("mac" . ?m)
             ("linux" . ?l)
             ("git" . ?g)
             ("simulation" . ?s)
             ("RoR" . ?r)
             ("javascript" . ?j)
             ("web" . ?w)
             ("emacs" . ?e)
             (:endgroup . nil)
             (:newline . nil)
             (:startgroup . nil)
             ("gnus" . ?g)
             ("org" . ?o)
             ("babel" . ?b)
             (:endgroup . nil)
             )
    )
    

misc

org 项目发布的时候是增量发布的, 比如发布到publichtml目录, 有时候想整个砍掉重新发布, 删掉这个目录并不能全部重新生成, 还需要同时删掉

.org-timestamps文件夹的时间戳.

org 下面的一些子模式的使用

babel

intro

babel可以让org-mode有能力在org-mode文档中执行不同语言的源代码, 而org-mode是emacs的一个major mode几乎可以对普通文本做任何事情.

babel主页地址

trouble shooting
  1. 在.emacs里面配置支持语言的时候, 括号里面需要写这里定义的语言的identifier,emacs才能识别,另外有时候也有看有根据requirement安装必要的东西.

ditta

intro

ditaa主要是用于处理各类ascii字符来绘各种图的插件,方便在各种源码中插入的各种简易图示处理为精美图片供发布。 生成ditaa处理的原ascii字符一般用 另几个mode,artist-mode,和picture-mode ,iimage-mode等。

ditaa 示例

ditaa 安装和使用说明

tips
  1. 当artist-mode 画出的block不完整的时候,比如箭头伸到方框中,之类的情况,则block颜色什么的就不能显示,ditaa不能把它作为元素处理。
  2. 关于曲线,弯曲点要上下对齐,错位则会以原样显示。

publish

trouble shooting
  • 如果整个org不是发布的服务器的根目录的话,特别是sitemap名字不能起成index.

因为这个时候这个里面的链接都是相对于这个文件的url的,如果起名字叫做index则,url就为:

http://localhost/subfolder

可以看到根本就没有index.html这个文件,所以如果你在index.html里面有一个链接,./emacs.html,则转成url就会变成

http://localhost/emacs.html

而不是期望的

http://localhost/subfolder/emacs.html
  • 自动生成的sitemap不能应用模板设置

    因为sitemap每次都自动生成,所以不太方便去每次往里面添加你自己定义的模板文件,所以很多设置不好个性化设置. 这个时候就最好设在整个project的默认设置里面,写入.emacs配置文件.

    有个解决方法, 就是 将自动生成的sitemap和最后publish用到的sitemap用两个文件…

    比如: 自动生成sitemap0.org,但是网页的sitemap呢,就用sitemap.org,在这个里面就可以配置连接的css文件啊什么的…

    每次自动生成就只会变化sitemap0.org, 而实际使用的sitemap.org没有修改,只是自动去include进来这个文件而已..比如:

#+SETUPFILE: ~/.emacs.d/org-templates/level-0.org

#+INCLUDE: ~/.emacs.d/org-templates/level-0.org

#+INCLUDE: ./sitemap0.org

gtd

一些使用org做gtd的资料 yifeiyang的博客

tips

  1. 如果要使用 斜体, 加粗 ,要注意//斜杠前后都要有空格,斜杠内部内容跟斜杠不能有空格。
  2. 默认下划线后内容会被解释为下标例如: 我下标 ,要避免,需要用\给\转义,就达到正常效果我\下标。并且下标内容结束后要空格,否则 默认后面内容都是下标。

bugs(测试在terminal下面不好使,单独打开是好的)

  1. C-<RET> org-insert-heading-respect-content 绑定不好使
  2. M-S-return org-insert-todo-heading 绑定不好使
  3. C-S-<RET> ort-insert-todo-heading-repect-content 绑定不好使
    1. M-<left> org-do-promote 绑定不好使
    2. M-<right> org-do-demote 绑定不好使

gnus

intro

Gnus 是emacs 用于收发邮件和上新闻组等等的程序.

gnus gmail   gmail gnus

gnus链接gmail服务器有两种方式: pop3 和 imap 每种协议都有不同的方式工作. 下面以imap 为例说明gmail的配置.

  • 首先,要在(设置->转发和 pop/imap)启用imap.
  • 在~/.gnus.el中(gnus启动时会读取的配置文件),设置如下
(add-to-list 'gnus-secondary-select-methods '(nnimap "gmail"
                                  (nnimap-address "imap.gmail.com")
                                  (nnimap-server-port 993)
                                  (nnimap-stream ssl)))
  • 新建文件~/.authinfo,并放入类似下面内容
machine imap.gmail.com login username@gmail.com password secret port 993
  • 将你自己的gmail帐号替换, secret表示换成你的密码,如果要加密,则这里留空.

认证文件加密

用easypg加密

把下面内容放到.emacs

(require 'epa-file)
(epa-file-enable)

只有每次保存以gpg为后缀的文件都会自动加密.

配置gnus使用新认证文件

修改原来的那一段配置为

(add-to-list 'gnus-secondary-select-methods '(nnimap "gmail"
                                  (nnimap-address "imap.gmail.com")
                                  (nnimap-server-port 993)
                                  (nnimap-authinfo-file "~/.authinfo.gpg")
                                  (nnimap-stream ssl)))

联系人以及自动补全

一般都BBDB 下载bbdb

trouble shooting

如果遇到

Opening output file: Searching for program, no such file or directory, gpg

说明没装gpg 这个程序.安装了先.mac版请安装macgpg, mac版使用说明.

两个版本安装都一样.

./configure
make
sudo make install

设置gmail完成以后,收件箱呢?发件箱呢? 默认只有订阅了的才会出现在开始的group里面,所以按^,进入Server buffer,就可以看到 {nnfolder:archive} (opened) {nndoc:gnus-help} (opened) {nnimap:gmail} (opened) (agent) {nntp:news.cn99.com} (opened) (agent) 移动到第三行,ret,就可以看到 Z 0: Apple Mail To Do Z 114: Deleted Messages 0: Drafts 2848: INBOX 0: Notes 26: Sent Messages K 1: 垃圾箱 K 0: 工作邮件 0: 已发送 K 0: 收据 K 0: 旅行相关 K 0: 私人邮件 K 0: 草稿

在自己感兴趣的文件夹下面按u,就可以订阅了. 然后在最开是的group界面就可以看到所有自己订阅的新闻了.如下 *: nnimap+gmail:已发送 *: nnimap+gmail:Drafts *: nnimap+gmail:Sent Messages *: nnimap+gmail:Notes *: nnimap+gmail:INBOX 4: news.announce.newusers(m) 3: news.groups.questions 27: gnu.emacs.gnus 9: nndoc+gnus-help:gnus-help

tips

  1. 如果不想没次都被问使用社么加密算法,把这个设置到.emacs里面
(setq epa-file-encrypt-to nil)
  1. 一个文件如果有n个帐号,gnus会让你输N次密码, 解决这个配置
(setq epa-file-cache-passphrase-for-symmetric-encryption t)

doc-view-mode

用来查看pdf之类的,需要安装texpdf包。

magit

magit可以让你用emacs来来查看和修改你的git仓库,审阅和提交你的修改,浏览修改记录。 magit不能支持全部的git命令,只是将一些最常用的命令更方便在emacs中使用。 magit-status是magit的入口,可以带你到当前git仓库的状态buffer,我绑定在C-c m。 在magit buffer可以使用$命令来切换到*magit-process* buffer来查看最近的git命令。

section

  • Tab toggle current section
  • S-Tab toggle children of current section
  • 1,2(M-h),3,4(M-s) visibility of current section levels
  • M-1,M-2(M-H),M-3,M-4(M-S) visibility of all section levels

Status

在git仓库目录下调用magit-status 会自动到当前仓库的status buffer, 如果当前目录 不是仓库则会弹出提示让你输个仓库目录,加C-u前缀会强制提示输入目录。如果给定目 录不是仓库,则会初始化一个空仓库。

变量magit-repo-dirs 如果是nil,则magit-status会要求输入目录,如果非nil,则将 其值作为目录列表对待。magit-status会在输入的时候试图用列表中的目录进行补全。 变量magit-repo-dirs-depth magit查找的目录深度。

在emacs之外做了任何修改,需要手动刷新的,可以在status buffer按g刷新。

Untracked

  • s add untracked file to staging title上面按就是所有untrack全部staged
  • C-u S 1.任何地方按下都stage all untracked 2.并且将所有changes -> tracked
  • i ignore untracked 将文件加入.gitignore
  • C-u i ask name of file to ignore ,可以输入目录和通配符
  • M-n C-u i的时候可以腺体预定义的一些值
  • C– i 默认提示通配符
  • I 类似于i 不过讲文件加入.git/info/exclude
  • k delete untracked file forever 在title上面删除所有untracked

Staging and Committing

  • s unstage -> stage
  • u stage->unstage
  • + - change size of hunks
  • 0 reset hunk size
  • C-u s ask name for staged
  • S move all hunks of all diffs into stages
  • U similar to above
  • C-u S stage all untracked and changes to tracked
  • k discard uncommited chagnes
  • c write chagne description
  • C-c C-c perform commit
  • C-x 4 a write changes in a ChangeLog file
  • C-c C-a whether next commit will amend the current commit
  • M-n M-p cycle through log-edit-comment-ring
  • C-c C-s –signoff var magit-commit-signoff for default
  • C-c C-e –allow-empty
  • C-c C-t toggle option to specify name and email
  • C-c C-k erase magit-log-edit buffer and bury it
  • C pop up description buffer it try to insert changelog style entry

History

  • l l show histroy
  • l r l show repo history between two branches
  • l =g limits the output to a specific regex matches
  • l L log in verbose form
  • magit-log-cutoff-length 最大显示log数目
  • e 两倍上面那个数目
  • C-u e 全部log

on commits action

  • RET SPC DEL pop up more info 光标位置会不同 ret移动光标到新buffer,spc del

不移

  • a apply current commit to current branch 不提交
  • A 同上,但是提交
  • v revert current commit要自己提交
  • C-w copy sha1 to kill ring
  • = show diff from current to marked
  • . mark and unmark current commit
  • C-u . unmark all

Reflogs

  • l h browse reflog local history of changes made to repo heads
  • l H ask for a head

Commit Buffer

  • a on diff on hunk apply to working copy
  • v apply the patch reverse
  • C-c C-b get back from referenced commit
  • C-c C-f forward in history

Diff

any buffer that shows a diff

  • e show the two versions of the file in ediff
  • d show changes from working tree to another revision
  • D two arbitrary revisions
  • a apply chagnes to working tree
  • v apply selected changes in reverse

Tagging

  • t t make a lighweight tag
  • t a annotated tag

Resetting

  • x ask for a revision and reset current head to it;not change to working

tree

  • X reset to most recently; discard local modification
  • C-u x reset both current head and working tree

Stashing

  • z z create a new stash a A k
  • C-u z z
  • z -k z leave changes in working tree and index
  • z s automatically enters a timestamp as description

Braches and Remotes

Branches Popup
  • b display a popup menu
  • b b switch to a different branches
  • b c create a new branches and switch
  • b k delete a branch
  • b r rename a branch
  • b v launch the branch manager
Remotes Popup
  • M display a pop menu to manipulate remotes
  • M a Add a new remote
  • M k delete a remote
  • M r rename a remtoe
Branches in Branch Manager
  • # current local branch
  • RET check out a branch
  • c create a new branch
  • k kill a branch
  • C-u k delete even note merged
  • r rename
  • T changes which remote branch it tracks.
Remotes in the Branch Manager
  • a add new
  • k
  • r

Wazzup

  • w show a summary of how your other branehs relate to current
  • i ignore branch in wazzup view
  • C-u w show all branches

Merging

  • m m initiate merge
  • X abort merge

Rebasing

  • R initate a rebase

Pushing and Pulling

  • P P git push
  • C-u P P ask for repo to push to
  • C-u C-u P P ask for target branch
  • f f git fetch
  • f o alway prompt for the remote
  • F F git pull

diff

diff   diff vc

使用 Unix 的 diff 工具程序,你可以找到两个文件的不同之处。所比较的两个文件可能是:

  • 原始文件与更改之后的文件
  • 不同的两个人编辑的同一个文件(譬如,一个项目中协同工作的两个人编辑的文件)
  • 不同机器上的两个文件(譬如,你的 .emacs 文件可能在家和工作场合各有一份拷贝)

对于后面两种文件,两个要比较的文件共有一个原始的文件。此种情况下, diff3 程序会轻松的帮你创建一个文件,文件内容是对原始文件所做的修改记录。

ediff   ediff vc

除非两个文件的不同之处很少,否则 diff 的输出将会很难阅读。幸运的是, Emacs 提供了一个 diff 的接口,称为 Ediff ,将此工作变得简单。不仅将 diff 的输出变得可读之外, Emacs 还提供了合并文件函数以及其他的应用补丁,更多的细节信息,可以参考 Ediff 的 info 文档。 Emacs 还能比较不同文件夹下的两个文件,若你在不同地方工作,这个功能可能会非常有用(如你的Lisp配置文件。

用 Ediff 来比较文件

Ediff 比较的项目有:( 可用 M-x 来启动 )

比较项目 说明
ediff-regions-linewise, ediff-regions- 询问两个缓冲区的名字,然后比较相应的区域。不过你只能在每一个缓冲区中选定一个区域,而不能比较一个文件缓冲区的两个区域。( TODO: 第15个小时的内容 "了解文件" ,会提供一个比较同一个文件中的两个区域的方法。)
ediff-buffers 询问两个缓冲区的名字,然后比较
ediff-files 询问两个文件的名字,加载之,然后比较
ediff-windows-linewise, ediff-windows-wordwise 让你选两个窗口,然后比较窗口的内容。 -linewise- 函数比 -wordwise- 函数要快,但另一方面, -wordwise- 工作方式更好,尤其是小区域作业时。 -linewise- 一行一行地比较, -wordwise- 一个单词一个单词地比较。
一些Ediff 控制命令

在 control buffer 中,按键。

快捷键 命令 说明
q ediff-quit 关闭 ediff control buffer, 并退出 ediff
Space 或 n ediff-next-difference 下一个差异处
Del 或 p ediff-previous-difference 上一个差异处
[n]j ediff-jump-to-difference 有数字前缀 [n] 修饰,第n个差异处,n可为负数
v 或 C-v ediff-scroll-vertically 所有缓冲区同步向下滚动
V 或 M-v ediff-scroll-vertically 所有缓冲区同步向上滚动
< ediff-scroll-horizontally 所有缓冲区同步向左滚动
> ediff-scroll-horizontally 所有缓冲区同步向右滚动
(vertical bar) ediff-toggle-split 切换缓冲区布局方式, 水平和竖直
m ediff-toggle-wide-display 在正常 frame 大小和最大化之间切换
a ediff-copy-A-to-B 把Buffer-A的内容复制到Buffer-B
b ediff-copy-B-to-A 把Buffer-B的内容复制到Buffer-A
r a 或 r b ediff-restore-diff 恢复 Buffer-A 或 Buffer-B 差异区域中的被修改的内容
A 或 B ediff-toggle-read-only 切换 Buffer-A 或 Buffer-B 的只读状态
g a 或 g b ediff-jump-to-difference-at-point 根据光标在缓冲区中的位置,设置一个离它们最近的差异区域为当前活动区域
C-l ediff-recenter 恢复先前的所有缓冲区比较的高亮差异区。
! ediff-update-diffs 重新比较并高亮差异区域
w a 或 w b ediff-save-buffer 保存 Buffer-A 或 Buffer-B 到磁盘
E ediff-documentation 打开 Ediff 文档
z ediff-suspend 关闭 ediff control buffer, 只是挂起,可在以后恢复 ediff 状态
比较三个文件

此种需要大都发生在两个文件共有一个原始的文件。假设 C —> A, C —> B. A与B可能都对C进行了修改,你需要知晓,究竟A和B哪个对C做了什么修改。此时就需要比较三个文件了。

假如A有一部分内容,而在B中不存在,可能是下列两种情况之一:

  • A 中增添了这部分内容
  • B 中删除了这部分内容

你就应该比较A B C 三个文件来确定究竟是哪种情况。 操作

有两个函数

函数 说明
ediff-files3 比较三个文件
ediff-buffers3 比较三个缓冲区

具体操作

比较两个文件或缓冲区的所有操作,几乎都适于三个比较。不过在进行缓冲区差异区从A到B拷贝的操作略有不同:

快捷键 说明
cb 将 Buffer-C 拷贝到 Buffer-A
ab 将 Buffer-A 拷贝到 Buffer-B

以此类推,在 Buffer-A , Buffer-B, Buffer-C之间的操作可以很容易猜出。

Ediff Session

你可能同时要比较好多对文件,你可以同时拥有多个 Ediff Session 。按 z 挂起当前 Ediff session ,然后启动另一个 Ediff session 就可以了。 此时,在 control buffer 中按 R 或是按下 M-x eregistry, 将会打开一个 Ediff Registry 的缓冲区,此缓冲区包含当前运行的所有 Ediff Sessions.可以选择一个 Ediff session 来进入。

TODO 合并文件
TODO 比较文件目录
TODO 与版本控制系统(VC) 一块儿工作

jabber

intro

emacs jabber 是emacs聊天工具, 基于xmpp协议

jabberEI

emacs chat with gmail

emacs中文网关于jabber

安装配置   @tech emacs

配置

在.emacs中写入

;; emacs-jabber
;;----------------------------------------
;; adjust this path:
(add-to-list 'load-path "~/.emacs.d/emacs-jabber/")
;; For 0.7.90 and above:
(require 'jabber-autoloads)

或者也可使用M-x jabber-customize,手工配置,会自动写入.emacs其实是一样的. 配完之后选择save for future sessions,例如 ../img/jabber-customize.tiff

配置帐户,以gmail(gtalk)帐户为例

(setq  jabber-account-list
       (quote (("yourcount@gmail.com""
                (:network-server . "talk.google.com")
                (:port . 5223)
                (:connection-type . ssl)
                ))
              )

快捷键

jabber快捷键基本以C-x C-j开头,比如C-x C-j C-h帮助,可以查看大部分可使用命令.

../img/jabber-help.tiff

使用

详细官方使用指南

按下C-u C-x C-j C-c (等效于M-x jabber-connetct) 启动jabber链接.

../img/jabber-promote-for-jid.tiff

然后输入帐号(根据设置tab会有补全),密码,就会按此帐号的设置来连接了.

然后哪里去了呢?

C-x C-b 会看到一个 jabber-roster的buffer

../img/jabber-roste-buffer.tiff

打开以后可以看到,上面是一些操作快捷键.还有菜单栏也有有多一个jabber菜单,可以控制连接,断线,状态提示等.

../img/jabber-roster.tiff

roster下半部分就是联系人咯.隐私我就不贴图了.

  • 和某个人聊天的话,就用 M-x jabber-chat-with 命令,输入某个人的帐号,或者直接从 \*-jabber-roster-\* buffer 里找到某人的帐号并按回车,就会出现 \*-jabber-chat-:-person-\* 这样的一个 buffer。在这个 Buffer 里,你就可以和他/她聊天了。如果对方有消息过来,Emacs 会在 minibuffer 里提示对方的名字,提示你有新的消息。
  • 聊天时,用回车就是发送消息,用 C-j 就是新建一行输入消息。
  • 默认情况下,你会显示为在线状态,如果需要修改状态,例如修改为 away,可以用命令 M-x jabber-send-presence 或快捷键 C-x C-j C-p 来切换状态。
  • 要退出用 M-x jabber-disconnect 命令即可;
  • 要添加某人为好友,可以用命令 M-x jabber-send-subscription-request;
  • 用命令 M-x jabber-customize 可以对 jabber 进行基本的配置。

skype

下载

$cd .emacs.d
$git clone https://github.com/romankrv/emacs-skype.git

配置

;; skype
;;----------------------------------------
(add-to-list 'load-path "~/.emacs.d/emacs-skype")
(require 'skype)
(setq skype--my-user-handle "yourname")

使用

M-x skype–init

on mac   @tech mac

在mac上会出现:

Symbol's function definition is void: dbus-call-method

安装dbus, 如果你使用[[https://github.com/mxcl/homebrew][homebrew] 做mac上的包管理工具,则

$brew install dbus

yasnippetes

安装

我用elpa的emacs包管理系统, 安装过程

  1. M-x package-list-packages
  2. C-s yasnippets
  3. i
  4. x

配置

yasnippets官网详细教程

在.emacs写入

;; yasnappets
;;----------------------------------------
(require 'yasnippet)

M-x eval-buffer

重新生效新配置,就会看到菜单多了一项YASnippet的菜单.

使用

输入缩略词的进行补全的触发快捷键为

  1. TAB
  2. C-i
  3. M-x yas/expand
  4. M-x yas/insert-snippet
  5. 菜单YASnippet

erc

已经很详细了,就不再写了

emacs erc

jinalle

baidu

iimage

intro

编辑org文档的时候经常希望图文并茂,并且不要点一下才显示出来,而是随文档打开一起显示.iimage好像就可以干这个.

emacs23.2以上版本自带iimage, 所以貌似不用手动load了.

然后用命令M-x iimage-mode RET就可以启动这个模式.

配置

如果想在 Emacs org 模式里启用 iimage 模式,把下面的代码放到配置文件里,则可以在 Emacs Org 的编辑区里显示图片。

(defun org-toggle-iimage-in-org ()
  "display images in your org file"
  (interactive)
  (if (face-underline-p 'org-link)
      (set-face-underline-p 'org-link nil)
      (set-face-underline-p 'org-link t))
  (iimage-mode))

使用

可以用 M-x org-toggle-iimage-in-org 或 M-x iimage-mode 命令来激活 iimage 模式,类似以下这些链接形式会直接显示为图片:

file://foo.png
`file://foo.png'
[[foo.gif]]
‹foo.png›
`foo.JPG'

trouble shooting

好像就是新添加的图片不会自动显示出来哦? 每次都要先disable,再anable,iimage-mode才可以哦…

daemon

概述

随着emacs所安装的插件包越来越多,自定义功能越来越丰富,emacs的启动速度会越来越慢.而 对emacs的配置越来越多正说明对emacs的使用越来越依赖,希望任意编辑活动都离不开 emacs,而如果只为了编辑几行代码,启动却要十几秒感觉得不偿失,所以从23开始emacs支持 daemon模式,即启动一个在后台运行的emacs server, 然后可以使用多个emacs client连接 到server上,与server共享一个emacs配置和实例.如果将server配置车给你开机启动,则以 后任何时候打开emacs都会变成秒开,比vim还要快很多.

另外一个重要的原因是,emacs和外部应用的通信,比如说,你从浏览器看到个好东西,要 发给emacs capture抓取并保存;你的外部icalindar系统设置的事件要发给emacs内部的 diary。没有一个daemon常开着是做不了这些事情的。

osx daemon

osx daemon的配置包括两个部分,daemon emacs server和emacs client. osx 下面基本有两种本质上一样的办法来做这件事情

  1. 自己写个applescript 脚本的应用,然后手动添加到用户的登陆项中.具体方法见这里.
  2. 或者用别人写好的,见这里.
  3. daemon下面字体等设置都会失效,方法见这里.
  4. 需要在gui下面打开menu-bar,term下面关闭.使用如下设置
                     (defun set-frame-menu-bar-lines (frame)
    (let ((want-menu (memq(framep frame) '(x w32 ns))))
     (set-frame-parameter frame 'menu-bar-lines (if want-menu 1 0))))
    (add-hook 'after-make-frame-functions 'set-frame-menu-bar-lines)
    
server

基本上就是写个脚本,启动daemon,然后随着用户登陆动作一起运行.如果只在终端下使用 emacs也是写到.bashrc中随着bash的启动而运行daemon server.

client

以后启动就从client启动就好了,不要在启动emacs了,osx中emacs client的地址在 /Applications/Emacs.app/Contents/MacOS/bin/emacsclient 在你自己的bash的启动脚本里面添加一些alias作为快捷方式.bash的话加在.bashrc zsh的话加在.zshrc中,例如我的.zshrc中这部分为:

alias emacs='/Applications/Emacs.app/Contents/MacOS/bin/emacsclient -nw'
alias e='emacs'
问题
  1. Q: gui client menu-bar-mode是打开的,但是不能显示menu A: LSUIElement flag is set to 1 for Emacs.app. To check that out, sift through the Emacs.app/Info.plist file. 参考地址
  2. emacs 中的shell $PATH变量与环境不一致,导致rails -v找不到,显示方式也不一样.

代码片段

instant-Paste

简介   @tech emacs

下面一些代码用于快速拷贝粘贴,基本方法是:

  1. 先设置一个点,不会的话C-@(因为C-SPC在win里面被输入法切换占了,mac里面被spotlight占了)。
  2. 然后到需要复制的源文本那里,依据要复制粘贴的内容(比如是单词,句子,行,括号。。。)按下相应的快捷键绑定,比如复制单词(C-c w)

此时就立即粘到那个点的位置了。

代码和配置   emacs

将以下配置写入.emacs

配置代码会在github更新 github地址

emacs自带的复制

复制 M-w 粘贴 C-y

主要差别在复制上, 上面那个复制会复制已经做标记的一个区域,一般标记一个区域用C-@,然后移动到另外一点,会自动显示两个点之间的部分。

复制粘贴的速度问题,主要就体现在如何快速选中。

所以emacs也提供了一些常用的快速选中或者mark的方法:

  1. M-@ 选中当前点后面的一个单词
  2. M-h 选中一个段落
  3. C-x C-p 选中一页
  4. C-M-h 选中一个函数
  5. C-x h 选中整个buffer
  6. C-M-@ 选中sexp(不知道啥。。。)

然后,M-w,复制,再稍后移动到希望粘贴的地方C-y就粘贴了, 如果希望一次复制很多,再粘,可以顺序复制到kill-ring里面,粘贴的方法,先C-y,在M-y。

align

  1. 对齐 C M \ (indent-region)
  2. 以某个符号为中线两边对齐 M x align-regexp [:] 例如,有段文本,想以括号为标准来对齐 Fred (123) 456-7890 Alice (123) 456-7890 Mary-Anne (123) 456-7890 Joe (123) 456-7890 执行命令以后为格式为: Fred (123) 456-7890 Alice (123) 456-7890 Mary-Anne (123) 456-7890 Joe (123) 456-7890