handle selection new line

This commit is contained in:
2025-12-09 19:41:50 -05:00
parent f58b5e88a7
commit b2b4ffe1bd

View File

@@ -96,24 +96,25 @@ main :: proc() {
}
move_cursor()
handle_backspace()
if repeatable_key_pressed(.ENTER) {
// TODO: selection
if selection.active {
} else {
new_line_cap := len(current_line()) - cursor.char
bs := make([dynamic]u8, 0, len(current_line()) == 0 ? 1 : new_line_cap * 2)
if cursor.char < len(current_line()) {
for c, i in current_line()[cursor.char:] {
append(&bs, c)
}
}
inject_at(&lines, cursor.line + 1, bs)
resize(current_line(), cursor.char)
cursor.line += 1
cursor.char = 0
delete_selection()
selection.active = false
}
new_line_cap := len(current_line()) - cursor.char
bs := make([dynamic]u8, 0, len(current_line()) == 0 ? 1 : new_line_cap * 2)
if cursor.char < len(current_line()) {
for c, i in current_line()[cursor.char:] {
append(&bs, c)
}
}
inject_at(&lines, cursor.line + 1, bs)
resize(current_line(), cursor.char)
cursor.line += 1
cursor.char = 0
}
if r.IsKeyDown(.LEFT_SUPER) && r.IsKeyPressed(.S) {
@@ -127,66 +128,6 @@ main :: proc() {
fmt.println("Wrote file!")
}
skip_backspace: if repeatable_key_pressed(.BACKSPACE) {
if cursor.line == 0 && cursor.char == 0 do break skip_backspace
// TODO: selection
if selection.active {
earliest := selection_earliest()
latest := selection_latest()
earliest_line := &lines[earliest.line]
earliest_selection := get_selection_for_line(earliest_line[:], earliest.line)
remove_range(earliest_line, earliest_selection.start, earliest_selection.end)
if latest.line != earliest.line {
latest_line := lines[latest.line]
latest_selection := get_selection_for_line(latest_line[:], latest.line)
append(earliest_line, string(latest_line[latest_selection.end:len(latest_line)]))
ordered_remove(&lines, latest.line)
delete(latest_line)
if selection.start.line < selection.end.line {
cursor.line -= 1
}
for i := earliest.line + 1; i < latest.line; i += 1 {
line_to_remove := lines[i]
defer delete(line_to_remove)
ordered_remove(&lines, i)
// NOTE(grant): Should we do this here?
if selection.start.line < selection.end.line {
cursor.line -= 1
}
}
} else {
cursor.char -= earliest_selection.end - earliest_selection.start
}
selection.active = false
} else {
if cursor.char == 0 {
// join lines
old_len := len(lines[cursor.line - 1])
append(&lines[cursor.line - 1], string(current_line()[:]))
line_to_remove := current_line()^
defer delete(line_to_remove)
ordered_remove(&lines, cursor.line)
cursor.line -= 1
cursor.char = old_len
} else {
if r.IsKeyDown(.LEFT_ALT) {
// delete by word
delete_to, found := find_previous_space(cursor.char, current_line()[:])
if found {
remove_range(current_line(), delete_to, cursor.char)
cursor.char = delete_to
} else {
remove_range(current_line(), 0, cursor.char)
cursor.char = 0
}
} else {
// delete single char
ordered_remove(&lines[cursor.line], cursor.char - 1)
cursor.char -= 1
}
}
}
}
cursor_padding := 3
// move viewport up
@@ -489,3 +430,69 @@ get_selection_for_line :: proc(line: []u8, line_index: int) -> Range {
}
return Range{start = selection_begin, end = selection_end}
}
handle_backspace :: proc() {
skip_backspace: if repeatable_key_pressed(.BACKSPACE) {
if cursor.line == 0 && cursor.char == 0 do break skip_backspace
// TODO: selection
if selection.active {
delete_selection()
selection.active = false
} else if cursor.char == 0 {
// join lines
old_len := len(lines[cursor.line - 1])
append(&lines[cursor.line - 1], string(current_line()[:]))
line_to_remove := current_line()^
defer delete(line_to_remove)
ordered_remove(&lines, cursor.line)
cursor.line -= 1
cursor.char = old_len
} else if r.IsKeyDown(.LEFT_ALT) {
// delete by word
delete_to, found := find_previous_space(cursor.char, current_line()[:])
if found {
remove_range(current_line(), delete_to, cursor.char)
cursor.char = delete_to
} else {
remove_range(current_line(), 0, cursor.char)
cursor.char = 0
}
} else {
// delete single char
ordered_remove(&lines[cursor.line], cursor.char - 1)
cursor.char -= 1
}
}
}
delete_selection :: proc() {
earliest := selection_earliest()
latest := selection_latest()
earliest_line := &lines[earliest.line]
earliest_selection := get_selection_for_line(earliest_line[:], earliest.line)
remove_range(earliest_line, earliest_selection.start, earliest_selection.end)
if latest.line != earliest.line {
latest_line := lines[latest.line]
latest_selection := get_selection_for_line(latest_line[:], latest.line)
append(earliest_line, string(latest_line[latest_selection.end:len(latest_line)]))
ordered_remove(&lines, latest.line)
delete(latest_line)
if selection.start.line < selection.end.line {
cursor.line -= 1
if selection.start.char < selection.end.char {
cursor.char -= selection.end.char - selection.start.char
}
}
for i := earliest.line + 1; i < latest.line; i += 1 {
line_to_remove := lines[i]
defer delete(line_to_remove)
ordered_remove(&lines, i)
// NOTE(grant): Should we do this here?
if selection.start.line < selection.end.line {
cursor.line -= 1
}
}
} else {
cursor.char -= earliest_selection.end - earliest_selection.start
}
}