Emacs

Emacs

Table of Contents:

What is GNU Emacs?
配置 Emacs
我的配置文件
在中文和英文之间加上空格
关于 Emacs 的字体
Sub-pages
emacs-wiki
Muse

What is GNU Emacs?

Emacs 是什么?没听说过这句话么:“宇宙里有三种人,第一种是用 Emacs 的人, 第二种是用 Vim 的人,第三种人用其它编辑器...”(不过按照 Google 黑板报里 某篇日志的说法,在第三种人之前还有一种人是用 Eclipse 的。)

GNU Emacs 是 Richard Stallman 编写的强力文本编辑器。最新的 Release 版 本是 21.4(FIX: 貌似现在已经发布了 22 版)。

配置 Emacs

我的配置文件

把我的 emacs 配置拿出来 show 一下 ~,附带解说 

;; Time-stamp: <corsair 2007-05-14 15:22:04>

;; =============== add load path ====================>
(add-to-list 'load-path "~/.emacs.d")
(add-to-list 'load-path "~/.emacs.d/maxima-mode")
(add-to-list 'load-path "~/.emacs.d/dictionary")
;; (add-to-list 'load-path "~/.emacs.d/emacs-wiki")
;; (add-to-list 'load-path "~/.emacs.d/emacs-wiki/contrib")
(add-to-list 'load-path "~/.emacs.d/slime-2.0")
(add-to-list 'load-path "~/.emacs.d/slime48")
(add-to-list 'load-path "~/.emacs.d/muse")
;; (add-to-list 'load-path "~/.emacs.d/emms")

我的 load-path 们,我下载的扩展基本上都装在 ~/.emacs.d 里 了,有几个自己提供了安装程序的扩展除外(比如 AUCTeX)。

(custom-set-variables
  ;; custom-set-variables was added by Custom.
  ;; If you edit it by hand, you could mess it up, so be careful.
  ;; Your init file should contain only one such instance.
  ;; If there is more than one, they won't work right.
 '(auto-save-default nil)
 '(c-syntactic-indentation t)
 '(c-tab-always-indent t)
 '(canlock-password "8225634b21d31eaa687444f4d1e696bab28e0b26")
 '(case-fold-search t)
 '(column-number-mode t)
 '(debug-on-error t)
 '(default-input-method "chinese-py-punct")
 '(display-time-mode t)
 '(fringe-mode (quote (16 . 0)) nil (fringe))
 '(global-font-lock-mode t nil (font-lock))
 '(indicate-buffer-boundaries
    (quote ((t . left) (top . left) (bottom . left)
            (up . left) (down . left))))
 '(safe-local-variable-values (quote ((todo-categories "daily"))))
 '(tab-width 4)
 '(transient-mark-mode t))

以上都是在 emacs 的 customize 界面里设置的,用 setq 可以达 到同样的效果。其中特别有用的是 c-tab-always-indent 这个东 西。设成 t 以后在写代码的时候无论在何时何地一按 Tab,立马按照语法缩进当 前行,如果要插入一个 Tab 宽度的空白的话可以用 M-i。另外那个 global-font-lock-mode 比较有迷惑性。它既可以是一个变量,也 可以是一个函数。在线文档里说你设 global-font-lock-mode这个 变量为 non-nil 是没有用的,必须要在 customize 里设,又或者调用这个函数 并传入三个参数(customize 干的其实就是这个),设了这个东西以后就会有代 码加亮。最后,那个transient-mark-mode 可以高亮显示出当前选 中的区域。

;; =============== Coding and Language ===============>
(set-selection-coding-system 'utf-8)
(set-clipboard-coding-system 'utf-8)
(set-keyboard-coding-system 'utf-8)
(set-language-environment 'utf-8)
(setq locale-coding-system 'utf-8)
(setq current-language-environment "utf-8")
(setq locale-language-names
      (cons '("zh_CN.UTF-8" "UTF-8" utf-8) locale-language-names))

;; Fix the width of Chinese marks.
(let ((l '(chinese-gb2312
           gb18030-2-byte
           gb18030-4-byte-bmp
           gb18030-4-byte-ext-1
           gb18030-4-byte-ext-2
           gb18030-4-byte-smp)))
  (dolist (elt l)
    (map-charset-chars #'modify-category-entry elt ?|)
    (map-charset-chars
     (lambda (range ignore)
       (set-char-table-range char-width-table range 2))
     elt)))

这一段是关于语言的设置,注意我的 emacs 版本是 23,对 unicode 有极好的 支持,如果是 21 版可能需要将编码设为 gbk 或 gb2312。

;;=========== Some basic settings ==============================>
(setq user-full-name "Corsair")
(setq user-mail-address "chris.corsair@gmail.com")
(setq default-major-mode 'text-mode) ; Use text-mode as default mode
                                     ; instead of fundermantle-mode.
(setq default-tab-width 4)
(setq tab-width 4)
(setq-default indent-tabs-mode nil) ; Make _Tab_ indent in some modes.
(setq column-number-mode t)     ; Display column number in modeline.
(setq kill-ring-max 255)        ; 255 available undo-s. :-p
(setq next-screen-context-lines 5) ; Begin scrolling when the cursor
                                   ; is 5 lines from the bottom.
(setq display-time-day-and-date t) ; Display current time and date in
                                   ; modeline.
;; Mark some symbols as end of sentences.
(setq sentence-end "\\([。!?;]\\|……\\|[.?!;][]\"')}]*\\($\\|[ \t]\\)\\)[ \t\n]*")
(setq sentence-end-double-space t) ; Use 2 spaces between sentences.
(setq frame-title-format "Corsair's GNU Emacs23 <%b>")
(setq scroll-margin 4
      scroll-conservatively 1000) ; continuous scrolling
;; Set the pattern that might be used as line start.
(setq adaptive-fill-regexp "[ \t]+\\|[ \t]*\\([0-9]+\\.\\|\\*+\\)[ \t]*")
;; This is really a dirty setting.  DO NOT use it!
(setq tab-stop-list
      '(4 8 12 16 20 24 28 32 36 40 44 48 52 56 60 64
        68 72 76 80 84 88 96 100 104 108 112 116 120))
;; let the delete key delete foreward
(if window-system (normal-erase-is-backspace-mode 1))

;; Display time information in modeline.
(setq display-time-format "%Y-%m-%d %A %I:%M")
(display-time)
;; Enable `auto-fill-mode' which can wrap lines for you.  Very handy.
(add-hook 'text-mode-hook
          (lambda () (auto-fill-mode t)))

(setq require-final-newline t)  ; Add a newline at the end of file if none.

;; Use time stamps
(add-hook 'write-file-hooks 'time-stamp)
(setq time-stamp-active t)
(setq time-stamp-format "%:u %04y-%02m-%02d %02H:%02M:%02S")
(setq time-stamp-end: "\n")

;;所有的 yes or no 全都用 y or n 代替 :-)
(fset 'yes-or-no-p 'y-or-n-p)
;; Turn on auto save function
(setq auto-save-default t)
;; Enable Narrow
(put 'narrow-to-region 'disabled nil)
;; 鼠标要挡住正在打的字时自动移开
(mouse-avoidance-mode 'animate)

(auto-image-file-mode)
;; Replace selected text when typing
(delete-selection-mode t)
;; Default input method for `C-\'
(setq default-input-method "TeX")
;; Remove toolbar...
(tool-bar-mode 0)
;; Use external `ls' rather than `ls-lisp'.
(setq ls-lisp-use-insert-directory-program t)
;; No sound alarm!
(setq visible-bell t)

以上是一些乱七八糟的设置,都有注释。其中值得一提的是我把 TeX 输入法作 为了默认输入法,用 C-\ 就可以直接调用。通过这个输入法可以用 TeX 命令输入一 些特殊符号。比如输入 \Omega 就会出来 Ω,简直太爽了  :-p。

;; printer settings
(setq printer-name "PDFPrinter")
(setq ps-font-size '(7 . 8))
(setq ps-multibyte-buffer 'bdf-font-except-latin)
(setq ps-paper-type 'a4)
(setq ps-number-of-columns 1)

设置打印。我用了一个生成 pdf 的虚拟打印机。

;; Scheme program
(setq scheme-program-name "mzscheme")

设置 run-scheme 函数调用的 scheme 解释器。

;;===========CC ah=======================>
(add-hook 'c-mode-common-hook
          (lambda () (c-toggle-auto-hungry-state 1)))

;;-----------CC Indention-----------------
(defconst my-c-style
  '((c-tab-always-indent        . t)
    (c-comment-only-line-offset . 0)
    (c-hanging-braces-alist     . ((substatement-open after)
                                   (brace-list-open)))
    (c-hanging-colons-alist     . ((member-init-intro before)
                                   (inher-intro)
                                   (case-label after)
                                   (label after)
                                   (access-label after)))
    (c-cleanup-list             . (scope-operator
                                   empty-defun-braces
                                   defun-close-semi))
    (c-offsets-alist            . ((arglist-close . c-lineup-arglist)
                                   (substatement-open . 0)
                                   (case-label        . 4)
                                   (block-open        . 0)
                                   (knr-argdecl-intro . -)))
    (c-echo-syntactic-information-p . t)
    )
  "My C Programming Style")

;; offset customizations not in my-c-style
(setq c-offsets-alist '((member-init-intro . ++)))

;; Customizations for all modes in CC Mode.
(defun my-c-mode-common-hook ()
  ;; add my personal style and set it for the current buffer
  (c-add-style "PERSONAL" my-c-style t)
  ;; we like auto-newline and hungry-delete
  (c-toggle-auto-hungry-state 1)
  ;; key bindings for all supported languages.  We can put these in
  ;; c-mode-base-map because c-mode-map, c++-mode-map, objc-mode-map,
  ;; java-mode-map, idl-mode-map, and pike-mode-map inherit from it.
  (define-key c-mode-base-map "\C-m" 'c-context-line-break)
  )

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

设置 c/c++ 模式的缩进风格,没什么好说的,直接从在线文档里剽窃。

;;Auto Show Matching Brace
(require 'paren)
(show-paren-mode 1)

这个可以高亮当前匹配的括号,就像这样:

(if (not window-system) nil
  ;;========= color themes ==================================>
  (require 'color-theme)
  ;; (color-theme-subtle-hacker)
  ;; (color-theme-charcoal-black)
  ;; (color-theme-dark-blue2)
  (color-theme-deep-blue)
  ;; (color-theme-hober)
  ;; (color-theme-kingsajz)

  ;;============ Enable TabBar =========================>
  (require 'tabbar)
  (tabbar-mode)
  ;; (global-set-key (kbd "") 'tabbar-backward-group)
  ;; (global-set-key (kbd "") 'tabbar-forward-group)
  ;; (global-set-key (kbd "") 'tabbar-backward)
  ;; (global-set-key (kbd "") 'tabbar-forward)
)

设置 color-theme 和 Tabbar。color-theme 是个造福人类的好东西,可以一次 整个的更改 Emacs 的颜色,而且提供了很多的配色方案(挑得我累死了...)。 Tabbar 会在当前 buffer 的上方显示一个 tabbar(-_-!),可以方便的切换到 使用相同的 major mode 的其它 buffer。具体是什么样,看[[img/shots/emacs.png][截图]吧 

;;========== htmlize =================================>
(require 'htmlize)

htmlize 可以把一个文件或 buffer 输出成 html,带加亮的。

;;=============== ibuffer ===========================>
(require 'ibuffer)
(global-set-key (kbd "C-x C-b") 'ibuffer)

ibuffer 是个好东西,它可以列出所有的 buffer 并提供批量操作。

;;============ hippie-expand (M-/) ========================>
(setq hippie-expand-try-functions-list
      '(try-expand-dabbrev
    try-expand-dabbrev-visible
    try-expand-dabbrev-all-buffers
    try-expand-dabbrev-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))

上面这一段可以增强 _M-/_ hippie-expand 的功能。从王垠这里抄的。

;; ============== CSS Mode ====================>
(autoload 'css-mode "css-mode")
(setq auto-mode-alist
     (cons '("\\.css\\'" . css-mode) auto-mode-alist))

Css mode 是用来写 css 的 major mode.

;; =============== Spell Checking ====================>
(setq-default ispell-program-name "aspell")
(add-hook 'text-mode-hook 'flyspell-mode)

使用 aspell 来作拼写检查,把 word 的那个垃圾功能忘了吧。

;; =============== Version Control Settings ==========>
(setq vc-default-init-version "1.0")
;; Read an inicial comment for the registering file
(setq vc-initial-comment t)
(setq vc-command-messages t)
(setq vc-register-switches "-x/,v")

版本控制系统,在写一些比较大的程序的时候会用到,当然前提是你的系统里要 有 RCS, cvs 或 svn 什么的。

;; =============== Shell Mode settings ===============>
(setq comint-scroll-to-bottom-on-input t)
(setq comint-prompt-read-only t)
;; Do not save a input into history if it is the same as the last one.
(setq comint-input-ignoredups t)

Emacs 里的 shell 环境是很方便的。 comint-scroll-to-bottom-on-input 这个变量设为 non-nil 以 后在 shell 里一开始打字就自动跳到提示符后面。 comint-prompt-read-only 使你不会一不小心傻乎乎地把提示符 都删掉了 。

;; =============== add other file ====================>
(load-file "~/.emacs-calendar.el")
(load-file "~/.emacs-erc.el")
(load-file "~/.emacs-dict.el")
(load-file "~/.emacs-slime.el")
(load-file "~/.emacs-muse.el")

其它的配置文件。

(if (not window-system) nil
  ;; =============== reset main frame's size ==============>
  (custom-set-faces
   ;; custom-set-faces was added by Custom.
   ;; If you edit it by hand, you could mess it up, so be careful.
   ;; Your init file should contain only one such instance.
   ;; If there is more than one, they won't work right.
   '(hl-line ((t (:inherit highlight :background "#16406c"))))
  (set-frame-size (car (frame-list)) 90 36)
  ;; Font setting
  (set-fontset-font "fontset-default"
                    'gb18030 '("STXihei" . "unicode-bmp"))
)

如果是在图形界面下运行的话,就启用当前行的高亮,设置窗口大小,并设置字 体。

(require 'printing)
(pr-update-menus)
;; (require 'fvwm-mode)
(require 'ascii-table)

;; Restore previous session
(require 'session)
(add-hook 'after-init-hook 'session-initialize)

;; AucTEX
(load "auctex.el" nil t t)
(load "preview-latex.el" nil t t)

(require 'two-mode-mode)
(require 'asy-mode)

PS:写完这一节才发现我的 .emacs 里有好多重复和矛盾的地方,晕...

在中文和英文之间加上空格

如果你和我一样喜欢在中文和英文中间加一个空格,下面这个函数可能有用。

(defun insert-space-between-eng-cn ()
  "Insert a space between English words and Chinese charactors"
  (interactive "")
  (beginning-of-buffer)
  (while (re-search-forward "\\(\\cc\\)\\([a-zA-Z]\\)" nil t)
    (replace-match "\\1 \\2" nil nil))
  (beginning-of-buffer)
  (while (re-search-forward "\\([a-zA-Z]\\)\\(\\cc\\)" nil t)
    (replace-match "\\1 \\2" nil nil))
;; 去掉全角标点与英文之间的空格
  (beginning-of-buffer)
  (while (re-search-forward "\\([。,!?;:“”()]\\) \\([a-zA-Z]\\)" nil t)
    (replace-match "\\1\\2" nil nil))
  (beginning-of-buffer)
  (while (re-search-forward "\\([a-zA-Z]\\) \\([。,!?;:“”()]\\)" nil t)
    (replace-match "\\1\\2" nil nil)))

(global-set-key (kbd "C-c C-r") 'insert-space-between-eng-cn)

这个东西还没怎么测试过,目前来看工作基本良好,除了使用后光标会跳到文件 的结尾... 谁能教我怎么用 set-mark-command 这个函数?按照 info 里的说法,它既能设置一个 mark,也能跳到以前设置的 mark,似乎可以解 决这个问题。

关于 Emacs 的字体

在 Windows 下用 Emacs 的同学请跳过此节...

现在都 21 世纪了,可是 Emacs 默认还是没有字体平滑(又名反锯齿或 anti-alias)。要开启字体平滑有两个办法(只适用于 23 版的 GNU Emacs,并 且假设你在 fonts.conf 里已经打开了 anti-alias):

  1. 重新编译 Emacs,编译时打开 xft 支持。
  2. 请别人帮你编译 Emacs,编译时打开 xft 支持。

下面介绍第一种方法。步骤如下:

# export CVS_RSH="ssh"
# cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs \
  co -r emacs-unicode-2 emacs
$ ./configure --with-gtk --enable-font-backend --with-xft
$ make bootstrap
$ make info
# make install

完成后用如下的命令行启动:

$ emacs --enable-font-backend -fn "Font name-size"

这样启动时就能看到英文已经有 anti-alias 了,但是中文还是难看的宋体(怎 么就有那么多人喜欢那个 simsun 呢...)。还记得我的 .emacs 有这么一行么:

(set-fontset-font "fontset-default"
                  'gb18030 '("STXihei" . "unicode-bmp"))

这是把华文细黑设成了中文的默认字体,效果么... 还是看截图。我觉得和苹果 上的 Aquamacs 有一拼 :-p

在网上看到很多人说可以把 FontBackendFont 资源加到 .Xresources 中,这样启动时就不用带参数了,但是在 我这里 FontBackend 资源没有作用... 大家自己试吧。


Sub-pages

emacs-wiki

以 Wiki 的形式管理文档,可以发布为 xhtml。

Muse

emacs-wiki 更 NB 的文档写作和发布环境。

行版吧...
  • CVS 一个 23 版的 Emacs:
  • # export CVS_RSH="ssh"
    # cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/emacs \
      co -r emacs-unicode-2 emacs
    
    $ ./configure --with-gtk --enable-font-backend --with-xft
    $ make bootstrap
    $ make info
    # make install
    

    完成后用如下的命令行启动:

    $ emacs --enable-font-backend -fn "Font name-size"
    

    这样启动时就能看到英文已经有 anti-alias 了,但是中文还是难看的宋体(怎 么就有那么多人喜欢那个 simsun 呢...)。还记得我的 .emacs 有这么一行么:

    (set-fontset-font "fontset-default"
                      'gb18030 '("STXihei" . "unicode-bmp"))
    

    这是把华文细黑设成了中文的默认字体,效果么... 还是看截图。我觉得和苹果 上的 Aquamacs 有一拼 :-p

    在网上看到很多人说可以把 FontBackendFont 资源加到 .Xresources 中,这样启动时就不用带参数了,但是在 我这里 FontBackend 资源没有作用... 大家自己试吧。


    Sub-pages

    emacs-wiki

    以 Wiki 的形式管理文档,可以发布为 xhtml。

    Muse

    emacs-wiki 更 NB 的文档写作和发布环境。