Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle composed characters in evil-range #1664

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions evil-common.el
Original file line number Diff line number Diff line change
Expand Up @@ -2990,13 +2990,25 @@ If no description is available, return the empty string."

(defun evil-range (beg end &optional type &rest properties)
"Return a list (BEG END [TYPE] PROPERTIES...).
BEG and END are buffer positions (numbers or markers),
TYPE is a type as per `evil-type-p', and PROPERTIES is
a property list."
BEG and END are buffer positions (numbers or markers), TYPE is a
type as per `evil-type-p', and PROPERTIES is a property list. If
beg or end are inside a sequence of composed characters, adjust
the positions to be outside of this sequence."
(let ((beg (evil-normalize-position beg))
(end (evil-normalize-position end)))
(end (evil-normalize-position end))
beg-out end-out)
(when (and (numberp beg) (numberp end))
(append (list (min beg end) (max beg end))
(setq beg-out (min beg end))
(setq end-out (max beg end))
(when evil-treat-composed-chars-as-one
(let ((comp (find-composition beg-out)))
;; find-composition returns (FROM TO VALID-P)
(when (and (listp comp) (nth 2 comp))
(setq beg-out (nth 0 comp))))
(let ((comp (find-composition end-out)))
(when (and (listp comp) (nth 2 comp))
(setq end-out (nth 1 comp)))))
(append (list beg-out end-out)
(when (evil-type-p type)
(list type))
properties))))
Expand Down
17 changes: 15 additions & 2 deletions evil-tests.el
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,12 @@ and the beginning")
(should (string= (evil-describe 1 2 'exclusive)
"1 character"))
(should (string= (evil-describe 5 2 'exclusive)
"3 characters"))))))
"3 characters")))
(let ((evil-treat-composed-chars-as-one t))
(compose-region 9 15 "ϐ") ; visually replaces "buffer" with ϐ
(ert-info ("Adjust range to account for composed characters")
(should (equal (evil-normalize 10 10 'exclusive)
'(9 15 exclusive))))))))

(ert-deftest evil-test-inclusive-type ()
"Expand and contract the `inclusive' type"
Expand All @@ -533,7 +538,15 @@ and the beginning")
(should (string= (evil-describe 1 1 'inclusive)
"1 character"))
(should (string= (evil-describe 5 2 'inclusive)
"4 characters")))))
"4 characters")))
(let ((evil-treat-composed-chars-as-one t))
(compose-region 9 15 "ϐ") ; visually replaces "buffer" with ϐ
(ert-info ("Don't end in composed characters")
(should (equal (evil-expand 7 12 'inclusive)
'(7 15 inclusive :expanded t))))
(ert-info ("Don't begin in composed characters")
(should (equal (evil-expand 10 20 'inclusive)
'(9 21 inclusive :expanded t)))))))

(ert-deftest evil-test-line-type ()
"Expand the `line' type"
Expand Down
13 changes: 13 additions & 0 deletions evil-vars.el
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,19 @@ without having to introduce new niche functionality.
Prefer to set `evil-v$-excludes-newline' to non-nil."
"1.15.0")

(defcustom evil-treat-composed-chars-as-one nil
"EXPERIMENTAL. Treat composed characters as single characters.

Composed characters are sequences of characters in the buffer
that are displayed as a single glyph. This is the device used by
`prettify-symbols-mode' among others. This option tells evil that
these sequences of characters should be treated as a single unit
to, for example, prevent part of the sequence from being deleted
by an evil command. It alters low-level functionality of evil and
is considered experimental."
:type 'boolean
:group 'evil)

(defcustom evil-v$-excludes-newline nil
"If non-nil, `evil-end-of-line' does not move as far as to include
the `\n' char at eol. This makes `v$' consistent with `$' used as a
Expand Down