13

I want to perform the same action that one does by hitting C-Space + moving the arrow keys, but in elisp.

Failing to find the right function (if they just were logically grouped in namespaces or somehow tagged...). Which one is it?

Cœur
  • 37,241
  • 25
  • 195
  • 267
deprecated
  • 5,142
  • 3
  • 41
  • 62

4 Answers4

18

You can translate keystrokes to elisp using C-h k key.

You'll notice the elisp function for setting the mark set-mark-command, takes one non-optional argument. Emacs uses the special interactive function to allow elisp functions to be written naturally with arguments. This allows them to be generic and easy to reuse in other elisp programs, while still possible to invoke directly from a keystroke. It also has some of the C-u prefix logic built-in.

In the case of set-mark-command, its first function is (interactive "P"), which means the prefix is passed in as an argument when called from the keyboard. You can simulate this directly in elisp with:

(set-mark-command nil)

For example, to select the current line in elisp:

(defun my-select-current-line ()
  (interactive)
  (move-beginning-of-line nil)
  (set-mark-command nil)
  (move-end-of-line nil)
  (setq deactivate-mark nil))

Note you have to tell emacs to leave the mark active at the end or else the region won't remain highlighted (although the point and mark will be where you left them).

ataylor
  • 64,891
  • 24
  • 161
  • 189
  • If I set the point at the end of a line and then run `(set-mark-command 0)`, the point gets moved but not the mark, hence nothing gets selected. What am I missing? Thank you. – deprecated Jul 27 '12 at 15:08
  • Set the mark at the start of the region, then move the point to the end. Also, the arg should actually be `nil` instead of zero. I've updated my answer with an example. – ataylor Jul 27 '12 at 15:38
  • The functionality works (thanks!) I'm not getting visual feedback, i.e. `deactivate-mark` doesn't seem to make a difference. Not important for my particular purpose anyway. – deprecated Jul 27 '12 at 17:36
  • 1
    The visual feedback will only work if you've defined it as an interactive command with `(interactive)` and invoke it with `M-x command-name` or bind it to a key. – ataylor Jul 27 '12 at 19:17
  • How do I move to end of buffer or end of frame? – Lionel May 07 '17 at 08:51
4

You should use push-mark in emacs lisp code, as follows:

(defun mark-n (n)
  "Programmtically mark the next N lines"   
  (interactive "nNum lines to mark: ")
  (push-mark)  
  (next-line n))
justinhj
  • 11,147
  • 11
  • 58
  • 104
4

Just in case this additional info is of use to someone else, I've found the following:

  • As for programatic movement, see Moving Point
  • (point) and (mark) retrieve their respective positions, so one can do (set-mark (+ 5 (mark))), for instance.
deprecated
  • 5,142
  • 3
  • 41
  • 62
1

The region is the part of the buffer between point and mark.

choroba
  • 231,213
  • 25
  • 204
  • 289