《elisp 每日一练》——阶段性总结与练习

《elisp 每日一练》——阶段性总结与练习

Masimaro
2026-08-09 / 0 评论 / 1 阅读 / 正在检测是否收录...

在之前的一系列文章中,我们已经详细介绍了关于文本和光标的一些操作以及对应的API。我们先回顾一下之前介绍的内容

前期内容回顾

我们先介绍了有关光标位置和移动光标的一些函数:

  • point-minpoint-max
  • line-beginning-positionline-end-position
  • goto-char
  • forward-line

以及拷贝对应区域文本的函数 buffer-substring

接着又介绍了有关恢复光标位置相关的API函数

  • mark
  • push-markpop-mark
  • save-excursion

而Emacs内部维护 mark 的方式被称为 mark-ring,有关 mark-ring 的函数与变量如下:

  • mark-ring
  • marker-position
  • line-number-at-pos
  • marker-buffer

markPoint 能构成一个 Region,关于 Region 的函数如下:

  • region-beginningregion-end
  • activate-mark
  • use-region-p

因为 region 本身不具备区域保护的功能,它无法限制我们仅仅操作某个区间的文本,所以Emacs又提供了 NarrowingWiden 机制。

  • narrow-to-region
  • widen
  • save-restriction

之后我们正式进入了对文本的增删改查的学习。相关API内容如下:

  • insert
  • delete-region
  • search-forwardre-search-forward 以及反向的 search-backwardre-search-backward
  • match-string
  • save-match-data
  • string-match
  • string-match-p
  • match-beginningmatch-end
  • replace-match

综合练习

本次练习,我们结合之前介绍的相关API来写一个综合性的功能。

我们平时在写代码时经常会写各种各样的注释,有些注释有一些固定的写法, 例如我经常写 TODO 表示这部分功能没有加,后面加上, FIXME 这部分实现的比较粗糙,后面在进行重构或者精细化处理。虽然未来大概率就不了了之了,但是留下这些注释显得比较专业(不是)

我们现在要做的就是收集 TODOFIXME 开头的这些注释,然后将它们加入到minibuffer 中,显示,在用户选择对应的注释之后跳转到buffer对应的位置

(defvar my/todo-mark-list '()
  "保存全局的todo列表,格式为(SUMMARY-TEXT . marker)")

;; 收集todo/fixme 数据
(defun my/code-todo-list-collect()
  (interactive)
  (setq my/todo-mark-list '())
  (save-excursion
    (save-restriction
      (widen)
      (goto-char (point-min))
      ;;遍历并收集数据
      (while (re-search-forward "//\\s-*\\(todo\\|fixme\\):?\\s-*\\(.*\\)$" nil t)
    (let* ((raw-content (match-string 2))
           ;; 准备数据
           (m (copy-marker (match-beginning 0))))
      (push (cons raw-content m) my/todo-mark-list))))))

(defun my/jump-to-next-todo()
  (interactive)
  (save-restriction
    (widen)
    (if (null my/todo-mark-list)
    (message "当前没有待修正的任务")

      (let* ((selected (completing-read "请选择要跳转的位置: " my/todo-mark-list nil t)))
    (when selected
      (let ((target (cdr (assoc selected my/todo-mark-list))))
        (push-mark)
        (switch-to-buffer (marker-buffer target))
        (goto-char target)))))))

本次的练习,我们分了两个函数,一个用于收集信息,另一个用于在minibuffer 进行交互。

在收集信息时我们仍然采用之前的写法,将string 放在CELL的最外层,这样 completing-read 可以正常读取出对应的字符串提示信息并且显示。而后面我们仍然是通过二者的关联性快速执行跳转。

虽然我将它称之为综合练习,但是目前我们还有有些内容没有涉及到,比如说修改注释,我们可以做的更复杂一些,将这种注释修改为更加标准的内容。后面我们学习了buffer、file相关的操作之后就可以做的更复杂一些,例如对搜索的结果进行持久化,又或者搜集整个工程中的待办事项。

总结

到此位置关于操作文本相关的内容我们都已经涉及到了,后面我们会开始进入有关 bufferwindow 专题讨论相关的操作

0

评论 (0)

取消