首页 > 解决方案 > Emacs Lisp 在更改缓冲区后通过开始和结束选择区域

问题描述

我想要一个 emacs 函数来选择(标记)由 start 和 end 给出的区域。我试过了

(defun mark-range (start end)
  "Mark buffer content from start to end"
  (message (concat "Select " (number-to-string start) " " (number-to-string end)))
  (setq bufmax (max start end))
  (setq bufmin (min start end))
  (goto-char bufmax)
  (set-mark bufmin) ;actually the comment on set-mark says: Do not use!

  ;(set-mark-command bufmin) did not work for this
)

它在简单函数中调用时有效,但有时即使消息显示正确的开始和结束内容,此函数也不起作用。那么选择就不存在了。

任何想法,我怎样才能实现可靠的功能?(我正在使用 spacemacs 开发分支)

编辑:好的,这是用例,我实际上想使用 Alt-Up Alt-Down 上下移动文本,就像在 eclipse 中一样

我发现有一个块移动文本,但它不是我想要的:选择该区域接触的整行并将其向上移动,然后保持选中以再次使用。

所以我首先检查在第一行之前我必须移动多少行,然后用它来再次选择行。但随后选择不起作用。它根本不存在。

我现在尝试整合 Drews 的答案,但并没有真正帮助,标记没有出现,(添加了 deactivate-mark,因为之前有一个,也没有运气)。之前用我的方法(包括(激活,停用))尝试过,也不起作用。

(defun rl-move-up-block(start end)

  (let (last first dist m-start)
  (goto-char (max start end))
  (setq last (line-number-at-pos))

  (goto-char (min start end))
  (setq first (line-number-at-pos))

  (goto-char (min start end))
  (forward-line -1)

  (setq dist (+ (- last first) 1))

  (dotimes (i dist)
    (move-text-line-down))


  (forward-line (- 0 dist))
  (set-mark (line-beginning-position))
  (forward-line (- dist 1))
  (end-of-line)
  (activate-mark)
 )
)

(defun rl-move-up (start end)
  "Move text up like in eclipse"
  (interactive "r")
  (if (use-region-p)
      (rl-move-up-block start end)
    (move-text-line-up)
    )
  )

(global-set-key (kbd "M-<up>") 'rl-move-up)

编辑2:好吧,我刚刚发现如果我删除了线条的移动,只需移动光标就可以替换它,标记就可以了。

  ;(dotimes (i dist)
  ;  (move-text-line-down))
  (forward-line dist)

所以问题是更改文本然后再次标记。我曾经试图通过在每行之间放置一个睡眠来查看它在慢动作中的作用。

没用,只是使整个功能花费了更长的时间-也许它需要刷新视图来调用某些东西。有什么可以刷新或完成更改的吗?也许这有助于在移动线条后使标记再次起作用。

标签: emacsselectionregion

解决方案


原来有一个变量。

我检查了 move-text-down 现有命令的代码,发现有一个变量设置为 nil 如果我在移动文本后这样做,它可以工作


  (dotimes (i dist)
    (move-text-line-down)) 

    (setq deactivate-mark nil) ; <<<<<<

    (forward-line (- 0 dist))

推荐阅读