Python 在SublimateText中,full_line是如何工作的?

Python 在SublimateText中,full_line是如何工作的?,python,sublimetext3,Python,Sublimetext3,我正在尝试使用python模仿view.full\u linesublimiteText函数,如果我们阅读 直线(点):返回包含该点的直线 行(区域):返回区域的修改副本,使其从行的开头开始,到行的结尾结束。请注意,它可能跨越多条线 全行(点):作为line(),但区域包含尾随的换行符(如果有) 全行(区域):作为行(),但区域包含尾随的换行符(如果有) 我试着按照文档中的解释来做,下面是我得到的: class Region(object): __slots__ = ['a', 'b',

我正在尝试使用python模仿
view.full\u line
sublimiteText函数,如果我们阅读

直线(点):返回包含该点的直线

行(区域):返回区域的修改副本,使其从行的开头开始,到行的结尾结束。请注意,它可能跨越多条线

全行(点):作为line(),但区域包含尾随的换行符(如果有)

全行(区域):作为行(),但区域包含尾随的换行符(如果有)

我试着按照文档中的解释来做,下面是我得到的:

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}")

那么,我怎样才能修复例程,使它的行为与SublimateText的一样是1:1呢?

您的代码中有几个相当明显的错误,它们阻止了它做您想要的事情

Error at pos: 0, output (0, 1), expected output (0, 16)
这看起来像是一个指示,当代码从位置0向前扫描以确定行的结束位置时,它将停止在位置1而不是位置16

看看你的代码,这里有一点;它是
if
的上部,因为您的测试区域总是以
a==b
的方式生成的:

region.a=lskip_nonewlines(文本,region.a)
region.b=rskip_nonewlines(文本,region.b)
region.b=region.b+1如果region.b
看看这个,找到结束位置是rskip_nonewlines()的工作,只要返回的区域比我们跳起来的文本小1。因此,可以推断此方法旨在返回找到的
换行符的位置:

def rskip_nonewlines(文本,pt):
len_text=len(text)
尽管如此:
如果pt=len_文本:
打破
如果文本[pt]=“\n”:
打破
pt+=1
返回点
当您使用0的
pt
调用它时,它所做的第一件事就是确定
0
Error at pos: 0, output (0, 1), expected output (0, 16)
Error at pos: 15, output (15, 16), expected output (0, 16)