#include "../include/input.h" #include "../include/editor_op.h" #include "../include/output.h" #include "../include/define.h" #include #include #include #include #include #include extern struct editorConfig E; /** * \fn char * editorPrompt(struct editorConfig *E, char *prompt) * \brief Return user input in a prompt when enter is hit. */ char *editorPrompt(char *prompt) { size_t buf_size = 128; char *buf = malloc(buf_size); size_t buf_len = 0; int c = 0; buf[0] = '\0'; while (1) { editorSetStatusMessage(prompt, buf); editorRefreshScreen(); c = editorReadKey(); if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) { if (buf_len != 0) { buf[--buf_len] = '\0'; } } else if (c == ESCAPE) { editorSetStatusMessage(""); free(buf); return NULL; } else if (c == '\r') { if (buf_len != 0) { editorSetStatusMessage(""); return buf; } } else if (!iscntrl(c) && c < 128) { if (buf_len == buf_size - 1) { buf_size *= 2; buf = realloc(buf, buf_size); } buf[buf_len++] = c; buf[buf_len] = '\0'; } } } char *key_to_string(int key) { static char key_str[32]; char tmp[10]; sprintf(tmp, "%d", key); // First test enter key if (key == '\r') { strcpy(key_str, "ENTER"); } else if (key >= 1 && key <= 26) { // CTRL keys snprintf(key_str, sizeof(key_str), "CTRL-%c", 'a' + key - 1); } else { switch (key) { case ARROW_UP: strcpy(key_str, "ARROW-UP"); break; case ARROW_DOWN: strcpy(key_str, "ARROW-DOWN"); break; case ARROW_LEFT: strcpy(key_str, "ARROW-LEFT"); break; case ARROW_RIGHT: strcpy(key_str, "ARROW-RIGHT"); break; case PAGE_UP: strcpy(key_str, "PAGE-UP"); fprintf(stderr, "pagr up\n"); break; case PAGE_DOWN: strcpy(key_str, "PAGE-DOWN"); break; case DEL_KEY: fprintf(stderr, "delete key\n"); strcpy(key_str, "DEL"); break; case BACKSPACE: strcpy(key_str, "BACKSPACE"); break; case '\r': strcpy(key_str, "ENTER"); break; case '\x1b': strcpy(key_str, "ESCAPE"); break; case BEG_LINE: strcpy(key_str, "HOME"); break; case END_LINE: strcpy(key_str, "END"); break; default: // For regular characters if (isprint(key)) { snprintf(key_str, sizeof(key_str), "%c", key); } else { snprintf(key_str, sizeof(key_str), "KEY-%d", key); } } } return key_str; } void editorMoveCursor(int key) { erow *row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y]; int row_len; switch (key) { case ARROW_RIGHT: if (row && E.cursor_x < row->size) { ++E.cursor_x; } else if (row && E.cursor_x == row->size) { E.cursor_y++; E.cursor_x = 0; } break; case ARROW_DOWN: if (E.cursor_y < E.numrows) { ++E.cursor_y; } break; case ARROW_UP: if (E.cursor_y != 0) { --E.cursor_y; } break; case ARROW_LEFT: if (E.cursor_x != 0) { --E.cursor_x; } else if (E.cursor_y > 0) { --E.cursor_y; E.cursor_x = E.row[E.cursor_y].size; } break; } row = (E.cursor_y >= E.numrows) ? NULL : &E.row[E.cursor_y]; row_len = row ? row->size : 0; if (E.cursor_x > row_len) { E.cursor_x = row_len; } } int executeKeyBind(char *key_sequence) { int i; for (i = 0; i < E.number_of_keybinds; ++i) { if (!strcmp(key_sequence, E.key_binds[i].key_sequence)) { fprintf(stderr, "lisp function %s\n", key_sequence); // It's a symbol, create a function call lisp_eval(lisp_cons(E.key_binds[i].command, lisp_null(), E.ctx), &E.ctx_error, E.ctx); return 1; } } return 0; } void editorProcessKeypress() { int c = editorReadKey(); if (executeKeyBind(key_to_string(c))) { return; } editorInsertChar(c); E.quit_times_buffer = E.constantes.QUIT_TIMES; }