add some more movement keybinds

fix reverse iterator acting differently than forward iterator
plugins
Patrick Cleavelin 2024-01-01 14:52:32 -06:00
parent 30729b908c
commit 16fbbebb58
5 changed files with 88 additions and 13 deletions

View File

@ -63,6 +63,7 @@ FileBuffer :: struct {
FileBufferIter :: struct {
cursor: Cursor,
buffer: ^FileBuffer,
hit_end: bool,
}
new_file_buffer_iter_from_beginning :: proc(file_buffer: ^FileBuffer) -> FileBufferIter {
@ -98,25 +99,28 @@ iterate_file_buffer :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBuf
return character, it.cursor.index, true;
}
// NOTE: This give the character for the NEXT position, unlike the non-reverse version
// which gives the character for the CURRENT position.
iterate_file_buffer_reverse_mangle_cursor :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBufferIndex, cond: bool) {
character = it.buffer.content_slices[it.cursor.index.slice_index][it.cursor.index.content_index];
if it.cursor.index.content_index == 0 {
if it.cursor.index.slice_index > 0 {
it.cursor.index.slice_index -= 1;
it.cursor.index.content_index = len(it.buffer.content_slices[it.cursor.index.slice_index])-1;
} else if it.hit_end {
return character, it.cursor.index, false;
} else {
return 0, it.cursor.index, false;
it.hit_end = true;
return character, it.cursor.index, true;
}
} else {
it.cursor.index.content_index -= 1;
}
return it.buffer.content_slices[it.cursor.index.slice_index][it.cursor.index.content_index], it.cursor.index, true;
return character, it.cursor.index, true;
}
// TODO: figure out how to give the first character of the buffer
iterate_file_buffer_reverse :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBufferIndex, cond: bool) {
if character, idx, cond = iterate_file_buffer_reverse_mangle_cursor(it); cond {
if character == '\n' {
if it.cursor.col < 1 {
if it.cursor.line > 0 {
line_length := file_buffer_line_length(it.buffer, it.cursor.index);
if line_length < 0 { line_length = 0; }
@ -124,7 +128,7 @@ iterate_file_buffer_reverse :: proc(it: ^FileBufferIter) -> (character: u8, idx:
it.cursor.line -= 1;
it.cursor.col = line_length;
} else {
return 0, it.cursor.index, false;
return character, it.cursor.index, false;
}
} else {
it.cursor.col -= 1;
@ -296,8 +300,13 @@ update_file_buffer_index_from_cursor :: proc(buffer: ^FileBuffer) {
file_buffer_line_length :: proc(buffer: ^FileBuffer, index: FileBufferIndex) -> int {
line_length := 0;
first_character := buffer.content_slices[index.slice_index][index.content_index];
left_it := new_file_buffer_iter_with_cursor(buffer, Cursor { index = index });
if first_character == '\n' {
iterate_file_buffer_reverse_mangle_cursor(&left_it);
}
for character in iterate_file_buffer_reverse_mangle_cursor(&left_it) {
if character == '\n' {
break;
@ -307,17 +316,49 @@ file_buffer_line_length :: proc(buffer: ^FileBuffer, index: FileBufferIndex) ->
}
right_it := new_file_buffer_iter_with_cursor(buffer, Cursor { index = index });
first := true;
for character in iterate_file_buffer(&right_it) {
if character == '\n' {
break;
}
if !first {
line_length += 1;
}
first = false;
}
return line_length;
}
move_cursor_start_of_line :: proc(buffer: ^FileBuffer) {
if buffer.cursor.col > 0 {
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
for _ in iterate_file_buffer_reverse(&it) {
if it.cursor.col <= 0 {
break;
}
}
buffer.cursor = it.cursor;
}
}
move_cursor_end_of_line :: proc(buffer: ^FileBuffer) {
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
line_length := file_buffer_line_length(buffer, it.cursor.index);
if buffer.cursor.col < line_length-1 {
for _ in iterate_file_buffer(&it) {
if it.cursor.col >= line_length-1 {
break;
}
}
buffer.cursor = it.cursor;
}
}
move_cursor_up :: proc(buffer: ^FileBuffer, amount: int = 1) {
if buffer.cursor.line > 0 {
current_line := buffer.cursor.line;
@ -399,6 +440,14 @@ move_cursor_forward_start_of_word :: proc(buffer: ^FileBuffer) {
update_file_buffer_scroll(buffer);
}
move_cursor_backward_start_of_word :: proc(buffer: ^FileBuffer) {
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
iterate_file_buffer_until_reverse(&it, until_start_of_word);
buffer.cursor = it.cursor;
update_file_buffer_scroll(buffer);
}
new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuffer, Error) {
context.allocator = allocator;

View File

@ -19,7 +19,9 @@ FileBuffer :: core.FileBuffer;
// TODO: use buffer list in state
do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) {
if state.current_input_map != nil {
if raylib.IsKeyDown(.LEFT_CONTROL) {
if raylib.IsKeyDown(.ESCAPE) {
state.current_input_map = &state.input_map;
} else if raylib.IsKeyDown(.LEFT_CONTROL) {
for key, action in &state.current_input_map.ctrl_key_actions {
if raylib.IsKeyPressed(key) {
switch value in action.action {
@ -93,10 +95,24 @@ register_default_leader_actions :: proc(input_map: ^core.InputMap) {
}, "close this help");
}
register_default_go_actions :: proc(input_map: ^core.InputMap) {
core.register_key_action(input_map, .H, proc(state: ^State) {
core.move_cursor_start_of_line(&state.buffers[state.current_buffer]);
state.current_input_map = &state.input_map;
}, "move to beginning of line");
core.register_key_action(input_map, .L, proc(state: ^State) {
core.move_cursor_end_of_line(&state.buffers[state.current_buffer]);
state.current_input_map = &state.input_map;
}, "move to end of line");
}
register_default_input_actions :: proc(input_map: ^core.InputMap) {
core.register_key_action(input_map, .W, proc(state: ^State) {
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer]);
}, "move forward one word");
core.register_key_action(input_map, .B, proc(state: ^State) {
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer]);
}, "move backward one word");
core.register_key_action(input_map, .K, proc(state: ^State) {
core.move_cursor_up(&state.buffers[state.current_buffer]);
@ -124,7 +140,7 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
state.source_font_height -= 2;
state.source_font_width = state.source_font_height / 2;
state.font = raylib.LoadFontEx("/Users/temp/Library/Fonts/JetBrainsMono-Regular.ttf", i32(state.source_font_height*2), nil, 0);
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
}
}, "increase font size");
@ -132,7 +148,7 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
state.source_font_height += 2;
state.source_font_width = state.source_font_height / 2;
state.font = raylib.LoadFontEx("/Users/temp/Library/Fonts/JetBrainsMono-Regular.ttf", i32(state.source_font_height*2), nil, 0);
state.font = raylib.LoadFontEx("/System/Library/Fonts/Supplemental/Andale Mono.ttf", i32(state.source_font_height*2), nil, 0);
raylib.SetTextureFilter(state.font.texture, .BILINEAR);
}, "decrease font size");
@ -142,6 +158,9 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
core.register_key_action(input_map, .SPACE, core.new_input_map(), "leader commands");
register_default_leader_actions(&(&input_map.key_actions[.SPACE]).action.(core.InputMap));
core.register_key_action(input_map, .G, core.new_input_map(), "Go commands");
register_default_go_actions(&(&input_map.key_actions[.G]).action.(core.InputMap));
}
register_buffer_list_input_actions :: proc(input_map: ^core.InputMap) {
@ -239,9 +258,10 @@ main :: proc() {
raylib.DrawRectangle(0, i32(state.screen_height - state.source_font_height), i32(state.screen_width), i32(state.source_font_height), theme.get_palette_raylib_color(.Background2));
line_info_text := raylib.TextFormat(
"Line: %d, Col: %d --- Slice Index: %d, Content Index: %d",
"Line: %d, Col: %d, Len: %d --- Slice Index: %d, Content Index: %d",
buffer.cursor.line + 1,
buffer.cursor.col + 1,
core.file_buffer_line_length(buffer, buffer.cursor.index),
buffer.cursor.index.slice_index,
buffer.cursor.index.content_index);
line_info_width := raylib.MeasureTextEx(state.font, line_info_text, f32(state.source_font_height), 0).x;

View File

@ -98,6 +98,6 @@ light_palette := []u32 {
};
get_palette_raylib_color :: proc(palette_color: PaletteColor) -> raylib.Color {
return raylib.GetColor(light_palette[palette_color]);
return raylib.GetColor(palette[palette_color]);
}

View File

@ -17,7 +17,7 @@ draw_buffer_list_window :: proc(state: ^core.State) {
win_rec,
theme.get_palette_raylib_color(.Background4));
win_margin := raylib.Vector2 { f32(text_padding*2), f32(state.source_font_height) };
win_margin := raylib.Vector2 { f32(state.source_font_width), f32(state.source_font_height) };
buffer_prev_width := (win_rec.width - win_margin.x*2) / 2;
buffer_prev_height := win_rec.height - win_margin.y*2;

View File

@ -67,6 +67,10 @@ draw_menu_bar_item :: proc(state: ^core.State, item: ^MenuBarItem, x, y: i32, pa
draw_menu_bar :: proc(state: ^core.State, data: ^MenuBarState, x, y: i32, parent_width, parent_height: i32, font_height: int) {
raylib.DrawRectangle(x, y, parent_width, i32(font_height), theme.get_palette_raylib_color(.Background3));
raylib.DrawTextEx(state.font, "Editor", raylib.Vector2 { f32(x), f32(y) }, f32(font_height), 0, theme.get_palette_raylib_color(.Foreground1));
x := x + i32((len("Editor") + 4) * state.source_font_width);
for _, index in data.items {
item := &data.items[index];
item_text := raylib.TextFormat("%s", item.text);
@ -129,6 +133,8 @@ test_menu_item :: proc(state: ^core.State, item: ^MenuBarItem, rect: raylib.Rect
}
test_menu_bar :: proc(state: ^core.State, menu_bar: ^MenuBarState, x, y: i32, mouse_pos: raylib.Vector2, mouse_has_clicked: bool, font_height: int) {
x := x + i32((len("Editor") + 4) * state.source_font_width);
for _, index in menu_bar.items {
item := &menu_bar.items[index];
item_text := raylib.TextFormat("%s", item.text);