前面已经说过,可以使用auto-insert自动添加文件头,今天来说一说自动更新文件头,比如说每次保存时自动更新last updated字段
自动更新Last Updated
如果使用的是header2,直接设置相关的变量就可,假如使用的是auto-insert,同样也可以使用emacs内置的time-stamp对Last Updated进行自动更新
time-stamp默认使用Time-stamp:,如果要对Last Updated进行自动更新,只需要简单的设置
1(setq time-stamp-active t)
2(setq time-stamp-line-limit 11)
3(setq time-stamp-start "[lL]ast[ -][uU]pdate[ \t]*:?")
4(setq time-stamp-end "\n")
5(setq time-stamp-format " %#A %Y-%02m-%02d %02H:%02M:%02S (%Z)")
然后添加
1(add-hook 'before-save-hook 'time-stamp)
这样就能在每次保存时自动更新相应的字段了
自动更新Filename
之前遇到过,使用auto-insert在每次创建新文件时自动添加了文件头,但后面文件名被修改了,文件头里的文件名却不会自动更改,基于这个原因需要自己实现一个函数(我没有找到可以使用的已经存在的package)
先理一理逻辑: 只需要查找当前文件前几行信息,如果找到File Name:字段,获取字段信息,与当前文件名进行对比,如果不一致则替换为当前文件名,直接给出代码吧
-
查找当前文件前几行
1(save-excursion 2 (goto-char (point-min)) ;;跳转到开头 3 (let ((lines 0)) 4 (while (< lines line-limit) 5 ;; 查找 6 (setq lines (1+ lines)) 7 (forward-line 1)))) -
获取当前文件名
1(file-name-nondirectory (buffer-file-name)) -
查找File Name
1(looking-at ".*\\(File Name:\\)\\(.*\\)") -
对文件名进行比对与替换
1(let ((beg (match-beginning 2)) 2 (end (match-end 2))) 3 (when (not (string= 文件名 (string-trim-left (match-string 2)))) 4 (goto-char beg) 5 (delete-region beg end) 6 (insert " " name)))即可得到相关的完整函数(完整函数后面再讲)
自动更新Email
工作和平时使用的邮箱不一样,我虽然设置了at_home变量区分工作与平时的邮箱,但不是每次我都记得要更新这个变量,所以有了这个需要,自动将文件头里的email信息更改为平时所用的邮箱,大致逻辑与自动更新Filename相同,所以我写了一个macro来自动生成相关的代码
直接给出代码
1(defun maple/header-update-action(name)
2 "A."
3 (let ((beg (match-beginning 2))
4 (end (match-end 2)))
5 (when (not (string= name (string-trim-left (match-string 2))))
6 (goto-char beg)
7 (delete-region beg end)
8 (insert " " name))))
9(defun maple/header-update(regex default line-limit)
10 "B."
11 (interactive)
12 (save-excursion
13 (goto-char (point-min))
14 (let ((lines 0))
15 (while (< lines line-limit)
16 (when (and (looking-at regex))
17 (maple/header-update-action default))
18 (setq lines (1+ lines))
19 (forward-line 1)))))
20(defmacro maple/header-update-engine (name regex default &optional line-limit)
21 "C."
22 `(defun ,(intern (format "maple/header-update-%s" name)) ()
23 ,(format "Update %s with regex." name)
24 (interactive)
25 (maple/header-update ,regex ,default ,(or line-limit 7))))
这样,我就可以调用macro来生成代码
-
自动更新Filename
1(maple/header-update-engine "filename" 2 ".*\\(File Name:\\)\\(.*\\)" 3 (file-name-nondirectory (buffer-file-name)) 7)生成一个
maple/header-update-filename的函数,只要调用它即可更新文件名信息 -
自动更新email 同样的
1(maple/header-update-engine "email" 2 ".*\\(Email:\\)\\(.*\\)" 3 "[email protected]" 7)生成一个可供调用的
maple/header-update-email
如果想要添加其它功能,只要使用maple/header-update-engine即可
相关的配置可以在我的github上找到
知识共享署名-非商业性使用-相同方式共享4.0国际许可协议