summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2021-04-16 16:25:03 -0400
committerLeo Tenenbaum <pommicket@gmail.com>2021-04-16 16:25:03 -0400
commitd76fb30c7f8e073dd17180752dbd56dfa62511d3 (patch)
tree9bd5ad978a54e00f6539fdb7d5f5d23e2aefeac5
parent51ac447d409bb565178ab9d78d4b5200e89f2cf4 (diff)
command history for :shell
-rw-r--r--command.c4
-rw-r--r--main.c5
-rw-r--r--menu.c37
-rw-r--r--ted.h2
4 files changed, 47 insertions, 1 deletions
diff --git a/command.c b/command.c
index c28bce5..b706b2d 100644
--- a/command.c
+++ b/command.c
@@ -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:
diff --git a/main.c b/main.c
index ff118cc..3a1b686 100644
--- a/main.c
+++ b/main.c
@@ -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);
diff --git a/menu.c b/menu.c
index aff805a..d363b37 100644
--- a/menu.c
+++ b/menu.c
@@ -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);
+}
diff --git a/ted.h b/ted.h
index d0632cc..5410398 100644
--- a/ted.h
+++ b/ted.h
@@ -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;