Was ist der einfachste Weg, um einen ausgewählten Bereich oder eine Zeile (wenn es keine Auswahl gibt) in emacs nach oben oder unten zu verschieben? Ich bin auf der Suche nach der gleichen Funktionalität wie in Eclipse (begrenzt auf M-up, M-down).
Antworten
Zu viele Anzeigen?Aktualisierung: Installieren Sie die move-text
Paket von Marmalade oder MELPA um den folgenden Code zu erhalten.
Ich verwende die folgende Methode, die sowohl für Regionen als auch für einzelne Zeilen funktioniert:
(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)
Eine Zeile kann verschoben werden mit Transpositionslinien verpflichtet zu C-x C-t
. Ich weiß allerdings nicht, wie es mit den Regionen aussieht.
Ich fand este elisp-Snippet, das das tut, was Sie wollen, außer dass Sie die Bindungen ändern müssen.
(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)
Sie sollten versuchen drag-stuff
!
Es funktioniert genau wie Eclipse Alt + Up / Down sowohl für einzelne Linien, als auch für ausgewählte Regionslinien!
Darüber hinaus ermöglicht es Ihnen, Wörter zu verschieben mit Alt + Left / Right
Das ist genau das, wonach Sie gesucht haben! Und es ist sogar erhältlich bei der ELPA-Repos !
Andere Lösungen haben bei mir nie funktioniert. Einige von ihnen waren fehlerhaft (Vertauschen von Zeilen beim Ändern ihrer Reihenfolge, wtf?) und einige von ihnen verschoben genau ausgewählten Bereich, so dass nicht ausgewählte Teile der Linien auf ihre Positionen. Aber drag-stuff
funktioniert genau wie in Eclipse!
Und noch mehr! Sie können versuchen, eine Region auszuwählen und mit Alt + Left / Right ! Dadurch wird der ausgewählte Bereich um ein Zeichen nach links oder rechts verschoben. Erstaunlich!
Um sie global zu aktivieren, führen Sie einfach Folgendes aus:
(drag-stuff-global-mode)
Ich habe ein paar interaktive Funktionen zum Verschieben von Zeilen nach oben/unten geschrieben:
;; 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)
Die Tastenkombinationen sind im Stil von IntelliJ IDEA, aber Sie können alles verwenden, was Sie wollen. Ich sollte wahrscheinlich einige Funktionen implementieren, die auch auf Regionen wirken.
Hier ist mein Snippet zum Verschieben der aktuellen Zeile oder der Zeilen, die von der aktiven Region umspannt werden. Dabei werden die Cursorposition und der markierte Bereich berücksichtigt. Und es bricht keine Zeilen um, wenn der Bereich nicht an der/den Zeilengrenze(n) beginnt/endet. (Es ist inspiriert von eclipse; ich fand eclipse viel praktischer als '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)))
- See previous answers
- Weitere Antworten anzeigen