expreg
:emacs: Mar 31, 2026Table of Contents
Lately, I stumbled across the nice package expreg. It allows to enlarge or shrink
a region based on semantic units and it is quite similar to expand-region. In contrast
to expand-region it uses tree-sitter in the background and has no mode specific
definitions.
1. Should I switch?
The first draft of the package was at a time where tree-sitter was still in the early
adoption among the Emacs modes and the expand-region worked well. Thus, a change seemed to
be unnecessary.
In the last couple of month the package got some care and I tried it. It works well in all
major modes I tried and its support in org-mode is better than expand-region.
2. Configuration
The configuration for the package is fairly simple.
(use-package expreg
:ensure t
:custom (expreg-restore-point-on-quit t)
:hook (text-mode-hook . (lambda ()
(add-to-list 'expreg-functions #'expreg--sentence)))
:general (jj-general-definer 'global-map
"C-+" '(expreg-expand :wk "expand region")
"C--" '(expreg-contract :wk "contract region")))
The function jj-general-definer is a macro which sets some defaults I use for the
general package.
expand-region sets a repeat map which allows to repeatedly press + or - which is nice to
use. Add the following code to get the same behavior for expreg:
(defvar expreg-repeat-map
(define-keymap
"+" #'expreg-expand
"-" #'expreg-contract))
(put #'expreg-expand 'repeat-map 'expreg-repeat-map)
(repeat-mode t)
2.1. Update 03.04.2026
I looked into the use-package documentation and found a better way to define the
repeat map.
:bind (:repeat-map jj-expreg-repeat-map
("+" . expreg-expand)
("-" . expreg-contract))
The symbol :repeat-map defines the following symbol as a repeat map and adds all
bindings in the scope to the :repeat-map.
If somebody knows a way to declare a repeat map with general.el feel free to
reach out.