#include "buffer.h" #include "cursor.h" #include "history.h" #include "hook.h" #include "line-ed.h" #include "prompt.h" #include "refresh.h" #include 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, }; size_t prev_cursor = ed->l_buf_ptr - ed->l_buf; char *dest = ed->l_buf_ptr; size_t 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, }; size_t prev_cursor = ed->l_buf_ptr - ed->l_buf; char *dest = ed->l_buf_ptr; size_t 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) { size_t 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; size_t 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--; size_t prompt_len = 0; if (ed->l_cursor_y == 0) { prompt_len = prompt_length(ed, PROMPT_MAIN); } size_t 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, (int)(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, (long long)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, (long long)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, (int)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); }