diff --git a/README.md b/README.md index 4c5a8f3..fbedd40 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,6 @@ A TUI IDE. # TODO -- [ ] Add feature where doing enter uses tree-sitter to add newline with indentation. - - it should also put stuff like `}` on the next line. -- [ ] Add the highlight of block edges when cursor is on a bracket (or in). -- [ ] Add this thing where selection double click on a bracket selects whole block. - - (only on the first time) and sets mode to `WORD`. - [ ] Add support for virtual cursor where edits apply at all the places. - [ ] Add alt + click to set multiple cursors. - [ ] Add search / replace along with search / virtual cursors are searched pos. @@ -23,4 +18,16 @@ A TUI IDE. - [ ] Add git stuff. - [ ] Fix bug where alt+up at eof adds extra line. - [ ] Think about how i would keep fold states sensical if i added code prettying. + +- [ ] Retry get proper blocks from tree-sitter. + - And use it for full block selection (including inline ones). + - And for indenting. + - And highlighting block edges etc. +- [ ] Add feature where doing enter uses tree-sitter to add newline with indentation. + - it should also put stuff like `}` on the next line. +- [ ] Add the highlight of block edges when cursor is on a bracket (or in). +- [ ] Add this thing where selection double click on a bracket selects whole block. + - (only on the first time) and sets mode to `WORD`. - [ ] Redo folding system and its relation to move_line_* functions. +- [ ] Also try regex based indentation. +- [ ] And indentation based blocks diff --git a/include/editor.h b/include/editor.h index 85cc349..77277b4 100644 --- a/include/editor.h +++ b/include/editor.h @@ -18,6 +18,8 @@ #define EXTRA_META 4 +#define INDENT_WIDTH 2 + struct Highlight { uint32_t fg; uint32_t bg; @@ -208,5 +210,8 @@ bool remove_fold(Editor *editor, uint32_t line); void apply_line_insertion(Editor *editor, uint32_t line, uint32_t rows); void apply_line_deletion(Editor *editor, uint32_t removal_start, uint32_t removal_end); +uint32_t leading_indent(const char *line, uint32_t len); +uint32_t get_indent(Editor *editor, Coord cursor); +bool closing_after_cursor(const char *line, uint32_t len, uint32_t col); #endif diff --git a/src/editor_events.cc b/src/editor_events.cc index 2cf3c7e..abf6f3e 100644 --- a/src/editor_events.cc +++ b/src/editor_events.cc @@ -302,8 +302,33 @@ void handle_editor_event(Editor *editor, KeyEvent event) { edit_insert(editor, editor->cursor, (char *)" ", 2); cursor_right(editor, 2); } else if (event.c[0] == '\n' || event.c[0] == '\r') { - edit_insert(editor, editor->cursor, (char *)"\n", 1); - cursor_right(editor, 1); + uint32_t line_len = 0; + LineIterator *it = begin_l_iter(editor->root, editor->cursor.row); + char *line = next_line(it, &line_len); + free(it); + bool closing = false; + if (line && line_len > 0 && line[line_len - 1] == '\n') + line_len--; + uint32_t indent = get_indent(editor, editor->cursor); + if (line) { + if (indent == 0) + indent = leading_indent(line, line_len); + closing = closing_after_cursor(line, line_len, editor->cursor.col); + free(line); + } + uint32_t closing_indent = + indent >= INDENT_WIDTH ? indent - INDENT_WIDTH : 0; + std::string insert_text("\n"); + insert_text.append(indent, ' '); + Coord new_cursor = {editor->cursor.row + 1, indent}; + if (closing) { + insert_text.push_back('\n'); + insert_text.append(closing_indent, ' '); + } + edit_insert(editor, editor->cursor, insert_text.data(), + insert_text.size()); + editor->cursor = new_cursor; + editor->cursor_preffered = UINT32_MAX; } else if (event.c[0] == CTRL('W')) { uint32_t prev_col_byte, prev_col_cluster; word_boundaries(editor, editor->cursor, &prev_col_byte, nullptr, diff --git a/src/editor_indents.cc b/src/editor_indents.cc new file mode 100644 index 0000000..a03acc2 --- /dev/null +++ b/src/editor_indents.cc @@ -0,0 +1,40 @@ +#include "../include/editor.h" + +uint32_t leading_indent(const char *line, uint32_t len) { + uint32_t indent = 0; + for (uint32_t i = 0; i < len; i++) { + if (line[i] == ' ') + indent++; + else if (line[i] == '\t') + indent += INDENT_WIDTH; + else + break; + } + return indent; +} + +uint32_t get_indent(Editor *editor, Coord cursor) { + if (!editor) + return 0; + LineIterator *it = begin_l_iter(editor->root, cursor.row); + uint32_t line_len; + char *line; + while ((line = prev_line(it, &line_len)) != nullptr) { + if (line_len == 0) + continue; + uint32_t indent = leading_indent(line, line_len); + free(line); + free(it); + return indent; + } + return 0; +} + +bool closing_after_cursor(const char *line, uint32_t len, uint32_t col) { + uint32_t i = col; + while (i < len && (line[i] == ' ' || line[i] == '\t')) + i++; + if (i >= len) + return false; + return line[i] == '}' || line[i] == ']' || line[i] == ')'; +}