0

I am very new to Emacs and I am discovering the functionality of "generic-mode" for the first time. I am trying to add a generic-mode to create basic syntax highlighting for an obscure programming language that I use. It's very simple:

;; BEGIN mtl-mode
(define-generic-mode
    ;; name of mode
    'mtl-mode
    ;; comments
    ;; '("(*" . "\*)") Opening comment is (* closing is *) but not sure how to do it!
    nil
    ;; keyword list
    '("ACV" "CONTACT" "DISCHARGE" "FOR" "MODULE" "REPEAT" "TESTMACRO"
      "TRANSF" "WITH" "BITS" "CONTINUE" "ELSE" "IF" "OPTO" "RES"
      "TESTPINS" "TYPEOF" "ZENER" "BREAK" "DCI" "IND" "PATGEN"
      "RETURN" "TESTMODULE" "UNTIL" "CAP" "DCV" "EXIT" "LED" "PIN"
      "TRACK" "CASE" "DIODE" "FET" "LINK" "PULSE" "TESTBLOCK" "TRAN"
      "WHILE" "PRINTF" "FFLUSH" "STDOUT"
      )
    ;; font-lock list
    '()
    ;; auto-mode list
    '(".*mtl")
    ;; function list
    nil
    ;; documentation
    "Mode for editing Aeroflex ICT MTL files")
;; END mtl-mode

This works fine for a start, but the keywords are not actually case sensitive in MTL. Is there a way to specify that they should not be treated as such? Or do I have to add separate keyword cases to the list for each common possibility (e.g. "WHILE" "while")

  • 1
    By the way, you're just missing a level of nesting for the comment list: '(("(*" . "*)")) – npostavs Jun 27 '16 at 14:26
  • Hm. I tried your suggestion and felt certain that it wouldn't work. It does work, so you are right, but I don't know why! The extra set of nesting looks redundant to me, but clearly it isn't... Thanks very much for the info. Now I know that it works, I will have to try to understand why. – Q'' Jun 27 '16 at 14:40
  • 1
    To understand why, maybe it helps to write it like this (list (cons "(*" "*)")), your original attempt is equivalent to (cons "(*" "*)"). See also Dotted Pair Notation – npostavs Jun 27 '16 at 15:00
  • 1
    Ah, okay, so if I understand correctly the way I wrote it (with your correction) is actually a kind of short-hand for the more explicit (list (cons "(*" "*)")) – Q'' Jun 28 '16 at 8:20
2

Font-lock provides a variable, font-lock-keywords-case-fold-search, that controls whether keywords should be seen as case sensitive or not:

Non-nil means the patterns in font-lock-keywords are case-insensitive. This is set via the function font-lock-set-defaults, based on the CASE-FOLD argument of font-lock-defaults.

Normally, when you add font-lock keywords the normal way (using font-lock-defaults), you can specify it there. Using define-generic-mode you don't have that option. Check if you can add a specific font-lock setup function in the "function list" to do this.

If you have some keywords that are case sensitive and some that are not, things get more complicated. In that case you would have to replace some font-lock keywords regexp:s with your own search functions, that bind case-fold-search and do the search using, for example, search-forward-regexp.

  • Unfortunately my knowledge of Emacs is not good enough to immediately test your answer, so give me a couple of days to get to the bottom of it and then I will come back here to update. Thanks. – Q'' Jun 27 '16 at 14:34
  • I have tried your suggestion by writing a derived mode and it works perfectly. Still trying to figure out if it's possible to do it using a generic-mode... – Q'' Jun 30 '16 at 16:47
  • @user12230, it should be possible. Try to write a simple function only setting the font-lock-keywords-case-fold-search variable, and add the variable to the "function list" in your call to define-generic-mode. – Lindydancer Jun 30 '16 at 18:27

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.