Function: hui-select-goto-matching-tag

hui-select-goto-matching-tag is an autoloaded, interactive and byte-compiled function defined in hui-select.el.

Signature

(hui-select-goto-matching-tag)

Documentation

Move point to start of the tag paired with closest tag point is at or precedes.

Tag in this context is an sgml-like tag surrounded by angle brackets, <>. Enabled in major modes contained in the list, hui-select-markup-modes. Return t if point is moved, else nil. Signal an error if no tag is found following point or if the closing tag does not have a > terminator character.

Key Bindings

Source Code

;; Defined in ~/.emacs.d/elpa/hyperbole-20260414.325/hui-select.el
;;;###autoload
(defun hui-select-goto-matching-tag ()
  "Move point to start of the tag paired with closest tag point is at or precedes.
Tag in this context is an sgml-like tag surrounded by angle brackets, <>.
Enabled in major modes contained in the list, `hui-select-markup-modes'.
Return t if point is moved, else nil.  Signal an error if no tag is found
following point or if the closing tag does not have a `>' terminator character."
  (interactive)
  (when (memq major-mode hui-select-markup-modes)
    (let ((result)
	  ;; Assume case of tag names is irrelevant.
	  (case-fold-search t)
	  (opoint (point))
	  (tag)
	  end-point
	  start-regexp
	  end-regexp)

      ;; Leave point at the start of the tag that point is within or that
      ;; follows point.
      (cond
       ;; Point is at the start of a tag.
       ((looking-at "<[^<> \t\n\r]"))
       ;; Point was within a tag.
       ((and (re-search-backward "[<>]" nil t)
	     (looking-at "<[^<> \t\n\r]")))
       ;; Move to following tag.
       ((and (re-search-forward "<" nil t)
	     (progn (backward-char 1)
		    (looking-at "<[^<> \t\n\r]"))))
       ;; No tag follows point.
       (t (error "(hui-select-goto-matching-tag): No tag found after point")))

      (if (catch 'done
	    (cond
	     ;; Beginning of a tag pair
	     ((looking-at "<[^/][^<> \t\n\r]*")
	      (setq tag (match-string 0)
		    start-regexp (regexp-quote tag)
		    end-regexp   (concat "</" (substring start-regexp 1)))
	      ;; Skip over nested tags.
	      (let ((count 0)
		    (regexp (concat start-regexp "\\|" end-regexp))
		    match-point)
		(while (and (>= count 0)
			    (re-search-forward regexp nil t))
		  (setq match-point (match-beginning 0))
		  (if (/= (char-after (1+ (match-beginning 0))) ?/)
		      ;; Start tag
		      (setq count (1+ count))
		    ;; End tag
		    (setq end-point (point))
		    (if (or (not (re-search-forward "[<>]" nil t))
			    (= (preceding-char) ?<))
			;; No terminator character `>' for end tag
			(progn (setq result end-point)
			       (throw 'done nil)))
		    (setq count (1- count))
		    (when (zerop count)
		      (goto-char match-point)
		      (setq result t)
		      (throw 'done result))))))
	     ;;
	     ;; 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 tag (match-string 0)
		    end-regexp (regexp-quote tag)
		    start-regexp   (concat "<" (substring end-regexp 2)))
	      (setq end-point (point))
	      (when (or (not (re-search-forward "[<>]" nil t))
			(= (preceding-char) ?<))
		;; No terminator character `>' for end tag
		(setq result end-point)
		(throw 'done nil))
	      ;; 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 (zerop count)
		      (setq result t)
		      (throw 'done t))))))))
	  nil
	;; Didn't find matching tag.
	(goto-char opoint))

      (cond ((integerp result)
	     (goto-char result)
	     (error "(hui-select-goto-matching-tag): Add a terminator character for this end <tag>"))
	    ((null tag)
	     (error "(hui-select-goto-matching-tag): No <tag> following point"))
	    ((null result)
	     (when (called-interactively-p 'interactive)
	       (beep)
	       (message "(hui-select-goto-matching-tag): No matching tag for %s>" tag)
	       result))
	    (t result)))))