emacs自动更新文件头


前面已经说过,可以使用auto-insert自动添加文件头,今天来说一说自动更新文件头,比如说每次保存时自动更新last updated字段

自动更新Last Updated

如果使用的是header2,直接设置相关的变量就可,假如使用的是auto-insert,同样也可以使用emacs内置的time-stamp对Last Updated进行自动更新

time-stamp默认使用Time-stamp:,如果要对Last Updated进行自动更新,只需要简单的设置

(setq time-stamp-active t)
(setq time-stamp-line-limit 11)
(setq time-stamp-start "[lL]ast[ -][uU]pdate[ \t]*:?")
(setq time-stamp-end "\n")
(setq time-stamp-format " %#A %Y-%02m-%02d %02H:%02M:%02S (%Z)")

然后添加

(add-hook 'before-save-hook 'time-stamp)

这样就能在每次保存时自动更新相应的字段了

自动更新Filename

之前遇到过,使用auto-insert在每次创建新文件时自动添加了文件头,但后面文件名被修改了,文件头里的文件名却不会自动更改,基于这个原因需要自己实现一个函数(我没有找到可以使用的已经存在的package)

先理一理逻辑: 只需要查找当前文件前几行信息,如果找到File Name:字段,获取字段信息,与当前文件名进行对比,如果不一致则替换为当前文件名,直接给出代码吧

  • 查找当前文件前几行
    (save-excursion
        (goto-char (point-min)) ;;跳转到开头
        (let ((lines 0))
        (while (< lines line-limit)
            ;; 查找
            (setq lines (1+ lines))
            (forward-line 1))))
    
  • 获取当前文件名
    (file-name-nondirectory (buffer-file-name))
    
  • 查找File Name
    (looking-at ".*\\(File Name:\\)\\(.*\\)")
    
  • 对文件名进行比对与替换
    (let ((beg (match-beginning 2))
          (end (match-end 2)))
      (when (not (string= 文件名 (string-trim-left (match-string 2))))
        (goto-char beg)
        (delete-region beg end)
        (insert " " name)))
    

    即可得到相关的完整函数(完整函数后面再讲)

自动更新Email

工作和平时使用的邮箱不一样,我虽然设置了at_home变量区分工作与平时的邮箱,但不是每次我都记得要更新这个变量,所以有了这个需要,自动将文件头里的email信息更改为平时所用的邮箱,大致逻辑与自动更新Filename相同,所以我写了一个macro来自动生成相关的代码

直接给出代码

(defun maple/header-update-action(name)
  "A."
  (let ((beg (match-beginning 2))
        (end (match-end 2)))
    (when (not (string= name (string-trim-left (match-string 2))))
      (goto-char beg)
      (delete-region beg end)
      (insert " " name))))
(defun maple/header-update(regex default line-limit)
  "B."
  (interactive)
  (save-excursion
    (goto-char (point-min))
    (let ((lines 0))
      (while (< lines line-limit)
        (when (and (looking-at regex))
          (maple/header-update-action default))
        (setq lines (1+ lines))
        (forward-line 1)))))
(defmacro maple/header-update-engine (name regex default &optional line-limit)
  "C."
  `(defun ,(intern (format "maple/header-update-%s" name)) ()
     ,(format "Update %s with regex." name)
     (interactive)
     (maple/header-update ,regex ,default ,(or line-limit 7))))

这样,我就可以调用macro来生成代码

  • 自动更新Filename
    (maple/header-update-engine "filename"
                                ".*\\(File Name:\\)\\(.*\\)"
                                (file-name-nondirectory (buffer-file-name)) 7)
    

    生成一个maple/header-update-filename的函数,只要调用它即可更新文件名信息

  • 自动更新email

    同样的

    (maple/header-update-engine "email"
                                ".*\\(Email:\\)\\(.*\\)"
                                "youemail@gmail.com" 7)
    
    生成一个可供调用的maple/header-update-email

如果想要添加其它功能,只要使用maple/header-update-engine即可

相关的配置可以在我的github上找到

There are comments.

  • emacs自动添加文件头


    想要在emacs中添加文件头有好几种方法:

    • 直接手打
    • 使用模板yasnippet
    • 使用header2
    • 使用内置的package auto-insert

    header2可能是最方便的一种自动添加文件头的方式,但我之前使用过,想要自定义自己想要的内容很难,而且白白浪费header2的功能

    今天主要说一说emacs内置里auto-insert,使用它在创建文件时自动添加文件头信息

    基础使用

    直接(auto-insert-mode) 并且设置

    (setq auto-insert-query nil) ;; 不提醒
    

    自定义文件头

    (setq auto-insert-alist
          '(((python-mode . "Python program") nil
             "#!/usr/bin/env python\n"
             "# -*- coding: utf-8 -*-\n"
             "# **************************************************************************\n"
             "# Copyright © " (substring (current-time-string) -4) " " (user-full-name) "\n …
  • 关于时间与空间的猜想


    • 背景

      不知道从何时开始,就听过这样一个说法: 如果人类所达到的速度超越光速,那么人类将穿越时空。前些年网文电视剧可谓穿越盛行,今天我也来胡言乱语一番!

    • 胡言乱语

      光从某一点x出发,在其经过的路径范围内,有一不同于光所在空间y空间z,z的时间流速与y空间的时间流速不一样,或者说z空间的时间流速小于于y空间的流速,即z空间一天,y空间一年。

      由此就可发现,当y空间内的光从x点出发,在经过z空间范围内时,由于在z,y空间时间流速不一致,原本到达k点 (x到k的距离大于x到z空间的距离)所花费的时间为1s,但z空间的存在,需要花费0.3s才能通过z空间的范围,现在只需要远小于0.3s的时间就能通过z空间的范围。

      相对于y空间而言,原本需要花费1s才能到达k点,现在也许只需要0.8s,如果简单按照速度公式v=S/t,光速将超越299792458m/s,相对而言,y空间与z空间也会有所谓的穿越。

    当然 …

  • 十二月十日小记


    今天真是不错的一天

    今天出门,在电梯遇到一人,“小伙子,你有二十了吧”,“我今年二十X了”,“我看你不到二十的样子”,“我以为我看起来挺老的”,“怎么会。。。”

    以前只是在电视新闻上看到有人直接撞到玻璃门上,其实真不怪他们,有时候玻璃门真看起来没有一样。我今天就这样直接撞上去了,说实话,还真疼

    附几张今天用手机拍的照片,昨天用相机拍的raw格式暂时打不开/捂脸

  • python尾递归优化


    参考 这里

    class TailRecurseException(BaseException):
        def __init__(self, args, kwargs):
            self.args = args
            self.kwargs = kwargs
    
    
    def tail_call_optimized(g):
        """
        This function decorates a function with tail call
        optimization. It does this by throwing an exception
        if it is it's own grandparent, and catching such
        exceptions to fake the …
  • 使用tornado实时输出日志


    import tornado
    from tornado.web import Application
    from tornado.web import RequestHandler
    from tornado.websocket import WebSocketHandler
    import os
    import json
    
    template = '''<!doctype html>
    <html lang="en">
      <head>
        <meta charset="UTF-8"/>
        <title>Document</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script src="https://cdn.bootcss.com/jquery …
  • python运行超时设置


    import signal
    
    class TimeoutError(Exception):
        pass
    
    def timeout(seconds=10, error_message="Timer expired"):
        def _timeout(func):
            def _handle_timeout(signum, frame):
                raise TimeoutError(error_message)
    
            def wrapper(*args, **kwargs):
                signal.signal(signal.SIGALRM, _handle_timeout)
                signal.alarm(seconds)
                try:
                    result = func(*args, **kwargs)
                finally:
                    signal.alarm(0)
                return result
    
            return wrapper
    
        return …
  • 一个很好的想法


    我有这样一个想法

    有这么一个app

    1. 它可以自定义表单,然后保存到本地或者远程数据库
    2. 还可以填写一个远程url,验证的token,或者其他验证需要的header信息
    3. 填好之后就可以提交相关的表单

    好吧,其实是写说说,写博客使用的

    它还有另外一个功能: 上传图片

    1. 同样是先填写远程url,验证信息
    2. 填写其它相关信息
    3. 选择本地图片进行上传
    4. 上传成功后返回相应的url链接

    好吧,越来越像朋友圈和QQ空间了

    但是,它可以自定义发布和上传的url呀!

    最后,如果要更大,更远一些,可以对使用者的博客等内容进行相应的聚合,分类,成为一个优质的移动聚合平台.

    嗯,好想法,就等谁实现了