summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornicm <nicm>2015-07-20 15:50:04 +0000
committernicm <nicm>2015-07-20 15:50:04 +0000
commit92af3766ecc456bd8ade8fe5746d27f4557fdaa8 (patch)
tree371174df95c9f8b2bd7e515505325853c88040d0
parentd4ce210713cc907fc69497c51cf9b64d2f414ca4 (diff)
Add an option (history-file) for a file to save/restore command prompt
history, from Olof-Joachim Frahm.
-rw-r--r--options-table.c5
-rw-r--r--server.c2
-rw-r--r--status.c91
-rw-r--r--tmux.14
-rw-r--r--tmux.c28
-rw-r--r--tmux.h3
6 files changed, 124 insertions, 9 deletions
diff --git a/options-table.c b/options-table.c
index 4ad45d37..7f75d22c 100644
--- a/options-table.c
+++ b/options-table.c
@@ -83,6 +83,11 @@ const struct options_table_entry server_options_table[] = {
.default_num = 0
},
+ { .name = "history-file",
+ .type = OPTIONS_TABLE_STRING,
+ .default_str = NULL
+ },
+
{ .name = "message-limit",
.type = OPTIONS_TABLE_NUMBER,
.minimum = 0,
diff --git a/server.c b/server.c
index 001a404c..d1c0bb3b 100644
--- a/server.c
+++ b/server.c
@@ -240,6 +240,7 @@ server_start(int lockfd, char *lockfile)
cfg_add_cause("%s: %s", cfg_file, cause);
}
cmdq_continue(cfg_cmd_q);
+ status_prompt_load_history();
server_add_accept(0);
@@ -250,6 +251,7 @@ server_start(int lockfd, char *lockfile)
set_signals(server_signal_callback);
server_loop();
+ status_prompt_save_history();
exit(0);
}
diff --git a/status.c b/status.c
index 0ffc0427..96ff8994 100644
--- a/status.c
+++ b/status.c
@@ -47,11 +47,102 @@ const char **status_prompt_complete_list(u_int *, const char *);
char *status_prompt_complete_prefix(const char **, u_int);
char *status_prompt_complete(struct session *, const char *);
+char *status_prompt_find_history_file(void);
+
/* Status prompt history. */
#define PROMPT_HISTORY 100
char **status_prompt_hlist;
u_int status_prompt_hsize;
+/* Find the history file to load/save from/to. */
+char *
+status_prompt_find_history_file(void)
+{
+ const char *home, *history_file;
+ char *path;
+
+ history_file = options_get_string(&global_options, "history-file");
+ if (*history_file == '\0')
+ return (NULL);
+ if (*history_file == '/')
+ return (xstrdup(history_file));
+
+ if (history_file[0] != '~' || history_file[1] != '/')
+ return (NULL);
+ if ((home = find_home()) == NULL)
+ return (NULL);
+ xasprintf(&path, "%s%s", home, history_file + 1);
+ return (path);
+}
+
+/* Load status prompt history from file. */
+void
+status_prompt_load_history(void)
+{
+ FILE *f;
+ char *history_file, *line, *tmp;
+ size_t length;
+
+ if ((history_file = status_prompt_find_history_file()) == NULL)
+ return;
+ log_debug("loading history from %s", history_file);
+
+ f = fopen(history_file, "r");
+ if (f == NULL) {
+ log_debug("%s: %s", history_file, strerror(errno));
+ free(history_file);
+ return;
+ }
+ free(history_file);
+
+ for (;;) {
+ if ((line = fgetln(f, &length)) == NULL)
+ break;
+
+ if (length > 0) {
+ if (line[length - 1] == '\n') {
+ line[length - 1] = '\0';
+ status_prompt_add_history(line);
+ } else {
+ tmp = xmalloc(length + 1);
+ memcpy(tmp, line, length);
+ tmp[length] = '\0';
+ status_prompt_add_history(tmp);
+ free(tmp);
+ }
+ }
+ }
+ fclose(f);
+}
+
+/* Save status prompt history to file. */
+void
+status_prompt_save_history(void)
+{
+ FILE *f;
+ u_int i;
+ char *history_file;
+
+ if ((history_file = status_prompt_find_history_file()) == NULL)
+ return;
+ log_debug("saving history to %s", history_file);
+
+ f = fopen(history_file, "w");
+ if (f == NULL) {
+ log_debug("%s: %s", history_file, strerror(errno));
+ free(history_file);
+ return;
+ }
+ free(history_file);
+
+ for (i = 0; i < status_prompt_hsize; i++) {
+ fputs(status_prompt_hlist[i], f);
+ fputc('\n', f);
+ }
+ fclose(f);
+
+}
+
/* Status output tree. */
RB_GENERATE(status_out_tree, status_out, entry, status_out_cmp);
diff --git a/tmux.1 b/tmux.1
index 69bde40a..7320df4f 100644
--- a/tmux.1
+++ b/tmux.1
@@ -2396,6 +2396,10 @@ passed through to applications running in
.Nm .
Attached clients should be detached and attached again after changing this
option.
+.It Ic history-file Ar path
+If not empty, a file to which
+.Nm
+will write command prompt history on exit and load it from on start.
.It Ic message-limit Ar number
Set the number of error or information messages to save in the message log for
each client.
diff --git a/tmux.c b/tmux.c
index 878180a7..a3481461 100644
--- a/tmux.c
+++ b/tmux.c
@@ -198,10 +198,27 @@ shell_exec(const char *shell, const char *shellcmd)
fatal("execl failed");
}
+const char*
+find_home(void)
+{
+ struct passwd *pw;
+ const char *home;
+
+ home = getenv("HOME");
+ if (home == NULL || *home == '\0') {
+ pw = getpwuid(getuid());
+ if (pw != NULL)
+ home = pw->pw_dir;
+ else
+ home = NULL;
+ }
+
+ return home;
+}
+
int
main(int argc, char **argv)
{
- struct passwd *pw;
char *s, *path, *label, **var, tmp[PATH_MAX];
char in[256];
const char *home;
@@ -320,14 +337,7 @@ main(int argc, char **argv)
/* Locate the configuration file. */
if (cfg_file == NULL) {
- home = getenv("HOME");
- if (home == NULL || *home == '\0') {
- pw = getpwuid(getuid());
- if (pw != NULL)
- home = pw->pw_dir;
- else
- home = NULL;
- }
+ home = find_home();
if (home != NULL) {
xasprintf(&cfg_file, "%s/.tmux.conf", home);
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
diff --git a/tmux.h b/tmux.h
index 3aceff9d..7edc4636 100644
--- a/tmux.h
+++ b/tmux.h
@@ -1469,6 +1469,7 @@ int checkshell(const char *);
int areshell(const char *);
void setblocking(int, int);
__dead void shell_exec(const char *, const char *);
+const char *find_home(void);
/* cfg.c */
extern struct cmd_q *cfg_cmd_q;
@@ -1943,6 +1944,8 @@ void status_prompt_clear(struct client *);
int status_prompt_redraw(struct client *);
void status_prompt_key(struct client *, int);
void status_prompt_update(struct client *, const char *, const char *);
+void status_prompt_load_history(void);
+void status_prompt_save_history(void);
/* resize.c */
void recalculate_sizes(void);