diff --git a/jedi/common.py b/jedi/common.py index ee60636a..abb271ae 100644 --- a/jedi/common.py +++ b/jedi/common.py @@ -159,24 +159,29 @@ def splitlines(string, keepends=False): also on form feeds. """ if keepends: - # If capturing parentheses are used in pattern, then the text of all - # groups in the pattern are also returned as part of the resulting - # list. - lst = re.split('(\n|\r\n)', string) + lst = string.splitlines(keepends=True) - # Need to merge the new lines with the actual lines. - odd = False - lines = [] - for string in lst: - if odd: - line += string - lines.append(line) - else: - line = string - odd = not odd - if odd: - lines.append(line) - return lines + # We have to merge lines that were broken by form feed characters. + merge = [] + for i, line in enumerate(lst): + if line.endswith('\f'): + merge.append(i) + + for index in reversed(merge): + try: + lst[index] = lst[index] + lst[index + 1] + del lst[index + 1] + except IndexError: + # index + 1 can be empty and therefore there's no need to + # merge. + pass + + # The stdlib's implementation of the end is inconsistent when calling + # it with/without keepends. One time there's an empty string in the + # end, one time there's none. + if string.endswith('\n') or string == '': + lst.append('') + return lst else: return re.split('\n|\r\n', string) diff --git a/test/test_common.py b/test/test_common.py index 8e3aae6b..217cdf52 100644 --- a/test/test_common.py +++ b/test/test_common.py @@ -5,9 +5,13 @@ def test_splitlines_no_keepends(): assert splitlines('asd\r\n') == ['asd', ''] assert splitlines('asd\r\n\f') == ['asd', '\f'] assert splitlines('\fasd\r\n') == ['\fasd', ''] + assert splitlines('') == [''] + assert splitlines('\n') == ['', ''] def test_splitlines_keepends(): assert splitlines('asd\r\n', keepends=True) == ['asd\r\n', ''] assert splitlines('asd\r\n\f', keepends=True) == ['asd\r\n', '\f'] assert splitlines('\fasd\r\n', keepends=True) == ['\fasd\r\n', ''] + assert splitlines('', keepends=True) == [''] + assert splitlines('\n', keepends=True) == ['\n', '']