fix:尝试修正Linux下打印光标位置错误问题
This commit is contained in:
parent
58fa3dbb09
commit
a00a49809e
120
filecomplete.cpp
120
filecomplete.cpp
@ -2,6 +2,8 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <regex>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -89,6 +91,7 @@ static std::vector<char> word{};
|
|||||||
static size_t wo{};
|
static size_t wo{};
|
||||||
static size_t len{};
|
static size_t len{};
|
||||||
static char* main_buf{};
|
static char* main_buf{};
|
||||||
|
static std::mutex mut;
|
||||||
|
|
||||||
void trans2buf(char* buffer);
|
void trans2buf(char* buffer);
|
||||||
void clear_line();
|
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 std::vector<std::string> history;
|
||||||
static size_t his_pos{};
|
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)
|
void append_his(const std::string& his)
|
||||||
{
|
{
|
||||||
history.push_back(his);
|
history.push_back(his);
|
||||||
@ -357,6 +382,7 @@ void clear_line()
|
|||||||
|
|
||||||
void set_cursor_x(short x)
|
void set_cursor_x(short x)
|
||||||
{
|
{
|
||||||
|
lock_print();
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
if (h_console == NULL) {
|
if (h_console == NULL) {
|
||||||
@ -380,6 +406,7 @@ void set_cursor_x(short x)
|
|||||||
#elif defined(OS_UNIX)
|
#elif defined(OS_UNIX)
|
||||||
printf("\033[%d;%dH", get_cursor_y(), x);
|
printf("\033[%d;%dH", get_cursor_y(), x);
|
||||||
#endif
|
#endif
|
||||||
|
unlock_print();
|
||||||
}
|
}
|
||||||
|
|
||||||
short get_cursor_y()
|
short get_cursor_y()
|
||||||
@ -435,25 +462,23 @@ short get_cursor_y()
|
|||||||
buf[i] = ch;
|
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
|
// Reset attributes
|
||||||
if (tcsetattr(0, TCSANOW, &new_attr) == -1) {
|
if (tcsetattr(0, TCSANOW, &new_attr) == -1) {
|
||||||
fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n");
|
fprintf(stderr, "[ERROR] Couldn't reset terminal attributes\n");
|
||||||
exit(1);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,14 +526,7 @@ char* fc_readline()
|
|||||||
std::chrono::time_point<std::chrono::high_resolution_clock> p1, p2;
|
std::chrono::time_point<std::chrono::high_resolution_clock> p1, p2;
|
||||||
p1 = std::chrono::high_resolution_clock::now();
|
p1 = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
#if defined(OS_WINDOWS)
|
enable_cur();
|
||||||
HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
CONSOLE_CURSOR_INFO cursorInfo;
|
|
||||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
|
||||||
cursorInfo.bVisible = TRUE;
|
|
||||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
auto refresh_show = [&]() {
|
auto refresh_show = [&]() {
|
||||||
word.clear();
|
word.clear();
|
||||||
clear_line();
|
clear_line();
|
||||||
@ -531,14 +549,8 @@ char* fc_readline()
|
|||||||
cur_pos += 1;
|
cur_pos += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
#if defined(OS_UNIX)
|
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
#endif
|
||||||
set_cursor_x(cur_pos + 1);
|
set_cursor_x(cur_pos + 1);
|
||||||
#if defined(OS_UNIX)
|
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -559,13 +571,7 @@ char* fc_readline()
|
|||||||
|
|
||||||
switch (ch) {
|
switch (ch) {
|
||||||
case ENTER:
|
case ENTER:
|
||||||
#if defined(OS_WINDOWS)
|
disable_cur();
|
||||||
hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
|
|
||||||
CONSOLE_CURSOR_INFO cursorInfo;
|
|
||||||
GetConsoleCursorInfo(hConsole, &cursorInfo);
|
|
||||||
cursorInfo.bVisible = FALSE;
|
|
||||||
SetConsoleCursorInfo(hConsole, &cursorInfo);
|
|
||||||
#endif
|
|
||||||
// 这里还需要清除预测显示
|
// 这里还需要清除预测显示
|
||||||
str_predict.clear();
|
str_predict.clear();
|
||||||
refresh_show();
|
refresh_show();
|
||||||
@ -676,6 +682,50 @@ char* fc_readline()
|
|||||||
return main_buf;
|
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)
|
void fc_free(char* str)
|
||||||
{
|
{
|
||||||
buf.clear();
|
buf.clear();
|
||||||
@ -697,6 +747,7 @@ void trans2buf(char* buffer)
|
|||||||
|
|
||||||
void color_print(const char* text, const COLOR_TYPE color)
|
void color_print(const char* text, const COLOR_TYPE color)
|
||||||
{
|
{
|
||||||
|
lock_print();
|
||||||
#if defined(OS_WINDOWS)
|
#if defined(OS_WINDOWS)
|
||||||
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
if (h_console == NULL) {
|
if (h_console == NULL) {
|
||||||
@ -755,4 +806,5 @@ void color_print(const char* text, const COLOR_TYPE color)
|
|||||||
// Resets the text to default color
|
// Resets the text to default color
|
||||||
printf("\033[0m");
|
printf("\033[0m");
|
||||||
#endif
|
#endif
|
||||||
|
unlock_print();
|
||||||
}
|
}
|
||||||
|
@ -14,16 +14,18 @@
|
|||||||
******************************************************/
|
******************************************************/
|
||||||
void fc_append(char deadline_ch);
|
void fc_append(char deadline_ch);
|
||||||
|
|
||||||
/*****************************************************
|
// 读取用户输入,替代 std::getline 如果返回值为 nullptr,表示用户输入了终止命令(ctrl-c)。
|
||||||
读取用户输入,替代 std::getline
|
|
||||||
|
|
||||||
如果返回值为 nullptr,表示用户输入了终止命令(ctrl-c)。
|
|
||||||
******************************************************/
|
|
||||||
char* fc_readline();
|
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);
|
void fc_free(char* str);
|
||||||
|
|
||||||
#endif
|
#endif
|
Loading…
x
Reference in New Issue
Block a user