#include "readline.h" #include "shell.h" #include #include /* memmove */ #include void readline_create_array(struct readline_type *readline) { readline->arr = calloc(initial_size, 1); readline->cursor_pos = 0; readline->last_element_index = -1; readline->considered_index = 0; readline->allocation_size = initial_size; } static void readline_copy_array(struct readline_type *readline, char *new_arr) { int i; for(i = 0; i <= readline->last_element_index; ++i) new_arr[i] = readline->arr[i]; } static void readline_allocate_memory(struct readline_type *readline) { char *new_arr = calloc(readline->allocation_size * 2, 1); readline_copy_array(readline, new_arr); free(readline->arr); readline->arr = new_arr; readline->allocation_size *= 2; } static void readline_reprint_modified_part(struct readline_type *readline, int begin_idx) { int i, counter; for(i = begin_idx, counter = 0; i <= readline->last_element_index; ++i, ++counter) putchar(readline->arr[i]); /* return cursor to previous position */ for( ; counter != 0; --counter) putchar('\b'); fflush(stdout); } void readline_add_char(struct readline_type *readline, int ch) { char *begin_arr; int size; if(readline->last_element_index+1 == readline->allocation_size) readline_allocate_memory(readline); /* insert in middle position */ if(readline->cursor_pos - 1 != readline->last_element_index) { begin_arr = readline->arr + readline->cursor_pos; size = readline->last_element_index - readline->cursor_pos + 1; memmove(begin_arr+1, begin_arr, size); readline->arr[readline->cursor_pos] = ch; ++readline->last_element_index; readline_reprint_modified_part(readline, readline->cursor_pos + 1); } else { ++readline->last_element_index; readline->arr[readline->last_element_index] = ch; } ++readline->cursor_pos; } void readline_reset_array(struct readline_type *readline) { readline->last_element_index = -1; readline->cursor_pos = 0; } void readline_clear(struct readline_type *readline) { free(readline->arr); readline->arr = NULL; } void readline_print(struct readline_type *readline) { int i; for(i = 0; i <= readline->last_element_index; ++i) putchar(readline->arr[i]); readline->cursor_pos = readline->last_element_index + 1; fflush(stdout); } enum keys readline_detect_arrow_keys(int ch) { char next_ch; if(ch == esc) { next_ch = getchar(); if(next_ch != '[') return unknown_key; next_ch = getchar(); switch(next_ch) { case left_arrow: return left_arrow; case right_arrow: return right_arrow; case up_arrow: return up_arrow; case down_arrow: return down_arrow; default: return unknown_key; } } return none; } void readline_move_along(struct readline_type *readline, enum keys found_key) { switch(found_key) { case left_arrow: if(readline->cursor_pos > 0) { putchar('\b'); fflush(stdout); --readline->cursor_pos; } break; case right_arrow: if(readline->cursor_pos <= readline->last_element_index) { putchar(readline->arr[readline->cursor_pos]); fflush(stdout); ++readline->cursor_pos; } break; default: ; } } void readline_character_deletion(struct readline_type *readline) { char *begin_arr; int size; if(readline->cursor_pos > 0) { putchar('\b'); fflush(stdout); begin_arr = readline->arr + readline->cursor_pos; size = readline->last_element_index - readline->cursor_pos + 1; memmove(begin_arr-1, begin_arr, size); readline->arr[readline->last_element_index] = ' '; readline_reprint_modified_part(readline, readline->cursor_pos - 1); --readline->last_element_index; --readline->cursor_pos; } }