#include "line/mode.h" #include #include #include #include #include "line/cursor.h" #include "line/getter.h" #include "history.h" using namespace std; namespace ov4 { void disable_raw() { raw_enabled = false; tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr); } void enable_raw() { if (raw_enabled) return; raw_enabled = true; termios attr_raw; tcgetattr(STDIN_FILENO, &attr); tcgetattr(STDIN_FILENO, &attr_raw); // LOCAL // disable // echo // canonical // signal // disable post-input processing, aka control-V attr_raw.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN); // INPUT // disable // software flow control, aka control-S/Q // \n and \r conversion attr_raw.c_iflag &= ~(IXON | ICRNL); // OUTPUT // disable // post-output processing attr_raw.c_oflag &= ~(OPOST); // misc attr_raw.c_iflag &= ~(BRKINT | INPCK | ISTRIP); attr_raw.c_cflag |= (CS8); atexit(disable_raw); // TCSAFLUSH // the change shall occur after all output written to fildes is transmitted // and all input so far received but not read shall be discarded before the change is made tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr_raw); } void clear_below() { print("\x1b[0J"); } string readline() { update_window_size(); history_vec.push_back(""); history_index = get_last_index(); reset_editor(); T_position pos = get_cursor_position(); prompt_pos = pos.col; char c; while (read(STDIN_FILENO, &c, 1) == 1) { if (iscntrl(c)) { //print("control: {}\r\n", static_cast(c)); //fflush(stdout); if (c == 0x0A || c == 0x0D) // \n OR \r { //print("line: {}\r\n", line_buffer); if (line_buffer.empty()) { history_index--; history_vec.pop_back(); } else { history_vec[get_last_index()] = line_buffer; } return line_buffer; } else if (c == 0x03) // control C { history_index--; history_vec.pop_back(); return ""; } // ESC sequence else if (c == '\x1b') { char seq[10]; // eat [ if (read(STDIN_FILENO, seq + 0, 1) != 1) continue; if (read(STDIN_FILENO, seq + 1, 1) != 1) continue; move_cursor(seq[1]); } } // normal char else { cursor_input_char(c); print_override(line_buffer); } } if (line_buffer.empty()) { history_index--; history_vec.pop_back(); } else { history_vec[get_last_index()] = line_buffer; } return line_buffer; } void editor_exit(int code) { disable_raw(); exit(code); } }