Я пытаюсь имитировать view.full_line
функцию SublimeText, используя python, если мы прочитаем документы , мы увидим:
line (point): возвращает строкусодержит точку.
строка (регион): возвращает измененную копию области, которая начинается в начале строки и заканчивается в конце строки.Обратите внимание, что он может занимать несколько строк.
full_line (точка): как строка (), но область включает в себя завершающий символ новой строки, если таковой имеется.
full_line (region): как строка (), но регион включает в себя завершающий символ новой строки, если таковой имеется.
Я пытался следовать объяснениям из этих документов, и вот что я получил:
class Region(object):
__slots__ = ['a', 'b', 'xpos']
def __init__(self, a, b=None, xpos=-1):
if b is None:
b = a
self.a = a
self.b = b
self.xpos = xpos
def __str__(self):
return "(" + str(self.a) + ", " + str(self.b) + ")"
def __repr__(self):
return "(" + str(self.a) + ", " + str(self.b) + ")"
def begin(self):
if self.a < self.b:
return self.a
else:
return self.b
def end(self):
if self.a < self.b:
return self.b
else:
return self.a
def lskip_nonewlines(text, pt):
len_text = len(text)
while True:
if pt <= 0 or pt >= len_text:
break
if text[pt - 1] == "\n" or text[pt] == "\n":
break
pt -= 1
return pt
def rskip_nonewlines(text, pt):
len_text = len(text)
while True:
if pt <= 0 or pt >= len_text:
break
if text[pt] == "\n":
break
pt += 1
return pt
def full_line(text, x):
region = Region(x)
if region.a <= region.b:
# try:
# if text[region.a]=="\n":
# region.a-=1
# except Exception as e:
# pass
region.a = lskip_nonewlines(text, region.a)
region.b = rskip_nonewlines(text, region.b)
region.b = region.b + 1 if region.b < len(text) else region.b
else:
region.a = rskip_nonewlines(text, region.a)
region.b = lskip_nonewlines(text, region.b)
region.a = region.a + 1 if region.a < len(text) else region.a
return (region.begin(), region.end())
if __name__ == '__main__':
text = "# I'm a comment\n\n\ndef foo():\n print('# No comment')\n"
sublime_output = [
[0, (0, 16)],
[1, (0, 16)],
[2, (0, 16)],
[3, (0, 16)],
[4, (0, 16)],
[5, (0, 16)],
[6, (0, 16)],
[7, (0, 16)],
[8, (0, 16)],
[9, (0, 16)],
[10, (0, 16)],
[11, (0, 16)],
[12, (0, 16)],
[13, (0, 16)],
[14, (0, 16)],
[15, (0, 16)],
[16, (16, 17)],
[17, (17, 18)],
[18, (18, 29)],
[19, (18, 29)],
[20, (18, 29)],
[21, (18, 29)],
[22, (18, 29)],
[23, (18, 29)],
[24, (18, 29)],
[25, (18, 29)],
[26, (18, 29)],
[27, (18, 29)],
[28, (18, 29)],
[29, (29, 55)],
[30, (29, 55)],
[31, (29, 55)],
[32, (29, 55)],
[33, (29, 55)],
[34, (29, 55)],
[35, (29, 55)],
[36, (29, 55)],
[37, (29, 55)],
[38, (29, 55)],
[39, (29, 55)],
[40, (29, 55)],
[41, (29, 55)],
[42, (29, 55)],
[43, (29, 55)],
[44, (29, 55)],
[45, (29, 55)],
[46, (29, 55)],
[47, (29, 55)],
[48, (29, 55)],
[49, (29, 55)],
[50, (29, 55)],
[51, (29, 55)],
[52, (29, 55)],
[53, (29, 55)],
[54, (29, 55)],
]
for test in sublime_output:
pos, expected_output = test
output = full_line(text, pos)
try:
assert output == expected_output
except Exception as e:
print(f"Error at pos: {pos}, output {output}, expected output {expected_output}")
Приведенный выше mcve сравнивает вывод с результатами, полученными из самого SublimeText.Вы можете видеть, что функция ведет себя довольно хорошо, но в некоторых угловых случаях она по-прежнему не работает:
Error at pos: 0, output (0, 1), expected output (0, 16)
Error at pos: 15, output (15, 16), expected output (0, 16)
Error at pos: 28, output (28, 29), expected output (18, 29)
Error at pos: 54, output (54, 55), expected output (29, 55)
Итак, как я могу исправить подпрограмму, чтобы она вела себя 1: 1, как SublimeText?