diff --git a/.vscode/settings.json b/.vscode/settings.json index 5069fe4..87a0026 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -5,7 +5,7 @@ "terminal.integrated.fontFamily": "Source Code Pro", "cmake.configureOnOpen": true, "cmake.debugConfig": { - "console": "integratedTerminal", + "console": "externalTerminal", "setupCommands": [ { "description": "-gdb-set charset utf-8", @@ -33,5 +33,44 @@ "ja": true, "zh-hant": true, "zh-hans": true + }, + "files.associations": { + "cmath": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "initializer_list": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "memory": "cpp", + "new": "cpp", + "ostream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeinfo": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocinfo": "cpp", + "xlocnum": "cpp", + "xmemory": "cpp", + "xmemory0": "cpp", + "xstddef": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xutility": "cpp" } } \ No newline at end of file diff --git a/filecomplete.cpp b/filecomplete.cpp index 16d6414..8c5705f 100644 --- a/filecomplete.cpp +++ b/filecomplete.cpp @@ -69,18 +69,39 @@ #define SPACE 32 #define TAB 9 +constexpr int buf_size = 1024 * 100; static std::vector> buf{}; static std::vector word{}; static size_t wo{}; static size_t len{}; +static short cy{}; +static short cx{}; -short terminal_width(); void clear_line(); void set_cursor_x(short x); short get_cursor_y(); -char* readline(); +char* fc_readline(); void color_print(char* text, COLOR_TYPE color); +std::pair get_wh() +{ + HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); + if (h_console == NULL) { + fprintf(stderr, "[ERROR] Couldn't handle terminal\n"); + exit(1); + } + CONSOLE_SCREEN_BUFFER_INFO console_info; + if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) { + fprintf(stderr, "[ERROR] Couldn't get terminal info\n"); + exit(1); + } + int cw = console_info.srWindow.Right - console_info.srWindow.Left + 1; + int ch = console_info.srWindow.Bottom - console_info.srWindow.Top + 1; + auto w = static_cast(cw); + auto h = static_cast(ch); + return std::make_pair(w, h); +} + void supply(std::vector& wch, char ch) { wch.push_back(ch); @@ -91,42 +112,11 @@ void supply(std::vector& wch, char ch) wch.push_back(tch); } -short terminal_width() -{ -#if defined(OS_WINDOWS) - // Handle current terminal - HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); - if (h_console == NULL) { - fprintf(stderr, "[ERROR] Couldn't handle terminal\n"); - exit(1); - } - - // Get current attributes - CONSOLE_SCREEN_BUFFER_INFO console_info; - if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) { - fprintf(stderr, "[ERROR] Couldn't get terminal info\n"); - exit(1); - } - - // Return current width - return console_info.dwSize.X; -#elif defined(OS_UNIX) - struct winsize t_size; - - if (ioctl(STDOUT_FILENO, TIOCGWINSZ, &t_size) == -1) { - fprintf(stderr, "[ERROR] Couldn't get terminal info\n"); - exit(1); - } - - return (short)t_size.ws_col; -#endif -} - void clear_line() { #if defined(OS_WINDOWS) // Get current terminal width - short width = terminal_width(); + short width = get_wh().first; if (width < 1) { fprintf(stderr, "[ERROR] Size of terminal is too small\n"); exit(1); @@ -139,11 +129,11 @@ void clear_line() empty[width - 1] = '\0'; } - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_CURSOR_INFO cursorInfo; - GetConsoleCursorInfo(hConsole, &cursorInfo); - cursorInfo.bVisible = FALSE; - SetConsoleCursorInfo(hConsole, &cursorInfo); + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_CURSOR_INFO cursorInfo; + GetConsoleCursorInfo(hConsole, &cursorInfo); + cursorInfo.bVisible = FALSE; + SetConsoleCursorInfo(hConsole, &cursorInfo); // Clear line printf("\r%s\r", empty); @@ -164,14 +154,19 @@ void set_cursor_x(short x) exit(1); } + auto wh = get_wh(); // Create position COORD xy; - xy.X = x - 1; xy.Y = get_cursor_y(); + short px = x % wh.first - 1; + xy.X = px < 0 ? 0 : px; // Set cursor position if (SetConsoleCursorPosition(h_console, xy) == 0) { - fprintf(stderr, "[ERROR] Couldn't set terminal cursor position\n"); + auto code = GetLastError(); + fprintf(stderr, + "[ERROR] Couldn't set terminal cursor position, err=%lu\n", + code); exit(1); } #elif defined(OS_UNIX) @@ -254,17 +249,14 @@ short get_cursor_y() #endif } -char* readline() +char* fc_readline() { - short buff_cap = terminal_width(); - char* buffer = (char*)calloc((size_t)buff_cap, sizeof(char)); + char* buffer = (char*)calloc((size_t)buf_size, sizeof(char)); if (buffer == NULL) { fprintf(stderr, "[ERROR] Couldn't allocate memory for buffer\n"); exit(1); } - short buff_len = 0; - // Current hint number int hint_num = 0; while (1) { @@ -275,12 +267,12 @@ char* readline() color_print(buffer, DEFAULT_MAIN_COLOR); // Move cursor - int cur_pos{}; - for (int i = 0; i < buf.size() && i < wo; ++i) { - cur_pos += static_cast(buf[i].size()); - } - set_cursor_x(cur_pos + 1); - + int cur_pos{}; + for (int i = 0; i < buf.size() && i < wo; ++i) { + cur_pos += static_cast(buf[i].size()); + } + set_cursor_x(cur_pos + 1); + // Read character from console int ch = _getch(); @@ -322,7 +314,7 @@ char* readline() wo = wo < 1 ? 0 : (--wo); break; case RIGHT: - wo = wo >= len ? len : (++wo); + wo = wo >= len ? len : (++wo); break; case UP: break; @@ -343,20 +335,19 @@ char* readline() } default: { supply(word, ch); - if (wo < buf.size()) { - if (len >= buf.size()) { - buf.resize(buf.size() * 2); - } - if (len > 0) { - for (size_t i = len - 1; i >= wo; --i) { - buf[i + 1] = buf[i]; - } - buf[wo] = word; - } - } - else { - buf.push_back(word); - } + if (wo < buf.size()) { + if (len >= buf.size()) { + buf.resize(buf.size() * 2); + } + if (len > 0) { + for (size_t i = len - 1; i >= wo; --i) { + buf[i + 1] = buf[i]; + } + buf[wo] = word; + } + } else { + buf.push_back(word); + } ++wo; ++len; break; @@ -366,6 +357,11 @@ char* readline() return buffer; } +void fc_free(char* str) +{ + free(str); +} + void color_print(char* text, COLOR_TYPE color) { #if defined(OS_WINDOWS) @@ -384,6 +380,8 @@ void color_print(char* text, COLOR_TYPE color) exit(1); } + auto wh = get_wh(); + backup = console_info.wAttributes; // Print colored text @@ -403,11 +401,11 @@ void color_print(char* text, COLOR_TYPE color) tbuf.push_back('\0'); printf("%s", tbuf.c_str()); - HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_CURSOR_INFO cursorInfo; - GetConsoleCursorInfo(hConsole, &cursorInfo); - cursorInfo.bVisible = TRUE; - SetConsoleCursorInfo(hConsole, &cursorInfo); + HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); + CONSOLE_CURSOR_INFO cursorInfo; + GetConsoleCursorInfo(hConsole, &cursorInfo); + cursorInfo.bVisible = TRUE; + SetConsoleCursorInfo(hConsole, &cursorInfo); // Restore original color if (SetConsoleTextAttribute(h_console, backup) == 0) { diff --git a/filecomplete.h b/filecomplete.h index a6fec9b..160b7a1 100644 --- a/filecomplete.h +++ b/filecomplete.h @@ -1,3 +1,4 @@ #pragma once -char* readline(); \ No newline at end of file +char* fc_readline(); +void fc_free(char* str); \ No newline at end of file diff --git a/main.cpp b/main.cpp index d1ab142..bd82562 100644 --- a/main.cpp +++ b/main.cpp @@ -4,11 +4,13 @@ int main(int argc, char** argv) { + std::cout << "PreContent1 " << std::endl; + std::cout << "PreContent2 " << std::endl; while (1) { - char* content = readline(); + char* content = fc_readline(); if (content) { std::cout << std::string(content) << std::endl; - free(content); + fc_free(content); } } return 0;