[Bug #20940] [PRISM] Support NO_COLOR

Also use bold/faint SGR when possible.
This commit is contained in:
Nobuyoshi Nakada 2024-12-13 13:53:33 +09:00 committed by Nobuyoshi Nakada
parent 966458199d
commit 5c372969ad
Notes: git 2024-12-15 08:15:39 +00:00

View File

@ -10137,7 +10137,8 @@ typedef struct {
size_t divider_length;
} pm_parse_error_format_t;
#define PM_COLOR_GRAY "\033[38;5;102m"
#define PM_COLOR_BOLD "\033[1m"
#define PM_COLOR_GRAY "\033[2m"
#define PM_COLOR_RED "\033[1;31m"
#define PM_COLOR_RESET "\033[m"
#define PM_ERROR_TRUNCATE 30
@ -10194,6 +10195,9 @@ pm_parse_errors_format_sort(const pm_parser_t *parser, const pm_list_t *error_li
return errors;
}
/* Append a literal string to the buffer. */
#define pm_buffer_append_literal(buffer, str) pm_buffer_append_string(buffer, str, rb_strlen_lit(str))
static inline void
pm_parse_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *newline_list, const char *number_prefix, int32_t line, uint32_t column_start, uint32_t column_end, pm_buffer_t *buffer) {
int32_t line_delta = line - parser->start_line;
@ -10239,7 +10243,7 @@ pm_parse_errors_format_line(const pm_parser_t *parser, const pm_newline_list_t *
* Format the errors on the parser into the given buffer.
*/
static void
pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, pm_buffer_t *buffer, bool colorize, bool inline_messages) {
pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, pm_buffer_t *buffer, int highlight, bool inline_messages) {
assert(error_list->size != 0);
// First, we're going to sort all of the errors by line number using an
@ -10265,7 +10269,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
int32_t max_line_number = first_line_number > last_line_number ? first_line_number : last_line_number;
if (max_line_number < 10) {
if (colorize) {
if (highlight > 0) {
error_format = (pm_parse_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%1" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
@ -10279,7 +10283,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
};
}
} else if (max_line_number < 100) {
if (colorize) {
if (highlight > 0) {
error_format = (pm_parse_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%2" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
@ -10293,7 +10297,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
};
}
} else if (max_line_number < 1000) {
if (colorize) {
if (highlight > 0) {
error_format = (pm_parse_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%3" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
@ -10307,7 +10311,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
};
}
} else if (max_line_number < 10000) {
if (colorize) {
if (highlight > 0) {
error_format = (pm_parse_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%4" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
@ -10321,7 +10325,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
};
}
} else {
if (colorize) {
if (highlight > 0) {
error_format = (pm_parse_error_format_t) {
.number_prefix = PM_COLOR_GRAY "%5" PRIi32 " | " PM_COLOR_RESET,
.blank_prefix = PM_COLOR_GRAY " | " PM_COLOR_RESET,
@ -10370,10 +10374,12 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
// If this is the first error or we're on a new line, then we'll display
// the line that has the error in it.
if ((index == 0) || (error->line != last_line)) {
if (colorize) {
pm_buffer_append_string(buffer, PM_COLOR_RED "> " PM_COLOR_RESET, 12);
if (highlight > 1) {
pm_buffer_append_literal(buffer, PM_COLOR_RED "> " PM_COLOR_RESET);
} else if (highlight > 0) {
pm_buffer_append_literal(buffer, PM_COLOR_BOLD "> " PM_COLOR_RESET);
} else {
pm_buffer_append_string(buffer, "> ", 2);
pm_buffer_append_literal(buffer, "> ");
}
last_column_start = error->column_start;
@ -10416,7 +10422,8 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
column += (char_width == 0 ? 1 : char_width);
}
if (colorize) pm_buffer_append_string(buffer, PM_COLOR_RED, 7);
if (highlight > 1) pm_buffer_append_literal(buffer, PM_COLOR_RED);
else if (highlight > 0) pm_buffer_append_literal(buffer, PM_COLOR_BOLD);
pm_buffer_append_byte(buffer, '^');
size_t char_width = encoding->char_width(start + column, parser->end - (start + column));
@ -10429,7 +10436,7 @@ pm_parse_errors_format(const pm_parser_t *parser, const pm_list_t *error_list, p
column += (char_width == 0 ? 1 : char_width);
}
if (colorize) pm_buffer_append_string(buffer, PM_COLOR_RESET, 3);
if (highlight > 0) pm_buffer_append_literal(buffer, PM_COLOR_RESET);
if (inline_messages) {
pm_buffer_append_byte(buffer, ' ');
@ -10517,6 +10524,12 @@ pm_parse_process_error(const pm_parse_result_t *result)
pm_buffer_t buffer = { 0 };
const pm_string_t *filepath = &parser->filepath;
int highlight = rb_stderr_tty_p();
if (highlight) {
const char *no_color = getenv("NO_COLOR");
highlight = (no_color == NULL || no_color[0] == '\0') ? 2 : 1;
}
for (const pm_diagnostic_t *error = head; error != NULL; error = (const pm_diagnostic_t *) error->node.next) {
switch (error->level) {
case PM_ERROR_LEVEL_SYNTAX:
@ -10550,7 +10563,7 @@ pm_parse_process_error(const pm_parse_result_t *result)
pm_list_node_t *list_node = (pm_list_node_t *) error;
pm_list_t error_list = { .size = 1, .head = list_node, .tail = list_node };
pm_parse_errors_format(parser, &error_list, &buffer, rb_stderr_tty_p(), false);
pm_parse_errors_format(parser, &error_list, &buffer, highlight, false);
}
VALUE value = rb_exc_new(rb_eArgError, pm_buffer_value(&buffer), pm_buffer_length(&buffer));
@ -10580,7 +10593,7 @@ pm_parse_process_error(const pm_parse_result_t *result)
);
if (valid_utf8) {
pm_parse_errors_format(parser, &parser->error_list, &buffer, rb_stderr_tty_p(), true);
pm_parse_errors_format(parser, &parser->error_list, &buffer, highlight, true);
}
else {
for (const pm_diagnostic_t *error = head; error != NULL; error = (const pm_diagnostic_t *) error->node.next) {