implemented movement by paragraph
This commit is contained in:
101
src/main.odin
101
src/main.odin
@@ -1,3 +1,16 @@
|
||||
/*
|
||||
- TODO implement movement up and down by paragraph
|
||||
- TODO implement scrolling/viewport
|
||||
- TODO implement deletion by word
|
||||
- TODO implement selection
|
||||
- TODO implement duplicate selection/line
|
||||
- TODO implement move selection/line up/down
|
||||
- TODO implement copy/cut/paste
|
||||
- TODO implement search
|
||||
- TODO implement file picker
|
||||
- TODO implement "execute" command
|
||||
*/
|
||||
|
||||
package main
|
||||
|
||||
import "core:fmt"
|
||||
@@ -24,21 +37,6 @@ text_height: f32
|
||||
cursor: Cursor
|
||||
lines: [dynamic][dynamic]u8
|
||||
|
||||
render_cursor :: proc(cursor: ^Cursor) {
|
||||
x := cursor.char * int(font_size / 2)
|
||||
y := i32(font_size) * i32(cursor.line)
|
||||
r.DrawLine(i32(x), y, i32(x), y + i32(text_height), r.WHITE)
|
||||
r.DrawLine(i32(x) + 1, y, i32(x) + 1, y + i32(text_height), r.WHITE)
|
||||
}
|
||||
|
||||
current_line :: proc() -> ^[dynamic]u8 {
|
||||
return &lines[cursor.line]
|
||||
}
|
||||
|
||||
is_whitespace :: proc(c: u8) -> bool {
|
||||
return c == ' ' || c == '\t' || c == '\n'
|
||||
}
|
||||
|
||||
main :: proc() {
|
||||
r.InitWindow(800, 600, "odit")
|
||||
r.SetTargetFPS(60)
|
||||
@@ -65,7 +63,7 @@ main :: proc() {
|
||||
cursor.char += 1
|
||||
}
|
||||
|
||||
if r.IsKeyPressed(r.KeyboardKey.RIGHT) {
|
||||
if repeatable_key_pressed(r.KeyboardKey.RIGHT) {
|
||||
preferred_position := cursor.char + 1
|
||||
if cursor.char == len(current_line()) && cursor.line != len(lines) - 1 {
|
||||
cursor.char = 0
|
||||
@@ -89,13 +87,13 @@ main :: proc() {
|
||||
cursor.char = min(preferred_position, len(current_line()))
|
||||
}
|
||||
|
||||
if r.IsKeyPressed(r.KeyboardKey.LEFT) {
|
||||
if repeatable_key_pressed(r.KeyboardKey.LEFT) {
|
||||
preferred_position := cursor.char - 1
|
||||
if cursor.char == 0 && cursor.line != 0 {
|
||||
cursor.line -= 1
|
||||
cursor.char = len(current_line())
|
||||
}
|
||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 <= cursor.char - 1 {
|
||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.char {
|
||||
seen_space := false
|
||||
#reverse for c, c_index in current_line()[:cursor.char - 1] {
|
||||
if is_whitespace(c) {
|
||||
@@ -111,19 +109,43 @@ main :: proc() {
|
||||
cursor.char = max(preferred_position, 0)
|
||||
}
|
||||
|
||||
if r.IsKeyPressed(r.KeyboardKey.UP) {
|
||||
cursor.line -= 1
|
||||
if repeatable_key_pressed(r.KeyboardKey.UP) {
|
||||
preferred_line := cursor.line - 1
|
||||
|
||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && 0 < cursor.line {
|
||||
#reverse for l, l_index in lines[:cursor.line] {
|
||||
if len(l) == 0 || all_whitespace(l[:]) {
|
||||
preferred_line = l_index
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor.line = max(0, preferred_line)
|
||||
if len(current_line()) < cursor.char {
|
||||
cursor.char = len(current_line())
|
||||
}
|
||||
}
|
||||
if r.IsKeyPressed(r.KeyboardKey.DOWN) {
|
||||
cursor.line += 1
|
||||
|
||||
if repeatable_key_pressed(r.KeyboardKey.DOWN) {
|
||||
preferred_line := cursor.line + 1
|
||||
|
||||
if r.IsKeyDown(r.KeyboardKey.LEFT_ALT) && cursor.line + 1 < len(lines) {
|
||||
for l, l_index in lines[cursor.line + 1:] {
|
||||
if len(l) == 0 || all_whitespace(l[:]) {
|
||||
preferred_line = cursor.line + l_index + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cursor.line = min(preferred_line, len(lines))
|
||||
if len(current_line()) < cursor.char {
|
||||
cursor.char = len(current_line())
|
||||
}
|
||||
}
|
||||
if r.IsKeyPressed(r.KeyboardKey.ENTER) {
|
||||
|
||||
if repeatable_key_pressed(r.KeyboardKey.ENTER) {
|
||||
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()) {
|
||||
@@ -136,6 +158,7 @@ main :: proc() {
|
||||
cursor.line += 1
|
||||
cursor.char = 0
|
||||
}
|
||||
|
||||
if r.IsKeyDown(r.KeyboardKey.LEFT_SUPER) && r.IsKeyPressed(r.KeyboardKey.S) {
|
||||
builder := strings.builder_make()
|
||||
defer strings.builder_destroy(&builder)
|
||||
@@ -146,7 +169,8 @@ main :: proc() {
|
||||
os.write_entire_file("foo.txt", transmute([]u8)strings.to_string(builder))
|
||||
fmt.println("Wrote file!")
|
||||
}
|
||||
if r.IsKeyPressed(r.KeyboardKey.BACKSPACE) {
|
||||
|
||||
if repeatable_key_pressed(r.KeyboardKey.BACKSPACE) {
|
||||
if cursor.line == 0 && cursor.char == 0 do continue
|
||||
if cursor.char == 0 {
|
||||
old_len := len(lines[cursor.line - 1])
|
||||
@@ -189,3 +213,32 @@ main :: proc() {
|
||||
dirty = false
|
||||
}
|
||||
}
|
||||
|
||||
render_cursor :: proc(cursor: ^Cursor) {
|
||||
x := cursor.char * int(font_size / 2)
|
||||
y := i32(font_size) * i32(cursor.line)
|
||||
r.DrawLine(i32(x), y, i32(x), y + i32(text_height), r.WHITE)
|
||||
r.DrawLine(i32(x) + 1, y, i32(x) + 1, y + i32(text_height), r.WHITE)
|
||||
}
|
||||
|
||||
current_line :: proc() -> ^[dynamic]u8 {
|
||||
return &lines[cursor.line]
|
||||
}
|
||||
|
||||
is_whitespace :: proc(c: u8) -> bool {
|
||||
return c == ' ' || c == '\t' || c == '\n'
|
||||
}
|
||||
|
||||
all_whitespace :: proc(cs: []u8) -> bool {
|
||||
for c in cs {
|
||||
if !is_whitespace(c) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
repeatable_key_pressed :: proc(k: r.KeyboardKey) -> bool {
|
||||
return r.IsKeyPressed(k) || r.IsKeyPressedRepeat(k)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user