big iperl bugfix, python semantic complete, etc

--HG--
branch : pmacs2
This commit is contained in:
moculus 2008-06-06 01:55:17 +00:00
parent 1b326ea7a2
commit 86fa0512af
6 changed files with 46 additions and 72 deletions

View File

@ -458,6 +458,11 @@ class InterpreterBuffer(Buffer):
def pipe_write(self, s):
self.pipe.stdin.write("%s\n" % s)
self.pipe.stdin.flush()
def completions(self, word):
self.pipe_write("COMPLETE:%s" % word)
candidates = self.pipe_read_completions()
self.pipe_read()
return candidates
def pipe_read_completions(self):
(typ_, value) = self.pipe_readline()
assert typ_ == 'COMPLETIONS', '%r %r' % (typ_, value)

View File

@ -82,67 +82,9 @@ class GetToken(Method):
else:
w.set_error('Token: %r (%s)' % (token.string, token.fqname()))
class TokenComplete2(Method):
'''Complete token names based on other tokens in the buffer'''
def _prune_candidates(self, t, minlen, candidates):
if not candidates:
return ([], t.string)
i = len(t.string)
while i < minlen:
c = candidates[0][i]
for s in candidates:
if s[i] != c:
return (candidates, candidates[0][:i])
i += 1
return (candidates, candidates[0][:minlen])
def _min_completion(self, w, t):
h = w.get_highlighter()
minlen = None
candidates = {}
for line in h.tokens:
for t2 in line:
if t2 is t:
continue
elif False and t2.name != t.name:
continue
elif t2.string.startswith(t.string):
candidates[t2.string] = 1
if minlen is None:
minlen = len(t2.string)
else:
minlen = min(minlen, len(t2.string))
return self._prune_candidates(t, minlen, candidates.keys())
def _execute(self, w, **vargs):
t = w.get_token2()
if t is None:
w.set_error("No token to complete!")
return
elif regex.reserved_token_names.match(t.name):
w.set_error("Will not complete reserved token")
return
(candidates, result) = self._min_completion(w, t)
if candidates:
p1 = Point(t.x, t.y)
p2 = Point(t.end_x(), t.y)
w.buffer.delete(p1, p2)
w.insert_string(p1, result)
if not candidates:
w.set_error("No completion: %r" % result)
elif len(candidates) == 1:
w.set_error("Unique completion: %r" % result)
elif result in candidates:
w.set_error("Ambiguous completion: %r" % candidates)
else:
w.set_error("Partial completion: %r" % candidates)
class TokenComplete(Method):
'''Complete token names based on other tokens in the buffer'''
_mini_prompt = 'Token Complete'
def _execute(self, w, **vargs):
self.old_window = w
tabber = completer.TokenCompleter()
@ -174,8 +116,9 @@ class TokenComplete(Method):
else:
if exists:
pass
w.application.open_mini_buffer("Foog: ", callback, method=self,
tabber=tabber, startvalue=s2)
w.application.open_mini_buffer("%s: " % self._mini_prompt, callback,
method=self, tabber=tabber,
startvalue=s2)
class OpenConsole(Method):
'''Evaluate python expressions (for advanced use and debugging only)'''

View File

@ -42,10 +42,7 @@ class IpythonTab(method.Method):
word = line[x1:x2]
b = w.mode.get_ipython()
b.pipe_write("COMPLETE:%s" % word)
candidates = b.pipe_read_completions()
w.mode.read_sync()
candidates = b.completions(word)
if candidates:
s = completer.find_common_string(candidates)
w.buffer.delete(Point(x1, 0), Point(x2, 0), force=True)

View File

@ -492,6 +492,7 @@ class PerlWrapParagraph(method.WrapParagraph):
w.set_error("did not detect comment or pod lines")
class PerlSemanticComplete(method.introspect.TokenComplete):
_mini_prompt = 'Semantic Complete'
def _min_completion(self, w, t):
a = w.application
a.methods['iperl-path-start'].execute(w, switch=False)

View File

@ -286,6 +286,28 @@ class PythonInitNames(method.Method):
w.mode.context.build_name_map()
w.application.set_error("Initialized name maps")
class PythonSemanticComplete(method.introspect.TokenComplete):
_mini_prompt = 'Semantic Complete'
def _min_completion(self, w, t):
a = w.application
a.methods['ipython-path-start'].execute(w, switch=False)
name = buffer.IperlBuffer.create_name(w.buffer)
b = a.get_buffer_by_name(name)
line = w.buffer.lines[t.y]
(x1, x2) = (t.x, t.end_x())
candidates = [t.string + s for s in b.completions(line[x1:x2])]
minlen = None
for candidate in candidates:
if minlen is None:
minlen = len(candidate)
else:
minlen = min(minlen, len(candidate))
return self._prune_candidates(t, minlen, candidates)
class PythonGotoName(method.Method):
'''Jump to a class or function defined in this module'''
args = [method.Argument("name", type(""), "pythonname", "Goto Name: ")]
@ -452,7 +474,7 @@ class Python(mode.Fundamental):
}
actions = [PythonInitNames, PythonListNames, PythonGotoName,
PythonGotoFunction, PythonGotoClass, PythonCheckSyntax,
PythonDictCleanup,
PythonDictCleanup, PythonSemanticComplete,
PythonInsertTripleSquotes, PythonInsertTripleDquotes]
completers = {
"pythonname": PythonNameCompleter(),
@ -485,6 +507,7 @@ class Python(mode.Fundamental):
self.add_bindings('python-dict-cleanup', ('C-c h',))
self.add_bindings('python-insert-triple-squotes', ('C-c M-\'',))
self.add_bindings('python-insert-triple-dquotes', ('C-c M-"',))
self.add_bindings('python-semantic-complete', ('C-c TAB',))
self.context = PythonContext(self)
install = Python.install

View File

@ -71,12 +71,10 @@ sub resolve_ref {
# the completer used by readline
sub readline_complete {
my ($word, $line, $x) = @_;
#return complete($word, $line, $x);
my $full_word = readline_full_word($word, $line, $x);
my $delta = $x - length($word) + length($full_word);
my $delta = length($full_word) - length($word);
my @candidates = complete($full_word);
return map { substr($_, $delta) } @candidates;
}
# some handy regexs
@ -114,6 +112,7 @@ sub _isa_complete {
}
sub sigil_complete {
my ($type, $sigil, $pkg, $sep, $name) = @_;
#print STDERR " $type|$sigil|$pkg|$sep|$name\n";
my $base = $pkg . $sep . $name;
my @names;
my @pkgs = _pkg_complete($pkg, $sep, $name, 1);
@ -181,10 +180,12 @@ sub complete {
} elsif($word =~ m/^${hash_re}(.*)$/) {
# literal hash
my ($hash, $key) = ($1, $2);
#print STDERR "\n$hash|$key\n";
my $obj = eval("\\\%$hash");
if($obj) {
@words = map { "\$${hash}{$_" } grep { $_ =~ m/^$key/ } keys(%$obj);
}
#print STDERR Dumper(\@words);
} elsif($word =~ m/^${hash_ref_re}(.*)$/) {
# hashref
my ($hash, $key) = ($1, $2);
@ -195,14 +196,18 @@ sub complete {
} elsif($word =~ m/^${default_re1}$/ || $word =~ m/^${default_re2}$/ || $word =~ m/^${default_re3}$/) {
# package or simple var
my($sigil, $pkg, $sep, $name) = ($1, $2, $3, $4);
#print STDERR "\n$sigil|$pkg|$sep|$name\n";
my($oldpkg, $oldsep) = ($pkg, $sep);
if($PKG && $pkg eq '' && $sep eq '') {
($pkg, $sep) = ($PKG, '::');
}
if($sigil eq '$') {
push(@words, sigil_complete('$', '$', $pkg, $sep, $name));
push(@words, map {"$_\["} sigil_complete('@', '$', $pkg, $sep, $name));
push(@words, map {"$_\{"} sigil_complete('%', '$', $pkg, $sep, $name));
foreach my $pair ([$pkg, $sep], ['', '']) {
my ($_pkg, $_sep) = @$pair;
push(@words, sigil_complete('$', '$', $_pkg, $_sep, $name));
push(@words, map {"$_\["} sigil_complete('@', '$', $_pkg, $_sep, $name));
push(@words, map {"$_\{"} sigil_complete('%', '$', $_pkg, $_sep, $name));
}
} elsif($sigil) {
@words = sigil_complete($sigil, $sigil, $pkg, $sep, $name);
} else {