diff --git a/src/core/core.odin b/src/core/core.odin index 67bd60d..d2f6a64 100644 --- a/src/core/core.odin +++ b/src/core/core.odin @@ -101,6 +101,7 @@ PanelType :: union { FileBufferPanel :: struct { buffer: FileBuffer, + viewed_symbol: Maybe(string), // only used for initialization file_path: string, diff --git a/src/main.odin b/src/main.odin index bbc27d3..9a6b0b7 100644 --- a/src/main.odin +++ b/src/main.odin @@ -59,39 +59,45 @@ draw :: proc(state: ^State) { new_ui.max_size.x = state.screen_width new_ui.max_size.y = state.screen_height - ui.open_element(new_ui, nil, { - dir = .LeftToRight, - kind = {ui.Grow{}, ui.Grow{}}, - }) + ui.open_element(new_ui, nil, + { + dir = .LeftToRight, + kind = {ui.Grow{}, ui.Grow{}}, + }, + style = { + background_color = .Background1 + } + ) { + floating_panels := [16]int{} + num_floating := 0 + for i in 0..render(state) } - ui.close_element(new_ui) } } } + + for i in 0..render(state) + } + } } ui.close_element(new_ui) - ui.compute_layout_2(new_ui) + ui.compute_layout(new_ui) ui.draw(new_ui, state) // TODO: figure out when to not show the input help menu diff --git a/src/panels/file_buffer.odin b/src/panels/file_buffer.odin index 92c63a1..915eb29 100644 --- a/src/panels/file_buffer.odin +++ b/src/panels/file_buffer.odin @@ -69,6 +69,24 @@ make_file_buffer_panel :: proc(file_path: string, line: int = 0, col: int = 0) - s := transmute(^ui.State)state.ui render_file_buffer(state, s, &panel_state.buffer) + if viewed_symbol, ok := panel_state.viewed_symbol.?; ok { + ui.open_element(s, nil, + { + dir = .TopToBottom, + kind = {ui.Fit{}, ui.Fit{}}, + floating = true, + }, + style = { + background_color = .Background2, + }, + ) + { + ui.open_element(s, viewed_symbol, {}) + ui.close_element(s) + } + ui.close_element(s) + } + return true } } @@ -143,10 +161,12 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB 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 + panel := transmute(^core.Panel)user_data + panel_state := &panel.type.(core.FileBufferPanel) + buffer := &panel_state.buffer ts.update_cursor(&buffer.tree, buffer.history.cursor.line, buffer.history.cursor.col) - ts.print_node_type(&buffer.tree) + panel_state.viewed_symbol = ts.print_node_type(&buffer.tree) core.reset_input_map(state) }, "View Symbol") @@ -260,6 +280,13 @@ file_buffer_input_actions :: proc(input_map: ^core.InputActions) { buffer.selection = core.new_selection(buffer.history.cursor); }, "enter visual mode"); + core.register_key_action(input_map, .ESCAPE, proc(state: ^core.State, user_data: rawptr) { + panel := transmute(^core.Panel)user_data + panel_state := &panel.type.(core.FileBufferPanel) + buffer := &panel_state.buffer + + panel_state.viewed_symbol = nil + }); } file_buffer_visual_actions :: proc(input_map: ^core.InputActions) { diff --git a/src/panels/grep.odin b/src/panels/grep.odin index 47b7da5..a3b9806 100644 --- a/src/panels/grep.odin +++ b/src/panels/grep.odin @@ -48,6 +48,7 @@ make_grep_panel :: proc() -> core.Panel { return core.Panel { type = core.GrepPanel {}, + is_floating = true, drop = proc(panel: ^core.Panel, state: ^core.State) { panel_state := &panel.type.(core.GrepPanel) @@ -147,10 +148,16 @@ make_grep_panel :: proc() -> core.Panel { if panel_state, ok := &panel.type.(core.GrepPanel); ok { s := transmute(^ui.State)state.ui - ui.open_element(s, nil, { - dir = .TopToBottom, - kind = {ui.Grow{}, ui.Grow{}} - }) + ui.open_element(s, nil, + { + dir = .TopToBottom, + kind = {ui.Grow{}, ui.Grow{}}, + floating = true, + }, + style = { + background_color = .Background1, + }, + ) { // query results and file contents side-by-side ui.open_element(s, nil, { @@ -196,7 +203,7 @@ make_grep_panel :: proc() -> core.Panel { style.background_color = .Background2 } - ui.open_element(s, result.file_path, {}, style) + ui.open_element(s, result.file_path[len(state.directory):], {}, style) ui.close_element(s) } } @@ -217,9 +224,14 @@ make_grep_panel :: proc() -> core.Panel { ui.close_element(s) // text input - ui.open_element(s, nil, { - kind = {ui.Grow{}, ui.Exact(state.source_font_height)} - }) + ui.open_element(s, nil, + { + kind = {ui.Grow{}, ui.Exact(state.source_font_height)} + }, + style = { + background_color = .Background2 + } + ) { defer ui.close_element(s) diff --git a/src/tree_sitter/ts.odin b/src/tree_sitter/ts.odin index 25e6461..a128b36 100644 --- a/src/tree_sitter/ts.odin +++ b/src/tree_sitter/ts.odin @@ -349,15 +349,15 @@ load_highlights :: proc(state: ^State) { } } -print_node_type :: proc(state: ^State) { +print_node_type :: proc(state: ^State) -> Maybe(string) { if state.tree == nil { - return + return nil } current_node := tree_cursor_current_node(&state.cursor) if node_is_null(current_node) { log.error("Current node is null after goto_first_child") - return + return nil } node_type_str := node_type(current_node) @@ -376,4 +376,6 @@ print_node_type :: proc(state: ^State) { log.infof("Node position: (%d:%d) to (%d:%d)", start_point.row+1, start_point.column+1, end_point.row+1, end_point.column+1) + + return string(node_type_str) } \ No newline at end of file diff --git a/src/ui/ui.odin b/src/ui/ui.odin index 933a462..014cd46 100644 --- a/src/ui/ui.odin +++ b/src/ui/ui.odin @@ -48,6 +48,8 @@ UI_Layout :: struct { kind: [2]UI_Size_Kind, size: [2]int, pos: [2]int, + + floating: bool, } UI_Size_Kind :: union { @@ -82,8 +84,11 @@ open_element :: proc(state: ^State, kind: UI_Element_Kind, layout: UI_Layout, st layout = layout, style = style, } - e.layout.pos = state.curr_elements[state.num_curr].layout.pos - e.layout.size = state.curr_elements[state.num_curr].layout.size + + if !e.layout.floating { + e.layout.pos = state.curr_elements[state.num_curr].layout.pos + e.layout.size = state.curr_elements[state.num_curr].layout.size + } if parent, ok := state.current_open_element.?; ok { e.parent = parent @@ -130,9 +135,9 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout { case Exact: { e.layout.size.x = int(v) } case Fit: { - child_index := e.first - for child_index != nil { - child := &state.curr_elements[child_index.?] + it := e.first + for child in iterate_siblings(state, &it) { + if child.layout.floating { continue } switch e.layout.dir { case .RightToLeft: fallthrough @@ -145,8 +150,6 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout { e.layout.size.x = math.max(e.layout.size.x, child.layout.size.x) } } - - child_index = child.next } } case Grow: { @@ -173,9 +176,9 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout { case Exact: { e.layout.size.y = int(v) } case Fit: { - child_index := e.first - for child_index != nil { - child := &state.curr_elements[child_index.?] + it := e.first + for child in iterate_siblings(state, &it) { + if child.layout.floating { continue } switch e.layout.dir { case .RightToLeft: fallthrough @@ -188,8 +191,6 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout { e.layout.size.y += child.layout.size.y } } - - child_index = child.next } } case Grow: { /* Done in the Grow pass */ } @@ -206,18 +207,64 @@ close_element :: proc(state: ^State, loc := #caller_location) -> UI_Layout { } @(private) -non_fit_parent_size :: proc(state: ^State, index: int, axis: int) -> [2]int { +iterate_siblings :: proc(state: ^State, sibling: ^Maybe(int)) -> (e: ^UI_Element, index: int, cond: bool) { + if sibling == nil || sibling^ == nil { + cond = false + return + } + + e = &state.curr_elements[sibling.?] + index = sibling.? + cond = true + + sibling^ = e.next + + return +} + +@(private) +iterate_siblings_reverse :: proc(state: ^State, sibling: ^Maybe(int)) -> (e: ^UI_Element, index: int, cond: bool) { + if sibling == nil || sibling^ == nil { + cond = false + return + } + + e = &state.curr_elements[sibling.?] + index = sibling.? + cond = true + + sibling^ = e.prev + + return +} + +@(private) +non_fit_parent_size :: proc(state: ^State, index: int, axis: int) -> int { if _, ok := state.curr_elements[index].layout.kind[axis].(Fit); ok { - if parent_index, ok := state.curr_elements[index].parent.?; ok { + if parent_index, ok := state.curr_elements[index].parent.?; ok && !state.curr_elements[index].layout.floating { return non_fit_parent_size(state, parent_index, axis) } else { - return state.max_size + return state.max_size[axis] } + } else if state.curr_elements[index].layout.floating { + return state.max_size[axis] } else { - return state.curr_elements[index].layout.size + return state.curr_elements[index].layout.size[axis] } } +@(private) +prev_non_floating :: proc(state: ^State, index: Maybe(int)) -> Maybe(int) { + it := index + for sibling, index in iterate_siblings_reverse(state, &it) { + if sibling.layout.floating { continue } + + return index + } + + return nil +} + @(private) grow_children :: proc(state: ^State, index: int) { e := &state.curr_elements[index] @@ -228,9 +275,14 @@ grow_children :: proc(state: ^State, index: int) { children_size: [2]int num_growing: [2]int - child_index := e.first - for child_index != nil { - child := &state.curr_elements[child_index.?] + has_floating := false + + it := e.first + for child in iterate_siblings(state, &it) { + if child.layout.floating { + has_floating = true + continue + } if _, ok := child.layout.kind.x.(Grow); ok { num_growing.x += 1 @@ -258,37 +310,33 @@ grow_children :: proc(state: ^State, index: int) { } } } - - child_index = child.next } if num_growing.x > 0 || num_growing.y > 0 { - remaining_size := [2]int{ x_e.x, y_e.y } - children_size + remaining_size := [2]int{ x_e, y_e } - children_size to_grow: [2]int to_grow.x = 0 if num_growing.x < 1 else remaining_size.x/num_growing.x to_grow.y = 0 if num_growing.y < 1 else remaining_size.y/num_growing.y - child_index := e.first - for child_index != nil { - child := &state.curr_elements[child_index.?] - + it := e.first + for child, child_index in iterate_siblings(state, &it) { switch e.layout.dir { case .RightToLeft: fallthrough case .LeftToRight: { if _, ok := child.layout.kind.x.(Grow); ok { - child.layout.size.x = to_grow.x + child.layout.size.x = state.max_size.x if child.layout.floating else to_grow.x } if _, ok := child.layout.kind.y.(Grow); ok { - child.layout.size.y = remaining_size.y + child.layout.size.y = state.max_size.y if child.layout.floating else y_e } } case .BottomToTop: fallthrough case .TopToBottom: { if _, ok := child.layout.kind.x.(Grow); ok { - child.layout.size.x = remaining_size.x + child.layout.size.x = state.max_size.x if child.layout.floating else x_e } if _, ok := child.layout.kind.y.(Grow); ok { - child.layout.size.y = to_grow.y + child.layout.size.y = state.max_size.y if child.layout.floating else to_grow.y } } } @@ -296,25 +344,23 @@ grow_children :: proc(state: ^State, index: int) { _, x_growing := child.layout.kind.x.(Grow) _, y_growing := child.layout.kind.y.(Grow) - if x_growing || y_growing { - grow_children(state, child_index.?) + if x_growing || y_growing || child.layout.floating { + grow_children(state, child_index) } - - child_index = child.next } } } -compute_layout_2 :: proc(state: ^State) { +compute_layout :: proc(state: ^State) { grow_children(state, 0) for i in 0..