From 332e0c53b700edb99b585a769c8a8ecd2cbce20b Mon Sep 17 00:00:00 2001 From: taynpg Date: Wed, 8 Jan 2025 16:58:27 +0800 Subject: [PATCH] =?UTF-8?q?init=EF=BC=9A=E5=88=9D=E7=89=88=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 8 ++ .vscode/settings.json | 18 ++++ README.md | 5 + src/filecomplete.cpp | 238 ++++++++++++++++++++++++++++++++++++++++++ src/filecomplete.h | 6 ++ src/main.cpp | 6 ++ xmake.lua | 10 ++ 7 files changed, 291 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 src/filecomplete.cpp create mode 100644 src/filecomplete.h create mode 100644 src/main.cpp create mode 100644 xmake.lua diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..de3a27d --- /dev/null +++ b/.gitignore @@ -0,0 +1,8 @@ +# Xmake cache +.xmake/ +build/ + +# MacOS Cache +.DS_Store +compile_commands.json + diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..21c6db6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,18 @@ +{ + "files.autoSave": "onFocusChange", + "editor.fontSize": 14, + "editor.fontFamily": "'Source Code Pro', 'Courier New', monospace", + "terminal.integrated.fontFamily": "Source Code Pro", + "editor.fontLigatures": true, + "C_Cpp.default.configurationProvider": "tboox.xmake-vscode", + "cmake.configureOnOpen": false, + "C_Cpp.default.compileCommands": "${workspaceRoot}/build/compile_commands.json", + "C_Cpp.default.cppStandard": "c++17", + "editor.inlayHints.enabled": "off", + "editor.unicodeHighlight.allowedLocales": { + "ja": true, + "zh-hant": true, + "zh-hans": true + }, + "makefile.configureOnOpen": false +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..904d3cf --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# 简介 + +在控制台程序中,可以补全文件路径。 + +本项目修改自 [https://github.com/DieTime/cli-autocomplete](https://github.com/DieTime/cli-autocomplete) 。 \ No newline at end of file diff --git a/src/filecomplete.cpp b/src/filecomplete.cpp new file mode 100644 index 0000000..4bb25ab --- /dev/null +++ b/src/filecomplete.cpp @@ -0,0 +1,238 @@ +#include "filecomplete.h" + +#ifdef _MSC_VER +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif +#endif + +#include +#include +#include + +#define MAX_OF(x, y) (((x) > (y)) ? (x) : (y)) + +#if defined(_WIN32) || defined(__CYGWIN__) || defined(_WIN64) +#ifndef OS_WINDOWS +#define OS_WINDOWS + +#include +#include +#include +#endif +#elif defined(__APPLE__) || defined(__unix__) || defined(__unix) || defined(unix) || defined(__linux__) +#ifndef OS_UNIX +#define OS_UNIX + +#include +#include +#include +#endif +#else +#error Unknown environment! +#endif + +#if defined(OS_WINDOWS) +#define ENTER 13 +#define BACKSPACE 8 +#define LEFT 75 +#define RIGHT 77 +#define UP 72 +#define DOWN 80 +#define DEL 83 +#define CTRL_C 3 +#define SPECIAL_SEQ_1 0 +#define SPECIAL_SEQ_2 224 +#define COLOR_TYPE uint16_t +#define DEFAULT_TITLE_COLOR 160 +#define DEFAULT_PREDICT_COLOR 8 +#define DEFAULT_MAIN_COLOR 7 +#elif defined(OS_UNIX) +#define ENTER 10 +#define BACKSPACE 127 +#define LEFT 68 +#define RIGHT 67 +#define UP 65 +#define DOWN 66 +#define DEL 51 +#define DEL_AFTER 126 +#define SPECIAL_SEQ_1 27 +#define SPECIAL_SEQ_2 91 +#define COLOR_TYPE char * +#define DEFAULT_TITLE_COLOR "0;30;102" +#define DEFAULT_PREDICT_COLOR "90" +#define DEFAULT_MAIN_COLOR "0" +#endif +#define SPACE 32 +#define TAB 9 + +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(); + if (width < 1) + { + fprintf(stderr, "[ERROR] Size of terminal is too small\n"); + exit(1); + } + + // Create long empty string + char *empty = (char *)malloc(sizeof(char) * width); + memset(empty, ' ', width); + empty[width - 1] = '\0'; + + // Clear line + printf("\r%s\r", empty); + + // Free line + free(empty); +#elif defined(OS_UNIX) + printf("\033[2K\r"); +#endif +} + +void set_cursor_x(short x) +{ +#if defined(OS_WINDOWS) + HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); + if (h_console == NULL) + { + fprintf(stderr, "[ERROR] Couldn't handle terminal\n"); + exit(1); + } + + // Create position + COORD xy; + xy.X = x - 1; + xy.Y = get_cursor_y(); + + // Set cursor position + if (SetConsoleCursorPosition(h_console, xy) == 0) + { + fprintf(stderr, "[ERROR] Couldn't set terminal cursor position\n"); + exit(1); + } +#elif defined(OS_UNIX) + printf("\033[%d;%dH", get_cursor_y(), x); +#endif +} + +short get_cursor_y() +{ +#if defined(OS_WINDOWS) + HANDLE h_console = GetStdHandle(STD_OUTPUT_HANDLE); + if (h_console == NULL) + { + fprintf(stderr, "[ERROR] Couldn't handle terminal\n"); + exit(1); + } + + // Get terminal info + CONSOLE_SCREEN_BUFFER_INFO console_info; + if (GetConsoleScreenBufferInfo(h_console, &console_info) == 0) + { + fprintf(stderr, "[ERROR] Couldn't get terminal Y position\n"); + exit(1); + } + + // Return Y position + return console_info.dwCursorPosition.Y; +#elif defined(OS_UNIX) + struct termios old_attr, new_attr; + char ch, buf[30] = {0}; + int i = 0, pow = 1, y = 0; + + // Backup terminal attributes + if (tcgetattr(STDIN_FILENO, &new_attr) == -1) + { + fprintf(stderr, "[ERROR] Couldn't get terminal attributes\n"); + exit(1); + } + + // Disable echo + old_attr = new_attr; + old_attr.c_lflag &= ~(ICANON | ECHO); + if (tcsetattr(STDIN_FILENO, TCSANOW, &old_attr) == -1) + { + fprintf(stderr, "[ERROR] Couldn't set terminal attributes\n"); + exit(1); + } + + // Get info about cursor + if (write(STDOUT_FILENO, "\033[6n", 4) != 4) + { + fprintf(stderr, "[ERROR] Couldn't get cursor information\n"); + exit(1); + } + + // Get ^[[{this};1R value + + for (ch = 0; ch != 'R'; i++) + { + if (read(STDIN_FILENO, &ch, 1) != 1) + { + fprintf(stderr, "[ERROR] Couldn't read cursor information"); + exit(1); + } + 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; +#endif +} diff --git a/src/filecomplete.h b/src/filecomplete.h new file mode 100644 index 0000000..20f2c66 --- /dev/null +++ b/src/filecomplete.h @@ -0,0 +1,6 @@ +#pragma once + +short terminal_width(); +void clear_line(); +void set_cursor_x(short x); +short get_cursor_y(); \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..b374e27 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,6 @@ +#include "filecomplete.h" +#include + +int main(int argc, char** argv) { + return 0; +} diff --git a/xmake.lua b/xmake.lua new file mode 100644 index 0000000..02d55f3 --- /dev/null +++ b/xmake.lua @@ -0,0 +1,10 @@ +add_rules("mode.debug", "mode.release") + +target("filecomplete") + set_kind("static") + add_files("src/filecomplete.cpp") + +target("example") + set_kind("binary") + add_deps("filecomplete") + add_files("src/main.cpp") \ No newline at end of file