diff --git a/README b/README index c54e7fa..4e2a652 100644 --- a/README +++ b/README @@ -9,12 +9,12 @@ python. Pmacs is available to you under the GNU GPL version 2. -While the general interface of pmacs is related to emacs, there was explicitly -no attempt to support all emacs' functions, emacs' underlying data structures, -or even all high-level functionality. There is not currently a formalized -"public API" for pmacs, although some parts are "more public" than others. The -code is somewhat commented, although currently there is only one author. Buyer -beware! +While the general interface of Pmacs is related to Emacs, there was explicitly +no attempt to support all Emacs' functions, Emacs' underlying data structures, +or even all high-level functionality of Emacs. There is not currently a +formalized "public API" for pmacs, although some parts are "more public" than +others. The code is somewhat commented, although currently there is only one +author. Buyer beware! Requirements: 1. python 2.3 or higher diff --git a/application.py b/application.py index fb23ea8..8985877 100755 --- a/application.py +++ b/application.py @@ -11,10 +11,10 @@ import mode2 import mode.mini, mode.search, mode.replace, mode.which import mode.console, mode.consolemini import mode.c, mode.python, mode.perl, mode.nasm, mode.sh, mode.sql, mode.java -import mode.lisp, mode.elisp, mode.scheme +import mode.lisp, mode.elisp, mode.scheme, mode.ocaml import mode.blame, mode.diff, mode.dir import mode.xml, mode.tt, mode.css, mode.javascript, mode.html -import mode.text, mode.mutt +import mode.text, mode.text2, mode.mutt import mode.bds, mode.life import mode.rst @@ -99,6 +99,7 @@ class Application(object): 'search': mode.search.Search, 'sh': mode.sh.Sh, 'text': mode.text.Text, + 'text2': mode.text2.Text2, 'which': mode.which.Which, 'xml': mode.xml.XML, 'html': mode.html.HTML, @@ -112,6 +113,8 @@ class Application(object): 'rst': mode.rst.RST, 'java': mode.java.Java, + 'ocaml': mode.ocaml.Ocaml, + # lisp dialects 'lisp': mode.lisp.Lisp, 'scheme': mode.scheme.Scheme, @@ -136,7 +139,8 @@ class Application(object): '.pm': 'perl', '.t': 'perl', '.c': 'c', - '.txt': 'text', + #'.txt': 'text', + '.txt': 'text2', '.s': 'nasm', '.sh': 'sh', '.bash': 'sh', @@ -152,6 +156,8 @@ class Application(object): '.java': 'java', '.el': 'elisp', '.scm': 'scheme', + '.mli': 'ocaml', + '.ml': 'ocaml', } self.mode_detection = { 'python': 'python', diff --git a/mode/ocaml.py b/mode/ocaml.py new file mode 100644 index 0000000..5b9ca60 --- /dev/null +++ b/mode/ocaml.py @@ -0,0 +1,92 @@ +import commands, os.path, sets, string, sys, traceback +import color, completer, default, mode2, method, regex, tab2 +from point2 import Point +from lex3 import Grammar, PatternRule, RegionRule, NocasePatternRule + +class StringGrammar(Grammar): + rules = [ + PatternRule(r'continuation', r'\\(?=\n$)'), + PatternRule(r'escaped', r"\\[\\ \"'ntbr]"), + PatternRule(r'octal', r'\\[0-9]{3}'), + PatternRule(r'hex', r'\\x[0-9A-Fa-f]{2}'), + ] + +class CommentGrammar(Grammar): + rules = [] +CommentGrammar.rules.append(RegionRule(r'comment', r'\(\*', CommentGrammar, r'\*\)')) + +class OcamlGrammar(Grammar): + rules = [ + PatternRule(r'spaces', r' +'), + PatternRule(r'eol', r'\n'), + RegionRule(r'comment', r'\(\*', CommentGrammar, r'\*\)'), + + PatternRule(r'linenum', r'#[0-9]+ *(?:"(?:[^"\\]|\\[0-9]{3}|\\x[0-9A-Za-z]{2}|\\.)*")?'), + + PatternRule(r'keyword', r"(?:with|while|when|virtual|val|type|try|true|to|then|struct|sig|rec|private|parser|or|open|of|object|new|mutable|module|mod|method|match|lxor|lsr|lsl|lor|let|lazy|land|initializer|inherti|include|in|if|functor|function|fun|for|false|external|exception|end|else|downto|done|do|constraint|class|begin|asr|assert|as|and)(?!['a-zA-Z0-9_])"), + + PatternRule(r'builtin', r"(?:int|char|string|float|bool|false|true|unit|exn|array|list|option|int32|int64|nativeint|format4|lazy_t)(?!['a-zA-Z0-9_])"), + PatternRule(r'builtin_exception', r"(?:Match_failure|Assert_failure|Invalid_argument|Failure|Not_found|Out_of_memory|Stack_overflow|Sys_error|End_of_file|Division_by_zero|Sys_blocked_io|Undefined_recursive_module|Exit)(?!['a-zA-Z0-9_])"), + PatternRule(r'builtin_function', r"raise|invalid_arg|failwith"), + + NocasePatternRule(r'identifier', r"[a-z_]['a-z0-9_]*"), + + NocasePatternRule(r'integer', r"-?[0-9][0-9_]*"), + NocasePatternRule(r'integer', r"-?0x[0-9a-f][0-9a-f_]*"), + NocasePatternRule(r'integer', r"-?0o[0-7][0-7_]*"), + NocasePatternRule(r'integer', r"-?0b[01][01_]*"), + + NocasePatternRule(r'float', r"-?[0-9][0-9_]*(?:\.[0-9_]*)?(?:e[+-]?[0-9][0-9_]*)?"), + + PatternRule(r'char', r"'[^\\']'"), + PatternRule(r'char', r"'\\[\\ \"'ntbr]'"), + PatternRule(r'char', r"'\\[0-9]{3}'"), + PatternRule(r'char', r"'\\x[0-9A-Fa-f]{2}'"), + + RegionRule(r'string', r'"', StringGrammar, '"'), + + PatternRule(r'label', r"~[a-z_]['a-zA-Z0-9_]*:"), + PatternRule(r'optlabel', r"\?[a-z_]['a-zA-Z0-9_]*:"), + + PatternRule(r'infix', r'[-=<>@^|&+*/$%][-!$%&*+\./:<=>?@^|~]*'), + PatternRule(r'prefix', r'[!?~][-!$%&*+\./:<=>?@^|~]*'), + ] + +class Ocaml(mode2.Fundamental): + grammar = OcamlGrammar + #opentokens = ('delimiter',) + #opentags = {'(': ')'} + #closetokens = ('delimiter',) + #closetags = {')': '('} + colors = { + 'comment.start': ('red', 'default'), + 'comment.null': ('red', 'default'), + 'comment.end': ('red', 'default'), + 'linenum': ('red', 'default'), + + 'keyword': ('cyan', 'default'), + + #'builtin': ('magenta', 'default'), + #'builtin_exception': ('magenta', 'default'), + #'builtin_function': ('magenta', 'default'), + + 'label': ('blue', 'default'), + 'optlabel': ('blue', 'default'), + + 'string.start': ('green', 'default'), + 'string.null': ('green', 'default'), + 'string.octal': ('magenta', 'default'), + 'string.hex': ('magenta', 'default'), + 'string.escaped': ('magenta', 'default'), + 'string.end': ('green', 'default'), + 'char': ('green', 'default'), + 'integer': ('default', 'default'), + 'float': ('default', 'default'), + } + def __init__(self, w): + mode2.Fundamental.__init__(self, w) + #self.add_bindings('close-paren', (')',)) + #self.add_bindings('close-brace', ('}',)) + #self.add_bindings('close-bracket', (']',)) + def name(self): + return "Ocaml" diff --git a/mode/text2.py b/mode/text2.py new file mode 100644 index 0000000..29ab0df --- /dev/null +++ b/mode/text2.py @@ -0,0 +1,28 @@ +import color, mode2, mode.text, method, ispell +from lex3 import Token, Rule, PatternRule, RegionRule, Grammar +from mode.text import WordRule, ContinuedRule + +class Text2Grammar(Grammar): + rules = [ + PatternRule(name=r'email', pattern=r'(?:^|(?<=[ :]))@\n ]+@(?:[^<>@\.\n ]+\.)*[^<>@\.\n ]+>?'), + PatternRule(name=r'url', pattern=r'(?:^|(?<= ))(?:http|https|ftp|sftp|file|smtp|smtps|torrent|news|jabber|irc|telnet)://(?:[^\.\n ]+\.)*[^\.\n ]+'), + ContinuedRule(), + WordRule(), + PatternRule(r'punct', r'[^a-zA-Z0-9_]'), + PatternRule(r'stuff', r'[a-zA-Z0-9_]+'), + ] + +class Text2(mode.text.Text): + grammar = Text2Grammar + colors = { + 'email': ('cyan', 'default'), + 'url': ('green', 'default'), + 'misspelled': ('red', 'default'), + 'cont.start': ('default', 'default'), + 'cont.end': ('default', 'default'), + 'word': ('default', 'default'), + 'punct': ('default', 'default'), + 'stuff': ('default', 'default'), + } + def name(self): + return "Text2"