diff --git a/.vscode/settings.json b/.vscode/settings.json index 8239b74..0f85196 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -108,6 +108,7 @@ "optional": "cpp", "sstream": "cpp", "stop_token": "cpp", - "thread": "cpp" + "thread": "cpp", + "regex": "cpp" } } \ No newline at end of file diff --git a/filecomplete.cpp b/filecomplete.cpp index e4cfcf6..601f2e9 100644 --- a/filecomplete.cpp +++ b/filecomplete.cpp @@ -59,7 +59,7 @@ namespace fs = std::filesystem; #define SPECIAL_SEQ_1 0 #define SPECIAL_SEQ_2 224 #define COLOR_TYPE uint16_t -#define DEFAULT_TITLE_COLOR 160 +#define DEFAULT_TITLE_COLOR 10 #define DEFAULT_PREDICT_COLOR 8 #define DEFAULT_MAIN_COLOR 7 #elif defined(OS_UNIX) @@ -92,6 +92,8 @@ static size_t wo{}; static size_t len{}; static char* main_buf{}; static std::mutex mut; +static std::string header{}; +static size_t header_len{}; void trans2buf(char* buffer); void clear_line(); @@ -99,6 +101,7 @@ void set_cursor_x(short x); short get_cursor_y(); char* fc_readline(); void color_print(const char* text, const COLOR_TYPE color); +void add_newer(const std::vector& wch); static std::vector cur_work_content; static std::vector deadline_vch; @@ -382,7 +385,7 @@ void clear_line() void set_cursor_x(short x) { - lock_print(); + fc_lock_print(); #if defined(OS_WINDOWS) HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); if (h_console == NULL) { @@ -406,7 +409,7 @@ void set_cursor_x(short x) #elif defined(OS_UNIX) printf("\033[%d;%dH", get_cursor_y(), x); #endif - unlock_print(); + fc_unlock_print(); } short get_cursor_y() @@ -487,6 +490,36 @@ void fc_append(char deadline_ch) deadline_vch.push_back(deadline_ch); } +void add_newer(const std::vector& wch) +{ + if (wo < buf.size()) { + if (len >= buf.size()) { + buf.resize(buf.size() * 2); + } + if (len > 0) { + for (size_t i = len - 1; i >= wo; --i) { + buf[i + 1] = buf[i]; + } + } + buf[wo] = wch; + } else { + buf.push_back(wch); + } + ++wo; + ++len; +}; + +void fc_set_header(const char* h) +{ + header.clear(); + header.append(h); + header_len = 0; + auto v = str_to_vec(header); + for (const auto& item : v) { + header_len += item.size(); + } +} + char* fc_readline() { main_buf = (char*)malloc(sizeof(char) * buf_size); @@ -504,33 +537,16 @@ char* fc_readline() }); flush_content(".", cur_work_content); - auto add_newer = [&](const std::vector& wch) { - if (wo < buf.size()) { - if (len >= buf.size()) { - buf.resize(buf.size() * 2); - } - if (len > 0) { - for (size_t i = len - 1; i >= wo; --i) { - buf[i + 1] = buf[i]; - } - } - buf[wo] = wch; - } else { - buf.push_back(wch); - } - ++wo; - ++len; - }; - bool need_predic = true; std::chrono::time_point p1, p2; p1 = std::chrono::high_resolution_clock::now(); - enable_cur(); + fc_enable_cur(); auto refresh_show = [&]() { word.clear(); clear_line(); // Print current buffer + color_print(header.c_str(), DEFAULT_TITLE_COLOR); color_print(nullptr, DEFAULT_MAIN_COLOR); if (!str_predict.empty()) { color_print(str_predict.data(), DEFAULT_PREDICT_COLOR); @@ -550,7 +566,7 @@ char* fc_readline() } } #endif - set_cursor_x(cur_pos + 1); + set_cursor_x(cur_pos + 1 + header_len); }; while (1) { @@ -571,7 +587,7 @@ char* fc_readline() switch (ch) { case ENTER: - disable_cur(); + fc_disable_cur(); // 这里还需要清除预测显示 str_predict.clear(); refresh_show(); @@ -682,7 +698,7 @@ char* fc_readline() return main_buf; } -void enable_cur() +void fc_enable_cur() { #if defined(OS_WINDOWS) auto hConsole = GetStdHandle(STD_OUTPUT_HANDLE); @@ -699,7 +715,7 @@ void enable_cur() #endif } -void disable_cur() +void fc_disable_cur() { #if defined(OS_WINDOWS) auto hConsole = GetStdHandle(STD_OUTPUT_HANDLE); @@ -716,12 +732,12 @@ void disable_cur() #endif } -void lock_print() +void fc_lock_print() { mut.lock(); } -void unlock_print() +void fc_unlock_print() { mut.unlock(); } @@ -747,7 +763,7 @@ void trans2buf(char* buffer) void color_print(const char* text, const COLOR_TYPE color) { - lock_print(); + fc_lock_print(); #if defined(OS_WINDOWS) HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); if (h_console == NULL) { @@ -806,5 +822,5 @@ void color_print(const char* text, const COLOR_TYPE color) // Resets the text to default color printf("\033[0m"); #endif - unlock_print(); + fc_unlock_print(); } diff --git a/filecomplete.h b/filecomplete.h index d4f0f95..43f9ba8 100644 --- a/filecomplete.h +++ b/filecomplete.h @@ -1,31 +1,75 @@ #ifndef FILE_COMPLETE_H #define FILE_COMPLETE_H -/* *************************************************** - 如果编译的结果的【执行】环境为GBK, 请手动定义宏 - BINARY_GBK - 否则默认是 UTF-8 编码。 -****************************************************** - 添加截止符号,提示路径时,以此截断,比如当前输入为: - GetFile someparm|tesa_fil_ - 如果设置了截止符号|, 提示时将认为 tesa_fil 是某个 - 文件的名称开头,否则认为 someparm|tesa_fil 是文件 - 名称的开头 -******************************************************/ +/** + * @file file_complete.h + * @brief 控制台读取用户输入时,文件自动补全功能 + * + * 编码说明: + * - 如果程序运行环境使用 GBK 编码,请手动定义宏 `BINARY_GBK`。 + * - 默认编码为 UTF-8。 + * + * 功能说明: + * - 支持添加截止符号以确定路径补全范围。 + * - 提供替代 `std::getline` 的用户输入读取函数。 + * - 提供控制台光标控制与线程安全打印机制。 + */ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief 设置路径补全的截止符号。 + * + * @param deadline_ch 截止符号(例如 '|')。 + */ void fc_append(char deadline_ch); -// 读取用户输入,替代 std::getline 如果返回值为 nullptr,表示用户输入了终止命令(ctrl-c)。 -char* fc_readline(); +/** + * @brief 设置补全提示的前缀显示内容。 + * + * @param header 要显示的前缀字符串。 + */ +void fc_set_header(const char* h); -// 光标禁用与启用 -void enable_cur(); -void disable_cur(); +/** + * @brief 读取用户输入,替代 `std::getline`。 + * + * @return 成功返回堆分配的字符串,需使用 `fc_free` 释放; + * 如果返回 `NULL`,表示检测到终止命令(如 Ctrl+C)。 + */ +char* fc_readline(void); -// 保证打印的顺序,三方打印需要等待内部打印结束才能打印,故有此锁。 -void lock_print(); -void unlock_print(); +/** + * @brief 启用控制台光标显示。 + */ +void fc_enable_cur(void); -// 用于释放 fc_readline() 返回的 buffer 堆内存。 +/** + * @brief 禁用控制台光标显示。 + */ +void fc_disable_cur(void); + +/** + * @brief 锁定打印,确保多线程环境下的打印顺序一致。 + */ +void fc_lock_print(void); + +/** + * @brief 解锁打印,允许其他线程继续输出。 + */ +void fc_unlock_print(void); + +/** + * @brief 释放 `fc_readline` 返回的字符串内存。 + * + * @param str 需要释放的字符串指针。 + */ void fc_free(char* str); -#endif \ No newline at end of file +#ifdef __cplusplus +} +#endif + +#endif /* FILE_COMPLETE_H */ diff --git a/main.cpp b/main.cpp index a6b1781..fc34d68 100644 --- a/main.cpp +++ b/main.cpp @@ -19,16 +19,19 @@ int main(int argc, char** argv) std::cout << "PreContent1 " << std::endl; std::cout << "PreContent2 " << std::endl; fc_append('|'); - std::thread t(delay_auto_show); + fc_set_header("测试$:"); + // std::thread t(delay_auto_show); while (1) { char* content = fc_readline(); if (content) { + std::string cmd_input(content); fc_free(content); std::cout << "" << std::endl; + std::cout << cmd_input << std::endl; } } - t.join(); + // t.join(); return 0; }