Select a line in Emacs

Emacs has out of the box selection for word, sentence, paragraph, and whole buffer, but apparently not for line. Let’s fix this.

By selection I mean what is called marking in Emacs. There is:

  • mark-word to select from cursor to the end of word, default keybind M-@
  • mark-end-of-sentence to select from cursor to the end of sentence
  • mark-paragraph to select the whole paragraph under cursor, default keybind M-h
  • mark-whole-buffer to select the entire current buffer, default keybind C-x h

There are also the more specialised mark-sexp, mark-defun and mark-page, but there is no mark-line, even though in my opinion it would fit well among all the other mark- commands.

So here is a mark-line that I devised directly from the default mark-word. The result works the expected way:

  • mark-line selects from cursor to the end of the line
  • issuing the command repeatedly extends the selected region towards the end of the buffer
  • giving it a negative argument selects lines towards the beginning of the buffer

If you want to select the entire line, move to the beginning of the line first, default keybinds C-a or M-m.

(defun mark-line (&optional arg allow-extend)
  "Set mark ARG lines away from point.
The place mark goes is the same place \\[end-of-line] would
move to with the same argument.
Interactively, if this command is repeated
or (in Transient Mark mode) if the mark is active,
it marks the next ARG lines after the ones already marked."
  (interactive "P\np")
  (cond ((and allow-extend
          (or (and (eq last-command this-command) (mark t))
          (region-active-p)))
     (setq arg (if arg (prefix-numeric-value arg)
             (if (< (mark) (point)) -1 1)))
     (set-mark
      (save-excursion
        (goto-char (mark))
        (forward-line arg)
        (point))))
    (t
     (push-mark
      (save-excursion
        (end-of-line (prefix-numeric-value arg))
        (point))
      nil t))))

Leave a Reply

Your email address will not be published. Required fields are marked *