status_t console_init(void) { update_screen_size(); console_hide_cursor(); console_clear_screen(); // enable stdio functionality stdin = (FILE *)&sInput; stdout = stderr = (FILE *)&sOutput; return B_OK; }
//------------------------------------------------------------------------------ static void display_matches(char** matches, int match_count, int max_length) { int i; char** new_matches; CONSOLE_SCREEN_BUFFER_INFO csbi; WORD text_attrib; HANDLE std_out_handle; wchar_t buffer[512]; int show_matches = 2; // The matches need to be processed so needless path information is removed // (this is caused by the \ and / hurdles). max_length = 0; ++match_count; new_matches = (char**)calloc(1, match_count * sizeof(char**)); for (i = 0; i < match_count; ++i) { int len; char* slash = strrchr(matches[i], '\\'); new_matches[i] = (slash != NULL) ? slash + 1 : matches[i]; len = (int)strlen(new_matches[i]); max_length = len > max_length ? len : max_length; } --match_count; std_out_handle = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleScreenBufferInfo(std_out_handle, &csbi); // Get the console's current colour settings if (g_match_palette[0] == -1) { // Pick a suitable foreground colour, check fg isn't the same as bg, and set. text_attrib = csbi.wAttributes; text_attrib ^= 0x08; if ((text_attrib & 0xf0) == (text_attrib & 0x0f)) { text_attrib ^= FOREGROUND_INTENSITY; } } else { text_attrib = csbi.wAttributes & 0xf0; text_attrib |= (g_match_palette[0] & 0x0f); } SetConsoleTextAttribute(std_out_handle, text_attrib); // If there's lots of matches, check with the user before displaying them // This matches readline's behaviour, which will get skipped (annoyingly) if ((rl_completion_query_items > 0) && (match_count >= rl_completion_query_items)) { DWORD written; _snwprintf( buffer, sizeof_array(buffer), L"\nDisplay all %d possibilities? (y or n)", match_count ); WriteConsoleW(std_out_handle, buffer, wcslen(buffer), &written, NULL); while (show_matches > 1) { int c = rl_read_key(); switch (c) { case 'y': case 'Y': case ' ': show_matches = 1; break; case 'n': case 'N': case 0x7f: show_matches = 0; break; } } } // Get readline to display the matches. Flush stream so we catch set colours update_screen_size(); if (show_matches > 0) { rl_display_match_list(new_matches, match_count, max_length); } else { rl_crlf(); } fflush(rl_outstream); // Reset console colour back to normal. SetConsoleTextAttribute(std_out_handle, csbi.wAttributes); rl_forced_update_display(); rl_display_fixed = 1; free(new_matches); }