2

I'm experimenting with making a major mode that does some simple syntax highlighting. My keywords are being highlighted just fine, but the quoted string in the example below is also being highlighted (but not by me).

Here is my code:

(defvar ct-mode-nset-keywords
  '("name" "type" "testme" "doc"))

(defvar ct-mode-nset-font-lock-defaults
      `((
         ;; highlight the second token on the name line
         ("^name:[ \t]*\\([-a-zA-Z][a-zA-Z0-9]+\\)"
          . (1 font-lock-function-name-face))
         ;; highlight all the other keywords
         ( ,(regexp-opt ct-mode-nset-keywords ) . font-lock-keyword-face)
         )))

(defun ct-nset-mode ()
  "Major mode for working with nameset files."
  (kill-all-local-variables)
  (setq major-mode 'ct-nset-mode)
  (setq mode-name "MyMode")
  (set (make-local-variable 'font-lock-defaults)
       ct-mode-nset-font-lock-defaults))

Here is my sample buffer. My keywords (name, type, doc) all highlight as expected. The second token on the name line also highlights as expected.

The problem is that the quoted string on the third line is being highlighted too (including the double quotes) by something.

name: wonky
type: string
doc : "this is a string"

In the sample buffer, if I evaluate the variable font-lock-defaults, I get the expected value:

font-lock-defaults
((("^name:[     ]*\\([-a-zA-Z][a-zA-Z0-9]+\\)" 1
    font-lock-function-name-face)
("\\(?:doc\\|\\(?:nam\\|t\\(?:estm\\|yp\\)\\)e\\)" 
    . font-lock-keyword-face)))

What code is font locking the quoted string? (My mode line says "MyMode Abbrev"), so I don't think any other modes are active. Thanks

5

This highlighting is syntactic font-lock highlighting. It occurs when variable font-lock-keywords-only is nil. This variable is normally set automatically by Font Lock mode based on the KEYWORDS-ONLY element in ‘font-lock-defaults’.

See the Elisp manual, node Syntactic Font Lock.

As that node explains, your major mode can use the function specified by variable syntax-propertize-function to apply ‘syntax-table’ text properties to override the buffer’s syntax table in special cases. (Syntactic highlighting uses the syntax table.)

See node Font Lock Basics of the Elisp manual for how to set variable font-lock-keywords-only to non-nil indirectly, by setting up the value of font-lock-defaults so that it has a non-nil KEYWORDS-ONLY part.

That means just using a value such as t as the second element of font-lock-defaults -- just after the list of keywords for normal (non-syntactic) font-lock highlighting. For example:

(defvar ct-mode-nset-font-lock-defaults
  `(( ;; highlight the second token on the name line
     ("^name:[ \t]*\\([-a-zA-Z][a-zA-Z0-9]+\\)" . (1 font-lock-function-name-face))
     ;; highlight all the other keywords
     ( ,(regexp-opt ct-mode-nset-keywords ) . font-lock-keyword-face))
    t)) ;; <================ non-nil KEYWORDS-ONLY

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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