我正在尝试编写一个elisp函数,该函数获取当前区域中的所有(非空)行并复制这些行就地。我给你举个例子:
此输入:
线路1
2号线
第3行
成为
线路1
线路1
2号线
2号线
3号线
第3行
如果有空行,它们将保留在原位,不应重复。如果编码了以下功能:
(defun duplicate-lines-in-region (beg end)
"Duplicates the lines in the current region \"in-place\"."
(interactive "r")
(if (use-region-p)
(let* ((text (buffer-substring-no-properties (region-beginning) (region-end)))
(lines (split-string text "\n" t))
(num-lines (length lines))
(current-line 0)
(end-pos 0))
(save-excursion
(goto-char (region-beginning))
(while (< current-line num-lines)
(end-of-line)
(insert "\n")
(insert (nth current-line lines))
(next-line)
(setq current-line (+ current-line 1))
(setq end-pos (point))))
(goto-char end-pos))
(error "No active region!")))
但是,此函数有一些(至少两个)错误:
我有点坚持将功能推进到更有用的状态。另外,我非常怀疑我的方法特别有效/写得很好......也许一些elisp-guru知道一种更简单的方法,可以用来单独处理一个区域中的每一行......
答案 0 :(得分:3)
这可能是作弊,但您可以使用正则表达式替换来匹配非空行并将其替换为捕获的行和副本。使用 M-x replace-regexp 突出显示的区域,以及以下参数:
\(.+\)$
\&^J\&
请注意,在上文中,^J
表示换行符/引用的回车键, C-q C-j 。
要将其转换为elisp,您只需要确保转义反斜杠和括号:
(defun duplicate-lines-in-region (beg end)
(interactive "*r")
(replace-regexp "\\(.+\\)$" "\\&\n\\&" nil beg end))