@@ -122,6 +122,17 @@ supports_escape_sequences(void)
122122return TRUE;
123123}
124124125+/* ANSI color codes - safe colors that work on light and dark themes */
126+#define MIRB_COLOR_RESET "\033[0m"
127+#define MIRB_COLOR_BOLD "\033[1m"
128+#define MIRB_COLOR_RED "\033[31m"
129+#define MIRB_COLOR_GREEN "\033[32m"
130+131+/* Color helpers - return empty string if colors disabled */
132+static const char *col_reset(void) { return mirb_use_ansi ? MIRB_COLOR_RESET : ""; }
133+static const char *col_bold(void) { return mirb_use_ansi ? MIRB_COLOR_BOLD : ""; }
134+static const char *col_red(void) { return mirb_use_ansi ? MIRB_COLOR_RED : ""; }
135+125136/* Check if line starts with a mid-block keyword (else, elsif, rescue, ensure, when)
126137 * These keywords should be at the same indent level as the opening keyword */
127138static mrb_bool
@@ -157,8 +168,8 @@ reprint_line_with_indent(int line_num, const char *line, int indent)
157168/* Move cursor up, clear line, return to beginning */
158169printf("\033[A\r\033[K");
159170160-/* Print prompt */
161-printf("%d* ", line_num);
171+/* Print prompt (green for all prompts) */
172+printf("%s%d*%s ", mirb_use_ansi ? MIRB_COLOR_GREEN : "", line_num, col_reset());
162173163174/* Print corrected indentation */
164175for (i = 0; i < indent; i++) {
@@ -270,7 +281,11 @@ p(mrb_state *mrb, mrb_value obj)
270281{
271282mrb_value val = mrb_funcall_argv(mrb, obj, MRB_SYM(inspect), 0, NULL);
272283if (!mrb->exc) {
284+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
285+printf(" %s=>%s ", col_bold(), col_reset());
286+#else
273287fputs(" => ", stdout);
288+#endif
274289 }
275290else {
276291val = mrb_exc_get_output(mrb, mrb->exc);
@@ -292,6 +307,10 @@ p_error(mrb_state *mrb, struct RObject* exc, mrb_ccontext *cxt)
292307val = mrb_obj_as_string(mrb, val);
293308 }
294309310+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
311+printf("%s", col_red());
312+#endif
313+295314/* get first line of backtrace for location info */
296315mrb_value bt = mrb_exc_backtrace(mrb, mrb_obj_value(exc));
297316if (mrb_array_p(bt) && RARRAY_LEN(bt) > 0) {
@@ -327,7 +346,11 @@ p_error(mrb_state *mrb, struct RObject* exc, mrb_ccontext *cxt)
327346char* msg = mrb_locale_from_utf8(RSTRING_PTR(val), (int)RSTRING_LEN(val));
328347fwrite(msg, strlen(msg), 1, stdout);
329348mrb_locale_free(msg);
349+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
350+printf("%s\n", col_reset());
351+#else
330352putc('\n', stdout);
353+#endif
331354}
332355333356/* Guess if the user might want to enter more
@@ -818,11 +841,20 @@ main(int argc, char **argv)
818841 }
819842signal(SIGINT, ctrl_c_handler);
820843 {
821-char prompt[32];
822-snprintf(prompt, sizeof(prompt), "%d%c ", line_num, code_block_open ? '*' : '>');
844+char prompt[64];
823845#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
824846/* Set indent level for auto-indent on continuation lines */
825847mirb_indent_level = code_block_open ? calc_indent_level(ruby_code) : 0;
848+/* Build prompt with colors - readline needs \001 \002 around non-printing chars */
849+if (mirb_use_ansi) {
850+snprintf(prompt, sizeof(prompt), "\001" MIRB_COLOR_GREEN "\002%d%c\001" MIRB_COLOR_RESET "\002 ",
851+line_num, code_block_open ? '*' : '>');
852+ }
853+else {
854+snprintf(prompt, sizeof(prompt), "%d%c ", line_num, code_block_open ? '*' : '>');
855+ }
856+#else
857+snprintf(prompt, sizeof(prompt), "%d%c ", line_num, code_block_open ? '*' : '>');
826858#endif
827859line = MIRB_READLINE(prompt);
828860 }
@@ -897,7 +929,11 @@ main(int argc, char **argv)
897929if (0 < parser->nwarn) {
898930/* warning */
899931char* msg = mrb_locale_from_utf8(parser->warn_buffer[0].message, -1);
900-printf("line %d: %s\n", parser->warn_buffer[0].lineno, msg);
932+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
933+printf("%swarning: line %d: %s%s\n", col_red(), parser->warn_buffer[0].lineno, msg, col_reset());
934+#else
935+printf("warning: line %d: %s\n", parser->warn_buffer[0].lineno, msg);
936+#endif
901937mrb_locale_free(msg);
902938 }
903939if (0 < parser->nerr) {
@@ -910,6 +946,9 @@ main(int argc, char **argv)
910946int relative_line = err_line - cxt->lineno + 1;
911947912948/* show error with line:column (using relative line number) */
949+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
950+printf("%s", col_red());
951+#endif
913952printf("line %d:%d: %s\n", relative_line, err_col, msg);
914953915954/* show source line and caret if available */
@@ -926,6 +965,9 @@ main(int argc, char **argv)
926965printf("^\n");
927966 }
928967 }
968+#if !defined(MRB_USE_LINENOISE) && defined(RL_READLINE_VERSION)
969+printf("%s", col_reset());
970+#endif
929971930972mrb_locale_free(msg);
931973line_num = 1;