需求:把一行/多行上移prefix-arg行
目标是一行时不难实现:
(defun jjpandari/move-line-up (count)
"Move prefix-arg lines up."
(interactive "p")
(dotimes (i count) (move-text-line-up))
)
考虑目标是多行的情形,借鉴这里:
改进版,判断行尾字符决定是 insert 还是 remove,支持多行:
(defun insert-or-remove-trailing-char (&optional ch)
(interactive)
(let ((ch (or ch (read-char "Input char: ")))
(fn (lambda (ch)
(end-of-line)
(if (eq (char-before) ch)
(delete-backward-char 1)
(insert-char ch)))))
(save-excursion
(if (region-active-p)
(save-restriction
(narrow-to-region (region-beginning) (region-end))
(deactivate-mark)
…
我改成了:
(defun jjpandari/move-line-up (count)
"Move prefix-arg lines up."
(interactive "p")
(save-restriction
(if (region-active-p)
(goto-char (point-min))
(while (< (point) (point-max))
(next-line)
(when (< (point) (point-max))
(dotimes (i count) (move-text-line-up))))
(dotimes (i count) (move-text-line-up)))))
并没有正常工作,甚至还会卡死emacs。请坛友们指点。 改进了,请看4楼
你的代碼槽點太多,比如按你這個來,沒选中的時候只会跳到第一行,別的什麼都沒干。原因是你沒搞清楚 if
的行為。
會卡是因爲你大量调用了 (move-text-line-up)
,开銷太大。
內置就有 move-text-region
。对照著看,差不多应該知道问題在哪。
;;;###autoload
(defun move-text-region (start end n)
"Move the current region (START END) up or down by N lines."
(interactive (move-text-get-region-and-prefix))
(let ((line-text (delete-and-extract-region start end)))
(forward-line n)
(let ((start (point)))
(insert line-text)
(setq deactivate-mark nil)
(set-mark start))))
Q: 一位精神病患者,医生想看一下他是否康复了,于是就把浴缸里的水放满了给了他一个勺子和一个碗,让他把里面水放完,应該怎麼做?
A: 拔掉塞子
嗯if
用错了。
现在region-p
时改成
(move-text-region-up (region-beginning) (region-end) count)
基本可以了,只是内容移动后选中部分会留在原来的地方,无论加不加save-restriction
1 个赞
我又去抄了一下evil-indent
,感觉现在应该算比较像样了,不过又碰到个疑问(注释部分本来是启用的,这里为了说明问题注释掉它们):
(defun jjpandari/move-line-up (count)
"Move prefix-arg lines up."
(interactive "p")
(if (region-active-p)
(let* ((beg (region-beginning))
(end (region-end))
(beg-line (line-number-at-pos beg))
(end-line (line-number-at-pos end))
(line-count (1+ (- end-line beg-line))))
(move-text-up beg end count)
(goto-char (point-min))
;; (forward-line (- beg-line count))
;; (indent-region (point) (line-beginning-position (+ 1 line-count)))
)
(move-text-up (line-beginning-position) (line-beginning-position 2) count)
(deactivate-mark)
(indent-for-tab-command))
)
注意看if
的THEN
部分,除了let*
的赋值外,只有move-text-up
和(goto-char (point-min))
,我期待的是执行后会跳到buffer开头,然而move-text-up
正常,goto min却没有起作用,求指点。