commands - emacs ubuntu
Mover línea/región arriba y abajo en emacs (9)
¿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 (limitado a M-up, M-down).
¡Deberías intentar drag-stuff
!
Funciona exactamente igual que eclipse Alt + Arriba / Abajo para líneas individuales, ¡así como para líneas de región seleccionadas!
Además de eso, te permite mover palabras con Alt + Izquierda / Derecha
¡Esto es exactamente lo que estás buscando! ¡Y está incluso disponible en los repositorios 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 a la región seleccionada, dejando partes no seleccionadas de las líneas en sus posiciones. ¡Pero drag-stuff
funcionan exactamente como en eclipse!
¡Y aún más! ¡Puede intentar seleccionar una región y usar Alt + Izquierda / Derecha ! Esto transpondrá la región seleccionada por un carácter a la izquierda o a la derecha. ¡Asombroso!
Para habilitarlo globalmente, simplemente ejecuta esto:
(drag-stuff-global-mode)
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 un eclipse; encontré que el eclipse es más conveniente que ''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)))
Hay una entrada en la wiki de emacs solo para esto:
http://www.emacswiki.org/emacs/MoveLine
Para regiones en movimiento:
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 estilo IntelliJ IDEA, pero puede usar cualquier cosa que desee. Probablemente debería implementar algunas funciones que operan en regiones también.
La función de transpose-paragraph
podría ayudarte.
También es posible que 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).
No hay incorporado. Puede usar transpose-lines (Cx Ct) pero no puede usarlo repetidamente. Mira 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.
Utilizo el paquete smart-shift (en Melpa) para esto. Por defecto, vuelve a enlazar CC <arrow>
para mover una línea o región. Se mueve horizontalmente por una cantidad específica de modo mayor (por ejemplo, c-basic-offset o python-indent-offset). Funciona en regiones también
;; binds C-C <arrows>
(when (require ''smart-shift nil ''noerror)
(global-smart-shift-mode 1))
Actualización: instale el paquete move-text
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)
Una línea se puede mover usando transpose-lines unidas a Cx Ct
. Aunque no sé nada de las regiones.
Encontré this 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)