Function: evil-select-block
evil-select-block is a byte-compiled function defined in
evil-common.el.
Signature
(evil-select-block THING BEG END TYPE COUNT &optional SELECTION-TYPE COUNTCURRENT FIXEDSCAN)
Documentation
Return a range (BEG END) of COUNT delimited text objects.
BEG END TYPE are the currently selected (visual) range. The
delimited object must be given by THING-up function (see
evil-up-block).
SELECTION-TYPE is symbol that determines which parts of the block
are selected. If it is inclusive or t OPEN and CLOSE are
included in the range. If it is exclusive or nil the delimiters
are not contained. If it is exclusive-line the delimiters are
not included as well as adjacent whitespace until the beginning
of the next line or the end of the previous line. If the
resulting selection consists of complete lines only and visual
state is not active, the returned selection is linewise.
If COUNTCURRENT is non-nil an objected is counted if the current selection matches that object exactly.
Usually scanning for the surrounding block starts at (1+ beg) and (1- end). If this might fail due to the behavior of THING then FIXEDSCAN can be set to t. In this case the scan starts at BEG and END. One example where this might fail is if BEG and END are the delimiters of a string or comment.
Source Code
;; Defined in ~/.emacs.d/elpa/evil-20251108.138/evil-common.el
(defun evil-select-block (thing beg end type count
&optional
selection-type
countcurrent
fixedscan)
"Return a range (BEG END) of COUNT delimited text objects.
BEG END TYPE are the currently selected (visual) range. The
delimited object must be given by THING-up function (see
`evil-up-block').
SELECTION-TYPE is symbol that determines which parts of the block
are selected. If it is `inclusive' or t OPEN and CLOSE are
included in the range. If it is `exclusive' or nil the delimiters
are not contained. If it is `exclusive-line' the delimiters are
not included as well as adjacent whitespace until the beginning
of the next line or the end of the previous line. If the
resulting selection consists of complete lines only and visual
state is not active, the returned selection is linewise.
If COUNTCURRENT is non-nil an objected is counted if the current
selection matches that object exactly.
Usually scanning for the surrounding block starts at (1+ beg)
and (1- end). If this might fail due to the behavior of THING
then FIXEDSCAN can be set to t. In this case the scan starts at
BEG and END. One example where this might fail is if BEG and END
are the delimiters of a string or comment."
(save-excursion
(save-match-data
(let* ((orig-beg beg)
(orig-end end)
(beg (or beg (point)))
(end (or end (point)))
(count (abs (or count 1)))
op cl op-end cl-end)
;; We always assume at least one selected character.
(if (= beg end) (setq end (1+ end)))
;; We scan twice: starting at (1+ beg) forward and at (1- end)
;; backward. The resulting selection is the smaller one.
(goto-char (if fixedscan beg (1+ beg)))
(when (and (zerop (funcall thing +1)) (match-beginning 0))
(setq cl (cons (match-beginning 0) (match-end 0)))
(goto-char (car cl))
(when (and (zerop (funcall thing -1)) (match-beginning 0))
(setq op (cons (match-beginning 0) (match-end 0)))))
;; start scanning from end
(goto-char (if fixedscan end (1- end)))
(when (and (zerop (funcall thing -1)) (match-beginning 0))
(setq op-end (cons (match-beginning 0) (match-end 0)))
(goto-char (cdr op-end))
(when (and (zerop (funcall thing +1)) (match-beginning 0))
(setq cl-end (cons (match-beginning 0) (match-end 0)))))
;; Bug #607: use the tightest selection that contains the
;; original selection. If non selection contains the original,
;; use the larger one.
(cond
((and (not op) (not cl-end))
(error "No surrounding delimiters found"))
((or (not op) ; first not found
(and cl-end ; second found
(>= (car op-end) (car op)) ; second smaller
(<= (cdr cl-end) (cdr cl))
(<= (car op-end) beg) ; second contains orig
(>= (cdr cl-end) end)))
(setq op op-end cl cl-end)))
(setq op-end op cl-end cl) ; store copy
;; if the current selection contains the surrounding
;; delimiters, they do not count as new selection
(let ((cnt (if (and orig-beg orig-end (not countcurrent))
(let ((sel (evil--get-block-range op cl selection-type)))
(if (and (<= orig-beg (car sel))
(>= orig-end (cdr sel)))
count
(1- count)))
(1- count))))
;; starting from the innermost surrounding delimiters
;; increase selection
(when (> cnt 0)
(setq op (progn
(goto-char (car op-end))
(funcall thing (- cnt))
(if (match-beginning 0)
(cons (match-beginning 0) (match-end 0))
op))
cl (progn
(goto-char (cdr cl-end))
(funcall thing cnt)
(if (match-beginning 0)
(cons (match-beginning 0) (match-end 0))
cl)))))
(let ((sel (evil--get-block-range op cl selection-type)))
(setq op (car sel)
cl (cdr sel)))
(cond
((and (equal op orig-beg) (equal cl orig-end)
(or (not countcurrent) (/= count 1)))
(error "No surrounding delimiters found"))
((save-excursion
(and (not (evil-visual-state-p))
(eq type 'inclusive)
(progn (goto-char op) (bolp))
(progn (goto-char cl) (bolp))))
(evil-range op cl 'line :expanded t))
(t (evil-range op cl type :expanded t)))))))