Basic indentation support
This commit is contained in:
17
README.md
17
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
40
src/editor_indents.cc
Normal 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] == ')';
|
||||
}
|
||||
Reference in New Issue
Block a user