#include #include #include #include int rows, cols; typedef struct commandLine { int* string; int length; int position; } commandLine; void clearInput() { for (int i = 0; i < cols; i ++) mvprintw(rows - 1, i, " "); } void printPrompt(commandLine cmdLine, int len) { mvprintw(rows - 1, 0, ">"); for (int i = 0; i < len; i ++) mvprintw(rows - 1, i + 1, "%c", cmdLine.string[i]); attron(A_BLINK); mvprintw(rows - 1, cmdLine.position + 1, ""); attroff(A_BLINK); } void clearScreen() { for (int i = 0; i < rows; i ++) for (int j = 0; j < cols; j ++) mvprintw(i, j, " "); } void printContent(commandLine *content) { for (int i = 0; i < rows - 2; i ++) for (int j = 0; j < cols; j ++) mvprintw(rows - 2 - i, j, "%c", content[i].string[j]); } void insertInStartString(commandLine *cmdLine, int* toInsert ) { for (int i = rows - 2; i > 0 ; i --) for (int j = 0; j < cols; j ++) cmdLine[i].string[j] = cmdLine[i - 1].string[j]; for (int i = 0; i < cols; i ++) cmdLine[0].string[i] = toInsert[i]; } void copyCommandLine(commandLine* destination, commandLine source) { for (int i = 0; i < source.length; i ++) destination->string[i] = source.string[i]; destination->position = source.position; destination->length = source.length; } void insertInStartCommandLine(commandLine *cmdLine, commandLine toInsert, int arrayLength) { for (int i = arrayLength - 1; i > 0 ; i --) { copyCommandLine(&(cmdLine[i]), cmdLine[i - 1]); } copyCommandLine(&(cmdLine[0]), toInsert); } void insert(int *cmd_string, int toInsert , int position, int len) { for (int i = len + 1; i > position; i --) cmd_string[i] = cmd_string[i - 1]; cmd_string[position] = toInsert; } void pop(commandLine* cmdLine) { if (cmdLine->position < 1) return; for (int i = cmdLine->position; i < cmdLine->length; i ++) cmdLine->string[i] = cmdLine->string[i + 1]; cmdLine->string[(cmdLine->length) - 1] = 0; cmdLine->length --; cmdLine->position --; } void resetBuffer (commandLine *buffer) { memset(buffer->string, 0, sizeof(int) * cols); buffer->length = 0; buffer->position = 0; } int main (int argc, char* argv[]) { initscr(); keypad(stdscr, TRUE); noecho(); start_color(); keypad(stdscr, true); getmaxyx(stdscr, rows, cols); int ch = ' '; int historySize = 150; int historyPosition = 0; commandLine *content; commandLine *history; commandLine buffer; content = malloc(rows * sizeof (commandLine)); history = malloc(historySize * sizeof (commandLine)); for (int i = 0; i < rows; i ++) content[i].string = malloc(cols * sizeof(int)); for (int i = 0; i < historySize; i ++) history[i].string = malloc(cols * sizeof(int)); buffer.string = malloc(cols * sizeof(int)); for (int i = 0; i < rows; i ++) for (int j = 0; j < cols; j ++) content[i].string[j] = 0; for (int i = 0; i < historySize; i ++) for (int j = 0; j < cols; j ++) history[i].string[j] = 0; printPrompt(buffer, buffer.length); while (1){ ch = getch(); switch (ch) { case 10: { insertInStartString(content, buffer.string); insertInStartCommandLine(history, buffer, historySize); historyPosition = 0; resetBuffer(&buffer); break; } case KEY_LEFT: if (historyPosition > 0) buffer.position -= buffer.position > 0? 1 : 0; else buffer.position -= buffer.position > 0? 1 : 0; break; case KEY_RIGHT: if (historyPosition > 0) buffer.position += buffer.position < buffer.length? 1 : 0; else buffer.position += buffer.position > 0? 1 : 0; break; case KEY_UP: historyPosition += historyPosition < historySize? 1 : 0; resetBuffer(&buffer); if (historyPosition > 0) copyCommandLine(&buffer, history[historyPosition - 1]); break; case KEY_DOWN: historyPosition -= historyPosition > 0? 1 : 0; resetBuffer(&buffer); if (historyPosition > 0) copyCommandLine(&buffer, history[historyPosition - 1]); break; case KEY_BACKSPACE: pop(&buffer); break; case KEY_F(1): endwin(); for (int i = 0; i < 10; i ++) { printf("%i (%i symbols): ", i, history[i].length); for (int j = 0; j < history[i].length; j ++) printf("%c", history[i].string[j]); printf("\n"); } break; default: insert(buffer.string, ch, buffer.position, buffer.length); buffer.position ++; buffer.length ++; break; } clearScreen(); clearInput(); printContent(content); printPrompt(buffer, buffer.length); mvprintw(0, 0, "%i", historyPosition); refresh(); } endwin(); return 0; }