首页 > IDE, 初级 > Emacs才是世界上最强大的IDE - 用Emaci阅读文件

Emacs才是世界上最强大的IDE - 用Emaci阅读文件

2010年4月12日 ahei 发表评论 阅读评论

相信有很多人平时要阅读大量文件, 而且阅读文件比编辑文件的时间要多的多, 在Emacs里编辑文件的时候, 阅读文件很不方便, 只能用C-v M-v上下滚屏. Emacs下有个view-mode专门是为阅读文件而准备的, 在view-mode里, u向上滚半屏, d向下滚半屏, SPC向下滚一屏, 阅读文件方便多了, 但是还不够, 为什么? 因为经常在阅读文件的时候, 你看到什么不对的地方需要修改, 而在view-mode下, 文件是只读的, 而且有时候, 你在编辑文件的时候, 也需要阅读文件, 那么这两种情况下, 你都要不停的切换view-mode, 非常的不方便, 而且在view-mode里面上下左右移动还得用C-n, C-p, C-f, C-b, 也是非常的不方便, 还有前进一个单词M-f, 后退一个单词M-b, 操作起来都还是很麻烦.

大家都知道vi, 它的快捷键是出名的短, 在vi的命令模式, 上下左右以字符前进是hjkl, 是vi最著名的地方了, 非常方便, 还有它的以单词前进和后退的快捷键w, b, e, 还有好多类似移动光标的命令, 都非常的方便. Emacs下有好多模拟vi的插件, vi-mode就是一个, 它是Emacs内置的, 它模拟了好多vi的特性, 简单的光标移动命令更是当然支持了. 用它来阅读文件的话, 也是不错的, 但是还是有两方面缺点, 一是在vi-mode下好多下, 好多Emacs本身的快捷键就用不了, 比如C-a, C-y等, 二是vi本身固有的缺点(个人观点), 那就是虽然那些快捷键比较短, 但是基本上要在命令模式下运行, 想想, 当你在编辑文件的时候, 想要上下左右移动光标, 然后继续编辑, 再来个上下半屏移动光标, 再来个编辑, 然后再搜索某个单词, 再来个编辑, 就得不停的在编辑模式和命令模式来回切换, 个人觉得非常的不方便, 所以用vi-mode来阅读文件也不是最理想的选择.

鉴于以上理由, 个人自己写了个minor mode, 结合Emacs的优点和部分vi的优点, 所以它的名字Emaci就是由EMACs和vI组成, Emacs占了四个字符, vi却只占了1个字符, 因为Emaci偏向于Emacs的功能更多.

安装好Emaci(只要(require ‘emaci))后, M-x emaci-mode (我把它绑定到了M-s上, 非常方便)进入emaci-mode. 由于大部分情况下打开一个文件浏览的情况比较多, 所以我写了一个函数emaci-exist-file, 这个函数的作用就是判断当前文件是否存在, 存在的话就自动打开emaci-mode, 我把这个函数加到了find-file-hook里面, 这样当你打开一个文件的时候就自动进入了emaci-mode, 打开新文件则不会进入emaci-mode.

进入emaci-mode后, 和vi类似, hjkl上下左右以字符单位移动光标, f, b前进和后退一个单词, I回到行首并且退出emaci-mode, A回到行尾并且退出emaci-mode. 和view-mode类似, u向上滚半屏, SPC向下滚半屏, w向上滚一屏, d向下滚一屏, <和>回到buffer头和buffer尾, 这个也和view-mode一样. g也是回到buffer头, J和K则是向下和向上移动7行, B执行eval-buffer, 1最大化当前window, 2把当前buffer垂直分成两半,3把当前buffer水平非常两半,q退出emaci-mode. 我的配置里,当安装了highlight-symbol后,n向前搜索当前光标处的下一个单词,p则向后搜索,非常方便。这样配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(defun highlight-symbol-settings-for-emaci ()
  "`highlight-symbol' settings for `emaci'."
  (eval-when-compile (require 'cl))
 
;;;###autoload
  (defun emaci-n ()
    "Command bind to key n."
    (interactive)
    (if (edebug-active)
        (edebug-next-mode)
      (if (equal major-mode 'gud-mode)
          (call-interactively 'gud-next)
            (call-interactively 'highlight-symbol-next))))
 
  (define-key-list
    emaci-mode-map
    `(("p" highlight-symbol-prev))))
 
(eval-after-load "emaci"
  `(highlight-symbol-settings-for-emaci))

与vi和view-mode相比最大的差异的地方也是我觉得最方便的地方, 是在emaci-mode下也可以进行一些编辑工作, 比如你在浏览某个文件的时候, 发现某一行不需要, 直接用C-k删除即可, 然后再用C-y复制一下刚才拷贝的东西, 当然同样, 可以删除一个区域, 一个单词, 一个字符, 删除字符还可以用vi中的x命令. 这些编辑操作都不需要你退出emaci-mode, 编辑完之后, 用C-x C-s保存即可. 只有当你需要敲一堆文字的时候, 因为可能会涉及到jkhl等快捷键, 这时候才需要用q退出emaci-mode. 这时候你就想了, 那是不是每次编辑之前还要看一下当前是否开了emaci-mode, 那岂不是非常麻烦? 不用担心, 开启了emaci-mode后, mode-line上会显示一个非常显眼的”Emaci”样, 我特地用白底红字标示出来, 就像这样:

Emaci的mode-line标记


当然,这个颜色你也可以控制的,该颜色是由颜色变量emaci-mode-line-face来控制的。
而且, 我一般把M-s绑定到了emaci-mode-on, M-S绑定到emaci-mode-off上面, 这样, 你想编辑的时候按下M-S, 浏览的时候按下M-s, 即使不用看那个白底红字的”Emaci”字样, 也不会出错的. 这点view-mode就不行, 它和其他的minor mode一样, 都是默认的颜色, 我一般开启了好多minor mode, 这样, 你想编辑的时候, 还得盯着mode-line看半天当前是否打开了view-mode.

emaci还对常用的一些mode, 比如view-mode(所以你如果不喜欢在emaci-mode里面能修改文件, 只想只读的阅读文件的话, 可以考虑view-mode, 它的配置文件在这里), Man-mode, apropos, diff-mode, help-mode等定制了通用的hjkl等方便的快捷键, 这些是通过emaci-brief-key-defs变量来控制的, 这个变量是一个list, list的每一个元素是由两个元素构成的list, 第一个元素是快捷键, 快捷键的写法和kbd宏的参数一样, 第二个参数是该快捷键对应的命令, 这个变量默认值如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(defcustom emaci-brief-key-defs
  `(("h" backward-char)
    ("l" forward-char)
    ("j" next-line)
    ("k" previous-line)
    ("J" roll-down)
    ("K" roll-up)
    ("b" backward-word)
    ("w" am-forward-word-or-to-word)
    ("o" other-window)
    ("G" end-of-buffer)
    ("a" move-beginning-of-line)
    ("e" move-end-of-line))
  "Key pairs used bind in modes `emaci-maps-to-bind-brief-keys'.
 
Each element of this variable is two-elements list, and first
element is key like argument of `kbd', and second element is command."
  :type 'list
  :group 'emaci)

而待绑定这些快捷键的keymap是由变量emaci-maps-to-bind-brief-keys控制的, 其默认值如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
(defcustom emaci-maps-to-bind-brief-keys
  `(view-mode-map
    Man-mode-map
    apropos-mode-map
    completion-list-mode-map
    log-view-mode-map
    compilation-mode-map
    diff-mode-map
    help-mode-map
    ,(if (>= emacs-major-version 21) 'grep-mode-map)
    color-theme-mode-map)
  "List used for `emaci-bind-modes-keys'.
 
Element of this list either a list whose first element is load file,
and second element is map, or a string which means load file, or a map."
  :group 'emaci)

此变量是一个keymap的list, list中的元素是keymap或者是nil。
如果你修改了以上两个变量后, 执行一下M-x emaci-bind-brief-keys使你的修改生效.

Emaci的配置文件在这里,配置如下:

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
;; -*- Emacs-Lisp -*-
 
;; Time-stamp: <2010-04-19 10:15:52 Monday by ahei>
 
(require 'util)
(require 'emaci)
 
(apply-define-key
 global-map
 `(("M-s" emaci-mode-on)
   ("M-S" emaci-mode-off)))
 
(defun emaci-settings ()
  "settings for `emaci'."
  (eal-define-keys
   'emaci-mode-map
   `(("/" describe-symbol-at-point)
     ("'" switch-to-other-buffer)
     ("L" count-brf-lines)
     ("t" sb-toggle-keep-buffer)
     ("." find-symbol-at-point)
     ("," find-symbol-go-back)
     ("]" goto-paren)))
 
  (setq emaci-brief-key-defs
        (append emaci-brief-key-defs
                `(("]" goto-paren))))
  (emaci-bind-brief-keys)
 
  ;;;###autoload
  (defun switch-major-mode-with-emaci ()
    "Run `switch-major-mode' with `emaci-mode'."
    (interactive)
    (let ((emaci emaci-mode))
      (call-interactively 'switch-major-mode)
      (emaci-mode (if emaci 1 -1))))
 
  (eal-define-keys-commonly
   global-map
   `(("C-x q" switch-major-mode-with-emaci))))
 
(eval-after-load "emaci"
  `(emaci-settings))
 
(provide 'emaci-settings)

听完我的介绍, 怎么样, 是不是你也一直期待这样的功能呢, 那赶快试试吧. 这里下载Emaci, Emaci还依赖ahei-misc, eval-after-load两个包,读者均可在DEA里面下载。

分享家:Addthis中国
GD Star Rating
loading...
Emacs才是世界上最强大的IDE - 用Emaci阅读文件, 9.5 out of 10 based on 13 ratings 标签:ahei, autoload, ede, emaci, Emacs, emacser, emacser.com, eval-after-load, face, gud, highlight, highlight-symbol, IDE, keymap, mode-line, screenshot, theme, 光标, 插件, 配色, 颜色

相关日志

分类: IDE, 初级
  1. 小和平鸽
    2010年5月30日05:52 | #1

    用 Emacs 很久以来都是从手册和 emacswiki.org 去学东西,一个意外的机会发现了 emacser.com 阅读下来感觉受益良多。
    这里想和大家探讨一下关于按键绑定的问题。。。希望使用的功能总是越多越好,越方便越好,但是可以绑的按键就是那么
    有限的几个,尤其是需要 global 绑定的时候。比如说我有下面从一开始使用 Emacs 就有的一些绑定
    ;;
    ;; copy paste operations
    (global-set-key (kbd “C-=”) (quote set-mark-command))
    (global-set-key (kbd “C-c l”) (quote copy-line))
    (global-set-key (kbd “C-c w”) (quote copy-word))
    (global-set-key (kbd “C-c a”) (quote copy-string-to-mark))
    (global-set-key (kbd “C-c p”) (quote copy-paragraph))
    (global-set-key (kbd “C-c q”) (quote copy-in-quote-to-mark))
    (global-set-key (kbd “C-c d”) (quote delete-region))
    ;;
    那个 C-c a 原来是绑定在 C-c s 上面的,s stands for string,非常直观,可以拷贝当前光标位置的 string 粘贴到的指
    定的 mark, 如果是在 shel-mode,就直接拷贝粘贴到当前提示符的最后。这样可以节省很多的拷贝粘贴的操作。后来为了模
    拟 vim 里的直接查找当前光标下的word,把这个绑定占用了。这个 copy-string-to-mark 的功能就被挤到了 C-c a 这里了。
    至于为什么使用 C-c a 呢?基本上就是因为,毕竟这俩键是紧挨着的,比较容易记住这个变化。
    ;;
    那么自从升级到了 Emacs 23 以后,大量的在使用 org-mode,那么 org-mode 推荐的一些默认绑定也都是从 C-c a 开始的。
    这个冲突到现在为止我还没有想出合适解决办法。毕竟上面那些绑定的确都是 global 的,我没道理进到 org-mode 以后就
    把他们换掉。所以目前为止还一直都在使用 M-x org-agenda a 这样的方式。最最郁闷的就是需要 M-x org-store-link,
    然后 M-x org-insert-link. 不是一般的不方便。
    ;;
    现在使用 emaci-mode,我就不得不把那个 (add-hook ‘find-file-hook ‘emaci-exist-file) 去掉,因为我目前没法方便
    的在 emaci-mode-on 和 emaci-mode-off 之间进行切换,我的 M-s 被 (anything-isearch-again) 占用了。总之就是说很难
    在使用了大量的各种功能之后还可以方便的找出一些确实方便,易记的按键绑定出来。
    ;;
    ;;
    大家有没有一些这方面的使用经验和体会可以交流一下吗?

    [回复]

    ahei 回复:

    @小和平鸽, 全局的命令比如你的copy-string-to-mark最好用全局的按键prefix,比如C-x,这样冲突就少了.你M-s被占了,你可以换一个其他你认为方便的啊.BTW quote你为啥不用单引号代替.

    [回复]

  2. yswzing
    2010年6月5日14:41 | #2

    使用 viper-mode 的飘过……

    其实楼主所说的 vi 的缺点(虽然个人并不认同)正可以通过 viper-mode 克服。viper-mode 有两种模式,按 ESC 进入 vi 模式,可以用 vi 的所有命令比如 hjkl;退出 vi 模式进入编辑模式后,可以用 emacs 的所有编辑命令比如 C-a, C-v, C-e。

    像楼主所举的编辑的例子,可以进入 emacs 编辑模式,然后全部使用 emacs 快捷键完成全部修改,再按 ESC 退出到 vi 模式,方便的用 hjkl 来 view。

    [回复]

    ahei 回复:

    @yswzing, 呵呵,我文中说了,我觉得来回切换非常麻烦.我的emaci可以在不需要退出emaci-mode,照样可以使用emacs自己的编辑功能

    [回复]

  3. yswzing
    2010年6月6日01:27 | #3

    楼主的 emaci-mode 在需要较多编辑操作时不需要切换吗?如果我没有理解错的话,你文中的意思是说在做较简单的编辑比如 C-k/C-y 时,可以直接在 emaci-mode 下完成;而如果需要较复杂的编辑,还是需要退出 emaci-mode。在我看来,这和 viper-mode 没有任何区别(除了快捷键不同,或许你的重点在此?)。

    楼主可能没有用过 vi,vi 在命令模式下也可以做编辑。从你文中所述功能来看,没有哪个是 viper-mode 做不到的,并且切换也不比 viper-mode 的少。

    当然,楼主的快捷键还是比较有特色的,很适合文本浏览。

    [回复]

    yswzing 回复:

    @yswzing,
    点错回复位置了,楼主勿怪啊

    [回复]

    ahei 回复:

    @yswzing, emaci-mode与viper-mode的不同处,也是我认为方便的地方在于:
    1. 在emaci-mode和emacs的正常编辑模式下切换非常方便,M-s和q
    2. mode-line上显示非常明显的标志,让你一眼能看到emaci-mode是否开着了
    3. 在emaci-mode下照样可以用emacs里面的快捷键,但是在viper-mode下却不能使用emacs正常编辑下的某些快捷键,比如C-a, C-y等,文中也说明了
    当然以上3点,应该也可以通过定制让viper-mode也能做到,不过可能就麻烦了点了.

    [回复]

    yswzing 回复:

    @ahei,
    > 1. 在emaci-mode和emacs的正常编辑模式下切换非常方便,M-s和q

    viper-mode 切换更方便:ESC(我一般把 CapsLock 当作 ESC 用)进入 viper-mode,I/A/i/a/s/S/C 等有无数键均可以进入编辑模式。当然,这么多键可能会吓住一些人,只记住 ESC 和 i 即可。

    > 2. mode-line上显示非常明显的标志,让你一眼能看到emaci-mode是否开着了

    viper-mode 和正常编辑 mode 的光标不同,一眼就可以看出,当然你可能一下找不到光标,如果是这样的话,还是 emaci-mode 方便一些。建议 emaci-mode 在浏览和编辑的时候可以把光标的形状换一下。

    > 3. 在emaci-mode下照样可以用emacs里面的快捷键,但是在viper-mode下却

    不能使用emacs正常编辑下的某些快捷键,比如C-a, C-y等,文中也说明了
    viper-mode 可以使用 C-a/C-e 等,但是一般在 viper-mode 下有更好的快捷键,你所说的 C-a 可以用 0 代替,C-y 可以用 p 代替。

    如果考虑定制的话,viper-mode 可以任意调整快捷键设置,比如你可以在命令模式下使用大部分的 vi 快捷键+一些方便的 emacs 快捷键,在编辑模式下使用全部的 emacs 快捷键。

    [回复]

    ahei 回复:

    @yswzing, 1. Emacs的按键定制坚持这样的原则,宁愿多用一些离键盘中心比较近的键,也不少用一些离键盘中心比较远的键,这点我非常喜欢,所以我非常不喜欢按那个ESC键,ESC键在有些键盘上特别远.在vi里面你可以试试C-c,99%的情况下可以代替ESC

    2. 目前cursor-change只在只读和可写两种状态下切换, 而且emaci-mode下其实是可写的, 所以切不切换光标状态是有争议的.你可以自己定制一下curchg-change-cursor-on-overwrite/read-only函数,等我有空的时候我加个切换光标的条件的变量,这样用户更方便的定制了.

    3. 你这样的话,用户按C-a C-y之前还要考虑是否在viper-mode下,而是否在viper-mode下还不是很容易看的出来,我想这样会严重降低用户体验的,你觉得呢.我写emaci-mode下一个非常重要的目的就是让用户不必区分是否在emaci-mode下,而可以使用Emacs正常编辑下的快捷键,因为像C-a C-y等快捷键还是非常方便的,我个人觉得C-a比0方便,还是因为C-a离键盘中心更近的原因,如果你把capslock和右ctrl键交换过了的话, 会更方便的.

    [回复]

    匿名 回复:

    @ahei,
    说到快捷键的方便程度,就仁者见仁,智者见智了,这个跟个人习惯有关。我个人一般是能用单键的不用组合键,所以我用 CapsLock 替代 ESC,而不是用 C-c 替代 ESC。

    对于不用 viper-mode 的人(应该占绝大部分)来说,楼主的 emaci-mode 还是非常方便的。不用学习一套新的键绑定,只要记住几个快捷键就行了。其中 Space/u/d 翻页还是很酷的。

    [回复]

    ahei 回复:

    @, 呵呵,你用capslock代替ESC,是方便了,但是你其他control的快捷键就不方便了啊,毕竟在Emacs下还是有非常多的以control开头的键.emaci的快捷键和less比较象,我非常喜欢,浏览起来非常方便.

    [回复]

    jayklx 回复:

    @,
    vi来说C-[绝对是王道啊~两个小拇指轻轻一点,就ok了~比esc好按多了, 也更加通用(esc在一些时候会失效)
    我觉得提esc提的太多了,导致很多人都忽略了C-[

    [回复]

    ahei 回复:

    @jayklx, 比C-c好用?

    [回复]

    jayklx 回复:

    @blizz,
    差不多吧,我比较习惯C-[
    小拇指平常一个放在A上,另一个放在L上, 两个稍微挪一点点就行了, C-c我映射成关闭
    窗口了
    很多终端上C-[是等同于esc的, 这样还是有点好处的吧..

    [回复]

  4. yswzing
    2010年6月6日03:44 | #4

    不小心搞成匿名了:)

    [回复]

  5. 凌狐
    2010年6月30日01:57 | #5

    在emaci-mode下编辑操作和浏览操作会有一些不方便。
    比如在这个模式下,我想输入文本”copyright”,其中文本p, g, h会与vi中的命令有冲突。

    在emaci-mode下,我现在只想要“浏览(jkhlaegG…..) +粘贴删除等(C-k, C-y, delete, backspace….)”, 即禁止在该模式下输入文本字符,请问我该如何设置呢?

    [回复]

    ahei 回复:

    @凌狐, emaci就是这样设计的,你如果想那样的话,你直接用view-mode就可以了

    [回复]

    凌狐 回复:

    @ahei, view-mode下缺少直接粘贴和删除的功能

    [回复]

    ahei 回复:

    @凌狐, 哈哈,那你既然知道这个,就应该知道了为啥输入某些未绑定的字母键能修改buffer了吧?你别按错不就是了,而且在emaci可以输入中文,多爽阿

    [回复]

    凌狐 回复:

    @ahei, emaci-mode哪都好,就是这点让我抓狂.
    It’s a real pain in the neck. That always makes me awful.

    jkhlaedxgGnpo这么多vi命令. 当你输入文本的时候能一下子反应过来吗? 有没有办法
    禁止非命令字符的输入, 当输入这些东西的时候提示无效? 请明示.

    [回复]

    ahei 回复:

    @凌狐, 你输入英文文本的时候用q退出emaci-mode不就行了吗?

    [回复]

    凌狐 回复:

    @ahei, q退出emaci-mode是一个解决方法.
    不过我的问题是这样的, 经常忘记开了emaci-mode, 即使它很人性化的显示为红色.
    当我文本输入的时候, 比方说输入”right”, ri是上屏了,可g命令又使光标到了文件头,
    而且在此写入了后面的字符.
    鉴于我的忘事,我想改emaci-mode为”基本的vi浏览命令(jkhlaegG…) +
    删除粘贴命令(C-k, C-y, delete…)”, 而且明确禁用非vi命令的文本输入, 并提示我
    此模式下不能输入, 需要q退出.
    我该如何禁用文本输入呢, 你有什么建议吗?

    [回复]

    ahei 回复:

    @凌狐, 忘了的话,就还原一下吧,很方便的。你可以把buffer设置成只读的,然后定义一些删除的命令,这些命令首先把buffer改成可写的,删除完后再改成只读的就可以了。

    [回复]

  6. weikent
    2011年12月20日22:02 | #6

    楼主,
    我看到你的配置文件中的 dot-mode 可以模拟vi的”.”。 我搜索配置文件,发现按键”.” 对应命令”emaci-.”。 但我找不到”emaci-.” 到定义。请问”emaci-.” 是在那里定义的。或者这个按键”.”是如何模拟的vi中到”.”。

    谢。

    [回复]

    ahei 回复:

    @weikent, 你仔细看下dot-mode的使用说明

    [回复]

  7. 2013年4月26日17:57 | #7

    我尝试修改emaci.el 增加功能发现不行啊. 我想自己映射某些键.却不生效.求教如何修改

    [回复]

评论分页
1 2 41107
  1. 2010年4月26日07:29 | #1
  2. 2010年5月12日09:42 | #2
:wink: :-| :-x :twisted: :) 8-O :( :roll: :-P :oops: :-o :mrgreen: :lol: :idea: :-D :evil: :cry: 8) :arrow: :-? :?: :!: