diff --git a/config/init.lisp b/config/init.lisp index 8946093..4e99e61 100644 --- a/config/init.lisp +++ b/config/init.lisp @@ -48,8 +48,8 @@ )) )) -(define enter-and-tab - (lambda () +(define enter-and-tab + (lambda () (editor-insert-new-line) (let ((is-in (move-cursor "up"))) (do ((ch (editor-read-char) (editor-read-char))) @@ -86,4 +86,3 @@ (map-key "\"" editor-split-screen-vertical "user") (map-key "o" editor-switch-next-pane "user") (map-key "*" editor-unify-panes "user") - diff --git a/include/define.h b/include/define.h index 35cf467..0a931c0 100644 --- a/include/define.h +++ b/include/define.h @@ -10,7 +10,7 @@ #define ERASE_END_LINE "\x1b[K" #define TAB "\x9" #define SPACE "\x20" -#define APP_DEBUG +// #define APP_DEBUG enum editorKey_e { BACKSPACE = 127, diff --git a/src/file_io.c b/src/file_io.c index 8874422..480a320 100644 --- a/src/file_io.c +++ b/src/file_io.c @@ -116,13 +116,13 @@ void editorSave() { len = strlen(buffer->row[i].chars); if (write(fd, buffer->row[i].chars, len) != len) { close(fd); - E.dirty = 0; editorSetStatusMessage("Can't save! I/O error: %s", strerror(errno)); return; } write(fd, "\n", 1); } + buffer->dirty = 0; close(fd); } editorSetStatusMessage("File saved"); diff --git a/src/output.c b/src/output.c index d8eab6e..35c323a 100644 --- a/src/output.c +++ b/src/output.c @@ -77,7 +77,7 @@ static void editorDrawPane(struct abuf* ab, EditorPane* pane) { start_offset = pane->x_offset; - if (buf->filename[strlen(buf->filename) - 1] == 'c') + if (buf->filename[strlen(buf->filename) - 1] == 'c' || buf->filename[strlen(buf->filename) - 1] == 'h') { // Render line with syntax highlighting, constrain to pane width highlighted = highlight_line( diff --git a/src/syntax_highlighter.c b/src/syntax_highlighter.c index 0c32f53..ad0226c 100644 --- a/src/syntax_highlighter.c +++ b/src/syntax_highlighter.c @@ -9,7 +9,7 @@ extern struct editorConfig E; const char *c_keywords[] = { "if", "else", "while", "for", "do", "switch", - "case", "break", "#include", "#define", "continue", "return", + "case", "break", "#include", "#define", "#if", "#endif", "#ifndef", "continue", "return", "goto", "struct", "union", "enum", "typedef", "static", "extern", "const", "volatile", "sizeof", "auto", "register", "inline", "restrict", NULL}; diff --git a/src/terminal.c b/src/terminal.c index 1e6ccc6..ab29e2b 100644 --- a/src/terminal.c +++ b/src/terminal.c @@ -7,8 +7,8 @@ #include #include -#include #include +#include #include "include/utf8.h" @@ -44,28 +44,52 @@ void enableRawMode() { } } -#include /* isprint */ +#include /* isprint */ char *key_to_string(int key) { static char key_str[32]; if (key == '\r') { strcpy(key_str, "ENTER"); + } else if (key == 0x09) { + strcpy(key_str, "TAB"); } else if (key >= 1 && key <= 26) { 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"); break; - case PAGE_DOWN: strcpy(key_str, "PAGE-DOWN"); break; - case DEL_KEY: strcpy(key_str, "DEL"); break; - case BACKSPACE: strcpy(key_str, "BACKSPACE"); break; - case BEG_LINE: strcpy(key_str, "HOME"); break; - case END_LINE: strcpy(key_str, "END"); break; - case '\x1b': strcpy(key_str, "ESCAPE"); break; + 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"); + break; + case PAGE_DOWN: + strcpy(key_str, "PAGE-DOWN"); + break; + case DEL_KEY: + strcpy(key_str, "DEL"); + break; + case BACKSPACE: + strcpy(key_str, "BACKSPACE"); + break; + case BEG_LINE: + strcpy(key_str, "HOME"); + break; + case END_LINE: + strcpy(key_str, "END"); + break; + case '\x1b': + strcpy(key_str, "ESCAPE"); + break; default: if (key > 127) { /* UTF-8 code point — re-encode into the buffer */ @@ -84,58 +108,76 @@ char *key_to_string(int key) { int editorReadKey() { char c; - /* read first byte — may be start of UTF-8 or escape */ - while (read(STDIN_FILENO, &c, 1) != 1); - appDebug("f : %X\r\n", c); + /* read first byte — may be start of UTF-8 or escape */ + while (read(STDIN_FILENO, &c, 1) != 1) + ; + appDebug("f : %X\r\n", c); - if (c == '\x1b') { - char seq[6]; - /* try to read escape sequence */ - if (read(STDIN_FILENO, &seq[0], 1) != 1) return '\x1b'; - if (read(STDIN_FILENO, &seq[1], 1) != 1) return '\x1b'; - if (seq[0] == '[') { - if (seq[1] >= '0' && seq[1] <= '9') { - if (read(STDIN_FILENO, &seq[2], 1) != 1) return '\x1b'; - if (seq[2] == '~') { - switch (seq[1]) { - case '1': return BEG_LINE; - case '3': return DEL_KEY; - case '4': return END_LINE; - case '5': return PAGE_UP; - case '6': return PAGE_DOWN; - case '7': return BEG_LINE; - case '8': return END_LINE; - } - } - } else { - switch (seq[1]) { - case 'A': return ARROW_UP; - case 'B': return ARROW_DOWN; - case 'C': return ARROW_RIGHT; - case 'D': return ARROW_LEFT; - case 'H': return BEG_LINE; - case 'F': return END_LINE; - } - } + if (c == '\x1b') { + char seq[6]; + /* try to read escape sequence */ + if (read(STDIN_FILENO, &seq[0], 1) != 1) + return '\x1b'; + if (read(STDIN_FILENO, &seq[1], 1) != 1) + return '\x1b'; + if (seq[0] == '[') { + if (seq[1] >= '0' && seq[1] <= '9') { + if (read(STDIN_FILENO, &seq[2], 1) != 1) + return '\x1b'; + if (seq[2] == '~') { + switch (seq[1]) { + case '1': + return BEG_LINE; + case '3': + return DEL_KEY; + case '4': + return END_LINE; + case '5': + return PAGE_UP; + case '6': + return PAGE_DOWN; + case '7': + return BEG_LINE; + case '8': + return END_LINE; + } } - return '\x1b'; + } else { + switch (seq[1]) { + case 'A': + return ARROW_UP; + case 'B': + return ARROW_DOWN; + case 'C': + return ARROW_RIGHT; + case 'D': + return ARROW_LEFT; + case 'H': + return BEG_LINE; + case 'F': + return END_LINE; + } + } } + return '\x1b'; + } - /* multi-byte UTF-8: read remaining bytes */ - int seqlen = utf8Seqlen((unsigned char)c); - if (seqlen > 1) { - /* pack into a pseudo-codepoint just to pass bytes through; - we handle encoding/decoding at the row level */ - char buf[4] = {c, 0, 0, 0}; - for (int i = 1; i < seqlen; i++) - if (read(STDIN_FILENO, &buf[i], 1) != 1) break; - /* decode and return as uint32, but we need int — use high range */ - const char *p = buf; - uint32_t cp = utf8Decode(&p); - return (int)cp; /* caller re-encodes when inserting */ - } + /* multi-byte UTF-8: read remaining bytes */ + int seqlen = utf8Seqlen((unsigned char)c); + if (seqlen > 1) { + /* pack into a pseudo-codepoint just to pass bytes through; + we handle encoding/decoding at the row level */ + char buf[4] = {c, 0, 0, 0}; + for (int i = 1; i < seqlen; i++) + if (read(STDIN_FILENO, &buf[i], 1) != 1) + break; + /* decode and return as uint32, but we need int — use high range */ + const char *p = buf; + uint32_t cp = utf8Decode(&p); + return (int)cp; /* caller re-encodes when inserting */ + } - return (unsigned char)c; + return (unsigned char)c; } int getCursorPosition(int *rows, int *cols) { @@ -183,12 +225,12 @@ int getWindowSize(int *rows, int *cols) { } void appDebug(const char *fmt, ...) { - #ifdef APP_DEBUG - va_list ap; - char message[256]; - va_start(ap, fmt); - vsnprintf(message, 256, fmt, ap); - va_end(ap); - fprintf(stderr, "%s\n", message); - #endif +#ifdef APP_DEBUG + va_list ap; + char message[256]; + va_start(ap, fmt); + vsnprintf(message, 256, fmt, ap); + va_end(ap); + fprintf(stderr, "%s\n", message); +#endif }