0

This question already has an answer here:

Recently, using fic-mode as reference, I implemented a way for words like TODO, etc. to be highlighted. Here is the code:

(defun todo/pos-in-doc-or-comment-region-p (pos)
  (memq (get-char-property pos 'face)
        '(font-lock-doc-face font-lock-comment-face)))

(defun todo/search-for-keyword (limit)
  (let ((original-match-data nil))
    (save-match-data
      (while (and (null original-match-data)
                  (re-search-forward "\\<\\(\\(\\(TODO(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(NOTE(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(FIXME(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(IMPORTANT(\\)\\([^)]+?\\)\\():\\)\\)\\)" limit t))
        (if (and (todo/pos-in-doc-or-comment-region-p (match-beginning 0))
                 (todo/pos-in-doc-or-comment-region-p (match-end 0)))
            (setq original-match-data (match-data)))))
    (when original-match-data
      (set-match-data original-match-data)
      (goto-char (match-end 0))
      t)))

(defvar todo/keywords
  '((todo/search-for-keyword  (3 font-lock-warning-face t t)
                              (4 font-lock-constant-face t t)
                              (5 font-lock-warning-face t t)
                              (7 font-lock-string-face t t)
                              (8 font-lock-constant-face t t)
                              (9 font-lock-string-face t t)
                              (11 font-lock-warning-face t t)
                              (12 font-lock-constant-face t t)
                              (13 font-lock-warning-face t t)
                              (15 font-lock-variable-name-face t t)
                              (16 font-lock-constant-face t t)
                              (17 font-lock-variable-name-face t t)
                              )))

(add-hook 'prog-mode-hook
          (lambda () (font-lock-add-keywords nil todo/keywords 'append)))

This was supposed to enable me to write things like TODO(name): something and have it properly highlighted like this:

What I wanted.

However, if I enable hl-line-mode using (global-hl-line-mode 1), the highlighting only happens if the point (cursor) is on a line different from the one on which the TODO... was typed. If I am on the same line, even doing font-lock-fontify-buffer does not refreshes syntax highlighting.

Also, once the highlighting has been "activated" (by pressing Enter, for example), if I come back to that line and edit something, the highlighting goes away once again.

Clash of the Highlitan

Can someone help as to how can I stop this clashing with hl-line-mode?


PS. I have set the line highlighting color using

(set-face-background hl-line-face theme/color/woodsmoke) ; hl-line

------------------------------------------------------------

Solution

Using the selected answer, putting

(set-face-attribute 'hl-line nil :inherit nil :background theme/color/woodsmoke)

before

(global-hl-line-mode 1)

fixes it.

marked as duplicate by Drew, DoMiNeLa10 Feb 16 at 12:05

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • I think this is a duplicate question, but I don't have time now to search for it. Maybe someone else can. – Drew Feb 15 at 16:02
  • And this is not the first such duplicate. – Drew Feb 16 at 1:33
1

I believe what you need to do is check the inheritance of the various faces. This can be done with describe-face. The available options are given in the manual under Face Attributes, but I believe the one you want is unspecified.

Here is what I use in my init.el for highlighting and how I solved the problem of the highlight clobbering other faces:

(load-theme 'tango-dark)
(global-hl-line-mode 1)
(set-face-attribute 'highlight nil :background "#3e4446" :foreground 'unspecified)

The first line changes the theme. The theme has a highlight color of bright yellow which will become apparent when we enable highlighting.

enter image description here

When highlighting is enabled, the highlight is glorious yellow,

enter image description here

This yellow overrides other faces,

enter image description here

However, using set-face-attribute, I can define what the :background is and leave the :foreground unspecified, leaving space for other faces,

enter image description here

  • I replaced (set-face-background hl-line-face theme/color/woodsmoke) by (set-face-attribute 'highlight nil :background theme/color/woodsmoke :foreground 'unspecified) but it didn't work. Thanks for pointing out the inheritance though, I'll try to hack something later. – strNOcat Feb 15 at 13:43
  • Also, hl-line doesn't really override any other syntax highlighting that comes bundled with Emacs, just this one that I've defined myself. – strNOcat Feb 15 at 13:51
  • EUREKA!!! Putting (set-face-attribute 'hl-line nil :inherit nil :background theme/color/woodsmoke) BEFORE (global-hl-line-mode 1) fixes it. I really need a better text editor! – strNOcat Feb 15 at 13:57
0

I have no idea why your solution works: AFAICT the problem is unrelated to what your faces are defined to look like. Instead it's your todo/pos-in-doc-or-comment-region-p which will get confused because when (get-char-property pos 'face) is called it will be "blinded" by the hl-line face and won't see the underlying faces applied by font-lock.

A quick hack is to use get-text-property instead of get-char-property (since hl-line-mode uses an overlay rather than text-properties). Personally I'd probably go for

(defun todo/pos-in-doc-or-comment-region-p (pos)
  (save-excursion (nth 8 (syntax-ppss pos)))

instead, tho. Also, I hate save-match-data so I'd rewrite your loop as follows:

(defun todo/search-for-keyword (limit)
  (let (ret)
    (while
      (and (setq ret (re-search-forward "\\<\\(\\(\\(TODO(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(NOTE(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(FIXME(\\)\\([^)]+?\\)\\():\\)\\)\\|\\(\\(IMPORTANT(\\)\\([^)]+?\\)\\():\\)\\)\\)" limit t))
           (not (and (todo/pos-in-doc-or-comment-region-p (match-beginning 0))
                     (todo/pos-in-doc-or-comment-region-p (match-end 0))))))
    ret))

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