Function: hui-select-markup-pair
hui-select-markup-pair is a byte-compiled function defined in
hui-select.el.
Signature
(hui-select-markup-pair POS)
Documentation
Return (start . end) of region of markup pair, one of which is at POS.
The region returned is between the opening and closing tag. Markups recognised are HTML, XML or SGML tag pairs. The major mode for each language that uses such tags must be included in the list, hui-select-markup-modes.
Source Code
;; Defined in ~/.emacs.d/elpa/hyperbole-20260414.325/hui-select.el
(defun hui-select-markup-pair (pos)
"Return (start . end) of region of markup pair, one of which is at POS.
The region returned is between the opening and closing tag.
Markups recognised are HTML, XML or SGML tag pairs. The major
mode for each language that uses such tags must be included in
the list, hui-select-markup-modes."
(when (memq major-mode hui-select-markup-modes)
(setq hui-select-previous 'markup-pair)
(let ((pos-with-space)
;; Assume case of tag names is irrelevant.
(case-fold-search t)
(result)
start-regexp
end-regexp
bolp
opoint)
(save-excursion
(setq result
(catch 'done
(goto-char pos)
(cond
;; Beginning of a tag pair
((looking-at "<[^/][^<> \t\n\r]*")
(setq start-regexp (regexp-quote (match-string 0))
end-regexp (concat "</" (substring start-regexp 1)))
(setq pos (point))
(skip-chars-backward " \t")
(setq bolp (bolp)
pos-with-space (point))
;; Skip over nested tags.
(let ((count 0)
(regexp (concat start-regexp "\\|" end-regexp)))
(while (and (>= count 0)
(re-search-forward regexp nil t))
(if (/= (char-after (1+ (match-beginning 0))) ?/)
;; Start tag
(setq count (1+ count))
;; Move past end tag terminator
(setq opoint (point))
(when (or (not (re-search-forward "[<>]" nil t))
(= (preceding-char) ?<))
(throw 'done opoint))
(setq count (1- count))
(when (= count 0)
(cond ((smart-eobp)
(if bolp
;; Include leading space since the
;; start and end tags begin and end
;; lines.
(setq pos pos-with-space)
(goto-char (1- (point)))))
((looking-at "[ \t]*[\n\r]")
;; Don't include final newline unless the
;; start tag was the first thing on its line.
(if bolp
(progn (goto-char (match-end 0))
;; Include leading space since the
;; start and end tags begin and end
;; lines.
(setq pos pos-with-space))
(goto-char (1- (match-end 0))))))
(throw 'done (hui-select-set-region pos (point))))))))
;;
;; End of a tag pair
((or (looking-at "</[^\> \t\n\r]+")
(and (skip-chars-backward "\<")
(looking-at "</[^\> \t\n\r]+")))
(goto-char (match-end 0))
(setq end-regexp (regexp-quote (match-string 0))
start-regexp (concat "\<" (substring end-regexp 2))
opoint (point))
(when (or (not (re-search-forward "[<>]" nil t))
(= (preceding-char) ?<))
(throw 'done opoint))
(setq pos (point))
(when (looking-at "[ \t]*[\n\r]")
(setq pos-with-space (match-end 0)))
;; Skip over nested tags.
(let ((count 0)
(regexp (concat start-regexp "\\|" end-regexp)))
(while (and (>= count 0)
(re-search-backward regexp nil t))
(if (= (char-after (1+ (point))) ?/)
;; End tag
(setq count (1+ count))
;; Start tag
(setq count (1- count))
(when (= count 0)
(when pos-with-space
;; Newline found after original end tag.
(skip-chars-backward " \t")
(if (bolp)
;; Don't include final newline unless the
;; start tag is the first thing on its line.
(setq pos pos-with-space)
(setq pos (1- pos-with-space))
;; Don't include non-leading space.
(skip-chars-forward " \t")))
(throw 'done (hui-select-set-region (point) pos)))))))))))
(if (integerp result)
(progn (goto-char result)
(error "(hui-select-markup-pair): Add a terminator character for this end tag"))
result))))