tag-matching and code-complete fixed

--HG--
branch : pmacs2
This commit is contained in:
moculus 2007-06-17 13:49:52 +00:00
parent 214ee106aa
commit 6847df5dff
2 changed files with 91 additions and 86 deletions

115
method.py
View File

@ -1,4 +1,4 @@
import os, commands, popen2, re import os, commands, popen2, re, sets
import buffer2, default, regex, util, window2 import buffer2, default, regex, util, window2
from point2 import Point from point2 import Point
@ -810,18 +810,22 @@ class CodeComplete(Method):
if len(w.buffer.lines[cursor.y]) == 0: if len(w.buffer.lines[cursor.y]) == 0:
return return
elif cursor.x == 0:
p1 = w.find_left_word(cursor.offset(1, 0))
p2 = w.find_right_word()
else:
p1 = w.find_left_word()
p2 = w.find_right_word(cursor.offset(-1, 0))
word = w.buffer.get_substring(p1, p2)
bounds = w.get_word_bounds()
if bounds is None:
return
(p1, p2) = bounds
buffer = w.buffer
word = buffer.get_substring(p1, p2)
app = w.application
highlighter = buffer.highlights[w.mode.name()]
tokens = highlighter.tokens
seen = {} seen = {}
sofar = None sofar = None
tokens = w.mode.highlighter.get_tokens()
for token in tokens: for group in tokens:
for token in group:
s = token.string s = token.string
if s == word: if s == word:
continue continue
@ -845,8 +849,8 @@ class CodeComplete(Method):
#w.application.set_error('No completion possible: %r' % word) #w.application.set_error('No completion possible: %r' % word)
pass pass
elif sofar: elif sofar:
w.buffer.delete_string(p1, p2) w.buffer.delete(p1, p2)
w.buffer.insert_string_at_cursor(p1, sofar) w.buffer.insert_string(p1, sofar)
if num_seen == 1: if num_seen == 1:
w.application.set_error('Unique!') w.application.set_error('Unique!')
else: else:
@ -1289,9 +1293,8 @@ class SomethingCrazy(Method):
pass pass
class CloseTag(Method): class CloseTag(Method):
tags = {'(': ')', opentags = {'(': ')', '{': '}', '[': ']'}
'{': '}', closetags = {')': '(', '}': '{', ']': '['}
'[': ']'}
mytag = ')' mytag = ')'
def _execute(self, w, **vargs): def _execute(self, w, **vargs):
# if w.mode doesn't do tag matching, just insert the character return # if w.mode doesn't do tag matching, just insert the character return
@ -1303,70 +1306,52 @@ class CloseTag(Method):
# NOTE: we derence the cursor *before* inserting the character, so it is # NOTE: we derence the cursor *before* inserting the character, so it is
# expecected that the cursor variable should be the point the new # expecected that the cursor variable should be the point the new
# character is on. # character is on.
buffer = w.buffer (x, y) = w.logical_cursor().xy()
#cursor = w.physical_cursor()
tag_stack = []
w.insert_string_at_cursor(self.mytag) w.insert_string_at_cursor(self.mytag)
cursor = w.physical_cursor() app = w.application
assert cursor.x > 0, "my assumptions made an ass out of u and me" buffer = w.buffer
highlighter = buffer.highlights[w.mode.name()]
tokens = highlighter.tokens
# find the token for the current region, to see if it is a parenthesis
# token or not. if not (i.e. part of a comment or string) then return.
regions = w.mode.get_regions()
assert len(regions[cursor.y]) > 0, "no regions found; strange"
i = 0 i = 0
found = False while i < len(tokens[y]):
while i < len(regions[cursor.y]): token = tokens[y][i]
r = regions[cursor.y][i] if token.x == x and token.string == self.mytag:
if r[0] == cursor.x - 1 and r[1] == cursor.x and r[3] == self.mytag:
found = True
break break
elif r[0] <= cursor.x - 1and r[1] >= cursor.x: elif token.x <= x and token.end_x() > x:
# in this case, we weren't adding a closing tag, but something app.set_error('found non-match: %r %d,%d' % (token.string, i, y))
# else (a parenthesis in a comment or string, for instance)
return return
i += 1 i += 1
assert found, "fascinizing: %d %s" % \ if i >= len(tokens[y]):
(cursor.x, repr(regions[cursor.y][-3:])) app.set_error('none found: %d' % (i))
return
# note that the first region we parse should be the region we just added tag_stack = []
# (and which we already verified existed), namely the region at index i. while y >= 0:
j = cursor.y while i >= 0 and i < len(tokens[y]):
while j >= 0: token = tokens[y][i]
if j == cursor.y: s = token.string
index = i if token.string in self.closetags:
else:
index = len(regions[j]) - 1
while index >= 0:
region = regions[j][index]
s = region[3]
if s in self.tags:
if tag_stack[-1] == self.tags[s]:
tag_stack.pop(-1)
else:
msg = "tag mismatch: %r vs. %r" % (s, tag_stack[-1])
raise Exception, msg
elif s == ')' or s == ']' or s == '}':
tag_stack.append(s) tag_stack.append(s)
if len(tag_stack) == 0: elif token.string in self.opentags:
break if tag_stack[-1] == self.opentags[s]:
del tag_stack[-1]
else: else:
index -= 1 app.set_error("tag mismatch; got %r expected %r" %
s, self.close_tags[tag_stack[-1]])
return
if len(tag_stack) == 0: if len(tag_stack) == 0:
break p = Point(token.x, y)
else: w.set_active_point(p, msg='match found at (%(y)d, %(x)d)')
j -= 1 return
i -= 1
y -= 1
assert len(tag_stack) == 0, "no match for %r found" % (tag_stack[0]) i = len(tokens[y]) - 1
p = w.logical_point(Point(region[0], j)) app.set_error('tag mismatch: no tag found')
w.set_active_point(p, msg='match found on line %(y)d, at character %(x)d')
class CloseParen(CloseTag): class CloseParen(CloseTag):
mytag = ')' mytag = ')'
class CloseBrace(CloseTag): class CloseBrace(CloseTag):
mytag = '}' mytag = '}'
class CloseBracket(CloseTag): class CloseBracket(CloseTag):
mytag = ']' mytag = ']'

View File

@ -294,6 +294,26 @@ class Window(object):
p = self.find_right_word() p = self.find_right_word()
if p is not None: if p is not None:
self.goto(p) self.goto(p)
def get_word_bounds_at_point(self, p):
if len(self.buffer.lines[p.y]) == 0:
return
elif p.x == 0:
p1 = self.find_left_word(Point(p.x + 1, p.y))
p2 = self.find_right_word()
else:
p1 = self.find_left_word()
p2 = self.find_right_word(Point(p.x - 1, p.y))
return (p1, p2)
def get_word_at_point(self, p):
bounds = self.get_word_bounds_at_point(p)
if bounds is None:
return None
else:
return self.buffer.get_substring(bounds[0], bounds[1])
def get_word_bounds(self):
return self.get_word_bounds_at_point(self.logical_cursor())
def get_word(self):
return self.get_word_at_point(self.logical_cursor())
# page up/down # page up/down
def _pshift_up(self, p, num): def _pshift_up(self, p, num):