219 lines
4.4 KiB
C
219 lines
4.4 KiB
C
#include "buffer.h"
|
|
#include "cursor.h"
|
|
#include "history.h"
|
|
#include "hook.h"
|
|
#include "line-ed.h"
|
|
#include "prompt.h"
|
|
#include "refresh.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
void put_char(struct line_ed *ed, char c)
|
|
{
|
|
if (ed->l_buf_ptr > ed->l_line_end + 1) {
|
|
return;
|
|
}
|
|
|
|
struct refresh_state state = {
|
|
.r_prev_cursor_x = ed->l_cursor_x,
|
|
.r_prev_cursor_y = ed->l_cursor_y,
|
|
};
|
|
|
|
unsigned int prev_cursor = ed->l_buf_ptr - ed->l_buf;
|
|
|
|
char *dest = ed->l_buf_ptr;
|
|
unsigned int len = ed->l_line_end - ed->l_buf_ptr + 1;
|
|
|
|
if (dest < ed->l_line_end) {
|
|
memmove(dest + 1, dest, len);
|
|
}
|
|
|
|
ed->l_cursor_x++;
|
|
ed->l_line_end++;
|
|
ed->l_buf_ptr++;
|
|
*dest = c;
|
|
|
|
if (ed->l_buf_ptr == ed->l_line_end) {
|
|
*ed->l_buf_ptr = '\0';
|
|
}
|
|
|
|
hook_buffer_modified(ed);
|
|
|
|
put_refresh(ed, &state);
|
|
}
|
|
|
|
static void backspace_simple(struct line_ed *ed)
|
|
{
|
|
if (ed->l_buf_ptr == ed->l_buf) {
|
|
return;
|
|
}
|
|
|
|
struct refresh_state state = {
|
|
.r_prev_cursor_x = ed->l_cursor_x,
|
|
.r_prev_cursor_y = ed->l_cursor_y,
|
|
};
|
|
|
|
unsigned int prev_cursor = ed->l_buf_ptr - ed->l_buf;
|
|
|
|
char *dest = ed->l_buf_ptr;
|
|
unsigned int len = ed->l_line_end - ed->l_buf_ptr + 1;
|
|
memmove(dest - 1, dest, len);
|
|
|
|
ed->l_cursor_x--;
|
|
ed->l_line_end--;
|
|
ed->l_buf_ptr--;
|
|
|
|
hook_buffer_modified(ed);
|
|
|
|
backspace_simple_refresh(ed, &state);
|
|
}
|
|
|
|
static void backspace_nl(struct line_ed *ed)
|
|
{
|
|
unsigned int prev_line_len = line_length(ed, ed->l_cursor_y - 1);
|
|
|
|
struct refresh_state state = {
|
|
.r_prev_cursor_x = ed->l_cursor_x,
|
|
.r_prev_cursor_y = ed->l_cursor_y,
|
|
.r_prev_line_len = prev_line_len,
|
|
};
|
|
|
|
char *dest = ed->l_buf_ptr;
|
|
unsigned int len = ed->l_line_end - ed->l_buf_ptr + 1;
|
|
memmove(dest - 1, dest, len);
|
|
|
|
ed->l_cursor_x = prev_line_len - 1;
|
|
ed->l_cursor_y--;
|
|
ed->l_buf_ptr--;
|
|
ed->l_line_end--;
|
|
|
|
hook_buffer_modified(ed);
|
|
|
|
backspace_nl_refresh(ed, &state);
|
|
}
|
|
|
|
void backspace(struct line_ed *ed)
|
|
{
|
|
if (ed->l_buf_ptr == ed->l_buf) {
|
|
return;
|
|
}
|
|
|
|
if (ed->l_cursor_x == 0 && ed->l_cursor_y <= ed->l_continuations) {
|
|
return;
|
|
}
|
|
|
|
if (ed->l_cursor_x == 0 && ed->l_cursor_y > 0) {
|
|
backspace_nl(ed);
|
|
} else {
|
|
backspace_simple(ed);
|
|
}
|
|
}
|
|
|
|
void cursor_left(struct line_ed *ed)
|
|
{
|
|
if (ed->l_cursor_x != 0) {
|
|
//fputs("\010", stdout);
|
|
b_tty_move_cursor_x(ed->l_tty, B_TTY_POS_CURSOR, -1);
|
|
fflush(stdout);
|
|
ed->l_cursor_x--;
|
|
ed->l_buf_ptr--;
|
|
return;
|
|
}
|
|
|
|
if (ed->l_cursor_y <= ed->l_continuations || ed->l_buf_ptr <= ed->l_buf) {
|
|
return;
|
|
}
|
|
|
|
ed->l_cursor_y--;
|
|
ed->l_buf_ptr--;
|
|
unsigned int prompt_len = 0;
|
|
if (ed->l_cursor_y == 0) {
|
|
prompt_len = prompt_length(ed, PROMPT_MAIN);
|
|
}
|
|
|
|
unsigned int len = line_length(ed, ed->l_cursor_y);
|
|
ed->l_cursor_x = len - 1;
|
|
|
|
//printf("\033[A\033[%dG", len + prompt_len);
|
|
b_tty_move_cursor_y(ed->l_tty, B_TTY_POS_CURSOR, -1);
|
|
b_tty_move_cursor_x(ed->l_tty, B_TTY_POS_START, len + prompt_len);
|
|
|
|
fflush(stdout);
|
|
}
|
|
|
|
void cursor_right(struct line_ed *ed)
|
|
{
|
|
if (ed->l_buf_ptr >= ed->l_line_end) {
|
|
return;
|
|
}
|
|
|
|
if (*ed->l_buf_ptr != '\n') {
|
|
ed->l_cursor_x++;
|
|
ed->l_buf_ptr++;
|
|
//fputs("\033[C", stdout);
|
|
b_tty_move_cursor_x(ed->l_tty, B_TTY_POS_CURSOR, 1);
|
|
fflush(stdout);
|
|
return;
|
|
}
|
|
|
|
if (ed->l_buf_ptr >= ed->l_line_end) {
|
|
return;
|
|
}
|
|
|
|
ed->l_cursor_y++;
|
|
ed->l_cursor_x = 0;
|
|
ed->l_buf_ptr++;
|
|
|
|
//printf("\033[B\033[G");
|
|
b_tty_move_cursor_y(ed->l_tty, B_TTY_POS_CURSOR, 1);
|
|
b_tty_move_cursor_x(ed->l_tty, B_TTY_POS_START, 0);
|
|
fflush(stdout);
|
|
}
|
|
|
|
void arrow_up(struct line_ed *ed)
|
|
{
|
|
if (ed->l_history_pos == 0) {
|
|
return;
|
|
}
|
|
|
|
if (ed->l_cursor_y > 0) {
|
|
//printf("\033[%uA", ed->l_cursor_y);
|
|
b_tty_move_cursor_y(ed->l_tty, B_TTY_POS_CURSOR, ed->l_cursor_y);
|
|
}
|
|
|
|
//printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1);
|
|
b_tty_move_cursor_x(
|
|
ed->l_tty, B_TTY_POS_START, prompt_length(ed, PROMPT_MAIN));
|
|
b_tty_clear(ed->l_tty, B_TTY_CLEAR_SCREEN | B_TTY_CLEAR_FROM_CURSOR);
|
|
|
|
save_buf_to_history(ed);
|
|
ed->l_history_pos--;
|
|
load_buf_from_history(ed);
|
|
|
|
print_buffer(ed);
|
|
fflush(stdout);
|
|
}
|
|
|
|
void arrow_down(struct line_ed *ed)
|
|
{
|
|
if (ed->l_history_pos == b_array_size(ed->l_history) - 1) {
|
|
return;
|
|
}
|
|
|
|
if (ed->l_cursor_y > 0) {
|
|
//printf("\033[%uA", ed->l_cursor_y);
|
|
b_tty_move_cursor_y(ed->l_tty, B_TTY_POS_CURSOR, ed->l_cursor_y);
|
|
}
|
|
|
|
//printf("\033[%zuG\033[J", prompt_length(ed, PROMPT_MAIN) + 1);
|
|
b_tty_move_cursor_x(
|
|
ed->l_tty, B_TTY_POS_START, prompt_length(ed, PROMPT_MAIN) + 1);
|
|
|
|
save_buf_to_history(ed);
|
|
ed->l_history_pos++;
|
|
load_buf_from_history(ed);
|
|
|
|
print_buffer(ed);
|
|
fflush(stdout);
|
|
}
|