help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

how do I have a mode where '#' is a comment but '.#.' isn't?


From: stuart
Subject: how do I have a mode where '#' is a comment but '.#.' isn't?
Date: Tue, 16 Dec 2008 15:54:02 -0800 (PST)
User-agent: G2/1.0

I have been working on a mode for a program where a hash mark by
itself is a comment character (#) whereas a hash mark surrounded by
dots (.#.) is not. Currently, I'm using this:

;; Change the interpretation of particular chars in Emacs' syntax
table
(defvar fst-mode-syntax-table
  (let ( (fst-mode-syntax-table (make-syntax-table) ) )
    (modify-syntax-entry  ?#   "<"   fst-mode-syntax-table)  ; start
comment
    (modify-syntax-entry  ?\n  ">"   fst-mode-syntax-table)  ; end
comment
    (modify-syntax-entry  ?\\  "_"   fst-mode-syntax-table)  ; don't
escape quote
    (modify-syntax-entry  ?%   "/"   fst-mode-syntax-table)  ;
functions as escape char
    fst-mode-syntax-table )
  "Syntax table for fst-mode" )

But it doesn't do the right thing--i.e., it treats '.#.' as a dot
followed by a comment. Is there any easy fix here? Thanks in advance.

P.S. Here's the entire mode file:

;;
---------------------------------------------------------------------------
;; Author:       Stuart Robinson
;; Date:         10 September 2007
;; Description:  This file provides an fst mode for emacs
;; Versions:     0.1 -- initial implementation for fst files with the
suffix
;;                      .infile
;;               0.2 -- cleaned up regex for built-ins, fixed
highlighting
;;                      glitches observed by Lauri Karttunen ,
added .script
;;                      file suffix for mode
;;               0.3 -- fixed built-in highlighting for 'regex' and
'push'
;;               0.4 -- backslashes are handled properly (not as
escape char)
;;               0.5 -- various minor fixes (added .p./.P./.o.)
;; Notes:        * original implementation based on code found at
;;                 http://two-wugs.net/emacs/mode-tutorial.html
;;               * the pre-defined font categories for emacs need to
be thought
;;                 out in terms of fst: for example, commands and
built-in
;;                 variables alike are treated as builtins, and it's
not clear
;;                 what a keyword would be; there are also probably
more constants
;; Bugs:         * curly braces should be treated as string
delimiteres (like
;;                 quotes)
;;               * pound sign in .#. treated as beginning of comment
;;
---------------------------------------------------------------------------

(defvar fst-mode-hook nil)

(defvar fst-mode-map
  (let ((fst-mode-map (make-keymap)))
    (define-key fst-mode-map "\C-j" 'newline-and-indent)
    fst-mode-map)
  "Keymap for fst major mode")

;; built-ins & variables

(defconst fst-font-lock-keywords-1
  (list
   ;; NOTE: The regex is wrapped in \\< and \\> to ensure that it only
matches words
   ;;       (i.e., it doesn't match substrings). It is generated by
running the program
   ;;       keyword-list-to-emacs-regex.rb on the file fst-keywords-no-
spaces.txt.
   '("\\<\\(for\\|add properties\\|ambiguity net\\|\\(apply \\
(patterns \\)?\\)?\\(up\\|down\\)\\|cleanup net\\|clear\\( stack\\)?\\|
close sigma\\|collect epsilon-loops\\|compact \\(net
\\|sigma\\)\\|compile-replace \\(upper\\|lower\\)\\|complete net\\|
compose\\( net\\)?\\|compose-apply \\(up\\|down\\)\\|concatenate\\( net
\\)?\\|continue script\\|crossproduct net\\|det
erminize net\\|edit properties\\|eliminate flag\\|epsilon-remove net\\|
extract-compile-replace \\(upper\\|lower\\)\\|factorize \\(up\\|down\\)
\\|ignore net\\|inspect net\\|interrupt scr
ipt\\|intersect\\( net\\)?\\|invert\\( net\\)?\\|label net\\|load\\( \\
(defined\\|stack\\)\\)?\\|lower-side net\\|minimize net\\|minus net\\|
multi char sigma net\\|name net\\|negate\\(
net\\)?\\|one-plus net\\|optimize net\\|paste net labels\\|pop stack\\|
print \\(aliases\\|arc-tally\\|defined\\|directory\\|eqv-labels\\|file-
info\\|flags\\|label-maps\\|label-tally\\|l
abels\\|list\\|lists\\|longest-string\\(-size\\)?\\|lower-words\\|name\
\|net\\|nth-lower\\|nth-upper\\|num-lower\\|num-upper\\|random-lower\\|
random-upper\\|random-words\\|shortest-stri
ng\\(-size\\)?\\|sigma\\(\\(-word\\)?-tally\\)?\\|size\\|stack\\|
storage\\|upper-words\\|words\\)\\|prune net\\|push\\( \\(defined\\|
epsilons\\)\\)?\\|\\(read \\)?regex\\|read \\(lec\\|
lexc\\|prolog\\|properties\\|spaced-text\\|text\\)\\|reduce labelset\\|
reverse\\( net\\)?\\|rotate stack\\|save\\( \\(defined\\|stack\\)\\)?\
\|share arcs\\|shuffle net\\|sigma net\\|sin
gle char sigma net\\|sort net\\|sub-string net\\|substitute \\(defined\
\|label\\|symbol\\)\\|substring net\\|\\(test \\)?equivalent\\|test \\
(lower-bounded\\|lower-universal\\|non-null\
\|null\\|overlap\\|sublanguage\\|unambiguous-down\\|unambiguous-up\\|
upper-bounded\\|upper-universal\\)\\|turn stack\\|twosided flag-
diacritics\\|uncompact net\\|unfactorize down\\|unfa
ctorize up\\|union\\( net\\)?\\|unoptimize\\( net\\)?\\|unreduce
labelset\\|unshare arcs\\|unvectorize net\\|upper-side net\\|vectorize
net\\|virtual \\(compose\\|concatenate\\|copy\\|d
eterminize\\|intersect\\|lower\\|minus\\|negate\\|one-plus\\|option\\|
priority-union\\|union\\|upper\\|zero-plus\\)\\|write \\(definition\\|
dot\\|prolog\\|properties\\|spaced-text\\|tex
t\\)\\|zero-plus net\\|alias\\|apropos\\|assert\\|char-encoding\\|
completion\\|copyright-owner\\|count-patterns\\|define\\|delete-
patterns\\|directory\\|echo\\|extract-patterns\\|fail-s
afe-composition\\|flag-is-epsilon\\|help\\|label-map\\|license-type\\|
list\\|locate-patterns\\|mark-\\(patterns\\|version\\)\\|max-\\
(context-length\\|state-visits\\)\\|minimal\\|name-n
ets\\|need-separators\\|obey-flags\\|print-\\(pairs\\|sigma\\|space\\)\
\|process-in-order\\|quit\\(-on-fail\\)?\\|quote-special\\|random-seed\
\|recode-cp1252\\|recursive-\\(apply\\|defi
ne\\)\\|retokenize\\|seq-\\(final-arcs\\|intern-arcs\\|string-one\\)\\|
set\\|show\\(-flags\\)?\\|sort-arcs\\|source\\|system\\|undefine\\|
unlist\\|use-mmap\\|use-timer\\|vectorize-n\\|v
erbose\\|virtual-to-real\\)\\>" . font-lock-builtin-face)
   '("\\('\\w*'\\)" . font-lock-variable-name-face))
  "Minimal highlighting expressions for FST mode")

;; keywords and constants

(defconst fst-font-lock-keywords-2
  (append fst-font-lock-keywords-1
                  (list
                   '("\\(\\$\\|?\\|~\\|@\\||\\|->\\|<-\\|&\\|_\\|*\\|\\
\\\\|0\\|\\.#\\.\\|\\.P\\.\\|\\.p\\.\\|\\.o\\.\\|@->\\|->@\\|@>\\|>@\
\)" . font-lock-keyword-face)
                   '("\\<\\(ON\\|OFF\\|NONE\\)\\>"   . font-lock-
constant-face)))
  "Additional Keywords to highlight in FST mode")

;; don't understand why this is necessary...

(defconst fst-font-lock-keywords-3
  (append fst-font-lock-keywords-2
                  (list
                   '("" . font-lock-constant-face)))
  "Balls-out highlighting in FST mode")

(defvar fst-font-lock-keywords fst-font-lock-keywords-3
  "Default highlighting expressions for FST mode")

;; Indentation not being handled properly--needs to be updated
(defun fst-indent-line ()
  "Indent current line as FST code"
  (interactive)
  (beginning-of-line)
  ; Check for rule 1
  (if (bobp)
      (indent-line-to 0)
    (let ((not-indented t) cur-indent)
      ; Check for rule 2
      (if (looking-at "^[ \t]*END_")
          (progn
            (save-excursion
              (forward-line -1)
              (setq cur-indent (- (current-indentation) default-tab-
width)))
            (if (< cur-indent 0)
                (setq cur-indent 0)))
        (save-excursion
          (while not-indented
            (forward-line -1)
            ; Check for rule 3
            (if (looking-at "^[ \t]*END_")
                (progn
                  (setq cur-indent (current-indentation))
                  (setq not-indented nil))
              ; Check for rule 4
              (if (looking-at "^[ \t]*\\(PARTICIPANT\\|MODEL\\|
APPLICATION\\|WORKFLOW\\|ACTIVITY\\|DATA\\|TOOL_LIST\\|TRANSITION\\)")
                  (progn
                    (setq cur-indent (+ (current-indentation) default-
tab-width))
                    (setq not-indented nil))
                ; Check for rule 5
                (if (bobp)
                    (setq not-indented nil)))))))
      ; If we didn't see an indentation hint, then allow no
indentation
      (if cur-indent
          (indent-line-to cur-indent)
        (indent-line-to 0)))))


;; Change the interpretation of particular chars in Emacs' syntax
table
(defvar fst-mode-syntax-table
  (let ( (fst-mode-syntax-table (make-syntax-table) ) )
    (modify-syntax-entry  ?#   "<"   fst-mode-syntax-table)  ; start
comment
    (modify-syntax-entry  ?\n  ">"   fst-mode-syntax-table)  ; end
comment
    (modify-syntax-entry  ?\\  "_"   fst-mode-syntax-table)  ; don't
escape quote
    (modify-syntax-entry  ?%   "/"   fst-mode-syntax-table)  ;
functions as escape char
    fst-mode-syntax-table )
  "Syntax table for fst-mode" )


(defun fst-mode ()
  "Major mode for editing fst scripts"
  (interactive)
  (kill-all-local-variables)
  (set-syntax-table fst-mode-syntax-table)
  (use-local-map fst-mode-map)
  (set (make-local-variable 'font-lock-defaults) '(fst-font-lock-
keywords))
  (set (make-local-variable 'indent-line-function) 'fst-indent-line)
  (setq major-mode 'fst-mode)
  (setq mode-name "FST")
  (run-hooks 'fst-mode-hook))


;; Make FST mode available for .infile and .script files
(provide 'fst-mode)
(add-to-list 'auto-mode-alist '("\\.infile\\'" . fst-mode))
(add-to-list 'auto-mode-alist '("\\.script\\'" . fst-mode))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]