New input:get_line system
This commit is contained in:
parent
18f69eef08
commit
9a4d993b4b
127
src/input.cpp
127
src/input.cpp
@ -1,33 +1,134 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iomanip> // for setfill
|
||||
#include <iostream>
|
||||
#include <unistd.h> // for STDIN_FILENO
|
||||
#include <termios.h> // for tc(get/set)attr
|
||||
using namespace std;
|
||||
|
||||
#include "include/config.h"
|
||||
#include "include/colors.h"
|
||||
|
||||
|
||||
char silent_get_char() { // Get char without echoing it
|
||||
struct termios oldt, newt;
|
||||
char ch;
|
||||
tcgetattr(STDIN_FILENO, &oldt);
|
||||
newt = oldt;
|
||||
newt.c_lflag &= ~(ICANON | ECHO);
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &newt);
|
||||
ch = getchar();
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
|
||||
return ch;
|
||||
}
|
||||
|
||||
vector<string> get_input(vector<string> input) {
|
||||
string buffer;
|
||||
|
||||
int line_num = input.size();
|
||||
while (1) {
|
||||
line_num++;
|
||||
printf(BOLD "%4d " RESET , line_num);
|
||||
if (!getline(cin, buffer)) {
|
||||
cout << "\rReceived EOF" << endl;
|
||||
void show_prompt(int line_number) {
|
||||
cout << BOLD << setw(4) << setfill(' ') << line_number << " " RESET;
|
||||
}
|
||||
|
||||
|
||||
string get_line_with_hist(vector<string> history, int line_num) {
|
||||
show_prompt(line_num);
|
||||
|
||||
string input;
|
||||
int history_index = history.size();
|
||||
int input_index = 0;
|
||||
char ch = 0;
|
||||
|
||||
while (ch != '\n') {
|
||||
ch = silent_get_char();
|
||||
|
||||
if (ch == 4 || ch == EOF) { // 4 is End Of Transmission which can also be received
|
||||
cout << "\rReceived EOF\033[K" << endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int n = buffer.length();
|
||||
if (n >= 2 && buffer[n-1] == ';' && buffer[n-2] == ';') {
|
||||
input.push_back(buffer);
|
||||
buffer[n-1] = '\0';
|
||||
if (ch == 27) { // Special sequences
|
||||
silent_get_char();
|
||||
ch = silent_get_char();
|
||||
|
||||
switch (ch) {
|
||||
case 'A': { //* Up arrow
|
||||
if (history_index > 0) {
|
||||
history_index--;
|
||||
cout << "\r\033[K"; // Clear the end of the line
|
||||
show_prompt(line_num);
|
||||
|
||||
cout << history[history_index];
|
||||
input = history[history_index];
|
||||
input_index = input.size();
|
||||
}
|
||||
break;
|
||||
} case 'B': { //* Down arrow
|
||||
if (history_index < (int)history.size() - 1) {
|
||||
history_index++;
|
||||
cout << "\r\033[K"; // Clear the end of the line
|
||||
show_prompt(line_num);
|
||||
|
||||
cout << history[history_index];
|
||||
input = history[history_index];
|
||||
input_index = input.size();
|
||||
}
|
||||
break;
|
||||
} case 'D': { //* Left arrow
|
||||
if (input_index > 0) {
|
||||
input_index--;
|
||||
cout << "\033[1D"; // Go left 1
|
||||
}
|
||||
break;
|
||||
} case 'C': { //* Right arrow
|
||||
if (input_index < (int)input.size()) {
|
||||
input_index++;
|
||||
cout << "\033[1C"; // Go right 1
|
||||
}
|
||||
break;
|
||||
} case '3': { //* Suppr
|
||||
silent_get_char(); // Remove last printed char
|
||||
if (input_index < (int)input.length()) {
|
||||
input.erase(input_index, 1);
|
||||
cout << "\033[K" << input.substr(input_index);
|
||||
|
||||
if (input_index < (int)input.size())
|
||||
cout << "\033[" << input.size() - input_index << "D";
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (ch == '\b' || ch == 127) { //* Backspace
|
||||
if (input_index > 0) {
|
||||
input.erase(input_index-1, 1);
|
||||
input_index--;
|
||||
|
||||
cout << "\033[1D\033[K"; // Go left 1, clear the end of the line
|
||||
cout << input.substr(input_index); // Print the input after the deleted character
|
||||
if (input_index < (int)input.size())
|
||||
cout << "\033[" << input.size() - input_index << "D"; // Place the cursor back in the right position
|
||||
}
|
||||
} else if (ch != '\n') {
|
||||
input.insert(input_index, 1, ch);
|
||||
cout << input.substr(input_index);
|
||||
input_index++;
|
||||
if (input_index < (int)input.size())
|
||||
cout << "\033[" << input.size() - input_index << "D"; // Place the cursor back in the right position
|
||||
}
|
||||
}
|
||||
cout << endl;
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
input.push_back(buffer);
|
||||
|
||||
vector<string> get_input(vector<string> input) {
|
||||
int line_num = input.size();
|
||||
while (1) {
|
||||
line_num++;
|
||||
input.push_back(get_line_with_hist(input, line_num));
|
||||
|
||||
int n = input.back().length();
|
||||
if (n >= 2 && input.back()[n-1] == ';' && input.back()[n-2] == ';') {
|
||||
input.back().erase(n-1, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return input;
|
||||
|
Loading…
Reference in New Issue
Block a user