Make your own Emacs package

Make you own Emacs package.
创建自己的Emacs包。

ElpaMELPA上面有许多的包,可以做各种各样的事情,但有可能你找不到一个合适你的某个问题的包,这时候可以自己动手写一个package,分离到MEELPA。

其实写一个package是一个比较简单的事情,但是又比较麻烦,麻烦在于有很多的约定需要了解,下面我们来动手写一个简单的闹钟包,参考了alarm.el。恰好我的包也叫做alarm.el,如有疑问请提出。

准备

开发阶段使用package-insstall-file来安装并且测试包是否正确,这个命令可以安装单个文件something.el,也可以安装一个tar包,这里主要有两个文件,所以需要打成tar包安装。

目录结构

alarm-20170724.1502
|-alarm-pkg.el
|-alarm.el
|-alarm.wav

  1. 目录名的命名规则是name-version
  2. alarm-pkg.el 是给emacs的package提供信息的一个文件
  3. alarm.el 程序主要内容在这个文件
  4. alarm.wav 闹钟响的时候播放这个文件,还可以使用.au文件

alarm-pkg.el

1
2
3
4
(define-package
"alarm"
"20170724.1502"
"A package to alarm yourself at some time.")

这个文件比较简单,只是调用了define-package来定义你的包信息,此函数的签名如下:

1
2
3
4
(defun define-package (_name-string _version-string
&optional _docstring _requirements
&rest _extra-properties)
(error "Don't call me!"))

第一个参数是包名,第二个参数是版本号,第三个参数可以是一个长字符串提供说明文档

alarm.el

这个文件的约定比较多,先看一下这个文件的头部

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
;;; alarm.el --- Alarm
;; Copyright (C) 2017, Emacs guys, all rights reserved.
;; Author: Kevim Jiang <wenlin1988@126.com>
;; Version: 20170724.1502
;; Keywords: alarm
;; Maintainer: Kevin Jaing <wenlin1988@126.com>
;; Created: 2017-07-24 12:00:00
;;; Commentary:
;; Set an alarm with `alarm-clock', and enter the time;
;; cancel the alarm with `alarm-clock-cancel'
;;; Code:

每一个段落以空白行隔开。第一行是文件名和一个简短的说明,而且开头以;;;三个分号注释。Commentary一段可以是长一些的说明文档,以及使用说明。最后是;;; Code:段,接下面就是真正的代码内容。可以使用checkdoc来检查头部的文档是否正确。还可以使用package-lint包的package-lint-current-buffer命令检查。

最后需要:

1
2
3
(provide 'alarm)
;;; alarm.el ends here

完整的alarm.el如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
;;; alarm.el --- Alarm
;; Copyright (C) 2017, Emacs guys, all rights reserved.
;; Author: Kevim Jiang <wenlin1988@126.com>
;; Version: 20170724.1502
;; Keywords: alarm
;; Maintainer: Kevin Jaing <wenlin1988@126.com>
;; Created: 2017-07-24 12:00:00
;;; Commentary:
;; require alarm in you init.el: `(require 'alarm)'
;; Set an alarm with `alarm-clock', and enter the time;
;; cancel the alarm with `alarm-clock-cancel'
;;; Code:
(defvar alarm-version "20170724.1502")
(defvar alarm-clock-timer nil
"Keep timer so that the user can cancel the alerm.")
(defun alarm-ding3 ()
"Play 3 times ding."
(dotimes (n 3)
(play-sound-file
(concat package-user-dir
"/alarm-" alarm-version
"/alarm.wav"))))
;;;###autoload
(defun alarm-clock-cancel ()
"Cancel the alarm clock."
(interactive)
(cancel-timer alarm-clock-timer))
;;;###autoload
(defun alarm-clock ()
"Set an alarm.
The time format is the same accepted by `run-at-time'.
For example 12:00am."
(interactive)
(let ((time (read-string "Time(example, 12:00am): ")))
(setq alarm-clock-timer (run-at-time time nil 'alarm-ding3))))
(provide 'alarm)
;;; alarm.el ends here

打包

tar -cvf alarm-20170724.1502.tar alarm-20170724.1502

然后使用package-install-file安装此tar包,重启emacs后可以使用alarm-clock来设置一个闹钟。记得在init.el文件使用(require 'alarm),小伙伴快来试试吧!

分享到melpa

首先得在github上clone melpa仓库,然后添加一个以包名命令的文件到recipes目录下,这里的文件是alarm

1
2
3
(alarm
:repo "kevindragon/alerm.el"
:fetcher github)

提交,然后提pull request,等待接收。

希望我的提交可以顺利通过。