Basic indentation support

This commit is contained in:
2025-12-18 18:55:08 +00:00
parent f347f50dbe
commit d5145d88a7
4 changed files with 84 additions and 7 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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,

40
src/editor_indents.cc Normal file
View File

@@ -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] == ')';
}