| 138 | } |
| 139 | |
| 140 | func (s *Snippet) String() string { |
| 141 | buf := &bytes.Buffer{} |
| 142 | |
| 143 | maxLineNumberDigits := digits(s.end) |
| 144 | lineNumberFormat := fmt.Sprintf("%%%dd", maxLineNumberDigits) |
| 145 | lineNumberSpacer := strings.Repeat(" ", maxLineNumberDigits) |
| 146 | lineIndicatorSpacer := strings.Repeat(" ", len(lineIndicator)) |
| 147 | columnSpacer := strings.Repeat(" ", max(s.column-1, 0)) |
| 148 | |
| 149 | // Loop over each line in the snippet |
| 150 | for i, lineHighlighted := range s.linesHighlighted { |
| 151 | if i > 0 { |
| 152 | fmt.Fprintln(buf) |
| 153 | } |
| 154 | |
| 155 | currentLine := s.start + i |
| 156 | lineNumber := fmt.Sprintf(lineNumberFormat, currentLine) |
| 157 | |
| 158 | // If this is a padding line or indicators are disabled, print it as normal |
| 159 | if currentLine != s.line || s.noIndicators { |
| 160 | fmt.Fprintf(buf, "%s %s | %s", lineIndicatorSpacer, lineNumber, lineHighlighted) |
| 161 | continue |
| 162 | } |
| 163 | |
| 164 | // Otherwise, print the line with indicators |
| 165 | fmt.Fprintf(buf, "%s %s | %s", color.RedString(lineIndicator), lineNumber, lineHighlighted) |
| 166 | |
| 167 | // Only print the column indicator if the column is in bounds |
| 168 | if s.column > 0 && s.column <= len(s.linesRaw[i]) { |
| 169 | fmt.Fprintf(buf, "\n%s %s | %s%s", lineIndicatorSpacer, lineNumberSpacer, columnSpacer, color.RedString(columnIndicator)) |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | // If there are lines, but no line is selected, print the column indicator under all the lines |
| 174 | if len(s.linesHighlighted) > 0 && s.line == 0 && s.column > 0 { |
| 175 | fmt.Fprintf(buf, "\n%s %s | %s%s", lineIndicatorSpacer, lineNumberSpacer, columnSpacer, color.RedString(columnIndicator)) |
| 176 | } |
| 177 | |
| 178 | return buf.String() |
| 179 | } |
| 180 | |
| 181 | func digits(number int) int { |
| 182 | count := 0 |