fix:尝试修正Linux下打印光标位置错误问题
This commit is contained in:
parent
58fa3dbb09
commit
a00a49809e
120
filecomplete.cpp
120
filecomplete.cpp
@ -2,6 +2,8 @@
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <regex>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@ -89,6 +91,7 @@ static std::vector<char> word{};
|
||||
static size_t wo{};
|
||||
static size_t len{};
|
||||
static char* main_buf{};
|
||||
static std::mutex mut;
|
||||
|
||||
void trans2buf(char* buffer);
|
||||
void clear_line();
|
||||
@ -104,6 +107,28 @@ static std::map<std::string, std::vector<std::string>> path_cache;
|
||||
static std::vector<std::string> history;
|
||||
static size_t his_pos{};
|
||||
|
||||
// 获取终端屏幕的行数和列数
|
||||
// bool get_terminal_size(int& rows, int& cols)
|
||||
// {
|
||||
// #ifdef _WIN32
|
||||
// #else
|
||||
// FILE* pipe = popen("stty size", "r"); // 执行 stty size 命令
|
||||
// if (!pipe) {
|
||||
// return false;
|
||||
// }
|
||||
// char buffer[128];
|
||||
// if (fgets(buffer, sizeof(buffer), pipe) != nullptr) {
|
||||
// // 解析输出,格式为 "行数 列数"
|
||||
// if (sscanf(buffer, "%d %d", &rows, &cols) == 2) {
|
||||
// pclose(pipe);
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// pclose(pipe);
|
||||
// return false;
|
||||
// #endif
|
||||
// }
|
||||
|
||||
void append_his(const std::string& his)
|
||||
{
|
||||
history.push_back(his);
|
||||
@ -357,6 +382,7 @@ void clear_line()
|
||||
|
||||
void set_cursor_x(short x)
|
||||
{
|
||||
lock_print();
|
||||
#if defined(OS_WINDOWS)
|
||||
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (h_console == NULL) {
|
||||
@ -380,6 +406,7 @@ void set_cursor_x(short x)
|
||||
#elif defined(OS_UNIX)
|
||||
printf("\033[%d;%dH", get_cursor_y(), x);
|
||||
#endif
|
||||
unlock_print();
|
||||
}
|
||||
|
||||
short get_cursor_y()
|
||||
@ -435,25 +462,23 @@ short get_cursor_y()
|
||||
buf[i] = ch;
|
||||
}
|
||||
|
||||
i -= 2;
|
||||
while (buf[i] != ';') {
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
i -= 1;
|
||||
while (buf[i] != '[') {
|
||||
y = y + (buf[i] - '0') * pow;
|
||||
pow *= 10;
|
||||
i -= 1;
|
||||
}
|
||||
|
||||
// Reset attributes
|
||||
if (tcsetattr(0, TCSANOW, &new_attr) == -1) {
|
||||
fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
return (short)y;
|
||||
std::regex rg("\033\\[(\\d*);(\\d+)R");
|
||||
std::smatch match;
|
||||
std::string input(buf);
|
||||
|
||||
// 使用正则表达式匹配输入
|
||||
int mx{}, my{};
|
||||
if (std::regex_search(input, match, rg)) {
|
||||
mx = match[1].str().empty() ? 1 : std::stoi(match[1].str()); // 行号,默认为 1
|
||||
my = std::stoi(match[2].str()); // 列号
|
||||
}
|
||||
return mx;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -501,14 +526,7 @@ char* fc_readline()
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> p1, p2;
|
||||
p1 = std::chrono::high_resolution_clock::now();
|
||||
|
||||
#if defined(OS_WINDOWS)
|
||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_CURSOR_INFO cursorInfo;
|
||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
cursorInfo.bVisible = TRUE;
|
||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
#endif
|
||||
|
||||
enable_cur();
|
||||
auto refresh_show = [&]() {
|
||||
word.clear();
|
||||
clear_line();
|
||||
@ -531,14 +549,8 @@ char* fc_readline()
|
||||
cur_pos += 1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if defined(OS_UNIX)
|
||||
fflush(stdout);
|
||||
#endif
|
||||
set_cursor_x(cur_pos + 1);
|
||||
#if defined(OS_UNIX)
|
||||
fflush(stdout);
|
||||
#endif
|
||||
};
|
||||
|
||||
while (1) {
|
||||
@ -559,13 +571,7 @@ char* fc_readline()
|
||||
|
||||
switch (ch) {
|
||||
case ENTER:
|
||||
#if defined(OS_WINDOWS)
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
CONSOLE_CURSOR_INFO cursorInfo;
|
||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
cursorInfo.bVisible = FALSE;
|
||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
#endif
|
||||
disable_cur();
|
||||
// 这里还需要清除预测显示
|
||||
str_predict.clear();
|
||||
refresh_show();
|
||||
@ -676,6 +682,50 @@ char* fc_readline()
|
||||
return main_buf;
|
||||
}
|
||||
|
||||
void enable_cur()
|
||||
{
|
||||
#if defined(OS_WINDOWS)
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hConsole == NULL) {
|
||||
fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
|
||||
exit(1);
|
||||
}
|
||||
CONSOLE_CURSOR_INFO cursorInfo;
|
||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
cursorInfo.bVisible = TRUE;
|
||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
#else
|
||||
printf("\033[?25h");
|
||||
#endif
|
||||
}
|
||||
|
||||
void disable_cur()
|
||||
{
|
||||
#if defined(OS_WINDOWS)
|
||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (hConsole == NULL) {
|
||||
fprintf(stderr, "[ERROR] Couldn't handle terminal\n");
|
||||
exit(1);
|
||||
}
|
||||
CONSOLE_CURSOR_INFO cursorInfo;
|
||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
cursorInfo.bVisible = FALSE;
|
||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
||||
#else
|
||||
printf("\033[?25l");
|
||||
#endif
|
||||
}
|
||||
|
||||
void lock_print()
|
||||
{
|
||||
mut.lock();
|
||||
}
|
||||
|
||||
void unlock_print()
|
||||
{
|
||||
mut.unlock();
|
||||
}
|
||||
|
||||
void fc_free(char* str)
|
||||
{
|
||||
buf.clear();
|
||||
@ -697,6 +747,7 @@ void trans2buf(char* buffer)
|
||||
|
||||
void color_print(const char* text, const COLOR_TYPE color)
|
||||
{
|
||||
lock_print();
|
||||
#if defined(OS_WINDOWS)
|
||||
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (h_console == NULL) {
|
||||
@ -755,4 +806,5 @@ void color_print(const char* text, const COLOR_TYPE color)
|
||||
// Resets the text to default color
|
||||
printf("\033[0m");
|
||||
#endif
|
||||
unlock_print();
|
||||
}
|
||||
|
@ -14,16 +14,18 @@
|
||||
******************************************************/
|
||||
void fc_append(char deadline_ch);
|
||||
|
||||
/*****************************************************
|
||||
读取用户输入,替代 std::getline
|
||||
|
||||
如果返回值为 nullptr,表示用户输入了终止命令(ctrl-c)。
|
||||
******************************************************/
|
||||
// 读取用户输入,替代 std::getline 如果返回值为 nullptr,表示用户输入了终止命令(ctrl-c)。
|
||||
char* fc_readline();
|
||||
|
||||
/*****************************************************
|
||||
用于释放 fc_readline() 返回的 buffer 堆内存。
|
||||
******************************************************/
|
||||
// 光标禁用与启用
|
||||
void enable_cur();
|
||||
void disable_cur();
|
||||
|
||||
// 保证打印的顺序,三方打印需要等待内部打印结束才能打印,故有此锁。
|
||||
void lock_print();
|
||||
void unlock_print();
|
||||
|
||||
// 用于释放 fc_readline() 返回的 buffer 堆内存。
|
||||
void fc_free(char* str);
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user