8

I am developing an emacs major mode for a language (aka mydsl). However, using the techniques on xahlee's site doesn't seem to be working for some reason (possibly older emacs dialect..)

The key issues I am fighting with are (1) highlighting comments is not working and (2), the use of regexp-opt lines is not working.

I've reviewed the GNU manual and looked over cc-mode and elisp mode... those are significantly more complicated than I need.

;;;Standard # to newline comment
;;;Eventually should also have %% to %% multiline block comments

(defun mydsl-comment-dwim (arg)
  "comment or uncomment"
  (interactive "*P")
  (require 'newcomment)
  (let
      ((deactivate-mark nil)
       (comment-start "#")
       (comment-end "")
       comment-dwim arg)))

(defvar mydsl-events
  '("reservedword1"  
    "reservedword2"))

(defvar mydsl-keywords
  '("other-keyword" "another-keyword"))

;;Highlight various elements
(setq mydsl-hilite
      '(
        ; stuff between "
        ("\"\\.\\*\\?" . font-lock-string-face)
        ; : , ; { } =>  @ $ = are all special elements
        (":\\|,\\|;\\|{\\|}\\|=>\\|@\\|$\\|=" . font-lock-keyword-face)
        ( ,(regexp-opt mydsl-keywords 'words) . font-lock-builtin-face)
        ( ,(regexp-opt mydsl-events 'words) . font-lock-constant-face)
))


(defvar mydsl-tab-width nil "Width of a tab for MYDSL mode")

(define-derived-mode mydsl-mode fundamental-mode
  "MYDSL mode is a major mode for editing MYDSL  files"
  ;Recommended by manual
  (kill-all-local-variables)
  (setq mode-name "MYDSL script")
  (setq font-lock-defaults '((mydsl-hilite)))  
  (if (null mydsl-tab-width)
      (setq tab-width mydsl-tab-width)
    (setq tab-width default-tab-width)
    )

  ;Comment definitions
  (define-key mydsl-mode-map [remap comment-dwim] 'mydsl-comment-dwim)
  (modify-syntax-entry ?# "< b" mydsl-mode-syntax-table)
  (modify-syntax-entry ?\n "> b" mydsl-mode-syntax-table)
  ;;A gnu-correct program will have some sort of hook call here.
  )

(provide 'mydsl-mode)
Paul Nathan
  • 39,638
  • 28
  • 112
  • 212
  • 3
    You do realize that Xah's site is satire, right? – jrockway Jun 06 '10 at 04:09
  • @jrockway - his emacs stuff seems to be mostly solid. I'm not sure what you mean. – Paul Nathan Jun 07 '10 at 15:40
  • I can't speak for jrockway, while I find Xah's information around Emacs prolific and well-intentioned, it often deviates from Emacs lisp norms and conventions, which I believe teach the wrong things. e.g. `mydsl-comment-dwim` is the wrong way to go about customizing `comment`'s behavior. Similarly, on Xah's page I quickly found a `wrap-markup` definition which (though functional) breaks the convention of taking arguments and using `(interactive "r")` to pass in the region. – Trey Jackson Jun 11 '10 at 03:52

1 Answers1

10

You have a couple of syntactic problems in your code, but you got it nearly correct. Here's my edited version which appears to do the right thing for a buffer in mydsl-mode:

; No changes to the simple vars
(defvar mydsl-events
  '("reservedword1"  
    "reservedword2"))

(defvar mydsl-keywords
  '("other-keyword" "another-keyword"))

;; I'd probably put in a default that you want, as opposed to nil
(defvar mydsl-tab-width nil "Width of a tab for MYDSL mode")

;; Two small edits.
;; First is to put an extra set of parens () around the list
;; which is the format that font-lock-defaults wants
;; Second, you used ' (quote) at the outermost level where you wanted ` (backquote)
;; you were very close
(defvar mydsl-font-lock-defaults
  `((
     ;; stuff between "
     ("\"\\.\\*\\?" . font-lock-string-face)
     ;; ; : , ; { } =>  @ $ = are all special elements
     (":\\|,\\|;\\|{\\|}\\|=>\\|@\\|$\\|=" . font-lock-keyword-face)
     ( ,(regexp-opt mydsl-keywords 'words) . font-lock-builtin-face)
     ( ,(regexp-opt mydsl-events 'words) . font-lock-constant-face)
     )))

(define-derived-mode mydsl-mode fundamental-mode "MYDSL script"
  "MYDSL mode is a major mode for editing MYDSL  files"

  ;; fundamental-mode kills all local variables, no need to do it again
  (setq mode-name "MYDSL script")

  ;; you again used quote when you had '((mydsl-hilite))
  ;; I just updated the variable to have the proper nesting (as noted above)
  ;; and use the value directly here
  (setq font-lock-defaults mydsl-font-lock-defaults)

  ;; when there's an override, use it
  ;; otherwise it gets the default value
  (when mydsl-tab-width
    (setq tab-width mydsl-tab-width))

  ;; for comments
  ;; overriding these vars gets you what (I think) you want
  ;; they're made buffer local when you set them
  (setq comment-start "#")
  (setq comment-end "")

  (modify-syntax-entry ?# "< b" mydsl-mode-syntax-table)
  (modify-syntax-entry ?\n "> b" mydsl-mode-syntax-table)
  ;;A gnu-correct program will have some sort of hook call here.
  )

(provide 'mydsl-mode)
event_jr
  • 17,467
  • 4
  • 47
  • 62
Trey Jackson
  • 73,529
  • 11
  • 197
  • 229
  • The modify-syntax-entry stuff comes from http://xahlee.org/emacs/elisp_comment_handling.html. The modify-syntax-entry stuff is - I think? the right way to manage comment handling, else emacs will highlight code in the comments. At any rate, the comment code doesn't work. – Paul Nathan Jun 04 '10 at 20:14
  • Note- The comment-dwim remap lets comment-dwim work correctly with mydsl-mode. According to Xahlee, the modify-syntax-entry descriptors should create comment highlighting. – Paul Nathan Jun 04 '10 at 22:48
  • @PaulNathan I don't see any difference between what I have (setting the comment vars and just using `comment-dwim` natively, and what Xah has written). `comment-dwim` works to comment out a region using `#` characters with my code. Emacs 23.1. – Trey Jackson Jun 05 '10 at 02:37
  • @Trey - Huh. I figured out `comment-dwim`, but the syntax table modifcations still won't work. I'm feeling I'm missing something completely obvious. I've tried different color themes. I have the latest emacs 23. – Paul Nathan Jun 05 '10 at 04:32
  • @Paul What do you mean the syntax table modifications don't work? Need more info. I comment out the `modify-syntax-entry` lines in a fresh Emacs and get proper comment highlighting. – Trey Jackson Jun 11 '10 at 03:32
  • @Trey: Highlighting isn't happening at all. :-) – Paul Nathan Jun 11 '10 at 23:24
  • @PaulNathan Here's what I did, using Emacs 23.1 on Windows. `emacs -q`, I then eval'ed the code I provided. Then I typed the stuff you're about to see, and did `M-x mydsl-mode`, and then set the background to `LightBlue` (so the colors would stand out). And this is what I got: http://img810.imageshack.us/img810/2808/emacsmydslmode2.jpg – Trey Jackson Jun 12 '10 at 02:54
  • @PaulNathan So (if I were you), I'd try the same - the `-q` (and possibly with `--no-site-file`) telling Emacs to not use your customizations. Maybe something in those customizations is mussing up your experience. – Trey Jackson Jun 14 '10 at 18:38
  • @PaulNathan Yah, you do need the `modify-syntax-entry`, I should have verbalized that earlier, you were right. So, do you have things working for yourself now? – Trey Jackson Jun 16 '10 at 18:39
  • Close - with the blank emacs, it works, but there's something fiddly with my customized setup that the commenting is fried. – Paul Nathan Jun 16 '10 at 18:44
  • @PaulNathan Well, good luck finding that. Hopefully your .emacs isn't too large. Progressively enabling chunks of my .emacs until I found the section which had the bad effect was the easiest way for me to solve this kind of problem. – Trey Jackson Jun 16 '10 at 19:12