¿Cuál es la forma más fácil de mover la región o línea seleccionada (si no hay selección) hacia arriba o hacia abajo en emacs? Estoy buscando la misma funcionalidad que en eclipse (limitada a M-up, M-down).
¿Cuál es la forma más fácil de mover la región o línea seleccionada (si no hay selección) hacia arriba o hacia abajo en emacs? Estoy buscando la misma funcionalidad que en eclipse (limitada a M-up, M-down).
Respuestas:
Una línea se puede mover usando líneas de transposición enlazadas C-x C-t
. Aunque no sé sobre regiones.
Encontré este fragmento de elisp que hace lo que quieres, excepto que necesitas cambiar los enlaces.
(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)
Actualización: instale el move-text
paquete de Marmalade o MELPA para obtener el siguiente código.
Esto es lo que uso, que funciona tanto en regiones como en líneas individuales:
(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)
¡Deberías intentarlo drag-stuff
!
¡Funciona exactamente como eclipse Alt+ Up/ Downpara líneas individuales, así como para líneas de región seleccionadas!
Además de eso, te permite mover palabras con Alt+ Left/ ¡ Right
Esto es exactamente lo que estás buscando! ¡E incluso está disponible en los repositorios de ELPA !
Otras soluciones nunca funcionaron para mí. Algunos de ellos tenían errores (transponiendo líneas mientras cambiaban su orden, ¿wtf?) Y algunos de ellos se movían exactamente en la región seleccionada, dejando partes no seleccionadas de las líneas en sus posiciones. ¡Pero drag-stuff
funciona exactamente como en eclipse!
¡Y aún más! Puede intentar seleccionar una región y usar Alt+ Left/ Right! Esto transpondrá la región seleccionada un carácter a la izquierda o la derecha. ¡Asombroso!
Para habilitarlo globalmente, simplemente ejecute esto:
(drag-stuff-global-mode)
(drag-stuff-define-keys)
en el archivo init antes de que las combinaciones de teclas comiencen a funcionar. Esto se explica en este github: github.com/rejeep/drag-stuff.el
He escrito un par de funciones interactivas para mover líneas arriba / abajo:
;; 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)
Las combinaciones de teclas son del estilo IntelliJ IDEA, pero puede usar lo que quiera. Probablemente debería implementar algunas funciones que operan también en regiones.
Aquí está mi fragmento para mover la línea actual o las líneas abarcadas por la región activa. Respeta la posición del cursor y la región resaltada. Y no romperá las líneas cuando la región no comience / termine en los bordes de la línea. (Está inspirado en el eclipse; encontré el eclipse mucho más conveniente que las 'líneas de transposición').
;; 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)))
Hay una entrada en la wiki de emacs solo para esto:
http://www.emacswiki.org/emacs/MoveLine
Para regiones móviles:
No hay incorporado. Puede usar líneas de transposición (Cx Ct) pero no puede usarlo repetidamente. Mire las funciones en http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/ .
También debería ser fácil adaptar eso a las regiones.
La transpose-paragraph
función podría ayudarte.
Es posible que también desee echar un vistazo a la sección de transposición en el manual de Emacs. Esencialmente:
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).
Utilizo el paquete smart-shift (en Melpa) para esto. De forma predeterminada, se vuelve C-C <arrow>
a enlazar para mover una línea o región. Se mueve horizontalmente en una cantidad específica del modo principal (por ejemplo, c-basic-offset o python-indent-offset). También funciona en regiones.
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))