+ (if multiple
+ (delete-dups (nreverse faces))
+ (car (last faces)))))
+
+(defun faces--attribute-at-point (attribute &optional attribute-unnamed)
+ "Return the face ATTRIBUTE at point.
+ATTRIBUTE is a keyword.
+If ATTRIBUTE-UNNAMED is non-nil, it is a symbol to look for in
+unnamed faces (e.g, `foreground-color')."
+ ;; `face-at-point' alone is not sufficient. It only gets named faces.
+ ;; Need also pick up any face properties that are not associated with named faces.
+ (let ((faces (or (get-char-property (point) 'read-face-name)
+ ;; If `font-lock-mode' is on, `font-lock-face' takes precedence.
+ (and font-lock-mode
+ (get-char-property (point) 'font-lock-face))
+ (get-char-property (point) 'face)))
+ (found nil))
+ (dolist (face (if (face-list-p faces)
+ faces
+ (list faces)))
+ (cond (found)
+ ((and face (symbolp face))
+ (let ((value (face-attribute-specified-or
+ (face-attribute face attribute nil t)
+ nil)))
+ (unless (member value '(nil "unspecified-fg" "unspecified-bg"))
+ (setq found value))))
+ ((consp face)
+ (setq found (cond ((and attribute-unnamed
+ (memq attribute-unnamed face))
+ (cdr (memq attribute-unnamed face)))
+ ((memq attribute face) (cadr (memq attribute face))))))))
+ (or found
+ (face-attribute 'default attribute))))