From 9cddd796ffef383893b5fd4e228f4d18673a77bd Mon Sep 17 00:00:00 2001 From: Nicholas Marriott Date: Tue, 6 Jan 2009 15:37:15 +0000 Subject: [PATCH] Prompt history. --- CHANGES | 6 ++++-- server-fn.c | 5 ++++- server.c | 18 +++++++++++++++++- status.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- tmux.h | 7 ++++++- 5 files changed, 79 insertions(+), 6 deletions(-) diff --git a/CHANGES b/CHANGES index 7bcb353f..acf1a7a2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,8 @@ 06 January 2009 -* Use a splay tree for key bindings. +* Per-client prompt history of up to 100 items. +* Use a splay tree for key bindings instead of an array. As a side-effect this + sorts them when listed. 22 December 2008 @@ -796,7 +798,7 @@ (including mutt, emacs). No status bar yet and no key remapping or other customisation. -$Id: CHANGES,v 1.177 2009-01-06 14:10:32 nicm Exp $ +$Id: CHANGES,v 1.178 2009-01-06 15:37:15 nicm Exp $ LocalWords: showw utf UTF fulvio ciriaco joshe OSC APC gettime abc DEF OA clr LocalWords: rivo nurges lscm Erdely eol smysession mysession ek dstname RB diff --git a/server-fn.c b/server-fn.c index ba3def83..c5a042ed 100644 --- a/server-fn.c +++ b/server-fn.c @@ -1,4 +1,4 @@ -/* $Id: server-fn.c,v 1.50 2008-08-28 17:45:27 nicm Exp $ */ +/* $Id: server-fn.c,v 1.51 2009-01-06 15:37:15 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -68,6 +68,8 @@ server_set_client_prompt( c->prompt_callback = fn; c->prompt_data = data; + c->prompt_hindex = 0; + c->tty.flags |= (TTY_NOCURSOR|TTY_FREEZE); c->flags |= CLIENT_STATUS; } @@ -82,6 +84,7 @@ server_clear_client_prompt(struct client *c) c->prompt_string = NULL; xfree(c->prompt_buffer); + c->prompt_buffer = NULL; c->tty.flags &= ~(TTY_NOCURSOR|TTY_FREEZE); c->flags |= CLIENT_REDRAW; diff --git a/server.c b/server.c index 1605afef..f42a3aa0 100644 --- a/server.c +++ b/server.c @@ -1,4 +1,4 @@ -/* $Id: server.c,v 1.87 2008-12-13 18:06:08 nicm Exp $ */ +/* $Id: server.c,v 1.88 2009-01-06 15:37:15 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -507,6 +507,8 @@ server_accept_client(int srv_fd) c->in = buffer_create(BUFSIZ); c->out = buffer_create(BUFSIZ); + ARRAY_INIT(&c->prompt_hdata); + c->tty.fd = -1; c->title = NULL; @@ -569,6 +571,20 @@ server_lost_client(struct client *c) tty_free(&c->tty); + if (c->title != NULL) + xfree(c->title); + + if (c->message_string != NULL) + xfree(c->message_string); + + if (c->prompt_string != NULL) + xfree(c->prompt_string); + if (c->prompt_buffer != NULL) + xfree(c->prompt_buffer); + for (i = 0; i < ARRAY_LENGTH(&c->prompt_hdata); i++) + xfree(ARRAY_ITEM(&c->prompt_hdata, i)); + ARRAY_FREE(&c->prompt_hdata); + close(c->fd); buffer_destroy(c->in); buffer_destroy(c->out); diff --git a/status.c b/status.c index d4e9cf5e..dde750aa 100644 --- a/status.c +++ b/status.c @@ -1,4 +1,4 @@ -/* $Id: status.c,v 1.52 2008-12-08 16:19:51 nicm Exp $ */ +/* $Id: status.c,v 1.53 2009-01-06 15:37:15 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -32,6 +32,8 @@ char *status_replace(struct session *, char *, time_t); size_t status_width(struct winlink *); char *status_print(struct session *, struct winlink *, struct grid_cell *); +void status_prompt_add_history(struct client *); + /* Draw status for client on the last lines of given context. */ void status_redraw(struct client *c) @@ -530,8 +532,37 @@ status_prompt_key(struct client *c, int key) c->flags |= CLIENT_STATUS; } break; + case KEYC_UP: + if (ARRAY_LENGTH(&c->prompt_hdata) == 0) + break; + xfree(c->prompt_buffer); + + c->prompt_buffer = xstrdup(ARRAY_ITEM(&c->prompt_hdata, + ARRAY_LENGTH(&c->prompt_hdata) - 1 - c->prompt_hindex)); + if (c->prompt_hindex != ARRAY_LENGTH(&c->prompt_hdata) - 1) + c->prompt_hindex++; + + c->prompt_index = strlen(c->prompt_buffer); + c->flags |= CLIENT_STATUS; + break; + case KEYC_DOWN: + xfree(c->prompt_buffer); + + if (c->prompt_hindex != 0) { + c->prompt_hindex--; + c->prompt_buffer = xstrdup(ARRAY_ITEM( + &c->prompt_hdata, ARRAY_LENGTH( + &c->prompt_hdata) - 1 - c->prompt_hindex)); + } else + c->prompt_buffer = xstrdup(""); + + c->prompt_index = strlen(c->prompt_buffer); + c->flags |= CLIENT_STATUS; + break; case '\r': /* enter */ if (*c->prompt_buffer != '\0') { + status_prompt_add_history(c); + c->prompt_callback(c->prompt_data, c->prompt_buffer); server_clear_client_prompt(c); break; @@ -560,3 +591,19 @@ status_prompt_key(struct client *c, int key) break; } } + +/* Add line to the history. */ +void +status_prompt_add_history(struct client *c) +{ + if (ARRAY_LENGTH(&c->prompt_hdata) > 0 && + strcmp(ARRAY_LAST(&c->prompt_hdata), c->prompt_buffer) == 0) + return; + + if (ARRAY_LENGTH(&c->prompt_hdata) == PROMPT_HISTORY) { + xfree(ARRAY_FIRST(&c->prompt_hdata)); + ARRAY_REMOVE(&c->prompt_hdata, 0); + } + + ARRAY_ADD(&c->prompt_hdata, xstrdup(c->prompt_buffer)); +} diff --git a/tmux.h b/tmux.h index 9ade8c65..8f891079 100644 --- a/tmux.h +++ b/tmux.h @@ -1,4 +1,4 @@ -/* $Id: tmux.h,v 1.205 2009-01-06 14:10:32 nicm Exp $ */ +/* $Id: tmux.h,v 1.206 2009-01-06 15:37:15 nicm Exp $ */ /* * Copyright (c) 2007 Nicholas Marriott @@ -119,6 +119,9 @@ extern const char *__progname; /* Default configuration file. */ #define DEFAULT_CFG ".tmux.conf" +/* Default prompt history length. */ +#define PROMPT_HISTORY 100 + /* Fatal errors. */ #define fatal(msg) log_fatal("%s: %s", __func__, msg); #define fatalx(msg) log_fatalx("%s: %s", __func__, msg); @@ -745,6 +748,8 @@ struct client { size_t prompt_index; void (*prompt_callback)(void *, char *); void *prompt_data; + u_int prompt_hindex; + ARRAY_DECL(, char *) prompt_hdata; struct session *session; };