我的 GNU Emacs 配置“程序” 续 完

plugins.el

=plugins.el= 的作用是引用各种网上下载的第三方扩展。简单来说就是成堆成堆的 =(require 'something)= 。由于 =require= 函数只需要一个参数,这意味着我们将只需要一个一维的 =list= ,这样会比 keybinding.el 的情况更简单一些。下面是 =require-extensions= 函数。

 

(defun require-extensions (action lst)
""
(mapcar (lambda(ext)
"" (funcall action ext)) lst))


有了这个函数,我们就可以进行非常简单的工作了——删掉 =require= ,换成 =list= 。

 

 

代码
(require-extensions 'require
(list
'tabbar
'switch-window
'thing-edit
'second-sel
'browse-kill-ring+
'bbdb
'gnuplot
'muse-mode
'ibuffer
'w3m-load
'rect-mark
'ido
'multi-term
'lusty-explorer
'oddmuse
'emaci
'move-text
'uniquify
'hide-region
))

 


至于每一个扩展的个别配置,就分别写在文件的后面了。

 

可以看到,我用的扩展并不多。因为每天工作当中基本就在 =shell-mode= , =sh-mode= 和 =org-mode= 这几个模式当中打转转。下班之后大概是用 =emacs-lisp-mode= 。

outline-minor-mode

在这里比较值得一提的还有一个 =outline-minor-mode= 的设置。这个模式实在是一个很有用的东西。甚至在 =shell-mode= 里面我都会打开它。但是针对每一个不同的 mode 设置各自的 =outline-regexp= , 对,我是想说是挺烦人的。也许你们要比我 nice,好让人羡慕啊。 好,言归正传,我选择写一个函数来搞定它。我叫它 =set-outline-minor-mode-regexp= 。 只是,这次,事情稍微有点复杂。

首先这个函数的环境比较特殊,所以相对来说就会比较复杂。因为他是用在 =add-hook= 函数当中的,这意味着我没有机会直接传递我要的数据给 =set-outline-minor-mode-regexp= 。我需要绕一下,用一个全局变量 =outline-minor-mode-list= 来存储数据,并且这次的数据会是一个二维的 =list= ,所以处理也会复杂一些。

 

(setq outline-minor-mode-list
(list
'(emacs-lisp-mode "(defun")
'(shell-mode ".*[bB]ash.*[#\$] ")
'(sh-mode "function")

))

这里就是我说的这个函数,也许你们可以帮我把它写的更简单一些。

 

 

代码
(defun set-outline-minor-mode-regexp ()
""
(outline
-minor-mode 1)
(let ((regexp
-list (append outline-minor-mode-list nil))
(find
-regexp
(lambda (lst)
""
(let ((innerList (car lst)))
(
if innerList
(
if (string= (car innerList) major-mode)
(car (cdr innerList))
(progn (pop lst)
(funcall find
-regexp lst))))
))))
(make
-local-variable 'outline-regexp)
(setq outline-regexp (funcall find-regexp regexp-list)))

(
set-key-bindings 'local-set-key
(list
(list (kbd
"C-c C-t") 'hide-body)
(list (kbd "C-c C-a") 'show-all)
(list (kbd "C-c C-e") 'show-entry)
; (kbd "C-c C-d") 和 shell-mode 冲突,所以继续沿用 C-c @ C-d,不做自定义
))
)

然后针对每一个需要的模式添加 hook就行了。

 

 

(add-hook 'shell-mode-hook 'set-outline-minor-mode-regexp t)
(add
-hook 'sh-mode-hook 'set-outline-minor-mode-regexp t)
(add
-hook 'emacs-lisp-mode-hook 'set-outline-minor-mode-regexp t)


最后在 函数里面还要提到的一点是 =(make-local-variable 'outline-regexp)= 。我在这里显式的把 =outline-regexp= 作成 buffer local 了。如果不这样做的话, =sh-mode= 中的 =outline-regexp= 赋值会很诡异的覆盖掉 =shell-mode= 里面的值。虽然我还不太清楚为什么在别的 mode 里面就没有问题。灵异中……

 

org-mode.el

最后是 =org-mode.el= , 我不知道再提到这个文件是不是还有必要。因为这里在没有什么神奇的地方了。这里只是一些关于 =org-mode= 的一些设置, 还有……一些 skeleton 定义。因为基本上 =org-mode= 的默认设置就已经蛮好用了(我用的是 7.01h 版),所以现在这个文件内的内容基本上就是 skeleton 定义。只是因为他们还没有变得足够多,所以我还没有把它们分成一个单独的文件来管理。那么就说说 skeleton 吧。最近比较常用的 skeleton 主要是以下这些:

 

代码
(define-skeleton iexp
"Input #+BEGIN_EXAMPLE #+END_EXAMPLE in org-mode"
""
"#+BEGIN_EXAMPLE\n"
_
"\n"
"#+END_EXAMPLE"
)

(define
-skeleton isrc
"Input #+begin_src #+end_src in org-mode"
""
"#+begin_src lisp \n"
_
"\n"
"#+end_src"
)

(define
-skeleton iprop
"Input :PROPERTIES: :END: in org-mode"
""
":PROPERTIES:\n"
_
"\n"
":END:"
)

(define
-skeleton insert-emacser-code
""
""
"#+BEGIN_HTML\n"
"<pre lang=\"lisp\" line=\"1\">\n"
_
"\n"
"</pre>\n"
"#+END_HTML\n"
)

(define
-abbrev org-mode-abbrev-table "iexp" "" 'iexp)
(define-abbrev org-mode-abbrev-table "isrc" "" 'isrc)
(define-abbrev org-mode-abbrev-table "iprop" "" 'iprop)
(define-abbrev org-mode-abbrev-table "ihtml" "" 'insert-emacser-code)


很容易看出来,有了这些东西以后,在写 =org= 文档的时候会很方便。并且,为了能够对已经存在的代码添加 =#+BEGIN_EXAMPLE= =#+begin_src= 等等定义,我还编写了几个扩展函数:

 

 

代码
(defun i-babel-quote (beg end str1 str2)
(
goto-char end)
(forward
-line 1)
(insert str2)
(newline)
(
goto-char beg)
(forward
-line -1)
(newline)
(insert str1)
)

(defun iexp (St Ed)
" "
(interactive
"r")
(let ((beg St) (end Ed))
(message
"%s %s" beg end)
(i
-babel-quote beg end "#+BEGIN_EXAMPLE" "#+END_EXAMPLE")))

(defun isrc (St Ed)
" "
(interactive
"r")
(let ((beg St) (end Ed))
(message
"%s %s" beg end)
(i
-babel-quote beg end "#+begin_src " "#+end_src")))
(defun i
= (St Ed)
""
(interactive
"r")
(let ((beg St) (end Ed))
(
goto-char end)
(insert
"=")
(
goto-char beg)
(insert
"=")
(
goto-char (+ end 2)))
)

 

最后呢,我把一些 Shell当中比较常用的命令也定义成了 skeleton 。之所以不在 Shell profile 当中定义它,一方面是因为在我的工作中每天都要接触到大量的 Unix/Linux机器,放在 Emacs 里面的话呢,所有的命令都只需要定义一次,就可以在任意一个机器上使用。另外一方面呢,就是 skeleton,包括 abbrev 都是 Emacs 内部的东西,也就是说他们只会把定义的命令扩展开来,而并不会直接的去执行他,只有当我看到扩展结果并且按下回车,comint.el才会把相应的命令转交给 shell process 去执行,这在很多时候要比 shell 本身的 alias 和 function 机制安全的多的多。以下是一些示例:

 

代码
(define-skeleton kill-multiple-proces
"Build killing multiple process command list"
""
"ps -ef | grep -i " _ " | awk '{ print \"kill -9 \" $2 }'"
)

(define
-abbrev shell-mode-abbrev-table "killps" "" 'kill-multiple-proces)

(define
-skeleton gunzip-tar
"unzip .tar.gz package in where -z is not available"
""
"gunzip -cd " _ " | tar -xf - "
)

(define
-skeleton def_listener
"Define a listener in a WMQ QMgr"
""
"DEF LISTENER(LST) TRPTYPE(TCP) PORT(" _ ") CONTROL(QMGR)\n"
)

(define
-abbrev shell-mode-abbrev-table "deflst" "" 'def_listener)

(define
-skeleton def_clusrcvr
"Define a Cluster Receiver Channel in a WMQ QMgr"
""
"DEF CHL(TO.QMCOD.4.FTECA) CHLTYPE(CLUSRCVR) CONNAME('" _ "') CLUSTER(FTECA)\n"
)

(define
-abbrev shell-mode-abbrev-table "defclusrcvr" "" 'def_clusrcvr)

 

对于很多更简单的命令,直接就定义在 abbrev 里面了。

dove-ext.el

最后的最后,是 =dove-ext.el= 。这个文件的内容都是我自己编写的各种扩展函数。包括上面提到的部分和更多还没有被提到的。 你可以到 EmacsWiki上去浏览这些函数。

posted on 2010-11-13 14:43  David Young 杨博华  阅读(1815)  评论(3编辑  收藏  举报

导航