diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a35ec25 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +# The main all target +default_target: all +.PHONY : default_target + +all: + @cmake --build /home/tyrel/CLionProjects/editor/cmake-build-debug --target tted -- -j 6 + @mv cmake-build-debug/tted . + diff --git a/tted.c b/tted.c index 8a27e7b..ff1c32c 100644 --- a/tted.c +++ b/tted.c @@ -64,7 +64,7 @@ struct editorConfig E; /** prototypes */ void editorSetStatusMessage(const char *fmt, ...); void editorRefreshScreen(); -char *editorPrompt(char *prompt); +char *editorPrompt(char *prompt, void (*callback)(char *, int)); /** terminal */ void die(const char *s) { @@ -186,7 +186,7 @@ int getWindowSize(int *rows, int *cols) { } } -/** Row operations */ +/** row operations */ int editorRowCxToRx(erow *row, int cx) { int rx = 0; int j; @@ -198,6 +198,19 @@ int editorRowCxToRx(erow *row, int cx) { } return rx; } +int editorRowRxToCx(erow *row, int rx) { + int cur_rx = 0; + int cx; + for (cx = 0; cx < row->size; cx++) { + if(row->chars[cx] == '\t'){ + cur_rx += (TTED_TAB_STOP - 1) - (cur_rx % TTED_TAB_STOP); + } + cur_rx++; + + if (cur_rx > rx) return cx; + } + return cx; +} void editorUpdateRow(erow *row) { int tabs = 0; @@ -344,9 +357,31 @@ char *editorRowsToString(int *buflen) { return buf; } + +void editorOpen(char *filename) { + free(E.filename); + E.filename = strdup(filename); + FILE *fp = fopen(filename, "r"); + if (!fp) die("fopen"); + + char *line = NULL; + size_t linecap = 0; + ssize_t linelen; + while ((linelen = getline(&line, &linecap, fp)) != -1) { + while (linelen > 0 && (line[linelen - 1] == '\n' || + line[linelen - 1] == '\r')) + linelen--; + editorInsertRow(E.numrows, line, linelen); + } + free(line); + fclose(fp); + E.dirty = 0; + +} + void editorSave() { if (E.filename == NULL) { - E.filename = editorPrompt("Save as: %s (ESC to cancel)"); + E.filename = editorPrompt("Save as: %s (ESC to cancel)", NULL); if (E.filename == NULL) { editorSetStatusMessage("Save aborted"); return; @@ -371,29 +406,70 @@ void editorSave() { } free(buf); } +/** find */ + +void editorFindCallback(char *query, int key) { + static int last_match = -1; + static int direction = 1; + + if (key== '\r' || key == '\x1b') { + last_match = -1; + direction = 1; + return; + } else if (key == ARROW_RIGHT || key == ARROW_DOWN){ + direction = 1; + } else if (key == ARROW_LEFT || key == ARROW_UP){ + direction = -1; + } else { + last_match = -1; + direction = 0; + } -void editorOpen(char *filename) { - free(E.filename); - E.filename = strdup(filename); - FILE *fp = fopen(filename, "r"); - if (!fp) die("fopen"); + if (last_match == -1) direction = 1; + int current = last_match; - char *line = NULL; - size_t linecap = 0; - ssize_t linelen; - while ((linelen = getline(&line, &linecap, fp)) != -1) { - while (linelen > 0 && (line[linelen - 1] == '\n' || - line[linelen - 1] == '\r')) - linelen--; - editorInsertRow(E.numrows, line, linelen); + + int i; + for (i=0; i < E.numrows; i++){ + current += direction; + if (current == -1) { + current = E.numrows -1; + } else if (current == E.numrows){ + current = 0; } - free(line); - fclose(fp); - E.dirty = 0; + erow *row = &E.row[current]; + char *match = strstr(row->render, query); + if(match){ + last_match = current; + E.cy = current; + E.cx = editorRowCxToRx(row, match - row->render); + E.rowoff = E.numrows; + break; + } + } } +void editorFind() { + int saved_cx = E.cx; + int saved_cy = E.cy; + int saved_coloff = E.coloff; + int saved_rowoff = E.rowoff; + + char *query = editorPrompt("Find: %s (Use ESC/Arrows/Enter)", editorFindCallback); + + if(query){ + free(query); + } else { + E.cx=saved_cx; + E.cy=saved_cy; + E.coloff=saved_coloff; + E.rowoff=saved_rowoff; + } +} + + /** append buffer */ struct abuf { @@ -532,7 +608,7 @@ void editorSetStatusMessage(const char *fmt, ...) { /** input */ -char *editorPrompt(char *prompt){ +char *editorPrompt(char *prompt, void(*callback)(char *, int)){ size_t bufsize = 128; char *buf = malloc(bufsize); @@ -547,11 +623,13 @@ char *editorPrompt(char *prompt){ 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){ @@ -562,6 +640,8 @@ char *editorPrompt(char *prompt){ buf[buflen++] = c; buf[buflen] = '\0'; } + + if (callback) callback(buf, c); } } @@ -639,6 +719,10 @@ void editorProcessKeypress() { } break; + case CTRL_KEY('f'): + editorFind(); + break; + case BACKSPACE: case CTRL_KEY('h'): case DEL_KEY: @@ -704,7 +788,7 @@ int main(int argc, char *argv[]) { editorOpen(argv[1]); } - editorSetStatusMessage("HELP: Ctrl-Q = quit; Ctrl-S = save;"); + editorSetStatusMessage("HELP: Ctrl-Q = quit; Ctrl-S = save; Ctrl-f = find"); while (1) { editorRefreshScreen();