persist cursor column

main
Patrick Cleaveliln 2025-07-21 00:03:50 +00:00
parent 6b1167a0ac
commit 705606e92a
7 changed files with 81 additions and 25 deletions

View File

@ -47,6 +47,7 @@ FileBuffer :: struct {
extension: string,
flags: BufferFlagSet,
last_col: int,
top_line: int,
selection: Maybe(Selection),
@ -423,6 +424,8 @@ move_cursor_start_of_line :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) =
cursor.?^ = it.cursor;
}
buffer.last_col = cursor.?.col
}
move_cursor_end_of_line :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, cursor: Maybe(^Cursor) = nil) {
@ -432,6 +435,8 @@ move_cursor_end_of_line :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, c
cursor = &buffer.history.cursor;
}
buffer.last_col = cursor.?.col
it := new_file_buffer_iter_with_cursor(buffer, cursor.?^);
line_length := file_buffer_line_length(buffer, it.cursor.index);
if stop_at_end {
@ -447,6 +452,8 @@ move_cursor_end_of_line :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, c
cursor.?^ = it.cursor;
}
buffer.last_col = cursor.?.col
}
move_cursor_up :: proc(buffer: ^FileBuffer, amount: int = 1, cursor: Maybe(^Cursor) = nil) {
@ -480,6 +487,12 @@ move_cursor_up :: proc(buffer: ^FileBuffer, amount: int = 1, cursor: Maybe(^Curs
cursor.?^ = it.cursor;
}
if cursor.?.col < buffer.last_col && file_buffer_line_length(buffer, cursor.?.index)-1 >= cursor.?.col {
last_col := buffer.last_col
move_cursor_right(buffer, amt = buffer.last_col - cursor.?.col, cursor = cursor)
buffer.last_col = last_col
}
update_file_buffer_scroll(buffer, cursor);
}
@ -513,6 +526,13 @@ move_cursor_down :: proc(buffer: ^FileBuffer, amount: int = 1, cursor: Maybe(^Cu
}
cursor.?^ = it.cursor;
if cursor.?.col < buffer.last_col && file_buffer_line_length(buffer, cursor.?.index)-1 >= cursor.?.col {
last_col := buffer.last_col
move_cursor_right(buffer, amt = buffer.last_col - cursor.?.col, cursor = cursor)
buffer.last_col = last_col
}
update_file_buffer_scroll(buffer, cursor);
}
@ -523,6 +543,8 @@ move_cursor_left :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) = nil) {
cursor = &buffer.history.cursor;
}
buffer.last_col = cursor.?.col
if cursor.?.col > 0 {
it := new_file_buffer_iter_with_cursor(buffer, cursor.?^);
iterate_file_buffer_reverse(&it);
@ -537,6 +559,8 @@ move_cursor_right :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, amt: in
cursor = &buffer.history.cursor;
}
buffer.last_col = cursor.?.col
it := new_file_buffer_iter_with_cursor(buffer, cursor.?^);
line_length := file_buffer_line_length(buffer, it.cursor.index);
@ -559,6 +583,8 @@ move_cursor_forward_start_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cu
iterate_file_buffer_until(&it, until_start_of_word);
cursor.?^ = it.cursor;
buffer.last_col = cursor.?.col
update_file_buffer_scroll(buffer, cursor);
}
@ -573,6 +599,8 @@ move_cursor_forward_end_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^Curs
iterate_file_buffer_until(&it, until_end_of_word);
cursor.?^ = it.cursor;
buffer.last_col = cursor.?.col
update_file_buffer_scroll(buffer, cursor);
}
@ -588,6 +616,8 @@ move_cursor_backward_start_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^C
//iterate_file_buffer_until(&it, until_non_whitespace);
cursor.?^ = it.cursor;
buffer.last_col = cursor.?.col
update_file_buffer_scroll(buffer, cursor);
}
@ -602,6 +632,8 @@ move_cursor_backward_end_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cur
iterate_file_buffer_until_reverse(&it, until_start_of_word);
cursor.?^ = it.cursor;
buffer.last_col = cursor.?.col
update_file_buffer_scroll(buffer, cursor);
}

View File

@ -67,7 +67,24 @@ draw :: proc(state: ^State) {
for i in 0..<len(state.panels.data) {
if panel, ok := util.get(&state.panels, i).?; ok {
if panel.render != nil {
panel->render(state)
background_color: theme.PaletteColor = .Background1 if panel.id == state.current_panel else .Background2
ui.open_element(new_ui, nil,
{
dir = .LeftToRight,
kind = {ui.Grow{}, ui.Grow{}},
},
style = {
border = {.Left, .Right, .Top, .Bottom },
border_color = .Green,
background_color = background_color,
}
)
{
panel->render(state)
}
ui.close_element(new_ui)
}
}
}

View File

@ -48,6 +48,7 @@ make_file_buffer_panel :: proc(file_path: string, line: int = 0, col: int = 0) -
leader_actions := core.new_input_actions()
register_default_leader_actions(&leader_actions);
file_buffer_leader_actions(&leader_actions);
core.register_key_action(&panel.input_map.mode[.Normal], .SPACE, leader_actions, "leader commands");
core.register_ctrl_key_action(&panel.input_map.mode[.Normal], .W, core.new_input_actions(), "Panel Navigation")
@ -88,11 +89,6 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB
dir = .TopToBottom,
kind = {ui.Grow{}, ui.Grow{}},
},
style = {
border = {.Left, .Right, .Top, .Bottom},
border_color = .Background4,
background_color = .Background1,
}
)
{
ui.open_element(s,
@ -100,11 +96,6 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB
{
kind = {ui.Grow{}, ui.Grow{}}
},
style = {
border = {.Left, .Right, .Top, .Bottom},
border_color = .Background4,
background_color = .Background1,
}
)
ui.close_element(s)
@ -114,6 +105,7 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB
style = {
border = {.Left, .Right, .Top, .Bottom},
border_color = .Background4,
background_color = .Background1,
}
)
{
@ -132,12 +124,13 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB
ui.open_element(
s,
fmt.tprintf(
"%v:%v - Slice %v:%v - Char: %v",
"%v:%v - Slice %v:%v - Char: %v - Last Col: %v",
buffer.history.cursor.line + 1,
buffer.history.cursor.col + 1,
buffer.history.cursor.index.chunk_index,
buffer.history.cursor.index.char_index,
core.get_character_at_iter(it)
core.get_character_at_iter(it),
buffer.last_col,
),
{}
)
@ -148,6 +141,17 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB
ui.close_element(s)
}
file_buffer_leader_actions :: proc(input_map: ^core.InputActions) {
core.register_key_action(input_map, .K, proc(state: ^core.State, user_data: rawptr) {
buffer := &(&(transmute(^core.Panel)user_data).type.(core.FileBufferPanel)).buffer
ts.update_cursor(&buffer.tree, buffer.history.cursor.line, buffer.history.cursor.col)
ts.print_node_type(&buffer.tree)
core.reset_input_map(state)
}, "View Symbol")
}
file_buffer_go_actions :: proc(input_map: ^core.InputActions) {
core.register_key_action(input_map, .H, proc(state: ^core.State, user_data: rawptr) {
buffer := &(&(transmute(^core.Panel)user_data).type.(core.FileBufferPanel)).buffer

View File

@ -69,6 +69,9 @@ make_grep_panel :: proc() -> core.Panel {
panel_state.glyphs = core.make_glyph_buffer(256,256)
panel_state.buffer = core.new_virtual_file_buffer()
core.register_ctrl_key_action(&panel.input_map.mode[.Normal], .W, core.new_input_actions(), "Panel Navigation")
register_default_panel_actions(&(&panel.input_map.mode[.Normal].ctrl_key_actions[.W]).action.(core.InputActions))
core.register_key_action(&panel.input_map.mode[.Normal], .ENTER, proc(state: ^core.State, user_data: rawptr) {
this_panel := transmute(^core.Panel)user_data
@ -163,7 +166,7 @@ make_grep_panel :: proc() -> core.Panel {
kind = {ui.Grow{}, ui.Grow{}}
},
style = {
border = {.Left, .Right, .Top, .Bottom},
border = {.Right},
border_color = .Background4
}
)

View File

@ -13,7 +13,6 @@ import "../core"
import "../util"
import "../ui"
// NOTE: odd that this is here, but I don't feel like thinking of a better dep-tree to fix it
register_default_leader_actions :: proc(input_map: ^core.InputActions) {
core.register_key_action(input_map, .Q, proc(state: ^core.State, user_data: rawptr) {
core.reset_input_map(state)
@ -22,15 +21,6 @@ register_default_leader_actions :: proc(input_map: ^core.InputActions) {
core.register_key_action(input_map, .R, proc(state: ^core.State, user_data: rawptr) {
open_grep_panel(state)
}, "Grep Workspace")
core.register_key_action(input_map, .K, proc(state: ^core.State, user_data: rawptr) {
buffer := transmute(^core.FileBuffer)user_data
ts.update_cursor(&buffer.tree, buffer.history.cursor.line, buffer.history.cursor.col)
ts.print_node_type(&buffer.tree)
core.reset_input_map(state)
}, "View Symbol")
}
register_default_panel_actions :: proc(input_map: ^core.InputActions) {

View File

@ -1,6 +1,7 @@
package theme
PaletteColor :: enum {
None,
Background,
Foreground,
@ -33,6 +34,7 @@ PaletteColor :: enum {
// Its the gruvbox dark theme <https://github.com/morhetz/gruvbox>
palette := []u32 {
0x00000000,
0x282828ff,
0xebdbb2ff,
@ -65,6 +67,7 @@ palette := []u32 {
light_palette := []u32 {
0x00000000,
0xfbf1c7ff,
0x3c3836ff,

View File

@ -251,7 +251,9 @@ parse_buffer :: proc(state: ^State, input: Input) {
}
update_cursor :: proc(state: ^State, line: int, col: int) {
assert(state.tree != nil)
if state.tree == nil {
return
}
root_node := tree_root_node(state.tree)
tree_cursor_reset(&state.cursor, root_node)
@ -274,6 +276,7 @@ load_highlights :: proc(state: ^State) {
capture_to_color := make(map[string]theme.PaletteColor, allocator = context.temp_allocator)
capture_to_color["include"] = .Red
capture_to_color["keyword.function"] = .Red
capture_to_color["keyword.return"] = .Red
capture_to_color["storageclass"] = .Red
capture_to_color["keyword.operator"] = .Purple
@ -347,6 +350,10 @@ load_highlights :: proc(state: ^State) {
}
print_node_type :: proc(state: ^State) {
if state.tree == nil {
return
}
current_node := tree_cursor_current_node(&state.cursor)
if node_is_null(current_node) {
log.error("Current node is null after goto_first_child")