現在のリージョンのすべての (空でない) 行を取得し、これらの行を in-place で複製する 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!")))
ただし、この関数にはいくつかの (少なくとも 2 つの) バグがあります。
- 空行は無視されませんが、出力が完全に破棄されます (行が間違った場所に挿入されます)。
- 挿入される最初の行は常に間違ったインデント (列 0) で挿入され、他のすべての行は正しいインデントに挿入されます。
私は、機能をより便利な状態に進めることにちょっとこだわっています。また、私のアプローチが特に効率的/よく書かれているとは思えません...おそらく、一部のelispの達人は、リージョン内の各行を個別に処理するために使用できる、より簡単なアプローチを知っています...