Problems with New Language Mode

Aaron Hsu arcfide at sacrificumdeo.net
Mon Apr 23 05:06:35 CEST 2007


Hello all,

I am attempting to rennovate the existing Scheme Mode that is available in  
the contrib directory. It was very incomplete as far as keywords and other  
features go. Some of the stuff seems to be rather complicated to do.

1) Highlighting quoted and quasiquoted texts. That is, items of the form:

	'some-teesxt/or
	'(a b c d)
	'(a (b c) (a b c))
	`(something ,call-out)
	`(something ,(call-function me))

The first few seem easy enough to do, but the last two are not so fun.  
,call-out should be highlighted separately and different than everything  
around it, as should ,(call-function me). call-function should also be  
highlighted differently if it is a keyword.

2) I have a bunch of keywords that I am using, and most of them seem to  
work very well. However, for some apparently random reason, certain  
keywords are matched correctly, and others are not. The form I am using  
thus far is <(keyword1|keyword2)>. For examples of what isn't be matched:  
<(let\*|let)> only matches let* and not let. On my character constants  
list which is similar in function, I have something like  
<(#f|#t|#\\something)> and the #\\something and #f both are highlighted as  
expected, but #t is not.

3) Scheme is a Lisp and requires some rather interesting indenting. For  
example:

   (let ((test (function))
         (test2 (function2 teat
                           arg2))
         (test3
           (function3)))
     (main-something arg1
                     arg2)
     (if (test this that)
         (something)
         (something-else))
     (What is this))

As this shows, certain special functions are indented only two spaces in  
 from the outer parens once a certain number of args have been fed. In the  
case of LET this is after one argument. Usually, most functions are  
indented two spaces if just the procedure call is on one line, as seen  
 from the TEST3 part. However, if one or more arguments are already on the  
same line with the procedure call, then the next line is indented to match  
with the first argument, as demonstratd by FUNCTION2. If a single  
parenthesis is opened and there is no procedure called at the start, such  
as in the example ((test (function)) ...) then it is indented just one  
space in from the opening parenthesis.

The current smart-indentation available in the contrib/ directory is  
woefully inadequate and actually completely incorrect on my system. I am  
kind of at a loss as to how to begin doing indentation of this kind. I am  
not familar with the NEdit macro language.

Below I am copying in my relevant .rc file contents. I hope that this will  
be helpful and that someone can give me some advice as to the problems I  
am experiencing and maybe even help me implement some of this stuff.

nedit.highlightPatterns: Ada:Default\n\
[...]
	Scheme:1:0{\n\
		Comment:";":"$"::Comment::\n\
		Quoted Constant:"'":"[ \\t\\n;]"::Text Key::\n\
		Quasiquote:"`":"[; ""\\n\\t]"::Text Key::\n\
		Quoted List:"\\(":"\\)"::Text Key:Quoted Constant:\n\
		Quasiquote List:"\\(":"\\)"::Text Key:Quasiquote:\n\
		Quasiquote Escape:",[^ ;\\n\\t()]*":::Text Arg:Quasiquote List:\n\
		Character  
Constant:"<(#t|#f|#\\\\space|#\\\\newline|#\\\\.|#\\\\bel|#\\\\backspace|#\\\\page|#\\\\return|#\\\\tab|#\\\\vt|#\\\\[0-9]{3})>":::Text  
Key::\n\
		Numeric Constant:"<(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))>":::Text Key1::\n\
		R5RS  
Keywords:"<(\\*|\\+|-|/|\\<|\\<=|=|\\>|\\>=|abs|acos|and|angle|append|apply|asin|assoc|assq|assv|atan|atan|begin|boolean\\?|bound-identifier=\\?|caaaar|caaadr|caaar|caadar|caaddr|caadr|caar|cadaar|cadadr|cadar|caddar|cadddr|caddr|cadr|call-with-current-continuation|call-with-input-file|call-with-output-file|call-with-values|car|case|cdaaar|cdaadr|cdaar|cdadar|cdaddr|cdadr|cdar|cddaar|cddadr|cddar|cdddar|cddddr|cdddr|cddr|cdr|ceiling|char-\\>integer|char-alphabetic\\?|char-ci\\<=\\?|char-ci\\<\\?|char-ci=\\?|char-ci\\>=\\?|char-ci\\>\\?|char-downcase|char-lower-case\\?|char-numeric\\?|char-ready\\?|char-upcase|char-upper-case\\?|char-whitespace\\?|char\\<=\\?|char\\<\\?|char=\\?|char\\>=\\?|char\\>\\?|char\\?|close-input-port|close-output-port|complex\\?|cond|cons|cos|current-input-port|current-output-port|datum-\\>syntax-object|define|define-syntax|delay|denominator|display|do|dynamic-wind|eof-object\\?|eq\\?|equal\\?|eqv\\?|eval|even\\?|exact-\\>inexact|exact\\?|exp|expt|floor|fluid 
-let-syntax|for-each|force|free-identifier=\\?|gcd|generate-temporaries|identifier\\?|if|imag-part|inexact-\\>exact|inexact\\?|input-port\\?|integer-\\>char|integer\\?|interaction-environment|lambda|lcm|length|let|let\\*|let-syntax|letrec|letrec-syntax|list|list-\\>string|list-\\>vector|list-ref|list-tail|list\\?|load|log|magnitude|make-polar|make-rectangular|make-string|make-vector|map|max|member|memq|memv|min|modulo|negative\\?|newline|not|null-environment|null\\?|number-\\>string|number\\?|numerator|odd\\?|open-input-file|open-output-file|or|output-port\\?|pair\\?|peek-char|positive\\?|procedure\\?|quasiquote|quote|quotient|rational\\?|rationalize|read|read-char|real-part|real\\?|remainder|reverse|round|scheme-report-environment|set!|set-car!|set-cdr!|sin|sqrt|string|string-\\>list|string-\\>number|string-\\>symbol|string-append|string-ci\\<=\\?|string-ci\\<\\?|string-ci=\\?|string-ci\\>=\\?|string-ci\\>\\?|string-copy|string-fill!|string-length|string-ref|string-set!|string\\<=\\ 
?|string\\<\\?|string=\\?|string\\>=\\?|string\\>\\?|string\\?|substring|symbol-\\>string|symbol\\?|syntax|syntax-case|syntax-object-\\>datum|syntax-rules|tan|transcript-off|transcript-on|truncate|unquote|unquote-splicing|values|vector|vector-\\>list|vector-fill!|vector-length|vector-ref|vector-set!|vector\\?|with-input-from-file|with-output-to-file|with-syntax|write|write|write-char|zero\\?)>":::Keyword::\n\
		Chez  
Keywords:"<(-1\\+|1\\+|1-|acosh|add1|alias|andmap|append!|apropos|apropos-list|ash|asinh|atanh|atom\\?|bignum\\?|block-read|block-write|bound-identifier=\\?|box|box\\?|break|bytes-allocated|call-with-input-file|call-with-output-file|call/1cc|call/cc|case-lambda|cfl\\*|cfl-|cfl-conjugate|cfl-imag-part|cfl-magnitude-squared|cfl-real-part|cfl/|cfl=|cflonum\\?|char-|char-name|chmod|clear-input-port|clear-output-port|close-port|collect|compile|compile-file|compile-port|compile-script|condition-broadcast|condition-signal|condition-wait|condition\\?|conjugate|cons|copy-environment|cosh|critical-section|date-and-time|datum|datum-\\>syntax-object|debug|decode-float|define-record|define-structure|define-syntax|define-syntax-expander|define-top-level-value|delete-file|disable-interrupts|display-statistics|display-string|dynamic-wind|enable-interrupts|engine-block|engine-return|environment-symbols|environment\\?|eps-expand|eps-expand-once|equal\\?|eqv\\?|error|eval|expand|expand/optimize|expt-mo 
d|extend-syntax|fasl-file|fasl-write|file-exists\\?|file-length|file-position|file-position|fixnum-\\>flonum|fixnum\\?|fl\\*|fl\\+|fl-|fl-make-rectangular|fl/|fl\\<|fl\\<=|fl=|fl\\>|fl\\>=|flabs|fllp|flonum-\\>fixnum|flonum\\?|flround|fluid-let|fluid-let-syntax|flush-output-port|foreign-callable|foreign-callable-entry-point|foreign-entry\\?|foreign-procedure|foreign-callable|fork-thread|format|fprintf|free-identifier=\\?|fx\\*|fx\\+|fx-|fx/|fx1\\+|fx1-|fx\\<|fx\\<=|fx=|fx\\>|fx\\>=|fxabs|fxeven\\?|fxlogand|fxlogbit0|fxlogbit1|fxlogbit\\?|fxlogior|fxlognot|fxlogor|fxlogtest|fxlogxor|fxmax|fxmin|fxmodulo|fxnegative\\?|fxnonnegative\\?|fxnonpositive\\?|fxodd\\?|fxpositive\\?|fxquotient|fxremainder|fxsll|fxsra|fxsrl|fxvector|fxvector-\\>list|fxvector-copy|fxvector-fill!|fxvector-length|fxvector-ref|fxvector-set!|fxvector\\?|fxzero\\?|generate-temporaries|gensym|gensym|gensym-\\>unique-string|gensym\\?|get-hash-table|get-output-string|get-registry|getenv|getprop|hash-table-for-each|hash-t 
able-map|hash-table\\?|identifier-syntax|identifier\\?|identifier\\?|import|import-only|include|inspect|inspect/object|install-expander|integer-length|integer\\?|interpret|last-pair|let-syntax|let-values|letrec\\*|letrec-syntax|list\\*|list-\\>fxvector|list-copy|list-head|literal-identifier=\\?|load|load-shared-object|lock-object|logand|logbit0|logbit1|logbit\\?|logior|lognot|logor|logtest|logxor|machine-type|magnitude-squared|make-boot-header|make-condition|make-engine|make-fxvector|make-fxvector|make-guardian|make-hash-table|make-input-port|make-input/output-port|make-list|make-mutex|make-output-port|make-parameter|make-record-type|make-sstats|make-thread-parameter|mark-port-closed!|merge|merge!|meta|mkdir|module|most-negative-fixnum|most-positive-fixnum|mutex-acquire|mutex-release|mutex\\?|new-cafe|nonnegative\\?|nonpositive\\?|null-environment|oblist|open-input-file|open-input-output-file|open-input-string|open-output-file|ormap|parameterize|port-closed\\?|port-handler|port-input 
-buffer|port-input-index|port-input-size|port-name|port-output-buffer|port-output-index|port-output-size|port\\?|pretty-file|pretty-format|pretty-print|process|profile-clear|profile-dump|property-list|put-hash-table!|put-registry!|putenv|putprop|quasiquote|quasisyntax|ratnum\\?|read-token|real-time|rec|record-case|record-constructor|record-field-accessible\\?|record-field-accessor|record-field-mutable\\?|record-field-mutator|record-predicate|record-reader|record-type-descriptor|record-type-descriptor\\?|record-type-field-decls|record-type-field-names|record-type-name|record-type-parent|record-type-symbol|record-writer|record\\?|register-signal-handler|remove|remove!|remove-foreign-entry|remove-hash-table!|remove-registry!|remprop|remq|remq!|remv|remv!|reverse!|revisit|round|sc-expand|scheme-report-environment|set-box!|set-port-input-index!|set-port-input-size!|set-port-output-index!|set-port-output-size!|set-sstats-bytes!|set-sstats-cpu!|set-sstats-gc-bytes!|set-sstats-gc-count!|set- 
sstats-gc-cpu!|set-sstats-gc-real!|set-sstats-real!|set-timer|set-top-level-value!|set-top-level-value!|sinh|sort|sstats-bytes|sstats-cpu|sstats-difference|sstats-gc-bytes|sstats-gc-count|sstats-gc-cpu|sstats-gc-real|sstats-print|sstats-print|sstats-real|sstats\\?|statistics|sub1|subst!|substq|substq!|substring-fill!|substv|syntax|syntax-\\>list|syntax-\\>vector|syntax-case|syntax-error|syntax-object-\\>datum|syntax-rules|system|tanh|thread\\?|time|top-level-bound\\?|top-level-value|trace|trace-case-lambda|trace-define|trace-define-syntax|trace-do|trace-lambda|trace-let|transcript-cafe|truncate-file|type-descriptor|unbox|unless|unlock-object|unquote|unquote-splicing|unread-char|unsyntax|unsyntax-splicing|untrace|vector-copy|vector-set-fixnum!|visit|void|weak-pair\\?|when|with|with-implicit|with-input-from-file|with-input-from-string|with-mutex|with-output-to-file|with-output-to-string|with-source-path|with-syntax)>":::Keyword::\n\
		String:"""":""""::String1::\n\
		String Escape:"\\\\.":::String:String:\n\
	}
nedit.languageModes: 	Ada:.ada .ad .ads .adb .a:::::::\n\
[...]
	Scheme:.scheme .scm .ss::Auto:Newline:::"[ \\n\\t;()]":

-- 
Aaron Hsu <arcfide at sacrificumdeo.net>
http://www.aaronhsu.com | XMPP/Gtalk: arcfide at xmpp.us
(703) 597-7656 | "No one could make a greater mistake than he who did  
nothing because he could do only a little." - Edmund Burke


More information about the Discuss mailing list