Created
June 8, 2026 16:10
-
-
Save HalanoSiblee/3848ede42725c2ea347de356853e78f4 to your computer and use it in GitHub Desktop.
Tab file auto-comp Exa
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //g++ -std=c++17 main.cpp -o editor -lncurses | |
| #include <iostream> | |
| #include <string> | |
| #include <vector> | |
| #include <filesystem> | |
| #include <ncurses.h> | |
| namespace fs = std::filesystem; | |
| struct CompletionState { | |
| bool is_active = false; | |
| std::vector<std::string> matches; | |
| size_t current_idx = 0; | |
| size_t trigger_start_pos = 0; | |
| }; | |
| // Scans directory for files starting with the specified prefix | |
| void gatherMatches(const std::string& current_word, CompletionState& state) { | |
| state.matches.clear(); | |
| state.current_idx = 0; | |
| size_t last_slash = current_word.find_last_of('/'); | |
| if (last_slash == std::string::npos) return; | |
| // Split into directory and file prefix | |
| // If last_slash is 0, the directory is just "/" (absolute root) | |
| std::string dir_part = (last_slash == 0) ? "/" : current_word.substr(0, last_slash + 1); | |
| std::string file_prefix = current_word.substr(last_slash + 1); | |
| try { | |
| fs::path search_path(dir_part); | |
| if (!fs::exists(search_path) || !fs::is_directory(search_path)) return; | |
| for (const auto& entry : fs::directory_iterator(search_path)) { | |
| std::string name = entry.path().filename().string(); | |
| if (name.rfind(file_prefix, 0) == 0) { | |
| // Construct the full match string cleanly | |
| std::string full_match = dir_part; | |
| if (dir_part.back() != '/') { | |
| full_match += "/"; | |
| } | |
| full_match += name; | |
| if (entry.is_directory()) { | |
| full_match += "/"; | |
| } | |
| state.matches.push_back(full_match); | |
| } | |
| } | |
| } catch (...) { | |
| // Suppress permission denied errors for certain system root directories | |
| } | |
| } | |
| int main() { | |
| // Initialize ncurses | |
| initscr(); | |
| raw(); | |
| keypad(stdscr, TRUE); | |
| noecho(); | |
| std::string buffer = ""; | |
| CompletionState comp; | |
| printw("=== Ncurses Autocomplete Editor Simulation ===\n"); | |
| printw("Instructions: Start typing. Supports './', '../', and absolute '/' paths.\n"); | |
| printw("Press TAB to cycle options. Press ESC to exit.\n"); | |
| printw("----------------------------------------------------------------------\n\n"); | |
| int start_y, start_x; | |
| getyx(stdscr, start_y, start_x); | |
| while (true) { | |
| move(start_y, start_x); | |
| clrtoeol(); | |
| printw("%s", buffer.c_str()); | |
| refresh(); | |
| int ch = getch(); | |
| if (ch == 27) { // ESC Key | |
| break; | |
| } | |
| else if (ch == '\t') { // TAB Key | |
| if (!comp.is_active) { | |
| size_t space_idx = buffer.find_last_of(" \"'"); | |
| size_t word_start = (space_idx == std::string::npos) ? 0 : space_idx + 1; | |
| std::string current_word = buffer.substr(word_start); | |
| // FIXED TRIGGER: Check for ./ , ../ , OR absolute paths starting with / | |
| if (current_word.rfind("./", 0) == 0 || | |
| current_word.rfind("../", 0) == 0 || | |
| (current_word.rfind("/", 0) == 0)) { | |
| comp.trigger_start_pos = word_start; | |
| gatherMatches(current_word, comp); | |
| if (!comp.matches.empty()) { | |
| comp.is_active = true; | |
| } | |
| } | |
| } | |
| if (comp.is_active && !comp.matches.empty()) { | |
| buffer.erase(comp.trigger_start_pos); | |
| buffer += comp.matches[comp.current_idx]; | |
| comp.current_idx = (comp.current_idx + 1) % comp.matches.size(); | |
| } | |
| } | |
| else if (ch == KEY_BACKSPACE || ch == 127 || ch == 8) { | |
| if (!buffer.empty()) { | |
| buffer.pop_back(); | |
| } | |
| comp.is_active = false; | |
| } | |
| else { | |
| buffer.push_back(static_cast<char>(ch)); | |
| comp.is_active = false; | |
| } | |
| } | |
| endwin(); | |
| return 0; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment