Chinaunix首页 | 论坛 | 博客
  • 博客访问: 901439
  • 博文数量: 113
  • 博客积分: 3160
  • 博客等级: 少校
  • 技术积分: 1801
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-19 10:09
文章分类

全部博文(113)

分类: LINUX

2012-05-21 17:50:21

2章  emacs编辑器

  

2.1 前面的话

 

开始的时候,你可能会觉得emacs不好用,有点古怪,尤其是当你发现连个粘贴只能用一堆快捷键而不能像

其它编辑器那样用鼠标右键时,心里可能会有一种被愚弄的感觉,难道这就是神的编辑器,难道只有

才能使用嘛! 可是当你慢慢习惯之后,你会发现它作为一个编辑器,它的文字处理能力和编辑效率确实很高。

你可以随意删除或者跳过字符,词组,一句,一行一段,这在编辑的时候非常有用,而这还不是emacs最大的

卖点,它最大的优点在于具有高度的配置能力,你能像盖房子一样,搭建一个完全适合自己习惯的编辑器。

 

2.2 emacs简介

 

emacs编辑器是由Richard Stallman 和 Guy Steele1975年合作开发的,它是在20世纪60年代末的文本编器

TECO的基础上,扩展了其中的一系列命令和宏发展而成的。emacs不仅仅是一个文本编辑器,它还可以利

lisp编程语言的优势对emacs进行定制和扩展。这也是emacs和其它编辑器的最大区别,但这种便利只有

lisp高手才能尽情享用。一般用户只能使用已经绑定好的命令或者由某个高手编写好的配置文件,但这基本

上已经够用了。如果你喜欢折腾的话也可以自己试着编写,这样当你在学emacs的同时还能学会lisp,这也算是

一剑双雕了。。

 

2.3基本命令

下面这些是emacs默认的绑定键。如果你学会使用lisp配置你自己的emacs,请尽量不要自己修改这些默认的

key-bindings,否则容易出错。(C对应CtrlM对应Alt)

 

2.3.1基本文件操作

 

下面这些主要涉及了文件的基本操作,包括打开,新建,保存,另存为以及退出emacs等比较常用的命令。

 

 

C-x C-f  打开/新建一个文件

C-x C-s  保存文件

C-x C-w 另存为文件

C-x C-v  关闭当前缓冲区文件并打开新文件

C-x i  在当前光标处插入文件

C-x b  新建/切换缓冲区

C-x C-b  显示缓冲区列表

C-x k  关闭当前缓冲区

C-x C-c  关闭emacs

 

2.3.2光标移动

这里边最方便的就是句首句尾和行首行尾,因为我的是笔记本键盘,上下左右主要是用方向键,如果要是

标准键盘的话,最好常用绑定键。

 

 

C-f  后一个字符 C-b  前一个字符

C-p  上一行 C-n  下一行

M-f  后一个单词 M-b  前一个单词

C-a  行首 C-e   行尾

C-v  向下翻一页 M-v  向上翻一页

M-<  到文件开头 M->  到文件末尾

 

2.3.3文本编辑

这里面包括了复制粘贴剪切删除等常用的操作命令。注意,在这里,移除包括了剪切和删除两个概念,要

区分清楚。

 

 

M-n/C-u n  重复执行后一个命令n

C-d  删除后一个字符 M-d  删除后一个单词

Del 删除前一个字符        M-Del  删除前一个单词

C-k  移除一行

C-@  设定标志位(主要是为了粘贴剪切以及删除使用)

C-w  移除标记区域的内容(剪切)

M-w  复制标记区域的内容(复制)

C-y  召回(yank)复制/移除的区域/行(粘贴)

M-y  召回更早的内容 (kill缓冲区内循环)

 

C-t  交换两个字符的位置

M-t  交换两个单词的位置

C-x C-t 交换两行的位置

M-u  使从光标位置到单词结尾处的字母变成大写

M-l  与M-u相反

M-c  使从光标位置开始的单词的首字母变为大写

 

2.3.4 一些重要的命令

 

C-g  停止当前运行/输入的命令

C-x u/C-_  撤销前一个命令(undo)

 

M-x revert-buffer RETURN  撤销上次存盘后所有改动

M-x recover-file RETURN  从自动存盘文件恢复

M-x recover-session RETURN  如果你编辑了几个文件用这个恢复

 

2.3.5搜索

C-s  向后搜索

C-r  向前搜索

 

2.3.6窗口命令

窗口命令比较常用,尤其是编辑多个文件的时候,你可以打开多个窗口,可以提高编辑效率。

 

 

C-x 2  水平分割窗格

C-x 3  垂直分割窗格

C-x o  切换至其他窗格

C-x 0  关闭窗格

C-x 1  关闭除了光标所在窗格外所有窗格

 

M C-v  滚动其他窗格内容

C-x 4 f   在其他窗格中打开文件

C-x 4 0  关闭当前缓冲区和窗格

C-x 5 2  新建窗口(frame)

C-x 5 f  在新窗口中打开文件

C-x 5 o  切换至其他窗口

C-x 5 0  关闭当前窗口

2.3.6 C/C++/java编程

这些就是光标的移动,比较有用。

 

M-a  移动光标到声明的开始处

M-e  移动光标到声明的结尾处

M C-a  移动光标到函数的开始处

M C-e  移动光标到函数的结尾处

 

2.3.7 帮助

C-h c  显示快捷键绑定的命令

C-h k  显示快捷键绑定的命令和它的作用

C-h f  显示函数的功能

C-h b  显示当前缓冲区所有可用的快捷键

C-h t  打开emacs教程 


2.3.8 其它 

C-x C-e 在lisp语句后可以执行那条语句

M-x eval-buffer  可以执行当前buffer内的Elisp代码

M-x eval-region 执行这个region内的代码

 

2.4 emacs定制

说实话,emacs的迷人之处就是具有非常强的自主配置能力,你可以完全根据自己的个人习惯来设置它。

就像我在下面罗列的那些lisp代码,你可以尽情的改变F1F2。。等等键所对应的功能,也可以在编

C/C++/java时使用自动补全等等非常人性化的功能。或许这就是emacs作为一个“神”一样的编辑器所

存在的理由。如果你非常喜欢折腾,那emacs绝对是你的首选编辑器。

 

每一次emacs启动的时候,它将加载一个名为~/.emacsLisp代码文件,对该文件进行编辑是一种常用的

定制emacs的方式。我不会讲lisp的具体使用方法,只是罗列出常用的对emacs进行配置的lisp代码,当你

熟悉这些代码的时候,再去深入学习lisp,或许效果更好。

 

下面是一个典型的Lisp语句:

(setq column-number-mode t)

(setq line-number-mode t)

它的意思是显示行列号。其中,括号表示这是一个lisp函数调用,圆括号内第一个符号setqemacs配置文件

中常用的的函数,它为某个全局变量赋值。该函数第一个参数为要设置的变量名,第二个数则是该变量的值。

下面讲到的每一行代码,你都可以直接拿到~/.emacs中使用。当你想要了解某一行代码的作用时,可以把它

复制粘贴到~/.emacs中,保存然后重启emacs就可以看到效果了。

 

 

小技巧:当你编辑~/.emacs配置文件的时候,每一次要看到效果都必须重新启动emacs,非常麻烦。你可以emacs打开.emacs文件并加入你想要的lisp代码后,使用C-x C-s保存,接着在minibuffer输入:

M-x eval-buffer,它会立即生效。你可以试验一下,非常方便和简单。 

 

2.4.1 设置界面

;;设置字体颜色为黑色,默认为黑色

(set-foreground-color "grey")

;;设置背景为黑色,默认为白色,你也可以自由设置其它颜色

(set-background-color "black")

;;设置光标的颜色为金黄,默认为黑色

(set-cursor-color "gold1")

;;设置鼠标的颜色

(set-mouse-color "gold1")

 

;; 设置语法高亮显示的背景和主题,区域选择的背景和主题,二次选择的背景和选择

(set-face-foreground 'highlight "white")

(set-face-background 'highlight "blue")

(set-face-foreground 'region "cyan")

(set-face-background 'region "blue")

(set-face-foreground 'secondary-selection "skyblue")

(set-face-background 'secondary-selection "darkblue")

 

2.4.2 设置周边

;;显示行列号,它显示在minibuffer上面那个杠上

(setq column-number-mode t)

(setq line-number-mode t)

(setq-default indent-tabs-mode t)

 

;;设置滚动栏在窗口右侧,默认是在左侧

(customize-set-variable 'scroll-bar-mode' right)

 

;;取消滚动栏

(set-scroll-bar-mode nil)

 

;;取消工具栏

(tool-bar-mode nil)

 

;; 禁用菜单栏,F10 开启关闭菜单

(menu-bar-mode nil)

 

;;设置标题栏为buffer的内容

(setq frame-title-format "emacs@%b")

 

;; 设置启动时窗口的长宽,下面为90*35

(setq initial-frame-alist '((width . 90) (height . 35)))

 

;;关闭出错时的提示声

(setq visible-bell t)

 

;;关闭emacs启动时的画面

(setq inhibit-startup-message t)

 

;;关闭gnus启动时的画面

(setq gnus-inhibit-startup-message t)

 

;;允许屏幕左移

(put 'scroll-left 'disabled nil) 

 

;;允许屏幕右移

(put 'scroll-right 'disabled nil) 

 

;;把这些缺省禁用的功能打开。

(put 'set-goal-column 'disabled nil)

(put 'narrow-to-region 'disabled nil)

(put 'upcase-region 'disabled nil)

(put 'downcase-region 'disabled nil)

(put 'LaTeX-hide-environment 'disabled nil)

 

2.4.3 显示时间设置

;;启用时间显示设置,在minibuffer上面的那个杠上

(display-time-mode 1)

 

;;时间使用24小时制

(setq display-time-24hr-format t)

 

;;时间显示包括日期和具体时间

(setq display-time-day-and-date t)

 

2.4.4 设置日历

;;设置日历的一些颜色

(setq calendar-load-hook

'(lambda ()

(set-face-foreground 'diary-face "skyblue")

(set-face-background 'holiday-face "slate blue")

(set-face-foreground 'holiday-face "white")))

 

;; 设置阴历显示,在 calendar 上用 pC 显示阴历

(setq chinese-calendar-celestial-stem

["" "" "" "" "" "" "" "" "" ""])

(setq chinese-calendar-terrestrial-branch

["" "" "" "" "" "" "" "" "" "" "" ""])

 

;; 设置 calendar 的显示

(setq calendar-remove-frame-by-deleting t)

 

;;设置星期一为每周的第一天

(setq calendar-week-start-day 1) 

 

;; 去掉不关心的节日,设定自己在意的节日,在 calendar 上用 显示节日

;; 在这里,可以把家人还有朋友的生日写上

(setq christian-holidays nil)

(setq hebrew-holidays nil)

(setq islamic-holidays nil)

(setq solar-holidays nil)

(setq general-holidays '((holiday-fixed 1 1 "元旦")

(holiday-fixed 2 14 "情人节")

(holiday-fixed 3 14 "白色情人节")

(holiday-fixed 4 1 "愚人节")

(holiday-fixed 5 1 "劳动节")

(holiday-float 5 0 2 "母亲节")

(holiday-fixed 6 1 "儿童节")

(holiday-float 6 0 3 "父亲节")

(holiday-fixed 7 1 "建党节")

(holiday-fixed 8 1 "建军节")

(holiday-fixed 9 10 "教师节")

(holiday-fixed 10 1 "国庆节")

(holiday-fixed 12 25 "圣诞节")))

 

2.4.5 设置符合个人的操作习惯

 

;;设置打开文件的缺省路径,这里为桌面,我喜欢把东西放在桌面上,默认的路径为“~/

(setq default-directory "/桌面")

 

;;设置M-_作为标志位,默认C-@setmark,C-@不太好用

(global-set-key (kbd "M-") 'set-mark-command)

 

;;改变Emacs要你回答yes的行为。按y或空格键表示yesn表示no

(fset 'yes-or-no-p 'y-or-n-p)

 

;;禁止在鼠标点击的地方插入剪贴板内容

(setq mouse-yank-at-point t)

 

;;所有模式中都自动填充

(setq-default auto-fill-function 'do-auto-fill)

 

;;设置默认的文档宽度

(setq default-fill-column 60)

 

;;不用 TAB 字符来indent, 这会引起很多奇怪的错误。

;;编辑 Makefile 的时候也不用担心,因为 makefile-mode 会把 TAB 键设置成真正的 TAB 字符,并且加亮显示的

(setq-default indent-tabs-mode nil)

(setq default-tab-width 8)

(setq tab-stop-list ())

 

;;防止页面滚动时跳动

;;scroll-margin 3 可以在靠近屏幕边沿3行时就开始滚动

;;scroll-step 1 设置每次都是一行一行向下翻,更有连贯性。

(setq scroll-step 1 

scroll-margin 3 

scroll-conservatively 10000)

 

;;设置缺省主模式是text,并进入auto-fill次模式.而不是基本模式fundamental-mode

(setq default-major-mode 'text-mode)

(add-hook 'text-mode-hook 'turn-on-auto-fill)

 

;;打开括号匹配显示模式

(setq show-paren-mode t) 

 

;;括号匹配时可以高亮显示另外一边的括号,但光标不会烦人的跳到另一个括号处。

(setq show-paren-style 'parenthesis)

 

;;让 Emacs 可以直接打开和显示图片。

(setq auto-image-file-mode t)

 

;; 不自动保存模式

(setq auto-save-mode nil)

 

;;允许emacs和外部其他程序的粘贴

(setq x-select-enable-clipboard t)

 

;; 自动的在文件末增加一新行

(setq require-final-newline t)

 

;;Non-nil if Transient-Mark mode is enabled.

(setq-default transient-mark-mode t)

 

;; 当光标在行尾上下移动的时候,始终保持在行尾。

(setq track-eol t)

 

;; 设置时间戳,标识出最后一次保存文件的时间。

(setq time-stamp-active t)

(setq time-stamp-warn-inactive t)

(setq time-stamp-format "%:y-%02m-%02d %3a %02H:%02M:%02S chunyu")

 

;Emacs的插件一般都是一个以el为后缀名的文件把这个文件下载下来后放到一个目录比如~/emacs/lisps, 然后执行下面这两条语句:

 

(add-to-list 'load-path "~/emacs/lisps")

(require 'pluginname)

 

;;C-j绑定到到达指定行上”(goto-line)

(global-set-key (kbd "C-j") 'goto-line)

 

 

;;c++-mode进行快捷键定制define-key即可

;;define-key第一个参数map一般为mode后面直接加”-map”

 

(define-key c++-mode-map (kbd "C-j") 'goto-line)

 

 

 

;; 设置默认tab宽度为2

(setq tab-width 2

indent-tabs-mode t

c-basic-offset 2)

 

;; 回车缩进

(global-set-key "\C-m" 'newline-and-indent)

(global-set-key (kbd "C-") 'newline)

 

 

 

;; 实现全屏效果,快捷键为f11

(global-set-key [f11] 'my-fullscreen) 

(defun my-fullscreen ()

(interactive)

(x-send-client-message

nil 0 nil "_NET_WM_STATE" 32

'(2 "_NET_WM_STATE_FULLSCREEN" 0))

)

 

 

;; 最大化

(defun my-maximized ()

(interactive)

(x-send-client-message

nil 0 nil "_NET_WM_STATE" 32

'(2 "_NET_WM_STATE_MAXIMIZED_HORZ" 0))

(x-send-client-message

nil 0 nil "_NET_WM_STATE" 32

'(2 "_NET_WM_STATE_MAXIMIZED_VERT" 0))

)

 

;; 启动emacs时窗口最大化

(my-maximized) 

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;

;; 实现不设置标志就能复制

;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

 

;;复制单词

 

(defun copy-word (&optional arg)

"Copy words at point into kill-ring"

(interactive "P")

(copy-thing 'backward-word 'forward-word arg)

(paste-to-mark arg))

;;绑定键

(global-set-key (kbd "C-c w")         (quote copy-word))

 

;;复制一行

(defun copy-line (&optional arg)

"Save current line into Kill-Ring without mark the line "

(interactive "P")

(copy-thing 'beginning-of-line 'end-of-line arg)

(paste-to-mark arg))

;;绑定键

(global-set-key (kbd "C-c l")         (quote copy-line))

 

;;复制一段

(defun copy-paragraph (&optional arg)

"Copy paragraphes at point"

(interactive "P")

(copy-thing 'backward-paragraph 'forward-paragraph arg)

(paste-to-mark arg))

;;绑定键

(global-set-key (kbd "C-c p")(quote copy-paragraph))

 

 

;;复制字符串

(defun beginning-of-string(&optional arg)

"  "

(re-search-backward "[ \t]" (line-beginning-position) 3 1)

(if (looking-at "[\t ]")  (goto-char (+ (point) 1)) )

)

 

(defun end-of-string(&optional arg)

" "

(re-search-forward "[ \t]" (line-end-position) 3 arg)

(if (looking-back "[\t ]") (goto-char (- (point) 1)) )

)

 

(defun thing-copy-string-to-mark(&optional arg)

" Try to copy a string and paste it to the mark

When used in shell-mode, it will paste string on shell prompt by default "

(interactive "P")

(copy-thing 'beginning-of-string 'end-of-string arg)

(paste-to-mark arg))

;;绑定键

(global-set-key (kbd "C-c s")         (quote thing-copy-string-to-mark))

 

 

(defun beginning-of-parenthesis(&optional arg)

"  "

(re-search-backward "[[<(?\"]" (line-beginning-position) 3 1)

(if (looking-at "[[<(?\"]")  (goto-char (+ (point) 1)) )

)

 

(defun end-of-parenthesis(&optional arg)

" "

(re-search-forward "[]>)?\"]" (line-end-position) 3 arg)

(if (looking-back "[]>)?\"]") (goto-char (- (point) 1)) )

)

 

(defun thing-copy-parenthesis-to-mark(&optional arg)

" Try to copy a parenthesis and paste it to the mark

When used in shell-mode, it will paste parenthesis on shell prompt by default "

(interactive "P")

(copy-thing 'beginning-of-parenthesis 'end-of-parenthesis arg)

(paste-to-mark arg))

;;绑定键

(global-set-key (kbd "C-c a")         (quote thing-copy-parenthesis-to-mark))

 

 

;;所有以上几个函数,都依赖于下面这三个基础函数,由他们三个负责完成实际的工作。

 

(defun get-point (symbol &optional arg)

"get the point"

(funcall symbol arg)

(point))

 

(defun copy-thing (begin-of-thing end-of-thing &optional arg)

"copy thing between beg & end into kill ring"

(let ((beg (get-point begin-of-thing 1))

(end (get-point end-of-thing arg)))

(copy-region-as-kill beg end)))

 

(defun paste-to-mark(&optional arg)

"Paste things to mark, or to the prompt in shell-mode"

(let ((pasteMe 

(lambda()

(if (string= "shell-mode" major-mode)

(progn (comint-next-prompt 25535) (yank))

(progn (goto-char (mark)) (yank) )))))

(if arg

(if (= arg 1)

nil

(funcall pasteMe))

(funcall pasteMe))

))

 

2.4.6 绑定键设置

;;绑定键的设置最好放在配置文件的最后,以免被后面的配置文件覆盖

 

;;设置F1打开帮助文档

(global-set-key [f1] 'info)

 

;;设置F2为恢复键 

(global-set-key [f2] 'undo) 

 

;;设置F3关闭当前buffer 

(global-set-key [f3] 'kill-this-buffer) 

 

;;设置F4打开一个终端,可以绑定:eshell,shell,terminal-emulator 

(global-set-key [f4] 'term)

 

;;C-f5 设置编译命令

;;f5 保存所有文件然后编译当前窗口文件

(defun du-onekey-compile ()

"Save buffers and start compile"

(interactive)

(save-some-buffers t)

(switch-to-buffer-other-window "*compilation*")

(compile compile-command))

(global-set-key [C-f5] 'compile)

(global-set-key [f5] 'du-onekey-compile)

 

;;F6设置为在Emacs中调用gdb

(global-set-key [f6] 'gdb) 

 

;;可以显示所有目录以及文件

(setq speedbar-show-unknown-files t)

 

;;设置f9调用speedbar命令

;;使用 和 可以上下移动,

;; + 展开目录或文件进行浏览,收缩,RET 访问目录或文件,更新 speedbar

(global-set-key [f9] 'speedbar)

 

;;设置F10打开/关闭菜单 

(global-set-key [f10] 'menu-bar-mode) 

 

;; 设置F11快捷键指定Emacs 的日历系统

(global-set-key [f11] 'calendar)

 

;; 设置F12 快速察看日程安排

(global-set-key [f12] 'list-bookmarks)

 

;; "C-,"设为屏幕左移命令

(global-set-key (kbd "C-,") 'scroll-left)

 

;; "C-."设为屏幕右移命令

(global-set-key (kbd "C-.") 'scroll-right)

 

2.4.7 C/C++/JAVA编程模式

;; C语言模式

(add-hook 'c-mode-hook

'(lambda ()

 

;;c语言风格设置为k&r风格

(c-set-style "k&r")

 

;; 此模式下,当按Backspace时会删除最多的空格

(c-toggle-hungry-state)

 

;; TAB键的宽度设置为4

(setq c-basic-offset 4)

 

;; 在菜单中加入当前Buffer的函数索引

(imenu-add-menubar-index)

 

;; 在状态条上显示当前光标在哪个函数体内部

(which-function-mode)))

 

;; C++语言模式

(add-hook 'c++-mode-hook

'(lambda()

 

;;C++语言风格设置为stroustrup风格

(c-set-style "stroustrup")

(c-toggle-auto-state)

(c-toggle-hungry-state)

(setq c-basic-offset 4)

(imenu-add-menubar-index)

(which-function-mode)))

 

 

;; JAVA语言模式

(add-hook 'java-mode-hook

'(lambda()

 

(c-set-style "java")

 

(c-toggle-auto-state)

 

(c-toggle-hungry-state)

 

(setq c-basic-offset 4)

 

(imenu-add-menubar-index)

 

(which-function-mode)))

 

 

;;能把一个代码块缩起来,需要的时候再展开

;; M-x hs-minor-mode

;; C-c @ ESC C-s show all

;; C-c @ ESC C-h hide all

;; C-c @ C-s show block

;; C-c @ C-h hide block

;; C-c @ C-c toggle hide/show

(load-library "hideshow")

(add-hook 'c-mode-hook 'hs-minor-mode)

(add-hook 'c++-mode-hook 'hs-minor-mode)

(add-hook 'java-mode-hook 'hs-minor-mode)

(add-hook 'perl-mode-hook 'hs-minor-mode)

(add-hook 'php-mode-hook 'hs-minor-mode)

(add-hook 'emacs-lisp-mode-hook 'hs-minor-mode)

 

 

;;自动补全右边的部分.包括<>, "", '', (), //, [] , {}等等。

(defun my-c-mode-auto-pair ()

(interactive)

(make-local-variable 'skeleton-pair-alist)

(setq skeleton-pair-alist '(

 

;;自动补全<>

(?\< ? _ ">")

 

;;自动补全//

(?` ?` _ "/")

 

;;自动补全()

(?\( ? _ " )")

 

;;自动补全[]

(?\[ ? _ " ]")

 

;;设自动补全""

(?\" ? _ "\"")

 

;;自动补全''

(?\' ? _ "'")

 

;;自动补全{}

(?{ \n > _ \n ?} >)))

 

(setq skeleton-pair t)

(local-set-key (kbd "<") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "/") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "(") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "/") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "'") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "\"") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "[") 'skeleton-pair-insert-maybe)

(local-set-key (kbd "{") 'skeleton-pair-insert-maybe))

(add-hook 'c-mode-hook 'my-c-mode-auto-pair)

(add-hook 'c++-mode-hook 'my-c-mode-auto-pair)

阅读(2606) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~