diff --git a/.vscode/settings.json b/.vscode/settings.json index 0f85196..da4cb4f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -109,6 +109,7 @@ "sstream": "cpp", "stop_token": "cpp", "thread": "cpp", - "regex": "cpp" + "regex": "cpp", + "csignal": "cpp" } } \ No newline at end of file diff --git a/filecomplete.cpp b/filecomplete.cpp index 65630c1..7a280b0 100644 --- a/filecomplete.cpp +++ b/filecomplete.cpp @@ -112,6 +112,7 @@ static std::string str_predict; static std::map> path_cache; static std::vector history; static size_t his_pos{}; +static std::string home_path{}; // 获取终端屏幕的行数和列数 // bool get_terminal_size(int& rows, int& cols) @@ -135,6 +136,38 @@ static size_t his_pos{}; // #endif // } +std::string get_home() +{ +#if defined(_WIN32) + char* value = nullptr; + std::size_t len = 0; +// _dupenv_s() 在 Visual Studio 2008 的 CRT (msvcr90) 中引入的,似乎没有进入系统 CRT (msvcrt)。 +// mingw-w64 GCC 通常默认只链接到系统 CRT,所以找不到这个符号。 +#if defined(MINGW32) || defined(MINGW64) + char* homedir = getenv("USERPROFILE"); + if (homedir) { + return std::string(homedir); + } + return ""; +#else + auto err = _dupenv_s(&value, &len, "USERPROFILE"); + if (err == 0 && value != nullptr) { + std::string ret(value); + free(value); + return ret; + } else { + return ""; + } +#endif +#else + char* homedir = getenv("HOME"); + if (homedir) { + return std::string(homedir); + } + return ""; +#endif +} + void append_his(const std::string& his) { history.push_back(his); @@ -173,7 +206,14 @@ std::string next_his() void flush_content(const std::string& search_dir, std::vector& out) { out.clear(); - fs::path work_path(search_dir); + + bool have_rep = false; + auto ts = search_dir; + if (search_dir.find("~") == 0) { + ts = home_path + search_dir.substr(1, search_dir.size() - 1); + have_rep = true; + } + fs::path work_path(ts); try { if (!fs::exists(work_path)) { return; @@ -181,13 +221,17 @@ void flush_content(const std::string& search_dir, std::vector& out) } catch (const std::exception& e) { return; } - if (path_cache.count(search_dir)) { - out = path_cache[search_dir]; + if (path_cache.count(ts)) { + out = path_cache[ts]; } else { for (const auto& entry : fs::directory_iterator(work_path)) { - out.push_back(entry.path().lexically_normal().string()); + auto fstrin = entry.path().lexically_normal().string(); + if (have_rep) { + fstrin = "~" + fstrin.substr(home_path.size(), fstrin.size() - home_path.size()); + } + out.push_back(fstrin); } - path_cache[search_dir] = out; + path_cache[ts] = out; } } @@ -546,6 +590,7 @@ char* fc_readline() free(tmp_buf); }); + home_path = get_home(); flush_content(".", cur_work_content); bool need_predic = true; std::chrono::time_point p1, p2;