tag-matching and code-complete fixed
--HG-- branch : pmacs2
This commit is contained in:
parent
214ee106aa
commit
6847df5dff
157
method.py
157
method.py
|
@ -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,43 +810,47 @@ 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)
|
|
||||||
|
|
||||||
seen = {}
|
bounds = w.get_word_bounds()
|
||||||
sofar = None
|
if bounds is None:
|
||||||
tokens = w.mode.highlighter.get_tokens()
|
return
|
||||||
for token in tokens:
|
|
||||||
s = token.string
|
(p1, p2) = bounds
|
||||||
if s == word:
|
buffer = w.buffer
|
||||||
continue
|
word = buffer.get_substring(p1, p2)
|
||||||
elif s.startswith(word):
|
app = w.application
|
||||||
seen[s] = True
|
highlighter = buffer.highlights[w.mode.name()]
|
||||||
if sofar is None:
|
tokens = highlighter.tokens
|
||||||
sofar = s
|
seen = {}
|
||||||
else:
|
sofar = None
|
||||||
l = min(len(s), len(sofar))
|
|
||||||
i = len(word)
|
for group in tokens:
|
||||||
while i < l:
|
for token in group:
|
||||||
if s[i] == sofar[i]:
|
s = token.string
|
||||||
i += 1
|
if s == word:
|
||||||
else:
|
continue
|
||||||
break
|
elif s.startswith(word):
|
||||||
sofar = s[:i]
|
seen[s] = True
|
||||||
|
if sofar is None:
|
||||||
|
sofar = s
|
||||||
|
else:
|
||||||
|
l = min(len(s), len(sofar))
|
||||||
|
i = len(word)
|
||||||
|
while i < l:
|
||||||
|
if s[i] == sofar[i]:
|
||||||
|
i += 1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
sofar = s[:i]
|
||||||
|
|
||||||
seen_keys = seen.keys()
|
seen_keys = seen.keys()
|
||||||
num_seen = len(seen_keys)
|
num_seen = len(seen_keys)
|
||||||
if word == sofar:
|
if word == sofar:
|
||||||
#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,10 +1293,9 @@ 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
|
||||||
if not w.mode.tag_matching:
|
if not w.mode.tag_matching:
|
||||||
|
@ -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)
|
||||||
|
elif token.string in self.opentags:
|
||||||
|
if tag_stack[-1] == self.opentags[s]:
|
||||||
|
del tag_stack[-1]
|
||||||
|
else:
|
||||||
|
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)')
|
||||||
index -= 1
|
return
|
||||||
if len(tag_stack) == 0:
|
i -= 1
|
||||||
break
|
y -= 1
|
||||||
else:
|
i = len(tokens[y]) - 1
|
||||||
j -= 1
|
app.set_error('tag mismatch: no tag found')
|
||||||
|
|
||||||
|
|
||||||
assert len(tag_stack) == 0, "no match for %r found" % (tag_stack[0])
|
|
||||||
p = w.logical_point(Point(region[0], j))
|
|
||||||
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 = ']'
|
||||||
|
|
20
window2.py
20
window2.py
|
@ -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):
|
||||||
|
|
Loading…
Reference in New Issue