always store absolute file paths

don't re-open already loaded buffers
plugins
Patrick Cleavelin 2024-01-04 22:31:15 -06:00
parent 32777f51a4
commit 44d3e498a1
5 changed files with 65 additions and 14 deletions

View File

@ -45,6 +45,8 @@ State :: struct {
screen_width: int, screen_width: int,
font: raylib.Font, font: raylib.Font,
directory: string,
source_font_width: int, source_font_width: int,
source_font_height: int, source_font_height: int,
line_number_padding: int, line_number_padding: int,

View File

@ -1,6 +1,7 @@
package core; package core;
import "core:os" import "core:os"
import "core:path/filepath"
import "core:mem" import "core:mem"
import "core:fmt" import "core:fmt"
import "core:math" import "core:math"
@ -45,6 +46,7 @@ Glyph :: struct #packed {
FileBuffer :: struct { FileBuffer :: struct {
allocator: mem.Allocator, allocator: mem.Allocator,
directory: string,
file_path: string, file_path: string,
top_line: int, top_line: int,
cursor: Cursor, cursor: Cursor,
@ -561,7 +563,7 @@ new_virtual_file_buffer :: proc(allocator: mem.Allocator) -> FileBuffer {
return buffer; return buffer;
} }
new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuffer, Error) { new_file_buffer :: proc(allocator: mem.Allocator, file_path: string, base_dir: string = "") -> (FileBuffer, Error) {
context.allocator = allocator; context.allocator = allocator;
fd, err := os.open(file_path); fd, err := os.open(file_path);
@ -570,13 +572,26 @@ new_file_buffer :: proc(allocator: mem.Allocator, file_path: string) -> (FileBuf
} }
defer os.close(fd); defer os.close(fd);
fi, fstat_err := os.fstat(fd);
if fstat_err > 0 {
return FileBuffer{}, make_error(ErrorType.FileIOError, fmt.aprintf("failed to get file info: errno=%x", fstat_err));
}
dir: string;
if base_dir != "" {
dir = base_dir;
} else {
dir = filepath.dir(fi.fullpath);
}
if original_content, success := os.read_entire_file_from_handle(fd); success { if original_content, success := os.read_entire_file_from_handle(fd); success {
width := 256; width := 256;
height := 256; height := 256;
buffer := FileBuffer { buffer := FileBuffer {
allocator = allocator, allocator = allocator,
file_path = file_path, directory = dir,
file_path = fi.fullpath,
original_content = slice.clone_to_dynamic(original_content), original_content = slice.clone_to_dynamic(original_content),
added_content = make([dynamic]u8, 0, 1024*1024), added_content = make([dynamic]u8, 0, 1024*1024),

View File

@ -1,6 +1,7 @@
package main package main
import "core:os" import "core:os"
import "core:path/filepath"
import "core:math" import "core:math"
import "core:strings" import "core:strings"
import "core:runtime" import "core:runtime"
@ -190,12 +191,14 @@ main :: proc() {
source_font_height = 16, source_font_height = 16,
input_map = core.new_input_map(), input_map = core.new_input_map(),
window = nil, window = nil,
directory = os.get_current_directory(),
}; };
state.current_input_map = &state.input_map; state.current_input_map = &state.input_map;
register_default_input_actions(&state.input_map); register_default_input_actions(&state.input_map);
for arg in os.args[1:] { for arg in os.args[1:] {
buffer, err := core.new_file_buffer(context.allocator, arg); buffer, err := core.new_file_buffer(context.allocator, arg, state.directory);
if err.type != .None { if err.type != .None {
fmt.println("Failed to create file buffer:", err); fmt.println("Failed to create file buffer:", err);
continue; continue;
@ -300,6 +303,14 @@ main :: proc() {
theme.get_palette_raylib_color(.Background1)); theme.get_palette_raylib_color(.Background1));
} }
relative_file_path, _ := filepath.rel(state.directory, buffer.file_path)
raylib.DrawTextEx(
state.font,
raylib.TextFormat("%s", relative_file_path),
raylib.Vector2 { 8 + 4 + 6 * f32(state.source_font_width), f32(state.screen_height - state.source_font_height) },
f32(state.source_font_height),
0,
theme.get_palette_raylib_color(.Foreground1));
raylib.DrawTextEx( raylib.DrawTextEx(
state.font, state.font,
line_info_text, line_info_text,

View File

@ -1,6 +1,7 @@
package ui; package ui;
import "core:math" import "core:math"
import "core:path/filepath"
import "vendor:raylib" import "vendor:raylib"
import "../core" import "../core"
@ -87,7 +88,8 @@ draw_buffer_list_window :: proc(win: ^core.Window, state: ^core.State) {
for _, index in state.buffers { for _, index in state.buffers {
buffer := &state.buffers[index]; buffer := &state.buffers[index];
text := raylib.TextFormat("%s:%d", buffer.file_path, buffer.cursor.line+1); relative_file_path, _ := filepath.rel(state.directory, buffer.file_path)
text := raylib.TextFormat("%s:%d", relative_file_path, buffer.cursor.line+1);
text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0); text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0);
if index == win.selected_buffer { if index == win.selected_buffer {

View File

@ -27,6 +27,8 @@ foreign rg {
drop_match_array :: proc(match_array: ExternMatchArray) --- drop_match_array :: proc(match_array: ExternMatchArray) ---
} }
import "core:os"
import "core:path/filepath"
import "core:math" import "core:math"
import "core:fmt" import "core:fmt"
import "core:runtime" import "core:runtime"
@ -50,7 +52,7 @@ transmute_extern_matches :: proc(extern_matches: ExternMatchArray, dest: ^[dynam
path: string = ""; path: string = "";
if match.path_ptr != nil && match.path_len > 0 { if match.path_ptr != nil && match.path_len > 0 {
path = strings.string_from_ptr(match.path_ptr, match.path_len); path, _ = filepath.abs(strings.string_from_ptr(match.path_ptr, match.path_len));
} }
text: string = ""; text: string = "";
@ -88,14 +90,32 @@ create_grep_window :: proc() -> ^GrepWindow {
win := cast(^GrepWindow)(state.window); win := cast(^GrepWindow)(state.window);
if win.matches != nil && len(win.matches) > 0 { if win.matches != nil && len(win.matches) > 0 {
buffer, err := core.new_file_buffer(context.allocator, strings.clone(win.matches[win.selected_match].path)); should_create_buffer := true;
if err.type != .None { for buffer, index in state.buffers {
fmt.println("Failed to create file buffer:", err); if strings.compare(buffer.file_path, win.matches[win.selected_match].path) == 0 {
} else { state.current_buffer = index;
runtime.append(&state.buffers, buffer); should_create_buffer = false;
state.current_buffer = len(state.buffers)-1; break;
}
}
buffer := &state.buffers[state.current_buffer]; buffer: ^core.FileBuffer = nil;
err := core.no_error();
if should_create_buffer {
new_buffer, err := core.new_file_buffer(context.allocator, strings.clone(win.matches[win.selected_match].path));
if err.type != .None {
fmt.println("Failed to open/create file buffer:", err);
} else {
runtime.append(&state.buffers, new_buffer);
state.current_buffer = len(state.buffers)-1;
buffer = &state.buffers[state.current_buffer];
}
} else {
buffer = &state.buffers[state.current_buffer];
}
if buffer != nil {
buffer.cursor.line = win.matches[win.selected_match].line-1; buffer.cursor.line = win.matches[win.selected_match].line-1;
buffer.cursor.col = 0; buffer.cursor.col = 0;
buffer.glyph_buffer_height = math.min(256, int((state.screen_height - state.source_font_height*2) / state.source_font_height)) + 1; buffer.glyph_buffer_height = math.min(256, int((state.screen_height - state.source_font_height*2) / state.source_font_height)) + 1;
@ -198,7 +218,7 @@ grep_files :: proc(win: ^core.Window, state: ^core.State) {
} }
pattern := strings.clone_to_cstring(strings.to_string(builder)); pattern := strings.clone_to_cstring(strings.to_string(builder));
win.extern_matches = rg_search(pattern, "./src"); win.extern_matches = rg_search(pattern, strings.clone_to_cstring(state.directory));
transmute_extern_matches(win.extern_matches, &win.matches); transmute_extern_matches(win.extern_matches, &win.matches);
} }
@ -241,7 +261,8 @@ draw_grep_window :: proc(win: ^core.Window, state: ^core.State) {
show_line_numbers = false); show_line_numbers = false);
for match, index in win.matches { for match, index in win.matches {
text := raylib.TextFormat("%s:%d:%d: %s", match.path, match.line, match.col, match.text); relative_file_path, _ := filepath.rel(state.directory, match.path)
text := raylib.TextFormat("%s:%d:%d: %s", relative_file_path, match.line, match.col, match.text);
text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0); text_width := raylib.MeasureTextEx(state.font, text, f32(state.source_font_height), 0);
if index == win.selected_match { if index == win.selected_match {