我是一名elisp(但不是编程)的初学者,对实现函数的最佳实践有一些疑问。我编写了一个elisp函数,根据某些规则重新格式化汇编程序源代码;此功能目前适用于单行。它主要使用行内导航,在子表达式上查看和替换匹配调用来实现目标。
现在我想将它应用于标记区域,逐行处理区域。该行为类似于缩进区域函数。
实施此方法的推荐(和有效)方法是什么?我考虑使用(line-number-at-pos ...)
应用于(region-beginning)
和(region-end)
来计算行号,然后从上到下移动,逐行缓冲,修改这些。
此外,通过此操作我需要保留什么?我虽然关于(保存匹配数据......)并且不确定如何处理标记和点。我猜他们会没用,因为文本范围发生了变化。
答案 0 :(得分:4)
使用save-excursion
保存并恢复点和标记,并使用save-restriction
缩小到该区域。
模板将是这样的:
(defun my-process-region (beg end)
"Apply `my-process-line` to every line in region."
(interactive "r")
(save-restriction
(widen)
(save-excursion
(narrow-to-region beg end)
(goto-char (point-min))
(while (not (eobp))
(my-process-line)))))
答案 1 :(得分:-1)
我接受了sds的回答。最后,我使用了下面的代码。原因是我想要整行可用于重新格式化,而不仅仅是标记的区域。所以ConverterParameter
单独就不会完成这项工作。
我很乐意了解更多信息,并感谢对优缺点或遗漏事物的评论:
(narrow-to-region)
接下来尝试 - 根据评论进行修改。我没有找到一种更简单的方法来扩展选择以包括整行...任何想法是否可以进一步简化(defun x-mode-reformat-region (beg end)
"..."
(interactive "r")
(save-excursion
(let ((nlines (+ 1 (apply '- (mapcar 'line-number-at-pos `(,end ,beg)))))
bol
...)
(goto-char beg)
(dotimes (i nlines)
(setq bol (line-beginning-position))
(goto-char bol)
;; do reformatting for this line -- uses bol for calculations
(forward-line)))))
/ setq
组合(除了直接使用narrow-to-region
作为参数?
(progn ...)