Вопрос

I have this code that switch lines up/down:

;; Moving a line up or down
(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))
        (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))
(global-set-key [M-S-down] 'move-text-down)

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

I was wondering if it is possible to tweak the move-text-internal function so it is possible to move part of line "after cursor" up or down.

Here is an example:

Before:

A X B W
Q E O P

If cursor was after X on the first line, after M-S-down:

A X O P
Q E B W

UPDATE: Thanks to Jordan Biondo for the the his code and function. I tweaked it to keep line moving as long as you keep invoking the command.

(defun flip-text (&optional arg)
  "Flip the text from point to the end of the current line with the text
in the next line from the same column to the end of the next line.
With a prefix arg, flip text with the line above the current."
  (interactive "p")
  (save-excursion
    (let ((tt (delete-and-extract-region (point) (point-at-eol)))
          (c (current-column)))
      (forward-line arg)
      (move-to-column c)
      (insert tt)
      (let ((ot (delete-and-extract-region (point) (point-at-eol))))
        (forward-line (- arg))
        (goto-char (point-at-eol))
        (insert ot)
    ))
    )
  (previous-line (- arg))
  )
(global-set-key (kbd "C-M-z") (lambda ()
                  (interactive)
                  (flip-text 1)))
(global-set-key (kbd "C-M-c") (lambda ()
                  (interactive)
                  (flip-text -1)))
Это было полезно?

Решение

This will do what you specified but does not do multiple lines.

(defun flip-text-to-eol (&optional up)
  "Flip the text from point to the end of the current line with the text
in the next line from the same column to the end of the next line.

With a prefix arg, flip text with the line above the current."
  (interactive "P")
  (save-excursion
    (let ((tt (delete-and-extract-region (point) (point-at-eol)))
          (c (current-column)))
      (forward-line (if up -1 1))
      (move-to-column c)
      (insert tt)
      (let ((ot (delete-and-extract-region (point) (point-at-eol))))
        (forward-line (if up 1 -1))
        (goto-char (point-at-eol))
        (insert ot)))))

enter image description here

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top