Was ist der einfachste Weg, um ausgewählte Regionen oder Linien (wenn keine Auswahl vorhanden ist) in Emacs nach oben oder unten zu verschieben? Ich suche nach der gleichen Funktionalität wie in Eclipse (begrenzt auf M-up, M-down).
Was ist der einfachste Weg, um ausgewählte Regionen oder Linien (wenn keine Auswahl vorhanden ist) in Emacs nach oben oder unten zu verschieben? Ich suche nach der gleichen Funktionalität wie in Eclipse (begrenzt auf M-up, M-down).
Antworten:
Eine Linie kann mit an gebundenen Transponierlinien verschoben werden C-x C-t
. Keine Ahnung von Regionen.
Ich habe dieses Elisp-Snippet gefunden, das macht, 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)
Update: Installieren Sie das move-text
Paket von Marmalade oder MELPA , um den folgenden Code zu erhalten.
Folgendes verwende ich, das sowohl für Regionen als auch für einzelne Linien 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)
Du solltest es versuchen drag-stuff
!
Es funktioniert genau wie Eclipse Alt+ Up/ Downfür einzelne Linien sowie für ausgewählte Regionslinien!
Darüber hinaus können Sie Wörter mit Alt+ Left/ verschieben. Right
Dies ist genau das, wonach Sie suchen! Und es ist sogar in den ELPA-Repos erhältlich !
Andere Lösungen haben bei mir nie funktioniert. Einige von ihnen waren fehlerhaft (Transponieren von Linien beim Ändern ihrer Reihenfolge, wtf?) Und einige von ihnen bewegten genau ausgewählte Regionen und ließen nicht ausgewählte Teile der Linien an ihren Positionen. Funktioniert aber drag-stuff
genau wie bei Eclipse!
Und noch mehr! Sie können versuchen, eine Region auszuwählen und Alt+ Left/ Right! Dadurch wird der ausgewählte Bereich um ein Zeichen nach links oder rechts transponiert. Tolle!
Um es global zu aktivieren, führen Sie einfach Folgendes aus:
(drag-stuff-global-mode)
(drag-stuff-define-keys)
in der Init-Datei benötigt, bevor die Tastenkombinationen funktionieren. Dies wird in diesem Github erklärt: github.com/rejeep/drag-stuff.el
Ich habe einige interaktive Funktionen zum Verschieben von Linien 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 IntelliJ IDEA-Stil, Sie können jedoch alles verwenden, was Sie möchten. Ich sollte wahrscheinlich einige Funktionen implementieren, die auch für Regionen funktionieren.
Hier ist mein Snippet, um die aktuelle Linie oder die von der aktiven Region überspannten Linien zu verschieben. Es berücksichtigt die Cursorposition und den hervorgehobenen Bereich. Und es werden keine Linien unterbrochen, wenn die Region nicht an den Liniengrenzen beginnt / endet. (Es ist von der Sonnenfinsternis inspiriert; ich fand die Sonnenfinsternis bequemer als 'Transponierungslinien'.)
;; 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)))
Dafür gibt es einen Eintrag im Emacs-Wiki:
http://www.emacswiki.org/emacs/MoveLine
Für bewegliche Regionen:
Es ist kein eingebauter. Sie können Transponierungslinien (Cx Ct) verwenden, aber Sie können sie nicht wiederholt verwenden. Schauen Sie sich die Funktionen auf http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/ an. .
Es sollte leicht sein, dies auch an Regionen anzupassen.
Die transpose-paragraph
Funktion könnte Ihnen helfen.
Vielleicht möchten Sie auch einen Blick auf den Transponierungsabschnitt im Emacs-Handbuch werfen . Im Wesentlichen:
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).
Ich benutze dafür das Smart-Shift-Paket (in Melpa). Standardmäßig wird erneut gebunden C-C <arrow>
, um eine Linie oder Region zu verschieben. Es bewegt sich horizontal um einen für den Hauptmodus spezifischen Betrag (z. B. c-basic-offset oder python-indent-offset). Funktioniert auch in Regionen.
;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
(global-smart-shift-mode 1))