Pulpcode

捕获,搅碎,拼接,吞咽

0%

暴力的使用emacs

gun

解决问题,最好是简单粗暴,这也是我所理解的python的哲学,下面我们把这种哲学贯彻到编辑器emacs的使用上去。

如果你确实想要在vim上装逼,又要比那群vim党装的更好,那么emacs就是你最好的选择。

当然我是在搞笑,实际上在linux下,你真没有什么好用的编辑器,要么用vim,要么用emacs,emacs只不过比vim要强大一些。但是emacs的学习曲线是很陡峭的,这就像你如果想玩好魔兽世界这个游戏,那么你如果没受过几年魔兽历史的熏陶,打过几年的魔兽争霸的积淀,是很难理解这个游戏的。实际上emacs的话题也很多,包括和vim不同的设计哲学,甚至包括elisp程序(因为emacs其本身就是一个lisp解释器)。所以看到这里你因该懂了,这篇博客就是满足既想用emacs装逼,又想立牌坊。哦不,说错了,又不想花太多时间学习的人,那么我们可以尝试用性价比的方式来解决这个问题。

首先你要安装一个emacs,需要注意的是,默认的yum或者是apt-get所能安装的emacs版本都是比较老的(可能是23的)。建议你安装24或者更高的版本,我们后面介绍的emacs配置也要求是24或者更高的版本。。所以去官网下载就是最好的选择了:http://www.gnuemacs.org/

暴力的快捷键

那句28定律怎么说的,实际上emacs的快捷键是很多的,而且大部分根本用不到。你只需要记住常用的,就足够暴力了。

快速移动

1
2
3
4
5
6
7
8
9
10
11
12
13
14
C-n 向下移动一个字符
C-p 向上移动一个字符
C-b 向左移动一个字符
C-f 向右移动一个字符
M-b 向左移动一个单词
M-f 向右移动一个单词
C-M 移动到行首
C-e 移动到行尾
C-v 向上翻页
M-v 向下翻页
M-< buffer开头
M-> buffer结尾

C-l 将光标所在行,作为中心行,刷屏

其实“段落首尾”,“句子首尾”,这样的快捷键根本用不到,因为你很少用emacs去写英文小说或者是日记什么的。大多情况就是写代码而已,所以忽略它们。

查找替换

太复杂的查找替换记不住,只记得查找用C-s向后查找,C-r向前查找就行了。替换只需要调用函数:M-x replace-string

复制,剪贴,粘贴,删除,撤销,重做

1
2
3
4
5
6
7
8
9
10
11
12
13
C-@ 设置选择下标
C-w 剪贴选中区域
M-w 复制选中区域

C-x H 全选整个缓冲区
C-k 删除光标后的整行内容
Backspace 向前删除一个字母
M-Backspace 向前删除一个单词
C-d 向后删除一个字母
M-d 向后删除一个单词

C-_ Undo
C-? Redo

(上面两个键在按的时候,都会Ctrl+Shift+X)
关于Yank Ring太复杂,可以直接忽略了。

其它快捷键

一个在python中最实用的快捷键,就是使用C-@选择块。

1
2
C-c < 向左缩进
C-c > 向右缩进

还有就是C-c C-c可以直接将当前的buffer发送到python解释器中,这在emacs中编写调试python代码太方便了。

实用的mode

org这种做TODOlist还有看日历的那些mode,我就不介绍了,因为我觉得这确实没什么卵用,玩这些完全是浪费时间。

shell

在emacs下开shell是非常实用的选择,方便的让你一边写代码一边debug。你还可以把整个shell打印出来的东西当文本用(比如向前查找,向后查找,复制粘贴之类的)还要记住两个实用的键M-p:上一个命令M-n:下一个命令。

Dired

启动文件管理模式的是C-X+D, 文件管理器,对于查找和打开文件这样的操作非常快。

follow-mode

这个模式可以分屏显示代码,也就是说第一屏的尾刚好连到第二屏的首。

安装配置

下载prelude,你在github上可以找到它:prelude,这个是我折腾了这么多配置中觉得最好用的一个配置。你安装好这个配置之后,启动emacs,它就会下载相应的依赖包了。大牛已经帮你踩完了坑,铺平了道路,你只要用它就可以了。

之后你需要做这些修改,找到~/.emacs.d/sample/prelude-modules.el,在这个文件中,将需要导入的包解开注释,不需要导入的包加上注释。

在这个配置中有一个实用的键绑定就是

1
2
F3:定义一个宏
F4:结束一个宏定义/运行一个宏

自定义配置

在你安装了配置之后,可以在~/emacs.d/personal/目录下建立一个el文件,在这个文件中写入你自定义的配置。

修改主题

这个prelude的默认主题是:zenburn,这个主题在X-windows上看起来很漂亮,但是在shell上会感觉有点卡,我建议在shell中就把这个主题关了,(disable-theme 'zenburn),在告诉你一个小技巧,就是不用每次改完配置重启,只需要load-file就可以了。或者你想换一个主题,只要输入load-theme就可以了。(setq prelude-theme 'xxxxx)

其它

要注意,注释和反注释在写代码的时候太重要了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
;; 转到某一行
(global-set-key (kbd "M-g") 'goto-line)

;; 复制一行
(defun copy-line (&optional arg)
"Save current line into Kill-Ring without mark the line"
(interactive "P")
(let ((beg (line-beginning-position))
(end (line-end-position arg)))
(copy-region-as-kill beg end))
)

(global-set-key (kbd "C-x y") 'copy-line)


;; 添加注释与反注释
(global-set-key (kbd "C-c C-b") 'comment-or-uncomment-region)

;; 开启yasnippet
(require 'yasnippet)
(add-to-list 'yas/root-directory "snippets")
(yas-reload-all)

(add-hook 'python-mode-hook
'(lambda ()
(yas-minor-mode)))

;; 好代码一行不应该超过80个字符
(add-hook 'python-mode-hook
(lambda () (highlight-lines-matching-regexp ".\\{81\\}" "red")))

;; 载入模板
(auto-insert-mode) ;;; Adds hook to find-files-hook
(setq auto-insert-directory "~/.emacs.d/mytemplates/") ;;; Or use custom, *NOTE* Trailing slash important
(setq auto-insert-query nil) ;;; If you don't want to be prompted before insertion
(setq auto-insert-alist
(append '((python-mode . "Template.py")
(c-mode . "Template.c")
)
auto-insert-alist)
)

;; 使用%在括号间跳转
(global-set-key "%" 'match-paren)

(defun match-paren (arg)
"Go to the matching paren if on a paren; otherwise insert %."
(interactive "p")
(cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1))
((looking-at "\\s\)") (forward-char 1) (backward-list 1))
(t (self-insert-command (or arg 1)))))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defun goto-match (arg)
(interactive "p")
(let ((stop nil) (c 1) (p-save (point)) (forward t) (self "") (target ""))
(cond ((looking-at "}") (setq forward nil) (setq self "}") (setq target "{"))
((looking-at "{") (setq forward t) (setq self "{") (setq target "}"))
((looking-at ")") (setq forward nil) (setq self ")") (setq target "("))
((looking-at "(") (setq forward t) (setq self "(") (setq target ")"))
((looking-at ">") (setq forward nil) (setq self ">") (setq target "<"))
((looking-at "<") (setq forward t) (setq self "<") (setq target ">"))
((looking-at "\\]") (setq forward nil) (setq self "\\]") (setq target "\\["))
((looking-at "\\[") (setq forward t) (setq self "\\[") (setq target "\\]"))
(t (setq stop t) (setq c -1)))
(while (not stop)
(progn
(if forward (forward-char 1) (backward-char 1))
(cond ((looking-at target) (setq c (1- c)))
((looking-at self) (setq c (1+ c))))
(if (or (= c 0) (= (point) (point-max))) (setq stop t))))
(if (= c -1) (self-insert-command (or arg 1)))
(if (> c 0) (goto-char p-save))))