diff --git a/.vscode/settings.json b/.vscode/settings.json index 4a59573..d28692c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -86,6 +86,7 @@ "xlocmes": "cpp", "xlocmon": "cpp", "xloctime": "cpp", - "xtree": "cpp" + "xtree": "cpp", + "deque": "cpp" } } \ No newline at end of file diff --git a/filecomplete.cpp b/filecomplete.cpp index 5c4770a..83cbecc 100644 --- a/filecomplete.cpp +++ b/filecomplete.cpp @@ -1,4 +1,5 @@ #include "filecomplete.h" +#include #include #include #include @@ -17,9 +18,9 @@ namespace fs = std::filesystem; #endif #endif -#include -#include -#include +#include +#include +#include #define MAX_OF(x, y) (((x) > (y)) ? (x) : (y)) @@ -91,7 +92,7 @@ void clear_line(); void set_cursor_x(short x); short get_cursor_y(); char* fc_readline(); -void color_print(const char* text, COLOR_TYPE color); +void color_print(const char* text, const COLOR_TYPE color); static std::vector cur_work_content; static std::vector deadline_vch; @@ -153,8 +154,42 @@ std::string file_predict(const char* data) return result; } +#if defined(OS_UNIX) +int _getch() +{ + int character; + struct termios old_attr, new_attr; + + // Backup terminal attributes + if (tcgetattr(STDIN_FILENO, &old_attr) == -1) { + fprintf(stderr, "[ERROR] Couldn't get terminal attributes\n"); + exit(1); + } + + // Disable echo + new_attr = old_attr; + new_attr.c_lflag &= ~(ICANON | ECHO); + if (tcsetattr(STDIN_FILENO, TCSANOW, &new_attr) == -1) { + fprintf(stderr, "[ERROR] Couldn't set terminal attributes\n"); + exit(1); + } + + // Get input character + character = getchar(); + + // Restore terminal attributes + if (tcsetattr(STDIN_FILENO, TCSANOW, &old_attr) == -1) { + fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n"); + exit(1); + } + + return character; +} +#endif + std::pair get_wh() { +#if defined(OS_WINDOWS) HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); if (h_console == NULL) { fprintf(stderr, "[ERROR] Couldn't handle terminal\n"); @@ -170,16 +205,51 @@ std::pair get_wh() auto w = static_cast(cw); auto h = static_cast(ch); return std::make_pair(w, h); +#elif defined(OS_UNIX) + return std::make_pair(12, 12); +#endif +} + +int get_u8_len(unsigned char ch) +{ + if (ch >= 0x00 && ch <= 0x7F) { + return 1; + } else if ((ch & 0xE0) == 0xC0) { + return 2; + } else if ((ch & 0xF0) == 0xE0) { + return 3; + } else if ((ch & 0xF8) == 0xF0) { + return 4; + } else if ((ch & 0xFC) == 0xF8) { + return 5; + } else if ((ch & 0xFE) == 0xFC) { + return 6; + } else { + return 0; + } } void supply(std::vector& wch, char ch) { +#if defined(STRCODE_GBK) wch.push_back(ch); if (ch >= 0 && ch < 128) { return; } auto tch = _getch(); wch.push_back(tch); +#else + wch.push_back(ch); + int length = get_u8_len(static_cast(ch)); + if (length == 0) { + printf("Invalid Charactor!\n"); + exit(1); + } + for (int i = 1; i < length; ++i) { + auto tch = _getch(); + wch.push_back(tch); + } +#endif } void clear_line() @@ -367,9 +437,19 @@ char* fc_readline() } // Move cursor int cur_pos{}; +#if defined(STRCODE_GBK) for (int i = 0; i < buf.size() && i < wo; ++i) { cur_pos += static_cast(buf[i].size()); } +#else + for (int i = 0; i < buf.size() && i < wo; ++i) { + if (buf[i].size() > 1) { + cur_pos += 2; + } else { + cur_pos += 1; + } + } +#endif set_cursor_x(cur_pos + 1); // Read character from console @@ -397,18 +477,26 @@ char* fc_readline() // 在这里补全 if (!str_predict.empty()) { std::vector> temp; - for (int i = 0; i < str_predict.size(); ++i) { + for (int i = 0; i < str_predict.size();) { std::vector b; char curch = str_predict[i]; b.push_back(curch); if (curch >= 0 && curch < 128) { temp.push_back(b); + ++i; } else { - if ((i + 1) < str_predict.size()) { - b.push_back(str_predict[i + 1]); - temp.push_back(b); - ++i; +#if defined(STRCODE_GBK) + int length = 2; +#else + int length = get_u8_len(curch); +#endif + for (int z = 1; z < length; ++z) { + if ((i + z) < str_predict.size()) { + b.push_back(str_predict[i + z]); + } } + temp.push_back(b); + i += length; } } str_predict.clear(); @@ -487,7 +575,7 @@ void trans2buf(char* buffer) buffer[j++] = '\0'; } -void color_print(const char* text, COLOR_TYPE color) +void color_print(const char* text, const COLOR_TYPE color) { #if defined(OS_WINDOWS) HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); @@ -538,9 +626,12 @@ void color_print(const char* text, COLOR_TYPE color) printf("%s", color); printf("m"); - // Print colored text - printf("%s", text); - + if (!text) { + trans2buf(main_buf); + printf("%s", main_buf); + } else { + printf("%s", text); + } // Resets the text to default color printf("\033[0m"); #endif diff --git a/filecomplete.h b/filecomplete.h index a263985..1da7c4a 100644 --- a/filecomplete.h +++ b/filecomplete.h @@ -1,7 +1,11 @@ #ifndef FILE_COMPLETE_H #define FILE_COMPLETE_H -/* ************************************************** +/* *************************************************** + 如果编译的结果的【执行】环境为GBK, 请手动定义宏 + STRCODE_GBK + 否则默认是 UTF-8 编码。 +****************************************************** 添加截止符号,提示路径时,以此截断,比如当前输入为: GetFile someparm|tesa_fil_ 如果设置了截止符号|, 提示时将认为 tesa_fil 是某个