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
|
||||
from point2 import Point
|
||||
|
||||
|
@ -810,43 +810,47 @@ class CodeComplete(Method):
|
|||
|
||||
if len(w.buffer.lines[cursor.y]) == 0:
|
||||
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 = {}
|
||||
sofar = None
|
||||
tokens = w.mode.highlighter.get_tokens()
|
||||
for token in tokens:
|
||||
s = token.string
|
||||
if s == word:
|
||||
continue
|
||||
elif s.startswith(word):
|
||||
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]
|
||||
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 = {}
|
||||
sofar = None
|
||||
|
||||
for group in tokens:
|
||||
for token in group:
|
||||
s = token.string
|
||||
if s == word:
|
||||
continue
|
||||
elif s.startswith(word):
|
||||
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()
|
||||
num_seen = len(seen_keys)
|
||||
num_seen = len(seen_keys)
|
||||
if word == sofar:
|
||||
#w.application.set_error('No completion possible: %r' % word)
|
||||
pass
|
||||
elif sofar:
|
||||
w.buffer.delete_string(p1, p2)
|
||||
w.buffer.insert_string_at_cursor(p1, sofar)
|
||||
w.buffer.delete(p1, p2)
|
||||
w.buffer.insert_string(p1, sofar)
|
||||
if num_seen == 1:
|
||||
w.application.set_error('Unique!')
|
||||
else:
|
||||
|
@ -1289,10 +1293,9 @@ class SomethingCrazy(Method):
|
|||
pass
|
||||
|
||||
class CloseTag(Method):
|
||||
tags = {'(': ')',
|
||||
'{': '}',
|
||||
'[': ']'}
|
||||
mytag = ')'
|
||||
opentags = {'(': ')', '{': '}', '[': ']'}
|
||||
closetags = {')': '(', '}': '{', ']': '['}
|
||||
mytag = ')'
|
||||
def _execute(self, w, **vargs):
|
||||
# if w.mode doesn't do tag matching, just insert the character return
|
||||
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
|
||||
# expecected that the cursor variable should be the point the new
|
||||
# character is on.
|
||||
buffer = w.buffer
|
||||
#cursor = w.physical_cursor()
|
||||
tag_stack = []
|
||||
(x, y) = w.logical_cursor().xy()
|
||||
w.insert_string_at_cursor(self.mytag)
|
||||
cursor = w.physical_cursor()
|
||||
assert cursor.x > 0, "my assumptions made an ass out of u and me"
|
||||
app = w.application
|
||||
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
|
||||
found = False
|
||||
while i < len(regions[cursor.y]):
|
||||
r = regions[cursor.y][i]
|
||||
if r[0] == cursor.x - 1 and r[1] == cursor.x and r[3] == self.mytag:
|
||||
found = True
|
||||
while i < len(tokens[y]):
|
||||
token = tokens[y][i]
|
||||
if token.x == x and token.string == self.mytag:
|
||||
break
|
||||
elif r[0] <= cursor.x - 1and r[1] >= cursor.x:
|
||||
# in this case, we weren't adding a closing tag, but something
|
||||
# else (a parenthesis in a comment or string, for instance)
|
||||
elif token.x <= x and token.end_x() > x:
|
||||
app.set_error('found non-match: %r %d,%d' % (token.string, i, y))
|
||||
return
|
||||
i += 1
|
||||
assert found, "fascinizing: %d %s" % \
|
||||
(cursor.x, repr(regions[cursor.y][-3:]))
|
||||
if i >= len(tokens[y]):
|
||||
app.set_error('none found: %d' % (i))
|
||||
return
|
||||
|
||||
# note that the first region we parse should be the region we just added
|
||||
# (and which we already verified existed), namely the region at index i.
|
||||
j = cursor.y
|
||||
while j >= 0:
|
||||
if j == cursor.y:
|
||||
index = i
|
||||
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 = []
|
||||
while y >= 0:
|
||||
while i >= 0 and i < len(tokens[y]):
|
||||
token = tokens[y][i]
|
||||
s = token.string
|
||||
if token.string in self.closetags:
|
||||
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:
|
||||
break
|
||||
else:
|
||||
index -= 1
|
||||
if len(tag_stack) == 0:
|
||||
break
|
||||
else:
|
||||
j -= 1
|
||||
|
||||
|
||||
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')
|
||||
p = Point(token.x, y)
|
||||
w.set_active_point(p, msg='match found at (%(y)d, %(x)d)')
|
||||
return
|
||||
i -= 1
|
||||
y -= 1
|
||||
i = len(tokens[y]) - 1
|
||||
app.set_error('tag mismatch: no tag found')
|
||||
|
||||
class CloseParen(CloseTag):
|
||||
mytag = ')'
|
||||
|
||||
class CloseBrace(CloseTag):
|
||||
mytag = '}'
|
||||
|
||||
class CloseBracket(CloseTag):
|
||||
mytag = ']'
|
||||
|
|
20
window2.py
20
window2.py
|
@ -294,6 +294,26 @@ class Window(object):
|
|||
p = self.find_right_word()
|
||||
if p is not None:
|
||||
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
|
||||
def _pshift_up(self, p, num):
|
||||
|
|
Loading…
Reference in New Issue