在Emacs中,移动选定区域或向上/向下移动行(如果没有选择)的最简单方法是什么?我希望能够像在Eclipse中那样使用功能(绑定到M-up和M-down)。
在Emacs中,移动选定区域或向上/向下移动行(如果没有选择)的最简单方法是什么?我希望能够像在Eclipse中那样使用功能(绑定到M-up和M-down)。
更新:安装来自Marmalade或MELPA的move-text
包,以获得以下代码。
这是我使用的内容,它可以用于区域和单独的行:
(defun move-text-internal (arg)
(cond
((and mark-active transient-mark-mode)
(if (> (point) (mark))
(exchange-point-and-mark))
(let ((column (current-column))
(text (delete-and-extract-region (point) (mark))))
(forward-line arg)
(move-to-column column t)
(set-mark (point))
(insert text)
(exchange-point-and-mark)
(setq deactivate-mark nil)))
(t
(let ((column (current-column)))
(beginning-of-line)
(when (or (> arg 0) (not (bobp)))
(forward-line)
(when (or (< arg 0) (not (eobp)))
(transpose-lines arg)
(when (and (eval-when-compile
'(and (>= emacs-major-version 24)
(>= emacs-minor-version 3)))
(< arg 0))
(forward-line -1)))
(forward-line -1))
(move-to-column column t)))))
(defun move-text-down (arg)
"Move region (transient-mark-mode active) or current line
arg lines down."
(interactive "*p")
(move-text-internal arg))
(defun move-text-up (arg)
"Move region (transient-mark-mode active) or current line
arg lines up."
(interactive "*p")
(move-text-internal (- arg)))
(global-set-key [M-S-up] 'move-text-up)
(global-set-key [M-S-down] 'move-text-down)
el-get
只是委托给了package.el
。任何el-get
可能支持的安装后设置代码都可以使用像use-package
这样的包来处理。 - sanityinc通过绑定C-x C-t
到transpose-lines,可以移动一行。不过我不确定如何移动区域。
我找到了this个elisp片段,它可以实现你想要的功能,但你需要更改绑定。
(defun move-text-internal (arg)
(cond
((and mark-active transient-mark-mode)
(if (> (point) (mark))
(exchange-point-and-mark))
(let ((column (current-column))
(text (delete-and-extract-region (point) (mark))))
(forward-line arg)
(move-to-column column t)
(set-mark (point))
(insert text)
(exchange-point-and-mark)
(setq deactivate-mark nil)))
(t
(beginning-of-line)
(when (or (> arg 0) (not (bobp)))
(forward-line)
(when (or (< arg 0) (not (eobp)))
(transpose-lines arg))
(forward-line -1)))))
(defun move-text-down (arg)
"Move region (transient-mark-mode active) or current line
arg lines down."
(interactive "*p")
(move-text-internal arg))
(defun move-text-up (arg)
"Move region (transient-mark-mode active) or current line
arg lines up."
(interactive "*p")
(move-text-internal (- arg)))
(global-set-key [\M-\S-up] 'move-text-up)
(global-set-key [\M-\S-down] 'move-text-down)
你应该尝试使用drag-stuff
!
它的功能与 eclipse 中的 Alt+Up/Down 相同,用于单行以及选定区域的多行!
此外,它还允许您使用 Alt+Left/Right 移动单词。
这正是你在寻找的!而且它甚至可以从ELPA repos中获取!
其他解决方案对我都没有用。其中一些有缺陷(交换行时改变它们的顺序,真是神奇?);其中一些则仅移动被选定的部分,留下未选定的部分在原位置上。但是,drag-stuff
的工作方式与 Eclipse 完全相同!
更棒的是!你可以尝试选择一个区域并使用 Alt+Left/Right!这将把所选区域向左或向右转置一个字符。太神奇了!
要全局启用它,只需运行此命令:
(drag-stuff-global-mode)
(drag-stuff-define-keys)
。这在以下 GitHub 中有解释:https://github.com/rejeep/drag-stuff.el - agent18我写了几个交互式函数来上下移动线:
;; move line up
(defun move-line-up ()
(interactive)
(transpose-lines 1)
(previous-line 2))
(global-set-key [(control shift up)] 'move-line-up)
;; move line down
(defun move-line-down ()
(interactive)
(next-line 1)
(transpose-lines 1)
(previous-line 1))
(global-set-key [(control shift down)] 'move-line-down)
这些按键绑定采用的是IntelliJ IDEA风格,但你可以使用任何你想要的。 我应该实现一些也能在区域上运行的函数。
这是一个移动当前行或活动区域跨越的多行的代码片段。它考虑了光标位置和高亮区域,并且当区域不从行边界开始/结束时,不会打断行。此方法受到eclipse启发,我发现eclipse方法比“transpose-lines”更方便。
;; move the line(s) spanned by the active region up/down (line transposing)
;; {{{
(defun move-lines (n)
(let ((beg) (end) (keep))
(if mark-active
(save-excursion
(setq keep t)
(setq beg (region-beginning)
end (region-end))
(goto-char beg)
(setq beg (line-beginning-position))
(goto-char end)
(setq end (line-beginning-position 2)))
(setq beg (line-beginning-position)
end (line-beginning-position 2)))
(let ((offset (if (and (mark t)
(and (>= (mark t) beg)
(< (mark t) end)))
(- (point) (mark t))))
(rewind (- end (point))))
(goto-char (if (< n 0) beg end))
(forward-line n)
(insert (delete-and-extract-region beg end))
(backward-char rewind)
(if offset (set-mark (- (point) offset))))
(if keep
(setq mark-active t
deactivate-mark nil))))
(defun move-lines-up (n)
"move the line(s) spanned by the active region up by N lines."
(interactive "*p")
(move-lines (- (or n 1))))
(defun move-lines-down (n)
"move the line(s) spanned by the active region down by N lines."
(interactive "*p")
(move-lines (or n 1)))
transpose-paragraph
函数可以帮助你。
你也可以查看Emacs手册中的transpose部分。 本质上:
C-t
Transpose two characters (transpose-chars).
M-t
Transpose two words (transpose-words).
C-M-t
Transpose two balanced expressions (transpose-sexps).
C-x C-t
Transpose two lines (transpose-lines).
没有内置的功能。您可以使用transpose-lines(C-x C-t),但不能重复使用它。请查看http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/上的函数。
将其适应于区域应该很容易。
C-x C-t
向上移动行进行转置,C-x z z z
将重复。向下移动一行是 C-u 1 C-x C-t
,再次重复是 C-x z z z
。当然可以做到,但不可否认有些繁琐。 - undefined我使用 Melpa 中的 smart-shift 软件包来完成这个任务。默认情况下,它将 C-C <arrow>
重新绑定为移动一行或区域。它会按照主模式特定的数量水平移动(例如 c-basic-offset 或 python-indent-offset)。它也可以处理区域。
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))