Add an option (history-file) for a file to save/restore command prompt

history, from Olof-Joachim Frahm.
This commit is contained in:
nicm 2015-07-20 15:50:04 +00:00
parent d4ce210713
commit 92af3766ec
6 changed files with 124 additions and 9 deletions

View File

@ -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,

View File

@ -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);
}

View File

@ -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);

4
tmux.1
View File

@ -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.

28
tmux.c
View File

@ -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) {

3
tmux.h
View File

@ -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);