diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:49:22 +0000 |
commit | 0a193e032ba1ecf3f003e027e833dc9d274cb740 (patch) | |
tree | a1dcc00cb7f5d26e437e05e658c38fc323fe919d /lisp/modules/progmodes |
Initial revision
Diffstat (limited to 'lisp/modules/progmodes')
-rw-r--r-- | lisp/modules/progmodes/c.lsp | 1118 | ||||
-rw-r--r-- | lisp/modules/progmodes/html.lsp | 327 | ||||
-rw-r--r-- | lisp/modules/progmodes/imake.lsp | 188 | ||||
-rw-r--r-- | lisp/modules/progmodes/lisp.lsp | 384 | ||||
-rw-r--r-- | lisp/modules/progmodes/make.lsp | 135 | ||||
-rw-r--r-- | lisp/modules/progmodes/man.lsp | 160 | ||||
-rw-r--r-- | lisp/modules/progmodes/rpm.lsp | 166 | ||||
-rw-r--r-- | lisp/modules/progmodes/sgml.lsp | 428 | ||||
-rw-r--r-- | lisp/modules/progmodes/sh.lsp | 113 | ||||
-rw-r--r-- | lisp/modules/progmodes/xconf.lsp | 68 | ||||
-rw-r--r-- | lisp/modules/progmodes/xlog.lsp | 102 | ||||
-rw-r--r-- | lisp/modules/progmodes/xrdb.lsp | 115 |
12 files changed, 3304 insertions, 0 deletions
diff --git a/lisp/modules/progmodes/c.lsp b/lisp/modules/progmodes/c.lsp new file mode 100644 index 0000000..bc4474b --- /dev/null +++ b/lisp/modules/progmodes/c.lsp @@ -0,0 +1,1118 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/c.lsp,v 1.26 2003/01/29 03:05:54 paulo Exp $ +;; + +(require "syntax") +(require "indent") +(in-package "XEDIT") + +(defsynprop *prop-format* + "format" + :font "*lucidatypewriter-medium-r*12*" + :foreground "RoyalBlue2" + :underline t +) + +(defsynoptions *c-DEFAULT-style* + ;; Positive number. Basic indentation. + (:indentation . 4) + + ;; Boolean. Support for GNU style indentation. + (:brace-indent . nil) + + ;; Boolean. Add one indentation level to case and default? + (:case-indent . t) + + ;; Boolean. Remove one indentation level for labels? + (:label-dedent . t) + + ;; Boolean. Add one indentation level to continuations? + (:cont-indent . t) + + ;; Boolean. Move cursor to the indent column after pressing <Enter>? + (:newline-indent . t) + + ;; Boolean. Set to T if tabs shouldn't be used to fill indentation. + (:emulate-tabs . nil) + + ;; Boolean. Force a newline before braces? + (:newline-before-brace . nil) + + ;; Boolean. Force a newline after braces? + (:newline-after-brace . nil) + + ;; Boolean. Force a newline after semicolons? + (:newline-after-semi . nil) + + ;; Boolean. Only calculate indentation after pressing <Enter>? + ;; This may be useful if the parser does not always + ;; do what the user expects... + (:only-newline-indent . nil) + + ;; Boolean. Remove extra spaces from previous line. + ;; This should default to T when newline-indent is not NIL. + (:trim-blank-lines . t) + + ;; Boolean. If this hash-table entry is set, no indentation is done. + ;; Useful to temporarily disable indentation. + (:disable-indent . nil) +) + +;; BSD like style +(defsynoptions *c-BSD-style* + (:indentation . 8) + (:brace-indent . nil) + (:case-indent . nil) + (:label-dedent . t) + (:cont-indent . t) + (:newline-indent . t) + (:emulate-tabs . nil) + (:newline-before-brace . nil) + (:newline-after-brace . t) + (:newline-after-semi . t) + (:trim-blank-lines . t) +) + +;; GNU like style +(defsynoptions *c-GNU-style* + (:indentation . 2) + (:brace-indent . t) + (:case-indent . nil) + (:label-dedent . t) + (:cont-indent . t) + (:newline-indent . nil) + (:emulate-tabs . nil) + (:newline-before-brace . t) + (:newline-after-brace . t) + (:newline-after-semi . t) + (:trim-blank-lines . nil) +) + +;; K&R like style +(defsynoptions *c-K&R-style* + (:indentation . 5) + (:brace-indent . nil) + (:case-indent . nil) + (:label-dedent . t) + (:cont-indent . t) + (:newline-indent . t) + (:emulate-tabs . t) + (:newline-before-brace . t) + (:newline-after-brace . t) + (:newline-after-semi . t) + (:trim-blank-lines . t) +) + +(defvar *c-styles* '( + ("xedit" . *c-DEFAULT-style*) + ("BSD" . *c-BSD-style*) + ("GNU" . *c-GNU-style*) + ("K&R" . *c-K&R-style*) +)) + +(defvar *c-mode-options* *c-DEFAULT-style*) +; (setq *c-mode-options* *c-gnu-style*) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; This is a very lazy "pattern matcher" for the C language. +;; If the syntax in the code is not correct, it may get confused, and +;; because it is "lazy" some wrong constructs will be recognized as +;; correct when reducing patterns. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defindent *c-mode-indent* :main + ;; this must be the first token + (indtoken "^\\s*" :start-of-line) + (indtoken "\\<case\\>" :c-case) + (indtoken "\\<default\\>" :c-default) + (indtoken "\\<do\\>" :do) + (indtoken "\\<if\\>" :c-if) + (indtoken "\\<else\\>" :c-else) + (indtoken "\\<for\\>" :c-for) + (indtoken "\\<switch\\>" :c-switch) + (indtoken "\\<while\\>" :c-while) + ;; Match identifiers and numbers as an expression + (indtoken "\\w+" :expression) + (indtoken ";" :semi :nospec t) + (indtoken "," :comma :nospec t) + (indtoken ":" :collon :nospec t) + ;; Ignore spaces before collon, this avoids dedenting ternary + ;; and bitfield definitions as the parser does not distinguish + ;; labels from those, another option would be to use the pattern + ;; "\\w+:", but this way should properly handle labels generated + ;; by macros, example: `MACRO_LABEL(value):' + (indtoken "\\s+:" nil) + + (indinit (c-braces 0)) + (indtoken "{" + :obrace + :nospec t + :code (decf c-braces) + ) + (indtoken "}" + :cbrace + :nospec t + :begin :braces + :code (incf c-braces) + ) + (indtable :braces + (indtoken "{" + :obrace + :nospec t + :switch -1 + :code (decf c-braces) + ) + (indtoken "}" + :cbrace + :nospec t + :begin :braces + :code (incf c-braces) + ) + ) + + (indinit (c-bra 0)) + (indtoken ")" :cparen :nospec t :code (incf c-bra)) + (indtoken "(" :oparen :nospec t :code (decf c-bra)) + (indtoken "]" :cbrack :nospec t :code (incf c-bra)) + (indtoken "[" :obrack :nospec t :code (decf c-bra)) + (indtoken "\\\\$" :continuation) + + ;; C++ style comment, disallow other tokens to match inside comment + (indtoken "//.*$" nil) + + (indtoken "#" :hash :nospec t) + + ;; if in the same line, reduce now, this must be done because the + ;; delimiters are identical + (indtoken "'([^\\']|\\\\.)*'" :expression) + (indtoken "\"([^\\\"]|\\\\.)*\"" :expression) + + (indtoken "\"" :cstring :nospec t :begin :string) + + (indtoken "'" :cconstant :nospec t :begin :constant) + + (indtoken "*/" :ccomment :nospec t :begin :comment) + ;; this must be the last token + (indtoken "$" :end-of-line) + + (indtable :string + ;; Ignore escaped characters + (indtoken "\\." nil) + ;; Return to the toplevel when the start of the string is found + (indtoken "\"" :ostring :nospec t :switch -1) + ) + (indtable :constant + ;; Ignore escaped characters + (indtoken "\\." nil) + ;; Return to the toplevel when the start of the character is found + (indtoken "'" :oconstant :nospec t :switch -1) + ) + (indtable :comment + (indtoken "/*" :ocomment :nospec t :switch -1) + ) + + ;; "Complex" statements + (indinit (c-complex 0) (c-cases 0)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Order of reduce rules here is important, process comment, + ;; continuations, preprocessor and set states when an eol is found. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + (indinit (c-offset (point-max)) + (c-prev-offset c-offset) + ) + (indreduce :indent + t + ((:start-of-line)) + (and (= *ind-start* *ind-offset*) + (setq + *offset* (+ *ind-offset* *ind-length*) + ) + ) + (setq + c-prev-offset c-offset + c-offset *ind-offset* + ) + ) + + ;; Delete comments + (indreduce nil + t + ((:ocomment nil :ccomment)) + ) + + ;; Join in a single token to simplify removal of possible multiline + ;; preprocessor directives + (indinit c-continuation) + (indreduce :continuation + t + ((:continuation :end-of-line)) + (setq c-continuation t) + ) + + (indreduce :eol + t + ((:end-of-line)) + ;; Anything after the eol offset is safe to parse now + (setq c-continuation nil) + ) + + ;; Delete blank lines + (indreduce nil + t + ((:indent :eol)) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preprocessor + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce nil + (>= *ind-offset* *ind-start*) + ((:indent :hash)) + (setq *indent* 0) + (indent-macro-reject-left) + ) + (indreduce nil + t + ((:indent :hash nil :eol)) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Expressions + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce :expression + t + ;; Reduce to a single expression + ((:expression :parens) + (:expression :bracks) + (:expression :expression) + ;; These may be multiline + (:ostring (not :ostring) :cstring) + (:oconstant (not :oconstant) :cconstant) + ) + ) + + (indreduce :expression + t + ((:expression :eol :indent :expression) + (:expression :eol :expression) + ) + ) + + (indreduce :exp-comma + t + ((:expression :comma) + ) + ) + + ;; A semicollon, start a statement + (indreduce :stat + t + ((:semi)) + ) + + ;; Expression following (possibly empty) statement + (indreduce :stat + t + (((or :expression :exp-comma) :stat)) + ) + + ;; Multiline statements + (indreduce :stat + t + (((or :expression :exp-comma) :eol :indent :stat) + ;; rule below may have removed the :indent + ((or :expression :exp-comma) :eol :stat) + ) + ) + + (indinit c-exp-indent) + ;; XXX This rule avoids parsing large amounts of code + (indreduce :stat + t + ;; Eat eol if following expression + ((:indent :stat :eol) + (:indent :stat) + ) + (if + (or + (null c-exp-indent) + (/= (cdar c-exp-indent) (+ *ind-offset* *ind-length*)) + ) + ;; A new statement, i.e. not just joining a multiline one + (push + (cons + (offset-indentation *ind-offset* :resolve t) + (+ *ind-offset* *ind-length*) + ) + c-exp-indent + ) + ;; Update start of statement + (rplaca + (car c-exp-indent) + (offset-indentation *ind-offset* :resolve t) + ) + ) + (when (consp (cdr c-exp-indent)) + (if (and + (zerop c-complex) + (zerop c-cases) + (zerop c-bra) + (= (caar c-exp-indent) (caadr c-exp-indent)) + ) + ;; Two statements with the same indentation + (progn + (setq *indent* (caar c-exp-indent)) + (indent-macro-reject-left) + ) + ;; Different indentation or complex state + (progn + (rplacd c-exp-indent nil) + (setq c-complex 0) + ) + ) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle braces + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce :stat + ;; If block finishes before current line, group as a statement + (< (+ *ind-offset* *ind-length*) *ind-start*) + ((:obrace (not :obrace) :cbrace)) + ) + (indreduce :obrace + ;; If not in the first line + (< *ind-offset* *ind-start*) + ;; If the opening { is the first non blank char in the line + ((:indent :obrace)) + (setq *indent* (offset-indentation (+ *ind-offset* *ind-length*))) + + ;; XXX This may be the starting brace of a switch + (setq c-case-flag nil) + (indent-macro-reject-left) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Labels + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; XXX this frequently doesn't do what is expected, should redefine + ;; some rules, as it frequently will dedent while typing something + ;; like test ? exp1 : exp2 + ;; ^ dedents here because it reduces everything + ;; before ':' to a single :expression token. + (indreduce :label + t + ((:indent :expression :collon :eol)) + (when (and *label-dedent* (>= *ind-offset* *ind-start*)) + (setq + *indent* + (- (offset-indentation *ind-offset* :resolve t) *base-indent*) + ) + (indent-macro-reject-left) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle if + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce :if + t + ((:c-if :parens) + ) + (incf c-complex) + ) + + (indreduce :else + t + ((:c-else)) + (incf c-complex) + ) + + ;; Join + (indreduce :else-if + t + ((:else :if) + (:else :eol :indent :if) + ) + (incf c-complex) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle for + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Join with the parentheses + (indreduce :for + t + ((:c-for :parens) + ) + (incf c-complex) + ) + ;; Before current line, simplify + (indreduce :stat + (< (+ *ind-offset* *ind-length*) *ind-point*) + ((:for :stat) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle while and do + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce :while + t + ((:c-while :parens) + ;; Assume that it is yet being edited, or adjusting indentation + (:c-while) + ) + (incf c-complex) + ) + (indreduce :stat + t + ((:do :stat :while) + (:while :stat) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle switch + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indinit c-case-flag) + + (indreduce :switch + t + ((:c-switch :parens) + ) + ) + ;; Transform in a statement + (indreduce :stat + (< (+ *ind-offset* *ind-length*) *ind-start*) + ((:switch :stat) + ;; Do it now or some rule may stop parsing, and calculate + ;; a wrong indentation for nested switches + (:switch :eol :indent :stat) + ) + ) + ;; An open switch + (indreduce :obrace + (and + (<= c-braces 0) + (> *ind-start* *ind-offset*) + ) + ((:indent :switch :obrace) + ) + (setq + *indent* (offset-indentation *ind-offset* :resolve t) + c-case-flag nil + ) + (indent-macro-reject-left) + ) + (indreduce :obrace + (and + (<= c-braces 0) + (> *ind-start* *ind-offset*) + ) + ((:indent :switch :eol :indent :obrace) + ) + (setq + *indent* (- (offset-indentation *ind-offset* :resolve t) *base-indent*) + c-case-flag nil + ) + (and *brace-indent* (incf *indent* *base-indent*)) + (indent-macro-reject-left) + ) + ;; Before current line + (indreduce :case + (and + (or + (not *case-indent*) + (prog1 c-case-flag (setq c-case-flag t)) + ) + (<= c-braces 0) + (< *ind-offset* *ind-start*) + ) + ((:indent :case) + ) + (setq + *indent* (offset-indentation *ind-offset* :resolve t) + c-case-flag nil + ) + (indent-macro-reject-left) + ) + (indreduce :case + t + ((:c-case :expression :collon) + (:c-default :collon) + ;; Assume that it is yet being edited, or adjusting indentation + (:c-case) + (:c-default) + ) + (and (>= *ind-offset* *ind-start*) + (incf c-cases) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Handle parentheses and brackets + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Reduce matches + (indreduce :parens + t + ((:oparen (not :oparen) :cparen)) + (when + (and + (< *ind-offset* *ind-start*) + (> (+ *ind-offset* *ind-length*) *ind-start*) + ) + (setq *indent* (1+ (offset-indentation *ind-offset* :align t))) + (indent-macro-reject-left) + ) + ) + (indreduce :bracks + t + ((:obrack (not :obrack) :cbrack)) + (when + (and + (< *ind-offset* *ind-start*) + (> (+ *ind-offset* *ind-length*) *ind-start*) + ) + (setq *indent* (1+ (offset-indentation *ind-offset* :align t))) + (indent-macro-reject-left) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Assuming previous lines have correct indentation, this allows + ;; resolving the indentation fastly + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Line ended with an open brace + (indreduce :obrace + (< *ind-offset* *ind-start*) + ((:indent (or :for :while :if :else-if :else :do) :obrace) + ) + (setq *indent* (offset-indentation *ind-offset* :resolve t)) + (indent-macro-reject-left) + ) + ;; Adjust indentation level if current line starts with an open brace + (indreduce nil + (< *ind-offset* *ind-start* (+ *ind-offset* *ind-length*)) + ;; Just set initial indentation + ((:indent (or :for :while :if :else-if :else :do) :eol :indent :obrace) + ) + (setq + *indent* + (- (offset-indentation *ind-offset* :resolve t) *base-indent*) + ) + (and *brace-indent* (incf *indent* *base-indent*)) + (indent-macro-reject-left) + ) + ;; Previous rule failed, current line does not start with an open brace + (indreduce :flow + ;; first statement is in current line + (and + (<= c-braces 0) + (> (+ *ind-offset* *ind-length*) *ind-start* *ind-offset*) + ) + ((:indent (or :for :while :if :else-if :else :do) :eol :indent) + ) + (setq *indent* (offset-indentation *ind-offset* :resolve t)) + (indent-macro-reject-left) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Simplify, remove old (:eol :indent) + ;; This must be the last rule, to avoid not matching the + ;; rules for fast calculation of indentation above + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce nil + (> *ind-offset* c-prev-offset) + ((:eol :indent)) + ) + + + (indinit (c-flow 0)) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indinit c-if-flow) + (indresolve :if + (and (< *ind-offset* *ind-start*) + (push c-flow c-if-flow) + (incf *indent* *base-indent*) + (incf c-flow) + ) + ) + (indresolve (:else-if :else) + (when c-if-flow + (while (< c-flow (car c-if-flow)) + (incf *indent* *base-indent*) + (incf c-flow) + ) + (or (eq *ind-token* :else-if) (pop c-if-flow)) + ) + (and (< *ind-offset* *ind-start*) + (incf *indent* *base-indent*) + (incf c-flow) + ) + ) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; For/while/do + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indinit c-do-flow) + (indresolve (:for :while :do) + (if (eq *ind-token* :do) + (and (< *ind-offset* *ind-start*) (push c-flow c-do-flow)) + (when (and c-do-flow (eq *ind-token* :while)) + (while (< c-flow (car c-do-flow)) + (incf *indent* *base-indent*) + (incf c-flow) + ) + (pop c-do-flow) + ) + ) + (and (< *ind-offset* *ind-start*) + (incf *indent* *base-indent*) + (incf c-flow) + ) + ) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Switch + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indresolve :switch + (setq c-case-flag nil) + ) + (indresolve (:case :c-case) + (if (< *ind-offset* *ind-start*) + (or c-case-flag + (setq + *indent* + (+ (offset-indentation *ind-offset* :resolve t) + *base-indent* + ) + ) + ) + (if c-case-flag + (and (= (decf c-cases) 0) + (decf *indent* *base-indent*) + ) + (or *case-indent* + (decf *indent* *base-indent*) + ) + ) + ) + (setq c-case-flag t) + ) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Braces/flow control + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indresolve :flow + (incf *indent* *base-indent*) + ) + (indresolve :obrace + (and (< *ind-offset* *ind-start*) + (incf *indent* *base-indent*) + ) + ) + (indresolve :cbrace + (decf *indent* *base-indent*) + (and *case-indent* c-case-flag + (decf *indent* *base-indent*) + (setq c-case-flag nil) + ) + (and (not *offset*) (>= *ind-offset* *ind-start*) + (setq *offset* *ind-offset*) + ) + ) + + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Statements + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indresolve :stat + (when (< *ind-offset* *ind-start*) + (while (> c-flow 0) + (setq + *indent* (- *indent* *base-indent*) + c-flow (1- c-flow) + ) + ) + ) + (and + *cont-indent* + (< *ind-offset* *ind-start*) + (> (+ *ind-offset* *ind-length*) *ind-start*) + (incf *indent* *base-indent*) + ) + ) + + (indresolve :expression + (and + *cont-indent* + (zerop c-bra) + (> *indent* 0) + (< *ind-offset* *ind-start*) + (> (+ *ind-offset* *ind-length*) *ind-start*) + (incf *indent* *base-indent*) + ) + ) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Open + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indresolve (:oparen :obrack) + (and (< *ind-offset* *ind-start*) + (setq *indent* (1+ (offset-indentation *ind-offset* :align t))) + ) + ) +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Find a "good" offset to start parsing backwards, so that it should +;; always generate the same results. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun c-offset-indent (&aux char (point (point))) + ;; Skip spaces forward + (while (member (setq char (char-after point)) indent-spaces) + (incf point) + ) + (or (characterp char) (return-from c-offset-indent point)) + + ;; Skip word chars + (when (alphanumericp char) + (while (and (setq char (char-after point)) (alphanumericp char)) + (incf point) + ) + (or (characterp char) (return-from c-offset-indent point)) + + ;; Skip spaces forward + (while (member (setq char (char-after point)) indent-spaces) + (incf point) + ) + (or (characterp char) (return-from c-offset-indent point)) + ) + + ;; don't include " or ' to avoid parsing strings "inverted" + (if (member char '(#\Newline #\" #\')) point (1+ point)) +) +(compile 'c-offset-indent) + +(defun c-should-indent (options) + (when (hash-table-p options) + ;; check if previous line has extra spaces + (and (gethash :trim-blank-lines options) + (indent-clear-empty-line) + ) + + ;; indentation disabled? + (and (gethash :disable-indent options) + (return-from c-should-indent) + ) + + (let* + ( + (point (point)) + (start (scan point :eol :left)) + (char (char-before point)) + offset + match + text + ) + + ;; at the start of an empty file + (or (characterp char) + (return-from c-should-indent) + ) + + ;; if at bol and should indent only when starting a line + (and (gethash :only-newline-indent options) + (return-from c-should-indent (= point start)) + ) + + (and + (char= char #\;) + (gethash :newline-after-semi options) + (return-from c-should-indent t) + ) + + ;; if one of these was typed, must check indentation + (and (member char '(#\{ #\} #\: #\] #\) #\#)) + (return-from c-should-indent t) + ) + + ;; at the start of a line + (and (= point start) + (return-from c-should-indent (gethash :newline-indent options)) + ) + + ;; if first character + (and (= point (1+ start)) + (return-from c-should-indent t) + ) + + ;; check if is the first non-blank character in a new line + (when + (and + (gethash :cont-indent options) + (= point (scan point :eol :right)) + (alphanumericp char) + ) + (setq offset (1- point)) + (while + (and + (> offset start) + (member (char-before offset) indent-spaces) + ) + (decf offset) + ) + ;; line has only one character with possible spaces before it + (and (<= offset start) + (return-from c-should-indent t) + ) + ) + + ;; check for keywords that change indentation + (when (alphanumericp char) + (setq offset (1- point)) + (while + (and + (alphanumericp (char-before offset)) + (> offset start) + ) + (decf offset) + ) + (setq + text (read-text offset (- point offset)) + match (re-exec #.(re-comp "(case|else|while)\\w?\\>") + text) + ) + (and + (consp match) + (return-from c-should-indent (<= (- (caar match) offset) 2)) + ) + ) + ) + ) + ;; Should not indent + nil +) +(compile 'c-should-indent) + + +(defun c-indent-check (syntax syntable options + &aux start point char left brace change) + (setq + point (point) + char (char-before point) + left point + brace (member char '(#\{ #\})) + ) + + (when + (and brace (gethash :newline-before-brace options)) + (setq start (scan point :eol :left)) + (while + (and + (> (decf left) start) + (member (char-before left) indent-spaces) + ) + ;; skip blanks + ) + (when (> left start) + (replace-text left left (string #\Newline)) + (c-indent syntax syntable) + (setq change t) + ) + ) + + (when + (or + (and brace (not change) (gethash :newline-after-brace options)) + (and (char= char #\;) (gethash :newline-after-semi options)) + ) + (setq left (point)) + (replace-text left left (string #\Newline)) + (goto-char (1+ left)) + (c-indent syntax syntable) + ) +) + +(defun c-indent (syntax syntable) + (let* + ( + (options (syntax-options syntax)) + *base-indent* + *brace-indent* + *case-indent* + *label-dedent* + *cont-indent* + ) + + (or (c-should-indent options) (return-from c-indent)) + + (setq + *base-indent* (gethash :indentation options 4) + *brace-indent* (gethash :brace-indent options nil) + *case-indent* (gethash :case-indent options t) + *label-dedent* (gethash :label-dedent options t) + *cont-indent* (gethash :cont-indent options t) + ) + + (indent-macro + *c-mode-indent* + (c-offset-indent) + (gethash :emulate-tabs options) + ) + + (c-indent-check syntax syntable options) + ) +) +(compile 'c-indent) + +(defsyntax *c-mode* :main nil #'c-indent *c-mode-options* + ;; All recognized C keywords. + (syntoken + (string-concat + "\\<(" + "asm|auto|break|case|catch|char|class|const|continue|default|" + "delete|do|double|else|enum|extern|float|for|friend|goto|if|" + "inline|int|long|new|operator|private|protected|public|register|" + "return|short|signed|sizeof|static|struct|switch|template|this|" + "throw|try|typedef|union|unsigned|virtual|void|volatile|while" + ")\\>") + :property *prop-keyword*) + + ;; Numbers, this is optional, comment this rule if xedit is + ;; too slow to load c files. + (syntoken + (string-concat + "\\<(" + ;; Integers + "(\\d+|0x\\x+)(u|ul|ull|l|ll|lu|llu)?|" + ;; Floats + "\\d+\\.?\\d*(e[+-]?\\d+)?[lf]?" + ")\\>") + :icase t + :property *prop-number* + ) + + ;; String start rule. + (syntoken "\"" :nospec t :begin :string :contained t) + + ;; Character start rule. + (syntoken "'" :nospec t :begin :character :contained t) + + ;; Preprocessor start rule. + (syntoken "^\\s*#\\s*\\w+" :begin :preprocessor :contained t) + + ;; Comment start rule. + (syntoken "/*" :nospec t :begin :comment :contained t) + + ;; C++ style comments. + (syntoken "//.*" :property *prop-comment*) + + ;; Punctuation, this is also optional, comment this rule if xedit is + ;; too slow to load c files. + (syntoken "[][(){}/*+:;=<>,&.!%|^~?-][][(){}*+:;=<>,&.!%|^~?-]?" + :property *prop-punctuation*) + + + ;; Rules for comments. + (syntable :comment *prop-comment* #'default-indent + ;; Match nested comments as an error. + (syntoken "/*" :nospec t :property *prop-error*) + + (syntoken "XXX|TODO|FIXME" :property *prop-annotation*) + + ;; Rule to finish a comment. + (syntoken "*/" :nospec t :switch -1) + ) + + ;; Rules for strings. + (syntable :string *prop-string* #'default-indent + ;; Ignore escaped characters, this includes \". + (syntoken "\\\\.") + + ;; Match, most, printf arguments. + (syntoken "%%|%([+-]?\\d+)?(l?[deEfgiouxX]|[cdeEfgiopsuxX])" + :property *prop-format*) + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Rule to finish a string. + (syntoken "\"" :nospec t :switch -1) + + ;; Don't allow strings continuing in the next line. + (syntoken ".?$" :begin :error) + ) + + ;; Rules for characters. + (syntable :character *prop-constant* nil + ;; Ignore escaped characters, this includes \'. + (syntoken "\\\\.") + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Rule to finish a character constant. + (syntoken "'" :nospec t :switch -1) + + ;; Don't allow constants continuing in the next line. + (syntoken ".?$" :begin :error) + ) + + ;; Rules for preprocessor. + (syntable :preprocessor *prop-preprocessor* #'default-indent + ;; Preprocessor includes comments. + (syntoken "/*" :nospec t :begin :comment :contained t) + + ;; Ignore lines finishing with a backslash. + (syntoken "\\\\$") + + ;; Return to previous state if end of line found. + (syntoken ".?$" :switch -1) + ) + + (syntable :error *prop-error* nil + (syntoken "^.*$" :switch -2) + ) + + ;; You may also want to comment this rule if the parsing is + ;; noticeably slow. + (syntoken "\\c" :property *prop-control*) +) diff --git a/lisp/modules/progmodes/html.lsp b/lisp/modules/progmodes/html.lsp new file mode 100644 index 0000000..86f8eea --- /dev/null +++ b/lisp/modules/progmodes/html.lsp @@ -0,0 +1,327 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/html.lsp,v 1.3 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +#| + This is not a validation tool for html. + + It is possible to, using macros generate all combinations of text attributes, + to properly handle <b>...<i>...</i>...</b> etc, as well as generating macros + to automatically closing tags, but for now this file was built to work as an + experience with the syntax highlight code. +|# + +(defsynprop *prop-html-default* + "default" + :font "-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Gray10") + +(defsynprop *prop-html-bold* + "bold" + :font "-*-lucida-bold-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-italic* + "italic" + :font "-*-lucida-medium-i-*-*-14-*-*-*-*-*-*-1" + :foreground "Gray10") + +(defsynprop *prop-html-pre* + "pre" + :font "-*-courier-medium-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Gray10") + +(defsynprop *prop-html-link* + "link" + :font "-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Blue" + :underline "t") + +(defsynprop *prop-html-small* + "small" + :font "-*-lucida-medium-r-*-*-10-*-*-*-*-*-*-1" + :foreground "Gray10") + +(defsynprop *prop-html-big* + "big" + :font "-*-lucida-medium-r-*-*-20-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-name* + "name" + :font "-*-lucida-bold-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Black" + :background "rgb:e/f/e") + +(defsynprop *prop-html-h1* + "h1" + :font "-*-lucida-bold-r-*-*-20-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-h2* + "h2" + :font "-*-lucida-bold-r-*-*-17-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-h4* + "h4" + :font "-*-lucida-bold-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-h5* + "h5" + :font "-*-lucida-bold-r-*-*-10-*-*-*-*-*-*-1" + :foreground "Gray15") + +(defsynprop *prop-html-li* + "li" + :font "-*-lucida-bold-r-*-*-8-*-*-*-*-*-*-1" + :foreground "rgb:0/5/0" + :underline t) + +(defsynprop *prop-html-hr* + "hr" + :font "-*-courier-bold-r-*-*-12-*-*-*-*-*-*-1" + :foreground "rgb:0/5/0" + :overstrike t) + +(defsynprop *prop-html-title* + "title" + :font "-*-lucida-medium-r-*-*-14-*-*-*-*-*-*-1" + :foreground "Red3" + :underline "t") + +(defsynprop *prop-html-tag* + "tag" + :font "-*-courier-medium-r-*-*-10-*-*-*-*-*-*-1" + :foreground "green4") + +(defsynprop *prop-html-string* + "string" + :font "-*-lucida-medium-r-*-*-10-*-*-*-*-*-*-1" + :foreground "RoyalBlue2") + +(defsynprop *prop-html-comment* + "comment" + :font "-*-courier-medium-o-*-*-10-*-*-*-*-*-*-1" + :foreground "SlateBlue3") + +(defsynprop *prop-html-entity* + "entity" + :font "-*-lucida-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Red4") + +(defsynprop *prop-html-unknown* + "unknown" + :font "-*-courier-bold-r-*-*-10-*-*-*-*-*-*-1" + :foreground "yellow" + :background "red") + +(defmacro html-syntoken (name) + `(syntoken (string-concat "<" ,name "\\>") + :icase t :contained t + :begin (intern (string-concat ,name "$") 'keyword))) +(defmacro html-syntable (name property) + `(let + ((label (intern (string-concat ,name "$") 'keyword)) + (nested-label (intern (string (gensym)) 'keyword))) + (syntable label *prop-html-tag* nil + (synaugment :generic-tag) + (syntoken ">" :nospec t :property *prop-html-tag* :begin nested-label) + (syntable nested-label ,property nil + (syntoken (string-concat "</" ,name ">") + :icase t :nospec t :property *prop-html-tag* :switch -2) + (syntoken (string-concat "</" ,name "\\s*$") + :icase t :contained t :begin :continued-end-tag) + (synaugment :main))))) + + +(defsyntax *html-mode* :main *prop-html-default* nil nil + (syntoken "<!--" :nospec t :contained t :begin :comment) + (syntable :comment *prop-html-comment* nil + (syntoken "-->" :nospec t :switch -1)) + (syntoken "&([a-zA-Z0-9_.-]+|#\\x\\x?);?" :property *prop-html-entity*) + (syntoken "<li>" :nospec t :icase t :property *prop-html-li*) + (syntoken "<hr>" :nospec t :icase t :property *prop-html-hr*) + + (syntoken "<img\\>" :icase t :contained t :begin :tag) + (syntoken "<(p|br)>" :icase t :property *prop-html-tag*) + + ;; If in the toplevel, unbalanced! + ;; XXX When adding new nested tables, don't forget to update this pattern. + (syntoken + (string-concat + "</(" + "b|strong|i|em|address|pre|code|tt|small|big|a|span|div|" + "h1|h2|h3|h4|h5|title|font|ol|ul|dl|dt|dd|menu" + ")\\>") + :icase t :property *prop-html-unknown* :begin :unbalanced) + (syntable :unbalanced *prop-html-unknown* nil + (syntoken ">" :nospec t :switch :main) + (synaugment :generic-tag) + ) + + #|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| + ;; XXX ONLY add a rule for "html", "head" and "body" if you want to do a + ;; more complete check for common errors. If you add those rules, it will + ;; reparse the entire file at every character typed (unless there are + ;; errors in which case the parser resets the state). + ;; For visualization only that would be OK... + ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||# + + (html-syntoken "b") + (html-syntable "b" *prop-html-bold*) + (html-syntoken "strong") + (html-syntable "strong" *prop-html-bold*) + + (html-syntoken "i") + (html-syntable "i" *prop-html-italic*) + (html-syntoken "em") + (html-syntable "em" *prop-html-italic*) + (html-syntoken "address") + (html-syntable "address" *prop-html-italic*) + + (html-syntoken "pre") + (html-syntable "pre" *prop-html-pre*) + (html-syntoken "code") + (html-syntable "code" *prop-html-pre*) + (html-syntoken "tt") + (html-syntable "tt" *prop-html-pre*) + + (html-syntoken "small") + (html-syntable "small" *prop-html-small*) + + (html-syntoken "big") + (html-syntable "big" *prop-html-big*) + + ;; Cannot hack html-syntoken and html-syntable to handle this, + ;; as the option to <a may be in the next line. + (syntoken "<a\\>" :icase t :contained t :begin :a) + (syntable :a *prop-html-tag* nil + ;; Tag is open + (syntoken "\\<href\\>" :icase t :begin :a-href) + (syntoken "\\<name\\>" :icase t :begin :a-name) + (syntoken "<" :nospec t :property *prop-html-unknown* :switch -2) + (synaugment :generic-tag) + (syntoken ">" :nospec t :begin :a-generic-text) + (syntable :a-href *prop-html-tag* nil + (syntoken ">" :nospec t :begin :a-href-text) + (synaugment :generic-tag) + (syntable :a-href-text *prop-html-link* nil + (syntoken "</a>" + :icase t :nospec t :property *prop-html-tag* :switch -3) + (syntoken "</a\\s*$" :icase t :begin :continued-nested-end-tag) + (synaugment :main) + ) + ) + (syntable :a-name *prop-html-tag* nil + (syntoken ">" :nospec t :begin :a-name-text) + (synaugment :generic-tag) + (syntable :a-name-text *prop-html-name* nil + (syntoken "</a>" + :icase t :nospec t :property *prop-html-tag* :switch -3) + (syntoken "</a\\s*$" :icase t :begin :continued-nested-end-tag) + (synaugment :main) + ) + ) + (syntable :a-generic-text nil nil + (syntoken "</a>" + :icase t :nospec t :property *prop-html-tag* :switch -2) + (syntoken "<a/\\s$" :icase t :begin :continued-end-tag) + (synaugment :main) + ) + ) + + ;; Do nothing, just check start/end tags + (html-syntoken "ol") + (html-syntable "ol" nil) + (html-syntoken "ul") + (html-syntable "ul" nil) + (html-syntoken "dl") + (html-syntable "dl" nil) + ;; Maybe <dt> and <dd> should be in a special table, to not require + ;; and ending tag. + ;; XXX Maybe should also add a table for <p>. + (html-syntoken "dt") + (html-syntable "dt" nil) + (html-syntoken "dd") + (html-syntable "dd" nil) + + (html-syntoken "span") + (html-syntable "span" nil) + (html-syntoken "div") + (html-syntable "div" nil) + (html-syntoken "menu") + (html-syntable "menu" nil) + + (html-syntoken "h1") + (html-syntable "h1" *prop-html-h1*) + (html-syntoken "h2") + (html-syntable "h2" *prop-html-h2*) + (html-syntoken "h3") + (html-syntable "h3" *prop-html-bold*) + (html-syntoken "h4") + (html-syntable "h4" *prop-html-h4*) + (html-syntoken "h5") + (html-syntable "h5" *prop-html-h5*) + (html-syntoken "title") + (html-syntable "title" *prop-html-title*) + + (html-syntoken "font") + (html-syntable "font" *prop-control*) + + (syntoken "<" :nospec t :contained t :begin :tag) + (syntable :generic-tag *prop-html-tag* nil + (syntoken "\"" :nospec t :contained t :begin :string) + (syntoken "<" :nospec t :property *prop-html-unknown*) + ) + (syntable :tag *prop-html-tag* nil + (syntoken ">" :nospec t :switch -1) + (synaugment :generic-tag) + ) + ;; Tag ended in a newline, common practice... + (syntable :continued-end-tag *prop-html-tag* nil + (syntoken ">" :nospec t :switch -3) + (synaugment :generic-tag) + ) + (syntable :continued-nested-end-tag *prop-html-tag* nil + (syntoken ">" :nospec t :switch -4) + (synaugment :generic-tag) + ) + + (syntable :string *prop-html-string* nil + (syntoken "\\\\.") + (syntoken "\"" :nospec t :switch -1) + ) +) diff --git a/lisp/modules/progmodes/imake.lsp b/lisp/modules/progmodes/imake.lsp new file mode 100644 index 0000000..ea34ed6 --- /dev/null +++ b/lisp/modules/progmodes/imake.lsp @@ -0,0 +1,188 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/imake.lsp,v 1.2 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +(defsynprop *prop-shell* + "shell" + :font "*courier-bold-r*12*" + :foreground "Red4" +) + +(defsynprop *prop-variable* + "variable" + :font "*courier-medium-r*12*" + :foreground "Red3" +) + +;; The syntax-highlight definition does not try to flag errors, just show +;; tabs in the start of lines for better visualization. +(defsynprop *prop-tabulation* + "tabulation" + :font "*courier-medium-r*12*" + :background "Gray90" +) + +(defsynprop *prop-xcomm* + "xcomm" + :font "*courier-medium-o*12*" + :foreground "SkyBlue4" +) + + +(defsyntax *imake-mode* :main nil nil nil + (syntoken "^\\s*XCOMM\\W?.*$" + :property *prop-xcomm*) + + (syntoken "^\\t+" + :property *prop-tabulation*) + + (syntoken "$(" + :nospec t + :begin :shell + :property *prop-shell*) + + (syntoken "[][(){};$<=>&@/\\,.:~!|*?'`+-]" + :property *prop-shell*) + + ;; Preprocessor start rule. + (syntoken "^\\s*#\\s*\\w+" + :begin :preprocessor + :contained t) + + ;; Comment start rule. + (syntoken "/*" + :nospec t + :begin :comment + :contained t) + + ;; String start rule. + (syntoken "\"" + :begin :string + :nospec t + :contained t) + + ;; Quoted string start rule. + (syntoken "\\\"" + :begin :quoted-string + :nospec t + :contained t) + + (syntable :shell *prop-variable* nil + (syntoken ")" + :nospec t + :property *prop-shell* + :switch -1) + ) + + ;; Rules for comments. + (syntable :comment *prop-comment* nil + + ;; Match nested comments as an error. + (syntoken "/*" + :nospec t + :property *prop-error*) + + (syntoken "XXX|TODO|FIXME" + :property *prop-annotation*) + + ;; Rule to finish a comment. + (syntoken "*/" + :nospec t + :switch -1) + ) + + ;; Rules for preprocessor. + (syntable :preprocessor *prop-preprocessor* nil + + ;; Preprocessor includes comments. + (syntoken "/*" + :nospec t + :begin :comment + :contained t) + + ;; Visualization help, show tabs in the start of lines. + (syntoken "^\\t+" + :property *prop-tabulation*) + + ;; Ignore lines finishing with a backslash. + (syntoken "\\\\$") + + ;; Return to previous state if end of line found. + (syntoken ".?$" + :switch -1) + ) + + ;; Rules for strings. + (syntable :string *prop-string* nil + + ;; Ignore escaped characters, this includes \". + (syntoken "\\\\.") + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Rule to finish a string. + (syntoken "\"" + :nospec t + :switch -1) + + ;; Don't allow strings continuing in the next line. + (syntoken ".?$" + :begin :error) + ) + + ;; Rules for quoted strings. + (syntable :quoted-string *prop-constant* nil + + ;; Rule to finish the quoted string. + (syntoken "\\\"" + :nospec t + :switch -1) + + ;; Ignore escaped characters + (syntoken "\\\\.") + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Don't allow strings continuing in the next line. + (syntoken ".?$" + :begin :error) + ) + + (syntable :error *prop-error* nil + (syntoken "^.*$" + :switch -2) + ) +) diff --git a/lisp/modules/progmodes/lisp.lsp b/lisp/modules/progmodes/lisp.lsp new file mode 100644 index 0000000..ebf2c10 --- /dev/null +++ b/lisp/modules/progmodes/lisp.lsp @@ -0,0 +1,384 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/lisp.lsp,v 1.9 2003/01/30 02:46:26 paulo Exp $ +;; + +(require "syntax") +(require "indent") +(in-package "XEDIT") + +(defsynprop *prop-special* + "special" + :font "*courier-bold-r*12*" + :foreground "NavyBlue" +) + +(defsynprop *prop-quote* + "quote" + :font "*courier-bold-r*12*" + :foreground "Red3" +) + +(defsynprop *prop-package* + "package" + :font "*lucidatypewriter-medium-r*12*" + :foreground "Gold4" +) + +(defsynprop *prop-unreadable* + "unreadable" + :font "*courier-medium-r*12*" + :foreground "Gray25" + :underline t +) + +(defsynoptions *lisp-DEFAULT-style* + ;; Positive number. Basic indentation. + (:indentation . 2) + + ;; Boolean. Move cursor to the indent column after pressing <Enter>? + (:newline-indent . t) + + ;; Boolean. Use spaces instead of tabs to fill indentation? + (:emulate-tabs . nil) + + ;; Boolean. Remove extra spaces from previous line. + ;; This should default to T when newline-indent is not NIL. + (:trim-blank-lines . t) + + ;; Boolean. If this hash-table entry is set, no indentation is done. + ;; Useful to temporarily disable indentation. + (:disable-indent . nil) +) + +(defvar *lisp-mode-options* *lisp-DEFAULT-style*) + +(defindent *lisp-mode-indent* :main + ;; this must be the first token + (indtoken "^\\s*" :indent + :code (or *offset* (setq *offset* (+ *ind-offset* *ind-length*)))) + ;; ignore single line comments + (indtoken ";.*$" nil) + ;; multiline comments + (indtoken "|#" :comment :nospec t :begin :comment) + ;; characters + (indtoken "#\\\\(\\W|\\w+(-\\w+)?)" :character) + ;; numbers + (indtoken + (string-concat + "(\\<|[+-])\\d+(" + ;; integers + "(\\>|\\.(\\s|$))|" + ;; ratios + "/\\d+\\>|" + ;;floats + "\\.?\\d*([SsFfDdLlEe][+-]?\\d+)?\\>" + ")") + :number) + ;; symbols, with optional package + (indtoken + (string-concat + ;; optional package name and ending ':' + "([A-Za-z_0-9%-]+:)?" + ;; internal symbol if after package name, or keyword + ":?" + ;; symbol name + "[][{}A-Za-z_0-9!$%&/<=>^~*+-]+") + :symbol) + ;; strings in the same line + (indtoken "\"([^\\\"]|\\\\.)*\"" :string) + ;; multiline strings + (indtoken "\"" :cstring :nospec t :begin :string) + ;; "quoted" symbols in the same line + (indtoken "\\|([^\\|]|\\\\.)*\\|" :symbol) + ;; multiline + (indtoken "|" :csymbol :nospec t :begin :symbol) + (indtoken "#" :hash :nospec t) + + (indinit (parens 0)) + (indtoken "(" :oparen :nospec t :code (incf parens)) + (indtoken ")" :cparen :nospec t :code (decf parens)) + + (indtable :comment + ;; multiline comments can nest + (indtoken "|#" nil :nospec t :begin :comment) + (indtoken "#|" nil :nospec t :switch -1)) + + (indtable :string + ;; Ignore escaped characters + (indtoken "\\." nil) + ;; Return to the toplevel when the start of the string is found + (indtoken "\"" :ostring :nospec t :switch -1)) + + (indtable :symbol + ;; Ignore escaped characters + (indtoken "\\." nil) + ;; Return to the toplevel when the start of the symbol is found + (indtoken "|" :osymbol :nospec t :switch -1)) + + ;; ignore comments + (indreduce nil + t + ((:comment))) + + ;; reduce multiline strings + (indreduce :string + t + ((:ostring (not :ostring) :cstring))) + + ;; reduce multiline symbols + (indreduce :symbol + t + ((:osymbol (not :osymbol) :csymbol))) + + ;; reduce basic types, don't care if inside list or not + (indreduce :element + t + ((:number) + (:string) + (:character) + (:element :element) + (:indent :element))) + + (indreduce :symbol + t + ((:symbol :symbol) + (:symbol :element) + (:indent :symbol))) + + ;; the "real" indentation value, to make easier parsing code like: + ;; (foo (bar (baz (blah + ;; ^ ^ + ;; | | + ;; indent | + ;; effective indentation to be used + (indinit (indent 0)) + + ;; indentation values of opening parenthesis. + (indinit stack) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; if before current line and open parenthesis >= 0, use indentation + ;; of current line to calculate relative indentation. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + (indreduce :oparen ;; simple list? + (and (>= parens 0) (< *ind-offset* *ind-start*)) + ((:indent :oparen)) + (setq + *indent* (offset-indentation (+ *ind-offset* *ind-length*) :resolve t) + indent *indent*) + (indent-macro-reject-left)) + + ;; reduce list if there isn't indentation change + (indreduce :element + t + ((:oparen (not :oparen) :cparen))) + + (indresolve :oparen + (setq + *indent* + (offset-indentation + (+ *ind-offset* *ind-length* -1 *base-indent*) :align t)) + (push *indent* stack) + (incf indent *base-indent*) + (if (< *indent* indent) (setq *indent* indent))) + + (indresolve :cparen + (decf indent *base-indent*) + (setq *indent* (pop stack)) + (if (null stack) + (setq *indent* indent) + (setq *indent* (car stack)))) +) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Find a "good" offset to start parsing backwards, so that it should +;; always generate the same results. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defun lisp-offset-indent (&aux char (point (scan (point) :eol :left))) + ;; skip spaces + (while (member (setq char (char-after point)) indent-spaces) + (incf point)) + (if (member char '(#\))) (1+ point) point)) + +(defun lisp-should-indent (options &aux char point start) + (when (hash-table-p options) + ;; check if previous line has extra spaces + (and (gethash :trim-blank-lines options) + (indent-clear-empty-line)) + + ;; indentation disabled? + (and (gethash :disable-indent options) + (return-from lisp-should-indent)) + + (setq + point (point) + char (char-before (point)) + start (scan point :eol :left)) + + ;; at the start of a line + (and (= point start) + (return-from lisp-should-indent (gethash :newline-indent options))) + + ;; if first character + (and (= point (1+ start)) (return-from lisp-should-indent t)) + + ;; if closing parenthesis and first nonblank char + (when (and (characterp char) (char= char #\))) + (decf point) + (while + (and (> point start) (member (char-before point) indent-spaces)) + (decf point)) + (return-from lisp-should-indent (<= point start))) + ) + ;; should not indent + nil) + +(defun lisp-indent (syntax syntable) + (let* + ((options (syntax-options syntax)) + *base-indent*) + + (or (lisp-should-indent options) (return-from lisp-indent)) + + (setq *base-indent* (gethash :indentation options 2)) + + (indent-macro + *lisp-mode-indent* + (lisp-offset-indent) + (gethash :emulate-tabs options)))) + +(compile 'lisp-indent) + +(defsyntax *lisp-mode* :main nil #'lisp-indent *lisp-mode-options* + ;; highlight car and parenthesis + (syntoken "\\(+\\s*[][{}A-Za-z_0-9!$%&/<=>?^~*:+-]*\\)*" + :property *prop-keyword*) + (syntoken "\\)+" :property *prop-keyword*) + + ;; nil and t + (syntoken "\\<(nil|t)\\>" :icase t :property *prop-special*) + + (syntoken "|" :nospec t :begin :unreadable :contained t) + + ;; keywords + (syntoken ":[][{}A-Za-z_0-9!$%&/<=>^~+-]+" :property *prop-constant*) + + ;; special symbol. + (syntoken "\\*[][{}A-Za-z_0-9!$%&7=?^~+-]+\\*" + :property *prop-special*) + + ;; special identifiers + (syntoken "&(aux|key|optional|rest)\\>" :icase t :property *prop-constant*) + + ;; numbers + (syntoken + ;; since lisp is very liberal in what can be a symbol, this pattern + ;; will not always work as expected, since \< and \> will not properly + ;; work for all characters that may be in a symbol name + (string-concat + "(\\<|[+-])\\d+(" + ;; integers + "(\\>|\\.(\\s|$))|" + ;; ratios + "/\\d+\\>|" + ;;floats + "\\.?\\d*([SsFfDdLlEe][+-]?\\d+)?\\>" + ")") + :property *prop-number*) + + ;; characters + (syntoken "#\\\\(\\W|\\w+(-\\w+)?)" :property *prop-constant*) + + ;; quotes + (syntoken "[`'.]|,@?" :property *prop-quote*) + + ;; package names + (syntoken "[A-Za-z_0-9%-]+::?" :property *prop-package*) + + ;; read time evaluation + (syntoken "#\\d+#" :property *prop-preprocessor*) + (syntoken "#([+'cCsS-]|\\d+[aA=])?" :begin :preprocessor :contained t) + + (syntoken "\\c" :property *prop-control*) + + ;; symbols, do nothing, just resolve conflicting matches + (syntoken "[][{}A-Za-z_0-9!$%&/<=>^~*+-]+") + + (syntable :simple-comment *prop-comment* nil + (syntoken "$" :switch -1) + (syntoken "XXX|FIXME|TODO" :property *prop-annotation*)) + + (syntable :comment *prop-comment* nil + ;; comments can nest + (syntoken "#|" :nospec t :begin :comment) + ;; return to previous state + (syntoken "|#" :nospec t :switch -1) + (syntoken "XXX|FIXME|TODO" :property *prop-annotation*)) + + (syntable :unreadable *prop-unreadable* nil + ;; ignore escaped characters + (syntoken "\\\\.") + (syntoken "|" :nospec t :switch -1)) + + (syntable :string *prop-string* nil + ;; ignore escaped characters + (syntoken "\\\\.") + (syntoken "\"" :nospec t :switch -1)) + + (syntable :preprocessor *prop-preprocessor* nil + ;; a symbol + (syntoken "[][{}A-Za-z_0-9!$%&/<=>^~:*+-]+" :switch -1) + + ;; conditional expression + (syntoken "(" :nospec t :begin :preprocessor-expression :contained t) + + (syntable :preprocessor-expression *prop-preprocessor* nil + ;; recursive + (syntoken "(" :nospec t :begin :preprocessor-recursive :contained t) + (syntoken ")" :nospec t :switch -2) + + (syntable :preprocessor-recursive *prop-preprocessor* nil + (syntoken "(" :nospec t + :begin :preprocessor-recursive + :contained t) + (syntoken ")" :nospec t :switch -1) + (synaugment :comments-and-strings)) + (synaugment :comments-and-strings)) + (synaugment :comments-and-strings)) + + (syntable :comments-and-strings nil nil + (syntoken "\"" :nospec t :begin :string :contained t) + (syntoken "#|" :nospec t :begin :comment :contained t) + (syntoken ";" :begin :simple-comment :contained t)) + + (synaugment :comments-and-strings) +) diff --git a/lisp/modules/progmodes/make.lsp b/lisp/modules/progmodes/make.lsp new file mode 100644 index 0000000..d5cbc00 --- /dev/null +++ b/lisp/modules/progmodes/make.lsp @@ -0,0 +1,135 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/make.lsp,v 1.2 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +(defsynprop *prop-shell* + "shell" + :font "*courier-bold-r*12*" + :foreground "Red4" +) + +(defsynprop *prop-variable* + "variable" + :font "*courier-medium-r*12*" + :foreground "Red3" +) + +;; The syntax-highlight definition does not try to flag errors, just show +;; tabs in the start of lines for better visualization. +(defsynprop *prop-tabulation* + "tabulation" + :font "*courier-medium-r*12*" + :background "Gray90" +) + + +(defsyntax *make-mode* :main nil nil nil + (syntoken "^\\t+" :property *prop-tabulation*) + + (syntoken "^\\.\\w+" :property *prop-keyword*) + + (syntoken "$(" + :nospec t + :begin :shell + :property *prop-shell*) + + (syntoken "[][(){};$<=>&@/\\,.:~!|*?'`+-]" + :property *prop-shell*) + + ;; Preprocessor start rule. + (syntoken "#.*" + :property *prop-comment*) + + ;; String start rule. + (syntoken "\"" + :begin :string + :nospec t + :contained t) + + ;; Quoted string start rule. + (syntoken "\\\"" + :begin :quoted-string + :nospec t + :contained t) + + (syntable :shell *prop-variable* nil + (syntoken ")" + :nospec t + :property *prop-shell* + :switch -1) + ) + + ;; Rules for strings. + (syntable :string *prop-string* nil + + ;; Ignore escaped characters, this includes \". + (syntoken "\\\\.") + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Rule to finish a string. + (syntoken "\"" + :nospec t + :switch -1) + + ;; Don't allow strings continuing in the next line. + (syntoken ".?$" + :begin :error) + ) + + ;; Rules for quoted strings. + (syntable :quoted-string *prop-constant* nil + + ;; Rule to finish the quoted string. + (syntoken "\\\"" + :nospec t + :switch -1) + + ;; Ignore escaped characters + (syntoken "\\\\.") + + ;; Ignore continuation in the next line. + (syntoken "\\\\$") + + ;; Don't allow strings continuing in the next line. + (syntoken ".?$" + :begin :error) + ) + + (syntable :error *prop-error* nil + (syntoken "^.*$" + :switch -2) + ) +) diff --git a/lisp/modules/progmodes/man.lsp b/lisp/modules/progmodes/man.lsp new file mode 100644 index 0000000..77a59a8 --- /dev/null +++ b/lisp/modules/progmodes/man.lsp @@ -0,0 +1,160 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/man.lsp,v 1.2 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +(defsynprop *prop-man-b* + "b" + :font "*courier-bold-r*12*" + :foreground "gray12" +) + +(defsynprop *prop-man-i* + "i" + :font "*courier-medium-o*12*" + :foreground "black" +) + +(defsynprop *prop-man-bi* + "bi" + :font "*courier-bold-o*12*" + :foreground "gray20" +) + +(defsynprop *prop-man-th* + "th" + :font "-*-courier-*-*-*-*-18-*-*-*-*-*-*-1" + :foreground "Red3" +) + +(defsynprop *prop-man-sh* + "sh" + :font "-*-courier-*-*-*-*-14-*-*-*-*-*-*-1" + :foreground "OrangeRed3" +) + +(defsynprop *prop-man-ss* + "ss" + :font "-*-courier-*-*-*-*-12-*-*-*-*-*-*-1" + :foreground "Gold4" +) + +(defsynprop *prop-man-escape* + "escape" + :font "*lucidatypewriter-medium-r*12*" + :foreground "RoyalBlue4" +) + +(defsynprop *prop-man-string* + "string" + :font "*lucidatypewriter-bold-r*12*" + :foreground "RoyalBlue3" +; :underline t +) + +(defmacro man-syntoken (pattern) + `(syntoken (string-concat "^\\.(" ,pattern ")(\\s+|$)") + :icase t +; :contained t + :property *prop-preprocessor* + :begin (intern (string ,pattern) 'keyword))) + +(defmacro man-syntable (pattern property) + `(syntable (intern (string ,pattern) 'keyword) ,property nil + (syntoken "$" :switch -1) + (synaugment :extras))) + + +(defsyntax *man-mode* :main nil nil nil + (syntoken "^\\.\\\\\".*" + :property *prop-comment*) + + (man-syntoken "b|br|nm") + (man-syntable "b|br|nm" *prop-man-b*) + + (man-syntoken "i|ir|ri|ip") + (man-syntable "i|ir|ri|ip" *prop-man-i*) + + (man-syntoken "th|dt") + (man-syntable "th|dt" *prop-man-th*) + + (man-syntoken "sh") + (man-syntable "sh" *prop-man-sh*) + + (man-syntoken "ss") + (man-syntable "ss" *prop-man-ss*) + + (man-syntoken "bi") + (man-syntable "bi" *prop-man-bi*) + + ;; Anything not matched... + (syntoken "^\\.[a-z][a-z](\\s+|$)" + :icase t + :property *prop-preprocessor*) + + (syntable :extras nil nil + (syntoken "\\<__\\l+__\\>" + :property *prop-constant*) + (syntoken "\\\\fB" + :property *prop-preprocessor* + :begin :b) + (syntoken "\\\\fI" + :property *prop-preprocessor* + :begin :i) + (syntoken "\\\\f\\u" + :property *prop-preprocessor*) + + (syntoken "\\\\\\*?." + :property *prop-man-escape*) + + (syntoken "\"" + :property *prop-man-string*) + + (syntable :i *prop-man-i* nil + (syntoken "$" + :switch :main) + (syntoken "\\\\f\\u" + :property *prop-preprocessor* + :switch -1) + ) + (syntable :b *prop-man-b* nil + (syntoken "$" + :switch :main) + (syntoken "\\\\f\\u" + :property *prop-preprocessor* + :switch -1) + ) + ) + + (synaugment :extras) +) diff --git a/lisp/modules/progmodes/rpm.lsp b/lisp/modules/progmodes/rpm.lsp new file mode 100644 index 0000000..bd0cc6c --- /dev/null +++ b/lisp/modules/progmodes/rpm.lsp @@ -0,0 +1,166 @@ +;; +;; Copyright (c) 2003 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/rpm.lsp,v 1.1 2003/01/16 03:50:46 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +;; Only for testing, unifinished, good for viewing but too slow for real use... +#| +(defsynprop *prop-rpm-special* + "rpm-special" + :font "*courier-bold-r*12*" + :foreground "NavyBlue" +) + +(defsynprop *prop-rpm-escape* + "rpm-escape" + :font "*lucidatypewriter-medium-r*12*" + :foreground "Red3") + +;; main package is implicit +(defsyntax *rpm-mode* :package nil nil nil + (syntable :sections nil nil + (syntoken "^%package" + :icase t + :switch :package + ;; XXX :begin :package was added just to test finishing and + ;; starting a new syntax-table, unfortunately if using it + ;; this way, frequently the entire file will be reparsed + ;; at every character typed. + ;; TODO study these cases and implement code to avoid it, + ;; the easiest way is limiting the number of backtracked lines, + ;; the screen contents sometimes could not correctly reflect + ;; file contents in this case... + :begin :package + :property *prop-rpm-special*) + (syntoken "^%(build|setup|install|pre|preun|post|postun)\\>" + :icase t + :property *prop-rpm-special* + :switch :package + :begin :shell) + ;; %changelog, XXX no rules to return to the toplevel + (syntoken "^%changelog\\>" + :icase t + :switch :package + :begin :changelog + :property *prop-rpm-special*) + (syntable :changelog nil nil + ;; ignore if escaped + (syntoken "%%") + ;; "warn" if not escaped + (syntoken "%" :property *prop-control*) + ;; emails + (syntoken "<[a-z0-9_-]+@[a-z0-9_-]+\\.\\w+(\\.\\w+)?>" + :icase t + :property *prop-string*) + ) + ;; comments + (syntoken "#" :contained t :nospec t :begin :comment) + (syntable :comment *prop-comment* nil + ;; some macros are expanded even when inside comments, and may + ;; cause surprises, "warn" about it + (syntoken "%\\{?\\w+\\}?" :property *prop-rpm-special*) + (syntoken "$" :switch -1) + ) + (synaugment :global) + ) + + ;; may appear anywhere + (syntable :global nil nil + ;; preprocessor like commands + (syntoken "^%(define|if|ifarch|else|endif)\\>" + :icase t + :property *prop-preprocessor*) + ;; variables + (syntoken "%\\{.*\\}" :property *prop-constant*) + ) + + ;; example: "Group: ..." or "Group(pt_BR): ..." + (syntoken "^\\w+(\\(\\w+\\))?:" :property *prop-keyword*) + + ;; for sections with shell commands + (syntable :shell nil nil + (syntoken "\\<(if|then|elif|else|fi|for|do|done|case|esac|while|until)\\>" + :property *prop-keyword*) + (syntable :strings nil nil + (syntoken "\"" :nospec t :begin :string :contained t) + (syntable :string *prop-string* nil + (syntoken "\\$\\(?\\w+\\)?" :property *prop-constant*) + (syntoken "\\\\.") + (syntoken "\"" :nospec t :switch -1) + ) + (syntoken "\'" :nospec t :begin :constant :contained t) + (syntable :constant *prop-constant* nil + (syntoken "\\\\.") + (syntoken "\'" :nospec t :switch -1) + ) + (syntoken "\`" :nospec t :begin :escape :contained t) + (syntable :escape *prop-rpm-escape* nil + (syntoken "\\$\\(?\\w+\\)?" :property *prop-constant*) + (syntoken "\\\\.") + (syntoken "\`" :nospec t :switch -1) + ) + ) + (synaugment :strings :sections) + ) + (synaugment :sections) +) +|# + + +(defsyntax *rpm-mode* :package nil nil nil + ;; commands, macro definitions, etc + (syntoken "^\\s*%\\s*\\w+" :property *prop-keyword*) + + ;; rpm "variables" + (syntoken "%\\{.*\\}" :property *prop-constant*) + + ;; package info, example: "Group: ...", "Group(pt_BR): ...", etc. + (syntoken "^\\w+(\\(\\w+\\))?:" :property *prop-preprocessor*) + + ;; comments + (syntoken "#" :contained t :nospec t :begin :comment) + (syntable :comment *prop-comment* nil + ;; some macros are expanded even when inside comments, and may + ;; cause surprises, "warn" about it + (syntoken "%define\\>" :property *prop-control*) + (syntoken "%\\{?\\w+\\}?" :property *prop-string*) + (syntoken "$" :switch -1) + ) + + ;; emails + (syntoken "<?[a-z0-9_-]+@[a-z0-9_-]+\\.\\w+(\\.\\w+)*>?" + :icase t + :property *prop-string*) + ;; links + (syntoken "\\<(http|ftp)://\\S+" :property *prop-string*) +) diff --git a/lisp/modules/progmodes/sgml.lsp b/lisp/modules/progmodes/sgml.lsp new file mode 100644 index 0000000..511aae5 --- /dev/null +++ b/lisp/modules/progmodes/sgml.lsp @@ -0,0 +1,428 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/sgml.lsp,v 1.2 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +;; Default property the text is shown. +(defsynprop *prop-sgml-default* + "default" + :font "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Gray10" +) + +(defsynprop *prop-sgml-default-short* + "default-short" + :font "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Gray10" + :underline t +) + +;; Large font. +(defsynprop *prop-sgml-sect* + "sect" + :font "-*-helvetica-bold-r-*-*-17-*-*-*-*-*-*-1" + :foreground "Gray20" +) + +;; Monospaced property. +(defsynprop *prop-sgml-tt* + "tt" + :font "-*-courier-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Black" +) + +;; Italic property. +(defsynprop *prop-sgml-it* + "it" + :font "-*-helvetica-medium-o-*-*-12-*-*-*-*-*-*-1" + :foreground "Black" +) + +;; Bold font property. +(defsynprop *prop-sgml-bf* + "bf" + :font "-*-helvetica-bold-r-*-*-12-*-*-*-*-*-*-1" + :foreground "Gray10" +) + +;; Looks like a link... +(defsynprop *prop-sgml-link* + "link" + :font "-*-helvetica-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "blue" + :underline t +) + +;; Monospaced, also looks like a link... +(defsynprop *prop-sgml-email* + "email" + :font "-*-courier-medium-r-*-*-12-*-*-*-*-*-*-1" + :foreground "blue" + :underline t +) + +;; Another monospaced property, +(defsynprop *prop-sgml-screen* + "screen" + :font "-*-fixed-*-*-*-*-*-*-*-*-*-*-*-1" + :foreground "Gray10" +) + +(defsynprop *prop-sgml-maybe-entity* + "maybe-entity" + :font "*lucidatypewriter-medium-r*12*" + :foreground "VioletRed4" + :background "LightYellow" +) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; The macros sgml-syntoken and sgml-syntable allows creating rules for +;; matching text inside tags in the format: +;; <tag> or <tag arg=value> or <tag arg1=value ... argn=value> +;; any-text +;; </tag> +;; The generated rules don't allow things like: < tag> or </tag > +;; +;; This could also be done as a normal definition, with a starting rule like: +;; "<(tag1|tag2|tag3)\\>" +;; and an ending rule like: +;; "</(tag1|tag2|tag3)>" +;; But is implemented in way that will fail on purpose for things like: +;; <tag1>any text</tag3></tag1> +;; +;; NOTE: These definitions aren't cheap in the time required to process the +;; file, and are just adaptations/tests with the syntax-highlight code, +;; probably it is better to avoid using it in other syntax definitions. +;; NOTE2: It cannot be defined as a single macro because it is required to +;; generate 2 entries in the main SGML syntax highlight definition, +;; or, should generate the entire definition from a macro; you will +;; need to type the tag name twice, but shouldn't be a problem if +;; you are using sgml :-) +;; XXX: Maybe the syntax-highlight code could save the starting match and +;; apply a regex generated at run-time to check for the ending tag, +;; but this probably would make the parser too slow, better to have +;; a specialized parser if that is required... +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defmacro sgml-syntoken (name) + `(syntoken (string-concat "<" ,name "\\>") + :icase t + :contained t + :begin (intern (string-concat ,name "$") 'keyword)) +) +(defmacro sgml-syntable (name property) + `(let + ( + (label (intern (string-concat ,name "$") 'keyword)) + (nested-label (intern (string (gensym)) 'keyword)) + ) + (syntable label *prop-preprocessor* nil + ;; tag is still open, process any options + (synaugment :generic-tag) + (syntoken ">" + :nospec t + :property *prop-preprocessor* + :begin nested-label) + ;; Generate a nested table that includes everything, and only + ;; returns when the closing tag is found. + (syntable nested-label ,property nil + (syntoken (string-concat "</" ,name ">") + :icase t + :nospec t + :property *prop-preprocessor* + :switch -2) + (synaugment :main) + ) + ) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Generate tokens for tags that don't require and ending tag. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defmacro sgml-syntable-simple (name property) + `(let + ( + (label (intern (string-concat ,name "$") 'keyword)) + (nested-label (intern (string (gensym)) 'keyword)) + ) + (syntable label *prop-preprocessor* nil + ;; tag is still open, process any options + (synaugment :generic-tag) + (syntoken ">" + :nospec t + :property *prop-preprocessor* + :begin nested-label) + ;; Generate a nested table that finishes whenever an unmatched + ;; start or end tag is found. + (syntable nested-label ,property nil + (syntoken "</" + :icase t + :nospec t + :contained t + :begin :simple-nested-tag) + ;; These will take precedence over other rules + (syntoken "<" + :icase t + :nospec t + :contained t + :begin :simple-nested-tag) + (syntoken "<p>" + :icase t + :nospec t + :property *prop-preprocessor* + :switch :main) + (synaugment :main) + ) + ) + ) +) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Define some macros to generate tokens for tags in the format: +;; <tag/ ... / +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(defmacro sgml-syntoken-short (name) + `(syntoken (string-concat "<" ,name "/") + :icase t + :property *prop-preprocessor* + :begin (intern (string-concat ,name "/") 'keyword)) +) +(defmacro sgml-syntable-short (name property) + `(syntable (intern (string-concat ,name "/") 'keyword) ,property nil + (syntoken "/" + :nospec t + :property *prop-preprocessor* + :switch -1) + (syntoken "</?\\w+>" + :property *prop-control* + :switch :main) + ) +) + + +;; The main SGML syntax table +(defsyntax *sgml-mode* :main *prop-sgml-default* nil nil + ;; Comments + (syntoken "<!--" + :nospec t + :contained t + :begin :comment) + (syntable :comment *prop-comment* nil + ;; Only one rule, to finish the comment. + (syntoken "-->" + :nospec t + :switch -1) + ) + + ;; Entities + (syntoken "&[a-zA-Z0-9_.-]+;" + :property *prop-constant*) + ;; Probably an entity, missing ending `;' + (syntoken "&[a-zA-Z0-9_.-]+" + :property *prop-sgml-maybe-entity*) + + ;; Strings + (syntable :string *prop-string* nil + ;; Ignore escaped characters. + (syntoken "\\\\.") + ;; Rule to finish the string. + (syntoken "\"" + :nospec t + :switch -1) + ) + + ;; Links + (syntable :link *prop-preprocessor* nil + ;; No link string following "url=" + (syntoken ">" + :nospec t + :property *prop-control* + :switch -1) + (syntoken "\"" + :nospec t + :contained t + :begin :link-string) + (syntable :link-string *prop-sgml-link* nil + ;; Ignore escaped characters. + (syntoken "\\\\.") + ;; Rule to finish the link, note that returns two levels. + (syntoken "\"" + :nospec t + :switch -2) + ) + ) + + ;; "Special" tag + (syntoken "<!" + :nospec t + :contained t + :begin :special-tag) + ;; Rules for "special" tags + (syntable :special-tag *prop-preprocessor* nil + (syntoken "[" + :nospec t + :property *prop-preprocessor* + :begin :brackets) + ;; Finish the "special" tag + (syntoken ">" + :nospec t + :switch -1) + (syntable :brackets *prop-sgml-default* nil + (syntoken "]" + :nospec t + :property *prop-preprocessor* + :switch -1) + ;; Allow nesting. + (syntoken "[" + :nospec t + :property *prop-preprocessor* + :begin :brackets) + ;; Entities. + (syntoken "%[a-zA-Z0-9_.-]+;?" + :property *prop-annotation*) + ;; Allow everything inside the brackets + (synaugment :main) + ) + ;; Don't use generic tag tokens, only create a rule for strings + (syntoken "\"" + :nospec t + :begin :string + :contained t) + ;; Allow everything inside the "special" tag + (synaugment :main) + ) + + ;; Some "short" tags + (sgml-syntoken-short "tt") + (sgml-syntable-short "tt" *prop-sgml-tt*) + (sgml-syntoken-short "it") + (sgml-syntable-short "it" *prop-sgml-it*) + (sgml-syntoken-short "bf") + (sgml-syntable-short "bf" *prop-sgml-bf*) + (sgml-syntoken-short "em") + (sgml-syntable-short "em" *prop-sgml-bf*) + + ;; Short tag + (syntoken "<\\w+/" + :property *prop-preprocessor* + :begin :short-tag) + (syntable :short-tag *prop-sgml-default-short* nil + (syntoken "/" + :nospec t + :property *prop-preprocessor* + :switch -1) + (syntoken "</?\\w+>" + :property *prop-control* + :switch -1) + ) + + ;; Don't allow spaces, this may and may not be the start of a tag, + ;; but the syntax-highlight definition is not specialized... + (syntoken "<([^/a-zA-Z]|$)" + :property *prop-control*) + + ;; Some tags that require an end tag + (sgml-syntoken "tt") + (sgml-syntable "tt" *prop-sgml-tt*) + (sgml-syntoken "code") + (sgml-syntable "code" *prop-sgml-tt*) + (sgml-syntoken "tag") + (sgml-syntable "tag" *prop-sgml-tt*) + (sgml-syntoken "verb") + (sgml-syntable "verb" *prop-sgml-tt*) + (sgml-syntoken "programlisting") + (sgml-syntable "programlisting" *prop-sgml-tt*) + (sgml-syntoken "it") + (sgml-syntable "it" *prop-sgml-it*) + (sgml-syntoken "bf") + (sgml-syntable "bf" *prop-sgml-bf*) + (sgml-syntoken "em") + (sgml-syntable "em" *prop-sgml-bf*) + (sgml-syntoken "mail") + (sgml-syntable "mail" *prop-sgml-email*) + (sgml-syntoken "email") + (sgml-syntable "email" *prop-sgml-email*) + (sgml-syntoken "screen") + (sgml-syntable "screen" *prop-sgml-screen*) + (sgml-syntoken "tscreen") + (sgml-syntable "tscreen" *prop-sgml-screen*) + + + ;; Helper for tags that don't need an ending one. + ;; NOTE: Since the parser is not specialized, if the tag is + ;; folowed by one that has a special property defined here, + ;; it may not be detected, i.e. put a <p> after the <sect> + ;; and it will work. + (syntable :simple-nested-tag *prop-preprocessor* nil + ;; tag is still open, process any options + (synaugment :generic-tag) + (syntoken ">" + :nospec t + :property *prop-preprocessor* + :switch -3) + ) + (sgml-syntoken "sect") + (sgml-syntable-simple "sect" *prop-sgml-sect*) + (sgml-syntoken "sect1") + (sgml-syntable-simple "sect1" *prop-sgml-sect*) + (sgml-syntoken "sect2") + (sgml-syntable-simple "sect2" *prop-sgml-sect*) + + ;; Generic tags + (syntoken "<" + :nospec t + :contained t + :begin :tag) + ;; Table :generic-tag is defined to be augmented, no rule to finish it. + (syntable :generic-tag *prop-preprocessor* nil + ;; Start string + (syntoken "\"" + :nospec t + :begin :string + :contained t) + ;; Start url link + (syntoken "url=" + :nospec t + :begin :link) + ;; Cannot nest + (syntoken "<" + :nospec t + :property *prop-control*) + ) + (syntable :tag *prop-preprocessor* nil + ;; Finish the tag + (syntoken ">" + :nospec t + :switch -1) + ;; Import generic definitions + (synaugment :generic-tag) + ) +) diff --git a/lisp/modules/progmodes/sh.lsp b/lisp/modules/progmodes/sh.lsp new file mode 100644 index 0000000..79679ed --- /dev/null +++ b/lisp/modules/progmodes/sh.lsp @@ -0,0 +1,113 @@ +;; +;; Copyright (c) 2003 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/sh.lsp,v 1.1 2003/01/16 03:50:46 paulo Exp $ +;; + +(require "syntax") +(require "indent") +(in-package "XEDIT") + +(defsynprop *prop-escape* + "escape" + :font "*lucidatypewriter-medium-r*12*" + :foreground "Red3") + +(defsynprop *prop-variable* + "variable" + :font "*lucidatypewriter-medium-r*12*" + :foreground "Gold4") + +(defsynprop *prop-backslash* + "backslash" + :font "*courier-bold-r*12*" + :foreground "green4") + +;; XXX it would be interesting if "here-documents" could be parsed +;; just searching for "<<\s*EOF\\>" and then for "^EOF\\>" should +;; handle most cases, but would be a hack... +(defsyntax *sh-mode* :main nil #'default-indent nil + ;; keywords and common commands/builtins + (syntoken "\\<(if|then|elif|else|fi|case|in|esac|for|do|done|while|until|break|continue|eval|exit|exec|test|echo|cd|shift|local|return)\\>" + :property *prop-keyword*) + + ; comments + (syntoken "#.*$" :property *prop-comment*) + + ;; punctuation + (syntoken "[][;:*?(){}<>&!|$#]+" :property *prop-punctuation*) + + ;; variable declaration + (syntoken "\\w+=" :property *prop-preprocessor*) + + ;; numbers + (syntoken "\\<\\d+\\>" :property *prop-number*) + + ;; escaped characters at toplevel + (syntoken "\\\\." :property *prop-backslash*) + + ;; single quote + (syntoken "'" :nospec t :contained t :begin :single) + (syntable :single *prop-constant* nil + ;; do nothing, escaped characters + (syntoken "\\\\.") + (syntoken "'" :nospec t :switch -1) + ) + + ;; double quote + (syntoken "\"" :nospec t :contained t :begin :double) + (syntable :double *prop-string* #'default-indent + ;; escaped characters + (syntoken "\\\\." :property *prop-backslash*) + (syntoken "\"" :nospec t :switch -1) + ;; rule to start escape + (syntoken "`" :nospec t :contained t :begin :escape) + ;; ignore single quote, required because escape is augmented + (syntoken "'" :nospec t) + (synaugment :escape :variable) + ) + + ;; escaped commands + (syntoken "`" :nospec t :contained t :begin :escape) + (syntable :escape *prop-escape* #'default-indent + ;; escaped characters + (syntoken "\\\\." :property *prop-backslash*) + (syntoken "`" :nospec t :switch -1) + ;; rule to start double quote inside escape + (syntoken "\"" :nospec t :contained t :begin :double) + ;; rule to start single quote + (syntoken "'" :nospec t :contained t :begin :single) + (synaugment :double :variable) + ) + + (syntable :variable nil nil + (syntoken "\\$\\w+" :property *prop-variable*) + ) + (synaugment :variable) +) diff --git a/lisp/modules/progmodes/xconf.lsp b/lisp/modules/progmodes/xconf.lsp new file mode 100644 index 0000000..dea70a2 --- /dev/null +++ b/lisp/modules/progmodes/xconf.lsp @@ -0,0 +1,68 @@ +;; +;; Copyright (c) 2003 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/xconf.lsp,v 1.1 2003/01/16 03:50:46 paulo Exp $ +;; + +(require "syntax") +(require "indent") +(in-package "XEDIT") + +(defsyntax *xconf-mode* :main nil #'default-indent nil + ;; section start + (syntoken "\\<(Section|SubSection)\\>" + :property *prop-keyword* :icase t :begin :section) + ;; just for fun, highlight the section name differently + (syntable :section *prop-constant* #'default-indent + (syntoken "\"" :nospec t :begin :name) + (syntable :name *prop-constant* nil + ;; ignore escaped characters + (syntoken "\\\\.") + (syntoken "\"" :nospec t :switch -2) + ) + ) + + ;; section end + (syntoken "\\<(EndSection|EndSubSection)\\>" + :property *prop-keyword* :icase t) + + ;; numeric options + (syntoken "\\<\\d+(\\.\\d+)?\\>" :property *prop-number*) + + ;; comments + (syntoken "#.*$" :property *prop-comment*) + + ;; strings + (syntoken "\"" :nospec t :begin :string :contained t) + (syntable :string *prop-string* #'default-indent + ;; ignore escaped characters + (syntoken "\\\\.") + (syntoken "\"" :nospec t :switch -1) + ) +) diff --git a/lisp/modules/progmodes/xlog.lsp b/lisp/modules/progmodes/xlog.lsp new file mode 100644 index 0000000..6bc8b57 --- /dev/null +++ b/lisp/modules/progmodes/xlog.lsp @@ -0,0 +1,102 @@ +;; +;; Copyright (c) 2003 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/xlog.lsp,v 1.1 2003/01/16 06:25:51 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +(defsynprop *prop-xlog-probe* + "xlog-probe" + :font "*courier-medium-r*12*" + :background "rgb:c/f/c") + +(defsynprop *prop-xlog-config* + "xlog-config" + :font "*courier-medium-r*12*" + :background "rgb:c/e/f") + +(defsynprop *prop-xlog-default* + "xlog-default" + :font "*courier-medium-r*12*" + :background "rgb:e/c/f") + +(defsynprop *prop-xlog-warning* + "xlog-warning" + :font "*courier-bold-r*12*" + :foreground "Red4" + :background "Yellow1" +) + +(defsynprop *prop-xlog-error* + "xlog-error" + :font "*courier-bold-r*12*" + :foreground "Yellow2" + :background "Red3" +) + +(defsyntax *xlog-mode* :main nil nil nil + ;; highlight version + (syntoken "^XFree86 Version \\S+" :property *prop-annotation*) + + ;; release date + (syntoken "^Release Date: " :property *prop-keyword* :begin :note) + + ;; highlight operating system description + (syntoken "^Build Operating System: " :property *prop-keyword* :begin :note) + + (syntable :note *prop-annotation* nil (syntoken "$" :switch -1)) + + ;; don't highlight info lines + (syntoken "^\\(II\\) " :property *prop-keyword*) + + ;; default lines + (syntoken "^\\(==\\) " :property *prop-keyword* :begin :default) + (syntable :default *prop-xlog-default* nil (syntoken "$" :switch -1)) + + ;; probe lines + (syntoken "^\\(--\\) " :property *prop-keyword* :begin :probe) + (syntable :probe *prop-xlog-probe* nil (syntoken "$" :switch -1)) + + ;; config lines + (syntoken "^\\(\\*\\*\\) " :property *prop-keyword* :begin :config) + (syntable :config *prop-xlog-config* nil (syntoken "$" :switch -1)) + + ;; warnings + (syntoken "^\\(WW\\) " :property *prop-keyword* :begin :warning) + (syntable :warning *prop-xlog-warning* nil (syntoken "$" :switch -1)) + + ;; errors + (syntoken "^\\(EE\\) " :property *prop-keyword* :begin :error) + (syntable :error *prop-xlog-error* nil (syntoken "$" :switch -1)) + + ;; command line and "uncommon" messages + (syntoken "^\\(..\\) " :property *prop-control* :begin :warning) +) diff --git a/lisp/modules/progmodes/xrdb.lsp b/lisp/modules/progmodes/xrdb.lsp new file mode 100644 index 0000000..c0a099c --- /dev/null +++ b/lisp/modules/progmodes/xrdb.lsp @@ -0,0 +1,115 @@ +;; +;; Copyright (c) 2002 by The XFree86 Project, Inc. +;; +;; Permission is hereby granted, free of charge, to any person obtaining a +;; copy of this software and associated documentation files (the "Software"), +;; to deal in the Software without restriction, including without limitation +;; the rights to use, copy, modify, merge, publish, distribute, sublicense, +;; and/or sell copies of the Software, and to permit persons to whom the +;; Software is furnished to do so, subject to the following conditions: +;; +;; The above copyright notice and this permission notice shall be included in +;; all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +;; IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +;; FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +;; THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +;; WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +;; OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +;; SOFTWARE. +;; +;; Except as contained in this notice, the name of the XFree86 Project shall +;; not be used in advertising or otherwise to promote the sale, use or other +;; dealings in this Software without prior written authorization from the +;; XFree86 Project. +;; +;; Author: Paulo César Pereira de Andrade +;; +;; +;; $XFree86: xc/programs/xedit/lisp/modules/progmodes/xrdb.lsp,v 1.2 2002/10/06 17:11:48 paulo Exp $ +;; + +(require "syntax") +(in-package "XEDIT") + +(defsynprop *prop-xrdb-comment* + "xrdb-comment" + :font "*courier-medium-o*12*" + :foreground "sienna" +) + +(defsynprop *prop-xrdb-special* + "format" + :font "*lucidatypewriter-medium-r*12*" + :foreground "RoyalBlue4" +) + +(defsynprop *prop-xrdb-punctuation* + "punctuation" + :font "-*-courier-bold-r-*-*-14-*-*-*-*-*-*-1" + :foreground "OrangeRed4" +) + +(defsyntax *xrdb-mode* :main nil nil nil + (syntoken "^\\s*!.*" + :property *prop-xrdb-comment*) + (syntoken "^\\s*#.*" + :property *prop-preprocessor*) + (syntoken "\\*|\\.|\\?" + :property *prop-xrdb-punctuation* + :begin :resource) + (syntoken "." + :nospec t + :begin :resource) + + ;; Extra comments + (syntoken "/*" :nospec t :begin :comment :contained t) + (syntable :comment *prop-comment* nil + (syntoken "/*" :nospec t :property *prop-error*) + ;; Rule to finish a comment. + (syntoken "*/" :nospec t :switch -1) + ) + + (syntable :resource nil nil + (syntoken "\\*|\\.|\\?" :property *prop-xrdb-punctuation*) + (syntoken ":\\s*" :property *prop-xrdb-punctuation* :begin :value) + ) + + (syntable :value *prop-string* nil + (syntoken "\\\\$" :property *prop-constant*) + + + ;; If the pattern ends at a newline, must switch to the previous state. + ;; Not sure yet how to better handle this. The parser does not detect + ;; eol because it is a match to the empty string. A possible hack + ;; would be to check if the pattern string ends in a "$", but probably + ;; better in this case to have a syntoken option, to tell the parser + ;; an eol may exist. + (syntoken + (string-concat + "(" + "\\d+|" ;; numbers + "(#\\x+|rgb:\\x+/\\x+/\\x+)|" ;; color spec + "#\\w+" ;; translation table + ")$") + :property *prop-xrdb-special* :switch -2) + (syntoken "(\\\\n?|\")$" + :property *prop-constant* :switch -2) + + ;; XXX Cut&paste of the above, only without the match to eol + (syntoken + (string-concat + "(" + "\\d+|" + "(#\\x+|rgb:\\x+/\\x+/\\x+)|" + "#\\w+" + ")") + :property *prop-xrdb-special*) + (syntoken "(\\\\n?|\")" + :property *prop-constant*) + + (syntoken "/*" :nospec t :begin :comment :contained t) + (syntoken ".?$" :switch -2) + ) +) |