Compare commits

...

2 Commits

Author SHA1 Message Date
7c645a43ac untabify 2026-05-10 08:47:32 -04:00
d6bee8b2e2 fix end of file bug 2026-05-10 08:47:25 -04:00
3 changed files with 64 additions and 45 deletions

3
.gitignore vendored
View File

@@ -2,4 +2,5 @@ edit
*.ttf *.ttf
.build .build
main main
test test
*.dSYM

View File

@@ -14,13 +14,13 @@ MS_PER_FRAME :: 1000 / FPS;
State :: struct { State :: struct {
file_name: string; file_name: string;
cursor_x: int; cursor_x: int;
cursor_y: int; cursor_y: int;
window_width: int; window_width: int;
window_height: int; window_height: int;
buffer: string; buffer: string;
lines: [..][..]u8; lines: [..][..]u8;
line_height: int; line_height: int;
@@ -52,6 +52,9 @@ run_editor :: (file_name: string) {
state.file_name = file_name; state.file_name = file_name;
window := create_window(state.window_width, state.window_height, state.file_name); window := create_window(state.window_width, state.window_height, state.file_name);
state.window_width, state.window_height = Simp.get_render_dimensions(window);
my_init_fonts(*state); my_init_fonts(*state);
Simp.set_render_target(window); Simp.set_render_target(window);
@@ -248,7 +251,7 @@ handle_arrow :: (using state: *State, using event: Input.Event) {
if visible_lines.count == 0 return; if visible_lines.count == 0 return;
if key_code == { if key_code == {
case .ARROW_UP; case .ARROW_UP;
if cursor_y == 0 && first_line == 0 return; if cursor_y == 0 && first_line == 0 return;
if cursor_y == 0 { if cursor_y == 0 {
@@ -257,9 +260,10 @@ handle_arrow :: (using state: *State, using event: Input.Event) {
cursor_y -= 1; cursor_y -= 1;
} }
case .ARROW_DOWN; case .ARROW_DOWN;
if cursor_y == visible_lines.count - 1 { if cursor_y + first_line == lines.count - 1 {
// End of file?
} else if cursor_y == visible_lines.count - 1 {
first_line = min(first_line + 1, lines.count); first_line = min(first_line + 1, lines.count);
} else if cursor_y + first_line + visible_lines.count >= lines.count {
} else { } else {
cursor_y += 1; cursor_y += 1;
} }
@@ -288,9 +292,11 @@ handle_arrow :: (using state: *State, using event: Input.Event) {
} }
get_visible_lines :: (using state: State) -> [][..]u8 { get_visible_lines :: (using state: State) -> [][..]u8 {
#import "Print_vars";
if line_height <= 1 || window_height == 0 return .[]; if line_height <= 1 || window_height == 0 return .[];
num_lines_in_screen := window_height / line_height - 1; num_lines_in_screen := window_height / line_height - 1;
return array_view(lines, first_line, num_lines_in_screen); result := array_view(lines, first_line, num_lines_in_screen);
return result;
} }
string_to_line :: (str: string, cursor_char_index := -1) -> string, string { string_to_line :: (str: string, cursor_char_index := -1) -> string, string {
@@ -330,7 +336,7 @@ string_to_line :: (str: string, cursor_char_index := -1) -> string, string {
append(current_builder, s); append(current_builder, s);
current_builder = *suffix_builder; current_builder = *suffix_builder;
start = char_index + 1; start = char_index + 1;
} }
} }
@@ -370,10 +376,15 @@ read_file_lines :: (using state: *State, file_path: string) -> bool {
} }
my_init_fonts :: (using state: *State) { my_init_fonts :: (using state: *State) {
line_height = 16;
base_path := path_strip_filename(get_path_of_running_executable()); base_path := path_strip_filename(get_path_of_running_executable());
my_font = Simp.get_font_at_size("/home/grant/.local/share/fonts/otf/BerkeleyMono/", "BerkeleyMono-Regular.otf", line_height); #if OS == .LINUX {
line_height = 16;
my_font = Simp.get_font_at_size("/home/grant/.local/share/fonts/otf/BerkeleyMono/", "BerkeleyMono-Regular.otf", line_height);
} else if OS == .MACOS {
line_height = 32;
my_font = Simp.get_font_at_size("/Users/grant/Library/Fonts/", "BerkeleyMono-Regular.otf", line_height);
}
// my_font = Simp.get_font_at_size(base_path, "Anonymous Pro.ttf", line_height); // my_font = Simp.get_font_at_size(base_path, "Anonymous Pro.ttf", line_height);
assert(my_font != null); assert(my_font != null);
} }
@@ -407,4 +418,3 @@ array_remove_at :: (xs: *[..]$T, index: int) {
Input :: #import "Input"; Input :: #import "Input";
Simp :: #import "Simp"; Simp :: #import "Simp";

View File

@@ -1,10 +1,22 @@
main :: () { main :: () {
print("\nBeginning tests...\n"); print("\nBeginning tests...\n");
// test_handle_arrow_empty_lines(); test_get_visible_lines();
// test_handle_arrow_one_line(); test_handle_arrow_empty_lines();
x := 1; test_handle_arrow_one_line();
y := 2; print("Tests completed successfully\n");
assert_test(x == y); }
test_get_visible_lines :: () {
state: State;
state.line_height = 10;
state.window_height = 100;
assert_test(get_visible_lines(state).count == 0);
line: [..]u8;
array_add(*line, array_view("foo"));
array_add(*state.lines, line);
assert_test(get_visible_lines(state).count == 1);
print("test_get_visible_lines completed successfully\n");
} }
test_handle_arrow_empty_lines :: () { test_handle_arrow_empty_lines :: () {
@@ -14,7 +26,7 @@ test_handle_arrow_empty_lines :: () {
codes := Input.Key_Code.[.ARROW_DOWN, .ARROW_UP, .ARROW_LEFT, .ARROW_RIGHT]; codes := Input.Key_Code.[.ARROW_DOWN, .ARROW_UP, .ARROW_LEFT, .ARROW_RIGHT];
for codes { for codes {
handle_arrow(*state, .{key_code=it}); handle_arrow(*state, .{key_code=it});
assert(state.cursor_x == 0 && state.cursor_y == 0, "%: cursor_x % & cursor_y %", it, state.cursor_x, state.cursor_y); assert(state.cursor_x == 0 && state.cursor_y == 0, "%: cursor_x % & cursor_y %", it, state.cursor_x, state.cursor_y);
} }
@@ -23,14 +35,13 @@ test_handle_arrow_empty_lines :: () {
test_handle_arrow_one_line :: () { test_handle_arrow_one_line :: () {
state: State; state: State;
state.first_line = 0;
state.cursor_y = 0; state.cursor_y = 0;
state.cursor_x = 0; state.cursor_x = 0;
state.line_height = 10;
line: [..]u8; state.window_height = 100;
line_str := "foo bar";
add_line(*state, "foo bar");
array_add(*line, .{data=line_str.data, count=line_str.count});
array_add(*state.lines, line);
codes := Input.Key_Code.[.ARROW_DOWN, .ARROW_UP, .ARROW_LEFT]; codes := Input.Key_Code.[.ARROW_DOWN, .ARROW_UP, .ARROW_LEFT];
for codes { for codes {
@@ -38,33 +49,30 @@ test_handle_arrow_one_line :: () {
assert(state.cursor_x == 0 && state.cursor_y == 0); assert(state.cursor_x == 0 && state.cursor_y == 0);
} }
handle_arrow(*state, .{key_code=.ARROW_RIGHT}); handle_arrow(*state, .ARROW_RIGHT);
assert(state.cursor_x == 1 && state.cursor_y == 0); assert_test(state.cursor_x == 1 && state.cursor_y == 0);
print("test_handle_arrow_one_line completed successfully\n"); print("test_handle_arrow_one_line completed successfully\n");
} }
assert_test :: (value: bool, $code := #caller_code) { assert_test :: (value: bool, $call := #caller_code, loc := #caller_location) {
builder: String_Builder; if value == true return;
root, expressions := compiler_get_nodes(code); assert(false, "%\nValue is false.", #run get_expression(call), value, loc = loc);
loc := #location(code); }
print_to_builder(*builder, "%:%: Test: ", loc.fully_pathed_filename, loc.line_number); get_expression :: (call := #caller_code) -> string {
root := compiler_get_nodes(call);
builder: String_Builder;
print_expression(*builder, root); print_expression(*builder, root);
append(*builder, "\n"); return builder_to_string(*builder);
`result := #insert code; };
if !result {
for expressions { #scope_file
if it == root continue;
print_expression(*builder, it); add_line :: (using state: *State, line: string) {
append(*builder, "\n"); line_dyn: [..]u8;
} array_add(*line_dyn, array_view(line));
append(*builder, "\n"); array_add(*state.lines, line_dyn);
`expression := builder_to_string(*builder);
`print("%\n", expression);
} else {
`print("Passed!\n");
}
} }
#import,file "edit.jai"; #import,file "edit.jai";