|
|
|
@ -33,9 +33,7 @@ const (
|
|
|
|
|
|
|
|
|
|
func editorKeyPresses() bool {
|
|
|
|
|
char := editorReadKey()
|
|
|
|
|
state.StatusLine = ""
|
|
|
|
|
|
|
|
|
|
editorMoveCaret(char)
|
|
|
|
|
state.StatusLines[1] = ""
|
|
|
|
|
|
|
|
|
|
if char == ctrl_key('r') {
|
|
|
|
|
uiRefresh()
|
|
|
|
@ -55,71 +53,133 @@ func editorKeyPresses() bool {
|
|
|
|
|
editorRemoveChar(char)
|
|
|
|
|
} else if char >= 32 && char <= 126 || char == KEY_ENTER || char == KEY_TAB {
|
|
|
|
|
editorInsertChar(char)
|
|
|
|
|
} else {
|
|
|
|
|
editorMoveCaret(char)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func editorRemoveChar(char rune) {
|
|
|
|
|
lineText := state.rows[state.Cy]
|
|
|
|
|
rl := state.getCurrentRowLen()
|
|
|
|
|
|
|
|
|
|
cx := state.Cx
|
|
|
|
|
cy := state.Cy
|
|
|
|
|
rc := len(state.rows)
|
|
|
|
|
|
|
|
|
|
lt := ""
|
|
|
|
|
rl := 0
|
|
|
|
|
|
|
|
|
|
if rc > 0 {
|
|
|
|
|
lt = state.rows[cy]
|
|
|
|
|
rl = state.getCurrentRowLen()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// file is empty
|
|
|
|
|
if rc == 0 && lt == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1. Backspace at beginning of a line
|
|
|
|
|
2. Backspace in middle of a line
|
|
|
|
|
3. Backspace at end of a line
|
|
|
|
|
4. Backspace when there are 0 characters in the file
|
|
|
|
|
*/
|
|
|
|
|
if char == KEY_BACKSPACE {
|
|
|
|
|
if cx == 0 && state.Cy > 0 {
|
|
|
|
|
plt := state.rows[state.Cy-1]
|
|
|
|
|
state.rows[state.Cy-1] = fmt.Sprintf("%s%s", plt, lineText)
|
|
|
|
|
if state.Cy < len(state.rows)-1 {
|
|
|
|
|
state.rows = append(state.rows[:state.Cy-1], state.rows[state.Cy:]...)
|
|
|
|
|
editorMoveCaret(KEY_UP_ARROW)
|
|
|
|
|
if cx == 0 && cy == 0 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
// backspace in the middle of a line
|
|
|
|
|
if cx > 0 && cx < rl {
|
|
|
|
|
state.rows[cy] = fmt.Sprintf("%s%s", lt[:cx-1], lt[cx:])
|
|
|
|
|
editorMoveCaret(KEY_LEFT_ARROW)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// backspace at start of line
|
|
|
|
|
// join lines together and remove
|
|
|
|
|
if cx == 0 && cy > 0 {
|
|
|
|
|
plt := state.rows[cy-1]
|
|
|
|
|
_, highlightedRowLen := renderLine(plt)
|
|
|
|
|
state.rows[cy-1] = fmt.Sprintf("%s%s", plt, lt)
|
|
|
|
|
|
|
|
|
|
editorMoveCaret(KEY_UP_ARROW)
|
|
|
|
|
for x := 0; x < highlightedRowLen; x++ {
|
|
|
|
|
editorMoveCaret(KEY_RIGHT_ARROW)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// if we're at the last row, make sure to only remove the last line
|
|
|
|
|
if cy == rc-1 {
|
|
|
|
|
state.rows = state.rows[:cy]
|
|
|
|
|
} else {
|
|
|
|
|
state.rows = state.rows[:state.Cy-1]
|
|
|
|
|
state.Cy--
|
|
|
|
|
state.rows = append(state.rows[:cy], state.rows[cy+1:]...)
|
|
|
|
|
}
|
|
|
|
|
state.Cx = 0
|
|
|
|
|
} else if cx == 0 {
|
|
|
|
|
// do nothing because there are no characters
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
} else {
|
|
|
|
|
state.StatusLine = fmt.Sprintf("D: %d - %s%s", cx, lineText[:cx-1], lineText[cx:])
|
|
|
|
|
state.rows[state.Cy] = fmt.Sprintf("%s%s", lineText[:cx-1], lineText[cx:])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// backspace at end of line
|
|
|
|
|
if cx == rl {
|
|
|
|
|
state.rows[cy] = lt[:cx-1]
|
|
|
|
|
editorMoveCaret(KEY_LEFT_ARROW)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else if char == KEY_DELETE {
|
|
|
|
|
// in middle of line
|
|
|
|
|
if cx < rl-1 {
|
|
|
|
|
state.rows[state.Cy] = fmt.Sprintf("%s%s", lineText[:cx], lineText[cx+1:])
|
|
|
|
|
state.rows[state.Cy] = fmt.Sprintf("%s%s", lt[:cx], lt[cx+1:])
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func editorInsertChar(char rune) {
|
|
|
|
|
lt := ""
|
|
|
|
|
cx := state.Cx
|
|
|
|
|
if len(state.rows) > 0 {
|
|
|
|
|
lt = state.rows[state.Cy]
|
|
|
|
|
} else {
|
|
|
|
|
state.rows = []string{fmt.Sprintf("%c", char)}
|
|
|
|
|
return
|
|
|
|
|
cy := state.Cy
|
|
|
|
|
rc := len(state.rows)
|
|
|
|
|
|
|
|
|
|
lt := ""
|
|
|
|
|
rl := 0
|
|
|
|
|
|
|
|
|
|
if rc > 0 {
|
|
|
|
|
lt = state.rows[cy]
|
|
|
|
|
rl = state.getCurrentRowLen()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
1. Enter at beginning line
|
|
|
|
|
2. Enter at middle of line
|
|
|
|
|
3. Enter at end of line
|
|
|
|
|
*/
|
|
|
|
|
if char == KEY_ENTER {
|
|
|
|
|
oldL := lt[:cx]
|
|
|
|
|
newL := lt[cx:]
|
|
|
|
|
state.rows[state.Cy] = oldL
|
|
|
|
|
if state.Cy == len(state.rows)-1 {
|
|
|
|
|
state.rows[state.Cy] = oldL
|
|
|
|
|
state.rows = append(state.rows, newL)
|
|
|
|
|
} else {
|
|
|
|
|
state.rows = append(append(state.rows[:state.Cy], newL), state.rows[state.Cy:]...)
|
|
|
|
|
// beginning of line
|
|
|
|
|
if cx == 0 {
|
|
|
|
|
if cy == rc {
|
|
|
|
|
state.rows = append(state.rows, lt)
|
|
|
|
|
} else if cy < rc {
|
|
|
|
|
state.rows = append(append(state.rows[:cy], lt), state.rows[cy:]...)
|
|
|
|
|
}
|
|
|
|
|
state.rows[cy] = ""
|
|
|
|
|
|
|
|
|
|
// end of a line
|
|
|
|
|
} else if cx >= rl {
|
|
|
|
|
if cy < rc {
|
|
|
|
|
state.rows = append(append(state.rows[:cy], ""), state.rows[cy:]...)
|
|
|
|
|
state.rows[cy] = lt
|
|
|
|
|
} else if cy == rc {
|
|
|
|
|
state.rows = append(state.rows[:cy], "")
|
|
|
|
|
}
|
|
|
|
|
// mid line
|
|
|
|
|
} else if cx > 0 {
|
|
|
|
|
state.rows = append(append(state.rows[:cy], lt[cx:]), state.rows[cy:]...)
|
|
|
|
|
state.rows[cy] = lt[:cx]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
state.Cx = 0
|
|
|
|
|
editorMoveCaret(KEY_DOWN_ARROW)
|
|
|
|
|
} else {
|
|
|
|
|
state.rows[state.Cy] = fmt.Sprintf("%s%c%s", lt[:cx], char, lt[cx:])
|
|
|
|
|
state.StatusLines[1] = fmt.Sprintf("%c %d", char, char)
|
|
|
|
|
state.rows[cy] = fmt.Sprintf("%s%c%s", lt[:cx], char, lt[cx:])
|
|
|
|
|
editorMoveCaret(KEY_RIGHT_ARROW)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -165,6 +225,8 @@ func editorMoveCaret(char rune) {
|
|
|
|
|
case KEY_END:
|
|
|
|
|
x = state.Cols - 1
|
|
|
|
|
break
|
|
|
|
|
default:
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if char == ctrl_key(KEY_DOWN_ARROW) {
|
|
|
|
|