Does the minor mode whitespace library provide any way to apply different settings to different portions of the same buffer? For example, I might like to highlight `TAB characters in a comment block, since they can screw up YARD formatting, whilst not really caring about space-vs-TAB highlighting in actual code. (That's just an example; please don't over-analyse it. :-)

  • Tell us about what YARD is ... and how the comment strings in YARD look like
    – mxnt
    Commented Apr 7 at 5:26
  • Ensure that you use the snippet I shared in a sandbox, so that you save yourself some trouble just in case my font-lock code has some bugs. When there are font-lock bugs Emacs can at the worst freeze. Don't tell me that you haven't been warned. I am not a ruby developer, but what you ask for seems squarely in the lint territory. See if there are flymake or flycheck knobs for achieving what you want.
    – mxnt
    Commented Apr 7 at 10:35

1 Answer 1


To get this

Highlight tab in coments in yard-mode

Highlight tab in coments in yard-mode

on this

(Remember to do M-x tabify on the snippet below)


#       Reverses the contents of a String or IO object.
        # @param contents [String, #read] the contents to reverse
        # @return [String] the contents reversed lexically
def reverse(contents)
  contents = contents.read if contents.respond_to? :read

do this


;; -*- lexical-binding: t; -*-

;; https://emacs.stackexchange.com/questions/80966/separate-whitespace-settings-for-comment-reqions

(require 'subr-x)
(require 'seq)

(defgroup highlight-tab-in-comments nil
  "Options for Subword Highlight."
  :tag "Subword Highlight"
  :group 'highlight-tab-in-comments)

(defcustom highlight-tab-in-comments-overlays-priority 0
  "*Priority of the overlays created by `highlight-tab-in-comments'."
  :type 'integer
  :group 'highlight-tab-in-comments)

(defface highlight-tab-in-comments-face
  '((t (:box (:line-width (2 . 2) :color "red" :style released-button))))
  "Basic overline face."
  :group 'highlight-tab-in-comments)

(defun highlight-tab-in-comments-add-overlay-face (start end face)
  (let ((overlay (make-overlay start end)))
    (overlay-put overlay 'face face)
    (overlay-put overlay 'highlight-tab-in-comments face)
    (overlay-put overlay 'priority highlight-tab-in-comments-overlays-priority)))

(defun highlight-tab-in-comments-unfontify-region (beg end &optional _maybe_loudly)
  (font-lock-default-unfontify-region beg end)
  (thread-last (list beg end)
               (apply #'overlays-in)
               (seq-filter (lambda (it)
                             (overlay-get it 'highlight-tab-in-comments)))
               (seq-do #'delete-overlay)))

(defun highlight-tab-in-comments (&optional limit)
  (pcase-let* ((regexp (rx "\t")))
    (catch :exit
      (while (re-search-forward regexp limit t)
        (when (nth 4 (syntax-ppss)) ;; comment
          (let* ((start (match-beginning 0))
                 (end (match-end 0)))
             start end 'highlight-tab-in-comments-face)
            (throw :exit t)))))))

(define-minor-mode highlight-tab-in-comments-mode
  "highlight tab in comments"
  :lighter " highlight tab in comments"
  :group 'highlight-tab-in-comments
  (let ((rule `((highlight-tab-in-comments))))
      (font-lock-add-keywords nil rule)
      (setq-local font-lock-unfontify-region-function 'highlight-tab-in-comments-unfontify-region))
      (highlight-tab-in-comments-unfontify-region (point-min) (point-max))
      (font-lock-remove-keywords nil rule)

(provide 'highlight-tab-in-comments)

and this

Init snippet

(use-package whitespace-mode
  :hook (ruby-mode . whitespace-mode))

(use-package yard-mode
  :load-path "/home/kjambunathan/src1/nongnu/packages/init-directory-new/straight/repos/yard-mode.el/"
  :hook (ruby-mode . yard-mode))

(use-package highlight-tab-in-comments
  :demand t
  :load-path "/home/kjambunathan/src/emacs-stackexchange/highlight-tab-in-comments/"
  :hook (yard-mode . highlight-tab-in-comments-mode))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.