1

I'm putting the parsing techniques I'm learning into practice. I'm trying to write a programming mode in Emacs,so I can take advantage of syntax highlighting and the like. unfortunately, font-lock isn't working. Searching on Google and following the tutorials found there yielded no results. Below is my code. Any advice is appreciated.

;;;###autoload
(defgroup use-mode nil
  "Mode for editing Use source files."
  :group 'languages)

;;;###autoload
(defcustom use-mode-hook nil
  "Hook run when use-mode is started.")

(defvar use-mode-map (make-sparse-keymap)
"Keymap for use-mode.")

;;;###autoload
(add-to-list 'auto-mode-alist '("\\.use\\'" . use-mode))

(defvar use-keywords-1 '("use" . font-lock-keyword-face)
  "First level of font-lock in Use")

(defvar  use-font-lock-keywords use-keywords-1
  "Code highlighting.")

;;;###autoload
(define-derived-mode use-mode prog-mode "Use"
  "Major mode for editing Use source files."
  (setq font-lock-defaults '(use-font-lock-keywords)))

(provide 'use-mode)
Drew
  • 29,895
  • 7
  • 74
  • 104
Haden Pike
  • 259
  • 2
  • 7
  • 1
    Are you sure you want to `defcustom` your mode hook? For one, `define-derived-mode` automatically defines such a hook, but also hooks are typically things that end-users rarely set through Emacs' customization system, but rather directly in the init file. – Thomas Feb 23 '16 at 08:15
  • 1
    Don't autoload variables (not `defcustoms`), please, unless it's *absolutely* needed. – Stefan Feb 23 '16 at 14:42

1 Answers1

2

When you define font-lock keywords, you should supply a list of entries. So, if you replace:

(defvar use-keywords-1 '("use" . font-lock-keyword-face)
  "First level of font-lock in Use")

With the following, it will work:

(defvar use-keywords-1 '(("use" . font-lock-keyword-face))
  "First level of font-lock in Use")

Note that unless you plan to write a really advanced system, you don't need to provide different levels, so you can drop the *-1 variables.

(Just in case you haven't seen it already, I would like to recommend one of my packages, font-lock-studio. It is a interactive debugger for font-lock keywords.)

Lindydancer
  • 25,428
  • 4
  • 49
  • 68
  • Are you sure? When I try out your solution I get `Wrong type argument: listp` in Emacs 24.3.1. – Thomas Feb 23 '16 at 11:45
  • I just tried this in 24.5. Did you re-evaluate both `use-keywords-1` and `use-font-lock-keywords`? In which situation did you get the error? – Lindydancer Feb 23 '16 at 12:00
  • Ah, I probably didn't properly re-evaluate because `defvar` does not reset the value when eval'd a second time. `setq` to the rescue -- now it works beautifully. Upvoted! – Thomas Feb 23 '16 at 12:08
  • What do you think, though, of adding the second pair of parens in the definition of `use-font-lock-keywords`, as in the edit to my answer? – Thomas Feb 23 '16 at 12:10
  • Typically, font-lock keywords consist of a list of rules. Here, it only contained one (the highlighting of `use`). Once you would like to add a second rule, you must express it as a list of rules. E.g. `(defvar my-font-lock-keywords '(("use" . font-lock-keyword-face) ("var" . font-lock-variable-name-face)))`. Besides, if you name something "keywords" (with the plural "s"), you would expect it to be a collection, not just one. In addition, this is what major modes has been implemented for the past 20 years. – Lindydancer Feb 23 '16 at 12:18
  • Okay, the plural-s argument makes sense to me. Then if you have multiple "keywords" variables (use-keywords-1, use-keywords-2,...) you could append them in the definition of `my-font-lock-keywords`. – Thomas Feb 23 '16 at 12:31
  • In any event, I'm deleting my answer - it's partly wrong and what's right is covered in your answer too. – Thomas Feb 23 '16 at 12:32
  • Works perfectly in Emacs 24.5. Thanks for the help. – Haden Pike Feb 23 '16 at 14:58
  • I intend to extend the mode as I learn and add language constructs which is the reason I wanted the *-[1..3] levels of font-lock. – Haden Pike Feb 23 '16 at 15:01