8.2. 程序风格设置

每个人都有自己喜欢的程序风格,例如我就喜欢用 tab 而不是space ,下面是我的配置:

8.2.1. XML

目前的 Emacs 已经使用 nxml-mode作为默认的 xml 文件模式了,所以只需修改一下 tab 的使用就可以了。

(add-hook 'nxml-mode-hook (lambda ()
                           (setq tab-width 4)
                           (setq-default indent-tabs-mode t)
                           (local-set-key (kbd "RET") 'newline-and-indent)))
(setq nxml-child-indent 4)

8.2.2. C

个人比较喜欢 Linux Kernel 代码风格,在 Emacs 设置也比较简单。

(defun c-lineup-arglist-tabs-only (ignored)
  "Line up argument lists by tabs, not spaces"
  (let* ((anchor (c-langelem-pos c-syntactic-element))
         (column (c-langelem-2nd-pos c-syntactic-element))
         (offset (- (1+ column) anchor))
         (steps (floor offset c-basic-offset)))
    (* (max steps 1)
       c-basic-offset)))

(add-hook 'c-mode-common-hook
          (lambda ()
            (c-add-style
             "linux-tabs-only"
             '("linux" (c-offsets-alist
                        (arglist-cont-nonempty
                         c-lineup-gcc-asm-reg
                         c-lineup-arglist-tabs-only))))))

(add-hook 'c-mode-hook
          (lambda ()
            (let ((filename (buffer-file-name)))
              (when (and filename
                         (string-match (expand-file-name "~/Projects")
                                       filename))
                (setq indent-tabs-mode t)
                (c-set-style "linux-tabs-only")))))    

8.2.3. JavaScript

javascript 程序的开发需要安装一个 emacs 的扩展程序,通过 svn checkout 最新的代码,并编译它。

$ svn checkout http://js2-mode.googlecode.com/svn/trunk/ js2-mode
$ cd js2-mode/

这里可能需要修改一个 Makefile 文件,改后内容如下:

EMACS=emacs
BUILD=-batch -q -l js2-build.el -f js2-build-js2-mode

all:
    $(EMACS) $(BUILD)

编译完成后,将下面的文件复制到 emacs 的相关目录。

$ make
$ sudo cp build/js2-mode.el* /usr/share/emacs/site-lisp/

下载文件 espresso.el,并也复制到 emacs 的相关目录。

$ wget http://download.savannah.gnu.org/releases-noredirect/espresso/espresso.el
$ sudo cp espresso.el /usr/share/emacs/site-lisp/

修改 ~/.emacs 文件,增加下面的内容。

;;------------------------------------------------------------------------------------;;
;; javascript mode
(autoload 'js2-mode "js2-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.js$" . js2-mode))
(autoload 'espresso-mode "espresso")

(defun my-js2-indent-function ()
  (interactive)
  (save-restriction
    (widen)
    (let* ((inhibit-point-motion-hooks t)
           (parse-status (save-excursion (syntax-ppss (point-at-bol))))
           (offset (- (current-column) (current-indentation)))
           (indentation (espresso--proper-indentation parse-status))
           node)

      (save-excursion

        ;; I like to indent case and labels to half of the tab width
        (back-to-indentation)
        (if (looking-at "case\\s-")
            (setq indentation (+ indentation (/ espresso-indent-level 2))))

        ;; consecutive declarations in a var statement are nice if
        ;; properly aligned, i.e:
        ;;
        ;; var foo = "bar",
        ;;     bar = "foo";
        (setq node (js2-node-at-point))
        (when (and node
                   (= js2-NAME (js2-node-type node))
                   (= js2-VAR (js2-node-type (js2-node-parent node))))
          (setq indentation (+ 4 indentation))))

      (indent-line-to indentation)
      (when (> offset 0) (forward-char offset)))))

(defun my-js2-mode-hook ()
  (require 'espresso)
  (setq espresso-indent-level 4
        indent-tabs-mode nil
        c-basic-offset 4)
  (c-toggle-auto-state 0)
  (c-toggle-hungry-state 1)
  (set (make-local-variable 'indent-line-function) 'my-js2-indent-function)
  (define-key js2-mode-map [(meta control |)] 'cperl-lineup)
  (define-key js2-mode-map [(meta control \;)] 
    '(lambda()
       (interactive)
       (insert "/* -----[ ")
       (save-excursion
         (insert " ]----- */"))
       ))
  (define-key js2-mode-map [(return)] 'newline-and-indent)
  (define-key js2-mode-map [(backspace)] 'c-electric-backspace)
  (define-key js2-mode-map [(control d)] 'c-electric-delete-forward)
  (define-key js2-mode-map [(control meta q)] 'my-indent-sexp)
  (if (featurep 'js2-highlight-vars)
    (js2-highlight-vars-mode))
  (message "My JS2 hook"))

(add-hook 'js2-mode-hook 'my-js2-mode-hook)

上面的设置是 4 个空格的缩进,重启 emacs ,用 C+h 全选文件,然后 C+M+\ 格式话整个文件。

参考文档

8.2.4. 中文的 Unicode 编码

开发 Java 程序,需要将 properties 文件中的中文自动转化为 Unicode 编码,可以安装一个 emacs 的扩展程序 native2ascii.el

将这个文件复制到 /usr/share/emacs/site-lisp/目录。然后修改 ~/.emacs文件。

(load "native2ascii.el"