Elisp: Mark, Region, Active Region
Here's how to work with region, active region, in emacs lisp.
What is Mark, Region, Active Region?
- mark
-
A position in buffer that user can set, for the purpose of marking the start point of a text selection, or jump to a position later.
Alt+x
set-mark-command
【Ctrl+Space】 to set a mark.In lisp code, you should call
push-mark
orset-mark
. - region
-
The last marked position to the current cursor position.
Once a user sets a mark in a buffer, a region exists. So, almost always, there exists a region in a buffer.
By convention, commands ending in the word “-region” acts on the region. e.g. •
kill-region
•fill-region
•comment-region
•indent-region
- active region (text selection)
-
- Active Region is basically the same concept as text selection.
- Active Region is a boolean status, indicating if current region is “active”.
- Many commands automatically work on active region as input.
- Active Region is highlighted if Transient Mark Mode is on.
elisp function or variable related to active region are:
region-active-p
use-region-p
deactivate-mark
- mark-active
When is a Region Active?
Typically, when set-mark-command
is called, the region becomes active.
And, editing commands typically set the region status to inactive after it is called.
Functions for Mark and Region
region-beginning
-
Return the region beginning position.
(defun ff () "sample code to show region begin/end positions" (interactive) (message "begin at %s\nend at %s" (region-beginning) (region-end)))
region-end
-
Return the region end position.
region-active-p
-
return true if region is active.
push-mark
-
(push-mark &optional LOCATION NOMSG ACTIVATE)
Set mark at LOCATION (cursor position by default) and push old mark position to mark-ring
- mark-ring
-
Variable. A list of marked positions of the current buffer, most recent first.
- deactivate-mark
-
Buffer Local Variable. If true, editing commands will deactivate the mark when the command is done.
(defun xx () "sample code, a command that don't deactivate the mark when it is done." (interactive) (let ((deactivate-mark nil) (message "xx done"))))
deactivate-mark
-
(deactivate-mark &optional FORCE)
Deactivate the mark.
If Transient Mark Mode is disabled, this function normally does nothing; but if FORCE is true, it deactivates the mark.
Example: Create a Text Selection
(defun my-select-line () "Select current line." (interactive) (let (p1 p2) (setq p1 (line-beginning-position)) (setq p2 (line-end-position)) (push-mark p1) (goto-char p2) (setq mark-active t)))
💡 TIP: Emacs commands should not change/modify/activate region, unless it's the part of the purpose of the command. Because, it's confusing to user when a command changes text selection or mark.
Example: Check If Region is Active
When you want a command to act on a text selection when there is one, check on use-region-p
.
(defun my-is-region-active () "print whether region is active." (interactive) (if (use-region-p) (message "region active") (message "region not active")))
The function use-region-p
basically checks 3 things:
- Transient Mark Mode is on.
- mark-active is true.
- region isn't empty by checking use-empty-active-region.
Example: Get Text Selection or Current Word
Often you want a command that automatically act on a text unit such as current word, when there is no text selection, and use text selection if there is one.
Here's a example of getting current word, or active region.
(defun downcase-word-or-region () "Downcase current word or region." (interactive) (let (pos1 pos2 bds) (if (use-region-p) (setq pos1 (region-beginning) pos2 (region-end)) (progn (setq bds (bounds-of-thing-at-point 'symbol)) (setq pos1 (car bds) pos2 (cdr bds)))) ;; now, pos1 and pos2 are the starting and ending positions of the ;; current word, or current text selection if exist. (downcase-region pos1 pos2) ))
For detail on other text unit, see Elisp: thing-at-point
Reference
Emacs Lisp, mark, region
Emacs Lisp, text processing functions
- Elisp: Cursor Position Functions
- Elisp: Move Cursor
- Elisp: Text Editing Functions
- Elisp: Search Text
- Elisp: Find Replace Text in Buffer
- Elisp: Mark, Region, Active Region
- Elisp: Cut Copy Paste, kill-ring
- Elisp: Get Buffer String
- Elisp: Functions on Line
- Elisp: thing-at-point
- Elisp: Get Text Block 🚀
- Elisp: Save narrow-to-region