summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2023-01-02 19:22:27 -0500
committerpommicket <pommicket@gmail.com>2023-01-02 19:22:27 -0500
commit29824f8bef3dde9b091185be295de3ae07ee17fd (patch)
tree189661946119fd960cb9fd04e13fa335dfcbeb5a
parentc04562a24e7fbee0839d00a8bfd5253426a98f20 (diff)
:up-blank-line, etc.
-rw-r--r--.gitignore1
-rw-r--r--buffer.c104
-rw-r--r--command.c20
-rw-r--r--command.h4
-rw-r--r--main.c2
-rw-r--r--ted.cfg8
-rw-r--r--ted.h9
7 files changed, 138 insertions, 10 deletions
diff --git a/.gitignore b/.gitignore
index bd51247..b3123f1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,6 +3,7 @@ ted
!windows_installer/ted/ted
Debug
Release
+scratch
obj
*~
*.swp
diff --git a/buffer.c b/buffer.c
index 34fc9a2..2dd67f4 100644
--- a/buffer.c
+++ b/buffer.c
@@ -1036,7 +1036,7 @@ void buffer_center_cursor(TextBuffer *buffer) {
// move left (if `by` is negative) or right (if `by` is positive) by the specified amount.
// returns the signed number of characters successfully moved (it could be less in magnitude than `by` if the beginning of the file is reached)
-i64 buffer_pos_move_horizontally(TextBuffer *buffer, BufferPos *p, i64 by) {
+static i64 buffer_pos_move_horizontally(TextBuffer *buffer, BufferPos *p, i64 by) {
buffer_pos_validate(buffer, p);
if (by < 0) {
by = -by;
@@ -1088,7 +1088,7 @@ i64 buffer_pos_move_horizontally(TextBuffer *buffer, BufferPos *p, i64 by) {
}
// same as buffer_pos_move_horizontally, but for up and down.
-i64 buffer_pos_move_vertically(TextBuffer *buffer, BufferPos *pos, i64 by) {
+static i64 buffer_pos_move_vertically(TextBuffer *buffer, BufferPos *pos, i64 by) {
buffer_pos_validate(buffer, pos);
// moving up/down should preserve the column, not the index.
// consider:
@@ -1140,6 +1140,13 @@ i64 buffer_pos_move_down(TextBuffer *buffer, BufferPos *pos, i64 by) {
return +buffer_pos_move_vertically(buffer, pos, +by);
}
+static bool buffer_line_is_blank(Line *line) {
+ for (u32 i = 0; i < line->len; ++i)
+ if (!is32_space(line->str[i]))
+ return false;
+ return true;
+}
+
void buffer_cursor_move_to_pos(TextBuffer *buffer, BufferPos pos) {
buffer_pos_validate(buffer, &pos);
if (buffer_pos_eq(buffer->cursor_pos, pos)) {
@@ -1202,6 +1209,86 @@ i64 buffer_cursor_move_down(TextBuffer *buffer, i64 by) {
return ret;
}
+i64 buffer_pos_move_up_blank_lines(TextBuffer *buffer, BufferPos *pos, i64 by) {
+ if (by == 0) return 0;
+ if (by < 0) return buffer_pos_move_down_blank_lines(buffer, pos, -by);
+
+
+ buffer_pos_validate(buffer, pos);
+
+ u32 line = pos->line;
+
+ // skip blank lines at start
+ while (line > 0 && buffer_line_is_blank(&buffer->lines[line]))
+ --line;
+
+ i64 i;
+ for (i = 0; i < by; ++i) {
+ while (1) {
+ if (line == 0) {
+ goto end;
+ } else if (buffer_line_is_blank(&buffer->lines[line])) {
+ // move to the top blank line in this group
+ while (line > 0 && buffer_line_is_blank(&buffer->lines[line-1]))
+ --line;
+ break;
+ } else {
+ --line;
+ }
+ }
+ }
+ end:
+ pos->line = line;
+ pos->index = 0;
+ return i;
+}
+
+i64 buffer_pos_move_down_blank_lines(TextBuffer *buffer, BufferPos *pos, i64 by) {
+ if (by == 0) return 0;
+ if (by < 0) return buffer_pos_move_up_blank_lines(buffer, pos, -by);
+
+ buffer_pos_validate(buffer, pos);
+
+ u32 line = pos->line;
+ // skip blank lines at start
+ while (line + 1 < buffer->nlines && buffer_line_is_blank(&buffer->lines[line]))
+ ++line;
+
+ i64 i;
+ for (i = 0; i < by; ++i) {
+ while (1) {
+ if (line + 1 >= buffer->nlines) {
+ goto end;
+ } else if (buffer_line_is_blank(&buffer->lines[line])) {
+ // move to the bottom blank line in this group
+ while (line + 1 < buffer->nlines && buffer_line_is_blank(&buffer->lines[line+1]))
+ ++line;
+ break;
+ } else {
+ ++line;
+ }
+ }
+ }
+ end:
+ pos->line = line;
+ pos->index = 0;
+ return i;
+}
+
+i64 buffer_cursor_move_up_blank_lines(TextBuffer *buffer, i64 by) {
+ BufferPos cursor = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_up_blank_lines(buffer, &cursor, by);
+ buffer_cursor_move_to_pos(buffer, cursor);
+ return ret;
+}
+
+i64 buffer_cursor_move_down_blank_lines(TextBuffer *buffer, i64 by) {
+ BufferPos cursor = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_down_blank_lines(buffer, &cursor, by);
+ buffer_cursor_move_to_pos(buffer, cursor);
+ return ret;
+}
+
// move left / right by the specified number of words
// returns the number of words successfully moved forward
i64 buffer_pos_move_words(TextBuffer *buffer, BufferPos *pos, i64 nwords) {
@@ -1610,7 +1697,6 @@ void buffer_select_to_pos(TextBuffer *buffer, BufferPos pos) {
buffer->selection = !buffer_pos_eq(buffer->cursor_pos, buffer->selection_pos); // disable selection if cursor_pos = selection_pos.
}
-// Like shift+left in most editors, move cursor nchars chars to the left, selecting everything in between
void buffer_select_left(TextBuffer *buffer, i64 nchars) {
BufferPos cpos = buffer->cursor_pos;
buffer_pos_move_left(buffer, &cpos, nchars);
@@ -1635,6 +1721,18 @@ void buffer_select_up(TextBuffer *buffer, i64 nchars) {
buffer_select_to_pos(buffer, cpos);
}
+void buffer_select_down_blank_lines(TextBuffer *buffer, i64 by) {
+ BufferPos cpos = buffer->cursor_pos;
+ buffer_pos_move_down_blank_lines(buffer, &cpos, by);
+ buffer_select_to_pos(buffer, cpos);
+}
+
+void buffer_select_up_blank_lines(TextBuffer *buffer, i64 by) {
+ BufferPos cpos = buffer->cursor_pos;
+ buffer_pos_move_up_blank_lines(buffer, &cpos, by);
+ buffer_select_to_pos(buffer, cpos);
+}
+
void buffer_select_left_words(TextBuffer *buffer, i64 nwords) {
BufferPos cpos = buffer->cursor_pos;
buffer_pos_move_left_words(buffer, &cpos, nwords);
diff --git a/command.c b/command.c
index 0347544..cd64d38 100644
--- a/command.c
+++ b/command.c
@@ -17,6 +17,8 @@ static CommandName const command_names[] = {
{"select-down", CMD_SELECT_DOWN},
{"left-word", CMD_LEFT_WORD},
{"right-word", CMD_RIGHT_WORD},
+ {"up-blank-line", CMD_UP_BLANK_LINE},
+ {"down-blank-line", CMD_DOWN_BLANK_LINE},
{"select-left-word", CMD_SELECT_LEFT_WORD},
{"select-right-word", CMD_SELECT_RIGHT_WORD},
{"start-of-line", CMD_START_OF_LINE},
@@ -30,6 +32,8 @@ static CommandName const command_names[] = {
{"select-page-up", CMD_SELECT_PAGE_UP},
{"select-page-down", CMD_SELECT_PAGE_DOWN},
{"select-all", CMD_SELECT_ALL},
+ {"select-up-blank-line", CMD_SELECT_UP_BLANK_LINE},
+ {"select-down-blank-line", CMD_SELECT_DOWN_BLANK_LINE},
{"page-up", CMD_PAGE_UP},
{"page-down", CMD_PAGE_DOWN},
{"tab", CMD_TAB},
@@ -154,6 +158,14 @@ void command_execute(Ted *ted, Command c, i64 argument) {
else if (buffer) buffer_cursor_move_down(buffer, argument);
autocomplete_close(ted);
break;
+ case CMD_UP_BLANK_LINE:
+ if (buffer) buffer_cursor_move_up_blank_lines(buffer, argument);
+ autocomplete_close(ted);
+ break;
+ case CMD_DOWN_BLANK_LINE:
+ if (buffer) buffer_cursor_move_down_blank_lines(buffer, argument);
+ autocomplete_close(ted);
+ break;
case CMD_SELECT_LEFT:
if (buffer) buffer_select_left(buffer, argument);
autocomplete_close(ted);
@@ -222,6 +234,14 @@ void command_execute(Ted *ted, Command c, i64 argument) {
if (buffer) buffer_select_all(buffer);
autocomplete_close(ted);
break;
+ case CMD_SELECT_UP_BLANK_LINE:
+ if (buffer) buffer_select_up_blank_lines(buffer, argument);
+ autocomplete_close(ted);
+ break;
+ case CMD_SELECT_DOWN_BLANK_LINE:
+ if (buffer) buffer_select_down_blank_lines(buffer, argument);
+ autocomplete_close(ted);
+ break;
case CMD_INSERT_TEXT: {
const char *str = arg_get_string(ted, argument);
diff --git a/command.h b/command.h
index 6408141..2edd207 100644
--- a/command.h
+++ b/command.h
@@ -20,6 +20,8 @@ ENUM_U16 {
CMD_SELECT_DOWN,
CMD_LEFT_WORD, // move cursor left a word
CMD_RIGHT_WORD,
+ CMD_UP_BLANK_LINE,
+ CMD_DOWN_BLANK_LINE,
CMD_SELECT_LEFT_WORD,
CMD_SELECT_RIGHT_WORD,
CMD_START_OF_LINE, // move cursor to start of line
@@ -33,6 +35,8 @@ ENUM_U16 {
CMD_SELECT_ALL, // select entire buffer
CMD_SELECT_PAGE_UP,
CMD_SELECT_PAGE_DOWN,
+ CMD_SELECT_UP_BLANK_LINE,
+ CMD_SELECT_DOWN_BLANK_LINE,
// insertion
CMD_INSERT_TEXT, // insert text
diff --git a/main.c b/main.c
index 8fb9e1c..7ee1bc4 100644
--- a/main.c
+++ b/main.c
@@ -1,6 +1,6 @@
/*
@TODO:
-- make ctrl+up/ctrl+down move to next/prev blank line
+- ted.h documentation
- broken session fix: close buffers not in any used node
- handle multiple symbols with same name in go-to-definition menu
- better non-error window/showMessage(Request)
diff --git a/ted.cfg b/ted.cfg
index 6f78426..205ab74 100644
--- a/ted.cfg
+++ b/ted.cfg
@@ -140,10 +140,10 @@ Up = :up
Shift+Up = :select-up
Down = :down
Shift+Down = :select-down
-Ctrl+Up = 10 :up
-Ctrl+Shift+Up = 10 :select-up
-Ctrl+Down = 10 :down
-Ctrl+Shift+Down = 10 :select-down
+Ctrl+Up = 1 :up-blank-line
+Ctrl+Shift+Up = 1 :select-up-blank-line
+Ctrl+Down = 1 :down-blank-line
+Ctrl+Shift+Down = 1 :select-down-blank-line
Home = :start-of-line
Shift+Home = :select-start-of-line
Ctrl+Home = :start-of-file
diff --git a/ted.h b/ted.h
index b43d7b1..16aa07d 100644
--- a/ted.h
+++ b/ted.h
@@ -650,8 +650,6 @@ void buffer_scroll_to_pos(TextBuffer *buffer, BufferPos pos);
void buffer_scroll_center_pos(TextBuffer *buffer, BufferPos pos);
void buffer_scroll_to_cursor(TextBuffer *buffer);
void buffer_center_cursor(TextBuffer *buffer);
-i64 buffer_pos_move_horizontally(TextBuffer *buffer, BufferPos *p, i64 by);
-i64 buffer_pos_move_vertically(TextBuffer *buffer, BufferPos *pos, i64 by);
i64 buffer_pos_move_left(TextBuffer *buffer, BufferPos *pos, i64 by);
i64 buffer_pos_move_right(TextBuffer *buffer, BufferPos *pos, i64 by);
i64 buffer_pos_move_up(TextBuffer *buffer, BufferPos *pos, i64 by);
@@ -661,6 +659,10 @@ i64 buffer_cursor_move_left(TextBuffer *buffer, i64 by);
i64 buffer_cursor_move_right(TextBuffer *buffer, i64 by);
i64 buffer_cursor_move_up(TextBuffer *buffer, i64 by);
i64 buffer_cursor_move_down(TextBuffer *buffer, i64 by);
+i64 buffer_pos_move_up_blank_lines(TextBuffer *buffer, BufferPos *pos, i64 by);
+i64 buffer_pos_move_down_blank_lines(TextBuffer *buffer, BufferPos *pos, i64 by);
+i64 buffer_cursor_move_up_blank_lines(TextBuffer *buffer, i64 by);
+i64 buffer_cursor_move_down_blank_lines(TextBuffer *buffer, i64 by);
i64 buffer_pos_move_words(TextBuffer *buffer, BufferPos *pos, i64 nwords);
i64 buffer_pos_move_left_words(TextBuffer *buffer, BufferPos *pos, i64 nwords);
i64 buffer_pos_move_right_words(TextBuffer *buffer, BufferPos *pos, i64 nwords);
@@ -684,10 +686,13 @@ LSPDocumentPosition buffer_cursor_pos_as_lsp_document_position(TextBuffer *buffe
BufferPos buffer_insert_text_at_pos(TextBuffer *buffer, BufferPos pos, String32 str);
void buffer_insert_char_at_pos(TextBuffer *buffer, BufferPos pos, char32_t c);
void buffer_select_to_pos(TextBuffer *buffer, BufferPos pos);
+// Like shift+left in most editors, move cursor nchars chars to the left, selecting everything in between
void buffer_select_left(TextBuffer *buffer, i64 nchars);
void buffer_select_right(TextBuffer *buffer, i64 nchars);
void buffer_select_down(TextBuffer *buffer, i64 nchars);
void buffer_select_up(TextBuffer *buffer, i64 nchars);
+void buffer_select_down_blank_lines(TextBuffer *buffer, i64 by);
+void buffer_select_up_blank_lines(TextBuffer *buffer, i64 by);
void buffer_select_left_words(TextBuffer *buffer, i64 nwords);
void buffer_select_right_words(TextBuffer *buffer, i64 nwords);
void buffer_select_to_start_of_line(TextBuffer *buffer);