• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

basilisp-lang / basilisp / 10948062695

19 Sep 2024 08:02PM CUT coverage: 98.89%. Remained the same
10948062695

push

github

web-flow
Fix a bug where the reader was double counting the CRLF newline seq (#1064)

Hi,

can you please a fix for the line number in the metadata generated by
the reader. It fixes #1063.

We now check the char at -2 only if it’s:
-  `\n` (for `\nC` or `\r\nC` case)
-  `\r` (for the `\rC`, but not `\r\n`, case).

where `C` is any other char.

Added tests for the same.

Thanks

---------

Co-authored-by: ikappaki <ikappaki@users.noreply.github.com>

1903 of 1910 branches covered (99.63%)

Branch coverage included in aggregate %.

1 of 1 new or added line in 1 file covered. (100.0%)

8695 of 8807 relevant lines covered (98.73%)

0.99 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.45
/src/basilisp/lang/source.py
1
import itertools
1✔
2
import linecache
1✔
3
import os
1✔
4
from typing import Iterable, List, Optional
1✔
5

6
try:
1✔
7
    import pygments.formatters
1✔
8
    import pygments.lexers
1✔
9
    import pygments.styles
1✔
10
except ImportError:  # pragma: no cover
11

12
    def _format_source(
13
        s: str, disable_color: Optional[bool] = None  # pylint: disable=unused-argument
14
    ) -> str:
15
        return f"{s}{os.linesep}"
16

17
else:
18

19
    def _get_formatter_name(
20
        disable_color: Optional[bool] = None,
21
    ) -> Optional[str]:  # pragma: no cover
22
        """Get the Pygments formatter name for formatting the source code by
23
        inspecting various environment variables set by terminals.
24

25
        If If `disable_color` is explicitly True or `BASILISP_NO_COLOR` is set
26
        to a truthy value, use no formatting."""
27
        if (disable_color is True) or os.environ.get(
28
            "BASILISP_NO_COLOR", "false"
29
        ).lower() in {"1", "true"}:
30
            return None
31
        elif os.environ.get("COLORTERM", "") in {"truecolor", "24bit"}:
32
            return "terminal16m"
33
        elif "256" in os.environ.get("TERM", ""):
34
            return "terminal256"
35
        else:
36
            return "terminal"
37

38
    def _format_source(
39
        s: str, disable_color: Optional[bool] = None
40
    ) -> str:  # pragma: no cover
41
        """Format source code for terminal output.
42

43
        If `disable_color` is True, no formatting will be applied to the source code."""
44
        if (formatter_name := _get_formatter_name(disable_color)) is None:
45
            return f"{s}{os.linesep}"
46
        return pygments.highlight(
47
            s,
48
            lexer=pygments.lexers.get_lexer_by_name("clojure"),
49
            formatter=pygments.formatters.get_formatter_by_name(
50
                formatter_name, style=pygments.styles.get_style_by_name("emacs")
51
            ),
52
        )
53

54

55
def format_source_context(  # pylint: disable=too-many-arguments,too-many-locals
1✔
56
    filename: str,
57
    line: int,
58
    end_line: Optional[int] = None,
59
    num_context_lines: int = 5,
60
    show_cause_marker: bool = True,
61
    disable_color: Optional[bool] = None,
62
) -> List[str]:
63
    """Format source code context with line numbers and identifiers for the affected
64
    line(s).
65

66
    If `disable_color` is True, no color formatting will be applied to the source code.
67
    """
68
    assert num_context_lines >= 0
1✔
69

70
    lines = []
1✔
71

72
    if not filename.startswith("<") and not filename.endswith(">"):
1✔
73
        cause_range: Optional[range]
74
        if not show_cause_marker:
1✔
75
            cause_range = None
×
76
        elif end_line is not None and end_line != line:
1✔
77
            cause_range = range(line, end_line + 1)
1✔
78
        else:
79
            cause_range = range(line, line + 1)
1✔
80

81
        linecache.checkcache(filename=filename)
1✔
82
        if source_lines := linecache.getlines(filename):
1✔
83
            selected_lines: Iterable[str]
84
            if end_line is None and line > len(source_lines):
1✔
85
                end = len(source_lines) + 1
1✔
86
                start = max(end - num_context_lines, 0)
1✔
87
                selected_lines = itertools.chain(
1✔
88
                    source_lines[start:end], itertools.repeat("\n")
89
                )
90
            else:
91
                start = max(0, line - num_context_lines)
1✔
92
                end = min((end_line or line) + num_context_lines, len(source_lines))
1✔
93
                selected_lines = source_lines[start:end]
1✔
94

95
            num_justify = max(len(str(start)), len(str(end))) + 1
1✔
96
            for n, source_line in zip(range(start, end), selected_lines):
1✔
97
                if cause_range is None:
1✔
98
                    line_marker = " "
×
99
                elif n + 1 in cause_range:
1✔
100
                    line_marker = " > "
1✔
101
                else:
102
                    line_marker = "   "
1✔
103

104
                line_num = str(n + 1).rjust(num_justify)
1✔
105
                lines.append(
1✔
106
                    f"{line_num}{line_marker}| {_format_source(source_line.rstrip(), disable_color=disable_color)}"
107
                )
108

109
    return lines
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc