LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1051|回复: 0

Emacs的auto-newline功能试用

[复制链接]
发表于 2006-4-24 09:27:10 | 显示全部楼层 |阅读模式
如果你的 Emacs 版本够新的话,你可以打开 auto-newline 功能:

  1. (add-hook 'c-mode-common-hook
  2.           (lambda ()
  3.             (c-toggle-auto-newline 1)))
复制代码

这就是最基本的 auto-newline 功能,他会根据当前的键入自动判断是否需要换
行并在需要的时候自动换行并缩进。这个功能默认的地方有几处还不好用,比如
你定义一个 class 的时候,输入末尾的 } ,按理说应该再输入一个 ; 才对,
可是 Emacs 这个时候已经自动换行了。还有就是比如要写:

  1. int foo[] = {0};
复制代码

但是当你写到 { 的时候 Emacs 就换到下一行了,这些都是需要好好配置一下的。
herberteuler提供了他
的配置文件如下:

  1. (defvar xgp-cfsi-left-PAREN-old nil
  2.   "Command used to input "("")
  3. (make-variable-buffer-local 'xgp-cfsi-left-PAREN-old)

  4. (defun xgp-cfsi-modify-alist (alist term new)
  5.   (let ((tl (assq term (symbol-value alist))))
  6.     (if tl
  7.         (setcdr tl new)
  8.       (add-to-list alist (cons term new)))))

  9. (defun xgp-cfsi (style)
  10.   "Deciding whether using CFSI."
  11.   (interactive "sStyle: ")

  12.   (if (equal style "bsd")

  13.       (progn  
  14.         (c-set-style "bsd")
  15.         (setq indent-tabs-mode
  16.               t
  17.               c-hanging-braces-alist
  18.               (quote ((defun-open after)
  19.                       (defun-close after)
  20.                       (brace-list-open after)
  21.                       (brace-list-close)
  22.                       (brace-entry-open after)
  23.                       (statement-cont after)
  24.                       (substatement-open after)
  25.                       (block-close . c-snug-do-while)
  26.                       (extern-lang-open after)
  27.                       (namespace-open after)
  28.                       (module-open after)
  29.                       (composition-open after)
  30.                       (inexpr-class-open after)
  31.                       (inexpr-class-close after)
  32.                       (class-open after)
  33.                       (class-close)))
  34.               c-hanging-colons-alist
  35.               (quote ((label after)
  36.                       (case-label after)
  37.                       (access-label after)))
  38.               c-hanging-semi&comma-criteria
  39.               (quote (c-semi&comma-inside-parenlist)))
  40.         (local-set-key " " 'xgp-cfsi-bsd-SPC))

  41.     (progn  (c-set-style style)
  42.             (setq indent-tabs-mode
  43.                   nil
  44.                   c-hanging-colons-alist
  45.                   (quote ((label after)
  46.                           (case-label after)
  47.                           (access-label after)))
  48.                   c-hanging-semi&comma-criteria
  49.                   (quote (c-semi&comma-inside-parenlist)))
  50.             
  51.             ;CLASS-CLOSE
  52.             (xgp-cfsi-modify-alist 'c-hanging-braces-alist 'class-close nil)
  53.             (local-set-key " " 'self-insert-command)

  54.             ;In GNU style, '(' is always after ' '
  55.             (if (and (equal style "gnu") (not xgp-cfsi-left-PAREN-old))
  56.                 (progn (setq xgp-cfsi-left-PAREN-old
  57.                              (lookup-key (current-local-map) "("))
  58.                        (local-set-key "(" 'xgp-cfsi-gnu-PAREN)))))
  59.   
  60.   ;this is correct since ONLY GNU style put a ' ' before '('
  61.   (if (and (not (equal style "gnu")) xgp-cfsi-left-PAREN-old)
  62.       (progn (local-set-key "(" xgp-cfsi-left-PAREN-old)
  63.              (setq xgp-cfsi-left-PAREN-old nil))))

  64. (defun xgp-cfsi-bsd-SPC ()
  65.   (interactive)
  66.   (if (looking-back "^[ \t]*}[ \t]*\n[ \t]*$")
  67.       (let ((s (save-excursion (search-backward "}")
  68.                                (1+ (point)))))
  69.         (delete-region s (point))
  70.         (insert " "))
  71.     (insert " ")))

  72. (defun xgp-cfsi-gnu-PAREN ()
  73.   (interactive)
  74.   (if (not (looking-back " "))
  75.       (insert " "))
  76.   (funcall xgp-cfsi-left-PAREN-old nil))

  77. (defun xgp-cfsi-erase-blanks ()
  78.   "Erase all trivial blanks for CFSI."
  79.   (interactive)
  80.   (save-excursion
  81.     (goto-char (point-min))
  82.     (while (re-search-forward "[ \t]+$" nil t)
  83.       (replace-match "" nil nil))))
复制代码

再引用一段他的话:
这里的核心函数是 xgp-cfsi,它接受风格名作为参数,并设置自动换行的方式。
这样,在 bsd 风格中只有函数声明、单独的 if、while 和 for 的子句以及枚举
和初始化说明中需要手工按回车,其他情况中 Emacs 都会自动插入回车。然后我
在 c-mode-common-hook 中加入了 (c-toggle-hungry-state 1)、
(c-toggle-auto-newline 1),以及 (xgp-cfsi "bsd") 来将默认风格置为 bsd。
同时,如果需要输入其他风格的程序,Emacs 都会自动地进行排版。当然,我在
公司的开发组要求了一种我不喜欢的风格 (这也是我自己写这个函数的原因),它
是这样设置的:

  1. '(c-hanging-braces-alist (quote ((defun-open before after)
  2.                                  (defun-close before after)
  3.                                  (brace-list-open after)
  4.                                  (brace-list-close)
  5.                                  (brace-entry-open before after)
  6.                                  (statement-cont before after)
  7.                                  (substatement-open before after)
  8.                                  (block-close after)
  9.                                  (extern-lang-open before after)
  10.                                  (namespace-open before after)
  11.                                  (module-open before after)
  12.                                  (composition-open before after)
  13.                                  (inexpr-class-open before after)
  14.                                  (inexpr-class-close before after)
  15.                                  (class-open before after)
  16.                                  (class-close))))
  17. '(c-offsets-alist (quote ((block-open . 0)
  18.                           (block-close . 0)
  19.                           (statement-block-intro . +)
  20.                           (substatement . +)
  21.                           (substatement-open . 0)
  22.                           (substatement-label . 0) (label . 0)
  23.                           (case-label . 0)
  24.                           (do-while-closure . 0)
  25.                           (else-clause . 0)
  26.                           (catch-clause . 0)
  27.                           (case-label . 0)
  28.                           (access-label . -)
  29.                           (namespace-open . 0)
  30.                           (class-open . 0)
  31.                           (class-close . 0)
  32.                           (innamespace . 0))))
复制代码

我根据他的配置又做了自己的配置:

  1. (defun xgp-cfsi-modify-alist (alist term new)
  2.   (let ((tl (assq term (symbol-value alist))))
  3.     (if tl
  4.         (setcdr tl new)
  5.       (add-to-list alist (cons term new)))))
  6. (defun kid-set-my-c-style()
  7.   (kid-overwrite-alist (quote ((defun-open after)
  8.                                (defun-close after)
  9.                                (class-open before after)
  10.                                (class-close ())
  11.                                (block-open after)
  12.                                (block-close . c-snug-do-while)
  13.                                ;; in case I want to use ``int foo[] = {0};''
  14.                                (topmost-intro)
  15.                                (brace-list-open)
  16.                                (brace-list-close)
  17.                                (do-while-closure  after)
  18.                                (substatement-open  after)
  19.                                (else-clause after)
  20.                                (access-label after)
  21.                                (catch-clause  after)))
  22.                        'c-hanging-braces-alist)
  23.   (kid-overwrite-alist (quote ((case-label after)
  24.                                (access-label after)
  25.                                (label after)
  26.                                (inher-intro)))
  27.                        'c-hanging-colons-alist)
  28.   (setq c-hanging-semi&comma-criteria
  29.         (quote (c-semi&comma-inside-parenlist)))
  30.   (setq c-cleanup-list
  31.         (quote (brace-catch-brace
  32.                 brace-else-brace
  33.                 brace-elseif-brace
  34.                 empty-defun-braces
  35.                 defun-close-semi
  36.                 one-liner-defun
  37.                 list-close-comma
  38.                 scope-operator))))

  39. (defun kid-overwrite-alist (from to)
  40.   (cond ((null from) nil)
  41.         (t (progn (xgp-cfsi-modify-alist to
  42.                                           (car (car from))
  43.                                           (cdr (car from)))
  44.                    (kid-overwrite-alist (cdr from) to)))))
复制代码

然后我的 c-mode-hook 里面这样写:

  1. (add-hook 'c-mode-hook 'my-c-mode)
  2. (add-hook 'c++-mode-hook 'my-c++-mode)
  3. (add-hook 'c-mode-common-hook 'my-c-common-mode)

  4. (defun my-c-common-mode ()
  5.   (c-toggle-auto-newline 1)
  6.   ;; 此模式下,当按Backspace时会删除最多的空格
  7.   (c-toggle-hungry-state))

  8. (defun my-c-mode ()
  9.   ;; K&R 风格的缩进方案
  10.   (c-set-style "k&r")
  11.   (kid-set-my-c-style))
  12. (defun my-c++-mode ()
  13.     (c-set-style "stroustrup")
  14.     (kid-set-my-c-style))
复制代码

这样,就可以很好地使用了!你也可以根据自己的习惯配置。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表