5

I often want to quickly mark everything from point to the end of line, leaving point at the same place.

I tried to write simple function for that purpose:

(defun mark-from-point-to-end-of-line ()
  "Marks everything from point to end of line"
  (interactive)
  (save-excursion
    (progn
      (set-mark-command nil)
      (move-end-of-line nil)
      (set-mark-command nil)
      )))

However, it behaves not as expected, e.g. if you place point over m in line (move-end-of-line nil) and execute this command this will mark everything from beginning of buffer to point. I guess this is somehow related to save-excursion function, but can't be certain. How should I fix that?

P.S. Sorry for question title, don't know how to name it better.

  • Do you want to highlight the region, or just leave invisible marks at different locations? Or do you want to record the position number -- e.g., (point) at each location? There is a notation in the doc-string that states: Novice Emacs Lisp programmers often try to use the mark for the wrong purposes. See the documentation of `set-mark' for more information. Did you fall into the same trap as many of us did when first starting off? – lawlist Mar 24 '15 at 7:47
  • I've read about set-mark, set-mark-command, push-mark but didn't understand anything. If I eval this sequence it gives me exact what I want — mark region from point to the end of line: (set-mark-command nil)(move-end-of-line nil)(set-mark-command nil). I need it to wrap marked region with parentheses. – Geradlus_RU Mar 24 '15 at 8:03
  • But remember, I want to leave point position untouched after region marked. In the end I want to hit something to run my mark command, then hit C-S-( to wrap marked region and continue typing – Geradlus_RU Mar 24 '15 at 8:06
  • Here are a couple of related threads that describe options for implementing the feature you seek: stackoverflow.com/questions/2951797/… and stackoverflow.com/questions/1023770/… There is a recent feature in current versions of Emacs to return to the previous marked position -- something like set the mark with C-SPC and then to return, use C-u C-SPC -- I'll see if I can find a related thread for that feature. – lawlist Mar 24 '15 at 8:07
  • Oh, sorry, indeed I use M-(, but it's annoying me when I need to wrap something from where point is located to end of line first: C-@ C-e M-(, basically I want to replace C-@ C-e with one shortcut excepting that I have my point untouched. If I remove save-excursion my function behaves exactly as C-@ C-e C-@ – Geradlus_RU Mar 24 '15 at 8:11
8

Save-excursion restores point AND mark (as of emacs 24.4), so it is no help for you here. You could save the point manually with this idiom:

(let ((pos (point)))
  ...
  (goto-char pos))

However, in your case it's better to just set the mark at the end of the line:

(defun mark-from-point-to-end-of-line ()
  "Marks everything from point to end of line"
  (interactive)
  (set-mark (line-end-position))
  (activate-mark))

Note: In the current development version, save-excursion no longer restores the mark.

  • What a wonderful solution! And it is exact answer. Thank you for clarification about save-excursion, I should read help next time before I use any new functions (: – Geradlus_RU Mar 24 '15 at 13:11
  • 1
    Just for future record, it seems that starting with Emacs 25 save-excursion will no longer restore mark: lists.gnu.org/archive/html/emacs-diffs/2015-03/msg00260.html – Malabarba Mar 26 '15 at 15:48
  • 1
    Malabarba, noted in my answer. Not sure if that change will stick, though. Doesn't it break existing code? Though I don't think I ever used save-excursion to save the mark. – olaf b Mar 31 '15 at 0:57
1

I knew, I'll need this function someday...

(defun mark-line (&optional arg allow-extend)
  "Set mark ARG lines away from point.

The place mark goes is the same place \\[forward-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
            (forward-line (prefix-numeric-value arg))
            (point))
          nil t))))

(global-set-key (kbd "M-#") 'mark-line)              
  • great! thank you, but there is one caveat: it selects newline symbol too, thus if I use M-x mark-line RET M-( it will place closing parenthesis at beginning of new line. – Geradlus_RU Mar 24 '15 at 12:11
  • Well, you figure it out... – politza Mar 24 '15 at 12:14
0

Once you have a region, you can use C-x C-x ('exchange-point-and-mark') to restore your point, for example, C-SPC C-e C-x C-x should do what you want.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.