Move line/region up and down in emacs

Emacs

Emacs Problem Overview


What is the easiest way to move selected region or line (if there is no selection) up or down in emacs? I'm looking for the same functionality as is in eclipse (bounded to M-up, M-down).

Emacs Solutions


Solution 1 - Emacs

Update: Install the move-text package from Marmalade or MELPA to get the following code.

Here's what I use, which works on both regions and individual lines:

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

Solution 2 - Emacs

A line can be moved using transpose-lines bound to C-x C-t. I don't know about regions, though.

I found this elisp snippet that does what you want, except you need to change the bindings.

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

Solution 3 - Emacs

You should try drag-stuff !

It works exactly like eclipse Alt+Up/Down for single lines, as well as for selected region lines!

In addition to that it allows you to move words with Alt+Left/Right
This is exactly what you're looking for! And it is even available from the ELPA repos!

Other solutions never worked for me. Some of them were buggy(transposing lines while changing their order, wtf?) and some of them were moving exactly selected region, leaving unselected parts of the lines on their positions. But drag-stuff works exactly like in eclipse!

And even more! You can try selecting a region and using Alt+Left/Right ! This will transpose selected region by one character to the left or right. Amazing!

To enable it globally simply run this:

(drag-stuff-global-mode)

Solution 4 - Emacs

I have written a couple of interactive functions for moving lines up/down:

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

The keybindings are IntelliJ IDEA style, but you can use anything you want. I should probably implement some functions that operate on regions as well.

Solution 5 - Emacs

Here is my snippet to move the current line or the lines spanned by the active region. It respects cursor position and highlighted region. And it won't break lines when the region doesn't begin/end at line border(s). (It is inspired by eclipse; I found the eclipse way more convenient than '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)))

Solution 6 - Emacs

There is an entry in the emacs wiki just for this:

http://www.emacswiki.org/emacs/MoveLine

For moving regions:

http://www.emacswiki.org/emacs/MoveRegion

Solution 7 - Emacs

There's no built-in. You can use transpose-lines (C-x C-t) but you cannot use it repeatedly. Look at the functions on http://www.schuerig.de/michael/blog/index.php/2009/01/16/line-movement-for-emacs/.

It should be easy to adapt that to regions, too.

Solution 8 - Emacs

The transpose-paragraph function could help you.

You might also want to have a look to the transpose section in the Emacs manual. Essentially:

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

Solution 9 - Emacs

I use the smart-shift package (in Melpa) for this. By default it rebinds C-C <arrow> to move a line or region. It moves horizontally by a major-mode-specific amount (e.g. c-basic-offset or python-indent-offset). Works on regions also.

;; binds C-C <arrows>
(when (require 'smart-shift nil 'noerror)
  (global-smart-shift-mode 1))

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfikovnikView Question on Stackoverflow
Solution 1 - EmacssanityincView Answer on Stackoverflow
Solution 2 - EmacsMartin WickmanView Answer on Stackoverflow
Solution 3 - EmacsAleks-Daniel Jakimenko-A.View Answer on Stackoverflow
Solution 4 - EmacsBozhidar BatsovView Answer on Stackoverflow
Solution 5 - EmacsJi HanView Answer on Stackoverflow
Solution 6 - EmacsManuelView Answer on Stackoverflow
Solution 7 - EmacsFlorian ThielView Answer on Stackoverflow
Solution 8 - EmacsRoberto AloiView Answer on Stackoverflow
Solution 9 - EmacsjpkottaView Answer on Stackoverflow