zoukankan      html  css  js  c++  java
  • 一个 .emacs 配置文件的例子

    2.7 使用 Emacs 作为开发环境

    2.7.1 Emacs

      很不幸,UNIX® 系统不像其他的系统那样带有一种“你要的全有,不要的更多”的,包含所有的,巨大的程序开发环境。 [1] 但是,你可以搭建一个自己的开发环境。可能不会很漂亮,也不会非常集成化。但是你可以按自己的需求来搭建。而且是免费的。你将拥有所有的源码。

      问题的答案就是 Emacs。如今有很多人厌恶它,也有很多喜欢它。如果你是前者之一,恐怕这一章不会引起你的兴趣。而且,你需要一定量的内存来运行 Emacs──文字界面我推荐 8MB,而在 X 下最少需要 16MB 来获得合理的性能。

      Emacs 基本上是一个高度可配置的编辑器──实际上,Emacs 更像一个操作系统而不像一个编辑器!很多开发人员和系统管理员把所有的时间都花在 Emacs 里面,只在退出登陆的时候才退出这个编辑器。

      要在这里概括所有 Emacs 能做的事情是不可能的,但是这里列出了一些开发人员可能感兴趣的特性:

    • 非常强大的编辑器,允许对字串和正则表达式(类型)进行搜索和替代。跳至块结构的开始/末尾,等等。

    • 下拉菜单和在线帮助。

    • 语言相关的语法高亮显示和缩进。

    • 完全可配置。

    • 你可以在 Emacs 中编译和调试程序。

    • 出现编译错误以后,你可以直接跳至出问题的那一行代码。

    • 比较友好的 info 的前端,可以阅读 GNU 超文本文 档。当然包括 Emacs 自己的文档。

    • 友好的 gdb 的前端,允许你在追踪程序的时候查看 源代码。

    • 你可以在编译程序的同时查看 Usenet 新闻和阅读邮件。

      毫无疑问还有很多被我忽略的。

      在 FreeBSD 上可以用 the Emacs port 来安装 Emacs。

      一旦安装好了,就可以运行 Emacs,然后输入 C-h t 阅读 Emacs 教程──意思就是说按住 control,再按 h,松开 control,然后再按 t。(或者,你可以使用鼠 标从 Help 菜单重选择 Emacs Tutorial)。

      尽管 Emacs 有菜单,最好还是学习一下键组合。因为在你编辑的时候,连续地按下一系列按键,比找到鼠标然后点击正确的地方要快得多。而且,当你和一个老 Emacs 用户交流的时候,你经常会碰到下列的表达 “M-x replace-s RET foo RET bar RET”,因此知道这些东西会很有用。而且在任 何情况下,Emacs 的菜单里永远放不下所有它实际上拥有的有用的功能。

      幸运的是,很容易学习键组合。因为菜单每个项目的后面都标示了对应的键组合。我的建议就是,首先使用菜单项,比如,打开一个文件,直到你明白了其中的奥妙,并且可以自信的使用这个菜单项,再尝试使用 C-x C-f。当你一点困难也没有的时候,就可以转到下一个菜单项继续练习。

      如果记不住一个特殊的键组合到底能做什么,可以从 Help 菜单中选择 Describe Key ,然后输入这个键组合──Emacs 会告诉你它到底能干什么。你也可以点击 Command Apropos来寻找包含一个特定词的命令, 后面紧跟的就是键组合。

      另外,刚才那个表达式的意思就是按住 Meta 键,按下 x 键,松开 Meta 键,输入 replace-s (replace-string的简写 ──Emacs 另一个特性就是命令的缩写),按下 return键,输 入 foo(你要替换的字串),输入 bar (你要用来替换 foo 的字串) 然后再次按下 return 键。 Emacs 就会按你的要求进行搜索和替换操作。

      你一定在疑惑 Meta 键是个什么键。这是一个很多 UNIX 工作站都有的特殊的键。很不幸,PC没有这样一个键。通常在 PC 上这个键是 alt 键(如果你运气不好,这个键在你的 PC 上会是 escape 键)。

      哦,要退出 Emacs,键入 C-x C-c (意思就是按住 control 键,按下 x,按下 c,再松开 control 键)。如果你还有已经打开的未保存的文件,Emacs 会问你是否要保存文件。(不要理会文档中说的退出 Emacs 的常用方法 C-z──这个键组合会把 Emacs 放到后台,而且这个方法只在没有虚拟控制台的系统上有用)。

    2.7.2 配置 Emacs

      Emacs 能做很多有用的事情;一些是内置的,另外一些需要我们进行配置。

      Emacs 没有用一种私有的宏语言来配置自身,而是使用了某种特别适应编辑器 的 Lisp 版本,叫做 Emacs Lisp。如果你要继续读下去并且想学习一点 Common Lisp,学习使用 Emacs Lisp 是很有用的。Emacs Lisp 有很多 Common Lisp 的特性, 虽然前者相当小 (因此更容易掌握)。

      学习 Emacs Lisp 最好的方法就是下载 Emacs Tutorial

      但是,要配置 Emacs 并不需要任何实际的 Lisp 知识,因为我已经列出了一 个 .emacs 例子,足够让你顺利的开始工作。只要把这个文件复制到你的家目录,如果 Emacs 已经在运行,就重新起动;Emacs 会从这个文件中读取命令,然后(希望)能给你一个有用的基本设置。

    2.7.3 一个 .emacs 配置文件的例子

      不幸的是,要详细解释的话话就长了;但是还是有一两点值得注意。

    • ; 开头的是注释,会被 Emacs 忽略掉。

    • 第一行里面的 -*- Emacs-Lisp -*- 能 让我们在 Emacs 里面编辑这个 .emacs,并且打开所 有 Emacs Lisp 的编辑特性。Emacs 一般会尝试根据文件名来猜测,而且很有可 能猜错。

    • 在某些模式下,tab 键被绑定到一个缩进函数上。因 此按下 tab 键后,它能缩进一行代码。如果你想把 tab 当作一个字符插入到你编辑的东西里面,需要在按下 tab 键的时同时按住 control 键。

    • 这个文件通过识别文件名后缀来支持 C,C++,Perl,Lisp 和 Scheme 的语法高亮。

    • Emacs 已经有一个预先定义的函数叫 next-error。在一个编译错误输出窗口,按下 M-n 能让从一个编译错误移动到另一个;我们还定义了一个类似的函数, previous-error,这个函数在你按下 M-p 后,能让你回到上一个编译错误。其中最好的特性就是按 下 C-c C-c 后,能根据错误打开相应的文件并且跳到相应 的那行代码。

    • 我们打开了 Emacs 作为 服务端运行的特性,这样当你在 Emacs 外做一些事情的时候,又需要编辑一个文件的时候,只需要输入

      % emacsclient filename
          

      然后就可以在 Emacs 编辑那个文件了! [2]

    例 2-1. 一个 .emacs 配置文件的例子

    ;; -*-Emacs-Lisp-*-
    ;; This file is designed to be re-evaled; use the variable first-time
    ;; to avoid any problems with this.
    (defvar first-time t
    "Flag signifying this is the first time that .emacs has been evaled")
    ;; Meta
    (global-set-key "\M- " 'set-mark-command)
    (global-set-key "\M-\C-h" 'backward-kill-word)
    (global-set-key "\M-\C-r" 'query-replace)
    (global-set-key "\M-r" 'replace-string)
    (global-set-key "\M-g" 'goto-line)
    (global-set-key "\M-h" 'help-command)
    ;; Function keys
    (global-set-key [f1] 'manual-entry)
    (global-set-key [f2] 'info)
    (global-set-key [f3] 'repeat-complex-command)
    (global-set-key [f4] 'advertised-undo)
    (global-set-key [f5] 'eval-current-buffer)
    (global-set-key [f6] 'buffer-menu)
    (global-set-key [f7] 'other-window)
    (global-set-key [f8] 'find-file)
    (global-set-key [f9] 'save-buffer)
    (global-set-key [f10] 'next-error)
    (global-set-key [f11] 'compile)
    (global-set-key [f12] 'grep)
    (global-set-key [C-f1] 'compile)
    (global-set-key [C-f2] 'grep)
    (global-set-key [C-f3] 'next-error)
    (global-set-key [C-f4] 'previous-error)
    (global-set-key [C-f5] 'display-faces)
    (global-set-key [C-f8] 'dired)
    (global-set-key [C-f10] 'kill-compilation)
    ;; Keypad bindings
    (global-set-key [up] "\C-p")
    (global-set-key [down] "\C-n")
    (global-set-key [left] "\C-b")
    (global-set-key [right] "\C-f")
    (global-set-key [home] "\C-a")
    (global-set-key [end] "\C-e")
    (global-set-key [prior] "\M-v")
    (global-set-key [next] "\C-v")
    (global-set-key [C-up] "\M-\C-b")
    (global-set-key [C-down] "\M-\C-f")
    (global-set-key [C-left] "\M-b")
    (global-set-key [C-right] "\M-f")
    (global-set-key [C-home] "\M-<")
    (global-set-key [C-end] "\M->")
    (global-set-key [C-prior] "\M-<")
    (global-set-key [C-next] "\M->")
    ;; Mouse
    (global-set-key [mouse-3] 'imenu)
    ;; Misc
    (global-set-key [C-tab] "\C-q\t")   ; Control tab quotes a tab.
    (setq backup-by-copying-when-mismatch t)
    ;; Treat 'y' or <CR> as yes, 'n' as no.
    (fset 'yes-or-no-p 'y-or-n-p)
    (define-key query-replace-map [return] 'act)
    (define-key query-replace-map [?\C-m] 'act)
    ;; Load packages
    (require 'desktop)
    (require 'tar-mode)
    ;; Pretty diff mode
    (autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
    (autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
    (autoload 'ediff-files-remote "ediff"
    "Intelligent Emacs interface to diff")
    (if first-time
    (setq auto-mode-alist
    (append '(("\\.cpp$" . c++-mode)
    ("\\.hpp$" . c++-mode)
    ("\\.lsp$" . lisp-mode)
    ("\\.scm$" . scheme-mode)
    ("\\.pl$" . perl-mode)
    ) auto-mode-alist)))
    ;; Auto font lock mode
    (defvar font-lock-auto-mode-list
    (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'lisp-mode 'perl-mode 'scheme-mode)
    "List of modes to always start in font-lock-mode")
    (defvar font-lock-mode-keyword-alist
    '((c++-c-mode . c-font-lock-keywords)
    (perl-mode . perl-font-lock-keywords))
    "Associations between modes and keywords")
    (defun font-lock-auto-mode-select ()
    "Automatically select font-lock-mode if the current major mode is in font-lock-auto-mode-list"
    (if (memq major-mode font-lock-auto-mode-list)
    (progn
    (font-lock-mode t))
    )
    )
    (global-set-key [M-f1] 'font-lock-fontify-buffer)
    ;; New dabbrev stuff
    ;(require 'new-dabbrev)
    (setq dabbrev-always-check-other-buffers t)
    (setq dabbrev-abbrev-char-regexp "\\sw\\|\\s_")
    (add-hook 'emacs-lisp-mode-hook
    '(lambda ()
    (set (make-local-variable 'dabbrev-case-fold-search) nil)
    (set (make-local-variable 'dabbrev-case-replace) nil)))
    (add-hook 'c-mode-hook
    '(lambda ()
    (set (make-local-variable 'dabbrev-case-fold-search) nil)
    (set (make-local-variable 'dabbrev-case-replace) nil)))
    (add-hook 'text-mode-hook
    '(lambda ()
    (set (make-local-variable 'dabbrev-case-fold-search) t)
    (set (make-local-variable 'dabbrev-case-replace) t)))
    ;; C++ and C mode...
    (defun my-c++-mode-hook ()
    (setq tab-width 4)
    (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
    (define-key c++-mode-map "\C-ce" 'c-comment-edit)
    (setq c++-auto-hungry-initial-state 'none)
    (setq c++-delete-function 'backward-delete-char)
    (setq c++-tab-always-indent t)
    (setq c-indent-level 4)
    (setq c-continued-statement-offset 4)
    (setq c++-empty-arglist-indent 4))
    (defun my-c-mode-hook ()
    (setq tab-width 4)
    (define-key c-mode-map "\C-m" 'reindent-then-newline-and-indent)
    (define-key c-mode-map "\C-ce" 'c-comment-edit)
    (setq c-auto-hungry-initial-state 'none)
    (setq c-delete-function 'backward-delete-char)
    (setq c-tab-always-indent t)
    ;; BSD-ish indentation style
    (setq c-indent-level 4)
    (setq c-continued-statement-offset 4)
    (setq c-brace-offset -4)
    (setq c-argdecl-indent 0)
    (setq c-label-offset -4))
    ;; Perl mode
    (defun my-perl-mode-hook ()
    (setq tab-width 4)
    (define-key c++-mode-map "\C-m" 'reindent-then-newline-and-indent)
    (setq perl-indent-level 4)
    (setq perl-continued-statement-offset 4))
    ;; Scheme mode...
    (defun my-scheme-mode-hook ()
    (define-key scheme-mode-map "\C-m" 'reindent-then-newline-and-indent))
    ;; Emacs-Lisp mode...
    (defun my-lisp-mode-hook ()
    (define-key lisp-mode-map "\C-m" 'reindent-then-newline-and-indent)
    (define-key lisp-mode-map "\C-i" 'lisp-indent-line)
    (define-key lisp-mode-map "\C-j" 'eval-print-last-sexp))
    ;; Add all of the hooks...
    (add-hook 'c++-mode-hook 'my-c++-mode-hook)
    (add-hook 'c-mode-hook 'my-c-mode-hook)
    (add-hook 'scheme-mode-hook 'my-scheme-mode-hook)
    (add-hook 'emacs-lisp-mode-hook 'my-lisp-mode-hook)
    (add-hook 'lisp-mode-hook 'my-lisp-mode-hook)
    (add-hook 'perl-mode-hook 'my-perl-mode-hook)
    ;; Complement to next-error
    (defun previous-error (n)
    "Visit previous compilation error message and corresponding source code."
    (interactive "p")
    (next-error (- n)))
    ;; Misc...
    (transient-mark-mode 1)
    (setq mark-even-if-inactive t)
    (setq visible-bell nil)
    (setq next-line-add-newlines nil)
    (setq compile-command "make")
    (setq suggest-key-bindings nil)
    (put 'eval-expression 'disabled nil)
    (put 'narrow-to-region 'disabled nil)
    (put 'set-goal-column 'disabled nil)
    (if (>= emacs-major-version 21)
    (setq show-trailing-whitespace t))
    ;; Elisp archive searching
    (autoload 'format-lisp-code-directory "lispdir" nil t)
    (autoload 'lisp-dir-apropos "lispdir" nil t)
    (autoload 'lisp-dir-retrieve "lispdir" nil t)
    (autoload 'lisp-dir-verify "lispdir" nil t)
    ;; Font lock mode
    (defun my-make-face (face color &optional bold)
    "Create a face from a color and optionally make it bold"
    (make-face face)
    (copy-face 'default face)
    (set-face-foreground face color)
    (if bold (make-face-bold face))
    )
    (if (eq window-system 'x)
    (progn
    (my-make-face 'blue "blue")
    (my-make-face 'red "red")
    (my-make-face 'green "dark green")
    (setq font-lock-comment-face 'blue)
    (setq font-lock-string-face 'bold)
    (setq font-lock-type-face 'bold)
    (setq font-lock-keyword-face 'bold)
    (setq font-lock-function-name-face 'red)
    (setq font-lock-doc-string-face 'green)
    (add-hook 'find-file-hooks 'font-lock-auto-mode-select)
    (setq baud-rate 1000000)
    (global-set-key "\C-cmm" 'menu-bar-mode)
    (global-set-key "\C-cms" 'scroll-bar-mode)
    (global-set-key [backspace] 'backward-delete-char)
    ;      (global-set-key [delete] 'delete-char)
    (standard-display-european t)
    (load-library "iso-transl")))
    ;; X11 or PC using direct screen writes
    (if window-system
    (progn
    ;;      (global-set-key [M-f1] 'hilit-repaint-command)
    ;;      (global-set-key [M-f2] [?\C-u M-f1])
    (setq hilit-mode-enable-list
    '(not text-mode c-mode c++-mode emacs-lisp-mode lisp-mode
    scheme-mode)
    hilit-auto-highlight nil
    hilit-auto-rehighlight 'visible
    hilit-inhibit-hooks nil
    hilit-inhibit-rebinding t)
    (require 'hilit19)
    (require 'paren))
    (setq baud-rate 2400)         ; For slow serial connections
    )
    ;; TTY type terminal
    (if (and (not window-system)
    (not (equal system-type 'ms-dos)))
    (progn
    (if first-time
    (progn
    (keyboard-translate ?\C-h ?\C-?)
    (keyboard-translate ?\C-? ?\C-h)))))
    ;; Under UNIX
    (if (not (equal system-type 'ms-dos))
    (progn
    (if first-time
    (server-start))))
    ;; Add any face changes here
    (add-hook 'term-setup-hook 'my-term-setup-hook)
    (defun my-term-setup-hook ()
    (if (eq window-system 'pc)
    (progn
    ;;  (set-face-background 'default "red")
    )))
    ;; Restore the "desktop" - do this as late as possible
    (if first-time
    (progn
    (desktop-load-default)
    (desktop-read)))
    ;; Indicate that this file has been read at least once
    (setq first-time nil)
    ;; No need to debug anything now
    (setq debug-on-error nil)
    ;; All done
    (message "All done, %s%s" (user-login-name) ".")
    

    2.7.4 扩展 Emacs 所支持语言的范围

      现在,如果你只是想用 .emacs 设定好的语言 (C, C++, Perl, Lisp 和 Scheme) 来编程,事情就很好办。但是,如果突然一个新的语 言,叫 “whizbang”,有很多激动人心的特性,出来了,会发生什么事情?

      第一件要做的事情就是找到是否有任何文件能够告诉 Emacs 关于这个语言的信息。这种文件通常以 .el 结尾,是 “Emacs Lisp” 的缩写。例如,如果 whizbang 是 FreeBSD 的一个 port,那么我们可以用如下命令来定位这些文件

    % find /usr/ports/lang/whizbang -name "*.el" -print
    

      然后安装这些文件到 Emacs 的系统级 Lisp 目录。在 FreeBSD 2.1.0-Release 里,这个目录就是 /usr/local/share/emacs/site-lisp

      例如,如果刚才的定位命令的输出是

    /usr/ports/lang/whizbang/work/misc/whizbang.el
    

      我们可以执行

    # cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp
    

      下一步,我们需要确定 whizbang 的源文件是以什么后缀结尾。我们假定这些 源文件都是以 .wiz 结尾。我们需要在 .emacs 加上一条使 Emacs 能够使用 whizbang.el 中的信息。

      在 .emacs 中找到 auto-mode-alist entry,为 whizbang 添加一行,例如:

    ...
    ("\\.lsp$" . lisp-mode)
    ("\\.wiz$" . whizbang-mode)
    ("\\.scm$" . scheme-mode)
    ...
    

      意思就是,当你编辑一个以 .wiz 结尾的文件的时候, Emacs 会自动进入 whizbang-mode

      就在下面,你会发现 font-lock-auto-mode-list 这一条。添加 whizbang-mode

    ;; Auto font lock mode
    (defvar font-lock-auto-mode-list
    (list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
    "List of modes to always start in font-lock-mode")
    

      这意味着当你编辑 .wiz 文件的时候,Emacs 会自动 打开 font-lock-mode(就是语法高亮)。

      这就是所有必要的步骤。如果在你打开一个 .wiz 文件的时候,还有需要自动执行的任何其他步骤,你可以添加一个 whizbang-mode hook (查看 my-scheme-mode-hook 中添加 auto-indent 的步骤作为例子)。

    备注

    [1]

    现在在 ports collection 中包含了一些强大的,免费的 IDE,比如 KDevelop。

    [2]

    很多 Emacs 用户把他们的 EDITOR 环境变量设置为 emacsclient,因此每次他们需要编辑一个文件的时候,以上的动作就会被执行。

    本文档和其它文档可从这里下载:ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

    如果对于FreeBSD有问题,请先阅读文档,如不能解决再联系<questions@FreeBSD.org>.
    关于本文档的问题请发信联系 <doc@FreeBSD.org>.

  • 相关阅读:
    python学习之路-day1-python基础1
    JSON.NET基本使用
    tortoiseSVN 设置ignore
    一个简单的身份证校验
    一个HttpWebRequest工具类
    linq to NHibernate
    python-plot and networkx绘制网络关系图
    DDoS攻击及防御措施
    白帽子原则
    认识特洛伊木马
  • 原文地址:https://www.cnblogs.com/cy163/p/725843.html
Copyright © 2011-2022 走看看