parent
6a3002fa6c
commit
79f120d089
|
@ -134,7 +134,7 @@ class Application(object):
|
|||
'latex', 'insertmini', 'conf', 'haskell', 'erlang',
|
||||
'iperl', 'iperlmini', 'ipython', 'ipythonmini', 'awk',
|
||||
'bds', #XYZ
|
||||
'shell', 'shellmini', 'fstab'
|
||||
'shell', 'shellmini', 'fstab', 'yacc',
|
||||
)
|
||||
for name in names:
|
||||
exec("import mode.%s; mode.%s.install(self)" % (name, name))
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
%{
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <libxml/parser.h>
|
||||
#include <libxml/tree.h>
|
||||
|
||||
|
||||
extern char* yytext;
|
||||
|
||||
/*extern char * yylval;*/
|
||||
/*
|
||||
Parser for linker map files.
|
||||
*/
|
||||
|
||||
void print_node(xmlNodePtr node) {
|
||||
xmlDocPtr doc = NULL;
|
||||
doc = xmlNewDoc("1.0");
|
||||
xmlDocSetRootElement(doc, node);
|
||||
xmlSaveFile("ldmap.out.xml", doc);
|
||||
}
|
||||
|
||||
%}
|
||||
|
||||
%union {
|
||||
char* strn;
|
||||
xmlNodePtr node;
|
||||
};
|
||||
|
||||
%token SYMBOL LPAREN RPAREN HEX;
|
||||
%token OBJ_FILE ARCH_FILE DYN_FILE;
|
||||
%token HEADER ARCH_HEADER
|
||||
|
||||
%type<strn> thingie file objfile archfile dynfile sym hexval head
|
||||
|
||||
%type<node> arch_section arch_list arch_entry
|
||||
|
||||
|
||||
%%
|
||||
|
||||
thingie: thingie file { printf("File: %s\n", $2); $$ = $2;}
|
||||
| thingie sym { printf("Sym: %s\n", $2); $$ = $2;}
|
||||
| thingie hexval { printf("Hex: %s\n", $2); $$ = $2;}
|
||||
| thingie head { printf("Header: %s\n", $2); $$ = $2;}
|
||||
| thingie arch_section { printf("Arch section:\n"); print_node($2); $$ = ""}
|
||||
| thingie '(' { $$= "";}
|
||||
| thingie ')' { $$= "";}
|
||||
| thingie '*' { $$ = ""; }
|
||||
| thingie ',' { $$ = ""; }
|
||||
| thingie '=' { $$ = ""; }
|
||||
| thingie '+' { $$ = ""; }
|
||||
| thingie '&' { $$ = ""; }
|
||||
| thingie '!' { $$ = ""; }
|
||||
| thingie '?' { $$ = ""; }
|
||||
| thingie ':' { $$ = ""; }
|
||||
| { $$ = "end" }
|
||||
;
|
||||
|
||||
|
||||
arch_section: ARCH_HEADER arch_list
|
||||
{
|
||||
$$ = xmlNewNode(NULL, "arch-section");
|
||||
xmlAddChild($$, $2);
|
||||
}
|
||||
|
||||
arch_list:
|
||||
arch_list arch_entry arch_entry '(' sym ')'
|
||||
{
|
||||
xmlNodePtr tmp;
|
||||
tmp = xmlNewNode(NULL, "added");
|
||||
|
||||
/*$$ = $6; xmlAddChild($6, $1); */
|
||||
xmlAddChild(tmp, $2);
|
||||
xmlAddChild(tmp, $3);
|
||||
xmlNewProp(tmp, "symbol", $5);
|
||||
xmlAddChild($1, tmp);
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
| arch_list arch_entry file '(' sym ')'
|
||||
{
|
||||
xmlNodePtr tmp;
|
||||
tmp = xmlNewNode(NULL, "added");
|
||||
xmlAddChild(tmp, $2);
|
||||
xmlNewChild(tmp, NULL, "file", $3);
|
||||
xmlNewProp(tmp, "symbol", $5);
|
||||
xmlAddChild($1, tmp);
|
||||
$$ = $1;
|
||||
}
|
||||
|
||||
| {$$ = xmlNewNode(NULL, "arch-list")}
|
||||
|
||||
arch_entry: archfile '(' file ')'
|
||||
{
|
||||
$$= xmlNewNode(NULL, "archive");
|
||||
xmlNodeAddContent($$, $1);
|
||||
xmlNewProp($$, "member", $3);
|
||||
}
|
||||
|
||||
file: objfile { $$ = $1; }
|
||||
| archfile { $$ = $1; }
|
||||
| dynfile { $$ = $1; };
|
||||
|
||||
dynfile: DYN_FILE { $$ = strdup(yytext); };
|
||||
|
||||
objfile: OBJ_FILE { $$ = strdup(yytext); };
|
||||
|
||||
archfile: ARCH_FILE { $$ = strdup(yytext); };
|
||||
|
||||
sym: SYMBOL { $$ = strdup(yytext); };
|
||||
|
||||
hexval: HEX { $$ = strdup(yytext); };
|
||||
|
||||
head: HEADER { $$ = strdup(yytext); };
|
||||
|
||||
|
||||
%%
|
||||
|
||||
main() {
|
||||
/* do {*/
|
||||
yyparse();
|
||||
/* } while (!feof(yyin) );*/
|
||||
}
|
||||
|
||||
yyerror( char * s) {
|
||||
|
||||
fprintf(stderr, "yyerror is: %s ; %s\n", s, yytext);
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
import re, sets, string
|
||||
|
||||
import color, method, minibuffer, mode, searchutil
|
||||
from point import Point
|
||||
|
||||
subgroup_re = re.compile(r'((?:\\\\)*)\\(0|[1-9][0-9]*)')
|
||||
|
||||
class ReplaceOne(method.Method):
|
||||
def execute(self, w, **vargs):
|
||||
m = w.buffer.method
|
||||
_replace(m)
|
||||
_find_next(m, False)
|
||||
_finish(m, w)
|
||||
|
||||
class ReplaceDone(method.Method):
|
||||
def execute(self, w, **vargs):
|
||||
m = w.buffer.method
|
||||
_replace(m)
|
||||
_end(w)
|
||||
w.set_error("Replace done")
|
||||
|
||||
class SkipReplace(method.Method):
|
||||
def execute(self, w, **vargs):
|
||||
m = w.buffer.method
|
||||
_find_next(m, True)
|
||||
_finish(m, w)
|
||||
|
||||
class ReplaceAll(method.Method):
|
||||
def execute(self, w, **vargs):
|
||||
m = w.buffer.method
|
||||
while m.p1 is not None:
|
||||
_replace(m)
|
||||
_find_next(m, False)
|
||||
_end(w)
|
||||
w.set_error("Replace ended")
|
||||
|
||||
class BrmCancel(method.Method):
|
||||
def execute(self, w, **vargs):
|
||||
_end(w)
|
||||
w.set_error("BRM cancelled")
|
||||
|
||||
def _find_next(m, move=False):
|
||||
s = m.before
|
||||
w = m.old_window
|
||||
c = w.logical_cursor()
|
||||
try:
|
||||
if m.is_literal:
|
||||
r = re.compile(searchutil.escape_literal(s))
|
||||
else:
|
||||
r = re.compile(s)
|
||||
except:
|
||||
(m.p1, m.p2) = (None, None)
|
||||
return False
|
||||
|
||||
if move:
|
||||
newc = searchutil.find_next(r, w, False, start=c.add(1, 0))
|
||||
else:
|
||||
newc = searchutil.find_next(r, w, False, start=c.add(0, 0))
|
||||
|
||||
if newc:
|
||||
(m.p1, m.p2, m.match) = newc
|
||||
return True
|
||||
else:
|
||||
(m.p1, m.p2, m.match) = (None, None, None)
|
||||
return False
|
||||
|
||||
def _get_before(m):
|
||||
if m.match is None:
|
||||
return m.before
|
||||
else:
|
||||
return m.match.group(0)
|
||||
|
||||
def _get_after(m):
|
||||
if m.after is None:
|
||||
return None
|
||||
elif m.match is None:
|
||||
return m.after
|
||||
|
||||
def _repl(match):
|
||||
(pre, num) = (match.group(1), int(match.group(2)))
|
||||
if num == 0 or m.match.lastindex and num <= m.match.lastindex:
|
||||
return pre + m.match.group(num)
|
||||
else:
|
||||
return match.group(0)
|
||||
|
||||
return subgroup_re.sub(_repl, m.after)
|
||||
|
||||
def _set_prompt(m):
|
||||
w = m.old_window
|
||||
if m.p1 is None:
|
||||
#w.application.mini_prompt = '%r was not found' % m.before
|
||||
w.application.mini_prompt = '[%r] %r was not found' % (m.p1, m.before)
|
||||
return
|
||||
(x, y) = m.p1.xy()
|
||||
count = 0
|
||||
while y < len(w.buffer.lines):
|
||||
count += w.buffer.lines[y][x:].count(m.before)
|
||||
y += 1
|
||||
x = 0
|
||||
|
||||
after = _get_after(m)
|
||||
before = _get_before(m)
|
||||
|
||||
if count > 1:
|
||||
p = 'Replace %r with %r [ynadq] (%d occurances)?' % (before, after, count)
|
||||
elif count == 1:
|
||||
p = 'Replace %r with %r [ynadq] (1 occurance)?' % (before, after)
|
||||
elif count == 0:
|
||||
p = 'Replace %r with %r [ynadq] (0 occurances)?' % (before, after)
|
||||
#raise Exception("this can't happen")
|
||||
else:
|
||||
raise Exception("this REALLY can't happen")
|
||||
w.application.mini_prompt = p
|
||||
|
||||
def _replace(m):
|
||||
m.old_window.buffer.delete(m.p1, m.p2)
|
||||
if m.after:
|
||||
after = _get_after(m)
|
||||
m.old_window.buffer.insert_string(m.p1, after)
|
||||
|
||||
def _finish(m, w):
|
||||
if m.p1 is None:
|
||||
_end(w)
|
||||
w.set_error("Replace ended")
|
||||
else:
|
||||
_set_prompt(m)
|
||||
|
||||
def _end(w):
|
||||
w.application.close_mini_buffer()
|
||||
w.application.clear_highlighted_ranges('search')
|
||||
w.buffer.method.old_cursor = None
|
||||
w.buffer.method.old_window = None
|
||||
assert not w.application.mini_active
|
||||
|
||||
class Brm(mode.Fundamental):
|
||||
modename = 'Bicycle-Repairman'
|
||||
actions = [ReplaceAll, ReplaceDone, ReplaceOne, SkipReplace, BrmCancel]
|
||||
def __init__(self, w):
|
||||
mode.Fundamental.__init__(self, w)
|
||||
|
||||
self.actions = {}
|
||||
self.bindings = {}
|
||||
#self.add_bindings('replace-all', ('a', '!',))
|
||||
#self.add_bindings('replace-done', ('d',))
|
||||
#self.add_bindings('replace-one', ('y', 'SPACE',))
|
||||
#self.add_bindings('skip-replace', ('n', 'DELETE',))
|
||||
self.add_bindings('brm-cancel', ('q', 'RETURN', 'C-]', 'C-n', 'C-p', 'C-a', 'C-e', 'C-f', 'C-b', 'C-g'))
|
||||
|
||||
m = w.buffer.method
|
||||
found = _find_next(m, False)
|
||||
if not found:
|
||||
w.set_error('%r was not found' % m.before)
|
||||
raise minibuffer.MiniBufferError
|
||||
_set_prompt(m)
|
||||
|
||||
install = Brm.install
|
|
@ -63,7 +63,8 @@ class CGrammar(Grammar):
|
|||
PatternRule(r'char', r"'.'|'\\.'|'\\[0-7]{3}'"),
|
||||
|
||||
PatternGroupRule(r'includegrp', r'macro.start', r'# *include', r'spaces',
|
||||
r' +', r'header', r'< *[-A-Za-z/0-9_.]+ *>|" *[-A-Za-z/0-9_.]+ *"'),
|
||||
r' +', r'header', r'< *[-A-Za-z/0-9_.]+ *>|" *[-A-Za-z/0-9_.]+ *"',
|
||||
'macro.end', r'\n$'),
|
||||
|
||||
PatternRule(r'identifier', r"[a-zA-Z_][a-zA-Z0-9_]*"),
|
||||
|
||||
|
|
|
@ -1,8 +1,14 @@
|
|||
import commands, os.path, sets, string, sys, traceback
|
||||
import color, completer, context, default, mode, method, regex, tab
|
||||
import color, completer, context, default, mode, method, regex, tab, method.introspect
|
||||
from point import Point
|
||||
from lex import Grammar, PatternRule, RegionRule, OverridePatternRule
|
||||
|
||||
try:
|
||||
import bike
|
||||
has_bike = True
|
||||
except ImportError:
|
||||
has_bike = False
|
||||
|
||||
class StringGrammar1(Grammar):
|
||||
rules = [
|
||||
PatternRule(r'octal', r'\\[0-7]{3}'),
|
||||
|
@ -365,6 +371,33 @@ class PythonListNames(method.Method):
|
|||
output = '\n'.join(sorted(names)) + "\n"
|
||||
w.application.data_buffer("*Python-List-Names*", output, switch_to=True)
|
||||
|
||||
class PythonBrmFindReferences(method.Method):
|
||||
def _execute(self, w, **vargs):
|
||||
if w.mode.brm is None:
|
||||
w.set_error('bicycle repairman not installed')
|
||||
return
|
||||
path = w.buffer.path
|
||||
cursor = w.logical_cursor()
|
||||
y, x = cursor.yx()
|
||||
refs = w.mode.brm.findReferencesByCoordinates(path, y, x)
|
||||
lines = []
|
||||
n = 0
|
||||
for r in refs:
|
||||
f, n, c = r.filename, r.lineno, r.confidence
|
||||
s = '%s:%d: %3d%% confidence' % (f, n, c)
|
||||
lines.append(s)
|
||||
n += 1
|
||||
if n == 0:
|
||||
w.set_error('no references found')
|
||||
return
|
||||
|
||||
data = '\n'.join(lines)
|
||||
w.application.data_buffer("*References*", data, switch_to=True)
|
||||
if n == 1:
|
||||
w.set_error('1 reference found')
|
||||
else:
|
||||
w.set_error('%d references found' % n)
|
||||
|
||||
class PythonNameCompleter(completer.Completer):
|
||||
def _get_dict(self, w):
|
||||
return w.buffer.method.old_window.mode.context.get_names()
|
||||
|
@ -502,7 +535,7 @@ class Python(mode.Fundamental):
|
|||
}
|
||||
actions = [PythonInitNames, PythonListNames, PythonGotoName,
|
||||
PythonGotoFunction, PythonGotoClass, PythonCheckSyntax,
|
||||
PythonDictCleanup, PythonSemanticComplete,
|
||||
PythonDictCleanup, PythonSemanticComplete, PythonBrmFindReferences,
|
||||
PythonInsertTripleSquotes, PythonInsertTripleDquotes]
|
||||
completers = {
|
||||
"pythonname": PythonNameCompleter(None),
|
||||
|
@ -533,4 +566,10 @@ class Python(mode.Fundamental):
|
|||
self.add_bindings('python-semantic-complete', ('C-c TAB',))
|
||||
self.context = PythonContext(self)
|
||||
|
||||
# bicycle repairman!
|
||||
if has_bike:
|
||||
self.brm = bike.init()
|
||||
else:
|
||||
self.brm = None
|
||||
|
||||
install = Python.install
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
import color, mode, tab
|
||||
from lex import Grammar, PatternRule, RegionRule
|
||||
from mode.c import C, CGrammar, CTabber2
|
||||
|
||||
_rules = list(CGrammar.rules)
|
||||
_rules.insert(0, PatternRule(r"yacc_directive", r"^%[a-zA-Z_]+"))
|
||||
_rules.insert(1, PatternRule(r"yacc_section", r"%%"))
|
||||
_rules.insert(2, PatternRule(r"yacc_delimiter", r"%{|%}"))
|
||||
_rules.insert(3, PatternRule(r"yacc_production", r"^[a-z_]+:"))
|
||||
_rules.insert(4, PatternRule(r"yacc_var", r"\$[0-9\$]"))
|
||||
_rules.insert(5, PatternRule(r"yacc_empty", r"^ +\n$"))
|
||||
|
||||
class TrueDict(dict):
|
||||
def __contains__(self, k): return True
|
||||
def __getitem__(self, k): return True
|
||||
def __setitem__(self, k): pass
|
||||
def __delitem__(self, k): raise Exception, 'not possible'
|
||||
def __len__(self): return 1
|
||||
def __repr__(self): return '<TrueDict()>'
|
||||
def get(self, k): return True
|
||||
|
||||
class YaccGrammar(CGrammar):
|
||||
rules = _rules
|
||||
|
||||
class YaccTabber(CTabber2):
|
||||
open_tokens = {'delimiter': {'{': '}', '(': ')', '[': ']'},
|
||||
'yacc_delimiter': {'%{': '%}'}}
|
||||
close_tokens = {'delimiter': {'}': '{', ')': '(', ']': '['},
|
||||
'yacc_delimiter': {'%}': '%{'}}
|
||||
control_tokens = {'yacc_production': TrueDict()}
|
||||
scope_tokens = {}
|
||||
end_at_eof = False
|
||||
end_at_tokens = {'yacc_empty': TrueDict()}
|
||||
nocontinue_tokens = {}
|
||||
start_free_tokens = {'string.start': 'string.end'}
|
||||
end_free_tokens = {'string.end': 'string.start'}
|
||||
|
||||
class Yacc(mode.Fundamental):
|
||||
modename = 'yacc'
|
||||
extensions = ['.y']
|
||||
grammar = YaccGrammar
|
||||
tabbercls = YaccTabber
|
||||
colors = {
|
||||
'yacc_directive': ('yellow', 'default', 'bold'),
|
||||
'yacc_section': ('yellow', 'default', 'bold'),
|
||||
'yacc_delimiter': ('yellow', 'default', 'bold'),
|
||||
'yacc_production': ('yellow', 'default', 'bold'),
|
||||
'yacc_var': ('yellow', 'default', 'bold'),
|
||||
}
|
||||
|
||||
install = Yacc.install
|
6
tab.py
6
tab.py
|
@ -296,7 +296,7 @@ class StackTabber2(Tabber):
|
|||
def _match(self, *names):
|
||||
return self.stack and self.stack[-1].name in names
|
||||
def _nomatch(self, *names):
|
||||
return self.stack and self.stack[-1].name not in names
|
||||
return not self.stack or self.stack[-1].name not in names
|
||||
def _pop(self, *names):
|
||||
if self._match(*names):
|
||||
self.stack.pop()
|
||||
|
@ -408,6 +408,10 @@ class StackTabber2(Tabber):
|
|||
self._pop('macro')
|
||||
return
|
||||
|
||||
#d = self.end_at_tokens.get(name, {})
|
||||
#if d:
|
||||
# raise Exception, (name, s, d, d.get(s), d[s])
|
||||
|
||||
# remove implicit continuation
|
||||
if self.end_at_eof and i + start == end:
|
||||
self._pop_while('continue', 'control')
|
||||
|
|
Loading…
Reference in New Issue