mirror of
https://github.com/tmux/tmux.git
synced 2024-11-04 18:08:48 +00:00
Add an option (history-file) for a file to save/restore command prompt
history, from Olof-Joachim Frahm.
This commit is contained in:
parent
d4ce210713
commit
92af3766ec
@ -83,6 +83,11 @@ const struct options_table_entry server_options_table[] = {
|
|||||||
.default_num = 0
|
.default_num = 0
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "history-file",
|
||||||
|
.type = OPTIONS_TABLE_STRING,
|
||||||
|
.default_str = NULL
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "message-limit",
|
{ .name = "message-limit",
|
||||||
.type = OPTIONS_TABLE_NUMBER,
|
.type = OPTIONS_TABLE_NUMBER,
|
||||||
.minimum = 0,
|
.minimum = 0,
|
||||||
|
2
server.c
2
server.c
@ -240,6 +240,7 @@ server_start(int lockfd, char *lockfile)
|
|||||||
cfg_add_cause("%s: %s", cfg_file, cause);
|
cfg_add_cause("%s: %s", cfg_file, cause);
|
||||||
}
|
}
|
||||||
cmdq_continue(cfg_cmd_q);
|
cmdq_continue(cfg_cmd_q);
|
||||||
|
status_prompt_load_history();
|
||||||
|
|
||||||
server_add_accept(0);
|
server_add_accept(0);
|
||||||
|
|
||||||
@ -250,6 +251,7 @@ server_start(int lockfd, char *lockfile)
|
|||||||
|
|
||||||
set_signals(server_signal_callback);
|
set_signals(server_signal_callback);
|
||||||
server_loop();
|
server_loop();
|
||||||
|
status_prompt_save_history();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
91
status.c
91
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_prefix(const char **, u_int);
|
||||||
char *status_prompt_complete(struct session *, const char *);
|
char *status_prompt_complete(struct session *, const char *);
|
||||||
|
|
||||||
|
char *status_prompt_find_history_file(void);
|
||||||
|
|
||||||
/* Status prompt history. */
|
/* Status prompt history. */
|
||||||
#define PROMPT_HISTORY 100
|
#define PROMPT_HISTORY 100
|
||||||
char **status_prompt_hlist;
|
char **status_prompt_hlist;
|
||||||
u_int status_prompt_hsize;
|
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. */
|
/* Status output tree. */
|
||||||
RB_GENERATE(status_out_tree, status_out, entry, status_out_cmp);
|
RB_GENERATE(status_out_tree, status_out, entry, status_out_cmp);
|
||||||
|
|
||||||
|
4
tmux.1
4
tmux.1
@ -2396,6 +2396,10 @@ passed through to applications running in
|
|||||||
.Nm .
|
.Nm .
|
||||||
Attached clients should be detached and attached again after changing this
|
Attached clients should be detached and attached again after changing this
|
||||||
option.
|
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
|
.It Ic message-limit Ar number
|
||||||
Set the number of error or information messages to save in the message log for
|
Set the number of error or information messages to save in the message log for
|
||||||
each client.
|
each client.
|
||||||
|
28
tmux.c
28
tmux.c
@ -198,10 +198,27 @@ shell_exec(const char *shell, const char *shellcmd)
|
|||||||
fatal("execl failed");
|
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
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct passwd *pw;
|
|
||||||
char *s, *path, *label, **var, tmp[PATH_MAX];
|
char *s, *path, *label, **var, tmp[PATH_MAX];
|
||||||
char in[256];
|
char in[256];
|
||||||
const char *home;
|
const char *home;
|
||||||
@ -320,14 +337,7 @@ main(int argc, char **argv)
|
|||||||
|
|
||||||
/* Locate the configuration file. */
|
/* Locate the configuration file. */
|
||||||
if (cfg_file == NULL) {
|
if (cfg_file == NULL) {
|
||||||
home = getenv("HOME");
|
home = find_home();
|
||||||
if (home == NULL || *home == '\0') {
|
|
||||||
pw = getpwuid(getuid());
|
|
||||||
if (pw != NULL)
|
|
||||||
home = pw->pw_dir;
|
|
||||||
else
|
|
||||||
home = NULL;
|
|
||||||
}
|
|
||||||
if (home != NULL) {
|
if (home != NULL) {
|
||||||
xasprintf(&cfg_file, "%s/.tmux.conf", home);
|
xasprintf(&cfg_file, "%s/.tmux.conf", home);
|
||||||
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
|
if (access(cfg_file, R_OK) != 0 && errno == ENOENT) {
|
||||||
|
3
tmux.h
3
tmux.h
@ -1469,6 +1469,7 @@ int checkshell(const char *);
|
|||||||
int areshell(const char *);
|
int areshell(const char *);
|
||||||
void setblocking(int, int);
|
void setblocking(int, int);
|
||||||
__dead void shell_exec(const char *, const char *);
|
__dead void shell_exec(const char *, const char *);
|
||||||
|
const char *find_home(void);
|
||||||
|
|
||||||
/* cfg.c */
|
/* cfg.c */
|
||||||
extern struct cmd_q *cfg_cmd_q;
|
extern struct cmd_q *cfg_cmd_q;
|
||||||
@ -1943,6 +1944,8 @@ void status_prompt_clear(struct client *);
|
|||||||
int status_prompt_redraw(struct client *);
|
int status_prompt_redraw(struct client *);
|
||||||
void status_prompt_key(struct client *, int);
|
void status_prompt_key(struct client *, int);
|
||||||
void status_prompt_update(struct client *, const char *, const char *);
|
void status_prompt_update(struct client *, const char *, const char *);
|
||||||
|
void status_prompt_load_history(void);
|
||||||
|
void status_prompt_save_history(void);
|
||||||
|
|
||||||
/* resize.c */
|
/* resize.c */
|
||||||
void recalculate_sizes(void);
|
void recalculate_sizes(void);
|
||||||
|
Loading…
Reference in New Issue
Block a user