diff --git a/.clang-format b/.clang-format index 402f22e..36e4997 100644 --- a/.clang-format +++ b/.clang-format @@ -11,7 +11,7 @@ ReflowComments: true SpacesBeforeTrailingComments: 3 TabWidth: 4 ConstructorInitializerAllOnOneLineOrOnePerLine: true -ColumnLimit: 80 +ColumnLimit: 130 AllowShortBlocksOnASingleLine: Never AllowShortFunctionsOnASingleLine: None AllowShortEnumsOnASingleLine: false diff --git a/.vscode/settings.json b/.vscode/settings.json index fc82f5a..4a59573 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -85,6 +85,7 @@ "xlocbuf": "cpp", "xlocmes": "cpp", "xlocmon": "cpp", - "xloctime": "cpp" + "xloctime": "cpp", + "xtree": "cpp" } } \ No newline at end of file diff --git a/filecomplete.cpp b/filecomplete.cpp index a4fcc00..5c4770a 100644 --- a/filecomplete.cpp +++ b/filecomplete.cpp @@ -1,4 +1,5 @@ #include "filecomplete.h" +#include #include #include @@ -30,8 +31,7 @@ namespace fs = std::filesystem; #include #include #endif -#elif defined(__APPLE__) || defined(__unix__) || defined(__unix) || \ - defined(unix) || defined(__linux__) +#elif defined(__APPLE__) || defined(__unix__) || defined(__unix) || defined(unix) || defined(__linux__) #ifndef OS_UNIX #define OS_UNIX @@ -84,7 +84,9 @@ static size_t wo{}; static size_t len{}; static short cy{}; static short cx{}; +static char* main_buf{}; +void trans2buf(char* buffer); void clear_line(); void set_cursor_x(short x); short get_cursor_y(); @@ -92,24 +94,28 @@ char* fc_readline(); void color_print(const char* text, COLOR_TYPE color); static std::vector cur_work_content; -static std::vector dynamic_content; static std::vector deadline_vch; static std::string str_predict; +static std::map> path_cache; -void flush_content(const std::string& search_dir, std::vector& out, - bool reletive) +void flush_content(const std::string& search_dir, std::vector& out) { out.clear(); fs::path work_path(search_dir); - if (!fs::exists(work_path)) { + try { + if (!fs::exists(work_path)) { + return; + } + } catch (const std::exception& e) { return; } - for (const auto& entry : fs::directory_iterator(work_path)) { - if (reletive) { - out.push_back(entry.path().filename().string()); - } else { - out.push_back(entry.path().string()); + if (path_cache.count(search_dir)) { + out = path_cache[search_dir]; + } else { + for (const auto& entry : fs::directory_iterator(work_path)) { + out.push_back(entry.path().lexically_normal().string()); } + path_cache[search_dir] = out; } } @@ -129,16 +135,20 @@ std::string file_predict(const char* data) } else { search_key = cur; } - if (cur.find("/") == std::string::npos && - cur.find("\\") == std::string::npos) { + if (cur.find("/") == std::string::npos && cur.find("\\") == std::string::npos) { for (const auto& item : cur_work_content) { if (item != search_key && item.find(search_key) == 0) { - return item.substr(search_key.size(), - item.size() - search_key.size()); + return item.substr(search_key.size(), item.size() - search_key.size()); } } } - for (const auto& item : dynamic_content) { + std::string bk_search_path = search_key.substr(0, search_key.find_last_of("\\/") + 1); + std::vector sr; + flush_content(bk_search_path, sr); + for (const auto& item : sr) { + if (item != search_key && item.find(search_key) == 0) { + return item.substr(search_key.size(), item.size() - search_key.size()); + } } return result; } @@ -224,9 +234,7 @@ void set_cursor_x(short x) // Set cursor position if (SetConsoleCursorPosition(h_console, xy) == 0) { auto code = GetLastError(); - fprintf(stderr, - "[ERROR] Couldn't set terminal cursor position, err=%lu\n", - code); + fprintf(stderr, "[ERROR] Couldn't set terminal cursor position, err=%lu\n", code); exit(1); } #elif defined(OS_UNIX) @@ -316,14 +324,21 @@ void fc_append(char deadline_ch) char* fc_readline() { - char* buffer = (char*)calloc((size_t)buf_size, sizeof(char)); - if (buffer == NULL) { + main_buf = (char*)malloc(sizeof(char) * buf_size); + std::memset(main_buf, 0x0, buf_size); + if (main_buf == NULL) { fprintf(stderr, "[ERROR] Couldn't allocate memory for buffer\n"); exit(1); } - flush_content(fs::current_path().string(), cur_work_content, true); + char* tmp_buf = (char*)malloc(sizeof(char) * buf_size); + std::memset(tmp_buf, 0x0, buf_size); + std::shared_ptr deleter(new int(), [tmp_buf](int* p) { + delete p; + free(tmp_buf); + }); + flush_content(".", cur_work_content); auto add_newer = [&](const std::vector& wch) { if (wo < buf.size()) { if (len >= buf.size()) { @@ -342,10 +357,7 @@ char* fc_readline() ++len; }; - // Current hint number - int hint_num = 0; while (1) { - word.clear(); clear_line(); // Print current buffer @@ -365,7 +377,7 @@ char* fc_readline() switch (ch) { case ENTER: - return nullptr; + return main_buf; #if defined(OS_WINDWS) case CTRL_C: { exit(0); @@ -386,15 +398,15 @@ char* fc_readline() if (!str_predict.empty()) { std::vector> temp; for (int i = 0; i < str_predict.size(); ++i) { - std::vector blk; + std::vector b; char curch = str_predict[i]; - blk.push_back(curch); + b.push_back(curch); if (curch >= 0 && curch < 128) { - temp.push_back(blk); + temp.push_back(b); } else { if ((i + 1) < str_predict.size()) { - blk.push_back(str_predict[i + 1]); - temp.push_back(blk); + b.push_back(str_predict[i + 1]); + temp.push_back(b); ++i; } } @@ -449,24 +461,32 @@ char* fc_readline() break; } } - // 预测 - std::string tbuf; - for (size_t i = 0; i < buf.size() && i < len; ++i) { - for (const auto& c : buf[i]) { - tbuf.push_back(c); - } - } - tbuf.push_back('\0'); - str_predict = file_predict(tbuf.data()); + // 补正 + trans2buf(tmp_buf); + str_predict = file_predict(tmp_buf); } - return buffer; + return main_buf; } void fc_free(char* str) { + buf.clear(); + wo = 0; + len = 0; free(str); } +void trans2buf(char* buffer) +{ + int j = 0; + for (size_t i = 0; i < buf.size() && i < len; ++i) { + for (const auto& c : buf[i]) { + buffer[j++] = c; + } + } + buffer[j++] = '\0'; +} + void color_print(const char* text, COLOR_TYPE color) { #if defined(OS_WINDOWS) @@ -486,7 +506,6 @@ void color_print(const char* text, COLOR_TYPE color) } auto wh = get_wh(); - backup = console_info.wAttributes; // Print colored text @@ -496,15 +515,8 @@ void color_print(const char* text, COLOR_TYPE color) } if (!text) { - std::string tbuf; - for (size_t i = 0; i < buf.size() && i < len; ++i) { - for (const auto& c : buf[i]) { - tbuf.push_back(c); - } - } - tbuf.push_back('\0'); - printf("%s", tbuf.c_str()); - + trans2buf(main_buf); + printf("%s", main_buf); } else { printf("%s", text); } diff --git a/filecomplete.h b/filecomplete.h index 45ffe91..a263985 100644 --- a/filecomplete.h +++ b/filecomplete.h @@ -1,18 +1,23 @@ -#pragma once +#ifndef FILE_COMPLETE_H +#define FILE_COMPLETE_H -/* **************************************************************************************************** +/* ************************************************** 添加截止符号,提示路径时,以此截断,比如当前输入为: - GetFile someparm|tesa_fil_ - 如果设置了截止符号|, 提示时将认为 tesa_fil 是某个文件的名称开头,否则认为 someparm|tesa_fil 是文件名称的开头 -*****************************************************************************************************/ + GetFile someparm|tesa_fil_ + 如果设置了截止符号|, 提示时将认为 tesa_fil 是某个 + 文件的名称开头,否则认为 someparm|tesa_fil 是文件 + 名称的开头 +******************************************************/ void fc_append(char deadline_ch); -/***************************************************************************************************** +/***************************************************** 读取用户输入,替代 std::getline -*****************************************************************************************************/ +******************************************************/ char* fc_readline(); -/***************************************************************************************************** - 用于释放 fc_readline() 返回的 buffer 空间。 -*****************************************************************************************************/ -void fc_free(char* str); \ No newline at end of file +/***************************************************** + 用于释放 fc_readline() 返回的 buffer 堆内存。 +******************************************************/ +void fc_free(char* str); + +#endif \ No newline at end of file