diff --git a/src/core/file_buffer.odin b/src/core/file_buffer.odin index 1e90419..5ba0128 100644 --- a/src/core/file_buffer.odin +++ b/src/core/file_buffer.odin @@ -46,6 +46,7 @@ FileBuffer :: struct { file_path: string, extension: string, + flags: BufferFlagSet, top_line: int, selection: Maybe(Selection), @@ -57,6 +58,11 @@ FileBuffer :: struct { input_buffer: [dynamic]u8, } +BufferFlagSet :: bit_set[BufferFlags] +BufferFlags :: enum { + UnsavedChanges, +} + FileBufferIter :: struct { cursor: Cursor, buffer: ^FileBuffer, @@ -777,6 +783,7 @@ save_buffer_to_disk :: proc(state: ^State, buffer: ^FileBuffer) -> (error: os.Er os.flush(fd) log.infof("written %v bytes", offset) + buffer.flags -= { .UnsavedChanges } return } @@ -905,7 +912,6 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x, y, w, h: int, sh // and its after the text because the line length needs to be calculated if state.mode == .Visual && buffer.selection != nil { selection := swap_selections(buffer.selection.?) - // selection := buffer.selection.? sel_x := x + padding; width: int @@ -944,17 +950,10 @@ update_file_buffer_scroll :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) = } else if cursor.?.line < (buffer.top_line + 5) { buffer.top_line = math.max(cursor.?.line - 5, 0); } - - // if buffer.history.cursor.line > (buffer.top_line + buffer.glyphs.height - 5) { - // buffer.top_line = math.max(buffer.history.cursor.line - buffer.glyphs.height + 5, 0); - // } else if buffer.history.cursor.line < (buffer.top_line + 5) { - // buffer.top_line = math.max(buffer.history.cursor.line - 5, 0); - // } } // TODO: don't mangle cursor scroll_file_buffer :: proc(buffer: ^FileBuffer, dir: ScrollDir, cursor: Maybe(^Cursor) = nil) { - switch dir { case .Up: { @@ -971,6 +970,7 @@ insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8, append_to_end: if len(to_be_inserted) == 0 { return; } + buffer.flags += { .UnsavedChanges } index := buffer.history.cursor.index if !append_to_end else new_piece_table_index_from_end(buffer_piece_table(buffer)) @@ -988,6 +988,8 @@ delete_content_from_buffer_cursor :: proc(buffer: ^FileBuffer, amount: int) { if amount <= len(buffer.input_buffer) { runtime.resize(&buffer.input_buffer, len(buffer.input_buffer)-amount); } else { + buffer.flags += { .UnsavedChanges } + amount := amount - len(buffer.input_buffer); runtime.clear(&buffer.input_buffer); @@ -1005,6 +1007,8 @@ delete_content_from_buffer_cursor :: proc(buffer: ^FileBuffer, amount: int) { } delete_content_from_selection :: proc(buffer: ^FileBuffer, selection: ^Selection) { + buffer.flags += { .UnsavedChanges } + selection^ = swap_selections(selection^) delete_text_in_span(buffer_piece_table(buffer), &selection.start.index, &selection.end.index) diff --git a/src/panels/file_buffer.odin b/src/panels/file_buffer.odin index 4f30f33..bb1a1ce 100644 --- a/src/panels/file_buffer.odin +++ b/src/panels/file_buffer.odin @@ -37,12 +37,13 @@ make_file_buffer_panel :: proc(file_path: string, line: int = 0, col: int = 0) - log.error("Failed to create file buffer:", err); return; } - panel_state.buffer = buffer buffer.history.cursor.line = panel_state.line buffer.history.cursor.col = panel_state.col buffer.top_line = buffer.history.cursor.line core.update_file_buffer_index_from_cursor(&buffer) + + panel_state.buffer = buffer } leader_actions := core.new_input_actions() @@ -72,14 +73,6 @@ make_file_buffer_panel :: proc(file_path: string, line: int = 0, col: int = 0) - } } -open_file_buffer_in_new_panel :: proc(state: ^core.State, file_path: string, line, col: int) -> (panel_id: int, ok: bool) { - if panel_id, ok := open(state, make_file_buffer_panel(file_path, line, col)); ok { - return panel_id, true - } - - return -1, false -} - render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileBuffer) { draw_func := proc(state: ^core.State, e: ui.UI_Element, user_data: rawptr) { buffer := transmute(^core.FileBuffer)user_data; @@ -127,6 +120,11 @@ render_file_buffer :: proc(state: ^core.State, s: ^ui.State, buffer: ^core.FileB ui.open_element(s, fmt.tprintf("%s", state.mode), {}) ui.close_element(s) + if .UnsavedChanges in buffer.flags { + ui.open_element(s, "[Unsaved Changes]", {}) + ui.close_element(s) + } + ui.open_element(s, nil, { kind = {ui.Grow{}, ui.Grow{}}}) ui.close_element(s) diff --git a/src/panels/grep.odin b/src/panels/grep.odin index 2c140d9..3e94853 100644 --- a/src/panels/grep.odin +++ b/src/panels/grep.odin @@ -76,7 +76,7 @@ make_grep_panel :: proc() -> core.Panel { if panel_state.query_results != nil { selected_result := &panel_state.query_results[panel_state.selected_result] - if panel_id, ok := open_file_buffer_in_new_panel(state, selected_result.file_path, selected_result.line, selected_result.col); ok { + if panel_id, ok := open(state, make_file_buffer_panel(selected_result.file_path, selected_result.line, selected_result.col)); ok { close(state, this_panel.id) state.current_panel = panel_id