106 Stimmen

Zeile/Region in emacs nach oben und unten verschieben

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).

59voto

sanityinc Punkte 14752

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)

56voto

Martin Wickman Punkte 19017

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)

43voto

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)

14voto

Bozhidar Batsov Punkte 54038

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.

6voto

Ji Han Punkte 611

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)))

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X