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 or set-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”.
- Active Region is for the purpose of highing selected text, when Transient Mark Mode is on.
- And many commands automatically work on active region as input.
elisp function or variable related to active region are:
region-active-puse-region-pdeactivate-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
pop-mark-
(pop-mark)Get and remove the top item from mark-ring and set it as current mark.
- 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 does not 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
region-active-p.
(defun my-is-region-active () "print whether region is active." (interactive) (if (region-active-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 my-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: Get Text at Cursor (thing-at-point)
Reference
Elisp, mark, region
Elisp, 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: Get Line Begin/End Position, or Move To
- Elisp: Get Text at Cursor (thing-at-point)
- Elisp: Get Text Block 📜
- Elisp: Save narrow-to-region