Emacs. Help fix the move-text-up function


I customize Emacs for myself (v 24.5.1). I found the function I need to move a block of code (for example, line or region) up / down here: https://www.emacswiki.org/emacs/move-text.el
The function works correctly both with a line (line) and with a block (region), but there is a small problem when moving a line up, namely, if you become point on a line and call the move-text-up function. The line moves up once, point remains on the same line as it was. Accordingly, pressing again only back lowers the line that needed to be moved several lines higher.

Below is only a specific fragment with functions, the full text of the file can be found at the link above.

(defun move-text-internal (arg)
   ((and mark-active transient-mark-mode)
    (if (> (point) (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)
      (setq deactivate-mark nil)))
    (let ((column (current-column)))
      (when (or (> arg 0) (not (bobp)))
        (when (or (< arg 0) (not (eobp)))
          (transpose-lines arg))
        (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)))

(defun move-text-default-bindings ()
  "Bind `move-text-up' and `move-text-down' to M-up and M-down."
  (global-set-key [M-up] 'move-text-up)
  (global-set-key [M-down] 'move-text-down))

(provide 'move-text)

PS Yes, you don't have to look for errors in someone else's code. Perhaps there is a better solution.


I recommend using the shift-text module from melpa. I've been using your snippet for a while, but it has other problems as well.

From my config :

(use-package shift-text

  :ensure t


  (("C-M-n" . shift-text-down)
   ("C-M-p" . shift-text-up)
   ("C-M-f" . shift-text-right)
   ("C-M-b" . shift-text-left)
   ("C-M-j" . shift-text-down)
   ("C-M-k" . shift-text-up)
   ("C-M-l" . shift-text-right)
   ("C-M-h" . shift-text-left)))

(besides the standard, I use the HJKL vim style for navigation)

Scroll to Top