fuNote/input.c

185 lines
4.0 KiB
C

#include <ctype.h> // for iscntrl
#include <stdio.h> // for NULL
#include <stdlib.h> // for free
#include <unistd.h> // for STDOUT_FILENO
#include "input.h"
#include "file.h" // for editorSave
#include "fn.h" // for E, editorConfig, erow, CTRL_KEY, editorKey::AR...
#include "output.h" // for editorSetStatusMessage, editorDelChar, editorI...
#include "search.h" // for editorSearch
#include "terminal.h" // for editorReadKey
char *editorPrompt(char *prompt, void (*callback)(char *, int)) {
size_t bufsize = 128;
char *buf = malloc(bufsize);
size_t buflen = 0;
buf[0] = '\0';
while (1) {
editorSetStatusMessage(prompt, buf);
editorRefreshScreen();
int c = editorReadKey();
if (c == DEL_KEY || c == CTRL_KEY('h') || c == BACKSPACE) {
if (buflen != 0) buf[--buflen] = '\0';
} else if (c == '\x1b') {
editorSetStatusMessage("");
if (callback) callback(buf, c);
free(buf);
return NULL;
} else if (c == '\r') {
if (buflen != 0) {
editorSetStatusMessage("");
if (callback) callback(buf, c);
return buf;
}
} else if (!iscntrl(c) && c < 128) {
if (buflen == bufsize -1) {
bufsize *= 2;
buf = realloc(buf, bufsize);
}
buf[buflen++] = c;
buf[buflen] = '\0';
}
if (callback) callback(buf, c);
}
}
void editorMoveCursor(int key) {
erow *row = (E.cy >= E.numrows) ? NULL : &E.row[E.cy];
switch (key) {
case ARROW_LEFT:
if (E.cx != 0) {
E.cx--;
} else if (E.cy > 0) {
E.cy--;
E.cx = E.row[E.cy].size;
}
break;
case ARROW_RIGHT:
if (row && E.cx < row->size) {
E.cx++;
} else if (row && E.cx == row->size) {
E.cy++;
E.cx = 0;
}
break;
case ARROW_UP:
if (E.cy != 0) {
E.cy--;
}
break;
case ARROW_DOWN:
if (E.cy < E.numrows) {
E.cy++;
}
break;
}
row = (E.cy >= E.numrows) ? NULL : &E.row[E.cy];
int rowlen = row ? row->size : 0;
if (E.cx > rowlen) {
E.cx = rowlen;
}
}
void editorProcessKeypress() {
static int wantToQuit = 0;
int c = editorReadKey(); // Blocking!
switch (c) {
case '\r': // ENTER
if (wantToQuit == 0) {
editorInsertNewLine();
} else {
editorSetStatusMessage("");
}
break;
case CTRL_KEY('c'):
if (E.dirty) {
editorSetStatusMessage("WARNING: Unsaved changes. Exit anyway? [y/N]");
wantToQuit = 1;
return;
}
exitEditor();
break;
// Special cases if the user want to quit
// TODO: Make a "question mode" with a callback for y and n
case 'y':
if (wantToQuit == 0) {
editorInsertChar(c);
} else {
exitEditor();
}
break;
case CTRL_KEY('s'):
editorSave();
break;
case HOME_KEY:
E.cx = 0;
break;
case END_KEY:
if (E.cy < E.numrows) {
E.cx = E.row[E.cy].size;
}
break;
case CTRL_KEY('f'):
editorSearch();
break;
case BACKSPACE:
case CTRL_KEY('h'):
case DEL_KEY:
if (c == DEL_KEY) editorMoveCursor(ARROW_RIGHT);
editorDelChar();
break;
case PAGE_UP:
case PAGE_DOWN:
{
if (c == PAGE_UP) {
E.cy = E.rowoff;
} else if (c == PAGE_DOWN) {
E.cy = E.rowoff + E.screenrows - 1;
if (E.cy > E.numrows) E.cy = E.numrows;
}
int times = E.screenrows;
while(times--)
editorMoveCursor(c == PAGE_UP ? ARROW_UP : ARROW_DOWN);
}
break;
case ARROW_UP:
case ARROW_DOWN:
case ARROW_LEFT:
case ARROW_RIGHT:
editorMoveCursor(c);
break;
case CTRL_KEY('l'):
case '\x1b': // ESC
break;
default:
if (wantToQuit == 1) {
wantToQuit = 0;
editorSetStatusMessage("");
} else {
editorInsertChar(c);
}
break;
}
wantToQuit = 0;
}