 The function can also return a positive integer to indicate
 a specific level to which the current line could be indented.")
 
+(defconst haml-tag-beg-re
+  "^ *\\(?:[%\\.#][a-z0-9_:\\-]*\\)+\\(?:(.*)\\|{.*}\\|\\[.*\\]\\)*"
+  "A regexp matching the beginning of a Haml tag, through (), {}, and [].")
+
 (defvar haml-block-openers
-  `("^ *\\([%\\.#][a-z0-9_:\\-]*\\)+\\({.*}\\)?\\(\\[.*\\]\\)?[><]*[ \t]*$"
+  `(,(concat haml-tag-beg-re "[><]*[ \t]*$")
     "^ *[&!]?[-=~].*do[ \t]*\\(|.*|[ \t]*\\)?$"
     ,(concat "^ *[&!]?[-=~][ \t]*\\("
              (regexp-opt '("if" "unless" "while" "until" "else"

      (forward-char -1)

      ;; Highlight tag, classes, and ids
      (while (looking-at "[.#%][a-z0-9_:\\-]*")
        (put-text-property (match-beginning 0) (match-end 0) 'face
                           (case (char-after)
                             (?% font-lock-function-name-face)
                             (?# font-lock-keyword-face)
                             (?. font-lock-type-face)))
        (goto-char (match-end 0)))

      ;; Highlight obj refs
      (when (eq (char-after) ?\[)
        (let ((beg (point)))
          (haml-limited-forward-sexp eol)
          (haml-fontify-region-as-ruby beg (point))))

      ;; Highlight attr hashes
      (when (eq (char-after) ?\{)
        (let ((beg (point)))
          (haml-limited-forward-sexp eol)

          ;; Check for multiline
          (while (and (eolp) (eq (char-before) ?,) (not (eobp)))
            (forward-line)
            (let ((eol (save-excursion (end-of-line) (point))))
              ;; If no sexps are closed,
              ;; we're still continuing a  multiline hash
              (if (>= (car (parse-partial-sexp (point) eol)) 0)
                  (end-of-line)
                ;; If sexps have been closed,
                ;; set the point at the end of the total sexp
                (goto-char beg)
                (haml-limited-forward-sexp eol))))

          (haml-fontify-region-as-ruby (+ 1 beg) (point))))

      ;; Move past end chars
      (when (looking-at "[<>&!]+") (goto-char (match-end 0)))

  "Returns t if the current line can have lines nested beneath it."
  (let ((attr-props (haml-parse-multiline-attr-hash)))
    (when attr-props
      (return-from haml-indent-p
        (if (haml-unclosed-attr-hash-p) (cdr (assq 'hash-indent attr-props))
          (list (+ (cdr (assq 'indent attr-props)) haml-indent-offset) nil)))))
  (loop for opener in haml-block-openers
        if (looking-at opener) return t
