summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-12-28 18:04:49 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-12-28 18:04:49 -0500
commit7cf306d26d710dd551575a32b4f492e7a13a9610 (patch)
tree7e58e6fc636c4061df40fe2c439d907ef6cfb6d6
parent52ac1f9d10d8752aa99698c0ee80c4f9420de389 (diff)
more selection, improved buffer_pos_move_left_words
-rw-r--r--buffer.c121
-rw-r--r--main.c69
2 files changed, 131 insertions, 59 deletions
diff --git a/buffer.c b/buffer.c
index 57d4a4f..52692b7 100644
--- a/buffer.c
+++ b/buffer.c
@@ -879,36 +879,50 @@ i64 buffer_pos_move_down(TextBuffer *buffer, BufferPos *pos, i64 by) {
return +buffer_pos_move_vertically(buffer, pos, +by);
}
-i64 buffer_cursor_move_left(TextBuffer *buffer, i64 by) {
- i64 ret = buffer_pos_move_left(buffer, &buffer->cursor_pos, by);
+void buffer_cursor_move_to_pos(TextBuffer *buffer, BufferPos pos) {
+ buffer_pos_validate(buffer, &pos);
+ buffer->cursor_pos = pos;
+ buffer->selection = false;
buffer_scroll_to_cursor(buffer);
+}
+
+i64 buffer_cursor_move_left(TextBuffer *buffer, i64 by) {
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_left(buffer, &cur_pos, by);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
i64 buffer_cursor_move_right(TextBuffer *buffer, i64 by) {
- i64 ret = buffer_pos_move_right(buffer, &buffer->cursor_pos, by);
- buffer_scroll_to_cursor(buffer);
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_right(buffer, &cur_pos, by);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
i64 buffer_cursor_move_up(TextBuffer *buffer, i64 by) {
- i64 ret = buffer_pos_move_up(buffer, &buffer->cursor_pos, by);
- buffer_scroll_to_cursor(buffer);
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_up(buffer, &cur_pos, by);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
i64 buffer_cursor_move_down(TextBuffer *buffer, i64 by) {
- i64 ret = buffer_pos_move_down(buffer, &buffer->cursor_pos, by);
- buffer_scroll_to_cursor(buffer);
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_down(buffer, &cur_pos, by);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
-void buffer_cursor_move_to_pos(TextBuffer *buffer, BufferPos pos) {
- buffer_pos_validate(buffer, &pos);
- buffer->cursor_pos = pos;
- buffer_scroll_to_cursor(buffer);
+// Is this character a "word" character?
+// This determines how buffer_pos_move_words (i.e. ctrl+left/right) works
+static bool is_word(char32_t c) {
+ return c > WCHAR_MAX || c == U'_' || iswalnum((wint_t)c);
}
+static bool is_space(char32_t c) {
+ return c > WCHAR_MAX || iswspace((wint_t)c);
+}
// move left / right by the specified number of words
// returns the number of words successfully moved forward
@@ -930,13 +944,13 @@ i64 buffer_pos_move_words(TextBuffer *buffer, BufferPos *pos, i64 nwords) {
}
} else {
// move past any whitespace before the word
- while (index < line->len && iswspace(str[index]))
+ while (index < line->len && is_space(str[index]))
++index;
- bool starting_alnum = iswalnum(str[index]) != 0;
- for (; index < line->len && !iswspace(str[index]); ++index) {
- bool this_alnum = iswalnum(str[index]) != 0;
- if (this_alnum != starting_alnum) {
+ bool starting_isword = is_word(str[index]) != 0;
+ for (; index < line->len && !is_space(str[index]); ++index) {
+ bool this_isword = is_word(str[index]) != 0;
+ if (this_isword != starting_isword) {
// either the position *was* on an alphanumeric character and now it's not
// or it wasn't and now it is.
break;
@@ -944,7 +958,7 @@ i64 buffer_pos_move_words(TextBuffer *buffer, BufferPos *pos, i64 nwords) {
}
// move past any whitespace after the word
- while (index < line->len && iswspace(str[index]))
+ while (index < line->len && is_space(str[index]))
++index;
pos->index = index;
}
@@ -968,17 +982,20 @@ i64 buffer_pos_move_words(TextBuffer *buffer, BufferPos *pos, i64 nwords) {
} else {
--index;
- while (index > 0 && iswspace(str[index]))
+ while (index > 0 && is_space(str[index])) // skip whitespace after word
--index;
- bool starting_alnum = iswalnum(str[index]) != 0;
- for (; index > 0 && !iswspace(str[index]); --index) {
- bool this_alnum = iswalnum(str[index]) != 0;
- if (this_alnum != starting_alnum) {
- break;
+ if (index > 0) {
+ bool starting_isword = is_word(str[index]) != 0;
+ while (true) {
+ bool this_isword = is_word(str[index]) != 0;
+ if (is_space(str[index]) || this_isword != starting_isword) {
+ ++index;
+ break;
+ }
+ if (index == 0) break;
+ --index;
}
}
- if (iswspace(str[index]))
- ++index;
pos->index = index;
}
}
@@ -995,14 +1012,16 @@ i64 buffer_pos_move_right_words(TextBuffer *buffer, BufferPos *pos, i64 nwords)
}
i64 buffer_cursor_move_left_words(TextBuffer *buffer, i64 nwords) {
- i64 ret = buffer_pos_move_left_words(buffer, &buffer->cursor_pos, nwords);
- buffer_scroll_to_cursor(buffer);
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_left_words(buffer, &cur_pos, nwords);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
i64 buffer_cursor_move_right_words(TextBuffer *buffer, i64 nwords) {
- i64 ret = buffer_pos_move_right_words(buffer, &buffer->cursor_pos, nwords);
- buffer_scroll_to_cursor(buffer);
+ BufferPos cur_pos = buffer->cursor_pos;
+ i64 ret = buffer_pos_move_right_words(buffer, &cur_pos, nwords);
+ buffer_cursor_move_to_pos(buffer, cur_pos);
return ret;
}
@@ -1125,33 +1144,47 @@ void buffer_insert_utf8_at_cursor(TextBuffer *buffer, char const *utf8) {
}
}
-// like shift+right in most editors, move cursor n chars to the right, selecting everything in between
-void buffer_select_right(TextBuffer *buffer, i64 n) {
+// 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) {
+ if (!buffer->selection)
+ buffer->selection_pos = buffer->cursor_pos;
+ buffer_cursor_move_left(buffer, nchars);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0; // disable selection if cursor_pos = selection_pos.
+}
+
+void buffer_select_right(TextBuffer *buffer, i64 nchars) {
+ if (!buffer->selection)
+ buffer->selection_pos = buffer->cursor_pos;
+ buffer_cursor_move_right(buffer, nchars);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0;
+}
+
+void buffer_select_down(TextBuffer *buffer, i64 nchars) {
if (!buffer->selection)
buffer->selection_pos = buffer->cursor_pos;
- if (buffer_cursor_move_right(buffer, n)) // if we actually moved at all
- buffer->selection = true;
+ buffer_cursor_move_down(buffer, nchars);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0;
}
-void buffer_select_left(TextBuffer *buffer, i64 n) {
+void buffer_select_up(TextBuffer *buffer, i64 nchars) {
if (!buffer->selection)
buffer->selection_pos = buffer->cursor_pos;
- if (buffer_cursor_move_left(buffer, n))
- buffer->selection = true;
+ buffer_cursor_move_up(buffer, nchars);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0;
}
-void buffer_select_down(TextBuffer *buffer, i64 n) {
+void buffer_select_left_words(TextBuffer *buffer, i64 nwords) {
if (!buffer->selection)
buffer->selection_pos = buffer->cursor_pos;
- if (buffer_cursor_move_down(buffer, n))
- buffer->selection = true;
+ buffer_cursor_move_left_words(buffer, nwords);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0;
}
-void buffer_select_up(TextBuffer *buffer, i64 n) {
+void buffer_select_right_words(TextBuffer *buffer, i64 nwords) {
if (!buffer->selection)
buffer->selection_pos = buffer->cursor_pos;
- if (buffer_cursor_move_up(buffer, n))
- buffer->selection = true;
+ buffer_cursor_move_right_words(buffer, nwords);
+ buffer->selection = buffer_pos_cmp(buffer->cursor_pos, buffer->selection_pos) != 0;
}
static void buffer_shorten_line(Line *line, u32 new_len) {
@@ -1529,9 +1562,9 @@ void buffer_render(TextBuffer *buffer, float x1, float y1, float x2, float y2) {
sel_start = buffer->selection_pos;
} else assert(0);
- u32 index1 = sel_start.index;
for (u32 line_idx = maxu32(sel_start.line, start_line); line_idx <= sel_end.line; ++line_idx) {
Line *line = &buffer->lines[line_idx];
+ u32 index1 = line_idx == sel_start.line ? sel_start.index : 0;
u32 index2 = line_idx == sel_end.line ? sel_end.index : line->len;
assert(index2 >= index1);
diff --git a/main.c b/main.c
index d1ad1c4..b115196 100644
--- a/main.c
+++ b/main.c
@@ -92,6 +92,7 @@ int main(void) {
Uint8 const *keyboard_state = SDL_GetKeyboardState(NULL);
bool ctrl = keyboard_state[SDL_SCANCODE_LCTRL] || keyboard_state[SDL_SCANCODE_RCTRL];
bool shift = keyboard_state[SDL_SCANCODE_LSHIFT] || keyboard_state[SDL_SCANCODE_RSHIFT];
+ bool alt = keyboard_state[SDL_SCANCODE_LALT] || keyboard_state[SDL_SCANCODE_RALT];
while (SDL_PollEvent(&event)) {
// @TODO: make a function to handle text buffer events
@@ -123,26 +124,64 @@ int main(void) {
buffer_scroll(buffer, 0, +buffer_display_lines(buffer));
break;
case SDLK_RIGHT:
- if (shift) {
- buffer_select_right(buffer, 1);
- } else {
- if (ctrl)
- buffer_cursor_move_right_words(buffer, 1);
- else
- buffer_cursor_move_right(buffer, 1);
+ if (!alt) {
+ if (shift) {
+ if (ctrl)
+ buffer_select_right_words(buffer, 1);
+ else
+ buffer_select_right(buffer, 1);
+ } else {
+ if (ctrl)
+ buffer_cursor_move_right_words(buffer, 1);
+ else
+ buffer_cursor_move_right(buffer, 1);
+ }
}
break;
case SDLK_LEFT:
- if (ctrl)
- buffer_cursor_move_left_words(buffer, 1);
- else
- buffer_cursor_move_left(buffer, 1);
+ if (!alt) {
+ if (shift) {
+ if (ctrl)
+ buffer_select_left_words(buffer, 1);
+ else
+ buffer_select_left(buffer, 1);
+ } else {
+ if (ctrl)
+ buffer_cursor_move_left_words(buffer, 1);
+ else
+ buffer_cursor_move_left(buffer, 1);
+ }
+ }
break;
case SDLK_UP:
- buffer_cursor_move_up(buffer, 1);
+ if (!alt) {
+ if (shift) {
+ if (ctrl)
+ buffer_select_up(buffer, 10);
+ else
+ buffer_select_up(buffer, 1);
+ } else {
+ if (ctrl)
+ buffer_cursor_move_up(buffer, 10);
+ else
+ buffer_cursor_move_up(buffer, 1);
+ }
+ }
break;
case SDLK_DOWN:
- buffer_cursor_move_down(buffer, 1);
+ if (!alt) {
+ if (shift) {
+ if (ctrl)
+ buffer_select_down(buffer, 10);
+ else
+ buffer_select_down(buffer, 1);
+ } else {
+ if (ctrl)
+ buffer_cursor_move_down(buffer, 10);
+ else
+ buffer_cursor_move_down(buffer, 1);
+ }
+ }
break;
case SDLK_RETURN:
buffer_insert_char_at_cursor(buffer, U'\n');
@@ -194,8 +233,8 @@ int main(void) {
time_at_last_frame = time_this_frame;
}
- if (ctrl) {
- // control + arrow keys to scroll
+ if (alt) {
+ // alt + arrow keys to scroll
double scroll_speed = 20.0;
double scroll_amount_x = scroll_speed * frame_dt * 1.5; // characters are taller than they are wide
double scroll_amount_y = scroll_speed * frame_dt;