add:添加一个前缀提示符显示。
This commit is contained in:
parent
f6a975b984
commit
65c8996136
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
@ -108,6 +108,7 @@
|
||||
"optional": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"thread": "cpp"
|
||||
"thread": "cpp",
|
||||
"regex": "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<char>& wch);
|
||||
|
||||
static std::vector<std::string> cur_work_content;
|
||||
static std::vector<char> 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,24 +490,8 @@ void fc_append(char deadline_ch)
|
||||
deadline_vch.push_back(deadline_ch);
|
||||
}
|
||||
|
||||
char* fc_readline()
|
||||
void add_newer(const std::vector<char>& wch)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
char* tmp_buf = (char*)malloc(sizeof(char) * buf_size);
|
||||
std::memset(tmp_buf, 0x0, buf_size);
|
||||
std::shared_ptr<int> deleter(new int(), [tmp_buf](int* p) {
|
||||
delete p;
|
||||
free(tmp_buf);
|
||||
});
|
||||
|
||||
flush_content(".", cur_work_content);
|
||||
auto add_newer = [&](const std::vector<char>& wch) {
|
||||
if (wo < buf.size()) {
|
||||
if (len >= buf.size()) {
|
||||
buf.resize(buf.size() * 2);
|
||||
@ -522,15 +509,44 @@ char* fc_readline()
|
||||
++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);
|
||||
std::memset(main_buf, 0x0, buf_size);
|
||||
if (main_buf == NULL) {
|
||||
fprintf(stderr, "[ERROR] Couldn't allocate memory for buffer\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char* tmp_buf = (char*)malloc(sizeof(char) * buf_size);
|
||||
std::memset(tmp_buf, 0x0, buf_size);
|
||||
std::shared_ptr<int> deleter(new int(), [tmp_buf](int* p) {
|
||||
delete p;
|
||||
free(tmp_buf);
|
||||
});
|
||||
|
||||
flush_content(".", cur_work_content);
|
||||
bool need_predic = true;
|
||||
std::chrono::time_point<std::chrono::high_resolution_clock> 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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FILE_COMPLETE_H */
|
||||
|
7
main.cpp
7
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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user