help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Anyone have a 'move-line' function?


From: John Conrad
Subject: Re: Anyone have a 'move-line' function?
Date: Thu, 4 May 2006 12:24:45 -0400

On 5/4/06, Joe Smith <jes@martnet.com> wrote:
Mathias Dahl wrote:
> The following is quite ugly but seems to work. ...

liyer.vijay@gmail.com wrote:
> Here's a solution that doesn't add to the kill-ring ...

Very nice. Thanks guys.

I like the idea of using current-column (new to me anyway) and not
adding to the kill-ring.

Here's what I came up with--after studying your suggestions and
adapting what I had; Vijay's is simpler but it goes a little weird at
the file edges: moving the last line down adds empty lines; moving the
first line up gives an error and leaves point on line 2.

Thanks again. Comments/corrections welcome.

(defun move-line (n)
   "Move the current line up or down by N lines."
   (interactive "p")
   (setq col (current-column))
   (beginning-of-line) (setq start (point))
   (end-of-line) (forward-char) (setq end (point))
   (let ((line-text (delete-and-extract-region start end)))
     (forward-line n)
     (insert line-text)
     ;; restore point to original column in moved line
     (forward-line -1)
     (forward-char col)))

(defun move-line-up (n)
   "Move the current line up by N lines."
   (interactive "p")
   (move-line (if (null n) -1 (- n))))

(defun move-line-down (n)
   "Move the current line down by N lines."
   (interactive "p")
   (move-line (if (null n) 1 n)))

(global-set-key (kbd "M-<up>") 'move-line-up)
(global-set-key (kbd "M-<down>") 'move-line-down)

I don't know if this is the sort of comment you are welcoming, but I
think your style would be improved by wrapping the col, start and end
variables in a let expression (with the effect of making them local)
instead of declaring and setting global variables simultaneously with
setq. After you've declared them in the let, you can then use setq on
them as needed. In the following variation on your function, I create
a local col variable and set it to (current-column), then I create
start and end local variables but I do not initialize them with any
particular value. Later, I use setq on them the same way as you did in
your original function.

(defun move-line (n)
  "Move the current line up or down by N lines."
  (interactive "p")
  (let ((col (current-column))
        start
        end)
    (beginning-of-line)
    (setq start (point))
    (end-of-line)
    (forward-char)
    (setq end (point))
    (let ((line-text (delete-and-extract-region start end)))
      (forward-line n)
      (insert line-text)
      ;; restore point to original column in moved line
      (forward-line -1)
      (forward-char col))))

John Emerson Conrad




reply via email to

[Prev in Thread] Current Thread [Next in Thread]