|
|
|
|
@ -3,8 +3,9 @@ package main
|
|
|
|
|
import "core:fmt"
|
|
|
|
|
import "core:log"
|
|
|
|
|
import "core:os"
|
|
|
|
|
import "core:strings"
|
|
|
|
|
import "core:slice"
|
|
|
|
|
import "core:strings"
|
|
|
|
|
import "core:time"
|
|
|
|
|
import "core:math"
|
|
|
|
|
import rl "vendor:raylib"
|
|
|
|
|
|
|
|
|
|
@ -276,30 +277,39 @@ update :: proc(app: ^App) {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle special keys
|
|
|
|
|
if rl.IsKeyPressed(.ENTER) {
|
|
|
|
|
if rl.IsKeyDown(.ENTER) {
|
|
|
|
|
if current_file.selection.active {
|
|
|
|
|
delete_selection(current_file)
|
|
|
|
|
}
|
|
|
|
|
insert_character(current_file, '\n')
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyPressed(.BACKSPACE) {
|
|
|
|
|
if rl.IsKeyDown(.BACKSPACE) {
|
|
|
|
|
if current_file.selection.active {
|
|
|
|
|
delete_selection(current_file)
|
|
|
|
|
} else {
|
|
|
|
|
delete_character(current_file)
|
|
|
|
|
}
|
|
|
|
|
delete_character(current_file)
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyPressed(.TAB) {
|
|
|
|
|
if rl.IsKeyDown(.TAB) {
|
|
|
|
|
if current_file.selection.active {
|
|
|
|
|
delete_selection(current_file)
|
|
|
|
|
}
|
|
|
|
|
insert_character(current_file, '\t')
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyDown(.DELETE) {
|
|
|
|
|
if current_file.selection.active {
|
|
|
|
|
delete_selection(current_file)
|
|
|
|
|
}
|
|
|
|
|
delete_character(current_file, delete_backwards = true)
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle cursor movement
|
|
|
|
|
shift_held := rl.IsKeyDown(.LEFT_SHIFT) || rl.IsKeyDown(.RIGHT_SHIFT)
|
|
|
|
|
|
|
|
|
|
if rl.IsKeyPressed(.LEFT) {
|
|
|
|
|
if rl.IsKeyDown(.LEFT) {
|
|
|
|
|
if !shift_held && current_file.selection.active {
|
|
|
|
|
current_file.cursor_pos = current_file.selection.start
|
|
|
|
|
current_file.selection.active = false
|
|
|
|
|
@ -315,8 +325,9 @@ update :: proc(app: ^App) {
|
|
|
|
|
current_file.selection.end = current_file.cursor_pos
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyPressed(.RIGHT) {
|
|
|
|
|
if rl.IsKeyDown(.RIGHT) {
|
|
|
|
|
if !shift_held && current_file.selection.active {
|
|
|
|
|
current_file.cursor_pos = current_file.selection.end
|
|
|
|
|
current_file.selection.active = false
|
|
|
|
|
@ -332,8 +343,9 @@ update :: proc(app: ^App) {
|
|
|
|
|
current_file.selection.end = current_file.cursor_pos
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyPressed(.UP) {
|
|
|
|
|
if rl.IsKeyDown(.UP) {
|
|
|
|
|
if !shift_held && current_file.selection.active {
|
|
|
|
|
current_file.selection.active = false
|
|
|
|
|
} else if !current_file.selection.active && shift_held {
|
|
|
|
|
@ -344,8 +356,9 @@ update :: proc(app: ^App) {
|
|
|
|
|
if shift_held {
|
|
|
|
|
current_file.selection.end = current_file.cursor_pos
|
|
|
|
|
}
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyPressed(.DOWN) {
|
|
|
|
|
if rl.IsKeyDown(.DOWN) {
|
|
|
|
|
if !shift_held && current_file.selection.active {
|
|
|
|
|
current_file.selection.active = false
|
|
|
|
|
} else if !current_file.selection.active && shift_held {
|
|
|
|
|
@ -356,6 +369,13 @@ update :: proc(app: ^App) {
|
|
|
|
|
if shift_held {
|
|
|
|
|
current_file.selection.end = current_file.cursor_pos
|
|
|
|
|
}
|
|
|
|
|
time.sleep(DEFAULT_DELAY)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyDown(.HOME) {
|
|
|
|
|
move_cursor_to_start_of_line(current_file)
|
|
|
|
|
}
|
|
|
|
|
if rl.IsKeyDown(.END) {
|
|
|
|
|
move_cursor_to_end_of_line(current_file)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Handle scrolling
|
|
|
|
|
@ -648,14 +668,21 @@ insert_character :: proc(file: ^FileBuffer, character: rune) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
delete_character :: proc(file: ^FileBuffer) {
|
|
|
|
|
if file.cursor_pos > 0 {
|
|
|
|
|
delete_character :: proc(file: ^FileBuffer, delete_backwards: bool = false) {
|
|
|
|
|
if file.cursor_pos > 0 && !delete_backwards {
|
|
|
|
|
before := file.content[:file.cursor_pos-1]
|
|
|
|
|
after := file.content[file.cursor_pos:]
|
|
|
|
|
file.content = fmt.aprintf("%s%s", before, after)
|
|
|
|
|
file.cursor_pos -= 1
|
|
|
|
|
file.modified = true
|
|
|
|
|
clear_selection(file)
|
|
|
|
|
} else if file.cursor_pos < len(file.content) && delete_backwards {
|
|
|
|
|
fmt.println("cursor_pos:", file.cursor_pos, "len(file.content):", len(file.content))
|
|
|
|
|
before := file.content[:file.cursor_pos]
|
|
|
|
|
after := file.content[file.cursor_pos+1:]
|
|
|
|
|
file.content = fmt.aprintf("%s%s", before, after)
|
|
|
|
|
file.modified = true
|
|
|
|
|
clear_selection(file)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -777,6 +804,38 @@ move_cursor_down :: proc(file: ^FileBuffer) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
move_cursor_to_start_of_line :: proc(file: ^FileBuffer) {
|
|
|
|
|
// For wrapped text, we need to handle cursor movement differently
|
|
|
|
|
if file.cursor_pos < len(file.content) {
|
|
|
|
|
// Find the current line start
|
|
|
|
|
for i := file.cursor_pos - 1; i >= 0; i -= 1 {
|
|
|
|
|
if file.content[i] == '\n' {
|
|
|
|
|
file.cursor_pos = i + 1
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no newline found, go to start
|
|
|
|
|
file.cursor_pos = 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
move_cursor_to_end_of_line :: proc(file: ^FileBuffer) {
|
|
|
|
|
// For wrapped text, we need to handle cursor movement differently
|
|
|
|
|
if file.cursor_pos < len(file.content) {
|
|
|
|
|
// Find the next newline
|
|
|
|
|
for i := file.cursor_pos; i < len(file.content); i += 1 {
|
|
|
|
|
if file.content[i] == '\n' {
|
|
|
|
|
file.cursor_pos = i
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// If no newline found, go to end
|
|
|
|
|
file.cursor_pos = len(file.content)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
save_file :: proc(file: ^FileBuffer) {
|
|
|
|
|
success := os.write_entire_file(file.filename, transmute([]u8)file.content)
|
|
|
|
|
if success {
|
|
|
|
|
|