New input:get_line system
This commit is contained in:
parent
18f69eef08
commit
9a4d993b4b
129
src/input.cpp
129
src/input.cpp
@ -1,33 +1,134 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <iomanip> // for setfill
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <unistd.h> // for STDIN_FILENO
|
||||||
|
#include <termios.h> // for tc(get/set)attr
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
#include "include/config.h"
|
#include "include/config.h"
|
||||||
#include "include/colors.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();
|
void show_prompt(int line_number) {
|
||||||
while (1) {
|
cout << BOLD << setw(4) << setfill(' ') << line_number << " " RESET;
|
||||||
line_num++;
|
}
|
||||||
printf(BOLD "%4d " RESET , line_num);
|
|
||||||
if (!getline(cin, buffer)) {
|
|
||||||
cout << "\rReceived EOF" << endl;
|
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);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int n = buffer.length();
|
if (ch == 27) { // Special sequences
|
||||||
if (n >= 2 && buffer[n-1] == ';' && buffer[n-2] == ';') {
|
silent_get_char();
|
||||||
input.push_back(buffer);
|
ch = silent_get_char();
|
||||||
buffer[n-1] = '\0';
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
input.push_back(buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
|
Loading…
Reference in New Issue
Block a user