pmacs3/mode/awk.py

111 lines
4.4 KiB
Python

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