diff options
-rw-r--r-- | command.c | 4 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | menu.c | 37 | ||||
-rw-r--r-- | ted.h | 2 |
4 files changed, 47 insertions, 1 deletions
@@ -50,10 +50,14 @@ void command_execute(Ted *ted, Command c, i64 argument) { break; case CMD_UP: if (ted->selector_open) selector_up(ted, ted->selector_open, argument); + else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) + menu_shell_up(ted); else if (buffer) buffer_cursor_move_up(buffer, argument); break; case CMD_DOWN: if (ted->selector_open) selector_down(ted, ted->selector_open, argument); + else if (ted->menu == MENU_SHELL && buffer == &ted->line_buffer) + menu_shell_down(ted); else if (buffer) buffer_cursor_move_down(buffer, argument); break; case CMD_SELECT_LEFT: @@ -951,6 +951,11 @@ int main(int argc, char **argv) { } session_write(ted); + + arr_foreach_ptr(ted->shell_history, char *, cmd) { + free(*cmd); + } + arr_free(ted->shell_history); SDL_FreeCursor(ted->cursor_arrow); SDL_FreeCursor(ted->cursor_ibeam); @@ -85,6 +85,7 @@ static void menu_open(Ted *ted, Menu menu) { } break; case MENU_SHELL: ted_switch_to_buffer(ted, &ted->line_buffer); + ted->shell_history_pos = arr_len(ted->shell_history); break; } } @@ -298,10 +299,12 @@ static void menu_update(Ted *ted) { case MENU_SHELL: if (line_buffer->line_buffer_submitted) { char *command = str32_to_utf8_cstr(buffer_get_line(line_buffer, 0)); + if (ted->shell_history_pos == arr_len(ted->shell_history) || line_buffer->modified) { + arr_add(ted->shell_history, command); + } menu_close(ted); strbuf_cpy(ted->build_dir, ted->cwd); build_start_with_command(ted, command); - free(command); } break; } @@ -442,3 +445,35 @@ static void menu_render(Ted *ted) { } break; } } + +// move to next/previous command +static void menu_shell_move(Ted *ted, int direction) { + TextBuffer *line_buffer = &ted->line_buffer; + if (line_buffer->modified) { + // don't do it if the command has been edited + return; + } + i64 pos = ted->shell_history_pos; + pos += direction; + if (pos >= 0 && pos <= arr_len(ted->shell_history)) { + ted->shell_history_pos = (u32)pos; + buffer_clear(line_buffer); + if (pos == arr_len(ted->shell_history)) { + // bottom of history; just clear line buffer + } else { + line_buffer->store_undo_events = false; + buffer_insert_utf8_at_cursor(line_buffer, ted->shell_history[pos]); + line_buffer->store_undo_events = true; + line_buffer->modified = false; + } + // line_buffer->x/y1/2 are wrong (all 0), because of buffer_clear + line_buffer->center_cursor_next_frame = true; + } +} + +static void menu_shell_up(Ted *ted) { + menu_shell_move(ted, -1); +} +static void menu_shell_down(Ted *ted) { + menu_shell_move(ted, +1); +} @@ -308,6 +308,8 @@ typedef struct Ted { Node *resizing_split; char **tag_selector_entries; // an array of all tags (see tag_selector_open) + char **shell_history; // dynamic array of history of commands run with :shell (UTF-8) + u32 shell_history_pos; // for keeping track of where we are in the shell history. // points to a selector if any is open, otherwise NULL. Selector *selector_open; |