handle selection new line
This commit is contained in:
133
src/main.odin
133
src/main.odin
@@ -96,12 +96,14 @@ main :: proc() {
|
||||
}
|
||||
|
||||
move_cursor()
|
||||
handle_backspace()
|
||||
|
||||
if repeatable_key_pressed(.ENTER) {
|
||||
// TODO: selection
|
||||
if selection.active {
|
||||
|
||||
} else {
|
||||
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()) {
|
||||
@@ -114,7 +116,6 @@ main :: proc() {
|
||||
cursor.line += 1
|
||||
cursor.char = 0
|
||||
}
|
||||
}
|
||||
|
||||
if r.IsKeyDown(.LEFT_SUPER) && r.IsKeyPressed(.S) {
|
||||
builder := strings.builder_make()
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user