import commands, os import color, default, mode, tab from lex import Grammar, PatternRule, RegionRule from mode.python import StringGrammar2 from tab import StackTabber2 from method import Method, Argument, arg from method.shell import Exec, Pipe class RegexGrammar(Grammar): rules = [ PatternRule(r'escaped', r'\\.'), PatternRule(r'data', r'[^\\/]+'), ] class AwkGrammar(Grammar): rules = [ PatternRule(r'comment', r'#.*\n$'), PatternRule(r'spaces', r' +'), RegionRule(r'awk_regex', r'/(?! )', RegexGrammar, r'/'), PatternRule(r'awk_global', r'(?:TEXTDOMAIN|SUBSEP|RLENGTH|RSTART|RT|RS|PROCINFO|ORS|OFS|OFMT|NR|NF|LINT|IGNORECASE|FS|FNR|FILENAME|FIELDWIDTHS|ERRNO|ENVIRON|CONVFMT|BINMODE|ARGV|ARGIND|ARGC)(?![a-zA-Z0-9_])'), PatternRule(r'delimiter', r'(?:[\{\}()\[\]?:;,]|=(?!=)|\+=|-=|\*=|/=|\%=|\^=)'), PatternRule(r'keyword', r'(?:BEGIN|END|if|else|while|do|for|break|continue|delete|exit)(?![a-zA-Z0-9_])'), PatternRule(r'builtin', r'(?:close|getline|nextfile|next|printf|print|system|fflush|atan2|cos|exp|int|log|rand|sin|sqrt|srand|asorti|asort|gensub|gsub|index|length|match|split|sprintf|strtonum|substr|sub|tolower|toupper|mktime|strftime|systime|and|compl|lshift|or|xor|rshift|bindtextdomain|dcgettext|dcngettext|function|extension)(?![a-zA-Z0-9_])'), PatternRule(r'awk_field', r'\$\d*'), PatternRule(r'number', r'-?0x[0-9A-Fa-f]+'), PatternRule(r'number', r'-?0[0-7]*'), PatternRule(r'number', r'-?[0-9]+\.?[0-9]*'), PatternRule(r'number', r'-?\.[0-9]+'), PatternRule(r'unop', r'!(?![=~])|--|\+\+'), PatternRule(r'binop', r'(?:&&|\|\||<=|>=|!=|!~|==|\^|%|[-~/+*<>])'), RegionRule(r'string', r'"', StringGrammar2, r'"'), PatternRule(r'awk_function', r'[a-zA-Z_][a-zA-Z0-9_]*(?=\()'), PatternRule(r'awk_identifier', r'[a-zA-Z_][a-zA-Z0-9_]*'), PatternRule(r'continuation', r'\\\n$'), PatternRule(r'eol', r'\n'), ] class AwkTabber(StackTabber2): open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'}} close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['}} control_tokens = { 'keyword': {'if': 1, 'else': 1, 'while': 1, 'do': 1, 'for': 1}, } end_at_eof = True end_at_tokens = {} def _is_base(self, y): if y == 0: return True t = self._get_tokens(y)[0] if t.fqname() == 'awk_regex.start': return True elif t.name in ('awk_field', 'awk_global'): return True elif t.name == 'keyword' and t.string in ('BEGIN', 'END'): return True else: return False def _is_indent(self, t): return t.name == 'spaces' def _is_ignored(self, t): return t.name in ('spaces', 'eol', 'comment') class AwkFilterFile(Exec): show_success = True args = [arg('path', dt="path", p="Filter File: ", dv=default.path_dirname, ld=True, h="file to open")] def _execute(self, w, **vargs): if not hasattr(w.buffer, 'path'): w.set_error("Buffer has no program") return elif w.buffer.changed(): w.set_error("Buffer is not saved") return else: self._doit(w, w.buffer.path, w.application.config['awk.filter-cmd'], cmdname='awk', bufname='*Awk-Output*', opts={'data': vargs['path']}) class AwkFilterBuffer(Method): pass class AwkFilterInput(Method): pass class Awk(mode.Fundamental): tabbercls = AwkTabber modename = 'awk' extensions = ['.awk'] grammar = AwkGrammar colors = { 'awk_global': ('yellow', 'default', 'bold'), 'awk_function': ('magenta', 'default', 'bold'), 'awk_field': ('yellow', 'default', 'bold'), 'awk_identifier': ('yellow', 'default', 'bold'), 'awk_regex.start': ('cyan', 'default', 'bold'), 'awk_regex.null': ('cyan', 'default', 'bold'), 'awk_regex.data': ('cyan', 'default', 'bold'), 'awk_regex.end': ('cyan', 'default', 'bold'), } config = { 'awk.filter-cmd': "awk -f %(path)r %(data)r", } actions = [AwkFilterFile, AwkFilterBuffer, AwkFilterInput] #format = "%(flag)s %(bname)-18s (%(mname)s) %(indent)s %(cursor)s/%(mark)s %(perc)s [%(func)s]" install = Awk.install