Add New Notes

This commit is contained in:
geekard
2012-08-08 14:26:04 +08:00
commit 5ef7c20052
2374 changed files with 276187 additions and 0 deletions

232
Zim/Utils/emacs/C,C++.txt Normal file
View File

@@ -0,0 +1,232 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-05T22:37:02+08:00
====== 在Emacs下用C/C++编程 ======
2010年10月25日 lertsau 发表评论 阅读评论
1 参考文献
2 序
3 基本流程
4 基本环境设置
4.1 编辑环境配置
4.2 自动补齐
5 编译和调试程序
6 阅读代码
===== 1 参考文献 =====
按照惯例,我写的文章在最开始处放参考文献。
hhuu @ newsmth 的《Emacs的日常生活》
emacs 的文档
emacs 相关插件的文档
===== 2 序 =====
用emacs写程序也有5个年头了深切地体会到Emacs的强大。程序员有三种一种是用vi的一种是用emacs的还有一种是其他。或许有些夸张但也颇能体现出emacs在程序员中的地位。
emacs最大的问题在于入门门槛较高。它看起来和多数人想象中的IDE相差甚远很多人看到emacs的第一眼就觉得它是个记事本还是个非常难用的记事本稍微好些的往往觉得emacs也就是个ultraEditor而已真是暴殄天物了。
我是个懒人不喜欢记太多的快捷键相信很多人和我一样。所以从我后面的叙述可以看出来除了常用的命令都是快捷键外其他命令多数都是用M-x执行或者用鼠标点菜单。这仅仅是个人风格问题先说明一下。
我的基本编程环境是:
Debian GNU/Linux sid 操作系统
Gnome 2.10.0 桌面环境
GUN Emacs 23.0.0.1 for debian
使用 Gnu tool chains(gcc,make,gdb等等)
后面的叙述都基于上述环境。另外本文主要针对C/C++程序开发,对其他语言有些也适用,从难度上说,本文主要针对入门者。
本文肯定会有很多错误,请指正, 谢谢。
===== 3 基本流程 =====
写C++程序基本上是这么几个步骤:
编辑代码
编写Makefile
编译代码,修改编译错误
调试代码,修改逻辑错误
当然,往往还需要阅读别人的代码。
根据上述步骤,本文主要针对以下几个方面:
配置Emacs建立便利的代码编辑环境和Makefile编写环境。
在Emacs中编译代码并修改编译错误。
在Emacs中配合GDB调试程序。
利用cscope和ecb在emacs中阅读代码。
===== 4 基本环境设置 =====
==== 4.1 编辑环境配置 ====
要写C++程序当然要用到cc-mode插件。CC-Mode原本是支持C语言的但现在也能支持很多语言比如 C++JavaObjective-CCORBAAWKPike等等。CC-Mode是gnu-emacs的标准插件。如果您要求不高那么默认的配置或许就能满足。CC-Mode的各种行为都可以自由地定制您可以参考这里的文档CC-Mode参考文档
这里是我的.emacs文件中关于CC-Mode配置的部分仅供参考
;;;; CC-mode配置 http://cc-mode.sourceforge.net/
(require 'cc-mode)
(c-set-offset 'inline-open 0)
(c-set-offset 'friend '-)
(c-set-offset 'substatement-open 0)
;;;;我的C/C++语言编辑策略
(defun my-c-mode-common-hook()
(setq tab-width 4 indent-tabs-mode nil)
;;; hungry-delete and auto-newline
(c-toggle-auto-hungry-state 1)
;;按键定义
(define-key c-mode-base-map [(control \`)] 'hs-toggle-hiding)
(define-key c-mode-base-map [(return)] 'newline-and-indent)
(define-key c-mode-base-map [(f7)] 'compile)
(define-key c-mode-base-map [(meta \`)] 'c-indent-command)
;; (define-key c-mode-base-map [(tab)] 'hippie-expand)
(define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
(define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
注意一下,上面最后两行是代码自动补齐的快捷键。后面我会提到代码自动补齐。
;;预处理设置
(setq c-macro-shrink-window-flag t)
(setq c-macro-preprocessor "cpp")
(setq c-macro-cppflags " ")
(setq c-macro-prompt-flag t)
(setq hs-minor-mode t)
(setq abbrev-mode t)
)
(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)
;;;;我的C++语言编辑策略
(defun my-c++-mode-hook()
(setq tab-width 4 indent-tabs-mode nil)
(c-set-style "stroustrup")
;; (define-key c++-mode-map [f3] 'replace-regexp)
)
==== 4.2 自动补齐 ====
自动补齐通常用的都是hippie-expand我也用了很长时间。不过有时候会觉得这个自动补齐“傻”了一点常会补齐出一些毫不相干的东西因为hippie-expand是根据你敲过的词和kill-ring等进行判断的并不对程序语法进行分析。
所以你还需要安装一个代码分析工具然后把它加进hippie-expand的扩展策略里去。我们可以用semantic。实际上**hippie-expandsemantic**是我所发现的最好的选择了,如果您有更好的,请您也告诉我一声:)
Semantic是CEDET 中的一个工具CEDET是Collection of Emacs Development Environment Tools的缩写它包含了好几个工具都挺不错的。可惜我只会用其中两个。
您可以在.emacs中对Semantic进行配置下面是我的.emacs相关的配置仅供参考
导入cedet
(load-file "~/lib/emacs-lisp/cedet-1.0pre3/common/cedet.el")
配置Semantic的检索范围:
(setq semanticdb-project-roots
(list
(expand-file-name "/")))
自定义自动补齐命令这部分是抄hhuu的如果在单词中间就补齐否则就是tab。
(defun my-indent-or-complete ()
(interactive)
(if (looking-at "\\>")
(hippie-expand nil)
(indent-for-tab-command))
)
(global-set-key [(control tab)] 'my-indent-or-complete)
hippie的自动补齐策略优先调用了senator的分析结果
(autoload 'senator-try-expand-semantic "senator")
(setq hippie-expand-try-functions-list
'(
senator-try-expand-semantic
try-expand-dabbrev
try-expand-dabbrev-visible
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-expand-list
try-expand-list-all-buffers
try-expand-line
try-expand-line-all-buffers
try-complete-file-name-partially
try-complete-file-name
try-expand-whole-kill
)
)
注意一下我前面CC-Mode配置中有这么两行
(define-key c-mode-base-map [(tab)] 'my-indent-or-complete)
(define-key c-mode-base-map [(meta ?/)] 'semantic-ia-complete-symbol-menu)
这样我们在CC-Mode中就可以调用自定义的hippie补全了快捷键是Tab。
另外我还把快捷键“Alt + / ”绑定到了semantic-ia-complete-symbol-menu命令上这是semantic的命令它会根据分析结果弹出补齐的菜单效果如图显示
CEDET中还有一个不错的工具是speedbar你可以用它在多个文件中快速切换。在我的.emacs配置文件里我把speedbar关联到了F5上
(global-set-key [(f5)] 'speedbar)
这样用F5就可以调出speedbar效果如下
不过说实话我自己很少用到speedbar我通常都是**用dired配合bookmark**使用:)
===== 5 编译和调试程序 =====
按上面的配置写完程序和Makefile文件后在Emacs源代码窗口中按F7就可以进行编译。因为在my-c-mode-common-hook()函数里,有这么一行:
(define-key c-mode-base-map [(f7)] 'compile)
默认情况下emacs的compile命令是调用make -k我把它改成了make。你也可以把它改成其他的比如gcc之类的。改下面的“make”就行了。
'(compile-command "make")
Emacs会划分一个窗格显示编译的消息在编译结束后emacs会自动将编译器的输出和程序关联起来告诉你第几行的程序有问题。直接在出错的行号上按Enter就可以跳转到相应文件的相应行。其实我通常都是用鼠标中键去点出错行号:)
搞定了编译错误后,接着要和逻辑错误斗争了。其实对简单的程序来说,**把中间结果打印到终端是最简单好用的调试办法**:)不过稍微复杂点的程序就会晕菜了这时我们就需要拿gdb跟踪程序流程了。
你用下面的命令就可以启动gdb了。
M-x gdb
通常我喜欢进入**gdb-many-windows**模式这样就会把一个Frame划分为5个窗格同时显示gdb命令窗口当前局部变量程序文本调用栈和断点。
gdb的命令就不在这里说了它的文档几乎到处都是。emacs把gdb的命令和快捷键做了绑定对于常用的命令还是输入快捷键比较方便。比如C-c C-n是Next lineC-c C-s是step in其实用的最多的快捷键也就是这两个。
===== 6 阅读代码 =====
在emacs下读代码通常有三种工具最简单的是**etags**,最复杂的是**ecb**emacs code browser位于中间的是**cscope**。
etags和ctags一样只不过前者是用于emacs的后者是用于vi的。我个人觉得etags功能稍稍显得不够用一点当然也可能是我用的不好:) 欢迎大牛指导。
使用tags之前要先对源代码分析建立tags文件在代码所在目录中运行etags -R 即可。
我常用的就这几个命令和快捷键:
M-x visit-tags-table <RET> FILE <RET> 选择tags文件
M-. [TAG] <RET> 访问标签
M-* 返回
C-u M-. 寻找标签的下一个定义
cscope是我感觉比较合适的一个工具。它其实是一个独立的软件完全可以脱离vi和emacs使用。但是结合emacs的强大功能cscope就显得更加方便了。GNU Emacs默认自带cscope的支持。**在使用之前cscope也需要对代码进行索引**。在emacs中可以这样做
C-c s a 设定初始化的目录,一般是你代码的根目录
C-s s I 对目录中的相关文件建立列表并进行索引
建完索引之后你就可以用cscope在代码里游荡了。常用的一些命令如下
C-c s s 序找符号
C-c s g 寻找全局的定义
C-c s c 看看指定函数被哪些函数所调用
C-c s C 看看指定函数调用了哪些函数
C-c s e 寻找正则表达式
C-c s f 寻找文件
C-c s i 看看指定的文件被哪些文件include
上面这些快捷键其实我自己也常常记不全没关系抬头看看上面的菜单栏有一栏就是Cscope这些命令里头都有:)

View File

@@ -0,0 +1,37 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-19T20:37:16+08:00
====== DocViewMode ======
Created Friday 19 August 2011
DocViewMode is another file mode viewer like DviViewMode which adds support for PDF and PS files written by TassiloHorn. Its official part of Emacs 23.
Conversion is done with ghostscript and various other tools. It even supports regexp search in documents.
To get it its best to install Emacs 23 (the current CVS HEAD).
You can get a snapshot of doc-view.el at doc-view.el.
The homepage of DocViewMode is http://www.tsdh.de/cgi-bin/wiki.pl/doc-view.el.
This can be customized via:
M-x customize-group doc-view RET
Required Software
__ Ghostscript.__
Other Things?
Cygwin
Emacs 23 Instructions.
1. Install several packages:
xpdf
ghostscript
2. Restart Emacs.
3. It should just work.

View File

@@ -0,0 +1,89 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-11-20T00:17:13+08:00
====== Emacs Python completion ======
Created Sunday 20 November 2011
http://www.rwdev.eu/articles/emacspyeng
C
Emacs Python completion
The purpose of this package is to support Python code completion and to make easier to use Python documentation using Emacs.
There are available following features:
code completion hitting <TAB> (or <C-M-i>) key: e.g.: time.cl<TAB> -> time.clock time.<TAB> -> list of possible choices
description of the element (function/module/class/keyword) at the point hitting <F1> key
hitting '(' and ',' shows funtion signature e.g.: time.strftime( -> strftime(format[, tuple]) -> string
<F2> getting signature of a given function name
<F3> getting description of a given element name
=============== Python 2.x =================
Requirements
Pymacs the latest version from trunk or prepared package for Python2.x
python-mode or python-mode.el included in this package
Installation
if you choose original Pymacs install according to instructions
if you choose my Pymacs package: copy file pymacs.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp), and directory Pymacs on PYTHONPATH (e.g. /usr/lib/python2.7/site-packages)
copy files python-mode.el and pycomplete.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp).
copy file pycomplete on your PYTHONPATH (e.g. /usr/lib/python2.7/site-packages)
Copy the following settings to your .emacs file
# .emacs
;; python-mode settings
(setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
(setq interpreter-mode-alist(cons '("python" . python-mode)
interpreter-mode-alist))
;; path to the python interpreter, e.g.: ~rw/python27/bin/python2.7
(setq py-python-command "python")
(autoload 'python-mode "python-mode" "Python editing mode." t)
;; pymacs settings
(setq pymacs-python-command py-python-command)
(autoload 'pymacs-load "pymacs" nil t)
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(require 'pycomplete)
# end of .emacs
=============== Python 3.x =================
Requirements
Pymacs the latest version from trunk or prepared package for Python3.x
python-mode or python-mode.el included in this package
Installation
if you choose original Pymacs install according to instructions
if you choose my Pymacs package: copy file pymacs.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp), and directory Pymacs on PYTHONPATH (e.g. /usr/lib/python3.1/site-packages)
copy files python-mode.el and pycomplete.el on your Emacs load-path (e.g. /usr/share/emacs/site-lisp).
copy file pycomplete3 on your PYTHONPATH (e.g. /usr/lib/python3.1/site-packages)
Copy the following settings to your .emacs file
# .emacs
;; python-mode settings
(setq auto-mode-alist (cons '("\\.py$" . python-mode) auto-mode-alist))
(setq interpreter-mode-alist(cons '("python" . python-mode)
interpreter-mode-alist))
;; path to the python interpreter, e.g.: ~rw/python31/bin/python3
(setq py-python-command "python3")
(autoload 'python-mode "python-mode" "Python editing mode." t)
;; pymacs settings
(setq pymacs-python-command py-python-command)
(autoload 'pymacs-load "pymacs" nil t)
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(require 'pycomplete)
# end of .emacs

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,179 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-09T17:11:32+08:00
====== Emacs setup for python development ======
Created Monday 09 January 2012
http://www.yilmazhuseyin.com/blog/dev/emacs-setup-python-development/
This is the follow up for basic emacs setup post. In this post I will explain how to update your emacs setup for python development. I will cover
* pymacs (Python binding for emacs. This is a ropemacs dependency)
* rope (Python refactoring library.This is a ropemacs dependency)
* ropemacs (Rope bindings for emacs)
* rope-mode (Minor mode for ropemacs)
* pyflakes (passive checker of Python programs)
* flymake (an on-the-fly syntax checker for GNU Emacs)
* flymake-mode (Minor mode for flymake)
* pyflakes error format script
* autocomplete rope integration
Install pymacs
From emacs wiki I found http://pymacs.progiciels-bpi.ca/ page and download pymacs. I also read the manual from this page which has directions to how you can install it. Here is how I did it.
Untared downloaded file and did a “$sudo python setup.py install” in it.
Copy pymacs.el to somewhere in your emacs loadpath. I put it in ~/.emacs.d/plugins/pymacs.el
I also added the following to .emacs file like manual says
1
2
3
4
5
6
7
(autoload 'pymacs-apply "pymacs")
(autoload 'pymacs-call "pymacs")
(autoload 'pymacs-eval "pymacs" nil t)
(autoload 'pymacs-exec "pymacs" nil t)
(autoload 'pymacs-load "pymacs" nil t)
;;(eval-after-load "pymacs"
;; '(add-to-list 'pymacs-load-path YOUR-PYMACS-DIRECTORY"))
Install rope
I googled for rope and found this page http://rope.sourceforge.net/ and found rope-0.9.3.tar.gz. I untared it and did
1
$sudo python setup.py install
Install ropemacs
I found this page. From there, I downloaded ropemacs repository snapshot. When you get it just untar it and run
1
sudo python setup.py install
After that point I read README.txt that was included in untarred directory. I added following script to .emacs file as README.txt file suggested
1
2
(require 'pymacs)
(pymacs-load "ropemacs" "rope-")
Install rope-mode
From ropemacs page I gave in previouse section, I found ropemode repository snapshot and downloaded it. After I untarred it, I called following command as usual.
1
sudo python setup.py install
Install pyflakes
Google for pyflakes and when you find the project site download pyflakes from there. After that untarred it and inside untarred directory call
1
sudo python setup.py install
Install flymake
UPDATE: As Stéphane Raimbault suggested in the comments. flymake.el is already added in emacs. So you can skip downloading flymake.el.
Google for flymake, find project site and download it. When you get flymake.el put it somewhere on your emacs load path.(~/.emacs.d/plugins/flymake.el)
Add flymake mode
After that, you should configure flymake to work with pyflakes like emacs-wiki explains. Alternatively you can go to flymake-mode page to get the script.
In my case I added the following script and put it to my .emacs file
1
2
3
4
5
6
7
8
9
10
11
12
13
(when (load "flymake" t)
(defun flymake-pyflakes-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "pyflakes" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.py\\'" flymake-pyflakes-init)))
(add-hook 'find-file-hook 'flymake-find-file-hook)
Add flymake errors to mini-buffer
Flymake marks the errors with red. But it does not prints the error on screen. So I found a script that writes the errors on the current line to mini-buffer. Here is the script that I added to my .emacs file
1
2
3
4
5
6
(defun my-flymake-show-help ()
(when (get-char-property (point) 'flymake-overlay)
(let ((help (get-char-property (point) 'help-echo)))
(if help (message "%s" help)))))
(add-hook 'post-command-hook 'my-flymake-show-help)
Add autocomplete rope integration
If you have auto-complete in your emacs setup, you can actually integrate auto-complete with rope. To do this, I found this page. From there I downloaded script for rope-autocomplete integration. Here is the script that I added to my .emacs file.
1
2
3
4
(ac-ropemacs-initialize)
(add-hook 'python-mode-hook
(lambda ()
(add-to-list 'ac-sources 'ac-source-ropemacs)))
Note for django developers
If you are developing django apps you might want to cover emacs basic setup and emacs web setup post with this one. All three posts covers total of my emacs setup for developing django applications.
Date: 6 Mayıs 2011 | Tags: python, django, linux, emacs, installation, | Categories: emacs,

View File

@@ -0,0 +1,95 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-09T20:12:06+08:00
====== Pylookup ======
Created Monday 09 January 2012
http://taesoo.org/Opensource/Pylookup
Pylookup is a mode to** search python documents **especially within emacs.
===== Usage =====
1. M-x pylookup-lookup
{{./1-lookup.png}}
M-x pylookup-lookup, (set your local key map)
2. Ido autocompletion
{{./2-ido.png}}
Interactive do interface to search keywords
C-r, C-s : next/prev match
3. Search results
{{./3-search.png}}
Results of searching a keyword
n/p : next/prev line
C-v,M-v : scroll up/down
q : quit
Space/Enter : lookup document
4.Read in your browser
{{./5-browsing.png}}
You can see the proper python document in your favorite browser, w3m, firefox, ie or whatever.
===== Install =====
==== Checkout ====
git clone http://github.com/tsgates/pylookup.git
Edit .emacs
;; add pylookup to your loadpath, ex) "~/.lisp/addons/pylookup"
(setq pylookup-dir "[PATH]")
(add-to-list 'load-path pylookup-dir)
;; load pylookup when compile time
(eval-when-compile (require 'pylookup))
;; set executable file and db file
(setq pylookup-program (concat pylookup-dir "/pylookup.py"))
(setq pylookup-db-file (concat pylookup-dir "/pylookup.db"))
;; to speedup, just load it on demand
(autoload 'pylookup-lookup "pylookup"
"Lookup SEARCH-TERM in the Python HTML indexes." t)
(autoload 'pylookup-update "pylookup"
"Run pylookup-update and create the database at `pylookup-db-file'." t)
Change [PATH] variable to proper path where you installed pylookup
Add above code in your .emacs
===== Preferences =====
==== • Keybinding ====
(global-set-key __"\C-ch"__ 'pylookup-lookup) #这是缺省的绑定
==== • Lookup downloaded documents ====
Update Database (In repository, there is database to lookup online document, but slow to load in a browser)
$ cd ~/.lisp/addons/pylookup
$ ./pylookup.py -u file:///home/tsgates/.lisp/addons/pylookup/python-2.6.2-docs-html
$ ./pylookup.py -l test
COMPARISON_FLAGS (in module doctest) [lib];file:///home/tsgates/.lisp/addons/pylookup...
* Move to pylookup directory
* Execute pylookup.py with your absolute python document path, download from here
* Test by executing pylookup.py -l test and check pylookup indicating proper path you set
==== • Default browser ====
;; __w3m,系统需要安装w3m同时还需要安装emacs-3m插件__
(setq browse-url-browser-function 'w3m-browse-url)
(setq browse-url-default-browser "firefox.exe") ;; firefox in M$ Windows
==== • Numpy Support ====
self.list_entry = False" in IndexProcessor.__init__
===== Acknowledgements =====
Martin Blais's haddoc mode: http://furius.ca/haddoc
Github: http://github.com/tsgates/pylookup
This code is distributed under the GNU GPL v.2.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 KiB

View File

@@ -0,0 +1,49 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-09T19:27:11+08:00
====== pyflakes ======
Created Monday 09 January 2012
http://www.plope.com/Members/chrism/flymake-mode
I found something useful! I found something useful!
Flymake is an on-the-fly syntax checker for Emacs. Essentially every so often it runs your buffer through a language-specific__ syntax checker__ and __highlights code errors__ and __warnings__ in a different color. I can hear "real" IDE people laughing at me now, but for better or worse, I will probably use Emacs until I die; not because I like it particularly, but because it's the only thing my fingers know how to use, thus searching for better tools is pointless.
Out of the box, Flymake__ can't __analyze Python code, but it helpfully has a plugin system. It allows you to plug in, for example, __pylint or pyflakes__ or probably any other checker. I use pyflakes regularly.
whine[wain]n.闹声, 抱怨, 牢骚 v.哭诉, 发牢骚
Pyflakes is excellent, it basically __just whines when you're using a name that hasn't been defined __(an indictment of your lack of testing for that code path) or __you've imported a name twice__, or __you're not using a name that you've imported.__
http://developer.51cto.com/art/201003/190888.htm
Python CST 和AST 类似都是语法分析所获得的中间结果。他们的不同之处在于CST直接对应语法分析的匹配的过程是直接生成的含有大量冗余信息。而AST省略了中间的冗余信息直接对应实际的语义也就是分析的结果。
Importantly, it walks the Python AST rather than trying to import things (which other checkers seem to tend to try to do), so it's fast and using it has no side effects. I tend to__ use pyflakes as a before-checkin sanity check__ to make sure I haven't forgotten to remove an import, so it made sense to try to fit it into my editor.
Here's what I did to get it working. As I said, it's all cargo-culted, consistent with the rest of my Emacs configuration.
* I downloaded flymake.el and put it in a directory in my emacs load-path. I'm not even sure I needed to do this, I think it ships with Emacs now. Who knows, it works.
* I made sure I could invoke pyflakes as "pyflakes" (I put the pyflakes executable on my PATH).
pyflakes是一个可执行程序同时还有相应的python模块
* I added some (more) inscrutable stuff to my .emacs file
The stuff I added to the .emacs file:
(when (load "flymake" t)
(defun flymake-pyflakes-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "pyflakes" (list local-file))))
(add-to-list '__flymake-allowed-file-name-masks __
'("\\.py\\'" flymake-pyflakes-init)))
(add-hook 'find-file-hook 'flymake-find-file-hook)
The first stanza tells flymake to** use pyflakes on .py files when in flymake-mode**. The second tells emacs to always use flymake as a __minor mode__ when loading buffers so I don't have to type "M-x flymake-mode" to get syntax checking when I load a buffer.
And now! It works. I don't know how it works but it does. The below picture proves it (I import traceback but I don't use it).
And thus verify come the inane checkins for things I'm working on now that read "remove unused import".

View File

@@ -0,0 +1,73 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-09T22:37:53+08:00
====== python-mode and ipython ======
Created Monday 09 January 2012
https://bugs.launchpad.net/python-mode/+bug/912919
rev 752 breaks ipython
python-mode.el
Bugs
Bug #912919
Reported by Thomas Caswell on 2012-01-06
2 out of 4 heat flames
This bug affects 1 person
Affects Status Importance Assigned to Milestone
python-mode.el
Incomplete
Medium
Andreas Roehler
python-mode.el 6.0.5 "hill"
Also affects project Also affects distribution Nominate for series
Bug Description
Changing py-mode-map to python-mode-map broke ipython. I have added a hacky fix to their tracking.
https://github.com/ipython/ipython/pull/1242
Tags: ipython
Andreas Roehler (a-roehler) wrote on 2012-01-07: Re: [Bug 912919] [NEW] rev 752 breaks ipython #1
Am 06.01.2012 21:57, schrieb Thomas Caswell:
> Public bug reported:
>
> Changing py-mode-map to python-mode-map broke ipython. I have added a
> hacky fix to their tracking.
>
> https://github.com/ipython/ipython/pull/1242
>
Hi,
need some recipe to reproduce.
Completion in IPython works fine here with TAB.
Did you patch against current trunk?
BTW have a look at
defcustom py-complete-function
thanks,
Andreas
Andreas Roehler (a-roehler) on 2012-01-07
Changed in python-mode:
importance: Low → Medium
status: New → Incomplete
assignee: nobody → Andreas Roehler (a-roehler)
milestone: none → 6.0.5
https://github.com/ipython/ipython/pull/1242
===== changed key map name to match changes to python mode =====
This is a minor change to handling the python-mode key mappings. In reversion 752
( http://bazaar.launchpad.net/~python-mode-devs/python-mode/python-mode/revision/752 ) the name of the map was changed from py-mode-map to python-mode-map.
This isn't in any distributions yet, so I am not sure how you want to deal with this.

View File

@@ -0,0 +1,16 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-19T18:26:43+08:00
====== Emacs 的 Change Log 功能 ======
Created Friday 19 August 2011
很多时候,我们的程序目录里并没有像样的版本管理功能(比如自己的一些小工具),过了一段时间,你很可能会发现你不记得以前修改了一些什么、已经实现了哪些功能,甚至于,你都忘记了你的代码里还有啥小 Bug 没处理掉。
Emacs 自带了一个快速日志记录功能,即 Change Log 的功能。一个 Change Log 文件按时间顺序记录了你修改程序的时间、原因以及一些你想写下来备忘的内容。当然Emacs 只会自动帮我们生成记录的时间、修改的文件名,其它的内容还是需要我们自己来补充。
默认情况下Emacs 会用当前目录下名为 ChangeLog 的文件来记录这些 log 信息,该文件可以记录该目录以及所有子目录的日志。
用快捷键 C-x 4 a 或是命令 M-x add-change-log-entry-other-window 就可以为当前编辑的文件在 ChangeLog 文件里添加一条日志Emacs 会自动创建时间戳和文件名,剩下的内容我们自己补全。
类似于其他 Emacs 提供的功能,我们可以根据自己的喜好来设置参数,详情看 Chang Log 的官方文档。

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-14T21:08:00+08:00
====== Emacs 编辑环境 ======
Created Thursday 14 April 2011

View File

@@ -0,0 +1,361 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-14T21:08:52+08:00
====== 1基础部分 ======
Created Thursday 14 April 2011
===== 介绍 Emacs 的编辑环境 =====
您首先应当知道的是,在 UNIX 中最流行的两种编辑器是 Emacs 和 vi两者都有超过 30 年的历史。不过,它们都是很难过时的工具。和 UNIX 一样,这些编辑器的基本设计已有几十年之久,但是在最先进的开发中,它们仍然得到了广泛的应用。
Emacs 是历史上最早的开放源代码和免费软件工程之一。它的发明者 Richard Stallman 建立了 GNU 工程及其父组织—自由软件基金会(请参阅参考资料)。甚至在 Stallman 发布 GNU 公共许可GNU GPL一种许可条款如今的大多数开放源代码软件都是在该条款下发布的之前他就已经在类似的免费 copyleft 软件许可(被称为 EMACS 公共许可)下发布了 Emacs 的源代码。
Emacs 这个名字已经成为专有名词,但它最初是一个首字母缩写词,代表 Editing MACrosStallman 最初实现的是用 TECO 语言写成的一组宏。Emacs 现在是用 Emacs Lisp 编写的,后者是一种优雅的高级编程语言。
GNU 工程的简要介绍中称 Emacs 是一种自身配备了相关说明文档的可扩展文本编辑器 (the extensible self-documenting text editor)。Emacs 是可扩展的,这意味着可以在已有功能的基础上添加或构建新功能。之所以有这种可能,是因为它是用 Lisp 编写的,您可以编写新的 Emacs Lisp 例程以添加新功能。您甚至能在 Emacs 会话还在运行时运行这些新功能。它自身配备了相关说明文档,因为每个按键都有相应的即时帮助,即使在键入一个命令时也能显示帮助信息。这样,您可以单击 Help 按钮,弹出各种可能情况的列表。
Emacs 被称为一个编辑环境,因为它不仅仅是一个普通意义上的、用于纯文本编辑的编辑器。许多管理员和开发人员在各种平台上用它来编译和调试程序、管理电子邮件、在系统中操作文件、运行 shell 命令,以及完成很多其他工作。人们甚至用它在 Usenet 新闻组中进行交流,还用它来浏览网页。扩展包和内置插件可以处理从 Internet 中继聊天 (Internet Relay Chate, IRC) 和发送消息到网络通信的各种情况。一个流传很久的 UNIX 笑话是这样说的:“如果 Emacs 环境里有一个好的编辑器的话,它就不至于这么糟糕了。”
因为很多任务都可以用 Emacs 来完成,所以它也有自己的词汇表,当您在这一部分中深入了解典型的 Emacs 窗口时,您将学到这些词汇。这一部分还介绍了如何启动和停止 Emacs以及如何键入各种命令。
启动 Emacs
要从 shell 中启动 Emacs键入
__emacs__
如果您在控制台或终端中启动 Emacs您会看到它打开后充满了整个终端窗口如图 1 所示。
如果您是在 X 客户端Emacs 一般会在属于它自己的窗口中打开,如图 2 所示。您还可以指定让它在某个终端窗口打开(如图 1 所示方法是使用__ -nw __选项。乍一看Emacs 的这两个视图似乎是不同的应用程序但两者只有表面的差别。它们仅有的真正不同之处在于缺省的颜色、X 客户端显示的图形徽标,以及 X 客户端顶部附近的图标组(包含某些最常用命令的快捷方式)。两者的文本功能和 X 版本是一模一样的。
===== Emacs 窗口剖析 =====
这个屏幕的有些部分需要现在就解释一下。我们从顶部开始,向下介绍。
==== 菜单栏 ====
在 Emacs 屏幕顶部是一个突出显示的条,上面有一些单词。这被称为菜单栏,您可以在菜单中选择常用的 Emacs 命令。您能用键盘访问这些菜单;在 X 客户端中,您还可以用鼠标展开菜单。专家们通常会配置他们的 Emacs使它关闭菜单栏好在屏幕上留出更大的编辑空间。但是在您学习 Emacs 时,菜单栏是帮您熟悉其丰富功能的好方法。此外,如果您在 X 中打开了 Emacs您会看到顶部有一组特殊的图标请参见图 2它们是某些最常用的菜单选项的快捷方式。要用键盘访问菜单栏请按__ F10__。现在就试试看看终端中是如何打开一个新的窗口并显示菜单列表的如图 3 所示。
==== 从 Emacs 菜单栏中进行选择 ====
您可以使用向上或向下的**方向键**,在菜单选项中移动,然后按 Enter。如果您选择的项目有一个子菜单它会显示在屏幕上。您可以用同样的方法在新的子菜单中选择一个项目直到您选中了要运行的命令为止。如果您想终止这一过程可以随时按下 Ctrl-G。这个特殊的键盘输入会使计算机发出一声蜂鸣声并退出当前正在执行的任何命令。如果没有正在执行的命令按下这个键盘输入只会使计算机发出蜂鸣声。请现在尝试一下。
===== 窗口 =====
屏幕中央大片的主要区域被称为 Emacs 窗口,它是您进行编辑工作的地方。当您打开一个要编辑的文件时,这里将显示该文件的内容。当文件或文档中的内容显示在 Emacs 窗口中时,它被称为**缓冲区**。您可以随时在 Emacs 中同时打开多个缓冲区(即使它们不会显示在主窗口中也一样)。在编辑会话中,虽然只有一个缓冲区会显示在窗口中,但您一般仍会打开多个缓冲区。在 X 客户端中,在窗口的左边会显示一个滚动条。(终端的版本也会出现,但它仅在打开某个缓冲区时显示。)滚动条显示 Emacs 窗口中的文本与缓冲区剩余部分的位置关系与大小关系。
===== 模式行 =====
在每个 Emacs 窗口中都有一条横贯底部的高亮条,它被称为模式行,您可以把它看成是状态栏。它将为您提供有关** Emacs 会话和当前缓冲区**(在上面的窗口中显示)的信息,包括您做出的最新修改是否已被保存到磁盘、光标所在行的行号、屏幕底部显示的内容在缓冲区中的位置(用占总体的百分比表示),以及当前有哪些 Emacs 功能和设置处于活动状态。
===== 迷您缓冲区 (minibuffer) =====
在模式行下面和屏幕(或 X 客户端窗口)底部的一片小空间被称为迷您缓冲区 (minibuffer)。这是 Emacs 用来显示与操作相关的消息的地方。当 Emacs 要求您输入某种内容(如某文件的名称)时,将在此处显示。与 UNIX shell 类似,迷您缓冲区使用制表符作为提示符。按下 **Tab **键可获得一个可能情况的列表。另外在minibuffer中输入信息时可以用M-p M-n 以及常用的移动删除命令。
===== Emacs 的键绑定 =====
一**个用来调用特定命令的 Emacs 组合键被称为一个键绑定**。这些都可以自定义,但 Emacs 也附有缺省的绑定。
一眼看去,为数众多的 Emacs 键绑定似乎很复杂,让人不知所措,不过请务必记住,它们是为了提高您的速度和便于记忆而专门设计的。通常每个绑定都有一个记忆的方法,如 S 键就是用来保存 (save) 的。在您尝试使用它们时请想想这一点。__总的说来Emacs 命令可分为两大类:一类要使用 Ctrl 键,而另一类使用 Meta 键。__
===== Ctrl 组合键 =====
许多 Emacs 命令是由某个 Ctrl 组合键指定的。.在 Emacs 的符号中Ctrl 键写成“C-”,后面则是与第二个按键对应的字符。例如,在 Emacs 符号中Ctrl-X 组合键写成 C-x。要输入一个 Ctrl 组合键,请按住 Ctrl 键,然后按第二个键,然后将两个键同时松开。大多数命令都有一个 Ctrl 组合键,在按下此组合键后要再输入一个单词或第二个 Ctrl 组合键。例如,可以尝试运行 C-x C-s 命令,将当前的缓冲区保存到磁盘。因为您没有作出更改,所以也无需进行保存,但这个组合键值得一试。现在,请尝试进行以下操作:
按住 Ctrl 键。
按 X 键,然后把两个键同时松开。
再按住 Ctrl 键。
按 S 键,然后把两个键同时松开。
这个键盘输入将运行 save-buffer 命令。在迷您缓冲区中Emacs 会报告“(No changes need to be saved)”。
Emacs 用户在按这些组合键时,**在第二个步骤中往往不会松开 Ctrl 键,这样可以省去第三个步骤**,加快键入速度。请尝试一下。
===== Meta 组合键 =====
Emacs 键盘输入中的第二种主要类型是 Meta 键;在 Emacs 符号中Meta 按键被表示为 M-。如果您从未听说过 Meta 键,那是因为目前的大多系统并没有这个键。输入 Meta 组合键,有三种方法:
Meta 键常被绑定到 Alt 键,使用方法与 Ctrl 键类似。如果您的设置就是这样,请使用该设置,这是最简单、最常见的方法。
通常您可以使用 Esc 键完成一个 Meta 按键序列,但您的操作与输入一个 Ctrl 按键序列时不同。按下 Esc然后松开再按第二个键。
您可以用 Ctrl-[ 代替 Esc 键。如果您通过网络线路运行 Emacs无法使用 Esc 和 Alt 键,这种方法会很方便。
请尝试输入 M-b 命令,这会把光标向回移动一个单词,有三种操作方法:
按住 Alt 键,然后按一下 B。
按下 Esc然后松开再按一下 B。
按住 Ctrl 键,再按 [,同时松开两个键,然后再按一下 B。
您运行的**每个 Emacs 命令都是一个函数,由 Emacs Lisp 定义,并有一个函数名**。甚至连用向上方向键将光标向上移动一行也是一个函数previous-line。您可以使用 M-x 命令,然后再输入函数名,运行任意一个函数。
请尝试以下操作:
按住 Alt 键。
按 X 键。
同时松开两个键您会注意到迷您缓冲区中会出现“M-x”字样。
键入 previous-line 并按 Enter。
当您这样操作时,光标会向上移动一行。当然,您平常是不会这样运行这个函数的,因为使用向上方向键比这容易多了,不过这是个好例子。函数为数众多,而且由于 Emacs 是可扩展的,您可以编写自己的函数以扩展其功能。
与通过向上方向键运行 previous-line 类似的是,**许多函数都分配了快捷键。当您输入这样的一个键或组合键时,将运行相应的函数**。您还可以使用 C-p 运行 previous-line 函数。现在,请尝试下面的操作:
按住 Ctrl。
按 P 键。
再按方向键,将光标移到窗口的顶部。
作为总结,表 1 列出了您可以在 Emacs 键绑定中使用的主要按键前缀类型。和 Emacs 中的其他东西一样,这些都是可以自定义和重新定义的。
__表 1. 常用的缺省 Emacs 按键前缀__
按键前缀 描述
C-c 当前**编辑模式特有**的命令
C-x 文件和缓冲区命令
C-h 帮助命令
M-x 函数名称
===== 停止 Emacs =====
要退出 Emacs请键入
__C-x C-c__
如果有未保存的缓冲区,这个命令会使您有机会保存它们。
这是退出 Emacs 的一般方法。请现在就试着操作一下,然后在 shell 的提示符下键入 emacs重新启动 Emacs。
===== 缓冲区和文件 =====
在这一部分中,将介绍最重要的 Emacs 缓冲区和文件命令:如何将文件载入缓冲区,如何将缓冲区保存到文件,如何在缓冲区间切换,以及如何“杀死”缓冲区。
===== 从头创建一个新文件 =====
当您用普通的方式启动 Emacs 时,它将向一个名为** scratch **的缓冲区开放,该缓冲区的用途显示在缓冲区顶部的一条消息中:
;; This buffer is for notes you don't want to save,
and for Lisp evaluation.
;; If you want to create a file, visit that file with C-x C-f,
;; then enter the text in that file's own buffer.
模式行左边的区域始终用来显示当前缓冲区的名称。在此处,您可以看到这个缓冲区的名称,即 *scratch*。**如果是 Emacs 自动创建的特殊缓冲区,其名称两边会有星号。**
试着输入一行文本This is a practice file. 然后再按 Enter将光标向下移到一个新行。当您开始输入时您会看到**模式行的左侧出现两个星号,这表明当前的缓冲区中有未保存到磁盘的文本。**
创建新文件的方法之一是将 scratch 缓冲区写到某个文件中。组合键 __C-x C-s 会运行 save-buffer__ 命令将当前的缓冲区保存到某个文件。正如您先前看到的当您在一个无需保存的缓冲区中运行此命令时Emacs 会显示相应的信息。但如果在您运行该命令的缓冲区中有未保存的更改,且该缓冲区与磁盘上的某个特定文件相关联时,缓冲区的内容会被写入该文件。如果您是在新缓冲区或某个没有与文件关联的缓冲区(例如您现在所在的 scratch 缓冲区中运行该命令Emacs 将提示您指定用来保存该缓冲区的文件名称。
现在,请尝试下面的操作:键入 Ctrl-x Ctrl-s。看看在迷您缓冲区中是如何要求您给出要保存的文件名称的如图 4 所示。现在键入 practice。
在您按下 Enter 后Emacs 会在迷您缓冲区中报告,有一个名为 practice 的新文件已被写入磁盘。键入 C-x C-c退出 Emacs然后查看目录找到您的文件
关于 scratch 缓冲区,还有一件事是需要记住的。**如果 Emacs 中没有打开其他缓冲区,那么 scratch 缓冲区会一直存在,当它是打开的唯一缓冲区时,是无法被关闭的。**
===== 利用文件名启动 Emacs =====
要使 Emacs 启动时将某个特定的文件的内容放进一个新的缓冲区中以便编辑,请提供此文件的名称作为参数。如果您提供了多个文件,则每个文件会在属于它自己的缓冲区中打开。**如果您提供的文件名在磁盘上不存在Emacs 会为该文件创建一个新的缓冲区**,并说明(在模式行中)这是一个新文件。这是您在启动 Emacs 并编辑一个新文件时所做的。当您将缓冲区保存到磁盘时Emacs 将其写入文件,并使用您提供的参数做为它的文件名。
请试着用您的文件“practice”启动 Emacs
您仍会看到 Emacs 的欢迎屏幕,但如果您按下一个键,如 C-g或等足够长的时间您会在 Emacs 窗口中看到您文件。没错,欢迎屏幕是另一个可供配置的选项。
===== 打开一个文件 =====
Emacs 不会对文件的内容进行直接操作。它会把文件内容的副本读取到您编辑的缓冲区中。使用 __C-x C-f即 find-file 命令__以便用文件的内容打开一个缓冲区。
===== 访问缓冲区 =====
C-x b 命令可以从当前缓冲区切换到您指定的另一个缓冲区。迷您缓冲区中始终会提供一个缺省的缓冲区选项。如果您按下 Enter 且没有指定缓冲区的名称,您会切换到上述的缓冲区。**缺省值一般是您上次访问的缓冲区**。如果您之前没有访问任何缓冲区,则缺省值通常为 scratch 缓冲区。
现在键入 C-x b注意 scratch 缓冲区会作为建议项显示在迷您缓冲区中。键入 Enter您的 practice 文件将从窗口中消失,代之以您熟悉的 scratch 缓冲区中的内容。在缺省情况下scratch 缓冲区会包含三行消息,但有时该缓冲区为空白。)再次键入 C-x b然后按 Enter切换回 practice 缓冲区。
在 Emacs 中,如果您希望创建一个新的缓冲区,请切换到您要指定名称的那个缓冲区。
再次键入 C-x b不过要将该缓冲区命名为 mybuffer。注意窗口是空的这是一个全新的缓冲区。键入一行文本然后按 Enter
On what wings dare we aspire?
键入 C-xC-s将这个缓冲区保存到磁盘。注意现在 Emacs 会要求您指定一个文件名。__如果您创建的新缓冲区没有与磁盘上的某个文件关联您可以在决定保存它时指定一个文件名。您指定的文件名不必与缓冲区名称相同可以把它命名为 practice.b请注意Emacs 会改变缓冲区的名称使之与新文件相符。__
===== 杀死缓冲区 =====
请使用 C-x C-k 命令杀死某个缓冲区,或将其排除在您的 Emacs 会话之外。您将被提示键入要杀死的缓冲区的名称,**当前的缓冲区是缺省缓冲区**,如果您直接按下 Enter会将它杀死。
现在试着杀死旧的 practice 缓冲区键入__ C-x C-k__然后当 Emacs 在迷您缓冲区中要求输入一个缓冲区名称时,键入 practice然后按 Enter。practice 缓冲区会被杀死,而 practice.b 缓冲区则像刚才一样留在窗口中。
===== 将缓冲区保存到磁盘 =====
您已经知道了如何通过运行 **C-x C-s save-buffer 命令**,将缓冲区的内容保存到磁盘。您需要了解这一过程的更多信息。
模式行的前几个字符描述了缓冲区的状态。现在,在您的 practice.b 缓冲区中键入另一行文本,然后按 Enter
What the hand dare seize the fire?
注意,模式行中的两个破折号会变成两个星号。**破折号说明缓冲区的内容与磁盘中的相同,而星号则表示缓冲区中有未保存的编辑内容**。
保存更改并退出 Emacs键入 C-x C-s C-x C-c。您的目录中会多出几个新文件
$ ls
practice
practice.b
practice.b~
practice 和 practice.b 文件是您创建的,但 practice.b~ 则是一个由 Emacs 自动创建的文件。这是 Emacs 的备份文件,当您每次在 Emacs 中编辑一个已经存在的文件时都会创建这个备份文件。当**您将编辑内容保存到文件时Emacs 会写到一个新文件中以制作备份(此编辑会话第一次保存该文件时创建)**,这个新文件的名称与原先的文件相同,只是多了一个波浪符号。旧的 practice 文件没有备份,因为您在创建它之后从未对其进行编辑。如果您此后在 Emacs 中编辑了它Emacs 会将内容写入相应的 practice~ 备份文件。
Emacs 还会写入另一种文件,被称为 autosave 文件它与原先的文件名称相同但是在名称前后会各添加一个英镑符号。在您操作缓冲区期间Emacs 会按设置的间隔向 autosave 文件写入内容。在缺省情况下是每输入 300 个新字符就向 autosave 文件写入一次。通常,**在您杀死缓冲区时是不会见到 autosave 文件的。**这是因为与缓冲区关联的 autosave 文件被删除了。如果您的系统崩溃或您在编辑会话中失去连接autosave 文件很有用,它为您提供了一个选择,使您可以在目录下找到这个文件以恢复丢失的编辑内容。
__缓冲区和文件命令总结__
表 2 包含的是某些最常用的缓冲区和文件命令列表,在您学习 Emacs 的过程中将用到这些命令。该表提供了命令绑定的键盘输入和命令的函数名。请记住,**您总能使用相应的键绑定,或将相应的函数名作为 M-x 的参数,以运行某个命令**(请参考学习如何键入 Meta 组合键)。
绑定 函数名 描述
C-x C-s save-buffer 将当前的缓冲区保存到磁盘。
C-x s save-some-buffers 要求将所有未保存的缓冲区保存到磁盘。
C-x C-c save-buffers-kill-emacs 要求将所有未保存的缓冲区保存到磁盘,并退出 Emacs。
C-x C-z suspend-emacs 挂起 Emacs 并使之成为一个后台进程。
C-x C-b list-buffers 列出所有缓冲区。
C-x k kill-buffer 杀死一个缓冲区(缺省情况下为当前的缓冲区)。
C-x C-q vc-toggle-read-only 切换当前缓冲区的可读状态(如果适用还可以执行版本控制)。
C-x d 打开目录
C-x i insert-file 在插入点插入某个文件的内容。
===== 在 Emacs 中编辑文本 =====
在缓冲区中输入和更改文本,以及在文本中进行导航,是您在 Emacs 中最重要的操作,无论您是在编辑文件,创建新文件,还是仅仅想研读某个文件,都要用到它们。在此部分,您将学习用来完成下述工作的基本按键序列和命令:如何在缓冲区中输入文本,如何在文本中导航,以及如何对文本进行基本的编辑,如删除字符和单词。
==== 键入文本和在缓冲区中移动 ====
正如您在从头创建一个新文件这一部分看到的,在 Emacs 缓冲区中输入文本是很容易的您只要动手打字就行。您可以键入字母字符将其输入某个缓冲区中。Emacs 有时会被称为**无模式编辑器**,常被拿来与模式编辑器如 vi 等作比较。这意味着编辑器的行为以及您可以键入的键盘输入和命令在您的会话中是保持不变的,与 vi 等编辑器不同后者的击键会根据您是在命令模式还是在输入模式而有不同的含义。Emacs 没有这类模式;不过,它确实有一种不同的模式,可以用来更改其行为或扩展其功能,这将是本系列的下一篇教程的主题。进行普通的输入时,有些事是您必须记住的。
==== 在插入点插入文本 ====
在 Emacs有一个重要的概念被称为__插入点point它表示字符的插入位置。这是缓冲区中一个想像的位置处于光标所在字符和前一个字符之间。__
每当您在缓冲区中输入文本时,该文本都会在这个点插入。**在缺省情况下,所有文本都在同一**行,在这个点之后的文本会向右推移,为您插入的内容让出空间。按 Enter移到下一行然后再按一下 Enter插入一个空白行。
在每一行的末尾按 Enter以输入一个段落然后在结尾再按一下 Enter创建一个空白行。
===== 移动插入点 =====
您会看到,在您键入时光标会一直跟随,**插入点保持不变**:从您键入第一个句子开始,您键入的一切内容都被插入字母 O 之前。要移动插入点,您可以使用方向键,而且正如您预期的那样,所有其他与光标动作有关的键都可供使用,如 PgUp、PgDn、Home 和 End。但 Emacs 自带用来移动光标的键绑定,而且因为您不必将手移到键盘的基准键之外就能使用它们,所以您在打字时会觉得它们非常有用。
正如您在学习如何键入 Meta 组合键部分中看到的,您可以使用 C-p 将标向上移动到上一行类似地C-n 将光标向下移动到下一行。C-f 会向前移动到下一个字符,而 C-b 会向后移动到上一个字符。
如果不想用 PgDn 和 PgUp 键向上和向下移动一屏,请使用 C-v 和 M-v 这两种键盘输入,它们可起到与前两个键相同的作用。要转至当前行的开始处,请使用 C-a使用 C-e转到当前行的结尾。
通常 Meta 键会被绑定到某个命令,这与相应的 Ctrl 键类似,对于移动命令,这条规则也同样适用。当使用 Meta 来代替 Ctrl 时F 和 B 键可以向前和向后移动一个单词 而不是一个字符,而 A 和 E 键可以移动到当前句子的开头和结尾。(在缺省配置中,没有定义 M-n 和 M-p 键盘输入。)
表 3 列出了各种移动和导航的键,以及它们的函数名和描述。试着用它们移动到缓冲区的开头、结尾,和中间的某些位置。
__表 3. 有用的 Emacs 键盘输入用于移动和导航__
键盘输入 函数 描述
C-p,
UpArrow previous-line 将插入点向上移动到上一行。
C-n, DownArrow next-line 将插入点向下移动到下一行。
C-f, RightArrow forward-char 将插入点移动到下一个字符。
C-b, LeftArrow back-char 将插入点移动到上一个字符。
M-f forward-word 将插入点移动到下一个单词。
M-b backward-word 将插入点移动到上一个单词。
C-v, PgDn scroll-up 将文本向上滚动一屏。
M-v, PgUp scroll-down 将文本向下滚动一屏。
Home beginning-of-buffer 将插入点移到缓冲区的开始处。(在某些版本中,这个键被缺省定义为移动到当前行的开始处。)
M-< 同上
End end-of-buffer 将插入点移到缓冲区的末尾。(在某些版本中,这个键被缺省定义为移动到当前行的末尾。)
M-> 同上
C-a beginning-of-line 将插入点移到本行的开始处。
C-e end-of-line 将插入点移到本行的结尾。
M-a beginning-of-sentence 将插入点移到句子的开始处。
M-e end-of-sentence 将插入点移到句子的结尾处。
C-{ beginning-of-paragraph 将插入点移到段落的开始处。
C-} end-of-paragraph 将插入点移到段落的结尾处。
===== 使用改写模式 =====
正如您看到的,您键入的文本被插入到插入点处。不过您也可以改写现有的文本。按一下 Ins 键这将切换到改写模式该模式在缺省情况下是关闭的。查看模式行您会看到__ Ovwrt__说明该模式已处于活动状态。用表 3 中描述的移动命令,移动光标,使之处于 we 中的 w 处,然后键入一个 h 字符。
请试着转至缓冲区的顶部:键入 M-a M-a C-f将光标移到 y然后输入一个 i 字符。对于下一个 y采取同样的操作键入 M-f C-f C-f C-f i以使缓冲区看起来如图 6 所示。
===== 引用插入 =====
文本并不仅限于用字母键输入。您可以输入控制字符,也可以根据字符代码输入字符。为此您可以执行**引用插入,该命令被绑定到 C-q**;此后再按一个键(或组合键)如 Ctrl 组合键,以便在插入点输入该键。您还可以输入一个字符代码值(用八进制表示),然后再按 Enter 键。
移到缓冲区的末尾,键入 Page break here然后按 Enter。现在键入一个分页符即 Ctrl-l 代表的字符,在它的后面接一个转义字符,该转义字符的八进制字符值为 033 C-q C-l C-q 033 Enter.
===== 删除,撤消和重复 =====
现在您可以试试 Emacs 中的一些工具,这些工具用来处理现有文本以及撤消(和重复)您已经做出的操作。
===== 删除文本 =====
**使用 Backspace 或 Del 键不是Delete键删除插入点左边的字符。**试着用这两个键删除您刚才输入的两个控制字符。
要删除**插入点右边即光标上**的字符,请用 C-d类似地M-d 会**从插入点**开始,删除到单词的末尾。您还可以向回删除,**M-Del 和 M-Backspace 都可以从插入点一直删除到单词的开头。或用**__M--反向操作符__**如:**
M-- C-d 反向删除一个字符
M-- M-d 反向删除一个单词
将光标移动到文件的最后一行应该是“What the hand dare seize the fire?”这个句子),然后按几次 M-d把这一行删除。
===== 撤消和重复 =====
啊呀,如果您并不想删除最后一句怎么办?您可以通过运行 undo 函数把它找回来。该函数被绑定到 __C-___您要键入它请按住 Ctrl并用 Shift 键输入下划线。请回到最后一行试试,每个单词操作一次,找回这些单词。
多操作几遍,直到 Page break here 重新显示为止。
现在您又对上次的撤消操作感到后悔了,您确实不想要 Page break here 了。您可以重复您撤消的操作,方法是键入 C-g这将取消所有的撤消操作然后多次键入 C-_ 使单词再次消失。
===== 多次运行同一个命令 =====
__C-u 是一个通用参数命令但还有其它含义如__后面接一个数字和一个命令。它将按某个次数多次运行特定的命令。
尝试以下操作:移动到第二句诗的开始处,键入 In what distant d然后再键入 C-u 2 e这将写入两个 e 字符。输入以下内容,完成诗句:
ps or skies
Built the fire of thine eyes?
===== 使用通用参数插入字符 =====
在**没有数字参数的情况下C-u 会假定这个数字为 4**。如果您将 C-u 本身作为参数,则 4 会自乘,得到 16您可以在反复自乘任意多次之后再指定一个命令如 C-u C-u C-u A 会在插入点处键入 64 个 A。
请用一个 C-b向回移动您会看到光标会回到前面的一行。现在试试通用参数键入 C-u C-b注意光标向回移动了四个字符而不是一个。再试试 C-u C-u C-b注意光标会向左移动 16 个字符。键入 C-u C-u C-u C-b然后再指定 1000 作为参数C-u 1000 C-b。光标会移动到缓冲区的开始处但请注意Emacs 会发出蜂鸣声,这表明它在完成要求的操作次数之前就已经到了缓冲区的顶部(无法再向回移动了)。
我们来总结一下刚才学到了什么。在您继续学习下一部分之前,请看看表 4它列出了重要的编辑命令和执行这些命令时用的缺省键盘输入。
__表 4. 常用 Emacs 编辑命令__
键盘输入 函数 描述
Ins overwrite-mode 切换改写模式(缺省为关闭)。
Backspace
Del delete-backward-char 删除插入点前的字符。
C-d delete-char 删除插入点处的字符。
M-d kill-word 从插入点开始向前删除字符,直到单词末尾。
M-Backspace,
M-Del backward-kill-word 从插入点开始向回删除字符,直至单词的开始处。
C-_ undo 撤消您的上一次键入或操作
C-q 字符 或 XXX quoted-insert 在插入点插入按键本身代表的字符或由八进制数字XXX表示的字符。
C-u 次数 命令 universal-argument 按总的次数(缺省为 4 次)连续执行命令。
M- 次数 命令 digit-argument 同上
===== 标记和鼠标 =====
您正在顺利地学习关于 Emacs 编辑的所有基本知识,但还有一些重要的概念是您需要知道的:如何标记文本区域并在这些区域上执行操作,以及如何使用鼠标。
==== 标记、移除、删除 ====
Emacs 有一项标记文本区域的功能,您可以将这个**区域作为一个整体进行编辑**:表 5 中对这些命令进行了描述和简要介绍。
==== 标记一个区域 ====
移动到缓冲区的顶部,即诗的第一节的开始处,然后键入** C-Space**,或**C-@**,方法是按住 Ctrl再按空格键。这被称为**设置标记**;迷您缓冲区中会出现一条消息,告诉您已经设置了标记。
**插入点和您设置标记的位置(包括标记处的字符)之前的部分被称为区域。**
将插入点由开始处移动到小节后的空白处,将整个第一小节设置为区域
===== 删除和恢复文本 =====
有些特殊的命令可用来操作区域,包括 C-w它能删除区域。
键入 C-w删除您刚才定义的区域。
每次您删除文本时,这些文本都会保存在 Emacs 的__ kill ring__ 中。您可以用 C-y 把它们恢复到插入点。移动到缓冲区的末尾,按 Enter插入另一个空白行然后将这个小节移回去。
您不仅能删除区域;使用 C-k 还可以删除从插入点到行末的所有文本。向上移到以 Tiger 开头的一行,然后用 C-k 删除它。注意,这一操作不会删除空白行;还要第二次使用 C-k。按此操作然后使用 C-y 将整行移回去。如果您用多个删除命令连续进行删除,它们会叠加在一起,只返回一个移除内容。
您可以将某一行恢复任意多次。移动到缓冲区的顶部,然后再次使用 C-y 把它移回去。
您还可连续多次使用 C-k 键盘输入进行删除,删除的内容会被移到一起。请试试一次删除多行,然后使用 C-y 将它们移回原先的位置。
===== 复制文本 =====
如果您是想复制区域,不必删除它。如果要将区域保存在 kill ring 中而不是删除它,请使用 M-w而不是 C-w
__表 5. 用来标记和删除文本的 Emacs 函数__
键盘输入 函数 描述
C-Space set-mark-command 在插入点设置标记。
C-k kill-line 删除从插入点到行末的所有文本。
C-w kill-region 删除区域。
M-w kill-ring-save 将区域保存在 kill ring 中,但不删除它。
C-y yank 恢复来自 kill ring 的文本。
===== 用鼠标进行标记和移动 =====
虽然 Emacs 是为了用键盘快速操作而设计的,但是您也可以使用鼠标,这对文本操作来说有时是很方便的。
要将**插入点移到缓冲区的任意位置**,请把鼠标指针移到该位置,然后单击一下鼠标左键。试着用鼠标移动到诗的第二节和第三节之间的空白处,然后键入新的一节。
用**左键**__双击__**一个单词以选中它**。双击您刚刚键入的 Tiger它将突出显示然后按 Del 将它删除。现在键入 Lamb将这个单词插入插入点处。
要用**鼠标选择一整行,请用鼠标左键**__三击__该行。请在顶行尝试此操作然后按 Del 将该行删除。键入 C-_ 恢复删除的内容。
在缓冲区的中间单击鼠标左键,然后再输入两段,完成这首诗:
您可以单击鼠标左键(设置区域的开始标记),然后拖动以选择一个区域,在释放左键前单击一次右键可以将选区内容复制到 kill ring 中,单击两次右键将删除选区。您可以使用 C-y 或鼠标中键将文本复制到插入点处。
===== 表 6. Emacs 中的鼠标操作 =====
鼠标命令 描述
B1 这一命令将设置插入点位置;拖动鼠标左键以设置区域。
B1-B1 这一命令标记一个单词。
B1-B1-B1 这一命令标记一行。
B2 这一命令将移除文本。
B3 这一命令会设置并突出显示区域,然后无需删除就将其放在 kill 缓冲区中。__如果某个区域已经被突出显示并设置该区域的末尾将移动到您单击的位置。__
B3-B3 这个命令将突出显示区域,然后删除它。如果某个区域已经被突出显示并设置,该区域的末尾将移动到您单击的位置,此后该区域将被删除。

View File

@@ -0,0 +1,105 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-14T21:57:03+08:00
====== 2基本模式和编辑特性 ======
Created Thursday 14 April 2011
===== 编辑模式 =====
Emacs 被划分为无模式 的编辑器,这意味着它与其他的编辑器(如 vi有所不同对于运行编辑器命令或者向缓冲区插入文本的插入模式没有特殊的命令模式——正如您在本系列前面的教程中所看到的可以在任何时候完成命令和文本插入。
然而Emacs 也有它自己的编辑模式,这就是**扩展它的能力或者改变一些特性工作方式的函数**。这些模式通常用于编辑某种类型或类别的数据如常规文档使用任何印欧语言编写、用特定的计算机编程语言C、Fortran、Lisp 等等编写的源代码、采用某种方式进行格式化大纲、电子邮件消息、Usenet 文章、基于字符的示例等等)或使用标记语言(超文本标记语言 (HTML)、Nroff、TeX 和可扩展标记语言 (XML)的文本。甚至专门有一种模式用于编辑非文本二进制的数据。另外Emacs 还提供了许多特殊的模式,可用于其他数据类型和系统处理,包括网络连接和网际中继交谈 (IRC)、Shell 会话和 UNIX 文件系统自身。
这些模式可以划分为**主要模式和次要模式**。**主要模式规定了主要的编辑行为,并且仅应用于当前编辑会话中的缓冲区**。在任何时刻,每个缓冲区都有且仅有一个活动的主要模式。
尽管在任何时刻,一个缓冲区仅有一个活动的主要模式,但您可以根据需要在主要模式之间进行切换。**一些专门的主要模式还提供了额外的功能和辅助**(如上下文突出显示和颜色设置),当您在编辑某些类型的文档时,这是很有帮助的,但是您无需为编辑某种类型的文件或文档选择特定的模式——可在任何模式中编辑一个 C 程序源代码文件,正如它可在编辑 C 程序语言的特殊模式中完成。
**次要 模式通常提供了一些与任何特定的主要模式无关的特性或功能**。可以把它们看作用于控制这些特性的切换:使用其函数名来调用一个次要模式可以开启或关闭该模式,任何时候您都可以开启多个次要模式。
次要模式包括__ Overwrite __模式本系列文章的第一部分教程对其进行了描述、用于管理签入版本控制系统 (RCS) 的文件的 __RCS__ 模式、以及处理自动文字回绕的 __Auto Fill __模式。可以在任何时候同时激活所有这些次要模式以及许多其他类似的模式。
===== 查看哪些模式是活动的 =====
如本系列文章的第一个教程中所述,靠近 Emacs 窗口底部的突出显示栏被称为模式行可以告诉您当前缓冲区的所有情况——包括哪种模式当前是活动的。在模式行右边的括号里注明了当前的模式。__最先列出主要模式的缩写名称后面是任何次要模式的缩写名称__。
当您启动 Emacs 编辑器而不打开任何文件时,则处于暂存缓冲区。在缺省情况下,这个缓冲区以 Lisp Interaction 模式打开,这是一个用于计算 Lisp 代码的特殊模式。
您可以用通常的方式启动 Emacs观察模式行里写了些什么。
当您改变这些模式的时候,将在模式行里看到其反映出来了模式的改变。现在,请尝试下面的操作:按 Ins 键以打开 Overwrite 模式并注意模式行的变化。Ins 键与 overwrite-mode 函数进行了绑定)。
再次按 Ins 以关闭 Overwrite 模式。
当启用一个次要模式时,通常在括号里会有显示,紧接在主要模式的后面。然而,**并非所有的次要模式都有这种指示器**——有些次要模式是非常明了的(如 Tool Bar 模式),它在 Emacs 框架的顶部显示了图形工具栏。较新版本的 Emacs 中其他的次要模式都非常简单(并且始终处于开启状态),以至于如果要把它们全部显示出来,只会使显示变得非常混乱;例如,次要模式 Unify 8859 On Encoding 的目的是为各种 ISO 8859 字符集提供统一的编码方式,这样有助于进行国际化。
另外,一些模式提供了**额外的指示器**,这些指示器也会在模式行里显示出来。例如 Line Number 模式,通过在 L 后面跟上行号来表示,该行号是光标在缓冲区中的当前位置。
===== 获得当前模式的描述 =====
可以使用 describe-mode 函数,该函数与 **C-h m** 进行了绑定,用于获得当前模式的描述。当您运行这个函数时,将打开一个新的帮助缓冲区,其中列出了所有的键绑定,这些键绑定是您进行输入的缓冲区的当前主要模式所特有的,后面跟的是应用于任何处于打开状态的次要模式的绑定。
正如您所看见的,用于 Lisp Interaction 模式的特殊绑定之一是 Tab 键。在这个模式中Tab 并不会像您希望的那样在打字机或文字处理应用程序中将光标移动到下一个制表位处,而是按照模式描述所说的,它会对当前 Lisp 代码行进行缩进。因为您没有在这个缓冲区中编写任何 Lisp 代码,所以 Tab 什么都不做——您可以试试看。
===== 缺省模式 =====
尽管暂存缓冲区通常设置为 Lisp Interaction 模式,但它并不是缺省 Emacs 模式。要找出缺省模式是什么,可以切换到一个新的缓冲区:输入 C-x b 并指定 lamb.txt 作为缓冲区的名称。输入 C-x 1 关闭帮助缓冲区。
您将看到这个新的 lamb.txt 缓冲区有了新的主要模式,即 **Fundamental 模式。这就是 Emacs 缓冲区的缺省模式**。在所有 Emacs 模式中这种模式是最简单明了的拥有最少的特殊键绑定和设置。在这种模式中Tab 键将按照您所希望的方式进行工作。
再次键入 C-h m 继续工作并获取这些模式的描述。
当您在新的缓冲区中打开现有文件中的内容时Emacs 将**基于该文件类型**为您选择一种模式。如果您打开的文件包含 C 程序源代码,那么 C 模式将成为主要模式;同样,如果您打开的文件包含口语(如英语)文本,那么 Emacs 会将 Text 模式设置为主要模式。
您可以不断地改变模式,并且您还可以对所有这些设置进行配置,这样一来,就始终能够以特定的模式打开某种文件或者某种类型的缓冲区。表 1 描述了常用的 Emacs 模式,并给出了它们的函数名。
===== 表 1. 常用的 Emacs 模式 =====
模式 函数 类型 描述
Fundamental fundamental-mode 主要模式 这一模式是缺省的 Emacs 模式,拥有最少设置和绑定。
Text text-mode 主要模式 这一模式是编辑文本的基本模式。
Abbrev abbrev-mode 次要模式 这一模式用于生成和使用缩写请参见 Abbrev 模式)。
Auto Fill auto-fill-mode 次要模式 这一模式用于自动文字回绕、填充较长的行和段落。
Overwrite overwrite-mode 次要模式 这一模式用于覆盖缓冲区中任何现有的文本,而不是在当前位置插入文本。在缺省情况下,它与 Ins 键绑定。
C c-mode 主要模式 这一模式用于编辑 C 程序源代码。
Line Number line-number-mode 次要模式 这一模式用于显示当前行号。
Lisp Interaction lisp-interaction 主要模式 这一模式用于编辑和编译 Lisp 代码。
Paragraph-Indent Text paragraph-indent-text-mode 主要模式 这一模式是 Text 模式的一种特殊变体,其中的段落移动命令可用于首行缩进的段落,而不仅仅是由空行隔开的段落。
TeX tex-mode 主要模式 这一模式用于编辑 TeX 文档。
WordStar wordstar-mode 主要模式 这一特殊模式提供了 WordStar 编辑器的键绑定。
===== 设置模式 =====
Emacs 模式是一些函数。要调用其中某个函数,您需要输入 M-x然后给出模式名。
现在可以尝试在新的缓冲区中调用 Text 模式:输入 M-x text-mode 并按 Enter。您马上可以看到模式行中的变化其中用 Text 替换了 Fundamental。
在 Text 模式中进行输入
Text 模式是一种基本的模式,与 Fundamental 模式相比仅有很少的改变,所以它的优势并不明显;但它是对口语(如英语)文本进行编辑的一个很好的基础。从 TeX 模式到 Outline 模式,许多用于编辑某类文本或文档的特殊模式都是基于 Text 模式的。
尝试在新的缓冲区中输入一些文本,继续上一个教程中 William Blake 的主题:
__Text 模式下Tab 键被定义为相对于先前段落的缩进以缩进段落__如果先前的段落没有缩进按 Tab 插入一个逐字制表符,移动光标到下一个制表符止。
要了解 Text 模式如何处理制表符,可以输入一些带制表符和空格的行:
===== Abbrev 模式 =====
Emacs 的缩写 是用一个特定的字符串定义的特殊单词。当在缓冲区中输入一个缩写时(并且 Abbrev 模式已打开),将对这个缩写进行扩展 或者使用定义它的字符串来替换它。Abbrev 模式(一种次要模式)使得您可以对较长的字符串或者短语进行速记,但是您可能还会想到一些其他的使用方式。
==== 定义一个缩写需要先启用abbrev-mode ====
添加缩写的简单方式是,运行一个 inverse-add 缩写函数 __inverse-add-global-abbrev C-x a i g__或者__ inverse-add-local-abbrevC-x a i l __。这些函数允许您为缓冲区中的某个单词定义一个缩写第一个函数可以对当前 Emacs 会话中打开的**任何缓冲区**应用这一缩写,而第二个函数仅对与当前缓冲区具有相同的主要模式的缓冲区定义这一缩写。后者可用于定义仅适用于某些模式的缩写,例如对包含程序源代码的缓冲区中的长变量名进行定义。
尝试定义一个缩写,并使其应用于所有的缓冲区:
在下一新行中,输入一个缩写单词 li,,以使得**光标位于这个单词的末尾**(即在 i 之后)。
通过输入 C-x a i g运行 inverse-add-global-abbrev 函数。
在小缓冲区中给出提示的地方定义您的缩写:输入 Little lamb 并按 Enter。
请注意,您在缓冲区中输入的缩写使用定义它的字符串进行了替换,并且光标移到了这个定义的开头。
现在,将光标移动到一个新行,并按您刚刚用过的方法生成一个新的缩写,通过输入 x缩写不区分大小写并使用这个字符串 He is 来定义它。
现在您已经定义了两个缩写。然而正如您在模式行里看到的Abbrev 模式是关闭的。请打开它:输入 __M-x abbrev-mode__。用您刚刚生成的定义删除这两行然后输入清单 1 中的代码。
li 和 x 的缩写按照您的输入进行了扩展,当您完成以上操作后,缓冲区看起来就应该与图 3 所示类似。
==== Emacs 缓冲区中的缩写扩展 ====
这个示例显示了如何定义在所有缓冲区中都可以使用的缩写。要定义一个缩写以使其仅应用于当前模式的缓冲区可以使用__ C-x a i l__。
==== 使用一个单词作为缩写的定义 ====
您还可以**为缓冲区中的单个单词定义缩写**。当您在编写程序源代码并且刚输入了一个较长的变量时,这种方式是特别有用的。
要为一个单词定义缩写,可以在光标位于这个单词之后时使用 __C-x a g__。在完成了这个操作之后当 Abbrev 模式开启时小缓冲区将提示您用缩写来替代那个单词。同样地要定义一个仅应用于当前主要模式的缩写可以使用__ C-x a l__。
==== 删除缩写 ====
要删除您在会话中定义的全部缩写,可以使用 kill-all-abbrevs 函数。
请尝试下面的操作:键入 __M-x kill-all-abbrevs__。
现在在任何缓冲区无论其处于何种模式中都没有使用您所定义的缩写li、x 和 c对其进行扩展。再输入两行内容作为结束

View File

@@ -0,0 +1,139 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-18T08:56:01+08:00
====== 程序员的Emacs ======
Created Monday 18 April 2011
===== 加载自己的LISP程序 =====
针对程序设计语言的编辑模式可以把emacs从根本上改造为一个语法指导的或语言敏感的(即能够识别和理解某种程序语言语法)的编辑器,从而
帮助用户俺自己的风格写出格式整齐,方便阅读的代码。
各种编辑模式其实由两大部分组成用来实现这个编辑模式的LISP程序文件(包),和用来启动这个编辑模式的函数。
要加载自己定义的函数可以用load函数但load函数需察看load-path变量的值以确定查找该函数所在程序包的目录
(setq load-path (append load-path (list "~/yourname/lisp"))) 或
(setq load-path (cons "~yourname/lisp" load-path))
前面一个是将自己的目录添加到load-path的后面而后一个是插入到load-path的前面。
注意cons后面的参数可以是一个原子项(如字符、字符串、数字)如果想让emacs查找工作目录该load-path加上一个nil即可如
(setq load-path (cons nil "~yourname/lisp" load-path)
由于load-path为一列表型变量故还可以使用add-to-list函数为其赋值如
(add-to-list 'load-path "~yourname/lisp")
然后让emacs加载自己的LISP程序包
(load "packagename") ;;注意参数为不带后缀名(.el , .elc )的字符串emacs启动时自动加载。
(autoload function "packagename" ) ;; 在执行给定函数时emacs自动加载相应的程序包。
还可以用load-file , load-library 等函数。
有些函数是emacs内置的它们控制emacs的特性(feature).
features变量保存了emacs可以使用的特性可以用require函数从文件中加载特性。
**(require FEATURE &optional FILENAME NOERROR)**
If feature FEATURE is not loaded, load it from FILENAME.
If FEATURE is not a member of the list `features', then the feature is not loaded; so load the file FILENAME.
If FILENAME is omitted, the printname of FEATURE is used as the file name,and `load' will try to load this name appended with the suffix `.elc' or
`.el', in that order. The name without appended suffix will not be used.
If the optional third argument NOERROR is non-nil, then return nil if the file is not found instead of signaling an error.
Normally the return value is FEATURE. The normal messages at start and end of loading FILENAME are suppressed.
**(provide FEATURE &optional SUBFEATURES)**
Announce that FEATURE is a feature of the current Emacs.
The optional argument SUBFEATURES should be a list of symbols listing
particular subfeatures supported in this version of FEATURE.
Emacs能识别的语言元素
单词,如标示符和数字
标点符号:包括运算符和语句分割符如分号
字符串:字符序列
括号:各种括号
空白:如空格、制表符
注释:注释分隔符中的字符序列
Emacs可以识别文本编辑时的单词、句子、段落他允许以这些语言学元素为单位来移动或删除文本他还知道某些标点符号的用法如括号的配对高亮。
Emacs把语法信息保存在语法表(syntax tables)中,有供全体缓冲区用的全局语法表,每个缓冲区还有一个局部语法表。程序语言的编辑模式还能识别和理解依赖于具体语言的语法如:语句、语句块、函数、子例程、LISP中的S-表达式等。
==== 基本缩进命令 ====
TAB 调整当前行的缩进知道与当前环境上下文的格式规则一直,编辑点的位置不变,因此可以在当前行的任意位置使用该键。
LINEFEED 命令时TAB+ENTER或C-ENTER与位于行尾时的C-j一致都是使新输入的一行自动缩进
M-C-q 重新缩进一对匹配的花括号中的所有行,该命令必须位于左花括号所在的行且假设做花括号已经恰当的缩进
M-C \ indent-region 对光标和文本块间的每一行按照定义的编程风格进行缩进。
M-m back-to-indentation 把光标移动到当前行的第一个非空白字符
M-^ delete-indentaion 把当前行合并到上一行去
Emacs能识别各种语言元素语句中的分号、冒号、逗号、或括号和井号能字符都是自动缩进的也就是说在输入这些字符时emacs会自动的对当前行缩进。
M-x c-set-style选择编码风格。内建的cc-mode缩进风格
bsdStyle used in code for BSD-derived versions of Unix.
cc-modeThe default coding style, from which all others are derived .
ellemtelStyle used in C++ documentation from Ellemtel Telecommunication Systems Laboratories in Sweden .
gnuStyle used in C code for Emacs itself and other GNU-related programs .
javaStyle used in Java code (the default for Java mode).
k&rStyle of the classic text on C, Kernighan and Ritchie's The C Programming Language .
linuxStyle used in C code that is part of the Linux kernel.
pythonStyle used in python extensions.
stroustrupC++ coding style of the standard reference work, Bjarne Stroustrup's The C++ Programming Language .
userCustomizations you make to .emacs or via Custom (see Chapter 10). All other styles inherit these customizations if you set them.
whitesmithStyle used in Whitesmith Ltd.'s documentation for their C and C++ compilers .
C-c C-a :打开/关闭自动换新行对应的命令是c-toggle-auto-state默认为禁用状态。启用后当输入分号、花括号、冒号时emacs自动加上一个换行符并
对新行自动缩进
C-c C-d打开/关闭c-toggle-hungry-state。在Del(maybe BackSpace)时,是否自动删除左边所有空格。
C-c C-t同时打开/关闭auto-newline和hungry-delete-key功能
M-x check-parens 检查代码中的括号匹配情况
C++ mode中
C-c ::插入域操作符::
==== 基本注释命令 ====
M- ident-for-commit 按照comment-colunmn的值进行缩进注释如果这一行上的文本超过了这一列的值它将从最后一个字符的位置再右移一个空格
然后插入一个注释分隔符并把光标放在分隔符的里面。如果当前行已经存在一个注释但其位置不再commnet-column则该命令将其重新在这列对齐注释。
另外若作用的时一个regionM-;就可以注释或者反注释该区域
C-M 将commnet-colmn设置为编辑点之后的列左边界为0列
M-x uncomment-region 取消文本块的注释
C-c C-c comment-region 注释文本块
C-u C-c C-c uncomment-region 取消文本块的注释
M-x kill-comment 清除当前行上的注释
另外还可以使用emacs的矩形区域填充和剪切功能实现函数块和文本块的快速注释
1.选中一段区域(例如用M-C-h选中一个函数)到最后一行__行首__然后按 __c-x r t__ 输入注释符如//,这时所有行的行首都有这个字符串。
2.去除注释可以同样选择区域(由于上一步给行首添加的注释是一个矩形,故这一次只需再选中这个矩形区域即可)最后一行要选择到注释内容后的那个字符然后__ c-x r k__
C-j 或M-j 自动缩进式换行注释注意换行注释时由变量comment-multi-line控制是下一行继续同一条注释还是另外创建一组新的注释分割符
M-q 若光标在注释文本中间,则自动进行段落重排,保留缩进和前导字符
m-x align 文本的自动对齐
===== 代码中移动命令 =====
M-a 移动到当前语句的开头,注意是语句而不是行首
M-e 移动到语句的结尾
C-M-f 向前移过某个表达式,命令的执行依赖与光标处的字符(编辑点右边)
如果第一个非空白字符为开始分隔符如各种括号,编辑点移到相匹配的结束分隔符之后
如果第一个非空白字符为一个记号(如关键字,数字,字符串的引号),编辑点就移到极好的末尾
C-M-b 向后移过某个表达式
C-M-k 向前剪切某个表达式剪切后编辑点与C-M-f相同
C-M-@ 向前编辑C-M-f移动过的区域
C-M-_ 同上
C-M-a 将光标移动到最近的函数定义的开始
C-M-e 将光标移动到下一个函数定义的结尾
C-M-h 将光标所在的函数标记为区域
C-c C-u 移动到当前预处理器条件的开始位置
C-c C-n 移动到下一个预处理调剂
C-c C-p 移动到上一个预处理条件
C-c C-e c-macro-expand 对包含预处理条件的文本块执行实际的预处理过程,可以用于确定有哪些代码是真正会被编译的,其结果放到*Macroexpansion*的窗口中。预处理器由变量c-macro-preprocessor设置。
===== TAGS的使用 =====
:Linux:Utils:emacs:代码搜索
===== 括号自动补全 =====
emacs可以利用skeleton-pair-insert-maybe来实现添加一下代码到.emacs中。这对编写lisp很方便但是在写c/c++ java的时候就没有多大的用处了。当然有更好用的yasnippet但是需要按一个扩展snippet的键。
( setq skeleton-pair-alist nil)
(global-set-key (kbd "[") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "(") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "{") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "<") 'skeleton-pair-insert-maybe)
(global-set-key (kbd "\"") 'skeleton-pair-insert-maybe)

View File

@@ -0,0 +1,185 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-18T21:32:57+08:00
====== Emacs定制 ======
Created Monday 18 April 2011
屏幕上显示的任何东西,任何命令,任何按键动作和任何一条消息等几乎都可以定制。
LISP函数的调用形式是 (function-name argumets-lists)
当.emacs配置文件出现问题时可以在命令行上指定-q参数Emacs将不运行这个文件中的配置指令。
-u username 用于测试另外用户的配置文件
==== 1.键盘的定制 ====
按键的动作是通过按键序列与命令关联起来的。Emacs里每个按键动作都会运行一个命令对于可打印字符运行self-insert-command。
键位映射表(keymap)是由多个按键绑定构成的一个集合。Emacs最基本的默认按键绑定保存在名为global-map的全局键位映射表中。
局部键位映射表local-map 是每个模式对应的一个映射表,作用是实现对应模式的特殊命令,不同的编辑模式对应的局部表不同。每个缓冲区的模式
都有一个本地键盘映射表该表首先用于对应窗口的按键操作若没有按键定义项就会察看global-map表。
对于绑定到组合键(多余一个字符的按键序列)的命令比如M-d 是怎样被查到的呢?
按键时Emacs执行的循环操作是基本的转换操作是使用输入字符的ASCII值来索引具有128个元素的一个向量即keymap有时一个字符的第8位配解释为META字符所有的META字符将包含ESCAPE前缀无论是否以该方式输入。
对于组合键如C-x 、M-、C-c等其实是被绑定到一些特殊的内部函数上而这写函数会让Emacs等到另一个按键配按下胡在去另外一个键位映射图中查找
该按键的绑定定义。如果后面的按键在一秒后没有按下就会在minibuffer中现实C-x-等。供C-x ,M- , M-x ,C-c使用的键位映射图分别为 ctl-x-map和esc-map
mode-specific-map. C-c 组合键是为关联与某具体编辑模式的局部键位映射图准备的。
通过在键位映射图中添加或写改(如果已经存在)定义项可以创造出自己的按键绑定,可以使用三个函数:
(define-key keymap "keystroke" 'command-name)
(global-set-key "keystroke" 'command-name)
(local-set-key "keystroke" 'command-name)
第一个是通用的,可以用来绑定任何一个键位映射图中的按键,但需要知道图名称。
把按键绑定插入到.emacs文件后需要运行(或者称为求值)这个文件才能生效可以用M-x eval-buffer 或 C-x C-e 执行光标所在的那一行上的LISP代码。
特殊字符的表达式
\C-x C-x x为任意字符
\C-[ 或\e ESC 转义符
\C-j 或 \n LINEFEED 换行符
\C-m 或 \r RETURN ;回车符
\C-i 或\t TAB制表符
由于转移字符只能用于有限的几个字符(如\o ,\p,\q等就没有意义)因此一般应用kbd函数来生成任意含有特殊含义的字符串。
kbd函数的调用形式为
(kbd string)
返回string对应的emacs控制序列使用kbd函数的好处是string中各特殊控制字符可以用三个大些字母来表示功能键可以用尖括号括起来的键名表示
按键前缀可以用但个大写字母加段横线表示这避免了keystroke中过多了转义字符。
string的格式为
(edmacro-mode) 下段说明来自这个函数的帮助文件
Text is divided into "words" separated by whitespace. Except for the words described below, the characters of each word go directly
as characters of the macro. The whitespace that separates words is ignored. __ Whitespace in the macro must be written explicitly__,
as in "foo SPC bar RET".
* The special words __RET, SPC, TAB, DEL, LFD, ESC__, and __NUL__ represent special control characters. The words must be written in uppercase.
它们都是三个大写字母
* A word in angle brackets, e.g., __<return>, <down>, or <f1>__, represents a function key. (Note that in the standard configuration, the
function key <return> and the control key RET are synonymous.) You can use angle brackets on the words RET, SPC, etc., but they
are not required there.
* Keys can be written by their ASCII code, using __a backslash followed by up to six octal digits__. This is the only way to represent keys
with codes above \377.
* One or more prefixes __M- (meta), C- (control), S- (shift), A- (alt), H- (hyper), and s- (super)__ may precede a character or key notation.
For function keys, the prefixes may go inside or outside of the brackets: C-<down> = <C-down>. The prefixes may be written in
any order: M-C-x = C-M-x.注意shift必须和C或M或A一起使用"S-SPC"是错误的,可以用"C-S-SPC"
. __ Prefixes are not allowed on multi-key words, e.g., C-abc__, except that the Meta prefix is allowed on a sequence of digits and optional
minus sign: M--123 = M-- M-1 M-2 M-3.
* The `^' notation for control characters also works: __ ^M = C-m__.
* Double angle brackets enclose command names: <<next-line>> is shorthand for M-x next-line RET.
* Finally, REM or ;; causes the rest of the line to be ignored as a comment.
Any word may be prefixed by a multiplier in the form of a decimal number and `*': 3*<right> = <right> <right> <right>, and
10*foo = foofoofoofoofoofoofoofoofoofoo.
Multiple text keys can normally be strung together to form a word, but you may need to add whitespace if the word would look like one
of the above notations: `; ; ;' is a keyboard macro with three semicolons, but `;;;' is a comment. Likewise, `\ 1 2 3' is four keys but `\123' is a single key written in octal, and `< right >' is seven keys but `<right>' is a single function key. When in doubt, use whitespace.
常见的错误:
(global-set-key (kbd "S-m") 'goto-line) ;;; S- 不能单独跟一个字符
(global-set-key (kbd "C-xa") 'goto-line) ;; C-后面只能连续跟一个字符 ,应为"C-x a"
(global-set-key (kbd "abC-m") 'goto-line) ;;; a不是一个命令前缀
(global-set-key (kbd "C-aC-bC-m") 'goto-line) ;; 不同的控制字符相互间必须有空格分开
(global-set-key (kbd "C-a C-b") 'goto-line) ;; C-a 并没有一个已经定义的键映射前缀函数绑定(缺省绑定的有 C-x -, C-x-4- M- C-h-C-c-),
(global-set-key (kbd "C-x C-a C-b") 'got-line) ;; 虽然C-x是已经定义的映射前缀但C-a并不是下一级的映射前缀
一般一个可打印字符的绑定可以直接用“a”的形式不可打印如带有CTL或ALT前缀的单一字符可用"C-a" 或“^A"或"M-a".
对于单个字符用local-set-key是定义在major-mode的局部缓冲区列表中用global-set-key是定义到全局缓冲区列表中。
对于由两个字符序列的绑定除非用已经定义的前缀(因为它们都有相应的keymap这时其实还是一级表C-x等其实是一个前缀命令)如C-x (ctl-x-map) , C-x 4 (ctl-x-4-map), C-h (help-map) , C-c(mode-specific-map) 否则必须先定义一个keymap。
"C-x a" "C-x 4a" "C-x 4 a" "C-h 4" " C-h a" "C-c a" 都是合法的(它们都是把a绑定的命令添加到对应的keymap中),但"C-x ad"等是不合法的除非先在C-x的映射表中定义一个对应与a的映射表(这时形成了一个两级表)如:
(setq tmpkeymap (make-keymap)) ;; set up the keymap var
(define-key ctl-x-map "a" tmpkeymap) ;; add the tmpkeymap to exit ctl-key-map
然后就可以使用"C-x ad"等以"C-x a 任意字符” 的形式绑定命令了如:
(define-key tmpkeymap "d" 'forward-word) ;; add a key to tmpkeymap ,由于制定了表,故无需再加前缀
或(global-set-key (kbd "C-x ad") 'forward-word) ;;没有指定表,故需加前缀
也可以定义自己的前缀表,方法和上面的类似:
(setq map (make-keymap))
(define-key global-map (kbd "C-a") map)
然后就可以往map表中绑定命令了:
(define-key map "d" 'forward-line) ;指定表时不需加前缀
(global-set-key (kbd “C-a d") 'forward-line) ;;不指定表时需指定前缀
注意如果上面的按键不用kbd函数的话要使用转移字符转义如
"\C-a d" "\M-a d"
对于\C-和\M-也可以直接用"\ead" 或"\"
===== 2.Emacs变量 =====
按键改变的是操作emacs的界面而变量(或选项)控制着emacs的各种行为。可以说只要相对emacs的某个方面进行定制就肯定会有一个
与之对应的控制变量(特别是想改变的东西涉及到一个数字或涉及到真、假条件时更是如此)。
当不知道变量名时可以通过apropos命令查出是否有与想定制相关的变量。
(setq varname val) ;;设置局部变量值
(setq-default varnaem val) ;;设置默认值(全局变量值)
但没有方法判断某一个变量是只有一个全局取值还是既有默认值又有局部值最佳的策略是先尽量使用setq命令无效时再使用setq-default.
变量值的类型:
字符串值:必须放在双引号中,特殊字符要转义
字符值:必须用问号做前缀,而且不能放在双引号中
符号值:以单引号开头,后跟符号名(通常位函数名或变量名),表示不执行函数和获得变量的值
===== 自动模式的定制 =====
M-x c-mode进入C mode模式
M-x c++-mode进入C++ 模式
===== 1.文件名与模式自动匹配 =====
emacs能根据文件后缀名自动进入相应的模式后缀名与主编辑模式的关联关系是有列表型变量auto-mode-alist管理的。
这个变量是一个(regexp . mode) 形式的数据组列表regexp为正则表达式mode为启动某一个主编辑模式的函数名。
注意regexp可以匹配文件名的任意部分。
例如:
(setq auto-mode-alist (cons '("\\.org$" . org-mode) auto-mode-alist))
注意: cons 后面必须要有一个单引号org-mode前必须要有一个句号记号 '(x . y)是用来把x和y配对组成一个数据组的LISP语法。注意正则表达式中用两个\\表示一个\这是因为emacs在读正则表达式时将其中的两个\\转为一个\传给相应的函数。
==== 2.缺省模式 ====
如果打开的文件没有匹配上auto-mode-alist中的任何一个表达式emacs就会把放到default-major-mode变量中的只作为基本默认模式。
(setq default-major-mode 'text-mode)
====== 对现有模式进行定制 ======
Emacs的各种主编辑模式都有一些可以把你编写的代码添加到它上面去的挂钩他们的名字一般叫做mode-hooks.
Emacs内建的各主编辑模式都有一个名为"mode-name-hook"的编辑模式挂钩其中的mode-name是该编辑模式的名称或启动他的函数的名字。
如C模式的c-mode-hookshell有一个shell-mode-hook.
挂钩是一种特殊的变量它的值代表一些LISP代码这些代码会在相应的编辑模式启动时得到运行。
启动一个编辑模式就等于运行一个LISP函数该函数通常要设置按键绑定、创建局部变量、创建缓冲区如果编辑模式有挂钩那么该函数的所做的
最后一件事就是运行挂钩变量中的LISP代码。
LISP基本函数lambda可以用来定义函数它与defun的区别是lambda定义的函数没有名字即为匿名函数其语法如下
(lambda (args)
code-block)
如果想把一个用lambda定义的函数作为一个值赋给某个变量就必须对他进行转义以防止它被求值(即防止它被调用运行)如:
(setq var-name
'(lambda ()
code)
在编写编辑模式挂钩的代码时可以用:
(setq mode-name-hook
'(lambda ()
code for mode hook))
如果使用setq来定义你自己的挂钩就会覆盖掉原有的挂钩要想避免出现这样的情况就可以使用add-hook函数
(add-hook 'mode-name-hook
'(lambda ()
code for mode hook))
编辑模式挂钩最常用的用途时为某个编辑模式的特殊命令修改一个或多个按键绑定。可以自己定义一些函数然后将其绑定到某一模式的键盘映射表上,也可以为某一模式现有的函数设置按键绑定。
按照规定定义某一编辑模式的正确方法是必须通过他的挂钩来进行,但如果只是给变量重新设置一个值,就可以不用使用挂钩;但如果想运行某些编辑模式相关的函数就必须使用挂钩。这是因为:
某一个编辑模式的局部变量是属于局部范畴的,如果没有启动该模式,他们就不会存在。但只要在.eamcs文件中包含一条给这个变量赋值的setq语句那么不管是否使用该模式这个变量就已经存在了。Emcas能够很好地应付这种情况当加载这种模式时它会注意到这个已经设置的变量值于是就不会覆盖掉它。
但函数的情况就不同了 ,如果.emacs文件里有一个属于某个编辑模式的局部函数当这个模式没有启动时Emacs会给出一条出错信息。因为它根本不知道该函数属于那个编辑模式因此必须把这个函数的调用语句放在他所在模式的钩子函数里。
===== 交换Control和alt的位置 =====
!
! Swap Caps_Lock and Control_L
!
!remove Lock = Caps_Lock
!remove Control = Control_L
!keysym Control_L = Caps_Lock
!keysym Caps_Lock = Control_L
!add Lock = Caps_Lock
!add Control = Control_L
!swithc alt and ctl
remove mod1 = Alt_L
remove Control = Control_L
keycode 37 = Alt_L
keycode 64 = Control_L
add Control = Control_L
add mod1 = Alt_L

157
Zim/Utils/emacs/IRC.txt Normal file
View File

@@ -0,0 +1,157 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-03T14:54:24+08:00
====== IRC ======
Created Sunday 03 April 2011
ERC, emacs irc client, 即是 emacs 里登录 irc 的客户端。irc 是什么? internet relay chat, 简单地说,就是用于群聊的。一帮无聊的 geeks 成天没事干,就在上面灌水,所以上面的 channel 技术类的占绝大数,比如 emacs, c++, debian, scheme 等等。
好,开始 ERC 之旅,先让我们登录到 #emacs-cn 上去:
a) M-x erc-select
host: irc.debian.org
port: 6667 到 7000 随便用一个
username: 先随便填一个,比如 foo
password: 还没注册的可以直接回车
b) 这时候你就进入了一个名字类似 “irc.debian.org:6669″ 的 server buffer. 接着执行:
ERC> /join #emacs-cn
就进入 #emacs-cn channel 啦!
c) 如何注册
切换到刚才那个 server buffer, 输入:
ERC> /msg nickserv help register
按着提示一步一步来就行,根据 irc server 的不同,有些会需要你用有效邮箱来确认一下。注册 id 的好处就是,这个 id 就不会被别人抢走了,比如有人已经用 foo 登录了,但这被你注册了,你连进去的时候,就能把名字抢过来,而对方可能会变成 foo` 之类的别名。
以上其实对于所有 irc client 来讲都是通用的。接下来是我的 ERC 一些配置供参考:
1. 基本设置
编码,尽量 utf-8 (#emacs-cn 也是用 utf-8):
(setq erc-default-coding-system '(utf-8 . utf-8))
如果某个 channel 是别的编码,也可以单独设置,例如国内某个 irc server 上 #linuxfire 就是用 gbk 编码,我们单独为它设置:
(setq erc-encoding-coding-alist '(("#linuxfire" . chinese-iso-8bit))
设置 nick, 全名: nick 就是登录时用的full name 是别人查询你的时候显示的信息。(类似BBS 的 C-a )
(setq erc-nick "xwl"
erc-user-full-name "William Xu")
2. 登录后自动加入预定的 channels
(erc-autojoin-mode 1)
(setq erc-autojoin-channels-alist
'(("oftc.net" ; debian.org 是它的别名
"#debian-zh"
"#emacs-cn")))
3. 连接服务器或进入聊天室后自动执行预设操作
ERC 提供各种各样的 hook 让你在某个操作(登入 server, 进入channel等之后执行一些你预设的操作。比如如果你有某个 channel 的管理员权限,可以在加入聊天室时自动转换到管理员身份:
(defun xwl-erc-auto-op ()
(let ((b (buffer-name)))
(when (string= b "#emacs-cn")
(erc-message "PRIVMSG" (concat "chanserv op " b)))))
(add-hook 'erc-join-hook 'xwl-erc-auto-op)
4. 过滤信息
如果你对某些消息或者某个人说的话特别感兴趣,我们可以通过关键字匹配对相关信息进行高亮。例如:
(erc-match-mode 1)
(setq erc-keywords '("emms" "python"))
(setq erc-pals '("rms"))
相反地,如果你对某些消息不感兴趣,比如有人进来啦,有人出去啦,如此这般一下就不会看到了:
(setq erc-ignore-list nil)
(setq erc-hide-list
'("JOIN" "PART" "QUIT" "MODE"))
5. 新信息提醒
信息一般可分为三种:
1) 某人悄悄跟你说话(即所谓的 private message),这会打开一个新小窗,即 buffer.
ERC>/msg NICK how are you doing
2) 某人公开地跟你说话,即别的在 channel 里的人也能看到。一般来说,习惯用 nick加 `: 表示。(要输入某人 nick 的时候,首字母加 TAB 就能帮你补全,一次不行,多 TAB 几次可以选择)
<xwl> ahei: 你可以 match regexp,
3) 别的情形。
ERC 会通过 erc-modified-channels-object 来设置 mode line提示有新消息类似
[#o: 38, #emacs-cn: 5]
为什么要区分以上三种情形呢? 因为我们可以对不同信息用不同的颜色在mode line 来提示,这样方便你决定是不是要及时地去查阅这条消息。
ERC 本身只在 mode line 提示新消息如果你切换到别的程序去了比如在firefox 里看 ppmm还想被提醒的话可以借助一些外部工具来实现。mac 下用 growllinux 可以用 zenitywindows 不知有什么类似工具? 给个例子:
(defun xwl-erc-text-matched-hook (match-type nickuserhost message)
"Shows a growl notification, when user's nick was mentioned.
If the buffer is currently not visible, makes it sticky."
(when (and (erc-match-current-nick-p nickuserhost message)
(not (string-match (regexp-opt '("Users"
"User"
"topic set by"
"Welcome to "
"nickname"
"identified"
"invalid"
))
message)))
(let ((s (concat "ERC: " (buffer-name (current-buffer)))))
(case system-type
((darwin)
(xwl-growl s message))))))
(add-hook 'erc-text-matched-hook 'xwl-erc-text-matched-hook)
(defun xwl-growl (title message)
(start-process "growl" " growl" growlnotify-command title "-a" "Emacs")
(process-send-string " growl" message)
(process-send-string " growl" "\n")
(process-send-eof " growl"))
6. 时间戳
(erc-timestamp-mode 1)
下面这个变量可以控制时间戳的显示方式,比如位置什么的,默认值:
(setq erc-insert-timestamp-function 'erc-insert-timestamp-left)
7. log
我们可以将 channel 里的聊天记录都保存下来,方便日后查询,或者有时候你的 emacs 突然挂掉的时候,还能找到挂之间有没有人对你说了什么。
(require 'erc-log)
(erc-log-mode 1)
(setq erc-log-channels-directory "~/var/erc/"
erc-save-buffer-on-part t
erc-log-file-coding-system 'utf-8
erc-log-write-after-send t
erc-log-write-after-insert t)
(unless (file-exists-p erc-log-channels-directory)
(mkdir erc-log-channels-directory t))
最后ERC 上 irc 还是蛮舒服的,因为所有的、你熟悉的 emacs 编辑命令都在那里! 国内 irc 用户还是少了点,对岸台湾倒是蛮多的。大家有空就上来玩吧~ 要是想看我的配置可以在 github.com 上看我的配置文件:
http://github.com/xwl/xwl-emacs-config/blob/master/.emacs.d/site-lisp/config/xwl-erc.el

View File

@@ -0,0 +1,90 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-18T09:45:22+08:00
====== LISP模式 ======
Created Monday 18 April 2011
===== Emacs提供了三种LISP编辑模式 =====
emacs-lisp-mode 用来编辑Emacs LISP代码
lisp-mode 用来编辑其他系统的LISP代码
lisp-interaction-mode 用来编辑和运行Emacs LISP代码(交互式)
这三种编辑模式的基本功能是一样的区别是他们各自对LISP代码运行的支持功能上。
**S-表达式**(syntactic expression 语法表达式)指的是任意一个没有语法错误的LISP表达式他可以是一个原子项(数字、字符串、字符、符号、变量等)或者是一个放在括号中的列表。**列表**(list)是S-表达式的特殊形式,而函数定义又是列表的特殊形式。
===== S-表达式处理命令 =====
对S-表达式进行处理的命令到底采用什么动作,取决于调用命令时插入点的位置,如果光标在一个左括号(或它前面的一个空白位置),将被处理的是以这个左括号开始列表。
如果光标在字母或数字等其它字符(或他们前面的一个空白位置)将被处理的S-表达式将是一个原子项(符号、变量或常数)
M-a 移动到当前语句的开头,注意是语句而不是行首
M-e 移动到语句的结尾
C-M-f 向前移过某个表达式,命令的执行依赖与光标处的字符(编辑点右边)
如果第一个非空白字符为开始分隔符如各种括号,编辑点移到相匹配的结束分隔符之后
如果第一个非空白字符为一个记号(如关键字,数字,字符串的引号),编辑点就移到极好的末尾
C-M-b 向后移过某个表达式
C-M-k 向前剪切某个表达式剪切后编辑点与C-M-f相同
C-M-@ 向前编辑C-M-f移动过的区域
C-M-_ 同上
C-M-a 将光标移动到最近的函数定义的开始
C-M-e 将光标移动到下一个函数定义的结尾
C-M-h 将光标所在的函数标记为区域
上面3个命令只有在当前函数的defun出现的代码行才能正常工作。
M-C-n forward-list 移动到上一个列表
M-C-p backware-list 移动到下一个列表
M-C-d down-list 向前移动,进入到下一级括号层次
M-C-u backward-up-list 向后移动,退出当前括号层次
上面4个命令光标的前后必须要有一个左括号或右括号如果没有Emacs就会报错。
===== 缩进样式 =====
Emacs LISP函数调用使用的基本的缩进量是2只要下一行的代码又向下嵌套了一级(如引入了一个语句块)Emacs就将使用这个值对其缩进。如
(defun time (x y)
(let (i 0)
(result 0)
(while (< i x)
(setq result (+ result y)
i (1+ i)))
result))
如果函数有一个以上的参数,则该函数的函数名及第一个参数将出现在第一个代码行上,其他参数分别列在后续的代码行上,
并且要雨第一个参数对齐,如:
(function-name arg1
arg2
arg3
... )
类似关键字的let和while等术语实际上是函数调用但LISP编辑模式能根据自己对这类函数的理解对他们进行特殊的缩进安排。
另外LISP编辑模式习惯于把多个右括号都连续地写在同一行的最末尾而不是把他们分别写到不同的代码行上。
LISP编辑模式(非最后一个交互式模式)为TAB和LINEFEED(C-j)提供了换行和自动缩进的功能同时还提供了M-C-q对光标后面的S-表达式的每一行进行缩进(例如把光标放在函数的定义行,就可以对整个函数中的语句进行缩进)
LISP编辑模式的注释由通用注释命令M-;负责如果注释内容占据了一整行这时按下TAB键则将注释移到comment-column指定的位置为了避免出现这种情况可以用两个
或多个分号来代替单个分号。在注释时可以使用M-j在下一行继续写注释。
===== 各模式都有的功能 =====
==== Emacs LISP ====
Emacs LISP 是为运行Emacs内部的LISP代码准备的所以支持直接运行输入的代码。
可以用M-C-x eval-defun 把光标附近的函数定义进行求值,同时把对该函数保存起来,以便在同一会话中调用该函数。
可以用M-TAB lisp-complete-symbol 自动补充光标前面的符号(如变量、函数名)。
可以用M- eval-expression 在辅助输入缓冲区中输入任何一种形式的单行LISP表达式然后对该表达式求值并把结果显示在辅助输入缓冲区中。
这非常适合检查变量的值,试用哪些键没有绑定,或需要额外参数的内置函数。
同时可以用C-x C-e eval-last-sexp 运行光标所在行的LISP语句比把结果显示在辅助缓冲区中。
==== LISP模式 ====
是为非Emacs内置的LISP语言处理工具而编写的代码服务的他提供了用来与外部LISP解释器进行通信的接口。
C-c C-z run-liisp 启动一个用户系统的LISP解释器进程并且创建一个*lisp*编辑缓冲区供输入和输出。如果把光标放在某个函数的定义当中再按下M-C-x就能把函数的定义放到LISP子进程中。
==== 交互式模式 ====
*scratch*编辑缓冲区默认进入的模式。
除了把LINEFEED即C-j绑定为eval-print-last-sexp外交互式模式与Emacs LISP模式可以说是一模一样如果想获得其它模式绑定在LIENFEED上的换行及缩进的效果必须先按回车再按TAB。
在交互式模式中可以利用LINEFEED检查变量的值、输入函数定义和运行函数(Emacs会把函数的定义保存下来供以后使用)等。注意交互模式的LINEFEED要求光标必须位于
定义函数的结尾行。

View File

@@ -0,0 +1,279 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-18T14:53:04+08:00
====== LISP语言 ======
Created Monday 18 April 2011
对于Emacs无论发现缺少何种功能都可以动手用LISP程序实现它。实际上可以把Emacs看作是一个带有很多内部函数的LISP系统其中很多函数是用来实现文本处理、
窗口管理、文件I/O和其它与文本编辑有关的函数。Emacs源代码使用C写的它实现了LISP解释器、LISP指令和一些最基本的文本编辑命令。Emacs的其它功能时在它们基础上用
一个规模巨大的内部LISP代码层实现的。
===== 基本元素 =====
函数、变量、原子项是LISP语言的最基本元素函数是LISP语言唯一的程序单元。
LISP中的函数定义为由上述基本元素组成的各种列表(list),而且这种列表往往还嵌套调用其它现有的函数。一切函数都可以有返回值,调用的一个函数的返回值就是定义该函数时的最后一个列表项的值。嵌套在另外一个函数里的某个函数调用相当于其它程序设计语言中的一条语句(statement)。函数调用的语句
(function-name argument1 argument2 ...)
这条语句适合一切函数的调用,那些相当于其它程序语言中的算术或比较操作符的函数也不例外。
LISP中的变量没有类型的概念一个变量可以去任意的类型。原子项时任意类型的值可以是整数、浮点数、字符、字符串、布尔值、符号同时也可以是编辑缓冲区、窗口、进程等特殊的Emacs类型。
整数
浮点数
字符LISP字符必须要由一个前导的问号不加引号ESCLINEFEED、TAB分别用\e,\n,\t表示其它控制字符要加上前缀"\C-"如?\C-a
字符串:必须放在一对双引号中间,字符串中的引号和反斜线字符必须用转义字符引导。
布尔值t表示真nil表示假任何一个不是nil的值意味着真在需要nil的场合null或空值表示假
符号:LISP语言中各种事物的名字如变量名函数名。有时我们需要的事物的名字而不是他们的值这就需在事物的名字前加一个单引号。
(setq auto-save-interval 80)
(setq thisvar thisvalue
thatvar thatvalue
theotherval theothervalue)
setq的返回值就是最后一个赋值。
列表时LISP语言中的一个基本概念它充分体现了堆栈结构的本质特性。列表时把LISP与其它程序设计语言区分开来的主要概念。这种数据结构有两部分组成头元素和剩下的尾元素。出于历史原因LISP称之为car和cdr,前者为列表里第一个东西后者为列表中剩余的东西。如果给car和cdr提供一个列表参数他们就返回列表的头和尾元素。cons函数带两个参数而这两个参数分别设为列表的头元素和尾元素。list函数以多了元素为输入参数用他们构造出一个列表。
(list 1 2 3 4)
(cons 1 (list 2 3 4))
上面两条语句功能相同。
堆栈可以很容易地用列表实现:
(setq calc-stack (cons x calc-stack))
获得栈顶的元素:
(car calc-stack)
弹出栈顶的元素:
(setq calc-stack (cdr calc-stack))
列表的元素可以使其它包括列表在内的任何东西这就是人们把列表称为递归数据结构的原因。事实上对LISP语言里任何一种东西来说如果他不是一个原子项就会是一个列表。这里面也包括函数它可以看作由一个函数名、参数、准备求值的表达式等元素组成的列表。
===== 函数的定义 =====
在LISP语法中短划线字符时在变量名、函数名等语言元素中用作间隔符的字符LISP是一种很古老的语言。因此语法对程序员并不是很友好用LISP语言写出的程序会使用大量的列表也就是使用大量的括号。人们习惯于将多个括号集中放在代码的末尾而不是把它们分别放在一行并于对应的左括号对齐。这导致其可读性变差。简单的函数实例如下
(defun count-words-buffer () 1
(interactive) 2
(let ((count 0)) 3
(goto-char (point-min)) 4
(while (< (point) (point-max)) 5
(forward-word 1) 6
(setq count (1+ count))) 7
(message "buffer contains %d words." count))) 8
(count-words-buffer) 9
defun定义了一个函数和他的参数defun本身也是一个函数他会在被调用时定义一个新的函数返回值是一个符号即定义的函数名函数的参数都放在括号里形成一个由变量名组成的列表如果在某个参数前加一个&optional就可以把这个参数设为可选参数如果一个参数是可选的并且在调用时没有给出他的取值就是nil。
let函数的基本调用格式是
(let ((var1 value1)
(var2 value2)
...)
statement-block)
let先对变量var1 var2进行定义并把他们的初始值设为value1 value2等接着let执行他的语句块部分语句块时顺序排列的一组函数调用。
let做了三件事
定义(或声明)了一个由变量组成的列表
给变量设置初始值
创建一个可以使用声明的变量的语句块let的语句块也叫做变量的作用域。
LISP语言中while结构的基本格式是
(while condition
statement-block)
循环条件condition是一个值(一个原子项、一个变量或者是一个有返回值的某个函数)while对其测试判断是否为nil。对于无限循环可以用C-g来结束LISP语句的执行。<函数及其它条件比较函数返回的都是一个布尔值。
(1+ count)函数1+是(+ 1 variable-name)的缩写形式,主要函数的返回值是最后一个列表项。
内部函数message在辅助输入区中显示一条信息其第一个参数是一个输出格式字符串其它的为参数名。
%s
%c
%d
%e
%f
%g
==== 把LISP函数转化为Emacs命令 ====
上述的函数有一个问题在执行后光标会移动到缓冲区的末尾。这是LISP命令普遍存在的问题解决的方法是用save-exeurion函数
(save-excursion
statement-block)
用这个函数后语句块中的语句被执行时引起的光标移动在Emacs的内部进行不会显示在屏幕上。在执行完毕后插入点和文本块标记将出现在原先的位置。save-excursion函数的返回值是语句块中最后一条语句的返回值。
在解决了光标移动问题后还要解决函数的登记问题必须先对函数进行注册然后才能在LISP交互式模式中使用。
(interactive "prompt-string")
这条语句必须是函数里的第一条语句也就是跟在defun和文档字符串行后面。interactive函数的作用时把函数注册为Emacs的一个命令这样在执行他时Emacs会提示用户输入你在defun语法里声明的参数这个函数的提示字符串是可选的。interactive是按照提示字符串中子字符串先后顺序为函数参数提供值的。
注意提示字符串有特殊要求,你必须为每一个你想提示用户输入的参数准备一个提示字符串的子串,子字符串用\n字符分割每个子字符串的第一个字符必须是一个用来表示该参数类型的代码。
参数类型代码:
b 一个现有编辑缓冲区名字
e 事件:鼠标动作或功能键动作
f 现有文件名
n 数字(整数)
s 字符串
B 一个可能不存在的缓冲区名字
F 一个可能不存在的文件名字
S 符号
interactive函数还有一个选项r当以交互式调用函数时自动把函数的两个参数值设为point和mark函数的返回值。
文档字符串时用户发出describe-function等在线帮助命令时将会看到的帮助信息他们时可选的长度时任意多行传统上其第一行应是对命令功能进行介绍的一个完整而精炼的句子。
===== LISP语言基础函数 =====
基础函数时用来打造自己工作函数的建筑材料LISP在其它程序设计语言使用操作符(用于算术、比较、逻辑运算)的地方使用的是函数。
==== 算术运算: ====
+ 、- 、*、/、%、1+、1-、max、min
==== 关系运算: ====
>、>=、< 、<=、/=
= 用于数字和字符
equal 等于,用于字符串和其它复杂的字符串
==== 逻辑运算 ====
and or not
除 1+ 1- %外其它的算术函数都可以有任意个参数,逻辑运算也是如此。算术运算只有在其参数中至少有一个是浮点数时才返回浮点值。
==== 语句块 ====
LISP语言中可以定义语句块的两个函数是:progn和let。
progn是最基础的
(progn
statemetn-block)
progn是个让一个语句块看起来就像是一条语句的简单方法与C中的花括号类似返回值时语句块中最后一条语句的值。progn特别适合向if这样的控制
结构中因为这些控制结果不像while那样允许使用语句块。
let函数的变体
(let (var1 var2 ...)
statement-block)
上面没有使用(var value)这样的列表它只是一个由变量名组成的列表所有的变量被初始化为nil。在有些场合如
let在定义变量时需要用某些局部变量的值来计算另一些局部变量的值这需要用let的另一种形式 let*.
==== 控制结构 ====
LISP提供了三种控制结构while、if、cond。
if函数的语法为
(if condition
true-case
false-block)
true-case必须是单独的一条语句而false-block则是一个语句块可以省略。
cond相当于C中的case或switch语句语法为
(cond
(condition1
statment-block)
(condition2
statment-block2)
....)
==== Emacs内部函数 ====
内部函数是指许多现成的Emacs函数和一些自己开发的函数它们大部分与字符串和编辑缓冲区中的文本处理工作有关。
与缓冲区和文本有关的函数:
函数名 返回值或执行的动作
point 光标的位置
mark 文本块标记的字符位置
point-min 最小字符位置(通常是1)
point-max 最大字符位置,通常为缓冲区的长度
bolp 光标是否位于行首
eolp 光标是否位于行尾
bobp 光标是否位于缓冲区开始
eobp 光标是否位于缓冲区末尾
insert 把任意个数的参数(字符或字符串)插入到光标之后
==== 正则表达式 ====
如果要对正则表达式中的元字符进行转义,就必须在它的前面加上两个连续的反斜线字符如\\*匹配一个星号字符这里使用两个星号的原因与Emacs LISP
读取和解码字符串的操作方法有关在读取字符串到一个LISP程序里时Emacs会把两个斜线转换为单个反斜线字符。但是把把正则表达式字符串交互式地
输入到用户级命令时只有一个斜线就够了。
正则表达式操作符汇总:
操作符 作用
. 匹配任意一个字符
* 匹配前面的字符或字符组零次或多次
+ ...一次或多次
零次或一次
[...]
\\( \\)
\\| 匹配前后的子表达式,其作用范围是直到正则表达式开头、结尾、一个\\( 、一个\\)或另一个\\|^
^
$
\n
\t
\\<
\\>
\\N
==== 使用正着表达式的函数 ====
用户级命令他们都可以用在LISP代码中
re-search-forward
re-search-backward
replace-regexp
query-replace-regexp
isearch-forward-regexp
isearch-backward-regexp
还有一些不能作为用户级命令使用但可以出现在LISP代码中的函数
looking-at 输入参数为正则表达式,查看光标后面的文本是否匹配该表达式,若是会截取\\(和\\)之间的片段并保持工艺后使用。
string-match 参数为一个正则表达式和一个字符串,返回匹配正则表达式的首字符在字符串中的索引
match-beginning
match-end 用来检索被保存起来的字符串片段,返回的时字符串片段在文本缓冲区的起始点和结束点。
buffer-string 把整个缓冲区作为一个字符串返回
buffer-substring 两个参数指定子字符串在缓冲区的起始和结束位置,把截取的子字符串返回。
===== 主编辑模式程序设计实例 =====
==== 主编辑模式的组建 ====
符号 实现这个主编辑模式的函数名称
名字 显示在状态行括号的名称
局部键位图 用来定义这个主编辑模式里各种命令的按键绑定
变量和常数 为实现这个编辑模式LISP代码使用的一些局部变量和局部常数
专用编辑缓冲区 这个主编辑模式下有特殊用途的编辑缓冲区
=== 一、设置主编辑模式的符号 ===
(setq major-mode 'mode-name)
=== 二、设置主编辑模式的名字 ===
(setq mode-name "stings")
=== 三、局部键位映射表 ===
== 1.定义映射表 ==
(setq tmpkeymap (make-keymap)) ;; set up the keymap var
也可以使用make-keymap的特殊形式如果需要绑定的按键数目不大使用make-sparse-keymap更有效。
== 2.把映射表设为主编辑模式的局部键位映射表 ==
(use-local-map tmpkeymap)
=== 四:定义和设置局部变量 ===
== 1.定义变量 ==
有几种定义变量的方法比如setq给参数赋值或用let给语句块定义并初始化参数更正规的方法是使用defvar函数。它允许程序员将变量的资料集成到
C-h v等在线帮助功能中。defvar函数的语法是
(defvar varname initial-value "description of the variable")
defvar还有一个变体叫做defconst用来定义常数。
== 2/设置局部变量 ==
把变量设为主编辑模式的局部变量。
(make-local-variable 'variable-name) ;;注意使用的是变量名而非其值
==== 五:专用特殊缓冲区 ====
这些缓冲区与任何文件都没有关联关系要想在新窗口创建一个新的编辑缓冲区可以使用pop-to-buffer函数
(pop-to-buffer "*Calc*")
其它的变体:
switch-to-buffer 与命令C-x b相同
set-buffer 将编辑缓冲区指定为文本编辑缓冲区使用

168
Zim/Utils/emacs/Lisp.txt Normal file
View File

@@ -0,0 +1,168 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-03T17:27:02+08:00
====== Lisp ======
Created Sunday 03 April 2011
针对Emacs中文本编辑的编程简介
2010年3月6日 ahei 发表评论 阅读评论
http://emacser.com/edit-in-elisp.htm
Elisp是Emacs下的Lisp方言而Emacs是一款编辑器。那么针对于EmacsLisp要做的很重要一部分工作当然就是对编辑的自动化支持。比如移动鼠标输入句子查找替换代码高亮等等简单地说就是为更好更方便地支持文本编辑提供支持。而把这些函数都重合起来就起成了Emacs mode。如我们常用的C++ mode,python mode。还有之前我一直在介绍的org-mode等都是由Elisp拼成的。
学习Elisp可以满足对Emacs进行定制的需求你可以把想要的功能写在.el文件里面让Emacs来调用。一方面可以实现一些简单的轻量级的功能而不需要为此寻找和安装一个完整的mode。另一方面可以修改现有的mode使得更符合自己的习惯。这符合开源的作法不爽即改。
Elisp函数的简单例子
===== 光标位置 =====
;; 返回当前光标的位置
(point)
;; region的头跟尾
(region-beginning)
(region-end)
;; 最大光标位置即文件尾elisp还提供最小光标位置(point-min)不过我觉得那应该都是1吧。
(point-max)
;; 返回buffer结尾的绝对位置无视narrow-to-region
(buffer-end 1)
===== 移动光标和搜索 =====
;移动光标到392
(goto-char 392)
; 向前/向后移动n字符
(forward-char n)
(backward-char n)
; 跳过所有\n\t,即把光标移动第一个不是换行或制表符那里
; 返回移动的字符数
(skip-chars-forward "\n\t")
(skip-chars-backward "\n\t")
; 移动光标到myStr后面向前和向后
; 返回新的光标位置
(search-forward myStr)
(search-backward myStr)
; 同上但是参数是正则表达式myRegex
; 返回新的光标位置
(re-search-forward myRegex)
(re-search-backward myRegex)
===== 文本编辑 =====
; 删除光标后的九个字符
(delete-char 9)
; 删除选中的两点之前的文本
(delete-region mystartpos myendpos)
; 在当前光标位置插入一字符串
(insert "Forza Inter")
; 从buffer中获得一个字符串并赋给mystr
(setq Mystr (buffer-substring mystartpos myendpos))
; 改变字符大小写
;这个例子是指当前光标之前的20个字符
(rapitalize-region (- (point) 20) (point))
===== 字符串 =====
; 长度
(length "abc") ; returns 3
; 获取一个子串
(substring myStr startIndex endIndex)
; 替换,以正则方式
(replace-regexp-in-string myRegex myReplacement myStr)
===== Buffers =====
; 当前buffer的名字
(buffer-name)
; 文件名(全路径)
(buffer-file-name)
; 设定一个buffer名
(set-buffer myBufferName)
; 保存
(save-buffer)
; 关闭指定的buffer
(kill-buffer myBuffName)
; 关闭当前buffer
(kill-this-buffer)
; 临时指定一个buffer作为当前buffer
(with-current-buffer myBuffer
;; do something here ...
)
===== Files =====
; 打开一个文件
(find-file myPath)
; 另存
; 会关闭当前的buffer打开另存好的文件
(write-file myPath)
; 把一个文件内容插入到当前位置
(insert-file-contents myPath)
; 将选中的评论文本加到某个文件后面
(append-to-file myStartPos myEndPos myPath)
; 重命名
(rename-file fileName newName)
; 复制
(copy-file oldName newName)
; 删除
(delete-file fileName)
; 获取路径
(file-name-directory myFullPath)
; 获取文件名(不含路径)
(file-name-nondirectory myFullPath)
; 得到文件名后缀
(file-name-extension myFileName)
; 获得不含后缀的文件名。
(file-name-sans-extension "abc.htm")
===== 简单的例子 =====
(defun insert-p-tag ()
"Insert <p></p> at cursor point."
(interactive)
(insert "<p></p>")
(backward-char 4))
在当前光标处插入一个p tag。做法是插放一个串然后将光标移回4位。
编写一个mode
理论上来讲知道上面这些东西你就有能力编写一个mode了。但是编写mode毕竟是一个复杂的工作需要编写者对elisp编程具有”hello world”以上很多级的熟练度。
在李杀网作者有一个系列文章来讨论如何为一个编程语言编写mode。
The End. Have fun!

262
Zim/Utils/emacs/Misc.txt Normal file
View File

@@ -0,0 +1,262 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-05T22:03:11+08:00
====== Misc ======
Created Tuesday 05 April 2011
gccsense也是auto-complete的补全引擎而已.语法检查用flymake,很强悍,DEA中有配置
安装yasnippet
安装elib
安装cedet
安装ECB
安装Cscope
配置tabbar
company-mode配置
安装auto-complete
配置gcc-code-assist
配置Doxymacs
emacs的自动补齐智能感应 收藏
在编写代码时,自动补齐(成员函数变量,以及……)能提高很大的效率,emacs的自动补齐方法有很多种,我参考了很多其他网友的文章,简单总结了下,希望其他网友不要怪罪我哈,呵呵,我希望把我的学习过程记录下来,能对其他网友有所帮助.以下是几种不同的方法(也可以一块用哈)
1. Emacs 自带的hippie-expand (参考的是王垠的)
hippie-expand是 Emacs 自带的功能,
把M-/ 绑定到 hippie-expand在.emacs文件中加入
;;绑定按键
(global-set-key [(meta ?/)] 'hippie-expand)
hippie-expand 的补全方式。它是一个优先列表, hippie-expand 会优先使用表最前面的函数来补全。通常的设置是:
(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))
首先使用当前的buffer补全如果找不到就到别的可见的窗口里寻找
如果还找不到那么到所有打开的buffer去找如果还……那么到kill-ring里
到文件名到简称列表里到list…… 当前使用的匹配方式会在 echo 区域
显示.
确实是非常好用,基本上我M-/就能到达我想要的了.
2 采用etags
etags能像cscope那样,在代码里跳来跳去,比如查找函数,变量等,它还能够自动补齐代码.
1),先生成etags文件
find . /usr/include/ -name "*.c" -or -name "*.cpp" -or -name "*.hpp" -or -name "*.h" |xargs etags --members --language=c++
2).配置.emacs
(setq tags-file-name "~/TAGS")
3),使用
在emacs中,M-tab 就可以自动补齐了,不过有时候还是不是很好用.
M-. 查找一个tag比如函数定义类型定义等。
C-u M-. 查找下一个tag的位置
M-* 回到上一次运行M-.前的光标位置。 M-TAB 自动补齐函数名。
3 采用cedet包
1)下载cedet
网址是 http://cedet.sourceforge.net/
2)编译
tar -zxf cedet-1.0pre3.tar.gz
cd cedet-1.0pre3
make
如果make不成功的话,就看看那个说明吧
3)配置
查看emacs的配置文件在哪里
whereis emacs
拷贝编译好了的cedet
cp -r cedet-1.0pre3 /usr/share/emacs/
查看是否有我们需要的那个文件
ls /usr/share/emacs/cedet-1.0pre3/common/cedet.el
配置.emacs文件,在.emacs文件中加入
;;;;;;;;;;cedet
(load-file "/usr/share/emacs/cedet-1.0pre3/common/cedet.el")
;;设置检索范围
(setq semanticdb-project-roots
(list
(expand-file-name "/")));;可以设置为项目的顶级目录
;;绑定按键,ctr+tab,以下三种,任意选择一个,我喜欢第二个
;;(global-set-key [(control tab)] 'senator-complete-symbol);
(global-set-key [(control tab)] ' senator-completion-menu-popup)
;; (global-set-key [(control tab)] 'semantic-ia-complete-symbol-menu)
4)使用
在一个未输入完成的函数上尝试下ctr+tab键
看看效果吧:
emacs auto-complete 收藏
晚上在家写自己的网游服务端底层库休息时在网上闲逛无意中发现一篇介绍emacs auto-complete的文章正是自己想要的东西。比hippie-expand使用更方便快捷。于是便下载下来配置成功。另补充原文没有详细讲解的二点
生成etags在工程目录下执行 find -name "*.h" -or -name "*.cpp" -or -name "*.c" |xargs etags --members --language=c++
使用etagsM-x visit-tags-table然后选择要使用的tag文件即可。
Emacs中使用Cscope 收藏
在emacs中使用cscope,在preServer下有三个目录其中含有.h或.cpp文件。
第一步在preServer下执行find ./ -name *.[hc]'*'> cscope.files,其作用是将当前目录下.h和.cpp 文件列表导入cscope.files。
第二步cscope -b其作用是生成符号列表文件cscope.out。
第三步emacs中一般自动支持cscope先设定初始索引目录一般是当前根目录。
;; -*-mode:lisp-interaction-*- -*- coding: gbk-dos -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 外观显示 ;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;禁用启动画面
(setq inhibit-startup-message t)
;; *scratch* buffer的提示信息
(setq initial-scratch-message "")
;; 字体 可 "Monaco-11" 来改字号
(set-default-font "Monaco-12")
;; 设置中文字体
(set-fontset-font "fontset-default"
'gb18030 '("微软雅黑" . "unicode-bmp"))
;; Frame 中的字体添加
(add-to-list 'default-frame-alist '(font . "Monaco-12"))
;; 调出 windows 的字体对话框, 奇怪的有些字体安装在系统了却没有出现, 在 notepad 中可以看到
;; (w32-select-font nil t)
;;尺寸
(setq initial-frame-alist '( (width . 80) (height . 25)))
;;标题格式, "文件名 @ 全路径文件名"
(setq frame-title-format '("%b @ " buffer-file-name))
;;取消显示工具栏
(tool-bar-mode nil)
;; 取消显示菜单栏
(menu-bar-mode nil)
;;去掉滚动条, 鼠标滚轮代替
(set-scroll-bar-mode nil)
;;底栏显示列号
(setq column-number-mode t)
;;显示括号匹配
(show-paren-mode t)
;;显示日期
(setq display-time-day-and-date t)
;;显示时间
(display-time)
;;时间为24小时制
(setq display-time-24hr-format t)
;;时间显示包括日期和具体时间
(setq display-time-day-and-date t)
;;时间栏旁边启动邮件设置
(setq display-time-use-mail-icon t)
;;时间的变化频率
(setq display-time-interval 10)
;;光标靠近鼠标指针时,让鼠标指针自动让开,别挡住视线。
(mouse-avoidance-mode 'animate)
;;指针不闪,不恍花眼睛。
(blink-cursor-mode -1)
(transient-mark-mode 1)
;; 显示行号切换
(global-set-key [C-f6] 'global-linum-mode)
;;语法加亮
(global-font-lock-mode t)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 全局设定 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;y/n替代yes/no
(fset 'yes-or-no-p 'y-or-n-p)
;;设置粘贴缓冲条目数量
(setq kill-ring-max 200)
;;递归使用minibuffer
(setq enable-recursive-minibuffers t)
;;支持外部程序粘贴
(setq x-select-enable-clipboard t)
;; 默认 80 列自动换行, 需要 M-x auto-fill-mode 模式下
(setq default-fill-column 80)
;;取消错误铃,闪屏
(setq visible-bell t)
;;设置默认工作目录
(setq default-directory "~/work/")
;;默认为text模式
(setq default-major-mode 'text-mode)
;; 我的信息
(setq user-full-name "xxxxx")
(setq user-mail-address "xxxxx@gmail.com")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 我的插件目录导入 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 添加目录和二级子目录
(defun add-to-load-path (load-path-name)
(let (default-directory-old default-directory)
(progn (cd load-path-name)
(normal-top-level-add-subdirs-to-load-path))))
(add-to-load-path "~/etc/emacs23/site-lisp")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 风格 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'color-theme)
(color-theme-initialize)
(color-theme-arjen)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Unicad ;;;;;;;;;;;;;;;;;;;;;;;;;;;
(require 'unicad)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;; htmlize
;;;; 网上下载的 htmlize 会使用报错: invalid face, 解决方法:
;;;; 将下面一行:
;;;; for f = face then (face-attribute f :inherit)
;;;; 改为
;;;; for f = face then (or (face-attribute f :inherit) 'unspecified)
(require 'htmlize)
(setq org-publish-project-alist
'(("orgfile"
:base-directory "~/work/org/source"
:publishing-directory "~/work/org/publish"
:base-extension "org"
:section-numbers nil
:auto-index t
:headline-levels 3
:publishing-function org-publish-org-to-html
:style "<link rel=\"stylesheet\" href=\"../other/mystyle.css\" type=\"text/css\">")
("images"
:base-directory "~/work/org/source/image"
:base-extension "jpg\\|gif\\|png\\|bmp"
:publishing-directory "~/work/org/publish/image"
:publishing-function org-publish-attachment)
("other"
:base-directory "~/work/org/source/other"
:base-extension "css\\|el"
:publishing-directory "~/work/org/publish/other"
:publishing-function org-publish-attachment
("website" :components ("orgfile" "images")))))
;; org 自动换行
(add-hook 'org-mode-hook
(lambda () (setq truncate-lines nil)))

129
Zim/Utils/emacs/dired.txt Normal file
View File

@@ -0,0 +1,129 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-08T17:08:50+08:00
====== Emacs -- 强大的文件管理器 ======
dired 是 Emacs 自带的文件管理器,操作非常方便,再加上一些扩展之后无疑是一个理想的文件管理器。看看这里来了解如何增强你的 dired 。
===== Mark & Flag =====
dired 最方便的一点就是可以**对许多文件进行标记,并进行批量操作**。标记的方法有很多,最普通的标记就是 __d __为当前文件贴上删除标签之后可以使用 __x__ 来真正删除所有贴上删除标签的文件。
dired 还提供了许多预定义的方便的标记操作(当使用__ C-u 传递一个前缀参数时他们执行相反操作__即去掉标记),例如:
通常这些命令可以方便地帮你清理垃圾如果还不满意可以使用__ % d __REGEXP <RET> 来输入自己的正则表达式,匹配到的文件会被贴上删除标签。
当然,能用的标签并不止是 __D (即删除标签)__几乎任何一个字符都可以使用(但需要通过转换默认的为D和*标签)不过__最常用的还是 *__ m 命令即是以 * 标记当前文件。同样dired 提供了很多方便的标记操作(这些命令在传递一个前缀参数的时候都会执行相反的操作,例如 C-u * * 会去掉所有可执行文件的标记)
dired 可以使用更多的字符进行标记,只是没有提供相应的快捷键操作而已,你可以先以 * 标记,然后使用 * c OLD-MARKCHAR NEW-MARKCHAR 来把 * 标记变换成其他标记,几乎任何字符(当然不包括中文这种多字节的字符)都可以作为标记,不过空格被特殊对待,用于表示所有未标记的文件。
===== 例子 =====
列举了这么多命令,多少有些枯燥,我们来把当前目录下的所有备份文件移动到 ~/backup 目录下。假设当前目录已经有一些文件被你以 D 标记,但是暂时还不想删除:
选择个临时标记,比如 t ,只要保证当前 buffer 里面没有已经存在的这种标记就行了。
*c D t 把当前所有 D 标签换为 t 标签。
~ 以 D 标记所有备份文件。
*c D * 把 D 标签换为 * 标签。
R ~/backup <RET> 来把所有标记为 * 的文件移动到 ~/backup 目录里面。
*c t D 恢复原来的 D 标记。
当然这要假设你原来没有设定其他的 * 标记要不然你也可以再添加一个临时标记。总之操作和清晰也很方便感觉像在汇编语言里面使用寄存器一样__大多数批量操作都是针对 * 标记的,所以对某个标记操作之前需要把他先转换为 * 标记。__
===== 文件操作 =====
dired 内建了很多文件操作,对于操作的文件有一个统一的约定,按照顺序是:
__如果你通过 C-u 传递一个前缀参数 N ,那么它对从当前行开始的 N 行执行操作( N 也可以是负数)。__
__ 如果有被标记为 * 的文件则以这些文件为操作对象。__
__ 只对当前光标所在的文件进行操作。__
这些命令全部__绑定到大写字母__上记忆也非常方便
C 拷贝文件。把 dired-recursive-copies 设为非 nil 的值可以递归拷贝目录,通常我们设定为 top ,这表示对于顶层目录 dired 会先进行询问是否要递归拷贝,而其中的子目录则不再询问。如果嫌询问太麻烦,可以直接设置为 always 。
D 删除文件。类似的有一个 dired-recursive-deletes 变量可以控制递归删除。
R 重命名文件,也就是移动文件。
H 创建硬链接。
S 创建软链接。
M 修改权限位,即 shell 里面的 chmod 命令。
G 修改文件所属的组。
O 修改文件的所有者。
T 修改文件的修改时间,类似于 shell 命令 touch 。
P 打印文件。
Z 压缩或解压文件。
L 把 Elisp 文件加载进 Emacs 。
B 对 Elisp 文件进行 Byte compile 。
__ A 对文件内容__进行正则表达式搜索搜索会在第一个匹配的地方停下然后可以使用 __M-, __搜索下一个匹配。
Q 对文件内容进行交互式的正则表达式__替换__。
!command 对文件执行shell命令
===== 单字符命令 =====
__#__ 为所有自动保存的文件(通常是文件名开始和结尾都是 # 的文件)贴上删除标签。
__~__ 为所有备份文件(即文件名以 ~ 结尾的文件Emacs 和 vi 等编辑器默认情况下都会产生这样的文件)贴上删除标签。
__&__ 为“垃圾文件”(看 dired-garbage-files-regexp 的值可以知道 dired 把哪些文件当作了垃圾文件)贴上删除标签。
以上命令的标记为D
a 在当前buffer打开目录(默认是在新的buffer打开目录)
i 在当前buffer尾部打开目录并设置标记
k 隐藏标记为*的文件
o 在新buffer中打开当前文件并将光标移到其中
q 关闭当前窗口(不是文件编辑窗口)
n 下移一行
p 上移一行
空格 下移一行
s 将文件按名称或修改时间排序
d 将文件标记为删除
u取消文件的标记状态
U 取消整个文件的标记状态
t 交换标记,将已加*与未加*的交换
j 跳转到当前目录中一个文件,并设置标记
g 现实k隐藏的文件
x 执行标记对应的操作
v 察看文件内容
m 设置标记
Break 删除上一行的标记
y 察看当前文件类型
! 对文件执行shell命令
+ 创建目录
__w 复制文件名,如果通过 C-u 传递一个前缀参数 0 ,则复制决定路径名,如果只是 C-u 则复制相对于 dired 当前目录的相对路径。__
I 把当前文件以 info 文档的格式打开。
N 把当前文件以 man 格式打开(使用 WoMan)。
Y 为所有标记的文件创建一个到指定目录的相对符号连接(即使用相对路径进行引用,而不是绝对路径)。
===== *命令 =====
** 标记所有可执行文件
*@ 标记所有符号链接文件
*/ 标记所有目录文件
*s 标记所有文件为*
*. 标记具有给定扩展名的文件
* % REGEXP <RET>标记所有__文件名__匹配到给定的正则表达式的文件
*? MARKCHAR 或 M-<DEL> __去除所有以 MARKCHAR 标记的文件的标记__如果传递一个前缀参数则会对每一个文件要求你确认是否去除标记。
__* c OLD-MARKCHAR NEW-MARKCHAR__ 把 * 标记变换成其他标记
以上命令的标记为*
===== %命令(一般和正则表达式有关) =====
%d REGEXP <RET> 把__文件名__符合正则表达式的文件标记为删除D
% m REGEXP <RET> >标记所有__文件名__匹配到给定的正则表达式的文件
% g REGEXP <RET> 标记所有__文件 内容__ 匹配到给定的正则表达式的文件
正则表达式语法为grep而非egrep
===== 强大的重命名功能 =====
dired 有一个文件名转换的理念,所以转换,并不一定是重命名,还可以是复制和创建链接。所以,除了 % u 和 % l 重命名原文件为大写、小写外,一个使用正则表达式进行转换的命令提供了四个选项: __% X 其中 X 可以是 R , C , H 和 S __分别代表重命名、复制、创建硬链接和创建软链接他们使用匹配和替换的机制这有点像 rename 这个程序,例如: % R \.[^.]*$ <RET> .1\& <RET> 给原来的文件名加个标号 1 ,把 foo.txt 变成 foo.1.txt 。
另外dired 还有一个叫做 __Wdired__ 的扩展可以直接在 dired 的 buffer 里面编辑文件名来达到重命名的效果。使用 __M-x wdired-change-to-wdired-mode__ 进入编辑模式,这个时候可以直接像编辑普通文本一样编辑文件名,还可以添加路径来实现把文件移动到其他目录(可以通过保存文件的方式来使更改生效)。除了文件名可以编辑以外,其他部分被标记为只读,但是如果把 __wdired-allow-to-change-permissions__ 设为 t 的话,还可以编辑文件的权限位。编辑完成之后使用 C-c C-c 来应用所做的编辑。非常方便。
===== 排序和过滤 =====
dired 有方便的排序功能,这里介绍了如何方便地使用排序功能。另外 dired 还有一个 __k__ 用于去掉不想显示出来的文件,它并不删除磁盘上的文件,只是临时从 dired 的 buffer 中去掉他们__ g __刷新一下它们又会显示出来这样首先用强大的标记功能进行标记然后使用 k 去掉,就实现了过滤的功能。
子目录操作
===== 同时操作当前目录和子目录 =====
dired 允许同时操作当前目录和子目录。在 dired-listing-switches 里面加入 R 选项就可以显示子目录如果只是想临时显示某个子目录的内容对该目录执行__ i __操作就会把该子目录的内容添加到 dired __当前 buffer 的末尾__并把光标移动到那里dired 在__移动之前会先设置一个 mark__ ,所以可以使用 C-u C-<SPC> (对于我来说,我把 set-mark-command 绑定到了 M-<SPC> 上,这里自然就是使用 C-u M-<SPC> 了)回到原来的位置。
还有一些方便的功能,我把几个常用的命令列在这里:

View File

@@ -0,0 +1,139 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-17T23:11:14+08:00
====== Dired ======
Created Wednesday 17 August 2011
http://www.fengyj.net/emacs/Dired.html
Dired
在 dired 中移动
在 dired 中删除文件(Flags)
一次性标记很多文件
在Dired中访问文件
在Dired中用Mark
操作文件
在 dired 中使用shell命令
dired 中的文件比较
==== 在 dired 中移动 ====
C-nn<space>向下移动一行。
C-pp<del>向上移动一行。<del>同时还会去掉之前的标记。
jdired-goto-file移动到指定目录或文件所在的行。
==== 在 dired 中删除文件(Flags) ====
d给文件作一个删除标记(flag)。
u删除文件的删除标记。
<del>:移动到上一行,然后移除上一行的删除标记。
x执行删除指令。
被删除标记标记的文件或目录前会有一个 D 标记。
一般情况下不能直接删除非空目录,除非变量 dired-recursive-deletes 不为空。
==== 一次性标记很多文件 ====
~:标记所有备份文件,形如“~文件名”的文件。
% d REGEXP <REG>o为符合正则表达式的文件作标记。
==== 在Dired中访问文件 ====
f直接访问当前行所指示的文件。 <return>e和f一样。
o和f相似但在另一个窗口打开文件光标移到新窗口。
c-o和f相似但在另一个窗口打开文件光标还是在旧窗口。
__^__访问父级目录相当于移到当前目录的".."行然后按f键。
v和 f 类似,但是打开的文件是只读的。
==== 在Dired中用Mark ====
dired的删除标记叫做 flag一般的标记则为 markdired-mark。
* mark
用*给当前文件作标记。如果提供一个正数作为参数N则标记从当前文件( 包括当前文件)开始向下的N个文件如 C-u 3 * m 顺序标记3个文件如果是负数则向上标记N个文件。
* *
标记所有可执行文件,如果有个参数,则 unmark 这些可执行文件。
* @
标记所有 链接 文件,如果有个参数,则 unmark 这些链接文件。
* /
标记所有目录文件,**除了"."和".."目录**,如果有个参数,则 unmark 这些目录。
__* s__
标记该目录下的所有文件及目录,除了"."和".."目录。
* u
删除当前行的标记
* <del>
移动到上一行,并删除那一行的 mark。
U
移除当前 dired buffer 中的所有 mark即当前目录中的所有 mark。
__M-}__
移动到下一个 marked file。(dired-next-marked-file)
M-{
移动到上一个 marked file。(dired-prev-marked-file)
* t
mark 开关,也就是 marked files 在执行完命令后变成 unmarked files而 unmarked files 变成 marked files。(dired-toggle-files)
__* c__ OLD-CHARACTOR NEW-CHARACTOR
改变 marked 标记,用 new charactor 的 mark 替换 old character 的 mark例如: * c * a则所有星号的标记都会变成字符 a。用该命令可以实现将任意字符作为标记包括空格字符空格字符也代表 unmarked files。
__* %__ REGEXP <enter>
标记所有文件名满足正则表达式的文件。这个和 % d 很类似,% d 是为了给文件作上删除标记。
__* g__ % REGEXP
如果正则表达式匹配了 dired buffer 中的文件的__内容__则标记该文件。(dired-mark-files-containing-regexp)
C-/
dired undo取消设定的 mark。
==== 操作文件 ====
在命令前加入数字参数 N就会操作以当前光标所在的行为基准向下连续的N个文件如果N是负数则操作反方向的连续N个文件。
如果文件被 * 号标记,则操作所有被星号标记的文件。 再者就操作当前行的文件。
下面是操作dired中文件的命令
`C new <ret>'
复制特定文件(`dired-do-copy')。类似shell命令 cp变量 `dired-recursive-copies' 控制是否遍历复制子目录,就像 cp -r默认情况是 `nil',意味不能复制子目录。
`D'
删除指定文件(`dired-do-delete')。和shell中的 rm 命令类似。
`R NEW <RET>'
重命名指定文件(`dired-do-rename')。如果指定的是单个文件,则仅仅完成重命名功能,如果指定的是多个文件,则 NEW 指示的是一个文件夹命令会把指定的文件剪切到文件夹里就像shell里的 mv 指令。
`H NEW <RET>'
制作特定文件的硬链接(`diref-do-hardlink')。和shell命令的 ln 类似。
`S NEW <RET>'
制作特定文件的符号链接(`dired-do-symlink')。和shell命令的 ln -s 类似。
__`M__ MODESPEC <RET>'
改变文件的权限(`dired-do-chmod')。
`G NEWGROUP <RET>'
改变文件所属的组为 NEWGROUP。(`dired-do-chgrp')。
`O NEWOWNER <RET>'
改变文件的所有者为 NEWOWNER。(`dired-do-chown')。
`T TIMESTAMP <RET>'
将文件的修改时间调整到当前时间和shell命令中的 touch 类似(`dired-do-touch')。
`P COMMAND <RET>'
(`dired-do-print')。
__`Z'__
压缩特定的文件(`dired-do-compress')。如果文件已经是压缩文件则Z会给该文件解压缩。
`L'
装载特定的 Emace Lisp。
==== 在 dired 中使用shell命令 ====
dired 的命令 ! 会在 minibuffer 中提示你輸入 shell 命令,用此命令来操作指定的文件。
有两种方式可以让shell command操作多个文件
* 命令行包含两边有空格的星号*
如果星号两边为空格__命令只会执行一次__* 号会代替当前dired buffer 中__标记__的所有文件名文件名的顺序即为dired buffer中文件名的顺序。
因此,命令 `! tar czvf zip.tar.gz *' 将当前dired buffer 中的所有文件压缩到 *zip.tar.gz* 中。
* 如果命令行不包括星号命令会在__每个文件上执行一次__。
例如:`! uudecode <return>'会用uudecode命令依次执行每个文件。
* 命令行上有星号但两边没有空格这时会将该星号传给shell当作通配符使用。匹配的文件会和标记的文件一起传给命令 如:
* wl -l "*.cpp~" * //会将当前目录下的所有以.cpp~结尾的文件与当前标记的所有文件一起传给wl命令。
* wl -l "*cpp~" //会将当前目录下的所有以.cpp~结尾的文件与当__前标记的文件一次一个__按先后顺序传给wl命令。
* 命令行包括两边为空格的 ? 用指令操作当前文件,当前行的文件名会替代?。例如:
! chmod 777 ? <return> 会将当前行的文件的权限改为777。
! 用命令行执行的指令不会立即改变dired buffer但可以用g强制刷新 dired buffer。
==== dired 中的文件比较 ====
有两个 dierd 命令用 diff 比较特定的文件:
` = '
用当前文件(the file at the point)来比较另外一个文件(the file at the mark)利用的是dired的diff程序(`dired-diff')。用 mark标记的文件不是dired的mark而是__emacs的标准mark__用快捷键 C-SPACE或C-@所作的mark。
`M-='
用当前文件的备份文件于当前文件进行比较。(`dired-backup-diff')。

View File

@@ -0,0 +1,135 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-17T23:28:57+08:00
====== Emacs的文件管理器Dired ======
Created Wednesday 17 August 2011
详细的用法说明可以参照Emacs的info文件这里只是介绍一些常用的功能。
M-x dired 或者 C-x d可以进入dired-mode这样便可以对文件进行操作了作为一个文件管理器还是挺不错的。
在.emacs里加入以下语句。
(setq dired-recursive-deletes t) ; 可以递归的删除目录
(setq dired-recursive-copies t) ; 可以递归的进行拷贝
(require 'dired-x) ; 有些特殊的功能
(global-set-key "/C-x/C-j" 'dired-jump) ; 通过 C-x C-j 跳转到当前目录的 Dired
(setq dired-guess-shell-alist-user
(list
(list "//.chm$" "xchm")
(list "//.rm$" "gmplayer")
(list "//.rmvb$" "gmplayer")
(list "//.avi$" "gmplayer")
(list "//.asf$" "gmplayer")
(list "//.wmv$" "gmplayer")
(list "//.htm$" "w3m")
(list "//.html$" "w3m")
(list "//.mpg$" "gmplayer")
)
) ; 设置一些文件的默认打开方式,此功能必须在(require 'dired-x)之后
一些常用的命令
和文件一样打开目录或通过 C-x d 都可以进入目录的 Dired 缓冲中。这里是打开 Dired-x 之后默认的绑定。说明后面[]中的符号的意义:
[*] 作用在已标记的所有文件(目录)或光标所在当前文件(目录)上。
[p] 用前缀参数表示文件个数,从当前文件开始,正数向下、负数向上。
[u] 用前缀参数改变默认行为。对于设置标记的命令一般变为去掉标记。
[x] 需要加载 dired-x。
查看帮助
? 简单帮助
h 模式帮助
移动光标
n, p, SPC 上、下移动光标 [p]
C-n, C-p 上、下移动光标 [p]
M-{, M-} 已标记的文件之间移动 [p]
C-M-p, C-M-n 缓冲中的子目录间移动 [p]
<, > 缓冲中的目录行间移动 [p]
C-M-u 缓冲中的目录树上移动 [p]
M-g 光标移动到某个文件上
M-G 光标移动到某个缓冲中的子目录上,(用 i 插入的)
标记文件
m 标记文件,下移一行 [p]
u 去掉标记,下移一行 [p]
U 去掉缓冲中所有的标记
M-Backspace 去掉缓冲中所有的某个标记,缺省为 * 标记
Backspace 并去掉上一行标记,并上移一行 [p]
t 标记/未标记互换
D 删除所有标记的文件/目录 [*]
d 设置“删除标记”字符D并且光标下移一行 [p]
x 删除用 d 标记的文件/目录
~ 将缓冲中备份文件做删除标记 [u]
& 没用的文件,做删除标记
# 将缓冲中自动保存的文件做删除标记 [u]
. 按备份文件版本,将备份文件做删除标记 [u]
% g 标记所有“含有”regexp 的文件 [u]
* * 标记所有可执行文件 [u]
* . 标记所有同扩展名文件 [ux]
* / 标记所有目录 [u]
* @ 标记所有符号连接 [u]
* c 改变标记的符号
% d 通过匹配 regexp 标记删除
% m 通过匹配 regexp 标记 [u]
复制、移动、创建 文件或目录以及连接
C-x C-f 创建文件
+ 创建目录
R 文件的重命名/移动 [p*]
C 复制文件 [*]
S 创建文件的 Symbol link (绝对路径) [p*]
Y 创建文件的 Symbol link (相对路径) [px*]
H 创建文件的 Hard link [p*]
% C 复制匹配 regexp 的文件 [p*]
% S 创建匹配 regexp 的 Symbol link (绝对路径) [p*]
% Y 创建匹配 regexp 的 Symbol link (相对路径) [p*]
% H 创建匹配 regexp 的 Hark link [p*]
修改文件名、属性
M 修改文件 rwx 权限属性 [*]
G 修改文件 Group 属性 [p*]
O 修改文件 Owner 属性 [p*]
T 修改文件的时间戳 [p*]
% l 文件名逐一改为小写 [p*]
% u 文件名逐一改为大写 [p*]
% R, % r 重命名/移动匹配 regexp 的文件 [p*]
访问文件,目录
e, f, RET 打开文件或目录
a 打开文件或目录,并替换当前缓冲
v 使用 view 模式查看文件q 退出,有些文件使用外部查看程序调用
o 另一个窗口中,打开文件或目录
C-o 另一个窗口中,打开文件或目录,但当前窗口不变
F 打开(多个)文件 [x*]
I 使用 Info 模式查看文件
N 使用 man 模式查看文件,若有前缀参数,提示输入处理命令 [ux*]
V 使用 RMAIL 模式查看文件 [x]
退出
^ 访问目录的父目录,若有前缀参数在另外的窗口中打开 [u]
q 退出缓冲,若有前缀参数则关闭缓冲 [u]
隐藏/刷新缓冲中内容
s 互换缓冲中“文件名/时间”排序 [u]
C-u s 修改传递给 ls 的参数,即修改每行的内容
i 把当前行的子目录插入缓冲中
M-o 隐藏/显示部分次要文件,使缓冲更简便,若有前缀参数标记隐藏的文件 [ux]
$ 隐藏/显示当前目录中内容 [p]
M-$ 隐藏/显示缓冲中所有目录内容
k 隐藏文件,按 g 可以再显示出来 [p*]
l 刷新缓冲文件 [p*]
g 刷新缓冲所有文件
C-/, C-_, C-x u dired 模式的 undo
其他
= 比较文件
M-= 文件和备份之间比较,若有前缀参数,提示输入 diff 选项 [u]
w 复制文件名到 kill-ring [p*]
Z 压缩/解压缩文件 [p*]
X 在文件上执行 shell 命令 [p*]
B 编译(Emacs Lisp)文件 [p*]
L 加载(Emacs Lisp)文件 [p*]
y 给出文件类型信息 (通过 file 命令)
P 打印文件 [p*]
dired-x.el 中的其他有用的函数
dired-mark-extension 按后缀标记
dired-flag-extension 按后缀标记删除
dired-clean-patch 标记删除 patch 文件
dired-clean-tex 标记删除 tex 编译文件
dired-very-clean-tex 标记删除 tex 编译文件
dired-jump 跳转到当前缓冲所在目录
dired-jump-other-window 在另一个窗口中跳转到当前缓冲所在目录
dired-omit-here-always 在当前目录生成 .dired 文件

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,23 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-05-22T21:32:23+08:00
====== 2 ======
Created Sunday 22 May 2011
(gnus-agentize)
(setq smtpmail-default-smtp-server "mail.cc.umanitoba.ca")
(setq smtpmail-smtp-server "mail.cc.umanitoba.ca")
(setq smtpmail-smtp-service 587)
(setq message-send-mail-function 'smtpmail-send-it)
(setq send-mail-function 'smtpmail-send-it)
(setq gnus-select-method '(nntp "news.cc.umanitoba.ca"))
(setq gnus-secondary-select-methods '((nnimap "gmail"
(nnimap-address "imap.gmail.com")
(nnimap-server-port 993)
(nnimap-stream ssl))
(nnimap "uofm" (nnimap-address "mail.cc.umanitoba.ca")
(nnimap-server-port 993)
(nnimap-stream ssl))
(nntp "freenews.netfront.net") ))

View File

@@ -0,0 +1,507 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-05T22:20:26+08:00
====== effcet-emacs ======
Created Tuesday 05 April 2011
http://blog.csdn.net/DelphiNew/archive/2008/01/19/2053676.aspx
**十个提升你Emacs生产力的高招**
Emacs是世界上最好的编辑器(真的有很多人这么认为)。不要以为emacs只是在编写程序时很牛X其实只要你真正精通了emacs会发现她几乎在所有用到打字的应用(比如写email啦起草文档啦写blog啦写html/xml文件等等等)时都是最牛的。
本文中所写的招数是面向emacs高级用户译者看此文时并不是emacs高级用户同样获益非浅啊你应该熟悉基本的emacs启动编辑操作你得知道怎么把东东拷到你的.emacs里面在所拷的东东出现问题时你得知道怎么调试或者能找到一个乐于助人的emacs高手也行
这里所列出的招数并非都是对emacs的定制有些是对你桌面环境的调节这些调节可以使桌面环境更好地与emacs无缝连接工作。
要想理解emacs的高效**关键是要明白她的所有设计都是出于效率考虑的**,这里所说的**效率包括“动作的效益”**。任何一个老练的音乐家都知道“动作的效益”是成为世界级艺术家的关键一环。在演奏时任何多余的动作都是浪费精力而且会产生不良效果。
使用鼠标基本上可以说是最违背动作效益的行为,因为你得提起你的手...摸着鼠标...摆正方位...可以说鼠标是个极笨重的设备emacs高手在不得不用一下鼠标的时候都认为这是一次高速缓冲命中失败学过微机原理的人可能听得懂这句话吧大大影响的连贯性和速度。
相对于emacs高手图形化IDE用户就好比业余的音乐家带着些许郁闷地把玩着自己的乐器。一般IDE都又炫又好看的对话框让你很难与之交互这句话面向的听众是emacs高手看过下面的条款6就会明白他说什么了但是却给新手一些操控的快感。可是咧~这种操控是相当粗糙的真正的程序员需要的是能给他们更多操控机能的东东。所以基本上可以说emacs对真正的程序员来说是世界上最好的编辑器啦
IDE还具备重构功能一般什么多人都爱拿这个来吹因为重构工具可以自动地帮你整理结构不良的代码。没错在某些程度上来说。但是偶告诉你个秘密喔重构工具不懂英文耶所以更不懂中文啦55。重构工具一般只能处理一些特定的文本前面所说的“某种程度”当她碰上其它编辑工作时就无能为力啦。重构工具只能解决一小部分问题而emacs却几乎能在你进行任何一类编辑时提供一系列条理清晰的操控能力。
然而正如我常说的眼见为实即便你相信你也得看到实际效果才心甘。那么接下来你得对emacs做一个严肃的、深远的、长期的承诺才能真正精通emacs。**精通emacs的过程包括学习Lisp、定制emacs使她最符合你的设想随着这一过程的你会更加地渴望有更多定制、更多的自动化所以哪怕你已经精通了emacs你对她的定制和扩展也不会停息的**。
所以,你看明白了吧?**emacs可不是一个给懦夫使用的编辑器**,这篇博客文章是给那些下了决心、做了承诺并且想要进一步增强他们对这个优雅的顶级的万古长青的软件的掌握。
其他的读者或者听众我想你的Eclipse应该刚好启动完毕了你可以调头回去忙你自个儿的啦~
__条款1把Caps-Lock和Control键互换__
在Windows和苹果Mac键盘上那个Ctrl键居然被远远地放在左下角而Ctrl对于emacs的使用却是时时刻刻都很重要的如果你不把Ctrl放到一个更舒服的位置你就很难成一个emacs艺术大师了。这位置应该与你的基本手位处于同一行那么Caps Lock是最佳选择。在很多unix工作站上这个位置放的就是Ctrl键原因同上。
要想在w2000或者XP中实现这个互换需要修改注册表。从开始菜单中选择“运行”输入regedit。在左边的树状视图中找到
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Keyboard Layout
XXXXX不用译了。
点击 KeyboardLayout 项,使之获得焦点。再从“编辑”菜单中选择新建一个二进制值,命名为 "Scancode Map",它的类型应该显示为 REG_BINARY。
然后选择这个新建的"Scancode Map"值项,用“编辑”菜单中选择修改二进制值,在二进制编辑对话框中,输入下列数据:
0000: 00 00 00 00 00 00 00 00
0008: 03 00 00 00 3A 00 1D 00
0010: 1D 00 3A 00 00 00 00 00
选择OK关闭对话框退出注册表编辑器注销后重登入你的caps和ctrl键应该就互换成功了。也可能要重启一次。
在linux的X-Window中可以使用xmodmap工具。在你的主目录新建一个名字为.xmodmap的文件如果已经存在则只需修改。向该文件加入下列内容
!
! Swap Caps_Lock and Control_L
!
remove Lock = Caps_Lock
remove Control = Control_L
keysym Control_L = Caps_Lock
keysym Caps_Lock = Control_L
add Lock = Caps_Lock
add Control = Control_L
保存,再向你的 ~/.bash_profile 文件加入一行:
xmodmap ~/.xmodmap
在Mac OS XPanther或Jaguar你得安装一个修改过的键盘驱动这说来有些吓人但是很有效。
这儿有个关于驱动的讨论:
http://www.macosxhints.com/article.php?story=20031102032521826
如果你用的不是Mac笔记本好像有一个XML文件可以编辑来实现可以参考这儿
http://www.eecs.wsu.edu/%7Eschneidj/mac-os-x-10.3.html#swap
下面的URL有一条关于在其它系统上实现的信息
http://www.manicai.net/comp/swap-caps-ctrl.html
__条款2不用Alt来调用M-x__
Alt-x是最常用的emacs组合键每次使用时你都得把左手蜷起来。**任何一个你要做几千次的动作最好应该是流线型的**所以你最好希望可以用Ctrl键来调用M-x。要想用Ctrl舒服你得选把条款1完成了
要养成使用Ctrl键习惯的另一个重要原因是:Alt键并不可靠也并alt-x可能都不能使用。与其为不同的系统设置而头痛还**不如直接就不使用alt键**,使用一个任何时候都有效的组合键相对来说更加容易且方便。
我选用的组合键序列是Ctrl-x Ctrl-m。请注意当你调用一个2键序列而这两个组合键都使用相同的转义键时你只需按住转义键这里指Ctrl再按其它两个键即可这里指x和m。所以现在调用M-x的方法是按住Ctrl按x按m松开Ctrl。
将下面的lisp表达式加到你的.emacs文件中就可以启用Ctrl-x Ctrl-m了
(global-set-key "\C-x\C-m" 'execute-extended-command)
(global-set-key "\C-c\C-m" 'execute-extended-command)
我另加了一行设定Ctrl-c Ctrl-m也调用同一命令使得这个按键组合**更能容错一些**。如果偶不小心把Ctrl-x按成Ctrl-c仍然能够成功调用。这两个按键都没有默认的emacs绑定所以你的设置不会影响到其实的快捷键。
你应该把这个按键序列练到习惯为止到时你差不多都不想再用alt-x了。当然你还会用到alt键来做其它的事一会儿就告诉你
顺便说一下如果你想把这招发挥到极致那在你按Ctrl-x**最好不要用你的无名指来敲x键**。这时我会用左手的食指的敲因为觉得这样比较习惯但是你可能会觉得用左手中指会更好一些。这是因为当你用小指去按那个变成Ctrl的Caps-Lock时你的手并不处于键盘的基本方位。**关键是要使用尽可能少的肢体伸缩,尽可能少的手指动作**。你可以实验出你自己觉得最舒服的方式来。
__条款 3: 使用 backward-kill-word (向后删一词)而不是 Backspace向后删一字__
**emacs高手一般都尽量避免使用backspace键**因为它离手的基本方位太远了。如果你经常打错字但是你的速度又很快一分钟打50个词以上的话把整个词删掉重打可比勤勤恳恳地用backspace倒删到你打错的地方再从一半打起要经济实惠得多。
加入下面的几行到你的.emacs文件中
(global-set-key "\C-w" 'backward-kill-word)
(global-set-key "\C-x\C-k" 'kill-region)
(global-set-key "\C-c\C-k" 'kill-region)
请注意ctrl-w已经有一个默认绑定kill-region了这是个相当重要的命令所以你得把它重新绑定到其它按键序列中去。我用的是Ctrl-x Ctrl-k(然后再加一个容错版的Ctrl-c Ctrl-k)。这样用主要是因为我在以前工作的公司一个很牛X的emacs高手这么帮偶设的现在我会的很多emacs技术都是当初这个高手教偶的。重绑定Ctrl-x Ctrl-k意味着你没有了edit-kbd-macro的快捷键但是这个键你真的不会经常去用所以不会觉得丢了什么东东的。
这样做还有一个额外的好处很多Unix命令行shell都提供类似emacs的命令行编辑按键而Ctrl-W一般都是backward-kill-word的默认绑定。这样的话你的习惯就和很多shell一致了。
你打字越快,这招就越升值。慢慢地你对如何最快更改各种打字错误会培养出一种最适合你自己的感觉。我的手感一般是这样的:
1.如果我打错一两个字符而此时我的光标刚好就在错误的旁边我就用backspace键。
2.如果错误字符在光标前面15到20个字符左右的地方那我一般就使用Ctrl-W直接杀回去然后重新打出这些词来。
如果错误的字还在更远处,那偶就用**alt-b跳回到错词后面再做ctrl-b定位到错误的字符处理进行更正**。
对于比之更远的错误我会使用快速导航来回到那个位置。条款4讲到一部分这个技术。
使用ctrl-w绑定backward-kill-word时有件事情你可得小心了Ctrl-w在很多windows程序中是强行绑定到“关闭窗口”这一操作上的。这一动作没得后悔在浏览器窗口中它也不会保存你填写过的表单。也就是说如果你正在为一个网页填写表单然后你忽地想用ctrl-w来更正一个错误咔嘣--完咧~在你那好用的OLE版M$ windows上你的所有工作都白费了。目前我还不知道怎么覆盖掉这个可怕的行为如果你知道怎么做麻烦你考虑我一下。
__条款4使用递增式搜索来进行快速导航__
**知道如何高效地移动光标是成为emacs高手的关键**。IDE用户把他们大部份的时间花在摸索鼠标上了根本没有想过如何用其它方法来实现光标导航却不知道自己的方法是多么的低效。在一个高手的手中emacs是世界上最高效的文本编辑工具主要是因为她可以让你不用鼠标做到几乎所有的事情。
emacs高手总是**设法让他们的会话窗口越高越好**,最好是能垂直地填满整个屏幕--因为垂直的屏幕空间在你查看一个文档时可以说是最宝贵的空间了。当你使用屏幕空间一次性查看多行文本时,使用递增式搜索一般比使用鼠标直接定位要快得多。
**养成使用ctrl-r(向前递增式搜索)和ctrl-s(向后递增式搜索)来在文档中进行移动的习惯**。__当你要向前或者向后移动5行左右而且你又看得到移动的目的地时你应该使用递增式搜索。__
要想高效地做到这一点你并不需要搜索你光标目的地处的整个单词。让你的目光掠过目标点周围的一行或者一段话选择一个看起来唯一性比较强而且比较好敲的单词然后递增地搜过去。如果你选单词不是那么的唯一那可能要按两三次crtl-r或者ctrl-s。但是放心emacs会把已匹配的单词高亮显示如果你看到匹配的东东太多了按一下ctrl-g然后重找一个词来递增导航。
一旦你掌握了它,**再怎么强调这一招数的强大都不会过份的**。你必须不断地重复直到你的手“自动地”去这样按才能算是真正掌握这一招。这时emacs就好像变成你身体的延伸一样成为你身体的一部分你可以想都不用想就把这些微妙的按键敲出来。这类似于你学车时最终掌握的一些微妙的本能反应。
__条款5使临时Buffer__
emacs最强大的功能之一就是她可以迅捷地生成一个**不与任何一个文件关联的buffer**。一旦你习惯了使用这一技术,你就对明显地感觉到其它编辑器这一功能性的不足。
要想建一个临时buffer很简单切换过去就是了Ctrl-x b调用命令switch-to-buffer然后你就瞎按一通adsflj。马上地你就来到一个草稿本上你可以在上面做笔记把临时结果导过来或者用来做任何对你手头问题有帮助的事。
如果你打算维护多个临时buffer你则应该给它们起些好记点的名字比如foo, bar, baz, buh...等等
如果你打算边靠边地比对两个buffer你可把emacs屏幕水平地分割一下。条款6会讲到
由于你的临时buffer并不与任何一个文件关联你杀它们就跟创建它们一样方便用ctrl-k也就是kill-buffer命令。
如果你打算保存临时buffer的内容了也很简单使用Ctrl-x Ctrl-w调用write-file命令。她会提示你输入一个文件名。保存文件后你可以杀掉这个buffer译注区区真的很喜欢用杀这个词来替代关闭这一说法~),并可以随时通过打开文件重新访问它的内容。
__条款6精通有关buffer(缓冲区)和window(视窗)的命令__
你会经常做一些需要打开多个视窗的编辑工作的。emacs使用一套与其它应用程序有些许不同的术语。一个buffer是指一个包含文本的逻辑空间这个空间有可能会与一个进程或者文件关联一个window是屏幕上显示着一个buffer或者这个buffer的一部分内容的可见区域。一个frame(窗框)则是一个你在操作系统说法里面管它叫window窗体的东西一个独立的包含标题栏或者是类似东西的窗体。
下面是几个需要重点掌握的命令:
* ctrl-x 2: split-window-vertically -- 把你的当前window切成上下两个等高并且显示同一buffer的window在你改变其中一个让它显示其它buffer之前
* ctrl-x 3: split-window-horizontally -- 很多人并不常用这个,但有时它非常有用喔。--把当前window切成左右两个等宽window。
* **ctrl-x +: balance-windows ** -- 让所有可见的window近似等高。如果你刚用ctrl-x 2两次那你就有两个1/4高的window和一个1/2高的使用这招可以让这三个window变得等高。
* ctrl-x o: other-window --把光标移动到window列表的下一个window当中去一般会把光标移到window下面一个window或者回滚到最顶的window。
* ctrl-x 1: delete-other-window -- 让当前光标所在的window填满整个frame其它的window都会消失。请注意buffer是由buffer-list的维护的所以无论什么时候运行这个命令都是安全的啦。
**对话框:所有罪恶的根源**
有几个软件设计决择是促使emacs成为一个无比强大的编辑器的主要原因。其中一个就是__emacs没有对话框__当然这也是emacs在一个只能显示文本的终端窗口也能提供完备功能的一个前提条件。但是巧就巧在这正是使emacs暴走般强大的一个关键的特性。
对话框很废对新手经常会有焦点不明的问题很多设计不好的程序还会因为对话框而自锁在刷新线程里面。对话框在你定制的视频模式下面从来就不会表现得很好。比如说吧如果你设置了用双显卡设置了双头显示在windows中的应用程序对话框老是会从错误的一个窗口中弹出来这种事情跟生痔疮似的让人难受无比。
在一个单显示器的机器上对话框有时会在出现在你意料之外的地方。哪怕是像Microsoft Office这样设计精良软件程序模式对话框也会从一堆被隐盖的窗口中的某一个里弹出来这会让整程序看上去完全没有回应在你找到那个无赖对话框并把它置顶之前程序就像死掉一样。
由于一些很奇怪的原因,对话框一般都大小不变的。这与应用程序窗体正好相反:它们几乎都是可改变大小的,也正因为如此,很多用户界面设计师要花好大的功夫来保证各种用户界面元素在窗体改变时能安排恰当的位置和尺寸。但是在默认情况下,大部分的对话框都是尺寸固定的--也许这是因为对话框根本就是窗口管理器设计完成之后再草草加入的补丁功能,而窗口管理器的设计压根儿就没把对话框考虑在内(猜猜俺是怎么知道这个的吧~~)。TMD甚至在Java Swing中对话框也是一团糟。
还有你别跟俺提按钮的事儿一提这个就来气儿。对话框在GUI世界里都有至少25年历史了但是对话框上该有些什么按钮都还没有一个统一的标准--甚至连按钮应该放在哪儿都各有各的说法。有些对话框把按钮放在标题栏里、有些放在底下、有些左边、有些还在右边。当你想用标题栏中的控件来关闭对话框时由于不同的GUI设计很难100%保证它真的会按你想的那样去做。谁都知道这样很违背直觉,但是大伙儿又只能听之任之。
对话框的问题远不止于“输入焦点”、“尺寸变更”、“控件定位”。哪怕你把对话框做得和主程序的UI一模一样对话框也无法具备主UI的功能。比如你定义(或者录制)了键盘输入的宏(不光是emacs有macro--其它程序如Excel或Word都有),那么这些宏在对话框中是无效的。如果对话框有一个可以卷动的控件,那可能你除了用卷动条之外再没其它办法可以卷页了(在emacs里的话哪都能用C-v M-v)。
形象一点来说就是现在你打开IE选择Internet选项进入高级标签页。就在这儿了你所有的全局自定义IE的选项都可怜巴巴地列在这儿。如果你想找到其中一个特定的选项那就得小心翼翼地卷动放大眼睛地看再用鼠标点。休想用编辑/查找’,这当然得是一个模式的,尺寸固定的对话框。基本上,对话框都这样。
**救星Buffer**
在Emacs中所有的输入都写入buffer里而__buffer是Emacs的一等公民__。所有你最喜爱的导航快捷键包括增量搜索在任何buffer中都是可用的。你可以在任意buffer中选择和拷贝文本在Emacs中没有什么模式的buffer所以你可以在保留任何buffer的内容的同时在其它window中工作这些buffers不一定是可见的--这种对话框的内容会一直保留在buffer列表中直到你亲自删除它。
在其它的程序中你很难找到像Emacs的buffer系统这样的体验。一旦你领会到这种模型是多么的强大和一致你使用其它程序时就会觉得有点不爽了--因为老会觉得它们的UI很碍事儿。
**精通buffer和window并且对它们的操控游刃有余的时候你就步上Emacs的大师之路了。**
__条款7丢弃UI__
你不需要菜单栏,菜单栏只不过是给那些找不着北的新手用的拐杖而已。同样,你也不需要有大按钮的工具栏,不需要卷动条--这些东东都是给失败者的,而它们却占用了宝贵的屏幕空间。还是在.emacs中用下面的代码把它们全关了吧。
关掉这些东西,你不会丢失什么功能的,在下一个条款中我将谈到具体的高效作法。
(2006/01/02加入的注解)最近看到一个人回复此君因为条款7而对本文全篇不爽。显然他就是那种非常习惯于使用鼠标啊菜单啊之类东东的人因此觉得被称为“找不着北的新丁”很不爽。此君进一步阐述说有无数的研究表明使用鼠标更加快捷。于是乎我也觉得自己应该把事情说清楚一点好条款接下来的部分是全新的这多亏了这位不忿的读者的Blog。
首先要说的是我也常常希望emacs能有一个更猛一点儿的显示引擎译注这方面Xemacs做得可以可以有像其它桌面应用程序一样的GUI和图像功能。然而未能如愿啊我的博客文章"The Emacs Problem"(译注自己google一下吧)对此有所阐述。当然我也乐于看到emacs没加入这种功能。。诶我说这些是想表明我不是个没头没脑的反GUI份子。
**滚动条:是可有可无的**
由于用键盘就能达到同样效果一般我都把emacs的滚动条关掉。然后滚动条也有个好处**它可以很形象地显示出你在文本中的编辑位置及文本的长度**;在状态区(译注:指mode line的%-指示器不是那么好读取--无数研究都表明,确实如此。比如,这也是为什么美军在他们的反应堆中使用类似的比例量变尺。我们看数字时常出错,而读比例尺时不会~
所以,如果你觉得滚动条让你很爽,那我也没意见。就只是想提醒你,它会促使你去摸鼠标,而某些操作(比如跳转到文本头部)用键盘会更快,对此没必要做什么用户调查的。如果做一些计时试验的话,哪怕一些很耍赖的人,也不得不承认用键盘来导航更快捷。
假定我们打算在一个很长的文本缓冲区的头部和尾**部都插入包含80个连字符-)的一行**,而你现在又在文本缓冲区中间编辑。这个例子有些做作,但我还真是做过一些需要包含全部文本内容的剪辑工作。用键盘的话,我三秒就可以完成,并且完全回到编辑状态。我要按的键盘序列是:"C-x t C-u 8 0 - RET C-x e C-u 8 0 -"
如果你用鼠标没有什么简易的方法能让你在3秒内做到这些事情。你想啊你得往返两次去摸鼠标抓住滚动柄他它拖到第一行这时候光标还不一定在行首他就是说你还得小心地点到那个位置去。
当然如果你勤加练习可能5秒钟就得搞定但何苦呢如果经常要做这个你应该写个宏啊。
**鼠标用例(only 1):区域选择**
有些操作明显用鼠标更快。**在emacs之外与你的窗口系统交互如果另一个程序没有类似emacs的键盘导航功能用鼠标一般会更快捷**。但是在emacs内部时我能想到的鼠标比键盘方便的操作就是区域选择尤其是你打算选一个矩形文本时。
有时区域选择也是用键盘更好。比如设定mark位置然后用ctrl-n来选行用ctrl-f一次多选一个字符。键盘的按键重复率是和硬件设定相关的有时会觉得很慢。我自己的显示设定在一屏中可以包含大约100行。如果从中间移到屏幕底部大约要用5秒。如果用鼠标来回操作需要4秒。所以在可见区域选择时用鼠标也不是很超值。
但是,如果我是想选比一屏还要多的文本,或者选区的开头和结尾都在行内位置时,用鼠标就又可靠双快捷了。我也乐于使用。
使用鼠标跟关掉UI不是一个事儿只不过是相关的事情所以就搁一块说罢了我20年前就做过这样的计时试验了。我衷心地建议你把菜单关掉~
**菜单:丢了它!**
用菜单来探索了解更多的emacs功能是不错的。不幸的是它比较容易产生误导让你认为emacs的功能就那么多了。其实很多emacs扩展并没有什么菜单支持――只有非常细心的扩展模块设计者才会花时间去添加菜单支持。所以如果你想只用菜单来了解emacs你会错过很多很多功能的。
菜单的另一个问题有点儿类似于之前我们提到的对话框它没有很强的伸缩性能。如果你用菜单来给用户提供1500个选项这个菜单的显示搞不好会把窗口整死的便如果用Emacs的buffer来做小case啦还有很诸如漂亮布局和分组显示等额外的好处。你用M-x list-colors-display或者M-x list-faces-display就知道我说的东东了。。
菜单还有一个(大)问题,它没有自动补全~当你查看到一个比较深的子菜单层级中以不小心进错一个子树时很容易觉得自己是迷路了。没有什么探索方法比较可搜索的帮助系统更加灵活了在MS的程序中是这样在emacs中也是。
最后,一旦你记住一个菜单功能了,每次你要使用时,你都得重新点击(搞不好还得进入子菜单)来调用。你调用次数越多,浪费的时间也就越多(相对于使用键盘来说)。
所以我觉得emacs菜单不好不能展现emacs全部的功能不能给出提示帮助你找到你想要的功能选择一多时菜单又撑不住所以相比于树视图之类的组件它不算是一个很通用的UI机制。当你知道怎么用时用起来又很慢。
简单来说呢就是:关掉菜单!就像那些闪亮的按钮一样~诶~~任何重要到要提供一个快捷按钮的操作,都应当有个快捷键。
__条款8掌握最重要的帮助功能__
要找出当前buffer中所以的按键功能输入M-x describe-bindings。它显示一个包含按键及被绑定命令的列表。
你把光标移动到相应的命令上按回车emacs会显示那个命令的帮助。
想知道一个按键操作是干什么的使用M-x describe-key然后按入你感兴趣的按键序列。如果你输的序列是有绑定的emacs会直接转到那个按键的帮助信息中。
如果你对某个功能感兴趣想找出相应的命令并且你已经心里有个大约的命令名那么你可以用M-x apropos然后再输入一个正则表达式参见条款9来搜索命令名。所以的emacs命令也包括函数和属性表都存在一个全局表中以备M-x apropos检索。
比如:你**想找一个功能**可以把一个buffer放到buffer列表的最末端你就可以用M-x apropos-command再输入“buffer”就显示出所有200来个包含有buffer这词的命令。在这个列表里面靠前的有一个命令bury-buffer它的文档写道
bury-buffer M-x bury-buffer RET Command: Put BUFFER at the end of the list of all buffers.译注帮助真的是英文要养成看E文的习惯啊
瞧!这不就是你要找的吗?用好(regexp)正则表达式的话,你很容易就可以限定搜索显示的范围。
要说最最重要的emacs帮助命令当属M-x info这命令会开启emacs内置的交互式菜单驱动的Info引擎。你应该学学怎么用Info。它包含数千页的文档而且是超文本链接的很不巧是web出现之前的emacs自有链接风格所以比man页要易读得多。一旦你掌握了Info系统的导航键用起来铁定比用浏览器看HTML帮助要快即便是看本地文件也是如此。一方面是因为emacs info有跨info文件搜索的功能另一方面就只归功于emacs有相比于浏览器更好的文本导航能力。
__条款9掌握Emacs的正则表达式__
最好的办法就是买本Friedl的书《Mastering Regular Expressions》。绝对值任何一位程序员都该有一本管你用什么语言什么编辑器。
emacs的正则表达式有些大伙儿都不太喜欢的特质但这并不是不可克服的一旦你学到手你的编辑功力会精进的喔~
与正则表达式相关的命令中,最重要的是 isearch-forward-regexp和 isearch-backward-regexp。默认设定下分别绑定于 ESC C-s和 ESC C-r但这么按有点儿僵。**任何要用到Escape键的操作都很僵**而且如果是在我的Compaq电脑上Alt-Ctrl-s这个按法emacs无法截获因为它是弹出系统诊断对话框的热键。
由于使用频繁我把自己的isearch-*-regexp命令绑定到 Alt-r 和 Alt-s上了。alt-s一般没有默认绑定alt-r默认为我不怎么使用的move-to-window-line因为我用条款4的方法在编辑窗口移动。
有些mode坚决要重绑定alt-r和alt0s这很烦人――害我要使用per-mode的招数来重绑定。但我没办法把所以的mode都招呼到。如果有哪个哥们儿知道怎么防止这两个键被任何mode重绑定麻烦你教我一下我会非常感激的。
另外两个也很重要的正则表达式命令是 replace-regexp 和 query-replace-regexp。它俩功能差不多提示你输入一个正则表达式和替换字符串只是 query-replace-regexp 要求你在每一个可能的替换发生时输入y或者n。
我跟 query-replace-regexp 关系很铁,以至于还得给它起个外号(别名~
(defalias 'qrr 'query-replace-regexp)
这样一来,我就用 M-x qrr 就可以使用这个功能了。
其它有用的命令还有 M-x list-matching-lines -- 可以把buffer中匹配某一regexp的行全列出来 M-x apropos -- 就是那个把所以匹配的命令都列出来的帮助命令
emacs正则表达式最常被问到的是“怎么在正则表达式或者替换字符串读取时输入回车呢” 如果仅仅简单地直接打回车那emacs会认为你把regexp输完了。这也是推荐qrr而不是 replace-regexp的原因啊――――在你非常有信心一次试写就可以把正则表达式写对之前至少我还没到那个境界
回答是:要输入一个 ^j (译注也就是Ctrl-j) 字符。在你要输入表达式或者替换串的时候如果你要输回车符选按Ctrl-q然后再按Ctrl-j。Ctrl-q是emacs的"quote"命令它不执行下一个按键而是把它插入到当前buffer或者minibuffer当中。
还有一些其它与regexp相关的知识
* __在elisp代码中你写两次转义"\\"而在minibuffer输入时你只写一次转义就OK了。__
* 由于emacs代码有很多要匹配括号所以emacs反转了括号的语义在emacs的regexp中"(",")"匹配实际的括号,而"\)","\("则用以建立匹配组(字串)。
* 在替换串中,使用\1 \2 ...来插入匹配组中的字符串
* 如果你输入的regexp没有正确工作把结果undo掉重新输一次命令当提示输入表达式时使用上下箭头按键可以找出你之前输入过的记录。这样可以习省时间开销和防止混乱。
__条款10掌握一套细致的文本处理命令__
emacs提供很多小巧实用的命令来对文本进行外科手术作业极大地提升了编辑效率。
如果是初学者不要经不住诱惑把ctrl-k重绑定到一个删除整行的命令上。我知道这是很多其它编辑器的"删行"命令。但相比于kill-line的默认行为这显行很粗造。默认行为删除到行末而不把行末换行符删除会让你有更细致的操控当你在对全盘文本进行外科手术作业时这会提高效率的。相信我所有的emacs用户都用过那些只支持鲁莽"kill-whole-line"的编辑器他们早就用过了但还把kill-line的默认行为设成现今这个样子不是没有原因的。
**键盘宏记录**
我可以毫不夸张地说emacs的宏是全宇宙最酷的东东了。从感觉上讲它们是一种特定用途的细致操作因为你当即把它们做出来然后就当即用来解决手头特定的问题。**只要你觉得自己要进行一组特定的有迹可寻的操作而且不止一次比如10次15次写一个键盘宏这真的非常简单高效。**
先试运行一下宏是有益的。首先把光标移到你第一个要改动的地方按下Ctrl-x ( 启动宏记录。继续你的编辑操作确保你的光标刚好在下一行或者说下几行视情况而定这样就可以按模式运行了。用Ctrl-x )来结束宏录制。再来就是用Ctrl-x e(call-last-kbd-macro)来调用宏了。。
有时,定义一个可靠的宏算得上是一种技艺――你得学会在添加操作之前,使用 beginning-of-line和 end-of-line 这样的**锚点来保证宏操作在一个可确定的位置上。**
递增搜索可以很方便地跳过下一个位置。如果你在记录宏时使用了isearch那么宏调用时isearch也会被执行非常方便。
在记录宏时有时会有些小的失误,这不要紧,直接改正这个失误,继续录宏。在宏调用时,这个失误会反复出现,然后反复被改正,而且很快,你几首注意不到。
用宏的技巧是很死的:确保你的宏完成它的任务并且不要放弃哪怕有时录一个正确的宏比你手工编辑还慢。因为下一次你就会快很多久而久之会成为你的本能反应。键盘宏是emacs最强大的功能之一它让你的生活更美好~~~
最捂一个有关宏的招数:有时候你得调用它们几百次,而且不止在一个文件中,可能在多个文件中。这时你应该把 call-last-kbd-macro 绑定到一个单次按键中比如f5啦。这时你可以翘起二郎腿反复地按那个键再看看编辑器上文本的变化有没什么意外即可。所以把综绑定到一个很远的按键也是可行的:
(global-set-key [f5] 'call-last-kbd-macro)
**调换XXX的功能**
虽然看起来很古怪但一旦你习惯了它们你就会发现调换功能出奇地有用。可能最突出要是__默认绑定到alt-t的transpose-words了:它的作用有两个一个是调换连续的两个词一个是把单词在句子中拖来拖去。__
transpose-words对mdoe特定的语法和词法边界是有感知的比如。把光标放到下面两个词的中间
([this])-is
然后按alt-t结果变为
([is])-this
你可以在连字符html标签和其它标点符号之间调换单词。这是一个急你所需的灵活功能。
当你调换两个词时,比如"dog food",左过的词与右边的词互换了(这里假定你把光标放到两个词中间),变成"food dog"。但是这时的光标是还是在被移到右边来的这个词(food)的右边。所**以如查你不停地按调换键,那个词就不断地在句子中向右边爬行驶**。我不知道有什么内置的方法可以让一个词往左边爬的但是如果要写一个的话也一点也不难。。相应的eclipse插件可能就得要5000行代码分布在60个文件中得花个9天时间来编写和调试了。。。
你还可以调换字符,行,句子,段落。无论你在编写纯文本还是程序时,这些都是很有用的,试验并试着记住它们,目标是形成本能反应~
下次要写的东东…
一开始我有点想写50个条款的就像Scott Meyers的力作《Effective C++》那样写50个条款。但最终我还是放弃了用一次休息时间就写出50个tips的相法并把题目中的50改成了10。我至少花了两个小时坐下来写了这篇文章。要是一个eclipse用户的话很可能会愿意花更多时间在文档中找寻可以帮助写blog的重构工具。
下面列一下接下来想到的,有用的条款吧:
1。 fill-paragraph (alt-p) -- 智能地帮你把文本分行,这是必备良药啊,在注释里面都能用。
2。 gnuserv: 自动用emacs来开启特定文档包括你浏览器的"view source")。
3。 M-x dired: 一个很强的文件/目录管理工具它提供了一些其它工具完全没有的强大功能至少据我所知比如用regexp把某个用户组的文件重命名。
4。 whitespace处理命令C-x C-odelete-blank-lines, delete-trailing-whitespace, tabify 和 untabify 等等。。。。
5。__ nxml-mode__: 唯一让你在处理xml时编辑如飞的方法作者是xml高手James Clark完全把其它基于IDE的XML编辑器比下去了。。
6。 __picture-mode__: 搞ascii艺术时最好用的东东。
7。 minibuffer管理: 掌握递归编辑,在各种情况下怎样中断退出,命令补全及其它各种输入技巧。
8。 不费吹费之力的导航: 绑定一些各个方向移动光标的命令:以字符为单位以词为单词的。使用alt加某个字符的快捷键组合。
9。 区域管理: 选一个不太难看的区域高亮颜色。
10。 矩形区域命令: 这是另一组很神奇的命令(译注:不过很多编辑器现在也都有这功能了)。
11。 emacs shell: 高效使用emacs shell的技巧。
12。 __align-regexp__: 我新收藏的命令,最近才学到的,几乎天天都用到。
13。 frame初始化: 如何在每次打开emacs时自动根据显示器尺寸把emacs窗口设定好。
14。 使用goal column: 每个emacs强人都该知道的。
15。 设定fill column: 最大发挥 fill-paragraph 和 fill-region的功能。
16。 优化操作系统设定: 设定键盘重复率设定好的emacs字体等等。
17。 浏览编辑归档文件: tar,gzip,zip,jar等等。这没什么奇怪的。
18。 高级绑定: 学习绑定的语法home/end等其它不常绑定的按键学习如何特定于buffer来绑定按键。
19。 掌握 kill ring 包括用 Derek upham的新mode来查看它的内容。
20。 掌握 Info: 定制你的Info目录查找和添加新的Info文档高级导航及书签功能。
21。 使用好__ M-x customize__: 学习它的运作,以及怎么避免使用它。
22。 工具程序: M-x calendar, M-x calc, 及其它。
这个列表会一直增长下去……呵呵,在某天我会再把它们写出来吧。
就这么多了,我得睡觉啦~~~。
后面是对这个blog的回复也有一些不错的建议喔~
++
Comments -----------------------------------------------------------------------------------------------------
Some random comments:
To yank at the i-search prompt, use M-y instead of C-y. The emacs info node on Incremental Search talks about the rebinding of C-y, C-w, etc at the i-search prompt.
To repeat execution of the last kbd macro, after hitting C-xe to run it once, keep hitting just the 'e' key for repeated execution.
Zap-to-char (M-z) is incredibly useful if you need to change myDatafileHandler to myStreamHandler and point is at D (the first char to change). Simple M-z e to zap the "Datafile" part and type in the replacement. This is not orthogonal to the backward-kill-word (bound to C-backspace for me since that works in windows browser windows as well as everything else) so there's a feel needed for which is optimal when, which for me mostly depends on where point is already.
Posted by: Ami F. at January 23, 2005 07:12 PM
"Swap Caps-Lock and Control": Or you could just get yourself a keyboard that's already swapped, or that lets you swap them in hardware. The Happy Hacking Keyboard is an example of the former. I like the Avant Stellar keyboard for the latter.
"Binding Alt-r and Alt-s": Try setting up a minor mode with the definitions you want. Then stick that keymap on the *front* of MINOR-MODE-MAP-ALIST.
Other tips:
Use `iswitchb' mode. It's faster for switching between buffers, and it provides more feedback.
Use P4 mode. But be sure to download a more recent version than what we have installed.
Emacs' integration with X11 selections is written to work well with xterm's sucky default policies. That means it works badly with modern apps and badly over slow network connections (say, a VPN from home). I have written a new set of commands to make Emacs talk to the clipboard, and they make life much easier.
Posted by: Derek U. at January 24, 2005 07:37 PM
Doing the swapping of control/cap-lock key can be done in \\HKEY_CURRENT_USER\Keyboard Layout instead of under \\HKEY_LOCAL_MACHINE.
Posted by: Chris W. at January 27, 2005 07:52 AM
I disagree with your agressive rebinding of keys. I used to rebind almost all my emacs keys so they would be more familiar to a windows user (Ctrl+C does copy, Ctrl+V is paste, etc). However, I found myself at a loss when I tried using my neighbor's computer with the default emacs installed.
Always learn default emacs keybindings first, then over-write them as you find appropriate. For example, I rebound Ctrl+J to be the goto-line macro. By default, Ctrl+J enters a newline. F7 is not bound to anything by default, so I made that bound to the compile macro (that keybinding actually comes from Visual Studio). That is about the extent of the keybindings I need/use. And, if I have to use a non-customized emacs, I can still get work done.
Cheers,
-Brian
Posted by: Brian M. at January 27, 2005 10:29 PM
To not pursue aggressive editor and keyboard customizations because other people stick to the standard is a bogus argument, in my opinion. Firstly, how often do you really use a terminal other than your own? And even then, how often do you write just scads of code there? When I do this, it's usually for just a couple of quick edits. So, why optimize for that 1% of time when you're not at your own setup? Secondly, if it does annoy me enough to care, I can always just load my rc file remotely. I use vim and have my .vimrc hardlinked into my /workplace directory so I can just say vim -u /net/ericw/workplace/.vimrc if I really need my magic. I'm certain the same can be done in emacs.
Customization is one of the main selling points of powerful editors, and our wrists are two of our most valuable assets as developers, so I don't understand why people eschew customization just because they fear that small percentage of the time when they won't have it.
Posted by: Eric W. at January 28, 2005 07:34 PM
Brian, I'm afraid I'm with Eric on this one.
I have friends who have nonstandard keyboards, in some cases to avoid repetitive-stress injury. I can't type at their workstations. I have this little secret, though, that works like a charm. I say: "uh, you type."
OK, not much of a secret, but it's gotten me by.
Everyone customizes their environment. Some SDEs use fonts so small I actually can't read them. Some use custom window managers with non-CUA hotkeys and behavior. People use Windows, Linux, MacOS. There are different Unix shells with different default keybindings and aliases. Should we tell everyone they have to use plain-vanilla Windows installations with no customizations?
You're effectively arguing that we should all reduce ourselves to the least common denominator of productivity. This argument has been debunked in other domains (e.g. should we make people with good vision wear blur-inducing glasses, so nobody feels like they're at a natural disadvantage?), and it doesn't hold water in ours either.
You're welcome to use the default bindings yourself, of course. But I wouldn't get on a bandwagon that tries to discourage people from getting better at their jobs. It's a slippery slope that I think you want to avoid.
Anyway, we now issue laptops with wireless iVPNs, so you can even bring your environment with you. It's just not an issue anymore.
Posted by: Steve Yegge at January 28, 2005 09:30 PM
I just want to know the tips you allude to in number (8) of your "Tune in next time..." section. How do you do the up/down/left/right browsing? I've been trying to train myself to use C-n, C-p, C-f, C-b and friends, but its awkward, and it isn't getting easier. Also, can I plllleeeeasssseee see your .emacs file :)
Posted by: Charles G. at February 18, 2005 01:47 AM
On March 4 2006, Luke Gorrie wrote:
Howdy,
I know it's bad form to comment on a blog entry without having read it thoroughly but I will take a chance because your eternal salavation is at stake.
I use C-h for backspace in Emacs and move `help-command' elsewhere:
(global-set-key "\C-h" 'backward-delete-char-untabify)
(define-key isearch-mode-map "\C-h" 'isearch-delete-char)
(global-set-key [(hyper h)] 'help-command)
and this also works in the shell along with C-m, C-j, C-i, etc.
Offered for your consideration. :-)
On March 5 2006, Anupam Kapoor wrote:
hi,
regarding tip #7, imho, its better to just disable it via Xresources,
rather than loading it all up and making it invisible (as you have
shown) via:
,----
| ! better to turn this off here than in .emacs
| ! where it has already been loaded.
| emacs.menuBar: off
| emacs.toolBar: off
|
| ! no scrollbars fur me
| emacs.verticalScrollBars: off
`----
kind regards
anupam
On March 9 2006, Scott Anderson wrote:
Steve,
Great article.
Reading section 7, I became amused by the person who claimed that
"countless studies" (or whatever) had proven that the mouse was
faster.
I'm guessing he never studied GOMS, which is a method of decomposing
UIs into their basic operations and then performing objective
complexity and time analysis.
A quick typist can hit about 10 keys per second, or .1s per key. To
use a mouse there are four movements involved: move from the keyboard
to the mouse, move the cursor to a location, perform some operation at
the location, then move the hand back to the keyboard.
Moving the hand takes about .4s. Moving the mouse cursor on the screen
takes .5s. So without even doing anything, you've used 1.3 seconds. A
mouse click takes .1 seconds, and if you're dragging something, you
measure the click down, the drag, and the release, adding up to
another .7 seconds.
So let's say I want to highlight a line for copy:
mouse:
.4 move to mouse
.5 move cursor to first character
.1 depress button
.5 drag to highlight (and this is optimistic, depending on how good
you are with finicky targets like highlighting)
.1 release button
.4 move to keyboard
.2 copy (alt-w, ctrl-c, whatever. count control keys as a separate keypress)
2.2 seconds to perform.
kb scenario 1: best case: already at beginning of line
.2 mark (ctrl-space)
.2 end-of-line (ctrl-e)
.2 copy
.6 seconds to perform, or nearly 4 times as fast.
kb scenario 2: worst case: requires navigation: 30 lines down, line
starts with "Reading"
.9s move to start of line (ctrl-r readi ctrl-r)
.2 mark (ctrl-space)
.2 end-of-line (ctrl-e)
.2 copy
1.5s, still faster
As it turns out, the only thing a mouse is really good for is
something involving a gross motor movement, like moving a window or
the like. Unless you're a crappy typist.
Anyway, good article, and I'm looking forward to reading the rest of
them.
Regards,
-scott
Back to Stevey's Drunken Blog Rants image of my email address, steve dot yegge at ye olde gmail

245
Zim/Utils/emacs/el-get.txt Normal file
View File

@@ -0,0 +1,245 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T13:45:24+08:00
====== el-get ======
Created Saturday 07 January 2012
https://github.com/dimitri/el-get
Short Story: el-get allows you to install and manage elisp code for Emacs. It supports lots of** differents types of sources** and is able to **install them, update them and remove them**, but more importantly it will __init __them for you.
That means it will __require__ the **features** you need,__ load__ the necessary files, set the__ Info__ paths so that C-h i shows the new documentation you now depend on, and finally __call__ your own** :post-init** function for you to setup the extension. Or call it a package.
===== Status and Version Numbers =====
Current el-get status is stable, ready for daily use and packed with extra features that make life easier. There are some more things we could do, as always, but they will be about smoothing things further.
==== • Latest released version ====
el-get version 3.1 is available, with a boatload of features, including **autoloads **support, **byte-compiling** in an external "clean room" Emacs instance,__ custom__ support,__ lazy initialisation__ support (defering all init functions to //eval-after-load//), and multi repositories ELPA support.
==== • Version numbering ====
Version String are now inspired by how Emacs itself numbers its versions. First is the **major **version number, then a dot, then the **minor** version number. The minor version number is 0 when still developping the next major version. So 3.0 is a developer release while 3.1 will be the next stable release.
Please note that this versioning policy has been picked while backing 1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
===== How to Install it? =====
Heres the **lazy installer先安装el-get文件然后将相关代码添加到启动文件中当emacs下次启动时会自动下载安装相应的软件包**:
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
You have to type__ C-j __with the cursor at the end of the last line, but** still on** the line. C-j runs the command// eval-print-last-sexp//, so it will evaluate the code youre looking at, and that will git clone el-get at the right place.
上面的代码只是**下载**el-get安装文件到本地目录并没有启动和配置它。所以需要把下面的**启动代码**添加到emacs的启动文件中。
Note that you can add this elisp code into your **emacs init file** directly, as the installer code will detect if el-get is already installed. Notice that doing so directly will require internet access to start emacs. You can avoid this with the following snippet instead:
把下面的代码添加到emacs的启动文件中.emacs
(add-to-list 'load-path "~/.emacs.d/el-get/el-get") ;;注意,加载的目录路径。
;;;如果已经下载到本地了则不需要重新下载。
(unless (require 'el-get nil t)
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp))))
See next section for details about how to setup you emacs so that its able to benefit from el-get automatically.
===== How to install the developer version (master branch)? =====
The lazy installer uses the default el-get-install.el file which targets the **2.stable branch**. To install el-get directly on the **master branch**, summon the el-get-master-branch variable into existence:
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working developper edition of el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(let (el-get-master-branch)
(end-of-buffer)
(eval-print-last-sexp))))
===== Basic usage =====
Now that el-get is installed, simply use__ M-x el-get-install__ and pick whatever package you need. Arrange to have el-get part of your setup, so that at** next emacs startup the installed packages are initialized**. Heres how to:
可以直接使用el-get-install安装自带的sources中的扩展也可以在.emacs等配置文件中添加**扩展列表**这样emacs下次启动时就会安装和初始化这些扩展。
注意__只有__添加在配置文件中的扩展el-get才会在启动时自动加载并初始化它们。因此通过el-get-install方式安装的扩展需要在下面的配置文件中el-get-sources中添加相应的package name。
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless (require 'el-get nil t)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.github.com/dimitri/el-get/master/el-get-install.el")
(end-of-buffer)
(eval-print-last-sexp)))
**(el-get 'sync)**
Thats the basic setup.
===== Advanced setup with local recipes =====
Of course, my emacs setup is managed in a private git repository. Some people on //#emacs// are using //git submodules //(or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy canonical list of packages I depend on to run emacs, and I want this documentation to be usable as-is. Enters el-get!
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(require 'el-get)
;; local sources ;;非el-get自带的sources如果name和自带的相同则这里的设置会**覆盖**自带里的设置。
(setq __el-get-sources__
'((:name magit
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
(:name asciidoc
:type elpa
:after (lambda ()
(autoload 'doc-mode "doc-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
(add-hook 'doc-mode-hook '(lambda ()
(turn-on-auto-fill)
(require 'asciidoc)))))
(:name lisppaste :type elpa)
(:name emacs-goodies-el :type apt-get)))
(setq my-packages
(append
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet) ;;这个列表里的扩展来自**自带**的sources
(mapcar 'el-get-source-name el-get-sources)))
(el-get 'sync my-packages) #注意, el-get的配置一般以该命令结束。
So now you have a pretty good documentation of the packages you want installed, **where** to get them, and **how** to install them. For the advanced methods (such as **elpa** or **apt-get**), you basically just need the **package name.因为el-get会自动调用系统的包管理系统来安装它们。** When relying on a bare git repository, you need to give some more information, such as the** URL** to clone and the** build** steps if any. Then also what **features **to require and maybe where to find the **texinfo** documentation of the package, for automatic inclusion into your local Info menu.
The good news is that not only you now have a solid readable description of all that **in a central place**, but this very description is all (el-get) needs to do its magic. This command will __check__ that each and every package is installed on your system (in __el-get-dir__) and if thats not the case, it will **actually install it**. Then, it will__ init__ the packages: that means caring about the __load-path__, the__ Info__-directory-list (and dir texinfo menu building) the__ loading__ of the emacs-lisp files, and finally it will __require__ the features.
emacs每次启动时el-get都会检查el-get命令的参数列表中的各扩展是否安装到系统的el-get-dir变量指定的目录中如果没有则自动下载并安装它们。然后初始化相关的软件包如添加load-path变量load相关文件require相关文件等这些初始化配置信息可以在:after、:featers、:info、:load-path等属性中指定
===== How to use it? =====
You see that el-get-sources example up there? It **finishes with a single (el-get) call**. Thats it. It will__ install__ new sources **on the list** and only__ init __already installed ones.
如果已经安装如直接通过el-get-install命令的package但没有添加到该list中则el-get不会初始化它们。
The status of each package is tracked into __~/.emacs.d/el-get/.status.el__ (by default__由el-get-dir变量指定安装包的位置默认为~/.emacs.d/el-get__) and can get the values required, installed or removed.
===== Sync or async? =====
Most often you want **el-get-install** and **el-get-build **to stay out of the way and be //asynchronous//, so that you can continue using Emacs while your new package is getting ready. But imagine youre starting up Emacs after a **git pull** on the other computer (after a commute, say), and theres some newer packages for this instance to consider installing.
Now you want a synchronous install, right?
So, by default (el-get) is __asynchronous__, but you can ask for it to be sync, or to still be asynchronous but to wait until it finished before to give control back:
(el-get 'sync) #异步更新
(el-get 'wait) #接着添加这条命令后,变为同步更新。
You even get a progress report!
===== Sources =====
See the documentation of the __el-get-sources__ variable for details. Please note that el-get-sources is another source location for recipes, adding to your **el-get-recipe-path**.
注意可以el-get-recipe-path变量来指定__sources目录这样el-get会自动到相关目录搜索要安装的package的配置文件__。
Note that you can also give a mix of **packages symbols**,** inline recipes **and **source lists** to __el-get__ as arguments, and completely** bypass **the el-get-sources variable.
(el-get 'sync) ;**;不指定参数时默认使用el-get-sources类表中的packages**
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
It is still __recommended__ to (setq el-get-sources '(list of packages)) then use (el-get 'sync), so that commands such as **el-get-update** know which packages to update.
但是最好还是使用el-get-sources参数来指定安装的package(不管是来之本地的sources还是自带的sources)这样其它的__默认使用该变量__的命令才可以正常工作。
===== Recipes =====
Some sources are contributed to el-get **directly**, so that you only have to put in the el-get-sources the__ name of the package__ you want to install.
Should you need some **local specific setup(本地化配置,但还是使用自带的文件下载安装扩展)**, you can do that by providing __a partial sources__ missing the** :type **property: your local properties will get __merged into__ the recipes one.(在el-get初始化代码中指定。)
Also, the variable __el-get-recipe-path__ allows you to maintain** local recipes **in case you either dislike the default one or are crafting some new one not commited to the main repository yet. But please do consider sending them over!
如果想在一个单独的文件里本地化配置自带的软件包,要注意文件中不要有:type属性同时该文件要在自带的文件__前__加载。因此该文件所在的目录要在el-get的recipes__前被搜索到__。
We do not intend to provide recipes for advanced types such as apt-get and elpa because theres so little to win here, and maintaining a package list would take too much time.
===== Package setup =====
The package setup can either go into the __:after function__, or in a file named __init-package.el__ in __el-get-user-package-directory__. Any such named file will get automatically loaded by el-get at init time, if it exists.
===== Build Commands =====
__Avoid using make install__, which will usually move files into a "system location." In our case, you probably just want your package //foo// to be all installed into //~/.emacs.d/el-get/foo(实际安装位置的顶级目录由//__el-get-dir变量指定__//)//, right? So, no make install.
===== Byte Compiling =====
el-get will byte compile the elisp for the package when its **source definition** includes a__ :compile__ property set to the** list** of files to byte compile (or to a single file), or __all__ the .el files found in the package when theres** no :build** command.
===== Hooks =====
el-get offers a variety of specific hooks (read the source), and two general purposes hooks facilities: **el-get-post-install-hooks **and **el-get-post-update-hooks**, called with the package name as argument.
===== Some more commands? =====
Yes, ok.
* M-x el-get-list-packages
Opens a buffer listing **all known packages** (those for which you have a recipe). The listing includes the package name, its status (one of "available", "installed", "removed" or "required") and the package description. The description is a free form text and has not been provided for all recipes. Please also note that el-get-emacswiki-refresh will create recipes omitting the description as of now.
* M-x el-get-describe
Prompt for a package name, **with completion**, then open an Help window with details about the selected package. Those include current status, website, description,__ installation method__, full recipe, and buttons to easily install, update or remove the package.
显示一个package的详细安装、移除、**配置信息**。
* M-x el-get-install
Will prompt for a package name, with completion, then install it. It will only propose packages that are not already installed. Any package that you have a recipe for is a candidate.
Please note that when installing a package that is__ not in your el-get-sources or your el-get call means that it will not be initialized__ for you automatically at **emacs startup**. You get a WARNING message when thats the case.
所以使用el-get-install命令安装的package可能不会被自动配置。需要手动地将它们添加到el-get-sources中。
* M-x el-get-cd
Will prompt for an installed package name, with completion, then open its directory with dired.
* M-x el-get-update
Will prompt for an __installed__ package name, with completion, then update it. This will run the build commands and** init **the package again.
* M-x el-get-self-update
Update only one package, el-get itself.
* M-x el-get-update-all
Will update all packages **used in el-get-sources**. Beware that using this function can lead to hours of settings review: more often than not updating a package requires some adjustments to your setup. Updating all of them at once will require reviewing almost all your setup.
* M-x el-get-reload
Reload the given package files. Happens automatically at update time too.
* M-x el-get-remove
Will prompt for an installed package name, with completion, then remove it. Depending on the type of the package, this often means simply **deleting the directory** where the source package lies. Sometime we have to use external tools instead (apt-get, e.g.). No effort is made to unload the features.
* M-x el-get-find-recipe-file
Will prompt for the name of a package, with completion, then find-file its recipe file.
* M-x el-get-make-recipes
Will prompt for an existing directory where to __output all your new recipe files__: one file for each entry in el-get-sources that is not just a symbol and that is not found anywhere in **el-get-recipe-path**.
* M-x el-get-checksum
Will prompt for the name of an installed package, with complement, then compute its checksum if the **package type supports** that feature. The checksum is __added to the kill-ring__ so that youre ready to yank it into your el-get-sources :checksum property if you want to.
* M-x el-get-emacswiki-refresh
Will launch a subprocess that connects to EmacsWiki and fetch from there the list of elisp scripts hosted. Then produce a recipe file per script, and store that in the given directory, which default to ~/.emacs.d/el-get/el-get/recipes/emacswiki/ if you didnt change **el-get-dir**.
===== Useful functions =====
* el-get-package-types-alist (statuses &rest types)
Return an alist of package names that are of __given types.__ Only consider packages whose status is **member** of STATUSES, which defaults to installed, required and removed.
ELISP> (el-get-package-types-alist** "installed" 'cvs 'emacswiki**)
((emacs-w3m . cvs)
(rect-mark . emacswiki)
(icomplete+ . emacswiki)
(php-mode-improved . emacswiki)
(rainbow-delimiters . emacswiki)
(goto-last-change . emacswiki)
(emacs-goodies-el . cvs))
* el-get-extra-packages (&rest packages)
Return installed or required packages that **are not **in given package list.
ELISP> (el-get-extra-packages dim-packages)
((verbiste "installed")
(package "installed"))
===== Extending it =====
Please see the documentation for the **el-get-methods** and provide a patch!
Adding __bzr__ support for example was only about writing 2 functions, mostly using copy paste. Heres the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
===== Upgrade Notes =====
Upgrading to 3.1
A change has been included so that el-get-sources is now only another source for recipes, and (el-get '…) will now only install and initialize known "required" and "installed" packages.
The documentation has been updated to detail the new setup.
If you have packages that have been installed in the past but you no longer want in your setup, heres how to get them out of the way:
M-: (el-get-save-package-status "package-name-here" "removed")
Please review documentation section Advanced setup with local recipes.

View File

@@ -0,0 +1,86 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T15:21:50+08:00
====== Auto-installing packages in Emacs with ELPA and el-get ======
Created Saturday 07 January 2012
http://www.facebook.com/notes/xmms2/auto-installing-packages-in-emacs-with-elpa-and-el-get/10150401940759307
由 XMMS2 于 2011年8月12日16:05 发布
Those who live in emacs all know the pain of __manually installing__ extra modes and extensions, especially on different hosts. **System packages** sometimes help, but they differ on every OS (Debian packages, MacPorts, etc.), dont always exist, and need to be installed manually.
A better alternative is to__ use emacs itself__ to manage, install and update all the required extra code. The __ELPA project__ provides a way to install packages from different repositories, while __el-get__ can help you declare recipes to install and update code from ELPA, or even Github or Emacswiki.
First, lets setup some code that tries to load ELPA and el-get, and installs them if they are not present.
; derived from ELPA installation
; http://tromey.com/elpa/install.html
(defun eval-url (url)
(let ((buffer (url-retrieve-synchronously url)))
(save-excursion
(set-buffer buffer)
(goto-char (point-min))
(re-search-forward "^$" nil 'move)
(eval-region (point) (point-max))
(kill-buffer (current-buffer)))))
;; Load ELPA
(add-to-list 'load-path "~/.emacs.d/elpa")
(defun install-elpa ()
(__eval-url __"http://tromey.com/elpa/package-install.el"))
(if (__require 'package nil t)__
(progn
;; Emacs 24+ includes ELPA, but requires some extra setup
;; to use the (better) tromey repo
(if (>= emacs-major-version 24)
(setq package-archives
(cons '("tromey" . "http://tromey.com/elpa/")
package-archives)))
(package-initialize))
(install-elpa))
;; Load el-get
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(defun install-el-get ()
(eval-url
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"))
(unless (__require 'el-get nil t__)
(install-el-get))
Note that when using** emacs 24, package.el is distributed with emacs** but it points to the GNU package repository; the code above adds tromeys more complete ELPA repository to the sources.
Unfortunately, the ELPA installer script **appends a snippet of code to the end of the ~/.emacs** file to **auto-load package.el on startup**. To avoid any problem, it is best to __manually remove__ that code any only keep the load-or-install code above.
Now that ELPA and el-get are setup, we can **declare all the packages we want installed**. They will be installed after the first time emacs is started, and simply **loaded and initialized** in the future.
; extra recipes for packages __unknown to el-get__ (yet)
(setq el-get-sources
'((:name css-mode :type __elpa__)
(:name js2-mode-mooz
:type git
:url "git://github.com/mooz/js2-mode.git"
:load "js2-mode.el"
:compile ("js2-mode.el")
:features js2-mode)))
; list all packages you want installed
(setq my-el-get-packages
(append
'(css-mode egg gist js2-mode-mooz)
(mapcar 'el-get-source-name el-get-sources)))
(el-get 'sync** my-el-get-packages**)
The el-get 'sync call does all the magic, based on all the packages **past in argument** (as my-el-get-packages). Any packages for which el-get __has a recipe__ can be installed.
The el-get-sources variable allows to __declare extra custom recipes__ for code to install. In the example above, css-mode is simply pulled from the ELPA repository, while js2-mode-mooz is fetched directly from Github.
Replicating this code in all your ~/.emacs files is a very easy and convenient way to bootstrap the same emacs environment on multiple hosts.

View File

@@ -0,0 +1,113 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T15:45:05+08:00
====== GNU Emacs的终极扩展管理工具 — el-get ======
Created Saturday 07 January 2012
http://emacser.com/el-get.htm
作者: Nick Qi
Lets el-get together
通常我们在配置GNU Emacs的时候都会安装一些第三方的lisp扩展来让GNU Emacs用起来更顺手但是这些第三方lisp扩展的安装、升级和配置的方法各异通常我们需要使用多种完全不同管理方式的lisp扩展http直接下载__发行版包管理器__下载__版本控制器__下载等。这样我们升级或者迁移的时候就可能会遇到各种麻烦。
GNU Emacs一直以来都缺少一个统一的第三方lisp扩展管理器GNU XEmacs与GNU Emacs的一个区别就是它有一个统一的第三方包管理工具。这其中的原因主要是因为GNU Emacs是GNU Project的一个重要代表它要求随它发行的所有lisp都__要作者签名用GPL授权给FSF__但是并不是所有的作者都支持GPL而且这个过程给第三方贡献增加了不少阻碍。所以当时就有一批开发者开发了GNU XEmacs。所以GNU Emacs一直到现在也没有引入官方的扩展管理工具指的是当前的稳定版本ELPA已经被合并到当前的开发分支了
===== 当前第三方包管理方法 =====
* emacswiki有auto-install.el之类的管理工具
* linux发行版的包管理如debian的lisp包
* tromey写的package.el
* 手工使用git之类的版本控制工具来管理lisp扩展
* 直接下载
当前这些方法的不足之处
* elpa可以管理当前大多数第三方扩展但是仍然有很多不在里面
* 手工管理,升级太麻烦,迁移也不方便
* linux发行版的包管理通常你用不了最新的扩展而且迁移也挺麻烦
* 开发分支的ELPA不要认为GNU Emacs会放弃原来的授权方式要进入官方ELPA估计和现在没有什么区别仍然有很多作者不会把自己的代码交给FSF。不过也会有第三方ELPA。
===== el-get华丽登场 =====
=== el-get简介 ===
* el-get能够透明的管理各种来源的第三方扩展不管你是通过linux发行版获取还是直接下载还是通过git等版本控制器获取的
* el-get能够安装升级和移除它管理的第三方扩展
* el-get支持安装后的__初始化__操作支持hook操作
* el-get支持扩展包man和info的安装安装好后你可以直接C-h i查看info
* el-get的__源描述文件__recipe超级简单可以轻松添加自己的扩展源
* el-get支持异步和同步安装和初始化
* el-get__支持ELPA__中的所有package安装ELPA是它的一种安装方法。。。
===== 安装el-get =====
el-get的作者参考和ELPA的package.el的做法使得el-get的安装非常简单:
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working el-get.
(url-retrieve
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
复制上面的代码到scratch中移动光标到最后一行结尾按下C-j然后就可坐等安装完成了。
===== 使用el-get =====
el-get的作者是debian developer所以el-get有深深的apt-get烙印。其实我还觉得el-get很有gentoo portage的影子直接描述扩展包地址然后直接下载安装。
==== 安装扩展 ====
接下来就是最激动人心的时刻了让我们先用magit、package和auto-complete来演示el-get的几个功能。
对于el-get本身你需要给它手动指定load-path因为启动的时候需要__先载入它的功能__然后才能通过它来安装和管理其他lisp扩展。
当然在你刚安装玩el-get还没有重启GNU Emacs之前你是可以直接使用它的功能的。
(setq el-get-sources
'(el-get
package
auto-complete
(:name magit
__:after__ (lambda () (global-set-key (kbd "C-x C-z") 'magit-status))))
)
(el-get 'sync)
复制上面的代码到scratchbuffer光标移动到buffer最后键入C-j执行lisp代码。这样el-get、package、auto-complete和magit就被安装到~/.emacs.d/el-get目录下了。而且magit包在安装好后__还执行了__一个按键绑定操作同样你也可以在任何需要配置的扩展后面__使用定制函数__。
===== 初始化扩展 =====
el-get还可以帮助你方便的初始化GNU Emacs扩展在每个source描诉的__:after__后面可以放上自己的**初始化函数**就像上面的magit那样。
通常(el-get)是异步执行的,所以如果你的扩展之间有依赖关系,它的初始化过程可能就会失败,所以为了方便大家写扩展包的初始化函数,作者给(el-get)增加了两种同步
方式:
* (el-get sync) 完全同步初始化的顺序严格按照el-get-sources中的顺序完成
* (el-get wait) 初始化过程异步可以多个source同时初始化但会等待整个初始化完成
===== 交互式命令接口 =====
* el-get-cd 用dired切换到指定package的文件夹
* el-get-install 根据用户设定的el-get-sources变量中的package来指定安装其中一个
* el-get-update 升级指定的package
* el-get-update-all 升级el-get-sources中的所有package慎用
* el-get-remove 删除已经安装而且在el-get-sources中的某个package
* 加上C-u前缀的时候el-get-install和el-get-remove是可以操作仓库中的所有package
===== 定制和贡献 =====
* el-get支持本地扩展包仓库参考el-get-recipe-path变量
* 参考package描述文件的文档对仓库中的package进行定制可以改变来源、构建命令、 初始化函数。。。
* 参考el-get-methods的文档给el-get增加更多的安装来源支持
* 贡献package描述文件package recipe添加你喜欢的package
* 使用并报告bug或者要求增加新的特性
* 让更多的人用上el-get
===== 资源和链接 =====
* el-get github地址: https://github.com/dimitri/el-get
* el-get 作者blog: http://tapoueh.org/news.dim.html
* 我的el-get分支: https://github.com/vmlinz/el-get

View File

@@ -0,0 +1,44 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T15:41:21+08:00
====== blog ======
Created Saturday 07 January 2012
http://tapoueh.org/emacs/el-get.html
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want __an easy canonical list of packages I depend on to run emacs__, and I want this documentation to be usable as-is. Enters el-get!
(setq el-get-sources
'((:name bbdb
:type git
:url "git://github.com/barak/BBDB.git"
:load-path ("./lisp" "./bits")
:info "texinfo"
:build ("./configure" "make"))
(:name magit
:type git
:url "http://github.com/philjackson/magit.git"
:info "."
:build ("./autogen.sh" "./configure" "make"))
(:name vkill
:type http
:url "http://www.splode.com/~friedman/software/emacs-lisp/src/vkill.el"
:features vkill)
(:name yasnippet
:type git-svn
:url "http://yasnippet.googlecode.com/svn/trunk/"))
(setq my-packages
(append
'(el-get escreen switch-window mailq cssh auto-complete)
(mapcar 'el-get-source-name el-get-sources)))
(el-get 'sync my-packages)
So now you have a pretty good documentation of the packages__ you want installed__, where to get them, and how to install them. For the advanced methods (such as elpa or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.
The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in__ el-get-dir__) and if that's not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building) the loading of the emacs-lisp files, and finally it will require the features.

View File

@@ -0,0 +1,396 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T15:54:55+08:00
====== doc ======
Created Saturday 07 January 2012
摘自源代码目录中的README文档
= el-get
Short Story: el-get allows you to install and manage +elisp+ code for
Emacs. It supports lots of __differents types of sources __and is able to
'install' them, 'update' them and 'remove' them, but more importantly it
will __'init'__ them for you.
That means it will** +require+** the 'features' you need,** +load+** the
necessary files, set the 'Info' paths so that **+C-h i+** shows the new
documentation you now depend on, and finally call your own
**+:post-init+ **function for you to setup the extension. Or call it a
package.
== Status and Version Numbers
Current** +el-get+** status is stable, ready for daily use and packed with extra
features that make life easier. There are some more things we could do, as
always, but they will be about smoothing things further.
=== Latest released version
+el-get+ version 2.1 is available, with a boatload of features, including
autoloads support, byte-compiling in an external "clean room" Emacs
instance, custom support, **lazy initialisation support** (defering all init
functions to __+eval-after-load+__), and multi repositories +ELPA+ support.
=== Version numbering
Version String are now inspired by how Emacs itself numbers its versions.
First is the major version number, then a dot, then the minor version
number. The minor version number is 0 when still developping the next major
version. So 3.0 is a developer release while 3.1 will be the next stable
release.
Please note that this versioning policy has been picked while backing
1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
== How to Install it?
Here's the 'lazy installer':
--------------------------------------
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
--------------------------------------
You have to type +C-j+ with** the cursor at the end of the last line, but**
**still on the line**. 'C-j runs the command eval-print-last-sexp', so it will
evaluate the code you're looking at, and that will +git clone el-get+ at the
'right place'.
Note that you can add this elisp code into your __emacs init file__ directly, as
the installer code will detect if +el-get+ is already installed. Notice
that doing so directly will require internet access to start emacs. You can
avoid this with the following snippet instead:
--------------------------------------
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless __(require 'el-get nil t)__
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp))))
--------------------------------------
See next section for details about how to** setup you emacs** so that it's able
to benefit from +el-get+ automatically.
== How to install the developer version (master branch)?
The 'lazy installer' uses the default +el-get-install.el+ file which targets
the +2.stable+ branch. To install el-get directly on the +master+ branch,
summon the +el-get-master-branch+ variable into existence:
--------------------------------------
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working developper edition of el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(let (el-get-master-branch)
(end-of-buffer)
(eval-print-last-sexp))))
--------------------------------------
== Basic usage
Now that +el-get+ is installed, simply use **+M-x el-get-install+** and pick
whatever package you need. __ Arrange to__ have +el-get+ part of your setup, so
that at next emacs startup the installed packages are **initialized**. Here's
how to:
通过el-get-install命令安装的package需要在el-get的配置文件中添加一些设置这样
emacs下次启动时el-get才会__自动地配置__它们。
--------------------------------------
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless (require 'el-get nil t)
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp))))
(el-get 'sync)
--------------------------------------
That's the basic setup.
== Advanced setup with local recipes
Of course, my emacs setup is managed in a private git repository. Some
people on +#emacs+ are using +git submodules+ (or was it straight import)
for managing external repositories in there, but all I can say is that I
frown on this idea. I want an easy canonical list of packages I depend on to
run emacs, and I want this documentation to be usable as-is. Enters el-get!
--------------------------------------
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(require 'el-get)
;; local sources
(setq __el-get-sources__
'((:name magit
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
(:name asciidoc
:type elpa
:after (lambda ()
(autoload 'doc-mode "doc-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
(add-hook 'doc-mode-hook '(lambda ()
(turn-on-auto-fill)
(require 'asciidoc)))))
(:name lisppaste :type elpa)
(:name dictionary-el :type apt-get)
(:name emacs-goodies-el :type apt-get)))
(setq __my-packages__
(append
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet)
(mapcar 'el-get-source-name el-get-sources)))
__(el-get 'sync my-packages)__
--------------------------------------
So now you have a pretty good documentation of the packages you want
installed, where to get them, and how to install them. For the advanced
methods (such as elpa or apt-get), you basically just need the package
name. When relying on a bare git repository, you need to give some more
information, such as the URL to clone and the build steps if any. Then also
what features to require and maybe where to find the texinfo documentation
of the package, for automatic inclusion into your local Info menu.
The good news is that not only you now have a solid readable description of
all that in a central place, but this very description is all (el-get) needs
to do its magic. This command will check that each and every package is
installed on your system (in __el-get-dir__) and if that's not the case, it will
actually install it. Then, it will__ init the packages__: that means caring
about the load-path, the Info-directory-list (and dir texinfo menu building)
the loading of the emacs-lisp files, and finally it will require the
features.
== How to use it?
You see that +el-get-sources+ example up there? It __finishes with a single__
__+(el-get)+ call__. That's it. It will 'install' new +sources+ on the list and
only 'init' already installed ones.
The status of each package is tracked into +~/.emacs.d/el-get/__.status.el__+
(by default) and can get the values +required+, +installed+ or +removed+.
=== Sync or async?
Most often you want +el-get-install+ and +el-get-build+ to stay out of the
way and be 'asynchronous', so that you can continue using Emacs while your
new package is getting ready. But imagine you're starting up Emacs after a
+git pull+ on the other computer (after a commute, say), and there's some
newer packages for this instance to consider installing.
Now you want a synchronous install, right?
So, by default +(el-get)+ is asynchronous, but you can ask for it to be
sync, or to still be asynchronous but to wait until it finished before to
give control back:
(el-get 'sync)
(el-get 'wait)
You even get a progress report!
=== Sources
See the documentation of the +el-get-sources+ variable for details. __Please__
__note that +el-get-sources+ is another source location for recipes, adding to__
__your +el-get-recipe-path+.__
Note that you can also give a mix of +packages+ symbols, +inline recipes+
and +source lists+ to +el-get+ as arguments, and completely __bypass__ the
+el-get-sources+ variable.
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
It is still __recommended__ to +(setq el-get-sources '(list of packages))+ then
use +(el-get 'sync)+, so that commands such as +el-get-update+ know which
packages to update.
=== Recipes
Some sources are contributed to +el-get+ directly, so that you only have to
put in the +el-get-sources+ the name of the package you want to
install.
Should you need some __local specific setup__, you can do that by providing a
partial sources **missing the +:type+ property**: your local properties will get
merged into the recipes one.
Also, the variable __+el-get-recipe-path+__ allows you to maintain local recipes
in case you either dislike the default one or are crafting some new one not
commited to the main repository yet. But please do consider sending them
over!
We do not intend to provide recipes for advanced types such as +apt-get+ and
+elpa+ because there's so little to win here, and maintaining a package list
would take too much time.
=== Package setup
The package setup can either go into the __+:after+__ function, or in a file
named __+init-package.el+ in +el-get-user-package-directory+__. Any such named
file will get automatically loaded by +el-get+ at +init+ time, if it exists.
=== Build Commands
__Avoid using +make install+__, which will usually move files into a
"system location." In our case, you probably just want your package
+foo+ to be all installed into +~/.emacs.d/el-get/foo+, right? So, no
+make install+.
=== Byte Compiling
+el-get+ will 'byte compile' the elisp for the package when its source
definition includes a +:compile+ property set to the list of files to byte
compile (or to a single file), or all the +.el+ files found in the package
when there's no +:build+ command.
=== Hooks
+el-get+ offers a variety of specific hooks (read the source), and two
general purposes hooks facilities: +el-get-post-install-hooks+ and
+el-get-post-update-hooks+, called with the package name as argument.
=== Some more commands?
Yes, ok.
M-x el-get-list-packages::
Opens a buffer listing all known packages (those for which you have a
recipe). The listing includes the package name, its status (one of
"available", "installed", "removed" or "required") and the package
description. The description is a free form text and has not been
provided for all recipes. Please also note that
+el-get-emacswiki-refresh+ will create recipes omitting the description
as of now.
M-x el-get-describe::
Prompt for a package name, with completion, then open an +*Help*+ window
with details about the selected package. Those include current status,
website, description, installation method, full recipe, and buttons to
easily install, update or remove the package.
M-x el-get-install::
+
Will prompt for a package name, with completion, then install it. It will
only propose packages that are not already +installed+. Any package that
you have a recipe for is a candidate.
+
Please note that when installing a package that is not in your
+el-get-sources+ or your +el-get+ call means that it will not be initialized
for you automatically at emacs startup. You get a +WARNING+ message when
that's the case.
M-x el-get-cd::
Will prompt for an +installed+ package name, with completion, then open
its directory with dired.
M-x el-get-update::
Will prompt for an installed package name, with completion, then update
it. This will run the +build+ commands and +init+ the package again.
M-x el-get-self-update::
Update only one package, +el-get+ itself.
M-x el-get-update-all::
Will update all packages used in +el-get-sources+. Beware that using
this function can lead to hours of settings review: more often than not
updating a package requires some adjustments to your setup. Updating
all of them at once will require reviewing almost all your setup.
M-x el-get-remove::
Will prompt for an +installed+ package name, with completion, then
remove it. Depending on the +type+ of the package, this often means
simply deleting the directory where the source package lies. Sometime we
have to use external tools instead (+apt-get+, e.g.). No effort is made
to unload the features.
M-x el-get-find-recipe-file::
Will prompt for the name of a package, with completion, then +find-file+
its +recipe+ file.
M-x el-get-make-recipes::
Will prompt for an existing directory where to output all your 'new'
recipe files: one file for each entry in +el-get-sources+ that is not
just a +symbol+ and that is not found anywhere in +el-get-recipe-path+.
M-x el-get-emacswiki-refresh::
Will launch a subprocess that connects to EmacsWiki and fetch from there
the list of elisp scripts hosted. Then produce a recipe file per
script, and store that in the given directory, which default to
+~/.emacs.d/el-get/el-get/recipes/emacswiki/+ if you didn't change
+el-get-dir+.
=== Useful functions
el-get-package-types-alist (statuses &rest types)::
Return an alist of package names that are of given types. Only consider
packages whose status is `member' of STATUSES, which defaults to
installed, required and removed.
ELISP> (el-get-package-types-alist "installed" 'cvs 'emacswiki)
((emacs-w3m . cvs)
(rect-mark . emacswiki)
(icomplete+ . emacswiki)
(php-mode-improved . emacswiki)
(rainbow-delimiters . emacswiki)
(goto-last-change . emacswiki)
(emacs-goodies-el . cvs))
el-get-extra-packages (&rest packages)::
Return installed or required packages that are not in given package
list.
ELISP> (el-get-extra-packages dim-packages)
((verbiste "installed")
(package "installed"))
== Extending it
Please see the documentation for the +el-get-methods+ and provide a patch!
Adding +bzr+ support for example was only about writing 2 functions, mostly
using copy paste. Here's the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
== Upgrade Notes
=== Upgrading to 3.1
A change has been included so that +el-get-sources+ is now __only another__
__source for recipes__, and +(el-get '...)+ will now only install and initialize
known "required" and "installed" packages.
The documentation has been updated to detail the new setup.
If you have packages that have been installed in the past but you no longer
want in your setup, here's how to get them out of the way:
M-: (el-get-save-package-status "package-name-here" "removed")
Please review documentation section 'Advanced setup with local recipes'.

View File

@@ -0,0 +1,143 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T15:04:30+08:00
====== emacsWiki ======
Created Saturday 07 January 2012
http://www.emacswiki.org/emacs/el-get#toc3
===== Contenus =====
Emacs Lisp get (Fetch, Install, Update, etc)
Why el-get?
How is el-get different from ELPA?
Why have both?
Social Packaging
el-get and emacswiki
emacs-kicker
===== Emacs Lisp get (Fetch, Install, Update, etc) =====
El-get is tool that allows downloading **external scripts/extensions **for Emacs, __install __them for you, knows how to __update__ them and __init__ them, care about **load-path** and **Info-directory-list**, **byte-compile** what should be, manages **autoloads**, etc.
JohnWiegley once said “el-get seems like its the Great Unifier of Emacs package systems and package repositories”
Think apt-get for Emacs, and check out el-get.
===== Why el-get? =====
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy **canonical list of packages **I depend on to run Emacs, and I want this documentation to be usable as-is. Enters el-get!
The following is an example of how to use it in your __.emacs__, you could also consider starting from the **emacs-kicker**.
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless (__require 'el-get nil t__)
(url-retrieve
"https://github.com/dimitri/el-get/raw/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp))))
;; now either el-get is `require'd __already__, or have been `load'ed by the
;; el-get installer.
(setq
** el-get-sources**
'(el-get ; el-get is self-hosting
escreen ; screen for emacs, C-\ C-h
php-mode-improved ; if you're into php...
switch-window ; takes over C-x o
auto-complete ; complete as you type with overlays
zencoding-mode ; http://www.emacswiki.org/emacs/ZenCoding
(:name buffer-move ; have to add your own keys
:after (lambda ()
(global-set-key (kbd "<C-S-up>") 'buf-move-up)
(global-set-key (kbd "<C-S-down>") 'buf-move-down)
(global-set-key (kbd "<C-S-left>") 'buf-move-left)
(global-set-key (kbd "<C-S-right>") 'buf-move-right)))
(:name smex ; a better (ido like) M-x
:after (lambda ()
(setq smex-save-file "~/.emacs.d/.smex-items")
(global-set-key (kbd "M-x") 'smex)
(global-set-key (kbd "M-X") 'smex-major-mode-commands)))
(:name magit ; __git__ meet emacs, and a binding
:after (lambda ()
(global-set-key (kbd "C-x C-z") 'magit-status)))
(:name goto-last-change ; move pointer back to last change
:after (lambda ()
;; when using AZERTY keyboard, consider C-x C-_
(global-set-key (kbd "C-x C-/") 'goto-last-change)))))
(unless (string-match "**apple-darwin**" system-configuration)
(loop for p in '(color-theme ; nice looking emacs
color-theme-tango ; check out color-theme-solarized
)
do (add-to-list 'el-get-sources p)))
;;
;; Some recipes require __extra tools__ to be installed
;;
;; Note: el-get-install requires **git**, so we know we have at least that.
;;
(when (el-get-executable-find "cvs")
(add-to-list 'el-get-sources 'emacs-goodies-el)) ; the debian addons for emacs
(when (el-get-executable-find "svn")
(loop for p in '(psvn ; M-x svn-status
yasnippet ; powerful snippet mode
)
do (add-to-list 'el-get-sources p)))
;; install new packages and init already installed packages
(el-get 'sync)
So now you have a pretty good documentation of the packages__ you want installed__, **where** to get them, and **how** to install them. For the advanced methods (such as **ELPA or apt-get**), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the **URL** to clone and the build steps if any. Then also what** features** to require and maybe where to find the **texinfo **documentation of the package, for automatic inclusion into your local Info menu.
The good news is that not only you now have a solid readable description of __all that in a central place__, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if thats not the case, it will actually install it. Then, it will__ init __the packages: that means caring about the** load-path**, the Info-directory-list (and dir texinfo menu building) the loading of the **EmacsLisp files**, and finally it will **require** the features.
===== How is el-get different from ELPA? =====
ELPA is the** Emacs Lisp Package Archive** and is also known as__ package.el__, to be included in Emacs 24. This allows emacs list extension authors to package their work. That means they have to follow some guidelines and format their contribution, then propose it for upload.
This requires licence checks (good) and for the new official ELPA mirror it even requires dead-tree papers exchange and contracts and copyright assignments, I believe.
===== Why have both? =====
While ELPA is a great thing to have, its so easy to find some high quality Emacs extension out there that are not part of the offer. Either authors are not interrested into uploading to ELPA, or they dont know how to properly package for it (its only simple for single file extensions, see).
So el-get is a pragmatic answer here. Its there because it so happens that I dont depend only on emacs extensions that are available with Emacs itself, in my distribution site-lisp and in ELPA. I need some more, and I dont need it to be complex to find it, fetch it, init it and use it.
Of course I could try and package any extension I find I need and submit it to ELPA, but really, to do that nicely Id need to contact the extension author (upstream) for him to accept my patch, and then consider a fork.
===== Social Packaging =====
With el-get I propose distributed packaging if you will. Lets have a look at __two recipes(菜单)__ here. First, the el-get one itself:
(:name el-get
:type git
:url "git://github.com/dimitri/el-get.git"
:features el-get
:compile "el-get.el")
Then a much more complex one, the bbdb one:
(:name bbdb
:type git
:url "git://github.com/barak/BBDB.git"
:load-path ("./lisp" "./bits")
:build ("./configure" "make autoloads" "make")
:build/darwin ("./configure --with-emacs=/Applications/Emacs.app/Contents/MacOS/Emacs" "make autoloads" "make")
:features bbdb
:after (lambda () (bbdb-initialize))
:info "texinfo")
The idea is that its __much simpler __to just come up with a recipe like this than to patch existing code and upload it to ELPA. And anybody can share their recipes very easily, with or without proposing them to me, even if I very much like to add some more in the official el-get list.
As a user, you dont even need to twiddle with recipes, mostly, because we **already have them** for you. What you do instead is __list them in el-get-sources__.
===== el-get and emacswiki =====
Just run **M-x el-get-emacswiki-refresh** and you will have a local cache of recipes for all scripts available in EmacsWiki. Now you can M-x el-get-install any of them, its a single command away.
===== emacs-kicker =====
Following up on the very popular **emacs-starter-kit**, Im now proposing the emacs-kicker. Its about a very simple __.emacs__ file using el-get. It comes with an arbitrary selection of packages that make your life easier, and with some medium advanced settings. The idea is to, well, kick start you.
https://github.com/dimitri/emacs-kicker
If you want to try it without installing it its very easy to do so. Just clone the git repository then start an Emacs that will use this. For example that could be, using the excellent Emacs For MacOSX:
$ /Applications/Emacs.app/Contents/MacOS/Emacs -Q -l init.el

View File

@@ -0,0 +1,203 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-07T16:25:55+08:00
====== 配置 ======
Created Saturday 07 January 2012
**El Get Sources**: Show Value
State: HIDDEN, invoke "Show" in the previous line to show.
Each entry is a PLIST where the following properties are
supported.
If your property list is missing the :type property, then it's
__merged__ with the recipe one, so that you can** override **any
definition provided by `el-get' recipes locally.
:name
The name of the package. It can be different from the name of
the directory where the package is stored (after a `git
clone' for example, in which case a symlink will be created.
:depends
A single package name, or a list of package names, on which
the package depends. All of a packages dependencies will be
installed before the package is installed.
:pkgname
The name of the package for the __underlying package management__
__system__ (`apt-get', `fink' or `**pacman**', also supported by
`emacsmirror'), which can be different from the Emacs package
name.
:type
The type of the package, currently el-get offers support for
`apt-get', `elpa', `git', `emacsmirror', `git-svn', `bzr' `svn',
`cvs', `darcs', `fink', `ftp', `emacswiki', `http-tar', __`pacman'__,
`hg' and `http'. You can easily support your own types here,
see the variable `el-get-methods'.
:branch
Which branch to fetch when using `git'. Also supported in
the installer in `el-get-install'.
:url
Where to fetch the package, only meaningful for `git' and `http' types.
:build
Your build recipe, a list.
A recipe R whose `car' is not a string will be replaced
by (eval R).
Then, each element of the recipe will be interpreted as
a command:
* If the element is a string, it will be interpreted directly
by the shell.
* Otherwise, if it is a list, any list sub-elements will be
recursively "flattened" (see `el-get-flatten'). The
resulting strings will be interpreted as individual shell
arguments, appropriately quoted.
:build/system-type
Your specific build recipe for a given `system-type' gets
there and looks like :build.
:load-path
A directory or a list of directories you want `el-get' to add
to your **`load-path'**. Those directories are__ relative to__ where
the package gets installed.
:compile
Allow to restrict what to byte-compile: by default, `el-get'
will compile __all elisp files in the :load-path directories__,
unless a :build command exists for the package source. Given
a :compile property, `el-get' will only byte-compile those
**given files**, directories or __filename-regexpes__ in the property
value. This property can be a `listp' or a `stringp' if you
want to compile only one of those.
:info
This string allows you to setup a __directory__ where to find a
'package.info' file, or a path/to/whatever.info file. It will
even run `ginstall-info' for you to create the `dir' entry so
that C-h i will be able to list the newly installed
documentation. Note that you might need to kill (C-x k) your
info buffer then C-h i again to be able to see the new menu
entry.
:load
List of files to load, or a single file to load after having
installed the source but __before__ `require'ing its features.
:features
List of features el-get will __`require'__ for you.
:autoloads
Control whether el-get should generate autoloads for this
package. Setting this to nil prevents el-get from generating
autoloads for the package. __Default is t__. Setting this to a
string or a list of string will load the named autoload
files.
:library
When **using :after but not using :features, **:library allows to
set the library against which to register the :after function
against `eval-after-load'. It defaults to either :pkgname
or :package, in this order. See also `el-get-eval-after-load'.
:options
Currently used by http-tar and cvs support.
When using http-tar, it allows you to give the tar options
you want to use. Typically would be "xzf", but you might
want to choose "xjf" for handling .tar.bz files e.g.
When using CVS, when it's set to "login", `el-get' will
first issue a `cvs login' against the server, asking you
interactively (in the minibuffer) any password you might to
enter, and only then it will run the `cvs checkout' command.
:module
Currently only used by the `cvs' support, allow you to
configure the module you want to checkout in the given URL.
:repo
Only used by the `elpa' support, a cons cell with the
form (NAME . URL), as in `package-archives'. If the package
source only specifies a URL, the URL will be used for NAME as
well.
:prepare
Intended for use __from recipes__, it will run once both the
**`Info-directory-list' and the**__ `load-path' __**variables have been**
** taken care of**, but before any further action from
`el-get-init'.
:before
A pre-init function to run once__ before__** `el-get-init' calls**
** `load' and `require'. ** It gets to run with `load-path'
already set, and after :prepare has been called. It's__ not__
__ intended__ for use from recipes.
:post-init
Intended for use from recipes. This function is registered
for __`eval-after-load'__ against the recipe library by
`el-get-init' once the **:load and :features** have been setup.
:after
A function to register for `eval-after-load' against the
recipe library, after :post-init, and __after per-package__
__ user-init-file (see `el-get-user-package-directory'). __ That's not
intended for recipe use.
:lazy
Default to nil. Allows to override `el-get-is-lazy' per
package.
:localname
Currently only used by both `http' and `ftp' supports, allows
to specify the target name of the downloaded file.
This option is useful if the package should be retrieved using
a presentation interface (such as as web SCM tool).
For example, destination should be set to "package.el" if
the package url has the following scheme:
"http://www.example.com/show-as-text?file=path/package.el"
:website
The website of the project.
:description
A short description of the project.

View File

@@ -0,0 +1,423 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-19T17:08:58+08:00
====== emacs国际化 ======
Created Friday 19 August 2011
http://www.linuxsir.org/bbs/showthread.php?t=237956
** 国际化(International): 使用非 ASCII 字符集(MULE 特性)
....
国际字符集支持
Emacs 支持的__国际字符集__范围很广从拉丁字母表的欧洲变体到中文、西里尔字母(Cyrillic)、梵文(北印度语(Hindi)和马拉地语(Marathi))、埃塞俄比亚文、希腊文、希伯来文、国际音标(IPA)、日本语、朝鲜文字、老挝,泰和越南语文,还有藏文。这些支持都集中在 Emacs 的被称为 __MULE__(MULti-lingual Enhancement to GNU Emacs, GNU Emacs 的多语言无敌版) 的修改版本中。
Emacs 也支持这些字符的__各种编码__它们用在其它国际化软件类似字处理程序以及邮件程序中。
Emacs 支持下列相关操作,从而实现了包含国际字符的文本编辑:
- 您可以查看包含非 ASCII 字符的文件,保存非 ASCII 文本,在 Emacs 和它启动的程序(例如编译器、拼写检查程序和邮件程序等等)之间传递非 ASCII 文本。设置__语言环境__(参见语言环境)的时候,编码系统以及与特定语言或文化相关的变量都将自动得到设置。或者,您也可以指定 Emacs 在编码和解码每个程序的文本时的方式(参见指定编码)。
- 您可以显示每种文字 (script) 包含的非 ASCII 字符。实现方式是通过在 X 和类似的图形环境中,使用合适的字体(参见定义字体集),以及在文本终端下,发送特殊的代码(参见指定编码)。如果某些字符显示不正常,参见无法显示的字符,那里记载了可能的问题以及解决的办法。
- 您可以插入非 ASCII 字符,或者搜索它们。为此,您可以指定一种适于您的语言的输入法(参见选择输入法),或者使用您的语言环境加载时设定的默认输入法。(Emacs 输入法是 Leim 软件包的一部分,它必须安装才能使用。)如果您的键盘可以产生非 ASCII 字符,您可以设置合适的键盘编码系统(参见指定编码),然后 Emacs 就可以接受那些字符了。Latin-1 字符也可以使用 C-x 8 前缀输入,参见单字节字符集支持。在 X 窗口系统中,您的语言环境变量(__locale__)必须设置为合适的值Emacs 才能正确解释键盘输入,参见语言环境。
本章的其余部分将详细描述下列主题。
* 国际字符: 多字节字符的基本概念
* 使用多字节字符: 控制是否使用多字节字符
* 语言环境: 为您使用的语言进行设置
* 输入法: 输入未标示在键盘上的文字字符
* 选择输入法: 指定您选用的输入法
* 多字节转换: 单字节字符如何转换为多字节
* 编码系统: 当您读写文件时的字符集转换,以及其他
* 识别编码: Emacs 如何推断必需的转换
* 指定编码: 各种设定转换的方法
* 字体集: 字体集是覆盖所有字符的字体集合
* 定义字体集: 定义新的字体集
* 无法显示的字符: 当字符无法显示的时候
* 单字节字符集支持: 无需多字节字符,您也可以选用一种西欧字符集
国际字符
国际字符集和文字的用户建立了很多或多或少称得上标准的编码系统来保存文件。Emacs 内部使用单一的多字节字符编码,因此可以在一个缓冲区或字符串中混合所有文字的字符。这个编码将每个非 ASCII 字符表示为 0200 到 0377 的字节序列。在读写文件的时候,与子进程交换数据的时候,以及有时在 C-q 命令中Emacs 在多字节字符编码和各种其他编码系统间转换(参见多字节转换)。
命令 C-h h(view-hello-file) 显示文件 etc/HELLO它显示了如何在各种语言中表达"你好"。它展示了多种文字。如果终端上无法显示一些字符,它们将显示为 '?' 或中空的方块(参见无法显示的字符)。
键盘通常不会为一个字符集的所有字符提供按键,即使在使用这个字符集的国家也是如此。因此 Emacs 支持多种 输入法,通常每种文字或语言都有一种,来方便地输入它们。
按键前缀 C-x <RET> 用于附属于多字节字符支持,编码系统以及输入法的命令。
使用多字节字符
您可以启用或禁用整个 Emacs 的多字节字符支持,也可以只设置单个缓冲区。如果缓冲区禁用多字节字符,那么每个字节就代表一个字符,即使 0200 到 0377 之间的码点也不例外。这样做来支持欧洲字符集ISO Latin-1 和 ISO Latin-2 的做法与 Emacs 19 中类似,其他 ISO 8859 字符集也是如此。
但是,不必关闭多字节字符支持也可以使用 ISO Latin 字符集Emacs 多字节字符集包含了这些字符集中所有字符,并且 Emacs 可以自由地与 ISO 编码转换。
默认情况下Emacs 启动是多字节模式,因为这样您可以没有限制地使用所有支持的语言和文字。
要在单字节方式下编辑某个文件,用 find-file-literally 打开文件,参见察看。要将多字节的缓冲区转换为相同字符的单字节表示,最简单的办法是将缓冲区保存为文件,关闭缓冲区,然后再次用 find-file-literally 打开文件。您也可以用 C-x <RET> c(universal-coding-system-argument) 命令,并且指定 'raw-text' 作为打开和保存文件时的编码系统。以 'raw-text' 打开文件不会禁止格式转换、解压缩和自动模式切换,而 find-file-literally 会禁止它们。
要关闭多字节字符集支持,启动 Emacs 时候加上 '--unibyte' 参数(参见初始化参数),或者设置环境变量 EMACS_UNIBYTE。您也可以在初始化文件中定制 enable-multibyte-characters 或等价地,直接设置变量 default-enable-multibyte-characters 为 nil来得到与 '--unibyte' 同样的效果。
要将单字节的会话转换为多字节,设置 default-multibyte-characters 为 t。在转换前创建的单字节缓冲区仍然会保持单字节。您可以在缓冲区中执行 toggle-enable-multibyte-characters 来打开这个缓冲区的多字节支持。
如果有 '--unibyte' 选项,根据包含非 ASCII 8-bit 字符的环境变量和 /etc/passwd 条目初始化的时候就不会创建多字节字符串。
Emacs 通常以多字节方式加载 Lisp 文件,无论是否使用了 '--unibyte'。这也包括初始化文件 .emacs以及 Emacs 包类似 Gnus 的初始化文件。您可以在文件的第一行中的注释里写 '-*-unibyte: t;-*-',指定以单字节方式加载(参见文件变量)。这样文件总是以单字节文本加载,即使没有使用 '--unibyte' 启动 Emacs 也是如此。这样约定的初衷是以同样方式加载所有 Lisp 文件比较可靠。但是,您可以在任何时候,用 C-x <RET> c raw-text <RET> 以单字节方式加载一个 Lisp 文件。
状态行指示了当前缓冲区是否启用了多字节支持。如果是的话,在最前的冒号前面会有两个或多个字符(通常是两个连接线)。如果没有启用多字节字符,冒号前只会有一个连接线。
语言环境
启用了多字节字符支持的 Emacs 缓冲区可以支持所有 Emacs 支持的字符集;不必设置特定语言也可以在 Emacs 缓冲区中显示它的文字。但是,选择 语言环境 的重要性在于,这样设置了很多默认值。语言环境实际是对文字的选择,而不是语言的选择。
语言环境控制了读取文本时使用的编码系统(参见指定编码)。它对文件、接收邮件、新闻和其他读入 Emacs 的文本都有效。它可能还设定了新建文件时的默认编码系统。每种语言环境还设定了默认的输入法。
要选择一种语言环境,可以设置变量 current-language-environment 或使用命令 M-x set-language-environment。运行命令时所在的缓冲区并不重要因为设置是在整个 Emacs 会话中全局有效的。所支持的语言环境包括ï¼
Belarusian, Brazilian Portuguese, Bulgarian, Chinese-BIG5, Chinese-CNS, Chinese-EUC-TW, Chinese-GB, Croatian, Cyrillic-ALT, Cyrillic-ISO, Cyrillic-KOI8, Czech, Devanagari, Dutch, English, Ethiopic, French, Georgian, German, Greek, Hebrew, IPA, Italian, Japanese, Kannada, Korean, Lao, Latin-1, Latin-2, Latin-3, Latin-4, Latin-5, Latin-6, Latin-7, Latin-8 (Celtic), Latin-9 (updated Latin-1 with the Euro sign), Latvian, Lithuanian, Malayalam, Polish, Romanian, Russian, Slovak, Slovenian, Spanish, Swedish, Tajik, Tamil, Thai, Tibetan, Turkish, UTF-8 (for a setup which prefers Unicode characters and files encoded in UTF-8), Ukrainian, Vietnamese, Welsh, and Windows-1255 (for a setup which prefers Cyrillic characters and files encoded in Windows-1255).
要在图形显示器上显示您的语言环境使用的文字,需要有合适的字体。如果一些字符显示为中空的方块,您应当安装 GNU Intlfonts 软件包它包含了大多数文字的字体6。参见字体集中有关设置字体的细节。
一些操作系统允许你设置字符集,通过设置环境变量 LC_ALL, LC_CTYPE 或 LANG7。在启动 Emacs 的时候Emacs 在系统语言环境别名表中查找您的字符集名称,与变量 locale-charset-language-names 和 locale-language-names 的值中的条目对比,如果找到匹配就选择相应的语言环境。(前者优先级比后者高。)它随即调整显示和终端编码系统,语言环境编码系统,语言环境的首选编码系统,以及 Emacs 解码键盘输入的非 ASCII 字符的方式。
如果您在运行 Emacs 时修改了 LC_ALL, LC_CTYPE 或 LANG 环境变量,您可以运行 set-locale-environment 命令来根据新的语言环境重新调整。
命令 set-locale-environment 通常使用语言环境首选的编码系统来解码系统消息。但是如果您的 locale 匹配变量 locale-prefered-coding-systems 中的条目Emacs 将使用相应的编码系统代替。例如,如果 locale 'ja_JP.PCK' 匹配 locale-prefered-coding-systems 中的 japanese-shift-jisEmacs 会使用这个编码,即使通常会首选 japanese-iso-8bit。
您可以覆盖启动时选择的语言环境,只要显式调用 set-language-environment或在初始化文件中定制 current-language-environment。
要显示特定语言环境 lang-env 的效果,运行命令 C-h L lang-env <RET>(describe-language-environment)。它会告诉您语言环境适用的语言,字符集,编码系统,以及可以用的输入法。它还会显示示例文本来描述语言环境使用的文字。默认情况下,它显示当前语言环境的信息。
您可以定制任意语言环境,使用 HOOK set-language-environment-hook。命令 set-language-environment 在设置语言环境后运行这个 HOOK。HOOK 函数通过检测变量 current-language-environment 来发现特定的语言环境。可以在 HOOK 中为某个语言环境设置非默认的内容,例如键盘输入和终端输出的编码系统,默认的输入法等等。
在设置语言环境之前set-language-environment 首先运行 HOOK exit-language-environment-hook。这个 HOOK 对于撤销在 set-language-environment-hook 中做出的定制很有用。例如,如果您在 set-hook 中对某个语言环境的按键关联做了设置,应当设置 exit-language-environment-hook 恢复按键的默认设置。
输入法
输入法 是一种字符转换,为交互输入而特别设计。在 Emacs 中,通常每种语言都有自己的输入法;有时使用相同字符的多种语言可以共用一种输入法。一些语言支持多种输入法。
最简单的输入法,是将 ASCII 字母映射到另一个字母表;这样就可以使用另一种字母表了。希腊文和俄文输入法是这样做的。
更强大的办法是组合:将字符序列转换为一个字母。很多欧洲文字输入法使用组合来产生单个非 ASCII 字母,通过输入由字母和音调标记组成的序列(或反过来)。例如,一些输入法将序列 a' 转换为单个注音字符。这些输入法没有自己特殊的命令;它们只是组合可打印字符的序列。
拼音文字的输入法通常在组合之后进行映射。泰文和朝鲜文是这样的。首先,字母被映射到特殊音节或音调的符号;然后,符号的序列构成了整个音节,被映射为一个拼音文字。
中文和日文需要更复杂的输入法。在中文输入法中,首先输入的是汉字的拼音(在 chinese-py 输入法中),或者字符的部件代码序列(在 chinese-4corner 和 chinese-sw 输入法中)。一种输入序列通常对应多种可能的中文字符。这时,可以用按键 C-f, C-b, C-n, C-p 以及数字来选择它们,这些按键有着特殊的意义。
可能的字符被排成几行,每行包含不超过 10 个候选字。通常Emacs 一次只在回显区显示一行;以 (i/j) 开始来指示是总计 j 行中的第 i 行。输入 C-n 或 </code>C-p</code> 来显示下一行或上一行。
输入 C-f 和 C-b 来在当前行的候选字中前后移动。这样做的时候Emacs 会用特殊颜色标示当前选择;输入 C-<SPC> 来接受当前选择作为输入。一行中的待选字都有编号,显示在每个字前面。输入数字 n 就可以选择当前行的第 n 个待选字,作为输入。
在中文输入法中按下 <TAB> 会显示一个包含所有可能字符的缓冲区;然后在字符上单击 Mouse-2 就可以选择候选字。按键 C-f, C-b, C-n, C-p 和数字同样可用,只是它们会在缓冲区中高亮标示当前的字符,而不是在回显区。
在日文输入法中首先使用拼音输入整个词然后当词输入缓冲区后Emacs 将它转换为一个或多个字符,根据一个大辞典。每个拼音对应多个不同的日文词;使用 C-n 和 C-p 来在待选字中循环选择。
有时需要禁止输入法处理,使您输入的字符不会与后续字符结合。例如,在输入法 latin-1-postfix 中,序列 e' 结合构成带音调的 'e'。但是怎么把它们输入成单独的字符呢?
一种方法是输入两次音调这是输入单独的字符和音调的特殊方法。例如e'' 将得到两个字符 e'’。另一种办法是在 e 后面输入一个不会与它结合的字母,然后立即删掉它。例如,输入 ee<DEL>' 来得到单独的 e 和 '’。
还有一种办法,更加通用但是不太容易输入,是在两个字符间按下 C-\ C-\,禁止它们结合。也就是使用命令 C-\(toggle-input-method) 两次。
在增量搜索中C-\ C-\ 尤其有用,因为它停止等待结合多个字符,开始搜索您已输入的内容。
要查询如何在当前输入法中输入光标下的字符,用 C-u C-x =。参见位置信息</a>。
变量 input-method-highlight-flag 和 input-method-verbose-flag 控制了输入法如何判断当前状态。如果 input-method-highlight-flag 不是 nil部分输入的序列将在缓冲区中高亮显示(大部分输入法如此,一些输入法禁止了这个特性)。如果 input-method-verbose-flag 不是 nil联想的字符列表将显示在回显区(不过在辅助缓冲区中输入时不会如此)。
选择输入法
C-\
打开或关闭所选的输入法
C-x <RET> C-\ method <RET>
为当前缓冲区选择新输入法
C-h I method <RET>
C-h C-\ method <RET>
描述输入法 method(describe-input-method)。默认情况下,它描述当前的输入法,如果有的话。描述中包含了如何使用输入法的详细信息
M-x list-input-methods
列出支持的输入法
要为当前缓冲区选择输入法,输入 C-x <RET> C-\(set-input-method)。命令从辅助缓冲区读取输入法名称,名称通常以输入法所属的语言环境开始。变量 current-input-method 记录了所选的输入法。
输入法使用 ASCII 字符序列来表示非 ASCII 字符。有时,需要临时关闭输入法,可以输入 C-\(toggle-input-method)。要重新打开输入法,再输入一次 C-\。
如果您输入了 C-\ 却尚未选择一种输入法,它将提示您指定一个。这与 C-x <RET> C-\ 指定输入法的效果是一样的。
当带有数字参数执行时,例如 C-u C-\toggle-input-method 总是提示您指定输入法,并且会把最近使用的输入法作为建议的默认值。
选择语言环境会为各种缓冲区设定默认的输入法。当设定了默认的输入法之后,要在当前缓冲区中使用它,请输入 C-\。变量 default-input-method 保存了默认的输入法,如果没有就是 nil。
在一些语言环境中支持多种输入法set-language-environment 中设定的默认输入法可能并不合您的心意。您可以让 Emacs 在特定语言环境中,设定另一种输入法为默认值,只要用命令 set-language-environment-hook (参见语言环境)。例如,
(defun my-chinese-setup ()
"Set up my private Chinese environment."
(if (equal current-language-environment "Chinese-GB")
(setq default-input-method "chinese-tonepy")))
(add-hook 'set-language-environment-hook 'my-chinese-setup)
这样会设置默认输入法为 chinese-tonepy在您选择 Chinese-GB 语言环境的时候。
一些字母文字的输入法本质上是将键盘重新映射,以模拟这些文字中常用的键盘布局。正确地重映射依赖于您的实际键盘布局。要指定您的键盘布局,使用命令 M-x quail-set-keyboard-layout。
您可以用命令 M-x quail-show-key 来显示在当前所选键盘布局中,为输入光标下的字符,应当按什么键(或按键序列)。命令 C-u C-x = 也在显示字符其他信息的同时,显示这一信息。
要显示所有支持的输入法,输入 M-x list-input-methods。列表中会给出各种输入法的信息包括状态行中代表它的字符。
多字节转换
当启用多字节字符时,从八进制 0240 到 0377 的字符是不能出现在缓冲区中的。有效的非 ASCII 可打印字符的编码从 0400 开始。
如果您输入了一个 0240 到 0377 之间的字符,或者用 C-q 输入了它Emacs 假设您要使用的是 ISO Latin-n 字符集之一,然后将它转换为代表这个 Latin-n 字符的 Emacs 代码。您应通过语言环境设置要使用的 ISO Latin 字符集,如果不指定,默认就是 Latin-1。
如果您输入了一个 0200 到 0237 之间的字符,也就是在 eight-bit-control 集合中的字符,它将被不变地插入。您不应这样做,因为这样缓冲区必须保存为 emacs-mule 或 raw-text 编码系统,这大概不是您想得到的。
编码系统
不同语言的用户建立了很多"标准"的编码系统来表示语言。Emacs 内部不使用这些编码系统;它在读取数据时从各种编码系统转换到自己的系统,在写数据时又将内部编码系统转换成其他编码系统。转换发生在读写文件,读写终端,以及与子进程交换数据的时候。
Emacs 为每个编码系统取一个名字。大多数编码系统只针对一种语言,编码系统的命名以语言名称开始。一些编码系统用于多种语言;它们的名字通常以 'iso' 开始。还有一些特殊的编码系统,包括 no-conversionraw-text 和 emacs-mule不对可打印字符做任何转换。
编码系统中,有特殊的一类,统称为代码页(codepage),用在 MS-Windows 和 MS-DOS 中编码文本。这些代码系统的命名是 cpnnnn这里 nnnn 是 3 位或 4 位的代码页编号。您可以像其他代码页一样使用它;例如,要打开以代码页 850 编码的文件,输入 C-x <RET> c cp850 <RET> C-x C-f filename <RET>。
除了转换非 ASCII 字符的不同表示之外编码系统还进行换行符的转换。Emacs 处理三种文件中换行的方式:新行符,回车换行,或者仅仅回车。
C-h C coding <RET>
描述编码系统 coding
C-h C <RET>
描述当前使用的编码系统
M-x list-coding-systems
显示所有支持的编码系统的列表
命令 C-h C(describe-coding-system) 显示特定编码系统的信息。您可以指定编码系统名称作为参数;或者,不指定参数,它将描述当前使用的各种编码系统,包括当前缓冲区、默认值,以及识别编码系统的优先级列表(参见识别编码)。
要显示所有支持的编码系统,输入 list-coding-systems。列表中包含了各种编码系统的信息包括用在状态行中的代表字母(参见状态行)。
列表中出现的编码系统,除了不作任何转换的 no-conversion 外,都指定了如何转换可打印字符的办法,而换行符转换取决于每个文件的内容。例如,如果文件内容用了回车换行序列区分各行,那么将进行 DOS 换行符转换。
列表中每种编码系统都包括三种变种,确切指定了换行符转换的方式:
...-unix
不作转换;假设文件使用新行符来分行。(这是 Unix 和 GNU 系统中的方式)
...-dos
假设文件使用回车换行来分行,做相应转换。(这是 Microsoft 系统中的方式9)
...-mac
假设文件使用回车来分行,做相应转换。(这是 Macintosh 系统中的方式)
为求简洁,在 list-coding-systems 的输出中忽略这些变种因为它们可以构造出来。例如iso-latin-1 编码系统的变种就是 iso-latin-1-unixiso-latin-1-dos 和 iso-latin-1-mac。
编码系统 raw-text 用来处理大部分是 ASCII但是包含大于 127 的字节值,而它们不是非 ASCII 字符的情况。在 raw-text 编码系统中Emacs 将不变地复制这些字节值,并且设置当前缓冲区的 enable-multibyte-characters 为 nil以正确解析它们。raw-text 以通常方式处理换行符,也就是基于文件内容判断,也有三种变种来指定转换的方式。
与之对比,编码系统 no-conversion 不作任何字符代码转换,无论是非 ASCII 字节值还是换行符。这在读写二进制文件、tar 归档文件和其他必须不变地处理的文件时游泳。它也将 enable-multibyte-characters 设置为 nil。
最简单的编辑文件而不作任何转换的办法是用 M-x find-file-literally 命令。它启用 no-conversion并且禁止其他可能在您看到文件内容前作转换的 Emacs 特性。参见查看。
编码系统 emacs-mule 意味着文件包含非 ASCII 字符,以 Emacs 内部编码保存。它基于文件内容判断换行符,也有三种变种来指定转换的方式。
识别编码
Emacs 尝试识别给定文本的编码,这是读取文本时重要的一步。(无论是读取文件、子进程的输出,还是 X 选区都是如此。) Emacs 大多数时候都可以选出正确的编码系统,只要您指定了优先级。
一些编码系统可以通过数据中的字节序列来识别或区分。但是,有些编码系统无法区分,毫无办法。例如,无法区分 Latin-1 和 Latin-2它们使用相同的字节代表了不同的含义。
Emacs 用编码系统优先级列表处理这种情况。当 Emacs 读取文件时如果您不指定要使用的编码系统Emacs 就针对每种编码系统检测数据,从优先级最高的开始,直到找到与数据匹配的编码系统为止。然后,它转换文件内容,假定文件是以这种编码系统表示。
编码系统的优先级列表依赖于所选的语言环境(参见语言环境)。例如,如果您说法语,您会希望 Emacs 首选 Latin-1 而不是 Latin-2如果您说捷克语您可能更希望 Latin-2 是首选。这也是指定语言环境的原因之一。
您可以用 M-x prefer-coding-system 来调整编码系统的优先级列表。这个命令从辅助缓冲区中读取编码系统的名称,然后将它插入到优先级列表的最前,这样它就成了首选。如果您多次执行这个命令,每次都将向优先级列表最前插入一个元素。
如果您使用指定了带换行符转换的编码系统,类似 iso-8859-1-dosEmacs 将首先尝试识别 iso-8859-1如果识别到就使用 DOS 换行转换。
有时文件名指定了要使用的编码系统。变量 file-coding-system-alist 保存了这种对应关系。有一个特别的函数 modify-coding-system-alist用来向列表加入元素。例如要用编码系统 chinese-iso-8bit 读写所有 '.txt' 文件,可以执行 Lisp 表达式
(modify-coding-system-alist 'file "\\.txt\\'" 'chinese-iso-8bit)
第一个参数是 file第二个参数是一个正则表达式指定了要应用的文件第三个参数是要在这些文件中使用的编码系统。
Emacs 根据文件内容判断使用哪种换行符转换:如果它只读到了回车,或者只读到了回车换行序列,那么它将随之选择转换。您可以禁掉自动的转换,只要设置变量 inhibit-eol-conversion 为非 nil。如果这样DOS 文件在缓冲区中将显示为包含 '^M' 字符;有些人认为这样比在状态行左侧显示小小的 '(DOS)' 标记更好(参见换行助记符)。
默认情况下,自动探测对于转义序列是敏感的。如果 Emacs 发现以转义字符开始的转义序列,并且序列可以识别为 ISO-2022 代码,那么 Emacs 将使用 ISO-2022 编码之一来解码文件。
但是,如果您希望转义序列被原样读出,这时就应当设置变量 inhibit-iso-escape-detection 为非 nil。这样编码检测将忽略转义序列不使用 ISO-2022 编码。结果是,转义序列将在缓冲区中可见。
inhibit-iso-escape-detection 的默认值是 nil。我们建议您不要一直改变它的值只在特定的操作中改变它。这是因为很多 Emacs Lisp 源代码包含非 ASCII 字符,以 iso-2022-7bit 编码系统编码,如果禁止转义序列探测,将无法正确读取解码这些文件。
您可以在某个文件的开始,用 '-*-...-*-' 结构来指定编码系统,或者在文件结尾用局部变量列表指定(参见文件变量)。看起来像是指定了"变量" coding 的值,实际上 Emacs 并没有叫做 coding 的变量;它只是用指定的编码系统作为文件的编码。例如,‘-*-mode: C; coding: latin-1;-*- 指定使用 Latin-1 编码系统和 C 模式。当您在文件中指定编码后,它将覆盖 file-coding-system-alist 的值。
变量 auto-coding-alistauto-coding-regexp-alist 和 auto-coding-functions 是为特定文件名模式,或包含特定模式的文件,指定编码系统的最有力的手段;它们甚至比文件中指定的 '-*-coding:-*-' 标记优先级更高。Emacs 使用 auto-coding-alist 来处理 tar 和存档文件,避免存档文件中,某个文件的 '-*-coding:-*-' 标记导致整个存档文件被一起处理。同样Emacs 使用 auto-coding-regexp-alist 来保证文件名毫无规律的 RMAIL 文件可以被正确解码。某个内建的 auto-coding- 函数可以检测 XML 文件的编码。
如果 Emacs 没有正确识别文件的编码,您可以用 C-x <RET> r coding-system <RET> 来用正确的编码系统重新读取文件。要查看 Emacs 实际用来解码文件的编码系统,查看状态行左侧的编码系统助记符(参见状态行)或者输入 C-h C <RET>。
当解码文本时,命令 unify-8859-on-decoding-mode 启用一种"归一化"拉丁字母表的模式。具体办法是将非 ASCII 的 Latin-n 字符转换为 Latin-1 或 Unicode 字符。这样就可以简单地同时使用多种 Latin-n 字母表了。在将来版本的 Emacs 中,我们希望可以全面转向 Unicode实现完整的字符集统一。
当 Emacs 为一个缓冲区选定编码系统后,它将编码系统保存在 buffer-file-coding-system 中,默认情况下,在将缓冲区写入文件时使用这个编码系统。保存操作包括 save-buffer 和 write-region。如果您希望以不同的编码系统来保存缓冲区到文件可以用 set-buffer-file-coding-system 为缓冲区设置不同的编码系统(参见指定编码)。
您可以向任意 Emacs 缓冲区插入任意字符,但是大多数编码系统只能处理有限的字符。这意味着,插入的字符可能无法用保存时使用的编码系统编码。例如,您可以打开一个 ASCII 文件,插入一些 Latin-1 字符,或者打开 iso-8859-2 编码的波兰文字并插入一些俄语词汇。当保存缓冲区的时候Emacs 就无法使用 buffer-file-coding-system 的当前值,因为您插入的字符无法以那种编码系统编码。
出现这种情况时Emacs 将尝试优先级最高的编码系统(由 M-x prefer-coding-system 或 M-x set-language-environment 设置)如果这些编码系统可以安全地编码缓冲区中所有字符Emacs 就会用它保存,并将它的值保存在 buffer-file-coding-system 中。否则Emacs 将显示一系列可用于编码缓冲区内容的编码系统,让您选择用哪一个。
如果您向邮件消息中插入不合适的字符Emacs 的行为会稍有区别。它将检测优先级最高的编码系统是否可以用于 MIME 消息。如果不能Emacs 将提示优先级最高的编码系统并不合适,并提示选择另外一个。这样,您就不会无意间发出接受方无法解码的消息。(如果您确实希望用优先级最高的那个编码系统,只要在提示时仍然选择它。)
当在 Mail 邮件模式下发送消息时(参见发送邮件)Emacs 有四种方法来判断用于编码消息文本的编码系统。它尝试缓冲区本身的 buffer-file-coding-system 值,如果非 nil 的话。否则,它将尝试 sendmail-coding-system 的值,如果非空的话。第三种办法是使用新文件的默认编码系统,如果非空的话,它由您的语言环境决定。如果前面三个变量都是 nilEmacs 将用 Latin-1 编码系统来编码发出的邮件。
当您在 RMAIL 中收到新邮件时,每条消息都自动以自己的编码系统来解码,就好像单独的文件一样。解码会使用您指定的编码系统优先级列表。如果 MIME 消息指定了字符集RMAIL 将遵照约定,除非 rmail-decode-mime-charset 是 nil。
对于读取和保存 RMAIL 文件本身Emacs 使用 rmail-file-coding-system 指定的编码系统。默认值是 nil也就是说 RMAIL 文件不会转换(它们将使用 Emacs 内部字符表示来读写)。
指定编码
当 Emacs 无法自动选择正确的编码系统时,您可以用这些命令来指定一个:
C-x <RET> f coding <RET>
使用编码系统 coding 来查看当前缓冲区中的文件。
C-x <RET> c coding <RET>
指定下一个命令的编码系统为 coding。
C-x <RET> k coding <RET>
设置键盘输入的编码系统为 coding。
C-x <RET> t coding <RET>
设置终端输出的编码系统为 coding。
C-x <RET> p input-coding <RET> output-coding <RET>
使用编码系统 input-coding 和 output-coding 作为当前缓冲区中子进程的输入和输出。
C-x <RET> x coding <RET>
在窗口系统中与其它程序传递选中文本时使用编码系统 coding。
C-x <RET> X coding <RET>
在窗口系统中与其它程序传递下一次选中文本时(仅一次)使用编码系统 coding。
命令 C-x <RET> f(set-buffer-file-coding-system) 指定当前缓冲区的文件的编码系统。换句话说,在保存或重读取当前文件时使用的编码系统。您在辅助缓冲区中指定要使用的编码系统。由于这个命令只对您已打开的文件有用,它只影响文件保存的方式。
还有一种指定编码系统的办法是在打开文件的时候。首先用命令 C-x <RET> c(universal-coding-system-argument);这个命令在辅助缓冲区中提示输入编码系统的名称。之后,这个编码系统会作用于 紧随其后的命令。
因此,如果紧随其后的命令是 C-x C-f那么它将使用指定的编码系统来打开文件 (也会在后面保存文件时使用这个编码系统)。如果紧随其后的命令是 C-x C-w它将用这个编码系统写文件。如果这样指定保存文件的编码与 C-x <RET> f 命令不同,当缓冲区包含编码系统无法处理的字符时不再警告。
其他受指定编码系统影响的命令包括 C-x C-i 和 C-x C-v以及在其他窗口中打开文件的 C-x C-f 变体。C-x <RET> c 影响产生子进程的命令,包括 M-x shell (参见 Shell 交互环境)。
如果紧随其后的命令不使用编码系统,那么 C-x <RET> c 没有任何作用。
要在查看文件时不作转换,可以用命令 M-x find-file-literally。参见查看。
变量 default-buffer-file-coding-system 指定了创建新文件时的编码系统。当打开新文件、创建缓冲区并保存为文件的时候将应用它。设置语言环境通常会设置这个变量为合适的默认值。
如果您使用错误的编码系统查看文件,您可以用 C-x <RET> r(revert-buffer-with-coding-system) 来纠正。这个命令用您指定的编码重新查看文件。
命令 C-x <RET> t(set-terminal-coding-system) 指定终端输出的编码。如果您指定了终端输出的编码,所有输出到终端的字符将转换为那个编码。
这个特性用于内建特定语言或字符集支持的字符终端,例如,欧式终端,支持 ISO Latin 字符集之一。您在使用多字节文本时需要指定终端编码系统,这样 Emacs 就可以知道终端实际支持的字符。
默认情况下,到终端的输出不会做任何转换,除非 Emacs 可以根据终端类型或您的语言环境设定推断出使用的编码 (参见 语言环境)。
命令 C-x <RET> k(set-keyboard-coding-system) 或者变体 keyboard-coding-system 指定了键盘输入的编码。键盘输入的字符代码转换对于带有不可打印的 ASCII 字符按键的终端很有用,例如一些为 ISO Latin-1 字符集或其子集设计的终端。
默认情况下,键盘输入是根据系统语言环境设置来转换的。如果终端不支持语言环境设定的编码 (例如,输入 M-i 得到了非 ASCII 字符),您需要设置 keyboard-coding-system 为 nil 来关闭编码。您可以将这一句
(set-keyboard-coding-system nil)
写入您的 ~/.emacs 文件。
对键盘输入转换编码系统,与使用一种输入法,其间有相似之处:它们都定义了键盘输入的序列,转换为单个字符。但是,输入法是为了让人可以方便地交互使用的,要转换的序列通常是 ASCII 字符串。编码系统通常转换的是不可打印的字符。
命令 C-x <RET> x(set-selection-coding-system) 指定了向窗口系统发送所选文本,以及接受从其他应用程序中选取的文本时的编码系统。命令对全部后续选取都会有效,除非您再次用它指定了别的编码。命令 C-x <RET> X(set-next-selection-coding-system) 指定了下一次 Emacs 读取或选中文本时的编码系统。
命令 C-x <RET> p(set-buffer-process-coding-system) 指定了向子进程输入输出时的编码系统。这个命令对当前缓存有效,每个子进程都有自己的缓存,因此您可以在一个子进程的缓存中执行这个命令,以为这个子进程指定输入和输出的转换。
进程输入输出转换的默认值依赖于当前语言环境。
如果文本插入缓冲时使用了错误的编码系统,您可以用 M-x recode-region 再次解码。它将提示您输入旧的编码系统以及期望的编码系统,然后转换选区中的文本。
变量 file-name-coding-system 指定了编码文件名时的编码系统。如果您将它设置为一个编码系统的名称 (一个 Lisp 符号或字符串)Emacs 将在所有文件操作中使用此编码系统来编码文件名。这样就可以在文件名中使用非 ASCII 字符了,或者说,可以用指定编码系统中包含的非 ASCII 字符。使用 C-x <RET> F(set-file-name-coding-system) 来交互地指定它。
如果 file-name-coding-system 是 nilEmacs 将使用默认的编码系统,由语言环境决定。在默认语言环境中,文件名中的非 ASCII 字符不会被特别编码;它们以 Emacs 内部表示出现在文件系统中。
警告: 如果您在一次 Emacs 会话当中修改了 file-name-coding-system (或语言环境),如果打开的文件使用先前的编码系统来编码文件名,但是文件名无法在新的编码系统中正确编码 (或编码有所不同),就会出问题。如果您试图用原来的文件名保存缓冲区,保存结果可能是错误的名字,或者会产生错误。如果出现这种问题,用 C-x C-w 为那个缓冲区设置一个新的文件名。
如果编码文件名时出错,使用命令 M-x recode-file-name 来改变文件名的编码系统。它将提示已有的文件名,旧的编码系统,以及要转换到的编码系统。
变量 locale-coding-system 指定编码和解码系统字符串,类似系统错误消息和 format-time-string 格式以及时间戳时的编码系统。它也用来解码 X 窗口系统中的非 ASCII 键盘输入。您应当选择一个与底层文本表示相兼容的编码系统,通常它是由环境变量 LC_ALLLC_CTYPE 和 LANG 之一决定的 (这三个变量,按照这个顺序,第一个非空的值将决定文本表示的编码)。
字体集
每种 X 字体通常只定义一种字母表或文字的字形。因此,要显示 Emacs 支持的所有文字,需要很多字体才行。在 Emacs 中,这样的字体集合被称为字体集 fontset。字体集是以一系列字体定义的每种字体负责一批字符。
每个字体集有一个名字,就像字体一样。可用的 X 字体是由 X 服务器定义的,而字体集是 Emacs 自行定义的。当您定义了一个字体集后,就可以在 Emacs 中引用它的名字把它用在任何可以使用单个字体的地方。当然Emacs 字体集只能包含 X 服务器支持的字体如果某些字符在屏幕上显示为中空的方块这表示在当前使用的字体集中不包含对应这些字符的字体。7
Emacs 自动创建两个字体集:标准 (standard) 和启动 (startup) 字体集。标准字体集可能包含针对宽泛的非 ASCII 字符的字体;但是,这不是 Emacs 默认使用的字体。(默认情况下Emacs 尝试使用有粗体和斜体变体的字体。)您可以用 -fn 命令行选项,或 Font 资源(参见 X 字体(Font X))。例如,
emacs -fn fontset-standard
字体集不会为每个字符编码都设定字体。如果一个字体集没有为某个字符设定字体,或者设定了您的系统中不存在的字体,那么它将无法正确显示这个字符。这个字符将被显示为一个中空的方块。
字体集的高度和宽度是由 ASCII 字符决定的(也就是,字体集中用于显示 ASCII 字符的字体)。如果字体集中另一个字体拥有不同的高度或不同的宽度,那么用这些字体显示的字符将被截断为字体集的大小。如果 highlight-wrong-size-font 不为 nil还将在大小错误的字符周围显示一个方框。
定义字体集
Emacs 根据 standard-fontset-spec 的值,自动创建标准字体集。字体集的名字是
-*-fixed-medium-r-normal-*-16-*-*-*-*-*-fontset-standard
也可以使用简称 fontset-standard。
标准字体集的粗体、斜体和粗斜体变种都是自动创建的。它们的名字是以 bold 替换 medium以 i 替换 r或者同时替换二者得到的。
如果您使用 Font 资源(X 窗口系统),或者 -fn 命令行参数设定默认 ASCII 字体Emacs 将自动为它创建一个字体集,也就是启动字体集,它的名字是 fontset-startup。创建步骤是将厂商、字体族、附加属性和平均宽度域替换为星号将字符集登记(charset_registry[mhss])替换为 fontset将字符集编码替换为 startup然后用结果字符串指定字体集。
例如,如果您这样启动 Emacs
emacs -fn "*courier-medium-r-normal--14-140-*-iso8859-1"
Emacs 将生成下面的字体集,用在最初的 X 窗口窗格中:
-*-*-medium-r-normal-*-14-140-*-*-*-*-fontset-startup
在 X 资源 emacs.Font 中,您可以指定字体集名称,像真实字体名一样用它。但是小心不要在通配符表达的资源中(类似 emacs*Font)指定字体集名称--通配符可以匹配各种其他资源,包括菜单等等,而菜单无法处理字体集。
您可以在名为 Fontset-n 的 X 资源中指定附加的字体集,这里 n 是一个整数,从 0 开始。资源值应该是下面的形式:
fontpattern, [charsetname:fontname]...
fontpattern 应当是标准的 X 字体名,除了最后两个域应当是 fontset-alias 的形式。
这个字体集有两个名字,其一是长名字,也就是 fontpattern其二是短名字 fontset-alias。您可以用任何一个名字来引用这个字体集。
结构 charset:font 指定了对于某个特定的字符集,使用(这个字体集中的)哪个字体。这里charset 是字符集的名称,而 font 是将在这个字符集中使用的字体。在定义一个字体集的时候,您可以重复这个结构任意次。
对于其他字符集Emacs 根据 fontpattern 来选择一种字体。它将 fontset-alias 替换为描述字符集的值。对于 ASCII 字符fontset-alias 将替换为 ISO8859-1。
另外如果有数个连续的域都是通配符Emacs 将把它们折叠为一个。这是为了避免使用自动缩放的字体。通过缩放大字体得到的字体不适于编辑,而缩放小字体没有用处,因为以原始大小使用小字体效果更好,这就是 Emacs 的做法。
因此,如果 fontpattern 是这样,
-*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24
那么 ASCII 字符的字体声明将是:
-*-fixed-medium-r-normal-*-24-*-ISO8859-1
而中文 GB2312 字符的字体声明将是:
-*-fixed-medium-r-normal-*-24-*-gb2312*-*
您也许没有安装任何匹配上述字体声明的中文字体。大多数 X 发行版仅仅包含 family 域是 song ti 或 fangsong ti 的中文字体。这种情况下,可以把 Fontset-n 声明为:
Emacs.Fontset-0: -*-fixed-medium-r-normal-*-24-*-*-*-*-*-fontset-24,\
chinese-gb2312:-*-*-medium-r-normal-*-24-*-gb2312*-*
这样,所有字体声明,除了中文 GB2312 之外,都在 family 域使用 fixed而为中文 GB2312 字符使用的字体声明将在 family 域使用星号。
用来处理字体集资源,创建字体集的函数是 create-fontset-from-fontset-spec。您也可以显式调用它来创建一个字体集。
参见 X 字体(Font X) 来获取有关 X 字体命名的更多信息。
无法显示的字符
您的终端也许无法显示一些非 ASCII 字符。大多数非窗口系统的终端只能使用单一字符集(设置变量 default-terminal-coding-system (参见指定编码)来告诉 Emacs 用的是哪一个);在这个编码系统中无法编码的字符将默认显示为问号。
窗口系统的终端可以显示更大范围的字符,但是您也许没有安装完全相应的字体;找不到字体的字符将显示为一个中空的方块。
如果您用的是 Latin-1 字符集,而终端无法显示 Latin-1那么您可以设置显示助记的 ASCII 序列。例如,"o 就是变音的 o。加载 iso-ascii 库就可以了。
如果您的终端可以显示 Latin-1那么您可以用混合等价的 Latin-1 字符与 ASCII 助记序列的方式,显示其他欧洲字符集的字符。加载 latin1-display 来启用这种行为。助记的 ASCII 序列大都相应于输入法的前缀。
单字节字符集支持
ISO 8859 Latin-n 字符集定义了八进制 0240 到 0377(十进制 160 到 255) 范围内的字符代码,来处理各种欧洲语种(以及一些非欧洲语种)中的重音字母以及标点符号。如果您禁用了多字节字符Emacs 仍然可以处理这些字符集,尽管每次只能处理一种。要设定使用哪一种,执行 M-x set-language-environment 并且指定一个合适的语言环境值,例如 Latin-n。
要获取更多关于单字节操作的信息,参见使用多字节字符。需要特别注意的是,您也许需要保证初始化文件是以单字节方式读取的,如果其中包含了非 ASCII 字符的话。
Emacs 可以显示这些字符只要正在使用的终端或字体支持它们的话就会自动显示。如果您在使用窗口系统Emacs 也可以通过字体集来显示单字节字符,它会根据当前语言环境,显示等价的多字节字符。要启用这种效果,可以设置变量 unibyte-display-via-language-environment 为非 nil 值。
如果终端不支持 Latin-1 字符集Emacs 可以将这些字符显示为 ASCII 序列,这样至少可以让您知道这些字符是什么。要启用这种效果,加载 iso-ascii 库。针对其他 Latin-n 字符集的库也可以实现,不过我们还没有去做。
非 ISO 8859 字符(十进制代码 128 到 159包括两端)将显示为八进制转义符号。对于非标准的"扩展"版本的 ISO 8859 字符集,您可以用 disp-table 库中的 standard-display-8bit 函数来改变这个行为。
有很多办法,可以用来输入单字节非 ASCII 字符:
- 如果您的键盘可以产生 128(十进制)及更大的字符编码,表示非 ASCII 字符,那么您可以直接输入那些字符。
在窗口系统的终端下,您应当无需特别配置就能使用这些键;它们自然而然地就能用。在文本终端下,您应当使用命令 M-x set-keyboard-coding-system 或定制选项 keyboard-coding-system 来指定键盘使用的编码系统(参见指定编码)。启用这一特性很可能需要您使用 Esc 来输入 Meta 字符;但是,在 Linux 终端下或 xterm 中,您可以重新设定 Meta 为输入 Esc同时仍然可以输入键盘上直接标示的或用 Compose 或 AltGr 键得到的单字节字符。参见用户输入(User Input)。
- 您可以使用所选的语言环境中的输入法。参见输入法。当您在单字节的缓冲区中使用输入法时,您在输入法中选择的字符将被转换为单字节。
- 您可以用按键 C-x 8 作为"组合字符"前缀,输入非 ASCII 的 Latin-1 可打印字符。这只对 Latin-1 有效。C-x 8 在插入(包括命令缓冲区以及其他缓冲区)、搜索和其他任何允许组合键的环境中都可以用。
C-x 8 需要加载 iso-transl 库。加载之后,<ALT> 修饰键将与 C-x 8 拥有相同的效果;按下 <ALT> 然后按一个重音符号,就可以改变下一个字符。另外,如果您有针对 Latin-1 的重音字符的寂键("dead accent chars"),加载了 iso-transl 之后,它们也被定义为与下一个字符组合。使用 C-x 8 C-h 来列出所有翻译,以及助记的命令名。
- 对于 Latin-1、Latin-2 和 Latin-3M-x iso-accents-mode 可以打开一个辅助模式,它与 latin-1-prefix 输入法很像,但是不依赖于输入法。这个模式是缓冲区范围的。用 M-x iso-accents-customize 可以定制它以适于多种语言。

View File

@@ -0,0 +1,60 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-19T17:07:22+08:00
====== emacs编码系统 ======
Created Friday 19 August 2011
2后来发现
在http://www.linuxsir.org/bbs/showthread.php?t=237956中有
除了转换非 ASCII 字符的不同表示之外编码系统还进行换行符的转换。Emacs 处理三种文件中换行的方式:新行符,回车换行,或者仅仅回车。
C-h C coding <RET>
描述编码系统 coding
C-h C <RET>
描述当前使用的编码系统
M-x list-coding-systems
显示所有支持的编码系统的列表
命令 C-h C(describe-coding-system) 显示特定编码系统的信息。您可以指定编码系统名称作为参数;或者,不指定参数,它将描述当前使用的各种编码系统,包括当前缓冲区、默认值,以及识别编码系统的优先级列表(参见识别编码)。
要显示所有支持的编码系统,输入 list-coding-systems。列表中包含了各种编码系统的信息包括用在状态行中的代表字母(参见状态行)。
当 Emacs 无法自动选择正确的编码系统时,您可以用这些命令来指定一个:
C-x <RET> f coding <RET>
使用编码系统 coding 来查看当前缓冲区中的文件。
C-x <RET> c coding <RET>
指定下一个命令的编码系统为 coding。
C-x <RET> k coding <RET>
设置键盘输入的编码系统为 coding。
C-x <RET> t coding <RET>
设置终端输出的编码系统为 coding。
C-x <RET> p input-coding <RET> output-coding <RET>
使用编码系统 input-coding 和 output-coding 作为当前缓冲区中子进程的输入和输出。
C-x <RET> x coding <RET>
在窗口系统中与其它程序传递选中文本时使用编码系统 coding。
C-x <RET> X coding <RET>
在窗口系统中与其它程序传递下一次选中文本时(仅一次)使用编码系统 coding。
经过复制网页的文本到emacs发现开始不能识别保存时还提示找不到合适的codingprefer 中设置的。保存后再打开时就正确了。通过C-h C 查寻该缓冲区的字符编码。发现是iso-2022-8bit-ss2-unix 的而prefer中没有设置该项。
通过增加prefer coding后。保存时果然没有提示了。
但还是出现粘贴的时候是乱码。必须保存后才可以。(这时我都有写一个函数的想法了)
3 还有几个参数没有设置,
set-buffer-file-coding-system
set-selection-coding-system
setq default-process-coding-syste
分别设置了一下发现是set-selection-coding-system 是原因所在。
设置了
(set-selection-coding-system 'iso-2022-8bit-ss2-dos)
(set-clipboard-coding-system 'iso-2022-8bit-ss2-dos)
后果然就ok了
其实(set-selection-coding-system ) 与 (set-clipboard-coding-system )都是指定一个值,设定一个就可以了。如果两个都设置了,就不要矛盾。

138
Zim/Utils/emacs/gnus.txt Normal file
View File

@@ -0,0 +1,138 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-05-05T22:36:23+08:00
====== gnus ======
Created Thursday 05 May 2011
一个较好的.gnus.el配置文件中文说明能看新闻组
;;Gnus 是个古老的,强大的邮件,新闻阅读lisp程序.
;;设置头像文件可惜我一直没搞定
;(setq message-required-news-headers
; (nconc message-required-news-headers
; (list '(X-Face . gnus-random-x-face))))
;;用户资料设定
(setq user-full-name "YouName")
(setq user-mail-address "YouEmail@gmail.com")
;;服务器的设定
(setq gnus-select-method '(nntp "news.yaako.com"))
(add-to-list 'gnus-secondary-select-methods '(nntp "news.newsfan.net"))
(add-to-list 'gnus-secondary-select-methods '(nntp "news.php.net"))
;(add-to-list 'gnus-secondary-select-methods '(nntp "news.newsgroup.com.hk"))
;(add-to-list 'gnus-secondary-select-methods '(nntp "news.CN99.com"))
;(add-to-list 'gnus-secondary-select-methods '(nntp "groups.google.com"))
;;开启代理功能为了能让gnus支持离线浏览gnus 5.10.x会自动开启该功能。
(gnus-agentize)
;;自动换行功能。
(add-hook 'message-mode-hook
(lambda ()
(setq fill-column 72);;这里的72是等一行到了72个字符后开始换行
(turn-on-auto-fill)))
(setq message-cite-function 'message-cite-original-without-signature)
;; 设定帖子的字符集
;(setq gnus-summary-show-article-charset-alist '((1 . cn-gb-2312) (2 . big5)))
(setq gnus-default-charset 'cn-gb-2312) ;; 默认编码
(setq gnus-group-name-charset-group-alist '((".*" . cn-gb-2312))) ;; 组名编码
(setq gnus-summary-show-article-charset-alist '((1 . cn-gb-2312) (2 . big5))) ;; 刷新编码
(setq gnus-newsgroup-ignored-charsets '(unknown-8bit x-unknown iso-8859-1)) ;; 忽略编码
;; 改变阅读新闻时窗口的布局窗口划分为上4下6比例
(gnus-add-configuration '(article
(vertical 1.0
(summary .4 point)
(article 1.0))))
;;开启记分
(setq gnus-use-adaptive-scoring t)
(setq gnus-save-score t)
(add-hook 'mail-citation-hook 'sc-cite-original)
(add-hook 'message-sent-hook 'gnus-score-followup-article)
(add-hook 'message-sent-hook 'gnus-score-followup-thread)
(defvar gnus-default-adaptive-score-alist
'((gnus-kill-file-mark (from -10))
(gnus-unread-mark)
(gnus-read-mark (from 10) (subjnnect 30))
(gnus-catchup-mark (subject -10))
(gnus-killed-mark (from -1) (subject -30))
(gnus-del-mark (from -2) (subject -15))
(gnus-ticked-mark (from 10))
(gnus-dormant-mark (from 5))))
(setq gnus-score-find-score-files-function
'(gnus-score-find-hierarchical gnus-score-find-bnews bbdb/gnus-score)
gnus-use-adaptive-scoring t)
;;;
(setq gnus-confirm-mail-reply-to-news t
message-kill-buffer-on-exit t
message-elide-ellipsis "[...]\n"
)
;;排序
(setq gnus-thread-sort-functions
'(
(not gnus-thread-sort-by-date)
(not gnus-thread-sort-by-number)
))
;; 新闻组分组
;; 有时订阅了很多新闻组,堆在一起不好管理。这个功能可以创建目录来分层管理
;; 这些新闻组。
;; group topic
(add-hook 'gnus-group-mode-hook 'gnus-topic-mode)
;; 现在可以在group buffer里面M-x gnus-topic-create-topic来创建一个"topic"
;; 然后将某个新闻组或者其他topic给C-k掉再移动到你创建的topic下C-y就可以
;; 将它们收到这个topic下。
;; topic的好处除了分层之外还有就是可以将不常看的topic折叠起来不要显示。
;; 就像下面这样。
;;
;; [ Gnus -- 0 ]
;; [ MAIL -- 3 ]...
;; [ NEWS -- 0 ]
;; [ emacs -- 0 ]
;; *: nntp+binghe.6600.org: gnu.emacs.help
;; *: nntp+binghe.6600.org:gnu.emacs.gnus
;; [ 人文与社会 -- 0 ]
;; [ 语言 -- 0 ]
;; *: nntp+news.newsfan.net:教育就业.外语.日语
;; *: nntp+news.newsfan.net: 教育就业.外语.英语
;; [ misc -- 0 ]...
;;
;; 参考 gnus info -> Group Buffer -> Group Topics
;;中文设置
(setq gnus-summary-show-article-charset-alist
'((1 . cn-gb-2312) (2 . big5) (3 . gbk) (4 . utf-8)))
(setq
gnus-default-charset 'cn-gb-2312
gnus-group-name-charset-group-alist '((".*" . cn-gb-2312))
gnus-newsgroup-ignored-charsets
'(unknown-8bit x-unknown iso-8859-1 ISO-8859-15 x-gbk GB18030 gbk DEFAULT_CHARSET))
;另外有些用web方式发出的邮件里有html加入下面的设置只看其中的
;plain text部分
(eval-after-load "mm-decode"
'(progn
(add-to-list 'mm-discouraged-alternatives "text/html")
(add-to-list 'mm-discouraged-alternatives "text/richtext")))
;;设置头像文件
(setq gnus-posting-styles
'((".*"
(name "YouName")
(face "")
;;这个我都是抄老外的,自己找去,在Gnus里看到好的头像然后到
;;groups.google里把他的字符串贴过来 -_-!
(address "YouEmail@gmail.com")
(organization "www.emacs.cn")
(signature "
My name is K T")
)
))

View File

@@ -0,0 +1,329 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-05-07T10:01:10+08:00
====== Emacs Gnus 的基本配置与使用 ======
http://www.ibm.com/developerworks/cn/linux/l-cn-emacsgnus/index.html
林绪虹 (WaterLin1999@gmail.com), 软件工程师, 西艾(广州)软件开发有限公司
简介: 本文将详细介绍用 Emacs Gnus 上新闻组、收发邮件的基本配置方法,基本的使用技巧等。通过这篇文章,对 Gnus 建立起基本的概念,并能满足日常的 Gnus 使用。
===== 导言 =====
Emacs Gnus 是 Emacs 用来收发邮件与上新闻组的一个模式。你也许会问,现在漂亮的邮件客户端程序非常多,比如 ThunderbirdOutlook 等,使用起来非常方便,为什么还要用 Emacs Gnus 这样黑乎乎的老怪物呢?
和 Emacs 的其他模式一样Gnus 初一看上去并没有让人喜欢它的理由。但是,如果你喜欢使用 Emacs**喜欢 Emacs 快速便捷的编辑功能与高定制性**,日常工作中也需要处理大量的邮件与新闻组阅读,那么你一定得试一试 Emacs Gnus 这个以灵活性著称的工具。
和 Emacs 一样Gnus 的入门曲线有点陡峭,本文的目的就是为你提供一个最基本的中文 Gnus 学习指南。在学习本文之前,你必须能熟练使用 Emacs了解最基本的 elisp 语法,以及明白新闻组的基本理念。
现在的 Emacs 版本已经自带了 Gnus 模式,直接用命令 __M-x gnus __就可以启动 Gnus 模式了,你还可以用命令 __M-x gnus-other-frame__ 新开一个 Emacs 窗口来单独处理 Gnus 有关的操作。
Emacs 是一个**单线程**程序,而 Gnus 在网络 I/O 上要花费大量的时间,在运行 Gnus 的时候可能会导致你的 Emacs 无法动弹、假死掉,所以如果你的邮件或是新闻组比较多,那就最好重开一个 Emacs 专门用来处理类似的事情。
不过先别着急启动 Gnus我们需要对 Gnus 做一些基本的配置。
===== Emacs Gnus 的基本配置 =====
默认情况下Gnus 的所有配置都是放到__ ~/.gnus.el__这个文件里这个文件对于 Gnus 的作用,就像是 .emacs之于 Emacs 的作用一样Gnus 根据文件 ~/.gnus.el里的配置进行相关的定制与操作。
我们现在就通过 .gnus.el文件来对 Gnus 进行一些最基本的配置。
==== 配置读取新闻组的服务器 ====
首先,我们应该配置从哪个服务器来读取新闻组的信息。把下面这一行放到 ~/.gnus.el文件里
__ (setq gnus-select-method '(nntp "news.somewhere.cn"))__
这表明我们想从 news.somewhere.cn 这个服务器读取新闻组的信息。
如果是在国内,可以使用 news.cn99.com 这个新闻组服务器,我觉得还不错。
==== 配置显示的用户名与邮箱 ====
相信你在新闻组回帖或是跟帖的时候,想让别人能看到你的名字以及 Email 吧?否则别人怎么知道你是谁、怎么跟你联系呢?
可以把下面的语句放到 .gnus.el里来设置在 Gnus 里显示的用户名与邮箱:
__(setq user-full-name "yourname") __
__ (setq user-mail-address "yourname@email.com") __
注意,这里填写的 Email 要求是有效的 Email 地址,否则 Emacs 在启动 Gnus 的时候会提示出错信息。
==== 配置 Gnus 来收取邮件 ====
既然我们在上面设置好了邮箱,最好能配置好 Gnus 通过 smtp 来发信以及通过 pop3 来收信,这样当我们想发信给某个作者的时候,就可以直接在 Gnus 里发邮件给作者。
如果你只需要用 Gnus 来读新闻组而不用收发邮件,则可以省略这一步,只需要用上面配置好的用户名与邮箱名就可以了。
配置的代码如下,你需要把相关的 pop3 和 smtp以及用户名与密码等改成你自己真实的信息然后放到 .gnus.el文件里
;; set email reader ;;告诉 Gnus 如何存放接收的邮件
(setq gnus-secondary-select-methods '((nnml "")))
;; set pop server
(setq mail-sources
'((pop :server "POP.MAIL.YAHOO.COM" ;; 在这里设置 pop3 服务器
:user "waterlin@ymail.com" ;; 用户名
:port "pop3"
:password "password"))) ;; 密码
;; set smtp
(setq smtpmail-auth-credentials
'(("SMTP.MAIL.YAHOO.COM" ;; SMTP 服务器
25 ;; 端口号
"waterlin@ymail.com" ;; 用户名
"yourpassword"))) ;; 密码
(setq smtpmail-default-smtp-server "SMTP.MAIL.YAHOO.COM")
(setq smtpmail-smtp-server "SMTP.MAIL.YAHOO.COM")
(setq message-send-mail-function 'smtpmail-send-it)
这里需要说明的是,通过第一行代码,我们告诉 Gnus 如何存放接收的邮件Gnus 把这个叫做__后台 ( back end )__最常用的方式是 nnfolder另外还有 nnmbox, nnml等其它几种方式我们选择其中一种就可以了更详细的信息可以参考 Gnus 的官方手册。
==== Gnus 里缓冲区的基本结构 ====
通过上面最简单、最基本的配置,我们已经可以使用 Gnus 了。用命令 M-x gnus开始进行新闻组、邮件阅读。
一启动,就可以看到如下默认的 Group Buffer 了:
图 1. Gnus 默认分组
图 1. Gnus 默认分组
总的来说Gnus 分为三大缓冲区 ( Buffer )
Group 缓冲区Summary 缓冲区以及 Article 缓冲区,分别显示为 *Group**Summary*, *Article* 这样三个名称。
*Group* 缓冲区用来显示新闻组以及邮件分组的列表,而 *Summary* 缓冲区则显示特定新闻组或邮件文件夹里的文章列表,*Article* 缓冲区则显示指定文章的全部内容。
总的来说,我们每次都是按 Group Buffer --> Summary Buffer --> Article Buffer 这样的顺序来进行新闻组或邮件阅读。
和在 Emacs 里进行文本编辑一样,在 *Group* 缓冲区里,你可以把光标上 ( C-p) 下 ( C-n) 移动到某个 group 上面,按回车就可以进入该新闻组或邮件文件夹进行阅读。上下移动的操作和一般的 Emacs 编辑操作完全相同。
在 *Summary* 缓冲区里,会显示出一长串的帖子列表,如果要读某个帖子,只要这个帖子的标题上按下空格或回车键就行了。按下 q键将返回到 *Group* 缓冲区里。
回页首
订阅新的新闻组
熟悉了 Gnus 的基本结构与操作后,我们需要添加一些新的、自己感兴趣的新闻组。
在 *Group* 缓冲区里,用命令 AA可以列出所有的新闻组列表如图 2 所示:
图 2. Gnus 显示的新闻组列表清单
图 2. Gnus 显示的新闻组列表清单
如果想订阅某个新闻组,只要把光标放到你想要订阅的新闻组上,用命令 u就可以订阅该新闻组了。
订阅完了你需要的新闻组后,按 L则可以回到普通的 *Group* 缓冲区里;如果你只需要 Gnus 显示包含有未读邮件或文章的组,则用小写的 l即可。
如果你读了一段时间,觉得这个新闻组对你来说没有价值了,按 u则可以退订该新闻组。
这里值得提醒的是,当你按 u来退订某个新闻组时并没有把它从你的列表里删除只是让它处于“僵尸”状态即哪怕有新的未读文章出现Gnus 也不会让它打扰你),而你用命令 L依然能在列表里看到它只是前面标记了一个大写的 U符号。如果你想彻底把这个新闻组从 *Group* 列表里删除的话,则要用 C-k命令。
回页首
新闻组里的发帖、回帖
在 *Group* 缓冲区里订阅了新闻组后,我们就可以通过 *Group* 缓冲区进入 *Summary* 缓冲区里进行新闻组阅读。
在新闻组里发帖子叫 post article即相当于把文章贴到一个公告栏里供大家检索。发帖子的操作很简单只要我们在 *Summary* 里按下 a这个键Emacs 即会自动根据当前的状态设定相关参数,我们需要做的,只是填写帖子的标题 (subject) 和内容。写完后用快捷键 C-c C-c发出如果写了一半想取消则键入 C-c C-k删除。
在新闻组里回帖子叫 follow up按下 f键就可以进入到回帖的编辑状态。但是用小写的 f 回帖并不引用原作者的文章,而在大多数情况下,为了方便别人承前启后的阅读,我们需要在回帖里引用原文,这时可以用 F这个命令。
如果你对某个文章很感兴趣,想回复或是联系作者,但是你并不想让别人知道这些内容(相信我,很多情况下是这样的),这时你就可以用 r或者 R键通过邮件来和作者私下聊聊这个给原作者回信的动作叫做 reply to。这个操作与 follow up 不同follow up 的时候,相当于你把你的回复贴在了一个公告栏里,凡是订阅了该新闻组的人都能读到你发出的帖子。这里要注意的是,你在回信给作者的时候,一定要记得确认他的邮件地址是否正确,因为很多人会用 伪装的地址邮件来发文章到新闻组里。
在 *Group* 和 *Summary* 缓冲区里上下移动的操作是相同,你还可以用 n移动到下一个未读新闻组或未读文章用 p来移动到上一个未读文章或新闻组用 C-n移动到下一个文章或是新闻组用 C-p移动到上一个文章或是新闻组。
回页首
给帖子加标记
当你进行了一段时间的 Gnus 新闻组阅读后相信你已经注意到了当你读过一个帖子之后Gnus 会自动在帖子的最左边加上一个或多个字母、符号,这就是标记。类似的标记还有好多种,这些标记有些是我们自己加上的,有些是 Gnus 自动加上的。这些标记表明了帖子的状态,是为了方便你判断帖子的状态而设计的,简洁高效。
要熟练、高效地用 Gnus 来进行新闻组阅读,就必须熟练掌握一些常用标记。总的来说,标记分为两大类,一类是“已读 (read)”标记,一般用字母表示,比如 R,r, O,E等等另一类是“未读 (unread)”标记,一般用特殊符号表示,比如 !, ?, *等等。Gnus 针对帖子的状态,采取的处理方式截然不同。如果一个帖子被标记为“已读”并且没有保留标志,那么当你离开这个 group用 q命令以后下次再进入的时候你就不会再见到它了当然你可以要求 Gnus 把已读的帖子翻出来给你看),只有那些被标记为“未读”的帖子、新帖以及一些带有保留标记的帖子等才会显示给你看。
这些标记数量虽多,但和 Emacs 的其他功能一样,只要掌握了 20% 的内容,我们就可以胜任平时 80% 的工作,现把常用的标记及其含义整理如表 1 和表 2 所示。
表 1. 已读标记
命令 解释
R 每次你读完一篇帖子之后Gnus 就会自动加上这个标记,表示这篇帖子你已经读过了,并且下次你再进入这个新闻组,默认并不显示该帖子。
r 表示当前帖子已读,但这个标记是你自己手动用 d 命令添加的,实际上你可能并没读过。有些文章,你一看到标题就没有阅读的胃口了,那就用 d 把它标记成已读吧,省时省力!
O 表示这是个老帖上次新闻组阅读的时候你已经读过了。默认情况下Gnus 并不会显示老帖,只有当你用 / o 命令时,才可以让 Gnus 把老贴翻出来。
表 2. 未读标记
命令 解释
! 保留 (ticked) 标记,带有这个标记的帖子将一直保持可见,如果你对某个帖子感兴趣,想留着方便以后的查阅,可以加上这个标记;如果有某个帖子,你想一直追踪与它相关的文章,那就可以把它标记为 !。注意:帖子标记为 ! 状态并不是说这个帖子就永久保留下来了如果这个帖子被管理员从新闻组服务器上删除了那么你就再也看不到它了。新闻组服务器按照相应的设置定期删除过期expired的老帖。对于一些真正有价值的文章安全起见你需要把它们保存到本地的硬盘里。
? 休眠 (dormant) 标记,标记当前的帖子进入“休眠状态”,即除非有人跟帖,否则你以后不会见到这个帖子。也就是说,平常这个帖子和标记为 R 的帖子没有差别,但是一旦有人跟帖,它就会自动显身,方便你联系上下文进行阅读。用 ? 命令可以加上这个标记。
空格 如果一个帖子前面什么符号也没有,就表示这是一个“未读”的帖子。
回页首
退出缓冲区
在任何一个缓冲区里(编辑邮件或是新闻组帖子的缓冲区除外),都可以按 q退出如果是在 *Group* 缓冲区里,则会提示是否退出整个 Gnus。
回页首
基本操作的整理
不管是邮件还是新闻组里的操作,大体上基本相同,现在把上面提到的快捷键总结整理一下。
在 *Group* 缓冲区里,详细的操作命令如表 3 所示。
表 3. Group 缓冲区命令列表
命令 解释
RET 进入缓冲区
g 查看新的邮件或新闻组消息
q 退出
c 把当前光标所在组的所有文章标记为已读
C 把所有的组都标记为已读
l 显示带有未读消息的新闻组
L 显示已订阅的所有分组,包括不包含未读消息的分组
m 创建一个新邮件
a 创建一个新的新闻组帖子
u 订阅或取消订阅一个新闻组
AA 列出服务器上所有可读的新闻组
C-k 从订阅列表里删除某个新闻组
在 *Summary* 里,详细的操作命令如表 4 所示。
表 4. Summary 缓冲区命令列表
命令 解释
RET 进入当前文章
n 下一个未读文章
p 上一个未读文章
SPACE 向下翻页
DEL 向上翻页
F/f 跟帖 ( 引用原文 / 不引用原文 )
R/r 回复原作者 ( 引用原文 / 不引用原文 )
m 创建一个新邮件
a 创建一个新帖子
c 把所有的文章标记为已读
另外,如果当前的 *Summary* 缓冲区是一个邮件分组,则可以用 B DEL来删除当前的邮件如果当前的 *Summary* 缓冲区是一个新闻组的话,你则没有权限来删除任何帖子(管理员除外)。
在 *Article* 缓冲区里,即在写新的邮件或是新闻组帖子的时候,详细的操作命令如表 5 所示。
表 5. Article 缓冲区命令列表
命令 解释
C-c C-c 发送正在编写的稿件
C-c C-d 把当前编辑的稿件保存为草稿
C-c C-k 删除当前正在编写的稿件
C-c C-m f 粘贴附件
M-q 重新排版段落
如果需要帮助,则用 C-h i gnus可以获得详细的帮助。
回页首
定制 Gnus ,添加更多特色功能
通过上面的基础教程,我们已经可以把 Gnus 用起来了,当然,我们不能仅仅满足于会用 Gnus我们还可以定制更多我们喜欢的参数从而把 Gnus 用好。
添加签名档
签名档几乎是新闻组里必不可少的一部分,通过签名档,可以让别人更快速地了解有关你的信息。你可以在签名档里添加有关对你自己的介绍,或是解释一下你的 Email或者仅仅是写上几句牢骚。
如果我们需要为中文新闻组设定中文签名档,为英文新闻组设定英文签名档,则可以用 下面的代码来实现:
(setq gnus-posting-styles
'(
(".*" (signature-file "~/emacs/gnus/.signature_english"))
("cn.*" (signature-file "~/emacs/gnus/.signature_chinese"))
))
上面的代码用正则表达式来把新闻组和签名文件绑定起来,对于符合 cn.* 这样正则表达式的新闻组,则发帖的时候会自动在未尾加上文件 ~/emacs/gnus/.signature_chinese 里的内容;而对于其他的新闻组,则用英文签名档,即文件 ~/emacs/gnus/.signature_english 里的内容。这里注意,签名档不要太长,一来系统可能不允许,二来也的确是影响他人的阅读。
给邮件分组
如果你的邮件量巨大的话,把它们一股脑地放在同一个文件夹里,查阅起来太不方便了,也可能会错过重要的邮件。这个时候,我们需要做的就是利用正则表达式,把拣回来的邮件进行自动分组 ( splitting )。这里以用 nnml 方式收信为例,简单介绍一下 Gnus 的邮件分组技术。可以把下面的代码放到 .gnus.el 里:
;; set mail folder
(setq nnmail-split-methods
'(
("Emacs.org-mode" "^To:.emacs-orgmode@gnu.org")
("Emacs.general" "^Subject:.*emacs")
("Email.personal" "^To:.waterlin@ymail.com")
("Email.errors" "^From:.*\\(mailer.daemon\\|postmaster\\)")
))
在上面的代码里,我们把邮件列表里 emacs-orgmode@gnu.org 来的邮件都扔到组 nnml:Emacs.org-mode 里,把私人邮件都放到 nnml:Email.personal 里,把退信之类的错误邮件都放到 nnml:Email.errors 分组里。这样,我们一收回邮件,就可以先跑去集中查阅一下私人邮件,剩下有时间再看看 emacs-orgmode@gnu.org 邮件列表,最后有空再处理一下退回来的邮件。这对于提高我们的工作效率,大有帮助。
当然,有的时候我们也需要手工把邮件分组,用命令 B m(gnus-summary-move-article),然后输入 group 的名称就可以移动邮件到该组了。如果该组不存在,则会根据输入的名称创建。
如果需要移动多个邮件,则可以把它们都标记为 #(gnus-summary-mark-as-processable) ,然后再输入 B m(gnus-summary-move-article)。如果有一个消息标记错了,则可以用 M-#(gnus-summary-unmark-as-processable) 来取消。如果要取消所有已经标记成 #的消息,用命令 M P U(gnus-summary-unmark-all-processable) 即可。
Gnus 的邮件分组技术还有着更灵活的使用技巧,有兴趣深入了解的可以查阅一下 官方文档。
新闻组的刷新
当你在 *Summary* 缓冲区里(不管是邮件或是新闻组)阅读了一段时间以后,你可能想看看本组里有没有新的文章或邮件,这时用命令 M-g 就可以刷新该 *Summary* 缓冲区。
在 *group* 里,需要重新从服务器读取、刷新分组信息,按 g 就可以了。
设定更顺手的 Summary 缓冲区阅读操作
当你在 *Summary* 缓冲区里阅读帖子的时候,按了空格或是回车,即会把窗口分裂成上下两格(如图 3 所示),上面依然是 *Summary* 缓冲区,下面用来显示该帖子的具体内容。有的时候,下面的内容太长了不能在一个屏幕里显示出来,这个时候,你并不需要把焦点切换到下面的窗口,只需要用空格键来进行翻页。同时,可以用 DEL 键来往上翻页。很酷吧~~
图 3. Summary 分成上下两格
图 3. Summary 分成上下两格
当然,我们还可以干一件更酷的事,把下面这一行加到 .gnus.el里
(define-key gnus-summary-mode-map (kbd "Backspace")
'gnus-summary-prev-page)
我们就可以用 Backspace键来向上翻动文章了再也不用在键盘上找那个可怜的 Del键了。
Emacs Gnus 用假地址后带来的问题
如果你经常在 Usenet 上留下足迹,那么你可能会收到大量的垃圾邮件。很多垃圾邮件制造程序,会自动收集新闻组里的邮件地址并发送数量可观的垃圾邮件。要解决这个问题,只有对你留在 Usenet 上的邮件地址作文章了。
如果我们用一些方法 伪装了我们的 Email 地址,则我们很可能也不能用 Gnus 来发邮件了,因为你已经更新了默认的 email 地址。
我们可以通过设置不同的 发布风格来解决这个问题,可以通过正则表达式,用类似下面的发布风格来对新闻组的发信与普通邮件的发信给予区分,从而让留在新闻组里的邮件是一个假的邮件地址。把下面的代码放到你的 .gnus.el里
(setq gnus-posting-styles
'(
(".*"
(signature-file "~/emacs/gnus/.signature_english")
(address "WaterLin@ymail.invalid"))
("cn.*"
(signature-file "~/emacs/gnus/.signature_chinese")
(address "WaterLin@ymail.invalid"))
("nnml:.*"
(signature-file "~/emacs/gnus/.signature_english")
(address "WaterLin@ymail.com"))
))
当然,如果你留了一个假地址在新闻组上,别忘了在你的签名档里解释一下。
回页首
实践
上面讲述了这些 Gnus 的基础知识后,和其他 Emacs 模式一样,只有通过大量的肌肉训练才能熟记这些命令,从而让操作变得高效起来。如果你跟着本文一直走到这里,相信你已经能熟练地应付 Gnus 的日常使用。如果你还有疑问,不妨学以致用,直接上 Gnus 的新闻组 gnu.emacs.gnus 上参与讨论吧!
参考资料
有关 Emacs 中的邮件功能请参考: http://sachachua.com/notebook/wickedcool/wc-emacs-06-gnus.html。
请参考一篇不错的教程:用 gnus 收发邮件、泡新闻组。
在 developerWorks Linux 专区寻找为 Linux 开发人员(包括 Linux 新手入门)准备的更多参考资料,查阅我们 最受欢迎的文章和教程。
在 developerWorks 上查阅所有 Linux 技巧和 Linux 教程。
关于作者
林绪虹是一名有着5年开发经验并有着 7 年 Emacs 使用经验的开发人员,过去的 7 年时间里,他利用 Emacs 进行写文档、个人知识管理以及基本的编程工作Emacs 使他能高效地完成他的工作。他拥有机械电子工程专业硕士学位,技术兴趣广泛并喜欢技术写作,并拥有自己的技术博客。

View File

@@ -0,0 +1,16 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-05-06T15:39:45+08:00
====== turor ======
Created Friday 06 May 2011
===== 1. Starting Gnus =====
If your system administrator has set things up properly, starting Gnus and reading news is extremely easy--you just type __M-x gnus__ in your Emacs. If not, you should customize the variable** gnus-select-method** as described in 1.1 Finding the News. For a minimal setup for posting should also customize the variables **user-full-name** and **user-mail-address.**
If you want to start Gnus in a different frame, you can use the command __M-x gnus-other-frame__ instead.
If things do not go smoothly at startup, you have to twiddle some variables in your `**~/.gnus.el**' file. This file is similar to `~/.emacs', but is read when Gnus starts.
===== 1.1 Finding the News =====

View File

@@ -0,0 +1,58 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-18T19:14:56+08:00
====== ibuffer ======
Created Thursday 18 August 2011
Emacs Tip of the Day: Start Using IBuffer ASAP.
By Vedang
IBuffer is a drastic improvement on the current emacs buffer management system. Its main strength is that it allows you to operate on a group of buffers in one go, and it provides an unbelievably large array of keyboard shortcuts to perform said group operations. Using IBuffer is simple, just stick this in your .emacs file:
(require 'ibuffer)
(global-set-key (kbd "C-x C-b") 'ibuffer-other-window)
I like to see my buffers sorted by major-mode, so I add this bit too:
(setq ibuffer-default-sorting-mode 'major-mode)
To mark a set of buffers for group operations, press m. To unmark, press u.
Now that we know the basics, lets look at some of the awesomeness at our disposal:
(Listed in decreasing order of frequency of use)
'O' - ibuffer-do-occur
- Do an occur on the selected buffers.
This does a regex search on all the selected buffers and displays the result in an *occur* window. It is unbelievably useful when browsing through code. It becomes truly awesome when you combine it with the filter powers of ibuffer (coming up ahead). Eg: Do C-x C-b, mark all files using (say) Perl major-mode, do occur to find out all places where a certain function is mentioned in these files. Navigate to the point at will through the Occur window.
'M-s a C-s' - ibuffer-do-isearch
- Do an incremental search in the marked buffers.
This is so awesome that you have to try it right this instant. Select two or more buffers, hit the hotkey, search for something that occurs in all these buffers. These two features alone are enough to make me a lifelong fan of IBuffer. Go do it now!
'Q' - ibuffer-do-query-replace
- Query replace in each of the marked buffers.
I dont think I have to sell this feature now that Ive explained the first two. I is its regex brother.
'E' - ibuffer-do-eval
- Evaluate a form in each of the marked buffers. (i.e. evaluate your own emacs-lisp code on each buffer)
Eg: suppose you are viewing a set of logs that are being updated in real-time. You want to activate auto-revert-mode on all the logs so that you can see all the changes simultaneously and finally catch that timing issue. Mark the logs in ibuffer, hit E and say (auto-revert-mode 1)
Some other magic:
=================
't' - Unmark all currently marked buffers, and mark all unmarked buffers.
'* *' - Unmark all marked buffers.
'* M' - Mark buffers by major mode.
'* s' - Mark special buffers
'/ m' - Add a filter by major mode.
'/ n' - Add a filter by buffer name.
'/ c' - Add a filter by buffer content.
'/ e' - Add a filter by an arbitrary Lisp predicate.
'/ /' - Remove all filtering currently in effect.
's f' - Sort the buffers by the file name.
's v' - Sort the buffers by last viewing time.
's s' - Sort the buffers by size.
's m' - Sort the buffers by major mode.
'=' - View the differences between this buffer and its associated file.
On a final note, I can stack any of these operations on top of each other. I can do a logical OR or a logical AND of the operations. My creativity is limited only by my imagination.

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:37:17+08:00
====== new-setup ======
Created Tuesday 10 January 2012

View File

@@ -0,0 +1,91 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:41:01+08:00
====== Emacs-w3m ======
Created Tuesday 10 January 2012
Repo: cvs -d :pserver:anonymous@cvs.namazu.org:/storage/cvsroot co emacs-w3m
Homepage: http://emacs-w3m.namazu.org/
===== Installation =====
Before installing emacs-w3m, you have to check whether your environment meets the requirements.
Installing emacs-w3m on UNIX-like systems
At the first, run the configure script.
% ./configure
If you've installed APEL, FLIM or something in non-standard directories other than the default load-path, you must specify them using the --with-addpath option as follows:
% ./configure --with-addpath=/opt/share/apel:/opt/share/flim
Next, execute the following commands to install emacs-w3m to an appropriate directory.
% make
# make install
If you are using Emacs 21.1 and newer or XEmacs, you had better install icon image files. To do this:
# make install-icons
You can also install emacs-w3m as an XEmacs package using make install-package instead of make install.
% make
# make install-package
In this case, you don't have to execute make install-icons.
===== Installing on non-UNIX-like systems =====
If you cannot execute the configure script on your system, or if no make command is available, execute the following command:
# emacs -batch -q -no-site-file -l w3mhack.el NONE -f w3mhack-nonunix-install
If APEL, FLIM (or any other library) aren't installed in the ordinary places, the installer will leave them out. In such a case, it is necessary to tell those places to the installer as shown below:
# emacs -batch -q -no-site-file -l w3mhack.el //c/share/apel://c/share/flim -f w3mhack-nonunix-install
===== Configuration =====
Put this line into your ~/.emacs file:
(require 'w3m-load)
Just type M-x w3m, and you can use emacs-w3m.
In order to handle text/html part with emacs-w3m under SEMI MUAs such as Wanderlust, you have to put the following line in your ~/.emacs file:
(require 'mime-w3m)
For more detail, see Info manual.
===== Mailing List =====
We have the mailing list, emacs-w3m@namazu.org, to discuss about emacs-w3m. Because almost all of its members are Japanese, Japanese is mainly used for discussion but we also welcome mails written in English. This list is opened to the public, and its archive is accessible via WEB. You can also subscribe to the gmane.emacs.w3m newsgroup which is gateway'd to this list bidirectionally.
If you want to subscribe to this list, check the disclaimer and send a mail containing
subscribe Your Name
(not your email address) in the body to emacs-w3m-ctl@namazu.org. To unsubscribe to it, send a mail containing just
# bye
in the body to emacs-w3m-ctl@namazu.org.
===== Related Links =====
http://www.emacswiki.org/emacs/emacs-w3m
w3m
w3m-m17n
w3mmee
APEL
FLIM
BITMAP-MULE
gifsicle
New custom

View File

@@ -0,0 +1,95 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:37:35+08:00
====== ac-math ======
Created Tuesday 10 January 2012
Repo: svn checkout http://ac-math.googlecode.com/svn/trunk/ ac-math-read-only
Homepage: http://code.google.com/p/ac-math/
This is an add-on which defines three ac-sources for the__ auto-complete__ package:
* ac-source-latex-commands - input latex commands
* ac-source-math-latex - input math latex tags (active only in math environments)
* ac-source-math-unicode - input of unicode symbols (active everywhere except math environments)
To start the math completion by typing the prefix "\" key. To select the completion type RET.
Depending on the context the unicode symbol or latex \tag will be inserted.
===== Activation =====
You must have auto-complete package installed.
Download ac-math.el and put it into your load-path directory.
This is an example of how to activate the 'ac-math' in latex-mode:
(require 'ac-math)
(add-to-list 'ac-modes 'latex-mode) ; make auto-complete aware of {{{latex-mode}}}
(defun ac-latex-mode-setup () ; add ac-sources to default ac-sources
(setq ac-sources
(append '(ac-source-math-unicode ac-source-math-latex ac-source-latex-commands)
ac-sources))
)
(add-hook 'LaTeX-mode-hook 'ac-latex-mode-setup)
If you are using 'flyspell' you would also like to activate the workaround:
(ac-flyspell-workaround)
===== Unicode Input =====
To use unicode in full force with LaTeX you will need XeTeX bundle.
By default unicode input (ac-source-math-unicode) is not activated in latex math environments. To activate it do
(setq ac-math-unicode-in-math-p t)
You can always call UNDO to insert LaTeX command instead of Unicode character. For instance \alp RET inserts the character, next undo reinserts \alpha. Thus, you might consider removing ac-source-math-latex altogether from the list of ac-sources to increase the completion speed:
(defun ac-latex-mode-setup ()
(setq ac-sources
(append '(ac-source-math-unicode ac-source-latex-commands)
ac-sources))
)
Unicode input is not restricted to LaTeX modes and is particularly useful in org-mode with it's powerful exporting facilities, or web development tools where unicode is crucial.
Suppose you want it for mode XXX:
(require 'ac-math)
(add-to-list 'ac-modes 'XXX-mode)
(defun ac-XXX-mode-setup ()
(add-to-list 'ac-sources 'ac-source-math-unicode)
)
(add-hook 'XXX-mode-hook 'ac-XXX-mode-setup)
===== Other Sources =====
Here is how to make the TaTeX completion work everywhere (default is only in math mode):
(defvar ac-source-math-latex-everywere
'((candidates . ac-math-symbols-latex)
(prefix . "\\\\\\(.*\\)")
(action . ac-math-action-latex)
(symbol . "l")
))
Here is how to make unicode completion work with prefix "%" (prefix is deleted automatically on completion):
(defvar ac-source-math-unicode-on-%
'((candidates . ac-math-symbols-unicode)
(prefix . "%\\(.*\\)")
(action . ac-math-action-unicode)
(symbol . "u")
))
Please let me know if you want anything different from above.

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:43:28+08:00
====== auctex ======
Created Tuesday 10 January 2012
Repo: cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/auctex co auctex
Homepage: http://www.gnu.org/software/auctex/

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:45:18+08:00
====== reftex ======
Created Tuesday 10 January 2012
Repo: cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/auctex co reftex
Homepage: http://cvs.savannah.gnu.org/viewvc/?root=auctex

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:46:37+08:00
====== auto-complete ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/m2ym/auto-complete.git
Homepage: http://cx4a.org/software/auto-complete/

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:47:51+08:00
====== autopair ======
Created Tuesday 10 January 2012
Repo: svn checkout http://autopair.googlecode.com/svn/trunk autopair

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:48:19+08:00
====== buffer-move ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/emacsmirror/buffer-move.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:48:43+08:00
====== cedet ======
Created Tuesday 10 January 2012
Repo: bzr checkout bzr://cedet.bzr.sourceforge.net/bzrroot/cedet/code/trunk cedet

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:23:53+08:00
====== color-theme ======
Created Tuesday 10 January 2012
Homepage: http://savannah.nongnu.org/bzr/?group=color-theme
Repo: bzr branch bzr://bzr.savannah.nongnu.org/color-theme/trunk color-theme

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:49:04+08:00
====== django-mode ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/myfreeweb/django-mode.git

View File

@@ -0,0 +1,248 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:38:05+08:00
====== el-get ======
Created Tuesday 10 January 2012
Repo: https://github.com/dimitri/el-get
Homepage: http://tapoueh.org/tags/el-get.html
===== README.asciidoc =====
Short Story: el-get allows you to install and manage elisp code for Emacs. It supports lots of differents types of sources and is able to install them, update them and remove them, but more importantly it will init them for you.
That means it will require the features you need, load the necessary files, set the Info paths so that C-h i shows the new documentation you now depend on, and finally call your own :post-init function for you to setup the extension. Or call it a package.
Status and Version Numbers
Current el-get status is stable, ready for daily use and packed with extra features that make life easier. There are some more things we could do, as always, but they will be about smoothing things further.
Latest released version
el-get version 3.1 is available, with a boatload of features, including autoloads support, byte-compiling in an external "clean room" Emacs instance, custom support, lazy initialisation support (defering all init functions to eval-after-load), and multi repositories ELPA support.
Version numbering
Version String are now inspired by how Emacs itself numbers its versions. First is the major version number, then a dot, then the minor version number. The minor version number is 0 when still developping the next major version. So 3.0 is a developer release while 3.1 will be the next stable release.
Please note that this versioning policy has been picked while backing 1.2~dev, so 1.0 was a "stable" release in fact. Ah, history.
How to Install it?
Heres the lazy installer:
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp)))
You have to type C-j with the cursor at the end of the last line, but still on the line. C-j runs the command eval-print-last-sexp, so it will evaluate the code youre looking at, and that will git clone el-get at the right place.
Note that you can add this elisp code into your emacs init file directly, as the installer code will detect if el-get is already installed. Notice that doing so directly will require internet access to start emacs. You can avoid this with the following snippet instead:
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless (require 'el-get nil t)
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(end-of-buffer)
(eval-print-last-sexp))))
See next section for details about how to setup you emacs so that its able to benefit from el-get automatically.
How to install the developer version (master branch)?
The lazy installer uses the default el-get-install.el file which targets the 2.stable branch. To install el-get directly on the master branch, summon the el-get-master-branch variable into existence:
;; So the idea is that you copy/paste this code into your *scratch* buffer,
;; hit C-j, and you have a working developper edition of el-get.
(url-retrieve
"https://raw.github.com/dimitri/el-get/master/el-get-install.el"
(lambda (s)
(let (el-get-master-branch)
(end-of-buffer)
(eval-print-last-sexp))))
Basic usage
Now that el-get is installed, simply use M-x el-get-install and pick whatever package you need. Arrange to have el-get part of your setup, so that at next emacs startup the installed packages are initialized. Heres how to:
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(unless (require 'el-get nil t)
(with-current-buffer
(url-retrieve-synchronously
"https://raw.github.com/dimitri/el-get/master/el-get-install.el")
(end-of-buffer)
(eval-print-last-sexp)))
(el-get 'sync)
Thats the basic setup.
Advanced setup with local recipes
Of course, my emacs setup is managed in a private git repository. Some people on #emacs are using git submodules (or was it straight import) for managing external repositories in there, but all I can say is that I frown on this idea. I want an easy canonical list of packages I depend on to run emacs, and I want this documentation to be usable as-is. Enters el-get!
(add-to-list 'load-path "~/.emacs.d/el-get/el-get")
(require 'el-get)
;; local sources
(setq el-get-sources
'((:name magit
:after (lambda () (global-set-key (kbd "C-x C-z") 'magit-status)))
(:name asciidoc
:type elpa
:after (lambda ()
(autoload 'doc-mode "doc-mode" nil t)
(add-to-list 'auto-mode-alist '("\\.adoc$" . doc-mode))
(add-hook 'doc-mode-hook '(lambda ()
(turn-on-auto-fill)
(require 'asciidoc)))))
(:name lisppaste :type elpa)
(:name emacs-goodies-el :type apt-get)))
(setq my-packages
(append
'(cssh el-get switch-window vkill google-maps nxhtml xcscope yasnippet)
(mapcar 'el-get-source-name el-get-sources)))
(el-get 'sync my-packages)
So now you have a pretty good documentation of the packages you want installed, where to get them, and how to install them. For the advanced methods (such as elpa or apt-get), you basically just need the package name. When relying on a bare git repository, you need to give some more information, such as the URL to clone and the build steps if any. Then also what features to require and maybe where to find the texinfo documentation of the package, for automatic inclusion into your local Info menu.
The good news is that not only you now have a solid readable description of all that in a central place, but this very description is all (el-get) needs to do its magic. This command will check that each and every package is installed on your system (in el-get-dir) and if thats not the case, it will actually install it. Then, it will init the packages: that means caring about the load-path, the Info-directory-list (and dir texinfo menu building) the loading of the emacs-lisp files, and finally it will require the features.
How to use it?
You see that el-get-sources example up there? It finishes with a single (el-get) call. Thats it. It will install new sources on the list and only init already installed ones.
The status of each package is tracked into ~/.emacs.d/el-get/.status.el (by default) and can get the values required, installed or removed.
Sync or async?
Most often you want el-get-install and el-get-build to stay out of the way and be asynchronous, so that you can continue using Emacs while your new package is getting ready. But imagine youre starting up Emacs after a git pull on the other computer (after a commute, say), and theres some newer packages for this instance to consider installing.
Now you want a synchronous install, right?
So, by default (el-get) is asynchronous, but you can ask for it to be sync, or to still be asynchronous but to wait until it finished before to give control back:
(el-get 'sync)
(el-get 'wait)
You even get a progress report!
Sources
See the documentation of the el-get-sources variable for details. Please note that el-get-sources is another source location for recipes, adding to your el-get-recipe-path.
Note that you can also give a mix of packages symbols, inline recipes and source lists to el-get as arguments, and completely bypass the el-get-sources variable.
(el-get 'sync 'package 'name 'list-of-packages-names-or-symbol)
It is still recommended to (setq el-get-sources '(list of packages)) then use (el-get 'sync), so that commands such as el-get-update know which packages to update.
Recipes
Some sources are contributed to el-get directly, so that you only have to put in the el-get-sources the name of the package you want to install.
Should you need some local specific setup, you can do that by providing a partial sources missing the :type property: your local properties will get merged into the recipes one.
Also, the variable el-get-recipe-path allows you to maintain local recipes in case you either dislike the default one or are crafting some new one not commited to the main repository yet. But please do consider sending them over!
We do not intend to provide recipes for advanced types such as apt-get and elpa because theres so little to win here, and maintaining a package list would take too much time.
Package setup
The package setup can either go into the :after function, or in a file named init-package.el in el-get-user-package-directory. Any such named file will get automatically loaded by el-get at init time, if it exists.
Build Commands
Avoid using make install, which will usually move files into a "system location." In our case, you probably just want your package foo to be all installed into ~/.emacs.d/el-get/foo, right? So, no make install.
Byte Compiling
el-get will byte compile the elisp for the package when its source definition includes a :compile property set to the list of files to byte compile (or to a single file), or all the .el files found in the package when theres no :build command.
Hooks
el-get offers a variety of specific hooks (read the source), and two general purposes hooks facilities: el-get-post-install-hooks and el-get-post-update-hooks, called with the package name as argument.
Some more commands?
Yes, ok.
M-x el-get-list-packages
Opens a buffer listing all known packages (those for which you have a recipe). The listing includes the package name, its status (one of "available", "installed", "removed" or "required") and the package description. The description is a free form text and has not been provided for all recipes. Please also note that el-get-emacswiki-refresh will create recipes omitting the description as of now.
M-x el-get-describe
Prompt for a package name, with completion, then open an Help window with details about the selected package. Those include current status, website, description, installation method, full recipe, and buttons to easily install, update or remove the package.
M-x el-get-install
Will prompt for a package name, with completion, then install it. It will only propose packages that are not already installed. Any package that you have a recipe for is a candidate.
Please note that when installing a package that is not in your el-get-sources or your el-get call means that it will not be initialized for you automatically at emacs startup. You get a WARNING message when thats the case.
M-x el-get-cd
Will prompt for an installed package name, with completion, then open its directory with dired.
M-x el-get-update
Will prompt for an installed package name, with completion, then update it. This will run the build commands and init the package again.
M-x el-get-self-update
Update only one package, el-get itself.
M-x el-get-update-all
Will update all packages used in el-get-sources. Beware that using this function can lead to hours of settings review: more often than not updating a package requires some adjustments to your setup. Updating all of them at once will require reviewing almost all your setup.
M-x el-get-reload
Reload the given package files. Happens automatically at update time too.
M-x el-get-remove
Will prompt for an installed package name, with completion, then remove it. Depending on the type of the package, this often means simply deleting the directory where the source package lies. Sometime we have to use external tools instead (apt-get, e.g.). No effort is made to unload the features.
M-x el-get-find-recipe-file
Will prompt for the name of a package, with completion, then find-file its recipe file.
M-x el-get-make-recipes
Will prompt for an existing directory where to output all your new recipe files: one file for each entry in el-get-sources that is not just a symbol and that is not found anywhere in el-get-recipe-path.
M-x el-get-checksum
Will prompt for the name of an installed package, with complement, then compute its checksum if the package type supports that feature. The checksum is added to the kill-ring so that youre ready to yank it into your el-get-sources :checksum property if you want to.
M-x el-get-emacswiki-refresh
Will launch a subprocess that connects to EmacsWiki and fetch from there the list of elisp scripts hosted. Then produce a recipe file per script, and store that in the given directory, which default to ~/.emacs.d/el-get/el-get/recipes/emacswiki/ if you didnt change el-get-dir.
Useful functions
el-get-package-types-alist (statuses &rest types)
Return an alist of package names that are of given types. Only consider packages whose status is member of STATUSES, which defaults to installed, required and removed.
ELISP> (el-get-package-types-alist "installed" 'cvs 'emacswiki)
((emacs-w3m . cvs)
(rect-mark . emacswiki)
(icomplete+ . emacswiki)
(php-mode-improved . emacswiki)
(rainbow-delimiters . emacswiki)
(goto-last-change . emacswiki)
(emacs-goodies-el . cvs))
el-get-extra-packages (&rest packages)
Return installed or required packages that are not in given package list.
ELISP> (el-get-extra-packages dim-packages)
((verbiste "installed")
(package "installed"))
Extending it
Please see the documentation for the el-get-methods and provide a patch!
Adding bzr support for example was only about writing 2 functions, mostly using copy paste. Heres the patch: https://github.com/dimitri/el-get/commit/63e9018102bdeb7b6d9136db231adcd983087217#L0R437
Upgrade Notes
Upgrading to 3.1
A change has been included so that el-get-sources is now only another source for recipes, and (el-get '…) will now only install and initialize known "required" and "installed" packages.
The documentation has been updated to detail the new setup.
If you have packages that have been installed in the past but you no longer want in your setup, heres how to get them out of the way:
M-: (el-get-save-package-status "package-name-here" "removed")
Please review documentation section Advanced setup with local recipes.

View File

@@ -0,0 +1,10 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:43:18+08:00
====== global ======
Created Tuesday 10 January 2012
Repo: cvs -z3 -d:pserver:anonymous@cvs.savannah.gnu.org:/sources/global co global
Homepage: http://www.gnu.org/software/global/global.html
http://savannah.gnu.org/cvs/?group=global

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:51:01+08:00
====== htmlize ======
Created Tuesday 10 January 2012
Repo: git clone http://fly.srk.fer.hr/~hniksic/emacs/htmlize.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:52:20+08:00
====== icicles ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/emacsmirror/icicles.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:53:15+08:00
====== ido ======
Created Tuesday 10 January 2012
Repo: wget http://repo.or.cz/w/emacs.git/blob_plain/HEAD:/lisp/ido.el

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:54:07+08:00
====== insert-time-string ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/emacsmirror/insert-time-string.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:54:53+08:00
====== magit ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/magit/magit.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:55:45+08:00
====== org-mode ======
Created Tuesday 10 January 2012
Repo: git clone git://orgmode.org/org-mode.git

View File

@@ -0,0 +1,10 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:56:33+08:00
====== package ======
Created Tuesday 10 January 2012
Repo
package: wget http://tromey.com/elpa/package.el
package-install: wget http://tromey.com/elpa/package-install.el

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:57:37+08:00
====== python ======
Created Tuesday 10 January 2012

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:02:52+08:00
====== Pymacs ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/pinard/Pymacs.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T15:57:44+08:00
====== ipython ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/ipython/ipython.git

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:00:57+08:00
====== pylint ======
Created Tuesday 10 January 2012
Repo: hg clone http://hg.logilab.org/pylint

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:02:01+08:00
====== pylookup ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/tsgates/pylookup.git

View File

@@ -0,0 +1,31 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:08:06+08:00
====== python-mode ======
Created Tuesday 10 January 2012
Repo: bzr branch [[lp:python-mode]]
Homepage: https://code.launchpad.net/~python-mode-devs/python-mode/python-mode
branch: https://code.launchpad.net/python-mode
===== Related blueprints =====
pymacs integration
IPython, ipython.el issues
edit or navigate code by feature
shift keep relative position
EmacsWiki
Ropemacs integration
deliver cython-mode.el
features delivered by paredit.el
Link to another blueprint

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:12:16+08:00
====== rope ======
Created Tuesday 10 January 2012
Repo: hg clone https://bitbucket.org/agr/rope
Homepage: http://rope.sourceforge.net/

View File

@@ -0,0 +1,14 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:13:53+08:00
====== ropemacs ======
Created Tuesday 10 January 2012
Repo: hg clone https://bitbucket.org/agr/ropemacs
Homepage: http://rope.sourceforge.net/ropemacs.html
**Ropemacs** is a plugin for performing python refactorings in emacs. It uses__ rope__ library and __pymacs__.
You should install** rope** library, **ropemode** and **pymacs** before using** ropemacs**. You can download ropemacs from here.

View File

@@ -0,0 +1,9 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:14:57+08:00
====== ropemode ======
Created Tuesday 10 January 2012
Repo: hg clone https://bitbucket.org/agr/ropemode
Homepage: http://rope.sourceforge.net/ropemacs.html

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:26:47+08:00
====== smex ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/nonsequitur/smex.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:27:15+08:00
====== switch-window ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/dimitri/switch-window.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:27:44+08:00
====== yanippet ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/capitaomorte/yasnippet.git

View File

@@ -0,0 +1,8 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-10T16:28:03+08:00
====== zencoding ======
Created Tuesday 10 January 2012
Repo: git clone git://github.com/rooney/zencoding.git

View File

@@ -0,0 +1,7 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-08-14T09:16:07+08:00
====== 插件 ======
Created Sunday 14 August 2011

View File

@@ -0,0 +1,200 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2012-01-08T14:38:59+08:00
====== AucTeX ======
Created Sunday 08 January 2012
http://emacser.com/auctex.htm/comment-page-1#comments
===== AucTeX 简介 =====
关于 TeX
关于 TeX 或是 LaTeX 的介绍和使用由于篇幅就不在本文的范围之内,如果需要了解详情可以访问 ctex 论坛。
===== 为何选用 AucTeX =====
TeX 的编辑器很丰富,有跨平台的 TeXworksKile 以及 vim 的 LaTeX-suite 插件。选用 emacs+AucTeX 作为 tex 的编辑器与之相比还是有太多的优点。
* 跨平台 。 AucTeX 作为 emacs 的插件,自然可以实现跨平台,只是由于外部工具的限制在 windows 实在有诸般限制。
* 半 WYSIWYG TeX 的工作方式为 WYTIWYG但是其搭配 emacsAucTeX 可以对 tex文件进行分析并且提供__一部分的可视化特性__例如可以以粗体显示章节目录以斜体表示 \textit{} 中的文本。另外配合 preview 组件,还可以显示 tex 文件中的公式和图片。
* 拓展性 AucTeX 是完全是 elisp 实现的,如果你觉得 AucTeX 不能很好的按照你预想的方式工作或是觉得 AucTeX 功能还是不够强大,你可以用 elisp 轻松的拓展其功能,当然这需要一定的 elisp 功力。
===== 安装 =====
=== 安装条件 ===
在 unix-like 上的手动安装比较方便,只需要 “./configure && make && make install” 即可,但是当前系统需要满足这些条件:
* 可以工作的 TeX 目录树 在 unix 上 TeXLive 更加流行,当然各个 linux 发行版本也可以使用各自包管理系统安装 TeXwindows 上 MikTeX 更加流行。无论是如何安装TeX 目录树都是很庞大的,你必须确保 TeX 可以编译。
* ghostscript AucTeX 的 preview 组件在 DVI 和 PDF 模式需要 ghostscript 的协作。
=== windows 下的安装 ===
需要单独说明下 AucTeX 在 windows 下的配置windows 下建议使用官方提供的预编译版本,如现在的版本为 “AucTeX-11.86-e23.1-msw.zip”。如果喜欢折腾自己的话也可以选择在 windows 编译安装 AucTeX但是除了满足之前叙述的安装前提外你还需要一个可以工作的 shell现在只有 MSYS 和 Cygwin 可供选择。最后还是再建议使用预编译的版本,更加建议你在 unix 下使用 emacs 和 TeX可以免去太多的被折腾。
===== 加载 AucTeX =====
首先你需要把 AucTeX 加入到 load-path 中,然后加载 AucTeX 即可。如把 AucTeX 的预编译安装包解压至 “~/.emacs.d/AucTeX” 路径,相应的配置如下,其他的目录也可以相应修改。
(add-to-list 'load-path
"~/.emacs.d/lisps/AucTeX/site-lisp/site-start.d")
(load "AucTeX.el" nil t t)
(load "preview-latex.el" nil t t)
(if (string-equal system-type "windows-nt")
(require 'tex-mik))
另外,如果 emacs 是运行在多需折腾的 windows 平台上,系统会加载 “tex-mik”文件这可以提供很多在 windows 上方便的设置。
===== 快速开始 =====
=== LaTeX 设置 ===
通常情况下,编译 tex 文件选用的多是 LaTeXplainTeX 和 conTeXt 相对使用要少一些。因此本文默认只涉及对 LaTeX 模式相关的设置。
为了使用 AucTeX 方便,为 LaTeX 模式 hook 自动换行数学公式reftex 和显示行号的功能。
(mapc (lambda (mode)
(add-hook 'LaTeX-mode-hook mode))
(list 'auto-fill-mode
'LaTeX-math-mode
'turn-on-reftex
'linum-mode))
现在 TeX 对于中文的处理基本有两种方案CJK 宏包和 xetex。如果使用 CJK 宏包需要对字体进行配置,这也是大部分面对 TeX 最折腾的地方。相比 CJK 宏包xetex 要方便的多。本文也建议你设置 TeX-engine 变量为 xetex 替代 latex 作为 tex 文件的默认排版引擎。
在 LaTeX mode 中,默认开启 PDF mode即默认使用 xelatex 直接生成 pdf 文件,而不用每次用 C-c C-t C-p 进行切换。设置 Tex-show-compilation 为 t在另一个窗口显示编译信息对于错误的排除很方便。另外编译时默认直接保存文件绑定补全符号到 TAB 键。
(add-hook 'LaTeX-mode-hook
(lambda ()
(setq TeX-auto-untabify t ; remove all tabs before saving
TeX-engine '__xetex__ ; use xelatex default
TeX-show-compilation t) ; display compilation windows
(TeX-global-PDF-mode t) ; PDF mode enable, not plain
(setq TeX-save-query nil)
(imenu-add-menubar-index)
(define-key LaTeX-mode-map (kbd "TAB") 'TeX-complete-symbol)))
===== 快速插入 =====
在 tex 文档中,为了结构化的需要,经常会需要插入 \chapter, \section,'\subsection 命令。在 AucTeX 中,这些命令都可以通过 __C-c C-s__ 一站式完成,你只需要告诉 AucTeX 你所需要插入**章节层次**(section level),然后告诉 AucTeX 相应章节的标题,如果需要,你也可以添加相应的标签(可选)。
类似的,在 tex 文档中,必不可少的 \begin{document}\end{document},以及众多的类似的各种各样的**环境**,自己在编辑 tex 文档时,经常会遗忘去匹配相应的环境,然后在编译时候要花费时间去修改。于 AucTeX 里你只需要键入__C-c C-e __然后告诉 AucTeX 你所希望插入文档的环境,例如你键入了 mathAucTeX 会悉心的插入数学环境 \begin{math}\end{math}’。
AucTeX 还提供了__ C-c C-m __快捷键供方便地插入**宏命令**,在大多数情况下 auxtex 都可以理解相应宏命令的参数个数并提示你一一输入。
在使用这些快捷键时,你可以使用 __TAB 自动补全__或是使用 M-pM-n浏览命令历史记录也可以使用上下快捷键但是相信众 emacs 党应该还是键盘流多,会更习惯前者。
此处涉及的相关快捷键如下:
C-c C-s 插入章节
C-c C-e 插入 LaTex 环境
C-c C-j 插入列表 item
C-c ] 闭合 LaTeX 环境
C-c C-m 插入 Tex 宏
===== 快速更改字体 =====
AucTeX 也提供了一系列方便的快捷键用以方便的插入指定应该文本如何格式化的命令这系列命令一致__以 C-c C-f 为前缀__C- 结尾告诉 AucTeX 你具体需要如何排版文本。
C-c C-f C-b 插入粗体文本
C-c C-f C-i 插入斜体文本
C-c C-f C-e 插入强调文本
C-c C-f C-s 插入微斜体文本
C-c C-f C-r 插入罗马体文本
C-c C-f C-f 插入无衬线体文本
C-c C-f C-t 插入打印机体字体
C-c C-f C-c 插入小型大写文本
C-c C-f C-d 删除字体信息
默认情况下输入以上的快捷键时会假定插入新的相应格式化文本如果你希望更改已存在文本的话需要先__设定区域__然后再使用这些快捷键。
===== 一站式的编译、查看、打印服务 =====
如果你已经完成了 tex 文档的编写想查看排版后输出的 pdf试着输入__ C-c C-c__AucTeX 会询问你想调用那项命令在大多数情形中AucTeX __所建议__给出的命令往往可以符合你的需要。例如你刚刚完成对文档的修改此时 AucTeX 所给出的建议命令为 latex即建议你重新编译文档而如果你已经完成对最新文档的编译AucTeX 会建议你查看最新的 pdf而不是再次对文档进行编译(如果需要更新文档的交叉索引信息,可能需要多次的编译)。
如果 AucTeX 给出的建议命令不合适,你可以键入 __TAB __查看当前可用的命令然后再指定 AucTeX 运行相应的合适命令。
在对于__自定义查看文档命令__的设置中不推荐使用原来的TeX-output-view-style而更推荐灵活性更强的 TeX-view-program-list与”TeX-view-program-selection”。TeX-output-view-style 是直接绑定指定类型与相应的 viewer而对于后者在不同系统平台之间你需要定义阅读器并且对于不同的类型灵活绑定。
TeX-view-program-list 控制 AucTeX 预定义的 viewer包括符号名与具体定义所调用的命令或函数预定义为 TeX-view-program-list-builtin 的内容,有兴趣可以查看一下该变量的内容。如果需要自定义,如在 windows 平台上,可能会定义 SumatraPDF 查看 pdf 文档,而把相应的符号名记为 SumatraPDF那就可以使用如下的命令去定义。
(setq TeX-view-program-list
'(("SumatraPDF "SumatraPDF.exe %o")))
当然仅仅只是定义了符号名,而对于该符号名所对应的具体 viewer 在该平台是否可用是需要使用者自己去选择控制的。更通用而言你可能需要同时使用Linux 与 Windows 系统,那你需要分别定义其上平台的 viewer如下的设置中就分别定义了 SumatraPDF, Gsview 用于 Windows 平台Okular, Evince, Firefox用于Linux 平台。
(setq TeX-view-program-list
'(("SumatraPDF" "SumatraPDF.exe %o")
("Gsview" "gsview32.exe %o")
("Okular" "okular --unique %o")
("Evince" "evince %o")
("Firefox" "firefox %o")))
对于如上的示例而言,在 Windows 平台上绑定 SumatraPDF 为 pdf viewerMiktex 的组件 Yap 为 dvi viewer而在 Linux 平台上,或许需要 Okular 作为pdf 与 dvi 的 viewer。当然对于 Gnomer 而言Evince 应该是比 Okular 更好的选择。
PS:
* 对于 windows 平台而言,需要确保命令在 PATH 路径下,如果没有在 PATH 路径下,请使用路径全名进行调用。
* 由于自己没有 MacOsX 平台使用经验,所以没有对此作相关的 viewer 设置如果有需要,也可以自己设置。
在设置好了 viewer 之后,就需要在不同类型的文件类型与相应的 viewer 之间进行绑定。TeX-view-program-selection 变量用于指定如何用 viewer 查看指定类型的文件。
(cond
((eq system-type 'windows-nt)
(add-hook 'LaTeX-mode-hook
(lambda ()
(setq TeX-view-program-selection '((output-pdf "SumatraPDF")
(output-dvi "Yap"))))))
((eq system-type 'gnu/linux)
(add-hook 'LaTeX-mode-hook
(lambda ()
(setq TeX-view-program-selection '((output-pdf "Okular")
(output-dvi "Okular")))))))
可以看出,使用后者绑定 viewer 与指定类型相对要更灵活的多,而 AucTeX 手册也推荐此种方式而且感觉可读性也更好。而在以后的版本中可能会移除TeX-output-view-style 变量。
===== 进阶使用 =====
==== 编译片段文件 ====
编译片段文件是个很实用的功能如果你的文档很庞大但是你只是需要看一下最近编辑修改过的__片段__这时就很有用。
用快捷键设置好一个**片段(region)**然后按下__ C-c C-r__ 编译文件,然后再按 C-c C-r 就可以查看片段编译后的文件了。
编译片段文件的过程中AucTeX 先首先生成 _region_.tex 文件,然后再依次进行编译和查看的操作,当然你也可以设置 TeX-region 控制生成的文件名。而为了生成 _region_.tex 文件AucTeX 需要知道那些是文档开始需要的内容(例如文档类,载入的宏包和自定义信息),那些是文档结束的内容。在 AucTeX 中这两者是由变量TeX-header-endTeX-trailer-start 控制的。前者在 LaTeX mode 中默认为 \begin{document},而后者默认为\end{document}因此AucTeX 会截取文件开始到 TeX-header-end 的内容和片段内容以及TeX-trailer-start 的内容组成 _region_.tex 文件。也可以简单的理解成 AucTeX 把原来文件的文档内容替换成了片段内容的过程。
此外,设置好 regionC-c C-t C-r 可以固定一个 “region”即使光标位置改变设定的将要部分编译的”region”也不会改变可以随时修改”region”中的内容再按 C-c C-t C-r 取消该”region”。
==== 多文件管理 ====
在协作文档时,为了便于对文档进行管理,一般都会把文档根据内容拆分成几个部分,搭配使用 LaTeX 的 \include(\input in plainTeX) 命令对文件进行组织。
举个例子,假设当前目录下有三个 tex 文件master.tex, sectone.tex, secttwo.tex其内容分别如下。
master.tex:
\documentclass{article}
\begin{document}
\include{sectone}
\include{secttwo}
\end{document}
sectone.tex:
\section{one}
hello, world!
secttwo.tex:
\section{two}
Don't be evil!
用 AucTeX 编辑 secttwo.tex 文件时,编译文件时就会出错,因为 AucTeX **无法知道当前文件所属的 master 文件**,因此需要通知 AucTeX master 文件的信息。
为了便于对文件进行组织和管理AucTeX 允许你为文件设置__文件变量__(file variables)。因此你可以把 sectwo.tex 修改成如下内容。
\section{two}
Don't be evil!
%%% Local Variables:
%%% **TeX-master: "master"**
%%% End:
现在再编译 secttwo.tex 文件AucTeX 就可以知道 master.tex 文件为 master文件__AucTeX 会转去编译 master.tex 文件__。因此你需要在每个 tex 文件末尾添加相应的信息文件一多就会变得很繁琐。因此AucTeX 提供了TeX-master 变量,可以设置其为 “master”这样就可以通知所有的文件 master 文件总为 master.tex 文件。
(setq-default** TeX-master **"master")
当然,如果你不需要对多文件进行组织和管理,设置 TeX-master 为 t 即可,即假设当前的文件总为 master 文件。
===== reftex 与 preview 的使用 =====
reftex 和 preview 是使用 tex 的两个很方便的插件reftex 为是 emacs 内置的插件preview 也是 AucTeX 的组成部件。这两个组件使用的不是很多,但还是很有用。此处仅仅是对它们多简要的介绍,如果需要,可以查看相应的文档。
reftex 可以按文档目录结构浏览。在 LaTeX 缓冲中,按 __C-c =__Emacs 会打开一个类似文档的目录的缓冲。
当然 reftex 的功能远远比此强大,更方便之处是配合 bibtex 可以很方便的插入参考文献。
preview 的好处是可以是 tex 文件中的数学公式和图片可视化,于相应的命令处用图片替代,当然这需要你的 emacs 开启图片支持和 ghostscript。

View File

@@ -0,0 +1,131 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-05T21:42:17+08:00
====== Emacs补全利器auto-complete+gccsense ======
1 前言
2 简介
3 安装
3.1 配置auto-complete
3.2 配置gcc-code-assist
3.3 安装配置gccsense
4 主要模块介绍
5 实例
6 附录
7 参考
===== 1 前言 =====
搜索引擎上关于emacs代码补全的文章一大堆大多讲的是cedet、semantic、ctags之类的。我自己也尝试过一些“主流”的组合奈何都不来感啊。用得最长的也就auto-complete了但是用的也仅仅是它__自带的buffer内内容的补全__基本不涉及__语义的补__全。偶然发现了gccsense这个东西简单配置了下比较满意。有图有真相
{{./emacs-gccsense.jpg}}
Emacs gccsense
我绑定的补全键到M+/这样遇到要补全的地方按下M+/就出现了补全菜单,旁边是提示。
===== 2 简介 =====
auto-complete提供一个**补全的前端**通过不同的后端支持ctags等。
gccsense是**补全的后端**,能提供**符合语义的补全**。因为它是直接利用gcc的代码使用了编译器内在的分析器。它是一个独立的程序目前通过插件可以被用到emacs和vim的补全上。因为是用的gcc的代码**理论上可以补全所有gcc支持的语言**。auto-complete和gccsense是一家出的。
==== 3 安装 ====
==== 3.1 配置auto-complete ====
下载http://cx4a.org/software/auto-complete/
配置.emacs我的auto-complete在/mydoc/lib/emacs-plugins/下
; auto complete
(add-to-list 'load-path "/mydoc/lib/emacs-plugins/auto-complete")
(require 'auto-complete-config)
(add-to-list 'ac-dictionary-directories "/mydoc/lib/emacs-plugins/auto-complete/ac-dict")
(ac-config-default)
==== 3.2 配置gcc-code-assist ====
gcc-code-assist就是在gcc代码基础上改的主要用来**从代码中提取补全信息**
下载http://cx4a.org/software/gccsense/#Downloads
编译安装之前准备好环境debian系统如下
sudo apt-get install build-essential libgmp3-dev libmpfr-dev flex ruby rubygems libsqlite3-ruby
其它系统如freebsd、macos请自行参考用户手册。
配置安装:
$ tar xvjf gcc-code-assist-*.tar.bz2
$ cd gcc-code-assist-*
$ ./configure --program-suffix=-code-assist --enable-languages=c,c++ --disable-bootstrap --disable-multilib
$ make # -j2
$ sudo make install
安装成功之后执行下,如果有正常输出,就说明安装成功:
$ gcc-code-assist --version
$ g++-code-assist --version
==== 3.3 安装配置gccsense ====
gccsense这个包包含一些辅助函数以及编辑器的插件
解压缩之后,执行:
$ cd gccsense-*
$ sudo cp bin/* /usr/local/bin/
执行一下命令,确保安装成功:
$ gccrec --version
$ autopch --version
emacs的插件文件为etc/gccsense.el放到插件目录然后在.emacs里面加入
(require 'gccsense)
即可。
由于我的gccsense.el放到了。/mydoc/lib/emacs-plugins/c下并且把auto-complete的补全命令绑定到了M+/上,所以这部分配置如下:
(add-to-list 'load-path "/mydoc/lib/emacs-plugins/c")
(require 'gccsense)
(global-set-key "\257" (quote ac-complete-gccsense))
ok搞定。
===== 4 主要模块介绍 =====
在介绍使用前,简单介绍下几个主要模块的作用
__gcc-code-assist__
gcc4.4代码基础上改的那位,**用来从被补全代码中分析出补全信息**
__gccrec__
编译一个文件往往要加上编译参数的比如自定义的include地址。但是编辑器在补全的时候是不知道这些的硬生生地调用gcc-code-assist来“模拟编译”参数补全造成的错误会扰乱补全信息的获取。gccrec就是为了解决这个问题在使用编辑器补全之前需要执行一次gccrec它会将编译参数信息存到~/.gccrec这个sqlite3的数据库中。具体用法参见下一节的示例。
__autopch__
用来启用预编译头来提高速度。autopch的相关部分请各位看官自行参考用户手册吧后面的示例代码简单不需要这个东西。
5 实例
准备一个测试cpp文件test.cpp
#include <string>
using namespace std;
int main()
{
string s;
}
使用gccrec记录编译命令
这里可以认为g++-code-assist就是g++,参数一样的,比如-I -l之类的。
用emacs打开test.cpp享受补全吧
在string s;后面接着输入s.然后按M-x ac-complete-gccsense就可以利用auto-complete和它的gccsense后端来补全了。
6 附录
这里贴上我的emacs相关部分的配置文件。
我把补全的命令绑定到了M-/上面,
gccsense.el放到了/mydoc/lib/emacs-plugins/c/下面,所以这样写:
(add-to-list 'load-path "/mydoc/lib/emacs-plugins/c")
(require 'gccsense)
(global-set-key "\257" (quote ac-complete-gccsense))
7 参考
gccsense用户手册http://cx4a.org/software/gccsense/manual.html

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

View File

@@ -0,0 +1,346 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-05T22:34:00+08:00
====== 用flymake检测C/C++语法 ======
2010年12月5日 Meteor Liu 发表评论 阅读评论
1 前言
2 flymake基本用法
3 ahei的改进
4 我的修改
5 检测python语法
6 遗留问题
===== 1 前言 =====
前段时间ahei使劲推荐flymake而且在dea中还给出一段flymake配置勾起了我学习flymake的兴趣。在此之前只是听说过flymake偶尔浅尝一下还没学会怎么用就放弃了这几天折腾flymae后觉得实在很给力。生活不是缺少美而是缺少发现美的眼睛这话说得还真有点道理。
===== 2 flymake基本用法 =====
flymake是一个**实时的语法检查工具**好像是从emacs22开始已经自带flymake自带的flymake提供了对C,C++,XML,HTML,C#,perl,php,java,tex,idl的支持。查看flymake-allowed-file-name-masks这个变量可以得到支持语言的详细信息。想要了解其它语言的支持可以看看http://www.emacswiki.org/FlyMake。
在以下四种情况下flymake会执行语法检测
打开文件时
换行(可通过flymake-start-syntax-check-on-newline配置)
代码改变0.5秒后(可通过flymake-no-changes-timeout配置)
手工执行 flymake-start-syntax-check
下面是flymake基本配置
**(requirt 'flymake-mode)**
**(autoload 'flymake-find-file-hook "flymake" "" t)**
**(add-hook 'find-file-hook 'flymake-find-file-hook)**
**(setq flymake-gui-warnings-enabled nil)**
**(setq flymake-log-level 0)**
加上以上配置后打开文件时会检测是否是flymake支持的语言是的话就会自动打开flymake-mode。flymake-gui-warnings-enabled设置为nil表示出错时不弹个对话框显示错误flymake-log-level设置为0表示记录错误日志。
本文主要讨论C/C++(因为别的我不会)__自带的flymake对C/C++的支持是通过Makefile实现的__Makefile中__必须有一个check-syntax目标__比如我在Linux下用automake那我在Makefile.am中加了这么一段(其实就是调用gcc)
check-syntax:
$(CXXCOMPILE) -Wall -Wextra -pedantic -fsyntax-only $(CHK_SOURCES)
如果不用automake手写Makefile的话相应地修改一下就行了。
有了这些设置后打开项目中的cpp文件应该会自动检测语法了语法有错误的话会用颜色标识出错的行M-x flymake-goto-next-error和M-xflymake-goto-prev-error可以在错误行间移动鼠标在错误行上停留会用tooltip显示错误信息M-x flymake-display-err-menu-for-current-line能弹出一个菜单显示错误。
另外ahei写了几个函数可以在错误行间移动时在minibuffer显示出错误信息
(defun flymake-display-current-error ()
"Display errors/warnings under cursor."
(interactive)
(let ((ovs (overlays-in (point) (1+ (point)))))
(catch 'found
(dolist (ov ovs)
(when (flymake-overlay-p ov)
(message (overlay-get ov 'help-echo))
(throw 'found t))))))
(defun flymake-goto-next-error-disp ()
"Go to next error in err ring, then display error/warning."
(interactive)
(flymake-goto-next-error)
(flymake-display-current-error))
(defun flymake-goto-prev-error-disp ()
"Go to previous error in err ring, then display error/warning."
(interactive)
(flymake-goto-prev-error)
(flymake-display-current-error))
我把它绑定到了这几个按键:
(defvar flymake-mode-map (make-sparse-keymap))
(define-key flymake-mode-map (kbd "C-c <f4>") 'flymake-goto-next-error-disp)
(define-key flymake-mode-map (kbd "C-c <S-f4>") 'flymake-goto-prev-error-disp)
(define-key flymake-mode-map (kbd "C-c <C-f4>")
'flymake-display-err-menu-for-current-line)
(or (assoc 'flymake-mode minor-mode-map-alist)
(setq minor-mode-map-alist
(cons (cons 'flymake-mode flymake-mode-map)
minor-mode-map-alist)))
编辑过程中每次修改过代码0.5秒后flymake都会检测错误这就可以随时发现代码编写的错误了。
在这补充一下flymake检测的方法
对于cpp文件每次检测时flymake是把buffer内的内容另存一份再检测另存出来的文件。
而对于h文件gcc没办法单独检查头文件flymake会在flymake-master-file-dirs设定的目录中查找include过这个头文件的实现文件把buffer另存为xxx_flymake.h把查找到的第一个满足条件的实现文件另存yyy_flymake_master.cpp并把里面的include语句改为include另存的文件然后通过yyy_flymake_master.cpp来间接检测头文件。
3 ahei的改进
自带的flymake对C++只能通过Makefile来支持还必须在Makefile中加入check-syntax目标实在很麻烦。要是代码不是通过Makefile来管理的flymake就无能为力了。
其实Makefile也是通过gcc来检测代码了那要是跳过Makefile直接调用gcc来检测代码该多好啊所以ahei在DEA中配置了flymake直接调用gcc检测C++代码具体代码在flymake-setting.el中主要是以下几个函数
(defvar flymake-makefile-filenames '("Makefile" "makefile" "GNUmakefile") "File names for make.")
(defun flymake-get-make-gcc-cmdline (source base-dir)
(let (found)
(dolist (makefile flymake-makefile-filenames)
(if (file-readable-p (concat base-dir "/" makefile))
(setq found t)))
(if found
(list "make"
(list "-s"
"-C"
base-dir
(concat "CHK_SOURCES=" source)
"SYNTAX_CHECK_MODE=1"
"check-syntax"))
(list (if (string= (file-name-extension source) "c") "gcc" "g++")
(list "-o"
"/dev/null"
"-S"
source)))))
(defun flymake-simple-make-gcc-init-impl (create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f)
"Create syntax check command line for a directly checked source file.
Use CREATE-TEMP-F for creating temp copy."
(let* ((args nil)
(source-file-name buffer-file-name)
(buildfile-dir (file-name-directory source-file-name)))
(if buildfile-dir
(let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy create-temp-f)))
(setq args
(flymake-get-syntax-check-program-args
temp-source-file-name
buildfile-dir
use-relative-base-dir
use-relative-source
get-cmdline-f))))
args))
(defun flymake-simple-make-gcc-init ()
(flymake-simple-make-gcc-init-impl 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-gcc-cmdline))
主要思路就是先检测Makefile文件如果存在就调用make否则就直接调用gcc检测。
4 我的修改
ahei配置的gcc非常实用我就是因为它喜欢上flymake的不过用过几天后发现ahei的配置里有几个问题没解决
没有对make或gcc进行检测
flymake进行语法检测都是通过调用外部程序来实现的比如make或gcc如果没有安装这两个程序flymake还是会死心眼地启动一个process去调用。
不支持用gcc直接检测头文件
ahei好像是把头文件忘掉了。
目标没有权限写入时会出错
因为flymake检测文件时会把buffer内容另存到一个临时文件中再检测如果我以普通用户身份打开/usr/include/下的头文件,或者/usr/src/下的实现文件时flymake会报靠说权限有问题并且你会发现这个文件没在emacs中被打开。
不支持父目录中的Makefile
原始的flymake调用flymake-init-find-buildfile-dir来查找Makefile它会从当前目录一直往上找直到根目录为止只要找到Makefile都可以。这有一个好处就是对一个有很多子目录的大工程不需要对每个子目录下的Makefile文件都加上check-syntax目标只需要在最顶层的Makefile中加就可以了。但ahei修改的时候可能是因为flymake-init-find-buildfile-dir找不到Makefile就会报错退出而无法转而使用gcc而放弃了这个函数改为只在当前目录下找Makefile文件而不支持查找父目录了。
我的配置主要是在ahei的基础上进行修改解决了这几个我发现的问题
1.没有检测make或gcc存在的问题我在配置文件中先检测有没有对应的外部程序没有的话就不配置到flymake-allowed-file-name-masks中了。
2.我加了两个函数flymake-master-make-gcc-header-init和flymake-master-make-gcc-init来支持直接用gcc检测头文件。
3.用ignore-error忽略掉权限错误用flymake-report-fatal-status把错误通过minibuffer报告出来。
4.用flymake-find-buildfile来查找Makefile文件能支持父目录Makefile查找。
修改后的代码如下(完整的配置见http://github.com/meteor1113/dotemacs/blob/master/init-basic.el)
?[Copy to clipboard]View Code LISP
(setq flymake-allowed-file-name-masks '())
(when (executable-find "texify")
(add-to-list 'flymake-allowed-file-name-masks
'("\\.tex\\'" flymake-simple-tex-init))
(add-to-list 'flymake-allowed-file-name-masks
'("[0-9]+\\.tex\\'"
flymake-master-tex-init flymake-master-cleanup)))
(when (executable-find "xml")
(add-to-list 'flymake-allowed-file-name-masks
'("\\.xml\\'" flymake-xml-init))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.html?\\'" flymake-xml-init)))
(when (executable-find "perl")
(add-to-list 'flymake-allowed-file-name-masks
'("\\.p[ml]\\'" flymake-perl-init)))
(when (executable-find "php")
(add-to-list 'flymake-allowed-file-name-masks
'("\\.php[1]?\\'" flymake-php-init)))
(when (executable-find "make")
(add-to-list 'flymake-allowed-file-name-masks
'("\\.idl\\'" flymake-simple-make-init))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.java\\'"
flymake-simple-make-java-init flymake-simple-java-cleanup))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.cs\\'" flymake-simple-make-init)))
(when (or (executable-find "make")
(executable-find "gcc")
(executable-find "g++"))
(defvar flymake-makefile-filenames '("Makefile" "makefile" "GNUmakefile")
"File names for make.")
(defun flymake-get-gcc-cmdline (source base-dir)
(let ((cc (if (string= (file-name-extension source) "c") "gcc" "g++")))
(list cc
(list "-Wall"
"-Wextra"
"-pedantic"
"-fsyntax-only"
"-I.."
"-I../include"
"-I../inc"
"-I../common"
"-I../public"
"-I../.."
"-I../../include"
"-I../../inc"
"-I../../common"
"-I../../public"
source))))
(defun flymake-init-find-makfile-dir (source-file-name)
"Find Makefile, store its dir in buffer data and return its dir, if found."
(let* ((source-dir (file-name-directory source-file-name))
(buildfile-dir nil))
(catch 'found
(dolist (makefile flymake-makefile-filenames)
(let ((found-dir (flymake-find-buildfile makefile source-dir)))
(when found-dir
(setq buildfile-dir found-dir)
(setq flymake-base-dir buildfile-dir)
(throw 'found t)))))
buildfile-dir))
(defun flymake-simple-make-gcc-init-impl (create-temp-f
use-relative-base-dir
use-relative-source)
"Create syntax check command line for a directly checked source file.
Use CREATE-TEMP-F for creating temp copy."
(let* ((args nil)
(source-file-name buffer-file-name)
(source-dir (file-name-directory source-file-name))
(buildfile-dir
(and (executable-find "make")
(flymake-init-find-makfile-dir source-file-name)))
(cc (if (string= (file-name-extension source-file-name) "c")
"gcc"
"g++")))
(if (or buildfile-dir (executable-find cc))
(let* ((temp-source-file-name
(ignore-errors
(flymake-init-create-temp-buffer-copy create-temp-f))))
(if temp-source-file-name
(setq args
(flymake-get-syntax-check-program-args
temp-source-file-name
(if buildfile-dir buildfile-dir source-dir)
use-relative-base-dir
use-relative-source
(if buildfile-dir
'flymake-get-make-cmdline
'flymake-get-gcc-cmdline)))
(flymake-report-fatal-status
"TMPERR"
(format "Can't create temp file for %s" source-file-name))))
(flymake-report-fatal-status
"NOMK" (format "No buildfile (%s) found for %s, or can't found %s"
"Makefile" source-file-name cc)))
args))
(defun flymake-simple-make-gcc-init ()
(flymake-simple-make-gcc-init-impl 'flymake-create-temp-inplace t t))
(defun flymake-master-make-gcc-init (get-incl-dirs-f
master-file-masks
include-regexp)
"Create make command line for a source file
checked via master file compilation."
(let* ((args nil)
(temp-master-file-name
(ignore-errors
(flymake-init-create-temp-source-and-master-buffer-copy
get-incl-dirs-f
'flymake-create-temp-inplace
master-file-masks
include-regexp)))
(cc (if (string= (file-name-extension buffer-file-name) "c")
"gcc"
"g++")))
(if temp-master-file-name
(let* ((source-file-name buffer-file-name)
(source-dir (file-name-directory source-file-name))
(buildfile-dir
(and (executable-find "make")
(flymake-init-find-makfile-dir source-file-name))))
(if (or buildfile-dir (executable-find cc))
(setq args (flymake-get-syntax-check-program-args
temp-master-file-name
(if buildfile-dir buildfile-dir source-dir)
nil
nil
(if buildfile-dir
'flymake-get-make-cmdline
'flymake-get-gcc-cmdline)))
(flymake-report-fatal-status
"NOMK"
(format "No buildfile (%s) found for %s, or can't found %s"
"Makefile" source-file-name cc))))
(flymake-report-fatal-status
"TMPERR" (format "Can't create temp file for %s" source-file-name)))
args))
(defun flymake-master-make-gcc-header-init ()
(flymake-master-make-gcc-init
'flymake-get-include-dirs
'("\\.cpp\\'" "\\.c\\'")
"[ \t]*#[ \t]*include[ \t]*\"\\([[:word:]0-9/\\_.]*%s\\)\""))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.\\(?:h\\(?:pp\\)?\\)\\'"
flymake-master-make-gcc-header-init flymake-master-cleanup))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.\\(?:c\\(?:pp\\|xx\\|\\+\\+\\)?\\|CC\\)\\'"
flymake-simple-make-gcc-init)))
5 检测python语法
因为偶尔我也用下python所以我也希望flymake能把python也支持了。python有三个语法检测工具我比较之后选择了pyflakes。
装好pyflakes后加入以下配置就可以像检测cpp那样检测py文件了
?[Copy to clipboard]View Code LISP
(when (executable-find "pyflakes")
(defun flymake-pyflakes-init ()
(let* ((temp-file (flymake-init-create-temp-buffer-copy
'flymake-create-temp-inplace))
(local-file (file-relative-name
temp-file
(file-name-directory buffer-file-name))))
(list "pyflakes" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks
'("\\.py\\'" flymake-pyflakes-init)))
如果是在windows下的话可能会找不到pyflakes这个外部程序因为C:\Python25\Scripts\pyflakes没被windows识别为可执行文件我是在C:\Python25\Scripts\下加了个pyflakes.bat的文件文件里写入以下内容就能正常检测了
C:\Python25\python.exe C:\Python25\Scripts\pyflakes %*
6 遗留问题
有两个问题我还没解决:
一、对C++来说找不到Makefile的时候自动改用gcc语法检测但有时候看别人工程时会碰到有Makefile但里面没有写check-syntax目标的问题(从网上下载的开源代码很少有在Makefile中写check-syntax目标的)。要是能配置成在Makefile中找不到check-syntax目标后也能自动改用gcc检测就好了。
二、flymake通过定时器改变代码超过0.5秒后进行语法检测其实我不太喜欢这种立即检测的方式相比之下我更喜欢保存文件后进行检测。要是下个版本的flymake可以把这两种方式做成可配置就好了。

View File

@@ -0,0 +1,54 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-15T14:36:56+08:00
===== Using IDO =====
;;in the .emacs
(require ido)
(ido-mode t)
===== 1. =====
To switch between buffers, press “__C-x b__”, then:
type some characters appearing in the buffer name(只要name中包含输入的字符即可), RET to visit the buffer in the front the list.
use __C-s __(next) or__ C-r __(previous) to move through the list.
__[Tab]__ display possible completion in a buffer (or visit the buffer if there is only one possible completion).
use __C-f __to fall back to find file (without ido-mode) or __C-b__ to fall back to switch to buffer (without ido-mode).
===== 2. =====
To find a file, press “__C-x C-f__”.
type some characters appearing in the file name, RET to choose the file or directory in the front of the list.
C-s (next) or C-r (previous) to move through the list.
[Tab] - display possible completion in a buffer (or open the file or go down the directory if there is only one possible completion).
**RET - type to go down inside the directory in front of the list.**
** [backspace] - go up to the parent directory.**
// - go to the root directory.** 可以用在文件路径的任何地方**
~/ - go to the home directory.
C-f - to go back temporarily to the normal find-file.
C-d - enter Dired for this directory (used to be C-x C-d in older versions)
__ C-j __- create a new file named with the text you entered (note: this is needed if the text you entered matches an existing file, because RET would open the existing one)
===== 3. =====
To restrict the list after a first filtering:(缩小检索范围)
type some characters appearing in the buffer/file name(say .cpp)
type **C-SPC (C-@)**
continue as normal with a list containing only the filtered names
===== 4. =====
Recently visited directories:
type__ M-p__ and __M-n__ to change to previous/next directories from the history
__M-s __to search for a file matching your input
__ M-k__ to remove the current directory from the history
directories are added to the history by navigating inside them via RET
===== 5. =====
The documentation for these keys is available via
M-x describe-function RET ido-find-file RET
C-h f ido-find-file RET

View File

@@ -0,0 +1,119 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-15T14:45:13+08:00
====== tutor ======
Created Friday 15 April 2011
http://www.masteringemacs.org/articles/2010/10/10/introduction-to-ido-mode/
===== Introduction to Ido Mode =====
by mickey on October 10th, 2010
There are many ways of improving your productivity when you use Emacs, and Ido (or “**Interactively DO things**”) is one of those packages that you enable and then never, ever turn off again. Its simply that useful. By super-charging Emacss completion engine and improving the speed at which you open files and buffers, you will significantly cut down on the time spent doing these menial tasks. Think about how often you switch buffers, open files or navigate directories in Emacs.
When Ido is enabled __it replaces the existing key-, and command bindings with its own, “Ido-powered”, versions__. Most ido commands are named “ido-xxxxx”; so find-file becomes ido-find-file, and so on.
The “Ido-powered” completion engine __matches anywhere in a name__, instead of just the beginning. That means if you were to search for the buffer “*Customize Group: Foobar*” without Ido youd have to contort your fingers and type the *, then TAB (and hope it completes) and if not, type in some more; then rinse and repeat.
With Ido youd type a few characters until you find the match, or until you narrow down your list of matches to a manageable subset, and then press RET. Even better, with __fuzzy matching__ you can find things even more efficiently. So the above buffer name could be found by typing “cgf” — c for Customize, g for Group and f for Foobar. Magic.
There are some who refuse to use Ido because it “gets in the way”; I think a lot of those worries stem from not knowing that it is possible to disable Idos completion mode when it makes sense to do so.
===== Enable Ido Everywhere =====
Add this to your .emacs file:
(setq ido-enable-flex-matching t)
(setq ido-everywhere t)
(ido-mode 1)
Thatll enable basic Ido support for files and buffers and the very useful “flex matching” as well.
===== My Customizations =====
Theres more to Ido than just enabling it. Ive compiled a list of interesting settings you can change and I have thrown in some of my preferences for good measure.
==== Find File At Point ====
Find File At Point, also known generally as “ffap”, is an intelligent (well, when I say that, I mean it uses simple heuristics to infer the context at point) system for opening files, and URLs.
Some people hate it, and personally I tolerate it. It gets in the way sometimes and when it does its really annoying, but mostly it helps me so it gets to stay. It works in surprisingly many contexts like inferring the filepath of a library in an elisp (require 'foobar) form.
This will make Ido guess the context, which is what I use.
** (setq ido-use-filename-at-point 'guess)**
You can disable URL ffap support by toggling ido-use-url-at-point.
==== Eliminating Obstacles ====
If you create a ton of throw-away buffers like I do, this setting will force Ido to always create a new buffer (in C-x b) if the name does not exist. I create throw-away buffers all the time and the last thing I need is Ido asking my permission to create one. Other choices are prompt and never.
**(setq ido-create-new-buffer 'always)**
You can customize the order in which files are sorted when Ido displays them in the minibuffer. There are certain file extensions I use more than others, so I tell Ido to emphasize those.
**(setq ido-file-extensions-order '(".org" ".txt" ".py" ".emacs" ".xml" ".el" ".ini" ".cfg" ".cnf"))**
==== Ignorance is Bliss ====
Ido is capable of ignoring (that is, by omission) buffers, directories, files and extensions using regexp.
Variable Name Description
ido-ignore-buffers Takes a list of buffers to ignore in C-x b
ido-ignore-directories Takes a list of directories to ignore in C-x d and C-x C-f
ido-ignore-files Takes a list of files to ignore in C-x C-f
I would recommend using M-x customize-variable RET variable-name-here to customize them unless you are comfortabe editing Emacs lisp directly. I dont ignore anything in Ido beyond the defaults, as I prefer to use the more general completion-ignored-extensions as it works with and without Ido.
To make Ido use completion-ignored-extensions you need to enable it:
** (setq ido-ignore-extensions t)**
Now you can customize that variable as well: M-x customize-variable RET completion-ignored-extensions. Go ahead and add all the useless object files, backup, autosave and other computing flotsam you dont want Ido to show.
NOTE:Ido will still complete the ignored elements if Ido would otherwise not show any other matches. So if you type out the name of an ignored file Ido will still let you open it just fine.
==== Ido Cheatsheet ====
Heres a quick cheatsheet of all the interesting Ido commands.
The “Available In” column indicates where the keybinding is available. “All” means that is is a feature inherent to ido-completing-read and as such is available in all the completion engines. “Files”, “Dirs” and “Buffers” means it is only available in one of those.
==== General-purpose Commands ====
Keybinding Description Available In
C-b Reverts to the old switch-buffer completion engine Buffers
C-f Reverts to the old find-file completion engine Files
C-d Opens a dired buffer in the current directory Dirs / Files
C-a Toggles showing ignored files (see ido-ignore-files) Files / Buffers
C-c Toggles if searching of buffer and file names should ignore case. (see ido-case-fold) Dirs / Files / Buffers
TAB Attempt to complete the input like the normal completing read functionality Dirs / Files / Buffers
C-p Toggles prefix matching; when its on the input will only match the beginning of a filename instead of any part of it. Files
C-s / C-r Moves to the next and previous match, respectively All
**C-t ** Toggles matching by Emacs regular expression. All
Backspace Deletes characters as usual or goes up one directory if it makes sense to do so. All (but functionality varies)
C-SPC / C-@ Restricts the completion list to anything that matches your current input. (Thanks to Joakim Hårsman for pointing it out) All
// Like most *nix shells two forward slashes in a path means “ignore the preceding path, and go back to the top-most directory”. Works the same in Ido but its more interactive: it will go to the root / (or the root of the current drive in Windows) Files
~/ Jumps to the home directory. On Windows this would be typically be %USERPROFILE% or %HOME%, if it is defined.
==== Files / Dirs ====
M-d Searches for the input in all sub-directories to the directory youre in. Files
C-k Kills the currently focused buffer or deletes the file depending on the mode. Files / Buffers
M-m Creates a new sub-directory to the directory youre in Files
OK, so you probably wont get in the habit of using all the commands; thats fine, but some are more important to remember than others, like: Backspace; C-s and C-r; // and ~/; and C-d.
If Ido is getting in your way, remember the fallback commands: C-f for files; C-b for buffers.
==== Work Directory Commands ====
Work directories are recently used directories that Ido caches so the files and directories in them can be quickly recalled. Work directory commands only function in find-file routines, but that goes without saying.
You change the cached directory list by manipulating the variable ido-work-directory-list. If youre tired of Ido caching slow, transient or generally unwanted directories you can add regular expressions to the list in ido-work-directory-list-ignore-regexps to keep Ido from caching them.
Similarly, when you go to the next or previous work directory you can force Ido to disregard directories that do not match your current input. To change this behavior, set ido-work-directory-match-only.
Keybinding Description
M-n / M-p Cycles through the next or previous work directories
M-k Kills (removes) the active work directory from the list.
M-s M-s forces ido to search the list of work directories for the current input.
Using M-s is an excellent way to quickly scan recently used directories for files. You do not have to explicitly type M-s as Ido will automagically start searching after a few seconds of idle time.
You can change the work directory merge delay by modifying the ido-auto-merge-delay-time variable.

View File

@@ -0,0 +1,129 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-06T20:09:15+08:00
====== yasnippet ======
Created Wednesday 06 April 2011
Emacs高效的yasnippet 简单使用和定制
2010年12月24日 星期五 18:16
Emacs高效的yasnippet
====================
Author: Lijunpeng <maillijunpeng@gmail.com>
Date: 2010-12-24 10:28:08 CST
Table of Contents
=================
1 介绍yasnippet
2 安装yasnippet
3 使用yasnippet
4 定制自己的模板
5 再以一个51外部中断函数举例
6 参考资源
1 介绍yasnippet
~~~~~~~~~~~~~~~~
官方地址:[http://code.google.com/p/yasnippet/]
想看原汁原味的介绍建议看官方文档,这里中文简要说明一下:
首先如果你是Emacser而你又没接触过yasnippet请查看这里有一个很hacking的视频。
地址:[http://v.youku.com/v_show/id_XMjMxNDg5MjQ4.html]
YASnippet 是emacs高效一个通用的模板系统。它允许定义缩写并通过[TAB]键自动帮你展开。在我们平常编辑一经常复用的模板是非常有帮助的比如本人平常做Latex
ppt就用到yasnippet就显得非常方便快捷。
2 安装yasnippet
~~~~~~~~~~~~~~~~
Yasnippet的安装详细已经有好多文章介绍并且官方视频里也简洁的演示这里给出最简单步骤
- 下载wget http://yasnippet.googlecode.com/files/yasnippet-bundle-0.6.1c.el.tgz
- 解压并移动emacs路径tar -xvf yasnippet-bundle-0.6.1c.el.tgz && mv yasnippet-bundle.el ~/.emacs.d/plugins
- 编辑.emacs文件(add-to-list 'load-path " ~/.emacs.d/plugins")
(require 'yasnippet-bundle)
- 重启一下emacs,如果emacs设置有启动画面请按下[q]键就可以看到菜单里多一个yasnippet菜单到些安装完毕。
3 使用yasnippet
~~~~~~~~~~~~~~~~
安装好之后我们就可以试试牛力方便的yasnippet
例如编辑一个C文件emacs /tmp/yas_test.c
键入模板关键词inc 然后[TAB]键,就出现有模板选择
键入模板关键词main 然后[TAB]键同样也出现一个我们常用main函数
简单的使用方法就是这样是不是有很hacking的感觉更多细节可以查看yasnippet菜单
4 定制自己的模板
~~~~~~~~~~~~~~~~~
- yasnippet的强大之处于允许用户自定义自己的模板这里介绍它的定制功能并通过latex-mode来演示它是如何高效编辑能力。这里演示用的Tex发行版本是texlive的latex-cjk-all扩展
- ubuntu 可以直接安装sudo apt-get install texlive cjk-latex latex-cjk-all
- 定制自己的模板必须在.emacs配置文件里指定模板的位置,这一步必不可少,所以在.emacs加上
(add-to-list 'load-path " ~/.emacs.d/plugins")
(require 'yasnippet-bundle)
(setq yas/root-directory "~/.emacs.d/snippets")
(yas/load-directory yas/root-directory)
这样.emacs的yasnippet就配置完成了下来就是定制模板缩写词
随便进入Emacs的一个mode模式,我演示这里是latex-mode,然后输入命令[M-x] yas/new-snippet即可在这个模式下建立模板
输入yas/new-snippet命令它会提示文件不存在是否建立这里直接键入[Enter]键,然后输入模块的名字。(注:这里模块的名字就是此模式下的缩写词即关键词)然后出现# -*- mode: snippet -*- 等字符,在这里删除它们,照着这里的演示一步一步来就要可以了。
以新建立一个幻灯片为例子,可以这个来:
1: #contributor : ljp <ljp.gogo@gmail.com>
2: #name : Create a slide frame
3: # --
4:
5: \frame{\frametitle{${1:Slide title}}
6: \pause{}
7: \begin{itemize}
8: \item $0
9: \end{itemize} }
说明snippet的语法变量是以$美元符开始的,根据变量$1 $2 $... 定义顺序光标移动位置,特殊的$0是最后光标停位置
第1行是模板贡献者的一些信息
第2行是模板说明也就是用鼠标点击yasnippet菜单里相应模式的模板的一些文字提示(这里Create a slide frame 就可以知道它是创建一个幻灯片)
第3行是语法要求声明模板内容开始
第4行以后的就是模板的内容了。
5 再以一个51外部中断函数举例
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. emacs /tmp/interrupt.c
2. [M-x] yas/new-snippet ->[Enter]键 -> 创建缩写关键词 interrupt ->[Enter]键
#contributor : ljp <ljp.gogo@gmail.com>
#name : Create a 51 interrupt function
# --
void int${1:变量1}() interrupt ${2:变量2} using ${3:变量3}
{
${0:这里是变量光标最后停留位置}
}
以上在C模式下就可以键入关键词interrupt 然后[TAB]键来创建一个51单片机外部中断
6 参考资源
~~~~~~~~~~~
- 李杀网:[http://xahlee.org/emacs/yasnippet_templates_howto.html]
- YASnippet基础入门:[http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html]
- 官方doc:[http://yasnippet.googlecode.com/svn/trunk/doc/index.html]
- 一个yasnippet模板快速制作PPT演示视频[http://v.youku.com/v_show/id_XMjMxNTQ1NzA4.html]
- 个人代码仓:[https://github.com/live5156go51]
PS: 祝大家对圣诞快乐!

View File

@@ -0,0 +1,56 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-06T21:16:21+08:00
====== auto-complete vs yas ======
Created Wednesday 06 April 2011
auto complete和yasnippet的区别
2009年11月27日 ahei 发表评论 阅读评论
auto-complete和yasnippet是Emacs下两款非常强悍的补全插件那么auto-complete和yasnippet是否就是一对竞争者呢有你没我有我没你
其实不是这样的,它们两个完全能融洽的相处,并且合作的非常愉快。
本质上来说auto complete只是一个补全界面它用来展示其他补全引擎的结果它支持好多补全引擎包括补全全路径文件名的backend补全单独文件名的backend补全当前buffer下单词的backend补全所有buffer下的单词的backend补全Elisp语法的引擎补全yasnippet片段的引擎补全缩写的引擎等等等等当然也包括yasnippet它会把所有的补全引擎的补全结果一起展示出来当然是根据你定义的补全引擎的顺序。
那么我们为什么不直接使用yasnippet而去使用auto complete呢
除了auto complete可以同时利用其他补全引擎的结果还使得使用yasnippet起来更方便。比如在yasnippet中你看不到当前光标出单词是否有它的片段定义你要补全它的时候要按tab而auto complete加了yasnippet的引擎后可以自动提示出当前光标处单词是否有yasnippet的片段定义yasnippet引擎的结果会用特殊的颜色标注这里有代码证明
(defface ac-yasnippet-candidate-face
'((t (:background "sandybrown" :foreground "black")))
"Face for yasnippet candidate.")
(defface ac-yasnippet-selection-face
'((t (:background "coral3" :foreground "white")))
"Face for the yasnippet selected candidate.")
(defvar ac-source-yasnippet
'((candidates . ac-yasnippet-candidate)
(action . yas/expand)
(candidate-face . ac-yasnippet-candidate-face)
(selection-face . ac-yasnippet-selection-face))
"Source for Yasnippet.")
上述代码中的candidate-face表示补全结果的颜色而selection-face表示当你把光标移到这个补全结果上的时候的颜色如下图所示
在auto complete使用yasnippet引擎
在auto complete使用yasnippet引擎
上图中defun和dired都是yasnippet引擎给出来的补全结果其他的则是其他引擎的补全结果yasnippet的补全结果用其他颜色标注而当前所选的yasnippet引擎的补全候选则是用另外一种颜色标注一目了然。
还有比如你有个for的yasnippet片段定义你输入fo的时候在yasnippet中这时候你并不能按tab进行补全但是在auto complete中你加了yasnippet引擎后auto complete会提示出yasnippet的补全结果for就像下面这样
在auto complete使用yasnippet引擎
在auto complete使用yasnippet引擎
这时候你按回车的话会自动扩展yasnippet的for片段的定义变成下面这样
Emacs的超级补全yasnippet
Emacs的超级补全yasnippet
那么auto complete是怎么做到不需要完整输入yasnippet的片段, 只需要输入部分就能补全yasnippet的片段呢? 很简单大家看到上面代码中ac-source-yasnippet的定义就明白了里面有一个(action . yas/expand)你应该猜到了吧它的意思就是当你选中yasnippet的candidate并且按下回车的时候auto complete会去执行那个yas/expand而它正是yasnippet的补全命令。
经上所述通过auto complete你用yasnippet更方便了。
现在你该明白了auto complete和yasnippet的区别了吧。

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@@ -0,0 +1,111 @@
Content-Type: text/x-zim-wiki
Wiki-Format: zim 0.4
Creation-Date: 2011-04-06T20:25:16+08:00
====== example2 ======
Created Wednesday 06 April 2011
http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html
Posted on 30-09-2009
===== YASnippet 基础入门 =====
Filed Under (技术) by waterlin
YASnippet 是 Emacs 的一个缩略词 (abbreviation) 模板替换系统,可以把一个预先设定好的缩略词扩展成模板。刚开始用 YASnippet 的时候,一般感觉无从下手,现在就简单介绍一下 YASnippet 最基本的使用方法。
YASnippet 的安装
YASnippet 有两种安装方法,可以视个人情况选用。
1). 单个 yasnippet-bundle.el 文件安装方式
如果想快速地试用、了解一下 YASnippet 这个系统,从官方网站下载 yasnippet-bundle.el 这个文件,放到 Emacs 扩展目录里,然后把下面的代码放到 .emacs 文件里:
(add-to-list 'load-path
"~/.emacs.d/plugins")
(require 'yasnippet-bundle)
本方法适合于快速地试用一下 YASnippet 系统,当然,如果你需要修改模板或是定制自己的扩展模板,你就需要用下面介绍的完全安装方法。
2). 完全安装方法
需要完全安装 YASnippet 的话,先从官方网站上下载完整的 yasnippet-x.y.z.tar.bz2 包,把包解压放到 Emacs 的扩展目录,然后添加下面的语句到 .emacs 文件里:
(add-to-list 'load-path
"~/.emacs.d/plugins/yasnippet-x.y.z")
(require 'yasnippet) ;; not yasnippet-bundle
(yas/initialize)
(yas/load-directory "~/.emacs.d/plugins/yasnippet-x.y.z/snippets")
YASnippet 的基本使用方法
正确安装好 YASnippet 后,重新启动 Emacs 就可以看到菜单栏里多了一个 YASnippet 的菜单图1所示
YASnippetMultiModeCopyright.png
mini buffer 上也会显示出类似于 (org yas) 的字样(这里是指 yas 作为子模式存在于主模式 org 里如图2所示。
YASnippetMultiModeCopyright.png
总的来说,正确安装好 YASnippet 后,只要输入缩略词,然后用 __TAB 键或是 C-i __就可以完成扩展了。
在 Emacs 启动后YASnippet 模式是作为一个子模式 (minor mode) 存在于各个模式之中。要用 YASnippet 进行缩略词补全有好多种方法,最常用的补全方法有三种:
输入一个缩写词 (abbrev),然后用 snippet 的触发键 (trigger key) 来补全。这个键默认是 TAB 或是 C-i当然也可以用命令 M-x yas/expand 来进行扩展。
用命令 M-x yas/insert-snippet 直接进行输入,输入完这个命令后,会弹出一个补全窗口,提示当前主模式下可以补全的模板。
直接从菜单栏里的 YASnippet 里,选择内容进行输入。
有关 YASnippet 使用的更详细叙述,可以参考官方文档 Expanding snippets。
YASnippet 个性化定制的命令
虽然 YASnippet 已经自带了许多常用的扩展模板,但是很多情况下,我们需要根据自己的实际情况,来进行模板定制。以下是扩展 YASnippet 常用的一些命令:
用命令 M-x yas/new-snippet 就可以新建一个扩展模板 (snippet)YASnippet 会自动提示存放该模板的最佳目录。
用命令 M-x yas/find-snippets 可以查找 snippet 文件,默认的目录是当前主模式下的模板文件 (snippet file) 的存放目录。
用命令 M-x yas/visit-snippet-file 可以通过弹出的对话框来寻找你需要的模板文件 (snippet file),在对话框里选择一个选项,就会打开这个模板文件 (snippet file) 来让你编辑。
org 里的 YASnippet 使用实例
下面就用一个实例,结合 YASnippet 的语法规则,来简单介绍一下 YASnippet 最基本的使用。
我在 org 模式里写笔记或是发布网页的时候,经常需要添加一个有关版权声明的文字(或为公司,或为自己)。因为公司和私人的内容都混在一起,所以我需要有多个模板。下面就以添加我个人版权声明的模板为例,介绍一下配置 YASnippet 的完整步骤。
1). 添加一个有关个人版权的 snippet
首先,在 org 模式里,用命令 M-x yas/new-snippet 来添加一个 snippet输入你想要的 snippet 名称,我这里输入
Copyright
YASnippet 会自动生成一个名叫 Copyright.yasnippet 的文件,生成的内容如下:
# -*- mode: snippet -*-
# name: Copyright
# key:
# binding: "keybinding"
# expand-env: ((some-var some-value))
# --
2). 现在我们只需要根据 YASnippet 的相关语法来修改这个文件就可以了。上面文件关键词的基本语法含义如下:
# name: 显示在弹出菜单里的 snippet 名称
# key: 缩略词,即你在用 TAB 键进行扩展前输入的关键词,如果不设定,则把这个关键词默认为本文件名
# binding: 设置使用哪个组合键来直接插入这个 snippet对于比较常用的模板内容比较有用
# expand-env: 用 elisp 重新设置一些环境变量
# 表示在这一行之上的全是注释
3). 因为我们这里是配置一个最简单的模板,所以,我们删掉 # key:# binding:# expand-env: 这三个高级定制功能。最后,我们写成类似下面的东西:
# -*- mode: snippet -*-
# name: Copyright
# --
#+BEGIN_HTML
<p style="TEXT-ALIGN: center">
原创文章,如转载请注明:转载自细节之锤 [ <a href="http://blog.waterlin.org/">http://blog.waterlin.org/</a> ]
</p>
<p style="TEXT-ALIGN: center">
Copyright © WaterLin.org. All rights reserved.
</p>
#+END_HTML
4). 重启 Emacs 让修改生效,然后我们再回到 org 文件里,这个时候,可以直接输入一个 Copyright (注意:缩略词大小写敏感),然后用 C-i 进行替换(原本可以用 TAB 键的,但是 Emacs23 里的 org 模式把 TAB 键给霸占了),就可以把 Copyright 这个词替换成上面用 html 写成的版权声明。
在 org 模式里,我们可以用同样的方法来插入 #+begin_example#+begin_ditaa#+begin_dot#+begin_src 等标记,这样可以节省一大笔时间。
一般来讲,用 YASnippet 来进行替换与自动插入,比直接用 elisp 写一个函数、命令来进行插入要简单、方便得多,并且容易管理。
YASnippet 的模板语言 (Template syntax) 还有着更加灵活的用法,参见官方文档 Writing snippets。

View File

@@ -0,0 +1,445 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" lang="en-US"><head profile="http://gmpg.org/xfn/11">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>浏忙大爆炸 » Blog Archive » YASnippet 基础入门</title>
<meta name="generator" content="WordPress 3.1"> <!-- leave this for stats -->
<link rel="stylesheet" href="emacs-yasnippet-basic-usage_files/style.css" type="text/css" media="screen">
<link rel="alternate" type="application/rss+xml" title="浏忙大爆炸 RSS Feed" href="http://blog.waterlin.org/feed">
<link rel="pingback" href="http://blog.waterlin.org/xmlrpc.php">
<!--[if IE 6]>
<link rel="stylesheet" href="http://waterlin.cookwhy.com/wp-content/themes/waterlinorg/styleie.css" type="text/css" media="screen" />
<![endif]-->
<link rel="alternate" type="application/rss+xml" title="浏忙大爆炸 » YASnippet 基础入门 Comments Feed" href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html/feed">
<link rel="EditURI" type="application/rsd+xml" title="RSD" href="http://blog.waterlin.org/xmlrpc.php?rsd">
<link rel="wlwmanifest" type="application/wlwmanifest+xml" href="http://blog.waterlin.org/wp-includes/wlwmanifest.xml">
<link rel="index" title="浏忙大爆炸" href="http://blog.waterlin.org/">
<link rel="start" title="我对11月份广州房价下跌的理解" href="http://blog.waterlin.org/articles/%e6%88%91%e5%af%b911%e6%9c%88%e4%bb%bd%e5%b9%bf%e5%b7%9e%e6%88%bf%e4%bb%b7%e4%b8%8b%e8%b7%8c%e7%9a%84%e7%90%86%e8%a7%a3.html">
<link rel="prev" title="用 org 把选定内容发布成 html 页面" href="http://blog.waterlin.org/articles/org-export-region-as-html.html">
<link rel="next" title="把 org 文档发布成网页工程的方法" href="http://blog.waterlin.org/articles/publish-org-files-to-html-project.html">
<meta name="generator" content="WordPress 3.1">
<link rel="canonical" href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html">
<link rel="shortlink" href="http://blog.waterlin.org/?p=79923">
<link rel="shortcut icon" href="http://blog.waterlin.org/articles/favicon.ico">
</head>
<body>
<center>
<div id="page">
<div id="header">
<div id="header_top">
<div id="menu_search_box">
<form method="get" id="searchform" style="display:inline;" action="http://blog.waterlin.org/">
Search:&nbsp;
<input class="s" name="s" id="s" type="text">&nbsp;
<input src="emacs-yasnippet-basic-usage_files/go.gif" value="Submit" class="sub" align="top" type="image">
</form>
</div>
<div id="header_title">
浏忙大爆炸&nbsp;|
<span>源于理工科男的烂笔头情结</span>
</div>
</div>
<div id="header_end">
<div id="menu">
<div id="menu_pad">
<div id="menu_items">
<div class="no_bg">&nbsp;&nbsp;|&nbsp;</div><div><a href="http://blog.waterlin.org/">博客</a></div>
<div class="no_bg">&nbsp;&nbsp;|&nbsp;</div><div><a href="http://en.waterlin.org/">English</a></div>
<div class="no_bg">&nbsp;&nbsp;|&nbsp;</div><div><a href="http://cn.waterlin.org/">首页</a></div>
<div class="no_bg">&nbsp;&nbsp;|&nbsp;</div><div><a href="http://blog.waterlin.org/contactme">留言给我</a></div>
<div class="no_bg">&nbsp;&nbsp;|&nbsp;</div><div><a href="http://blog.waterlin.org/about-2">关于</a></div>
</div>
</div>
</div>
</div>
</div>
<div>
<!-- Alimama ads -->
<!--
<script type="text/JavaScript">
alimama_pid="mm_12493040_1648461_5980954";
alimama_type="f";
alimama_sizecode ="tl_3x3_12";
alimama_fontsize=12;
alimama_bordercolor="FFFFFF";
alimama_bgcolor="E5E5E5";
alimama_titlecolor="0000FF";
alimama_underline=0;
alimama_height=62;
alimama_width=972;
</script>
<script src="http://a.alimama.cn/inf.js" type=text/javascript>
</script>
-->
</div>
<div id="blog">
<div id="blog_pad">
<div id="blog_left">
<div class="item_class">
<div class="item_class_title">
<div class="item_class_title_text">
<div class="titles">
<div class="top_title_top">Posted on 30-09-2009</div>
<div class="top_title"><a href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html" rel="bookmark" title="Permanent Link to YASnippet 基础入门">YASnippet 基础入门</a></div>
<div class="end_title">Filed Under (<a href="http://blog.waterlin.org/category/%e6%8a%80%e6%9c%af" title="View all posts in 技术" rel="category tag">技术</a>) by waterlin</div>
</div>
</div>
</div>
<div class="item_class_text">
<!-- add google ads -->
<script type="text/javascript"><!--
google_ad_client = "pub-3004770317513210";
/* 468x15, black link, 创建于 09-9-6 */
google_ad_slot = "9565258986";
google_ad_width = 468;
google_ad_height = 15;
//-->
</script>
<script type="text/javascript" src="emacs-yasnippet-basic-usage_files/show_ads.js">
</script><ins style="display:inline-table;border:none;height:15px;margin:0;padding:0;position:relative;visibility:visible;width:468px"><ins id="aswift_0_anchor" style="display:block;border:none;height:15px;margin:0;padding:0;position:relative;visibility:visible;width:468px"><iframe allowtransparency="true" hspace="0" marginwidth="0" marginheight="0" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){i+='.call';setTimeout(h,0)}else if(h.match){i+='.nav';w.location.replace(h)}s.log&amp;&amp;s.log.push(i)}" vspace="0" id="aswift_0" name="aswift_0" style="left: 0pt; position: absolute; top: 0pt;" frameborder="0" height="15" scrolling="no" width="468"></iframe></ins></ins>
<!-- add google ads -->
<p><a href="http://code.google.com/p/yasnippet/">YASnippet</a> 是 Emacs 的一个缩略词 (abbreviation) 模板替换系统,可以把一个预先设定好的缩略词扩展成模板。刚开始用 YASnippet 的时候,一般感觉无从下手,现在就简单介绍一下 YASnippet 最基本的使用方法。</p>
<ol>
<li>YASnippet 的安装
<p>YASnippet 有两种安装方法,可以视个人情况选用。</p>
<p>1). 单个 yasnippet-bundle.el 文件安装方式</p>
<p>如果想快速地试用、了解一下 YASnippet 这个系统,从官方网站下载 <a href="http://yasnippet.googlecode.com/files/yasnippet-bundle-0.6.1c.el.tgz">yasnippet-bundle.el</a> 这个文件,放到 Emacs 扩展目录里,然后把下面的代码放到 .emacs 文件里:</p>
<pre>(add-to-list 'load-path
<span>"~/.emacs.d/plugins"</span>)
(<span>require</span> '<span>yasnippet-bundle</span>)
</pre>
<p>本方法适合于快速地试用一下 YASnippet 系统,当然,如果你需要修改模板或是定制自己的扩展模板,你就需要用下面介绍的完全安装方法。</p>
<p>2). 完全安装方法</p>
<p>需要完全安装 YASnippet 的话,先从官方网站上下载完整的 <a href="http://yasnippet.googlecode.com/files/yasnippet-0.6.1c.tar.bz2">yasnippet-x.y.z.tar.bz2</a> 包,把包解压放到 Emacs 的扩展目录,然后添加下面的语句到 .emacs 文件里:</p>
<pre>(add-to-list 'load-path
<span>"~/.emacs.d/plugins/yasnippet-x.y.z"</span>)
(<span>require</span> '<span>yasnippet</span>) <span>;; </span><span>not yasnippet-bundle
</span>(yas/initialize)
(yas/load-directory <span>"~/.emacs.d/plugins/yasnippet-x.y.z/snippets"</span>)
</pre>
</li>
<li>YASnippet 的基本使用方法
<p>正确安装好 YASnippet 后,重新启动 Emacs 就可以看到菜单栏里多了一个 YASnippet 的菜单图1所示</p>
<p><img src="emacs-yasnippet-basic-usage_files/yasnippetmultimodecopyright.png" alt="YASnippetMultiModeCopyright.png" height="379"></p>
<p>mini buffer 上也会显示出类似于 (org yas) 的字样(这里是指 yas 作为子模式存在于主模式 org 里如图2所示。</p>
<p><img src="emacs-yasnippet-basic-usage_files/yasnippetmultimode.png" alt="YASnippetMultiModeCopyright.png" height="67"></p>
<p>总的来说,正确安装好 YASnippet 后,只要输入缩略词,然后用 TAB 键或是 C-i 就可以完成扩展了。</p>
<p>在 Emacs 启动后YASnippet 模式是作为一个子模式 (minor mode) 存在于各个模式之中。要用 YASnippet 进行缩略词补全有好多种方法,最常用的补全方法有三种:</p>
<ul>
<li>输入一个缩写词 (abbrev),然后用 snippet 的触发键 (trigger key) 来补全。这个键默认是 TAB 或是 C-i当然也可以用命令 M-x yas/expand 来进行扩展。</li>
<li>用命令 M-x yas/insert-snippet 直接进行输入,输入完这个命令后,会弹出一个补全窗口,提示当前主模式下可以补全的模板。</li>
<li>直接从菜单栏里的 YASnippet 里,选择内容进行输入。</li>
</ul>
<p>有关 YASnippet 使用的更详细叙述,可以参考<a href="http://yasnippet.googlecode.com/svn/trunk/doc/snippet-expansion.html">官方文档 Expanding snippets</a></p>
</li>
<li>YASnippet 个性化定制的命令
<p>虽然 YASnippet 已经自带了许多常用的扩展模板,但是很多情况下,我们需要根据自己的实际情况,来进行模板定制。以下是扩展 YASnippet 常用的一些命令:</p>
<ul>
<li>用命令 M-x yas/new-snippet 就可以新建一个扩展模板 (snippet)YASnippet 会自动提示存放该模板的最佳目录。</li>
<li>用命令 M-x yas/find-snippets 可以查找 snippet 文件,默认的目录是当前主模式下的模板文件 (snippet file) 的存放目录。</li>
<li>用命令 M-x yas/visit-snippet-file 可以通过弹出的对话框来寻找你需要的模板文件 (snippet file),在对话框里选择一个选项,就会打开这个模板文件 (snippet file) 来让你编辑。</li>
</ul>
</li>
<li>org 里的 YASnippet 使用实例
<p>下面就用一个实例,结合 YASnippet 的语法规则,来简单介绍一下 YASnippet 最基本的使用。</p>
<p>我在 org 模式里写笔记或是发布网页的时候,经常需要添加一个有关版权声明的文字(或为公司,或为自己)。因为公司和私人的内容都混在一起,所以我需要有多个模板。下面就以添加我个人版权声明的模板为例,介绍一下配置 YASnippet 的完整步骤。</p>
<p>1). 添加一个有关个人版权的 snippet</p>
<p>首先,在 org 模式里,用命令 M-x yas/new-snippet 来添加一个 snippet输入你想要的 snippet 名称,我这里输入</p>
<pre> Copyright
</pre>
<p>YASnippet 会自动生成一个名叫 Copyright.yasnippet 的文件,生成的内容如下:</p>
<pre> # -*- mode: snippet -*-
# name: Copyright
# key:
# binding: "keybinding"
# expand-env: ((some-var some-value))
# --
</pre>
<p>2). 现在我们只需要根据 YASnippet 的相关语法来修改这个文件就可以了。上面文件关键词的基本语法含义如下:</p>
<ul>
<li># name: 显示在弹出菜单里的 snippet 名称</li>
<li># key: 缩略词,即你在用 TAB 键进行扩展前输入的关键词,如果不设定,则把这个关键词默认为本文件名</li>
<li># binding: 设置使用哪个组合键来直接插入这个 snippet对于比较常用的模板内容比较有用</li>
<li># expand-env: 用 elisp 重新设置一些环境变量</li>
<li># 表示在这一行之上的全是注释</li>
</ul>
<p>3). 因为我们这里是配置一个最简单的模板,所以,我们删掉 # key:# binding:# expand-env: 这三个高级定制功能。最后,我们写成类似下面的东西:</p>
<pre> # -*- mode: snippet -*-
# name: Copyright
# --
#+BEGIN_HTML
&lt;p style="TEXT-ALIGN: center"&gt;
原创文章,如转载请注明:转载自细节之锤 [ &lt;a href="http://blog.waterlin.org/"&gt;http://blog.waterlin.org/&lt;/a&gt; ]
&lt;/p&gt;
&lt;p style="TEXT-ALIGN: center"&gt;
Copyright © WaterLin.org. All rights reserved.
&lt;/p&gt;
#+END_HTML
</pre>
<p>4). 重启 Emacs 让修改生效,然后我们再回到 org 文件里,这个时候,可以直接输入一个 Copyright
(注意:缩略词大小写敏感),然后用 C-i 进行替换(原本可以用 TAB 键的,但是 Emacs23 里的 org 模式把 TAB
键给霸占了),就可以把 Copyright 这个词替换成上面用 html 写成的版权声明。</p>
<p>在 org 模式里,我们可以用同样的方法来插入 #+begin_example#+begin_ditaa#+begin_dot#+begin_src 等标记,这样可以节省一大笔时间。</p>
</li>
</ol>
<p>一般来讲,用 YASnippet 来进行替换与自动插入,比直接用 elisp 写一个函数、命令来进行插入要简单、方便得多,并且容易管理。</p>
<p>YASnippet 的模板语言 (Template syntax) 还有着更加灵活的用法,参见<a href="http://yasnippet.googlecode.com/svn/trunk/doc/snippet-development.html">官方文档 Writing snippets</a></p>
<p>原创文章,如转载请注明:转载自细节之锤 [ <a href="http://blog.waterlin.org/">http://blog.waterlin.org/</a> ]</p>
<p>Copyright © WaterLin.org. All rights reserved.</p>
</div>
<div class="item_class_panel">
<div>
<span class="panel_comm"><a href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html#comments" title="Comment on YASnippet 基础入门">(2) Comments</a></span>&nbsp;&nbsp;&nbsp;
<a href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html" class="panel_read">Read More</a>&nbsp;&nbsp;&nbsp;
</div>
</div>
</div>
<!-- You can start editing here. -->
<div id="blog_comm">
<a id="comments"></a>
<h2>Comments</h2>
<div class="comm_panel">
<b><a href="http://blog.waterlin.org/articles/three-ways-to-generate-class-diagram.html" rel="external nofollow" class="url">浏忙大爆炸 » Blog Archive » 生成 C++ 类文档及关系图的方法</a></b> on 15 September, 2010 at 2:28 pm #
</div>
<div class="comm_text">
<p>[...] vim, Emacs 这类文本编辑器里,则可以很自然地使用宏操作来插入 Doxygen 注释;如果是用
Visual Studio 的话呢,也是可以用 DoxyComment add-in for Visual Studio 2005 [...]</p>
</div>
<br>
<div class="comm_panel">
<b><a href="http://imljp.info/?p=172" rel="external nofollow" class="url">/home/ljp » Emacs yasnippet hacking</a></b> on 17 January, 2011 at 9:07 am #
</div>
<div class="comm_text">
<p>[...] YASnippet基础入门:<a href="http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html" rel="nofollow">http://blog.waterlin.org/articles/emacs-yasnippet-basic-usage.html</a> [...]</p>
</div>
<br>
<div id="comments_from_bg">
<a id="respond"></a>
<div id="comm_post_title">
Post a Comment
</div>
<div id="comm_post_form">
<form action="http://blog.waterlin.org/wp-comments-post.php" method="post" id="commentform">
<table cellpadding="0" cellspacing="0">
<tbody><tr>
<td class="right">
Name:
</td>
<td>
<input name="author" id="author" size="22" tabindex="1" type="text">
</td>
</tr>
<tr>
<td class="right">
Email:
</td>
<td>
<input name="email" id="email" size="22" tabindex="2" type="text">
</td>
</tr>
<tr>
<td class="right">
Website:
</td>
<td>
<input name="url" id="url" size="22" tabindex="3" type="text">
</td>
</tr>
<!--<p><small><strong>XHTML:</strong> You can use these tags: &lt;a href=&quot;&quot; title=&quot;&quot;&gt; &lt;abbr title=&quot;&quot;&gt; &lt;acronym title=&quot;&quot;&gt; &lt;b&gt; &lt;blockquote cite=&quot;&quot;&gt; &lt;cite&gt; &lt;code&gt; &lt;del datetime=&quot;&quot;&gt; &lt;em&gt; &lt;i&gt; &lt;q cite=&quot;&quot;&gt; &lt;strike&gt; &lt;strong&gt; </small></p>-->
<tr>
<td class="right">
Comments:
</td>
<td>
<textarea name="comment" id="comment" cols="40" rows="5" tabindex="4"></textarea>
</td>
</tr>
<tr>
<td>
</td>
<td>
<input class="sub" src="emacs-yasnippet-basic-usage_files/sub.gif" type="image">
</td>
</tr>
</tbody></table>
<input name="comment_post_ID" value="79923" type="hidden">
<p style="display: none;"><input id="akismet_comment_nonce" name="akismet_comment_nonce" value="ab01027976" type="hidden"></p>
</form>
</div>
</div>
</div>
</div>
<div id="blog_right">
<div id="blog_right_body">
<div id="sidebar">
<div id="sidebar_left">
<ul>
<li>
<h2>广而告之</h2>
<script type="text/javascript"><!--
google_ad_client = "pub-3004770317513210";
/* 160x600, 创建于 09-8-10 */
google_ad_slot = "5265692676";
google_ad_width = 160;
google_ad_height = 600;
//-->
</script>
<script type="text/javascript" src="emacs-yasnippet-basic-usage_files/show_ads.js">
</script><ins style="display:inline-table;border:none;height:600px;margin:0;padding:0;position:relative;visibility:visible;width:160px"><ins id="aswift_1_anchor" style="display:block;border:none;height:600px;margin:0;padding:0;position:relative;visibility:visible;width:160px"><iframe allowtransparency="true" hspace="0" marginwidth="0" marginheight="0" onload="var i=this.id,s=window.google_iframe_oncopy,H=s&amp;&amp;s.handlers,h=H&amp;&amp;H[i],w=this.contentWindow,d;try{d=w.document}catch(e){}if(h&amp;&amp;d&amp;&amp;(!d.body||!d.body.firstChild)){if(h.call){i+='.call';setTimeout(h,0)}else if(h.match){i+='.nav';w.location.replace(h)}s.log&amp;&amp;s.log.push(i)}" vspace="0" id="aswift_1" name="aswift_1" style="left: 0pt; position: absolute; top: 0pt;" frameborder="0" height="600" scrolling="no" width="160"></iframe></ins></ins>
</li>
</ul>
<ul>
<li id="archives-3" class="widget widget_archive"><h2 class="widgettitle">文章索引模板</h2>
<ul>
<li><a href="http://blog.waterlin.org/articles/2011/04" title="April 2011">April 2011</a></li>
<li><a href="http://blog.waterlin.org/articles/2011/03" title="March 2011">March 2011</a></li>
<li><a href="http://blog.waterlin.org/articles/2011/02" title="February 2011">February 2011</a></li>
<li><a href="http://blog.waterlin.org/articles/2011/01" title="January 2011">January 2011</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/12" title="December 2010">December 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/11" title="November 2010">November 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/10" title="October 2010">October 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/09" title="September 2010">September 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/08" title="August 2010">August 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/07" title="July 2010">July 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/06" title="June 2010">June 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/05" title="May 2010">May 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/04" title="April 2010">April 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/03" title="March 2010">March 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/02" title="February 2010">February 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2010/01" title="January 2010">January 2010</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/12" title="December 2009">December 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/11" title="November 2009">November 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/10" title="October 2009">October 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/09" title="September 2009">September 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/08" title="August 2009">August 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/07" title="July 2009">July 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/06" title="June 2009">June 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/05" title="May 2009">May 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/04" title="April 2009">April 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/03" title="March 2009">March 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/02" title="February 2009">February 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2009/01" title="January 2009">January 2009</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/12" title="December 2008">December 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/11" title="November 2008">November 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/10" title="October 2008">October 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/09" title="September 2008">September 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/08" title="August 2008">August 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/07" title="July 2008">July 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/06" title="June 2008">June 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/05" title="May 2008">May 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/04" title="April 2008">April 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/03" title="March 2008">March 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/02" title="February 2008">February 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2008/01" title="January 2008">January 2008</a></li>
<li><a href="http://blog.waterlin.org/articles/2007/12" title="December 2007">December 2007</a></li>
</ul>
</li>
</ul>
</div>
<div id="sidebar_right">
<ul>
<li id="tag_cloud-3" class="widget widget_tag_cloud"><h2 class="widgettitle">标签</h2>
<div class="tagcloud"><a href="http://blog.waterlin.org/tag/c" class="tag-link-43" title="23 topics" style="font-size: 16.7399pt;">C++</a>
<a href="http://blog.waterlin.org/tag/conkeror" class="tag-link-44" title="3 topics" style="font-size: 10.4277pt;">Conkeror</a>
<a href="http://blog.waterlin.org/tag/cygwin" class="tag-link-45" title="5 topics" style="font-size: 11.8844pt;">Cygwin</a>
<a href="http://blog.waterlin.org/tag/drupal" class="tag-link-46" title="11 topics" style="font-size: 14.3121pt;">Drupal</a>
<a href="http://blog.waterlin.org/tag/emacs" class="tag-link-47" title="71 topics" style="font-size: 20.6243pt;">Emacs</a>
<a href="http://blog.waterlin.org/tag/firefox" class="tag-link-49" title="22 topics" style="font-size: 16.578pt;">Firefox</a>
<a href="http://blog.waterlin.org/tag/google" class="tag-link-51" title="13 topics" style="font-size: 14.8786pt;">Google</a>
<a href="http://blog.waterlin.org/tag/gtd" class="tag-link-52" title="8 topics" style="font-size: 13.2601pt;">GTD</a>
<a href="http://blog.waterlin.org/tag/lamp" class="tag-link-53" title="7 topics" style="font-size: 12.8555pt;">LAMP</a>
<a href="http://blog.waterlin.org/tag/linux" class="tag-link-54" title="7 topics" style="font-size: 12.8555pt;">Linux</a>
<a href="http://blog.waterlin.org/tag/mingw" class="tag-link-55" title="5 topics" style="font-size: 11.8844pt;">MinGW</a>
<a href="http://blog.waterlin.org/tag/perl" class="tag-link-56" title="32 topics" style="font-size: 17.8728pt;">Perl</a>
<a href="http://blog.waterlin.org/tag/phpbb" class="tag-link-57" title="3 topics" style="font-size: 10.4277pt;">phpBB</a>
<a href="http://blog.waterlin.org/tag/tex" class="tag-link-58" title="3 topics" style="font-size: 10.4277pt;">TeX</a>
<a href="http://blog.waterlin.org/tag/thunderbird" class="tag-link-59" title="6 topics" style="font-size: 12.4509pt;">Thunderbird</a>
<a href="http://blog.waterlin.org/tag/usenet" class="tag-link-61" title="4 topics" style="font-size: 11.237pt;">Usenet</a>
<a href="http://blog.waterlin.org/tag/vim" class="tag-link-62" title="2 topics" style="font-size: 9.45665pt;">Vim</a>
<a href="http://blog.waterlin.org/tag/windows" class="tag-link-63" title="11 topics" style="font-size: 14.3121pt;">Windows</a>
<a href="http://blog.waterlin.org/tag/wordpress" class="tag-link-65" title="18 topics" style="font-size: 15.9306pt;">Wordpress</a>
<a href="http://blog.waterlin.org/tag/xulrunner" class="tag-link-66" title="1 topic" style="font-size: 8pt;">XULRunner</a>
<a href="http://blog.waterlin.org/tag/zen-cart" class="tag-link-67" title="9 topics" style="font-size: 13.6647pt;">Zen-cart</a>
<a href="http://blog.waterlin.org/tag/%e5%95%86%e4%b8%9a" class="tag-link-71" title="9 topics" style="font-size: 13.6647pt;">商业</a>
<a href="http://blog.waterlin.org/tag/%e5%b7%b2%e6%8a%a5" class="tag-link-75" title="18 topics" style="font-size: 15.9306pt;">已报</a>
<a href="http://blog.waterlin.org/tag/%e6%8a%80%e6%9c%af" class="tag-link-74" title="22 topics" style="font-size: 16.578pt;">技术</a>
<a href="http://blog.waterlin.org/tag/%e6%96%87%e5%8c%96" class="tag-link-70" title="15 topics" style="font-size: 15.2832pt;">文化</a>
<a href="http://blog.waterlin.org/tag/%e7%90%86%e8%b4%a2" class="tag-link-76" title="1 topic" style="font-size: 8pt;">理财</a>
<a href="http://blog.waterlin.org/tag/%e7%94%9f%e6%b4%bb" class="tag-link-68" title="37 topics" style="font-size: 18.3584pt;">生活</a>
<a href="http://blog.waterlin.org/tag/%e7%bb%8f%e6%b5%8e" class="tag-link-69" title="4 topics" style="font-size: 11.237pt;">经济</a>
<a href="http://blog.waterlin.org/tag/%e8%bd%af%e4%bb%b6" class="tag-link-73" title="106 topics" style="font-size: 22pt;">软件</a></div>
</li>
<li id="html_javascript_adder-3" class="widget widget_html_javascript_adder">
<!-- Start - HTML Javascript Adder plugin v3.1.1 -->
<h2 class="widgettitle">订阅我吧</h2>
<div class="hjawidget">
<!-- Feedsky FEED发布代码开始 -->
<!-- FEED自动发现标记开始 -->
<link title="RSS 2.0" type="application/rss+xml" href="http://feed.feedsky.com/WaterDrop" rel="alternate">
<!-- FEED自动发现标记结束 -->
<script language="javascript"><!--
main_sub="";
more_subs="zhuaxia_01,pageflakes_01,rojo_01,google_01,netvibes_01,yahoo_01,newsgator_01,bloglines_01,xianguo_01,nazha_01,youdao_01,qq_01,douban_01";
is_new="yes";
--> </script>
<script language="javascript" src="emacs-yasnippet-basic-usage_files/publishlist_v2.html"></script><a href="http://www.zhuaxia.com/add_channel.php?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_zhuaxia.gif" alt="抓虾" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.pageflakes.com/subscribe.aspx?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_pageflakes.gif" alt="pageflakes" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.rojo.com/add-subscription?resource=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_rojo.gif" alt="Rojo" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://fusion.google.com/add?feedurl=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_google.gif" alt="google reader" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.netvibes.com/subscribe.php?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_netvibes.gif" alt="netvibes" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://add.my.yahoo.com/rss?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_yahoo.gif" alt="my yahoo" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.newsgator.com/ngs/subscriber/subfext.aspx?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_newsgator.gif" alt="newsgator" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.bloglines.com/sub/http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_bloglines.gif" alt="bloglines" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://www.xianguo.com/subscribe.php?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_xianguo.gif" alt="鲜果" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://inezha.com/add?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_nazha.gif" alt="哪吒" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://reader.youdao.com/b.do?keyfrom=feedsky&amp;url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_youdao.gif" alt="有道" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://mail.qq.com/cgi-bin/feed?u=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_qq.gif" alt="QQ邮箱" style="margin-bottom: 3px;" border="0" vspace="2"></a><br><a href="http://9.douban.com/reader/subscribe?url=http://feed.feedsky.com/WaterDrop" target="_blank"><img src="emacs-yasnippet-basic-usage_files/icon_subshot01_douban.gif" alt="九点" style="margin-bottom: 3px;" border="0" vspace="2"></a>
<!-- Feedsky FEED发布代码结束 -->
<a href="http://www.aakashweb.com/" target="_blank" rel="follow" title="Added with HTML Javascript Adder Wordpress plugin" style="float: right; font-size: 50%;"> ?</a>
</div>
<!-- End - HTML Javascript Adder plugin v3.1.1 -->
</li>
</ul>
</div>
</div>
</div> </div>
</div>
</div>
<div id="footer">
<div id="footer_text">
Copyright © 浏忙大爆炸. All rights reserved. 由 <a href="http://cookwhy.com/">酷歪基地</a> 提供 <a href="http://www.wordpress.org/">WordPress</a> 博客服务<br>
Designed By : <span><a href="http://www.askgraphics.com/" title="Website design">AskGraphics</a></span>
</div>
</div>
</div>
</center>
</body></html>

Binary file not shown.

After

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 705 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 811 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 900 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 687 B

Some files were not shown because too many files have changed in this diff Show More