mirror of
https://github.com/tmux/tmux.git
synced 2025-01-07 16:28:48 +00:00
Add different command historys for different types of prompts
("command", "search" etc). From Anindya Mukherjee.
This commit is contained in:
parent
6c659494f5
commit
866117636e
1
Makefile
1
Makefile
@ -61,6 +61,7 @@ SRCS= alerts.c \
|
|||||||
cmd-show-environment.c \
|
cmd-show-environment.c \
|
||||||
cmd-show-messages.c \
|
cmd-show-messages.c \
|
||||||
cmd-show-options.c \
|
cmd-show-options.c \
|
||||||
|
cmd-show-prompt-history.c \
|
||||||
cmd-source-file.c \
|
cmd-source-file.c \
|
||||||
cmd-split-window.c \
|
cmd-split-window.c \
|
||||||
cmd-swap-pane.c \
|
cmd-swap-pane.c \
|
||||||
|
@ -40,25 +40,26 @@ const struct cmd_entry cmd_command_prompt_entry = {
|
|||||||
.name = "command-prompt",
|
.name = "command-prompt",
|
||||||
.alias = NULL,
|
.alias = NULL,
|
||||||
|
|
||||||
.args = { "1kiI:Np:Tt:W", 0, 1 },
|
.args = { "1kiI:Np:t:T:", 0, 1 },
|
||||||
.usage = "[-1kiNTW] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE " "
|
.usage = "[-1kiN] [-I inputs] [-p prompts] " CMD_TARGET_CLIENT_USAGE
|
||||||
"[template]",
|
" [-T type] [template]",
|
||||||
|
|
||||||
.flags = CMD_CLIENT_TFLAG,
|
.flags = CMD_CLIENT_TFLAG,
|
||||||
.exec = cmd_command_prompt_exec
|
.exec = cmd_command_prompt_exec
|
||||||
};
|
};
|
||||||
|
|
||||||
struct cmd_command_prompt_cdata {
|
struct cmd_command_prompt_cdata {
|
||||||
int flags;
|
int flags;
|
||||||
|
enum prompt_type prompt_type;
|
||||||
|
|
||||||
char *inputs;
|
char *inputs;
|
||||||
char *next_input;
|
char *next_input;
|
||||||
|
|
||||||
char *prompts;
|
char *prompts;
|
||||||
char *next_prompt;
|
char *next_prompt;
|
||||||
|
|
||||||
char *template;
|
char *template;
|
||||||
int idx;
|
int idx;
|
||||||
};
|
};
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
@ -67,7 +68,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
struct args *args = cmd_get_args(self);
|
struct args *args = cmd_get_args(self);
|
||||||
struct client *tc = cmdq_get_target_client(item);
|
struct client *tc = cmdq_get_target_client(item);
|
||||||
struct cmd_find_state *target = cmdq_get_target(item);
|
struct cmd_find_state *target = cmdq_get_target(item);
|
||||||
const char *inputs, *prompts;
|
const char *inputs, *prompts, *type;
|
||||||
struct cmd_command_prompt_cdata *cdata;
|
struct cmd_command_prompt_cdata *cdata;
|
||||||
char *prompt, *ptr, *input = NULL;
|
char *prompt, *ptr, *input = NULL;
|
||||||
size_t n;
|
size_t n;
|
||||||
@ -114,6 +115,16 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
input = strsep(&cdata->next_input, ",");
|
input = strsep(&cdata->next_input, ",");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get prompt type. */
|
||||||
|
if ((type = args_get(args, 'T')) != NULL) {
|
||||||
|
cdata->prompt_type = status_prompt_type(type);
|
||||||
|
if (cdata->prompt_type == PROMPT_TYPE_INVALID) {
|
||||||
|
cmdq_error(item, "unknown type: %s", type);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
cdata->prompt_type = PROMPT_TYPE_COMMAND;
|
||||||
|
|
||||||
if (args_has(args, '1'))
|
if (args_has(args, '1'))
|
||||||
cdata->flags |= PROMPT_SINGLE;
|
cdata->flags |= PROMPT_SINGLE;
|
||||||
else if (args_has(args, 'N'))
|
else if (args_has(args, 'N'))
|
||||||
@ -122,13 +133,9 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cdata->flags |= PROMPT_INCREMENTAL;
|
cdata->flags |= PROMPT_INCREMENTAL;
|
||||||
else if (args_has(args, 'k'))
|
else if (args_has(args, 'k'))
|
||||||
cdata->flags |= PROMPT_KEY;
|
cdata->flags |= PROMPT_KEY;
|
||||||
else if (args_has(args, 'W'))
|
|
||||||
cdata->flags |= PROMPT_WINDOW;
|
|
||||||
else if (args_has(args, 'T'))
|
|
||||||
cdata->flags |= PROMPT_TARGET;
|
|
||||||
status_prompt_set(tc, target, prompt, input,
|
status_prompt_set(tc, target, prompt, input,
|
||||||
cmd_command_prompt_callback, cmd_command_prompt_free, cdata,
|
cmd_command_prompt_callback, cmd_command_prompt_free, cdata,
|
||||||
cdata->flags);
|
cdata->flags, cdata->prompt_type);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
|
@ -74,7 +74,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
status_prompt_set(tc, target, new_prompt, NULL,
|
status_prompt_set(tc, target, new_prompt, NULL,
|
||||||
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
|
cmd_confirm_before_callback, cmd_confirm_before_free, cdata,
|
||||||
PROMPT_SINGLE);
|
PROMPT_SINGLE, PROMPT_TYPE_COMMAND);
|
||||||
|
|
||||||
free(new_prompt);
|
free(new_prompt);
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
|
108
cmd-show-prompt-history.c
Normal file
108
cmd-show-prompt-history.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/* $OpenBSD$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Anindya Mukherjee <anindya49@hotmail.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||||
|
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "tmux.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Show or clear prompt history.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static enum cmd_retval cmd_show_prompt_history_exec(struct cmd *,
|
||||||
|
struct cmdq_item *);
|
||||||
|
|
||||||
|
const struct cmd_entry cmd_show_prompt_history_entry = {
|
||||||
|
.name = "show-prompt-history",
|
||||||
|
.alias = "showphist",
|
||||||
|
|
||||||
|
.args = { "T:", 0, 0 },
|
||||||
|
.usage = "[-T type]",
|
||||||
|
|
||||||
|
.flags = CMD_AFTERHOOK,
|
||||||
|
.exec = cmd_show_prompt_history_exec
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct cmd_entry cmd_clear_prompt_history_entry = {
|
||||||
|
.name = "clear-prompt-history",
|
||||||
|
.alias = "clearphist",
|
||||||
|
|
||||||
|
.args = { "T:", 0, 0 },
|
||||||
|
.usage = "[-T type]",
|
||||||
|
|
||||||
|
.flags = CMD_AFTERHOOK,
|
||||||
|
.exec = cmd_show_prompt_history_exec
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum cmd_retval
|
||||||
|
cmd_show_prompt_history_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
|
{
|
||||||
|
struct args *args = cmd_get_args(self);
|
||||||
|
const char *typestr = args_get(args, 'T');
|
||||||
|
enum prompt_type type;
|
||||||
|
u_int tidx, hidx;
|
||||||
|
|
||||||
|
if (cmd_get_entry(self) == &cmd_clear_prompt_history_entry) {
|
||||||
|
if (typestr == NULL) {
|
||||||
|
for (tidx = 0; tidx < PROMPT_NTYPES; tidx++) {
|
||||||
|
free(status_prompt_hlist[tidx]);
|
||||||
|
status_prompt_hlist[tidx] = NULL;
|
||||||
|
status_prompt_hsize[tidx] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = status_prompt_type(typestr);
|
||||||
|
if (type == PROMPT_TYPE_INVALID) {
|
||||||
|
cmdq_error(item, "invalid type: %s", typestr);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
free(status_prompt_hlist[type]);
|
||||||
|
status_prompt_hlist[type] = NULL;
|
||||||
|
status_prompt_hsize[type] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typestr == NULL) {
|
||||||
|
for (tidx = 0; tidx < PROMPT_NTYPES; tidx++) {
|
||||||
|
cmdq_print(item, "History for %s:\n",
|
||||||
|
status_prompt_type_string(tidx));
|
||||||
|
for (hidx = 0; hidx < status_prompt_hsize[tidx];
|
||||||
|
hidx++) {
|
||||||
|
cmdq_print(item, "%d: %s", hidx + 1,
|
||||||
|
status_prompt_hlist[tidx][hidx]);
|
||||||
|
}
|
||||||
|
cmdq_print(item, "%s", "");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
type = status_prompt_type(typestr);
|
||||||
|
if (type == PROMPT_TYPE_INVALID) {
|
||||||
|
cmdq_error(item, "invalid type: %s", typestr);
|
||||||
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
cmdq_print(item, "History for %s:\n",
|
||||||
|
status_prompt_type_string(type));
|
||||||
|
for (hidx = 0; hidx < status_prompt_hsize[type]; hidx++) {
|
||||||
|
cmdq_print(item, "%d: %s", hidx + 1,
|
||||||
|
status_prompt_hlist[type][hidx]);
|
||||||
|
}
|
||||||
|
cmdq_print(item, "%s", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
return (CMD_RETURN_NORMAL);
|
||||||
|
}
|
4
cmd.c
4
cmd.c
@ -36,6 +36,7 @@ extern const struct cmd_entry cmd_choose_buffer_entry;
|
|||||||
extern const struct cmd_entry cmd_choose_client_entry;
|
extern const struct cmd_entry cmd_choose_client_entry;
|
||||||
extern const struct cmd_entry cmd_choose_tree_entry;
|
extern const struct cmd_entry cmd_choose_tree_entry;
|
||||||
extern const struct cmd_entry cmd_clear_history_entry;
|
extern const struct cmd_entry cmd_clear_history_entry;
|
||||||
|
extern const struct cmd_entry cmd_clear_prompt_history_entry;
|
||||||
extern const struct cmd_entry cmd_clock_mode_entry;
|
extern const struct cmd_entry cmd_clock_mode_entry;
|
||||||
extern const struct cmd_entry cmd_command_prompt_entry;
|
extern const struct cmd_entry cmd_command_prompt_entry;
|
||||||
extern const struct cmd_entry cmd_confirm_before_entry;
|
extern const struct cmd_entry cmd_confirm_before_entry;
|
||||||
@ -105,6 +106,7 @@ extern const struct cmd_entry cmd_show_environment_entry;
|
|||||||
extern const struct cmd_entry cmd_show_hooks_entry;
|
extern const struct cmd_entry cmd_show_hooks_entry;
|
||||||
extern const struct cmd_entry cmd_show_messages_entry;
|
extern const struct cmd_entry cmd_show_messages_entry;
|
||||||
extern const struct cmd_entry cmd_show_options_entry;
|
extern const struct cmd_entry cmd_show_options_entry;
|
||||||
|
extern const struct cmd_entry cmd_show_prompt_history_entry;
|
||||||
extern const struct cmd_entry cmd_show_window_options_entry;
|
extern const struct cmd_entry cmd_show_window_options_entry;
|
||||||
extern const struct cmd_entry cmd_source_file_entry;
|
extern const struct cmd_entry cmd_source_file_entry;
|
||||||
extern const struct cmd_entry cmd_split_window_entry;
|
extern const struct cmd_entry cmd_split_window_entry;
|
||||||
@ -127,6 +129,7 @@ const struct cmd_entry *cmd_table[] = {
|
|||||||
&cmd_choose_client_entry,
|
&cmd_choose_client_entry,
|
||||||
&cmd_choose_tree_entry,
|
&cmd_choose_tree_entry,
|
||||||
&cmd_clear_history_entry,
|
&cmd_clear_history_entry,
|
||||||
|
&cmd_clear_prompt_history_entry,
|
||||||
&cmd_clock_mode_entry,
|
&cmd_clock_mode_entry,
|
||||||
&cmd_command_prompt_entry,
|
&cmd_command_prompt_entry,
|
||||||
&cmd_confirm_before_entry,
|
&cmd_confirm_before_entry,
|
||||||
@ -195,6 +198,7 @@ const struct cmd_entry *cmd_table[] = {
|
|||||||
&cmd_show_hooks_entry,
|
&cmd_show_hooks_entry,
|
||||||
&cmd_show_messages_entry,
|
&cmd_show_messages_entry,
|
||||||
&cmd_show_options_entry,
|
&cmd_show_options_entry,
|
||||||
|
&cmd_show_prompt_history_entry,
|
||||||
&cmd_show_window_options_entry,
|
&cmd_show_window_options_entry,
|
||||||
&cmd_source_file_entry,
|
&cmd_source_file_entry,
|
||||||
&cmd_split_window_entry,
|
&cmd_split_window_entry,
|
||||||
|
@ -350,12 +350,12 @@ key_bindings_init(void)
|
|||||||
"bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
|
"bind -N 'Rename current session' '$' command-prompt -I'#S' \"rename-session -- '%%'\"",
|
||||||
"bind -N 'Split window horizontally' % split-window -h",
|
"bind -N 'Split window horizontally' % split-window -h",
|
||||||
"bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
|
"bind -N 'Kill current window' & confirm-before -p\"kill-window #W? (y/n)\" kill-window",
|
||||||
"bind -N 'Prompt for window index to select' \"'\" command-prompt -Wpindex \"select-window -t ':%%'\"",
|
"bind -N 'Prompt for window index to select' \"'\" command-prompt -T window-target -pindex \"select-window -t ':%%'\"",
|
||||||
"bind -N 'Switch to previous client' ( switch-client -p",
|
"bind -N 'Switch to previous client' ( switch-client -p",
|
||||||
"bind -N 'Switch to next client' ) switch-client -n",
|
"bind -N 'Switch to next client' ) switch-client -n",
|
||||||
"bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"",
|
"bind -N 'Rename current window' , command-prompt -I'#W' \"rename-window -- '%%'\"",
|
||||||
"bind -N 'Delete the most recent paste buffer' - delete-buffer",
|
"bind -N 'Delete the most recent paste buffer' - delete-buffer",
|
||||||
"bind -N 'Move the current window' . command-prompt -T \"move-window -t '%%'\"",
|
"bind -N 'Move the current window' . command-prompt -T target \"move-window -t '%%'\"",
|
||||||
"bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'",
|
"bind -N 'Describe key binding' '/' command-prompt -kpkey 'list-keys -1N \"%%%\"'",
|
||||||
"bind -N 'Select window 0' 0 select-window -t:=0",
|
"bind -N 'Select window 0' 0 select-window -t:=0",
|
||||||
"bind -N 'Select window 1' 1 select-window -t:=1",
|
"bind -N 'Select window 1' 1 select-window -t:=1",
|
||||||
@ -479,8 +479,8 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode C-k send -X copy-end-of-line",
|
"bind -Tcopy-mode C-k send -X copy-end-of-line",
|
||||||
"bind -Tcopy-mode C-n send -X cursor-down",
|
"bind -Tcopy-mode C-n send -X cursor-down",
|
||||||
"bind -Tcopy-mode C-p send -X cursor-up",
|
"bind -Tcopy-mode C-p send -X cursor-up",
|
||||||
"bind -Tcopy-mode C-r command-prompt -ip'(search up)' -I'#{pane_search_string}' 'send -X search-backward-incremental \"%%%\"'",
|
"bind -Tcopy-mode C-r command-prompt -T search -ip'(search up)' -I'#{pane_search_string}' 'send -X search-backward-incremental \"%%%\"'",
|
||||||
"bind -Tcopy-mode C-s command-prompt -ip'(search down)' -I'#{pane_search_string}' 'send -X search-forward-incremental \"%%%\"'",
|
"bind -Tcopy-mode C-s command-prompt -T search -ip'(search down)' -I'#{pane_search_string}' 'send -X search-forward-incremental \"%%%\"'",
|
||||||
"bind -Tcopy-mode C-v send -X page-down",
|
"bind -Tcopy-mode C-v send -X page-down",
|
||||||
"bind -Tcopy-mode C-w send -X copy-pipe-and-cancel",
|
"bind -Tcopy-mode C-w send -X copy-pipe-and-cancel",
|
||||||
"bind -Tcopy-mode Escape send -X cancel",
|
"bind -Tcopy-mode Escape send -X cancel",
|
||||||
@ -559,7 +559,7 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode-vi Space send -X begin-selection",
|
"bind -Tcopy-mode-vi Space send -X begin-selection",
|
||||||
"bind -Tcopy-mode-vi '$' send -X end-of-line",
|
"bind -Tcopy-mode-vi '$' send -X end-of-line",
|
||||||
"bind -Tcopy-mode-vi , send -X jump-reverse",
|
"bind -Tcopy-mode-vi , send -X jump-reverse",
|
||||||
"bind -Tcopy-mode-vi / command-prompt -p'(search down)' 'send -X search-forward \"%%%\"'",
|
"bind -Tcopy-mode-vi / command-prompt -T search -p'(search down)' 'send -X search-forward \"%%%\"'",
|
||||||
"bind -Tcopy-mode-vi 0 send -X start-of-line",
|
"bind -Tcopy-mode-vi 0 send -X start-of-line",
|
||||||
"bind -Tcopy-mode-vi 1 command-prompt -Np'(repeat)' -I1 'send -N \"%%%\"'",
|
"bind -Tcopy-mode-vi 1 command-prompt -Np'(repeat)' -I1 'send -N \"%%%\"'",
|
||||||
"bind -Tcopy-mode-vi 2 command-prompt -Np'(repeat)' -I2 'send -N \"%%%\"'",
|
"bind -Tcopy-mode-vi 2 command-prompt -Np'(repeat)' -I2 'send -N \"%%%\"'",
|
||||||
@ -572,7 +572,7 @@ key_bindings_init(void)
|
|||||||
"bind -Tcopy-mode-vi 9 command-prompt -Np'(repeat)' -I9 'send -N \"%%%\"'",
|
"bind -Tcopy-mode-vi 9 command-prompt -Np'(repeat)' -I9 'send -N \"%%%\"'",
|
||||||
"bind -Tcopy-mode-vi : command-prompt -p'(goto line)' 'send -X goto-line \"%%%\"'",
|
"bind -Tcopy-mode-vi : command-prompt -p'(goto line)' 'send -X goto-line \"%%%\"'",
|
||||||
"bind -Tcopy-mode-vi \\; send -X jump-again",
|
"bind -Tcopy-mode-vi \\; send -X jump-again",
|
||||||
"bind -Tcopy-mode-vi ? command-prompt -p'(search up)' 'send -X search-backward \"%%%\"'",
|
"bind -Tcopy-mode-vi ? command-prompt -T search -p'(search up)' 'send -X search-backward \"%%%\"'",
|
||||||
"bind -Tcopy-mode-vi A send -X append-selection-and-cancel",
|
"bind -Tcopy-mode-vi A send -X append-selection-and-cancel",
|
||||||
"bind -Tcopy-mode-vi B send -X previous-space",
|
"bind -Tcopy-mode-vi B send -X previous-space",
|
||||||
"bind -Tcopy-mode-vi D send -X copy-end-of-line",
|
"bind -Tcopy-mode-vi D send -X copy-end-of-line",
|
||||||
|
@ -1168,7 +1168,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
mtd->references++;
|
mtd->references++;
|
||||||
status_prompt_set(c, NULL, "(search) ", "",
|
status_prompt_set(c, NULL, "(search) ", "",
|
||||||
mode_tree_search_callback, mode_tree_search_free, mtd,
|
mode_tree_search_callback, mode_tree_search_free, mtd,
|
||||||
PROMPT_NOFORMAT);
|
PROMPT_NOFORMAT, PROMPT_TYPE_SEARCH);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
mode_tree_search_set(mtd);
|
mode_tree_search_set(mtd);
|
||||||
@ -1177,7 +1177,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
mtd->references++;
|
mtd->references++;
|
||||||
status_prompt_set(c, NULL, "(filter) ", mtd->filter,
|
status_prompt_set(c, NULL, "(filter) ", mtd->filter,
|
||||||
mode_tree_filter_callback, mode_tree_filter_free, mtd,
|
mode_tree_filter_callback, mode_tree_filter_free, mtd,
|
||||||
PROMPT_NOFORMAT);
|
PROMPT_NOFORMAT, PROMPT_TYPE_SEARCH);
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
mtd->preview = !mtd->preview;
|
mtd->preview = !mtd->preview;
|
||||||
|
@ -302,6 +302,15 @@ const struct options_table_entry options_table[] = {
|
|||||||
.text = "Maximum number of server messages to keep."
|
.text = "Maximum number of server messages to keep."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "prompt-history-limit",
|
||||||
|
.type = OPTIONS_TABLE_NUMBER,
|
||||||
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
.minimum = 0,
|
||||||
|
.maximum = INT_MAX,
|
||||||
|
.default_num = 100,
|
||||||
|
.text = "Maximum number of commands to keep in history."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "set-clipboard",
|
{ .name = "set-clipboard",
|
||||||
.type = OPTIONS_TABLE_CHOICE,
|
.type = OPTIONS_TABLE_CHOICE,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
184
status.c
184
status.c
@ -33,9 +33,9 @@ static void status_message_callback(int, short, void *);
|
|||||||
static void status_timer_callback(int, short, void *);
|
static void status_timer_callback(int, short, void *);
|
||||||
|
|
||||||
static char *status_prompt_find_history_file(void);
|
static char *status_prompt_find_history_file(void);
|
||||||
static const char *status_prompt_up_history(u_int *);
|
static const char *status_prompt_up_history(u_int *, u_int);
|
||||||
static const char *status_prompt_down_history(u_int *);
|
static const char *status_prompt_down_history(u_int *, u_int);
|
||||||
static void status_prompt_add_history(const char *);
|
static void status_prompt_add_history(const char *, u_int);
|
||||||
|
|
||||||
static char *status_prompt_complete(struct client *, const char *, u_int);
|
static char *status_prompt_complete(struct client *, const char *, u_int);
|
||||||
static char *status_prompt_complete_window_menu(struct client *,
|
static char *status_prompt_complete_window_menu(struct client *,
|
||||||
@ -49,10 +49,16 @@ struct status_prompt_menu {
|
|||||||
char flag;
|
char flag;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *prompt_type_strings[] = {
|
||||||
|
"command",
|
||||||
|
"search",
|
||||||
|
"target",
|
||||||
|
"window-target"
|
||||||
|
};
|
||||||
|
|
||||||
/* Status prompt history. */
|
/* Status prompt history. */
|
||||||
#define PROMPT_HISTORY 100
|
char **status_prompt_hlist[PROMPT_NTYPES];
|
||||||
static char **status_prompt_hlist;
|
u_int status_prompt_hsize[PROMPT_NTYPES];
|
||||||
static u_int status_prompt_hsize;
|
|
||||||
|
|
||||||
/* Find the history file to load/save from/to. */
|
/* Find the history file to load/save from/to. */
|
||||||
static char *
|
static char *
|
||||||
@ -75,6 +81,28 @@ status_prompt_find_history_file(void)
|
|||||||
return (path);
|
return (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Add loaded history item to the appropriate list. */
|
||||||
|
static void
|
||||||
|
status_prompt_add_typed_history(char *line)
|
||||||
|
{
|
||||||
|
char *typestr;
|
||||||
|
enum prompt_type type = PROMPT_TYPE_INVALID;
|
||||||
|
|
||||||
|
typestr = strsep(&line, ":");
|
||||||
|
if (line != NULL)
|
||||||
|
type = status_prompt_type(typestr);
|
||||||
|
if (type == PROMPT_TYPE_INVALID) {
|
||||||
|
/*
|
||||||
|
* Invalid types are not expected, but this provides backward
|
||||||
|
* compatibility with old history files.
|
||||||
|
*/
|
||||||
|
if (line != NULL)
|
||||||
|
*(--line) = ':';
|
||||||
|
status_prompt_add_history(typestr, PROMPT_TYPE_COMMAND);
|
||||||
|
} else
|
||||||
|
status_prompt_add_history(line, type);
|
||||||
|
}
|
||||||
|
|
||||||
/* Load status prompt history from file. */
|
/* Load status prompt history from file. */
|
||||||
void
|
void
|
||||||
status_prompt_load_history(void)
|
status_prompt_load_history(void)
|
||||||
@ -102,12 +130,12 @@ status_prompt_load_history(void)
|
|||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
if (line[length - 1] == '\n') {
|
if (line[length - 1] == '\n') {
|
||||||
line[length - 1] = '\0';
|
line[length - 1] = '\0';
|
||||||
status_prompt_add_history(line);
|
status_prompt_add_typed_history(line);
|
||||||
} else {
|
} else {
|
||||||
tmp = xmalloc(length + 1);
|
tmp = xmalloc(length + 1);
|
||||||
memcpy(tmp, line, length);
|
memcpy(tmp, line, length);
|
||||||
tmp[length] = '\0';
|
tmp[length] = '\0';
|
||||||
status_prompt_add_history(tmp);
|
status_prompt_add_typed_history(tmp);
|
||||||
free(tmp);
|
free(tmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,7 +148,7 @@ void
|
|||||||
status_prompt_save_history(void)
|
status_prompt_save_history(void)
|
||||||
{
|
{
|
||||||
FILE *f;
|
FILE *f;
|
||||||
u_int i;
|
u_int i, type;
|
||||||
char *history_file;
|
char *history_file;
|
||||||
|
|
||||||
if ((history_file = status_prompt_find_history_file()) == NULL)
|
if ((history_file = status_prompt_find_history_file()) == NULL)
|
||||||
@ -135,9 +163,13 @@ status_prompt_save_history(void)
|
|||||||
}
|
}
|
||||||
free(history_file);
|
free(history_file);
|
||||||
|
|
||||||
for (i = 0; i < status_prompt_hsize; i++) {
|
for (type = 0; type < PROMPT_NTYPES; type++) {
|
||||||
fputs(status_prompt_hlist[i], f);
|
for (i = 0; i < status_prompt_hsize[type]; i++) {
|
||||||
fputc('\n', f);
|
fputs(prompt_type_strings[type], f);
|
||||||
|
fputc(':', f);
|
||||||
|
fputs(status_prompt_hlist[type][i], f);
|
||||||
|
fputc('\n', f);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
|
||||||
@ -545,7 +577,7 @@ status_message_redraw(struct client *c)
|
|||||||
void
|
void
|
||||||
status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
||||||
const char *msg, const char *input, prompt_input_cb inputcb,
|
const char *msg, const char *input, prompt_input_cb inputcb,
|
||||||
prompt_free_cb freecb, void *data, int flags)
|
prompt_free_cb freecb, void *data, int flags, enum prompt_type prompt_type)
|
||||||
{
|
{
|
||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
@ -581,9 +613,10 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
c->prompt_freecb = freecb;
|
c->prompt_freecb = freecb;
|
||||||
c->prompt_data = data;
|
c->prompt_data = data;
|
||||||
|
|
||||||
c->prompt_hindex = 0;
|
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
||||||
|
|
||||||
c->prompt_flags = flags;
|
c->prompt_flags = flags;
|
||||||
|
c->prompt_type = prompt_type;
|
||||||
c->prompt_mode = PROMPT_ENTRY;
|
c->prompt_mode = PROMPT_ENTRY;
|
||||||
|
|
||||||
if (~flags & PROMPT_INCREMENTAL)
|
if (~flags & PROMPT_INCREMENTAL)
|
||||||
@ -644,7 +677,7 @@ status_prompt_update(struct client *c, const char *msg, const char *input)
|
|||||||
c->prompt_buffer = utf8_fromcstr(tmp);
|
c->prompt_buffer = utf8_fromcstr(tmp);
|
||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
|
|
||||||
c->prompt_hindex = 0;
|
memset(c->prompt_hindex, 0, sizeof c->prompt_hindex);
|
||||||
|
|
||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
|
|
||||||
@ -768,7 +801,7 @@ status_prompt_space(const struct utf8_data *ud)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Translate key from emacs to vi. Return 0 to drop key, 1 to process the key
|
* Translate key from vi to emacs. Return 0 to drop key, 1 to process the key
|
||||||
* as an emacs key; return 2 to append to the buffer.
|
* as an emacs key; return 2 to append to the buffer.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
@ -1222,7 +1255,8 @@ process_key:
|
|||||||
goto changed;
|
goto changed;
|
||||||
case KEYC_UP:
|
case KEYC_UP:
|
||||||
case '\020': /* C-p */
|
case '\020': /* C-p */
|
||||||
histstr = status_prompt_up_history(&c->prompt_hindex);
|
histstr = status_prompt_up_history(c->prompt_hindex,
|
||||||
|
c->prompt_type);
|
||||||
if (histstr == NULL)
|
if (histstr == NULL)
|
||||||
break;
|
break;
|
||||||
free(c->prompt_buffer);
|
free(c->prompt_buffer);
|
||||||
@ -1231,7 +1265,8 @@ process_key:
|
|||||||
goto changed;
|
goto changed;
|
||||||
case KEYC_DOWN:
|
case KEYC_DOWN:
|
||||||
case '\016': /* C-n */
|
case '\016': /* C-n */
|
||||||
histstr = status_prompt_down_history(&c->prompt_hindex);
|
histstr = status_prompt_down_history(c->prompt_hindex,
|
||||||
|
c->prompt_type);
|
||||||
if (histstr == NULL)
|
if (histstr == NULL)
|
||||||
break;
|
break;
|
||||||
free(c->prompt_buffer);
|
free(c->prompt_buffer);
|
||||||
@ -1259,7 +1294,7 @@ process_key:
|
|||||||
case '\n':
|
case '\n':
|
||||||
s = utf8_tocstr(c->prompt_buffer);
|
s = utf8_tocstr(c->prompt_buffer);
|
||||||
if (*s != '\0')
|
if (*s != '\0')
|
||||||
status_prompt_add_history(s);
|
status_prompt_add_history(s, c->prompt_type);
|
||||||
if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
|
if (c->prompt_inputcb(c, c->prompt_data, s, 1) == 0)
|
||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
free(s);
|
free(s);
|
||||||
@ -1348,54 +1383,78 @@ changed:
|
|||||||
|
|
||||||
/* Get previous line from the history. */
|
/* Get previous line from the history. */
|
||||||
static const char *
|
static const char *
|
||||||
status_prompt_up_history(u_int *idx)
|
status_prompt_up_history(u_int *idx, u_int type)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* History runs from 0 to size - 1. Index is from 0 to size. Zero is
|
* History runs from 0 to size - 1. Index is from 0 to size. Zero is
|
||||||
* empty.
|
* empty.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (status_prompt_hsize == 0 || *idx == status_prompt_hsize)
|
if (status_prompt_hsize[type] == 0 ||
|
||||||
|
idx[type] == status_prompt_hsize[type])
|
||||||
return (NULL);
|
return (NULL);
|
||||||
(*idx)++;
|
idx[type]++;
|
||||||
return (status_prompt_hlist[status_prompt_hsize - *idx]);
|
return (status_prompt_hlist[type][status_prompt_hsize[type] - idx[type]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get next line from the history. */
|
/* Get next line from the history. */
|
||||||
static const char *
|
static const char *
|
||||||
status_prompt_down_history(u_int *idx)
|
status_prompt_down_history(u_int *idx, u_int type)
|
||||||
{
|
{
|
||||||
if (status_prompt_hsize == 0 || *idx == 0)
|
if (status_prompt_hsize[type] == 0 || idx[type] == 0)
|
||||||
return ("");
|
return ("");
|
||||||
(*idx)--;
|
idx[type]--;
|
||||||
if (*idx == 0)
|
if (idx[type] == 0)
|
||||||
return ("");
|
return ("");
|
||||||
return (status_prompt_hlist[status_prompt_hsize - *idx]);
|
return (status_prompt_hlist[type][status_prompt_hsize[type] - idx[type]]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add line to the history. */
|
/* Add line to the history. */
|
||||||
static void
|
static void
|
||||||
status_prompt_add_history(const char *line)
|
status_prompt_add_history(const char *line, u_int type)
|
||||||
{
|
{
|
||||||
size_t size;
|
u_int i, oldsize, newsize, freecount, hlimit, new = 1;
|
||||||
|
size_t movesize;
|
||||||
|
|
||||||
if (status_prompt_hsize > 0 &&
|
oldsize = status_prompt_hsize[type];
|
||||||
strcmp(status_prompt_hlist[status_prompt_hsize - 1], line) == 0)
|
if (oldsize > 0 &&
|
||||||
return;
|
strcmp(status_prompt_hlist[type][oldsize - 1], line) == 0)
|
||||||
|
new = 0;
|
||||||
|
|
||||||
if (status_prompt_hsize == PROMPT_HISTORY) {
|
hlimit = options_get_number(global_options, "prompt-history-limit");
|
||||||
free(status_prompt_hlist[0]);
|
if (hlimit > oldsize) {
|
||||||
|
if (new == 0)
|
||||||
size = (PROMPT_HISTORY - 1) * sizeof *status_prompt_hlist;
|
return;
|
||||||
memmove(&status_prompt_hlist[0], &status_prompt_hlist[1], size);
|
newsize = oldsize + new;
|
||||||
|
} else {
|
||||||
status_prompt_hlist[status_prompt_hsize - 1] = xstrdup(line);
|
newsize = hlimit;
|
||||||
return;
|
freecount = oldsize + new - newsize;
|
||||||
|
if (freecount > oldsize)
|
||||||
|
freecount = oldsize;
|
||||||
|
if (freecount == 0)
|
||||||
|
return;
|
||||||
|
for (i = 0; i < freecount; i++)
|
||||||
|
free(status_prompt_hlist[type][i]);
|
||||||
|
movesize = (oldsize - freecount) *
|
||||||
|
sizeof *status_prompt_hlist[type];
|
||||||
|
if (movesize > 0) {
|
||||||
|
memmove(&status_prompt_hlist[type][0],
|
||||||
|
&status_prompt_hlist[type][freecount], movesize);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status_prompt_hlist = xreallocarray(status_prompt_hlist,
|
if (newsize == 0) {
|
||||||
status_prompt_hsize + 1, sizeof *status_prompt_hlist);
|
free(status_prompt_hlist[type]);
|
||||||
status_prompt_hlist[status_prompt_hsize++] = xstrdup(line);
|
status_prompt_hlist[type] = NULL;
|
||||||
|
} else if (newsize != oldsize) {
|
||||||
|
status_prompt_hlist[type] =
|
||||||
|
xreallocarray(status_prompt_hlist[type], newsize,
|
||||||
|
sizeof *status_prompt_hlist[type]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (new == 1 && newsize > 0)
|
||||||
|
status_prompt_hlist[type][newsize - 1] = xstrdup(line);
|
||||||
|
status_prompt_hsize[type] = newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build completion list. */
|
/* Build completion list. */
|
||||||
@ -1501,7 +1560,7 @@ status_prompt_menu_callback(__unused struct menu *menu, u_int idx, key_code key,
|
|||||||
s = xstrdup(spm->list[idx]);
|
s = xstrdup(spm->list[idx]);
|
||||||
else
|
else
|
||||||
xasprintf(&s, "-%c%s", spm->flag, spm->list[idx]);
|
xasprintf(&s, "-%c%s", spm->flag, spm->list[idx]);
|
||||||
if (c->prompt_flags & PROMPT_WINDOW) {
|
if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
|
||||||
free(c->prompt_buffer);
|
free(c->prompt_buffer);
|
||||||
c->prompt_buffer = utf8_fromcstr(s);
|
c->prompt_buffer = utf8_fromcstr(s);
|
||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
@ -1609,7 +1668,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
|
|||||||
}
|
}
|
||||||
|
|
||||||
list = xreallocarray(list, size + 1, sizeof *list);
|
list = xreallocarray(list, size + 1, sizeof *list);
|
||||||
if (c->prompt_flags & PROMPT_WINDOW) {
|
if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
|
||||||
xasprintf(&tmp, "%d (%s)", wl->idx, wl->window->name);
|
xasprintf(&tmp, "%d (%s)", wl->idx, wl->window->name);
|
||||||
xasprintf(&list[size++], "%d", wl->idx);
|
xasprintf(&list[size++], "%d", wl->idx);
|
||||||
} else {
|
} else {
|
||||||
@ -1717,10 +1776,12 @@ status_prompt_complete(struct client *c, const char *word, u_int offset)
|
|||||||
u_int size = 0, i;
|
u_int size = 0, i;
|
||||||
|
|
||||||
if (*word == '\0' &&
|
if (*word == '\0' &&
|
||||||
((c->prompt_flags & (PROMPT_TARGET|PROMPT_WINDOW)) == 0))
|
c->prompt_type != PROMPT_TYPE_TARGET &&
|
||||||
|
c->prompt_type != PROMPT_TYPE_WINDOW_TARGET)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (((c->prompt_flags & (PROMPT_TARGET|PROMPT_WINDOW)) == 0) &&
|
if (c->prompt_type != PROMPT_TYPE_TARGET &&
|
||||||
|
c->prompt_type != PROMPT_TYPE_WINDOW_TARGET &&
|
||||||
strncmp(word, "-t", 2) != 0 &&
|
strncmp(word, "-t", 2) != 0 &&
|
||||||
strncmp(word, "-s", 2) != 0) {
|
strncmp(word, "-s", 2) != 0) {
|
||||||
list = status_prompt_complete_list(&size, word, offset == 0);
|
list = status_prompt_complete_list(&size, word, offset == 0);
|
||||||
@ -1733,7 +1794,8 @@ status_prompt_complete(struct client *c, const char *word, u_int offset)
|
|||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c->prompt_flags & (PROMPT_TARGET|PROMPT_WINDOW)) {
|
if (c->prompt_type == PROMPT_TYPE_TARGET ||
|
||||||
|
c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
|
||||||
s = word;
|
s = word;
|
||||||
flag = '\0';
|
flag = '\0';
|
||||||
} else {
|
} else {
|
||||||
@ -1743,7 +1805,7 @@ status_prompt_complete(struct client *c, const char *word, u_int offset)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If this is a window completion, open the window menu. */
|
/* If this is a window completion, open the window menu. */
|
||||||
if (c->prompt_flags & PROMPT_WINDOW) {
|
if (c->prompt_type == PROMPT_TYPE_WINDOW_TARGET) {
|
||||||
out = status_prompt_complete_window_menu(c, c->session, s,
|
out = status_prompt_complete_window_menu(c, c->session, s,
|
||||||
offset, '\0');
|
offset, '\0');
|
||||||
goto found;
|
goto found;
|
||||||
@ -1793,3 +1855,25 @@ found:
|
|||||||
}
|
}
|
||||||
return (out);
|
return (out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the type of the prompt as an enum. */
|
||||||
|
enum prompt_type
|
||||||
|
status_prompt_type(const char *type)
|
||||||
|
{
|
||||||
|
u_int i;
|
||||||
|
|
||||||
|
for (i = 0; i < PROMPT_NTYPES; i++) {
|
||||||
|
if (strcmp(type, status_prompt_type_string(i)) == 0)
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
return (PROMPT_TYPE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Accessor for prompt_type_strings. */
|
||||||
|
const char *
|
||||||
|
status_prompt_type_string(u_int type)
|
||||||
|
{
|
||||||
|
if (type >= PROMPT_NTYPES)
|
||||||
|
return ("invalid");
|
||||||
|
return (prompt_type_strings[type]);
|
||||||
|
}
|
||||||
|
47
tmux.1
47
tmux.1
@ -3453,7 +3453,9 @@ 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.
|
||||||
The default is 100.
|
.It Ic prompt-history-limit Ar number
|
||||||
|
Set the number of history items to save in the history file for each type of
|
||||||
|
command prompt.
|
||||||
.It Xo Ic set-clipboard
|
.It Xo Ic set-clipboard
|
||||||
.Op Ic on | external | off
|
.Op Ic on | external | off
|
||||||
.Xc
|
.Xc
|
||||||
@ -5376,11 +5378,25 @@ session option.
|
|||||||
.Pp
|
.Pp
|
||||||
Commands related to the status line are as follows:
|
Commands related to the status line are as follows:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
|
.It Xo Ic clear-prompt-history
|
||||||
|
.Op Fl T Ar prompt-type
|
||||||
|
.Xc
|
||||||
|
.D1 (alias: Ic clrphist)
|
||||||
|
Clear status prompt history for prompt type
|
||||||
|
.Ar prompt-type .
|
||||||
|
If
|
||||||
|
.Fl T
|
||||||
|
is omitted, then clear history for all types.
|
||||||
|
See
|
||||||
|
.Ic command-prompt
|
||||||
|
for possible values for
|
||||||
|
.Ar prompt-type .
|
||||||
.It Xo Ic command-prompt
|
.It Xo Ic command-prompt
|
||||||
.Op Fl 1ikNTW
|
.Op Fl 1ikN
|
||||||
.Op Fl I Ar inputs
|
.Op Fl I Ar inputs
|
||||||
.Op Fl p Ar prompts
|
.Op Fl p Ar prompts
|
||||||
.Op Fl t Ar target-client
|
.Op Fl t Ar target-client
|
||||||
|
.Op Fl T Ar prompt-type
|
||||||
.Op Ar template
|
.Op Ar template
|
||||||
.Xc
|
.Xc
|
||||||
Open the command prompt in a client.
|
Open the command prompt in a client.
|
||||||
@ -5436,14 +5452,20 @@ makes the prompt only accept numeric key presses.
|
|||||||
.Fl i
|
.Fl i
|
||||||
executes the command every time the prompt input changes instead of when the
|
executes the command every time the prompt input changes instead of when the
|
||||||
user exits the command prompt.
|
user exits the command prompt.
|
||||||
|
.Pp
|
||||||
.Fl T
|
.Fl T
|
||||||
tells
|
tells
|
||||||
.Nm
|
.Nm
|
||||||
that the prompt is for a target which affects what completions are offered when
|
the prompt type.
|
||||||
|
This affects what completions are offered when
|
||||||
.Em Tab
|
.Em Tab
|
||||||
is pressed;
|
is pressed.
|
||||||
.Fl W
|
Available types are:
|
||||||
is similar but indicates the prompt is for a window.
|
.Ql command ,
|
||||||
|
.Ql search ,
|
||||||
|
.Ql target
|
||||||
|
and
|
||||||
|
.Ql window-target .
|
||||||
.Pp
|
.Pp
|
||||||
The following keys have a special meaning in the command prompt, depending
|
The following keys have a special meaning in the command prompt, depending
|
||||||
on the value of the
|
on the value of the
|
||||||
@ -5665,6 +5687,19 @@ If omitted, half of the terminal size is used.
|
|||||||
The
|
The
|
||||||
.Fl C
|
.Fl C
|
||||||
flag closes any popup on the client.
|
flag closes any popup on the client.
|
||||||
|
.It Xo Ic show-prompt-history
|
||||||
|
.Op Fl T Ar prompt-type
|
||||||
|
.Xc
|
||||||
|
.D1 (alias: Ic showphist)
|
||||||
|
Display status prompt history for prompt type
|
||||||
|
.Ar prompt-type .
|
||||||
|
If
|
||||||
|
.Fl T
|
||||||
|
is omitted, then show history for all types.
|
||||||
|
See
|
||||||
|
.Ic command-prompt
|
||||||
|
for possible values for
|
||||||
|
.Ar prompt-type .
|
||||||
.El
|
.El
|
||||||
.Sh BUFFERS
|
.Sh BUFFERS
|
||||||
.Nm
|
.Nm
|
||||||
|
22
tmux.h
22
tmux.h
@ -1571,6 +1571,16 @@ struct status_line {
|
|||||||
struct status_line_entry entries[STATUS_LINES_LIMIT];
|
struct status_line_entry entries[STATUS_LINES_LIMIT];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Prompt type. */
|
||||||
|
#define PROMPT_NTYPES 4
|
||||||
|
enum prompt_type {
|
||||||
|
PROMPT_TYPE_COMMAND,
|
||||||
|
PROMPT_TYPE_SEARCH,
|
||||||
|
PROMPT_TYPE_TARGET,
|
||||||
|
PROMPT_TYPE_WINDOW_TARGET,
|
||||||
|
PROMPT_TYPE_INVALID = 0xff
|
||||||
|
};
|
||||||
|
|
||||||
/* File in client. */
|
/* File in client. */
|
||||||
typedef void (*client_file_cb) (struct client *, const char *, int, int,
|
typedef void (*client_file_cb) (struct client *, const char *, int, int,
|
||||||
struct evbuffer *, void *);
|
struct evbuffer *, void *);
|
||||||
@ -1734,18 +1744,16 @@ struct client {
|
|||||||
prompt_input_cb prompt_inputcb;
|
prompt_input_cb prompt_inputcb;
|
||||||
prompt_free_cb prompt_freecb;
|
prompt_free_cb prompt_freecb;
|
||||||
void *prompt_data;
|
void *prompt_data;
|
||||||
u_int prompt_hindex;
|
u_int prompt_hindex[PROMPT_NTYPES];
|
||||||
enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
|
enum { PROMPT_ENTRY, PROMPT_COMMAND } prompt_mode;
|
||||||
struct utf8_data *prompt_saved;
|
struct utf8_data *prompt_saved;
|
||||||
|
|
||||||
#define PROMPT_SINGLE 0x1
|
#define PROMPT_SINGLE 0x1
|
||||||
#define PROMPT_NUMERIC 0x2
|
#define PROMPT_NUMERIC 0x2
|
||||||
#define PROMPT_INCREMENTAL 0x4
|
#define PROMPT_INCREMENTAL 0x4
|
||||||
#define PROMPT_NOFORMAT 0x8
|
#define PROMPT_NOFORMAT 0x8
|
||||||
#define PROMPT_KEY 0x10
|
#define PROMPT_KEY 0x10
|
||||||
#define PROMPT_WINDOW 0x20
|
|
||||||
#define PROMPT_TARGET 0x40
|
|
||||||
int prompt_flags;
|
int prompt_flags;
|
||||||
|
enum prompt_type prompt_type;
|
||||||
|
|
||||||
struct session *session;
|
struct session *session;
|
||||||
struct session *last_session;
|
struct session *last_session;
|
||||||
@ -2517,6 +2525,8 @@ void server_check_unattached(void);
|
|||||||
void server_unzoom_window(struct window *);
|
void server_unzoom_window(struct window *);
|
||||||
|
|
||||||
/* status.c */
|
/* status.c */
|
||||||
|
extern char **status_prompt_hlist[];
|
||||||
|
extern u_int status_prompt_hsize[];
|
||||||
void status_timer_start(struct client *);
|
void status_timer_start(struct client *);
|
||||||
void status_timer_start_all(void);
|
void status_timer_start_all(void);
|
||||||
void status_update_cache(struct session *);
|
void status_update_cache(struct session *);
|
||||||
@ -2531,13 +2541,15 @@ void status_message_clear(struct client *);
|
|||||||
int status_message_redraw(struct client *);
|
int status_message_redraw(struct client *);
|
||||||
void status_prompt_set(struct client *, struct cmd_find_state *,
|
void status_prompt_set(struct client *, struct cmd_find_state *,
|
||||||
const char *, const char *, prompt_input_cb, prompt_free_cb,
|
const char *, const char *, prompt_input_cb, prompt_free_cb,
|
||||||
void *, int);
|
void *, int, enum prompt_type);
|
||||||
void status_prompt_clear(struct client *);
|
void status_prompt_clear(struct client *);
|
||||||
int status_prompt_redraw(struct client *);
|
int status_prompt_redraw(struct client *);
|
||||||
int status_prompt_key(struct client *, key_code);
|
int status_prompt_key(struct client *, key_code);
|
||||||
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_load_history(void);
|
||||||
void status_prompt_save_history(void);
|
void status_prompt_save_history(void);
|
||||||
|
const char *status_prompt_type_string(u_int);
|
||||||
|
enum prompt_type status_prompt_type(const char *type);
|
||||||
|
|
||||||
/* resize.c */
|
/* resize.c */
|
||||||
void resize_window(struct window *, u_int, u_int, int, int);
|
void resize_window(struct window *, u_int, u_int, int, int);
|
||||||
|
@ -1123,7 +1123,7 @@ window_customize_set_option(struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, value,
|
status_prompt_set(c, NULL, prompt, value,
|
||||||
window_customize_set_option_callback,
|
window_customize_set_option_callback,
|
||||||
window_customize_free_item_callback, new_item,
|
window_customize_free_item_callback, new_item,
|
||||||
PROMPT_NOFORMAT);
|
PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
|
|
||||||
free(prompt);
|
free(prompt);
|
||||||
free(value);
|
free(value);
|
||||||
@ -1264,7 +1264,7 @@ window_customize_set_key(struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, value,
|
status_prompt_set(c, NULL, prompt, value,
|
||||||
window_customize_set_command_callback,
|
window_customize_set_command_callback,
|
||||||
window_customize_free_item_callback, new_item,
|
window_customize_free_item_callback, new_item,
|
||||||
PROMPT_NOFORMAT);
|
PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
free(value);
|
free(value);
|
||||||
} else if (strcmp(s, "Note") == 0) {
|
} else if (strcmp(s, "Note") == 0) {
|
||||||
@ -1281,7 +1281,7 @@ window_customize_set_key(struct client *c,
|
|||||||
(bd->note == NULL ? "" : bd->note),
|
(bd->note == NULL ? "" : bd->note),
|
||||||
window_customize_set_note_callback,
|
window_customize_set_note_callback,
|
||||||
window_customize_free_item_callback, new_item,
|
window_customize_free_item_callback, new_item,
|
||||||
PROMPT_NOFORMAT);
|
PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1458,7 +1458,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_customize_change_current_callback,
|
window_customize_change_current_callback,
|
||||||
window_customize_free_callback, data,
|
window_customize_free_callback, data,
|
||||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
@ -1471,7 +1471,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_customize_change_tagged_callback,
|
window_customize_change_tagged_callback,
|
||||||
window_customize_free_callback, data,
|
window_customize_free_callback, data,
|
||||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
@ -1487,7 +1487,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_customize_change_current_callback,
|
window_customize_change_current_callback,
|
||||||
window_customize_free_callback, data,
|
window_customize_free_callback, data,
|
||||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case 'U':
|
case 'U':
|
||||||
@ -1500,7 +1500,7 @@ window_customize_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_customize_change_tagged_callback,
|
window_customize_change_tagged_callback,
|
||||||
window_customize_free_callback, data,
|
window_customize_free_callback, data,
|
||||||
PROMPT_SINGLE|PROMPT_NOFORMAT);
|
PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case 'H':
|
case 'H':
|
||||||
|
@ -1296,7 +1296,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
data->references++;
|
data->references++;
|
||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_tree_kill_current_callback, window_tree_command_free,
|
window_tree_kill_current_callback, window_tree_command_free,
|
||||||
data, PROMPT_SINGLE|PROMPT_NOFORMAT);
|
data, PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case 'X':
|
case 'X':
|
||||||
@ -1307,7 +1307,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
data->references++;
|
data->references++;
|
||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_tree_kill_tagged_callback, window_tree_command_free,
|
window_tree_kill_tagged_callback, window_tree_command_free,
|
||||||
data, PROMPT_SINGLE|PROMPT_NOFORMAT);
|
data, PROMPT_SINGLE|PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case ':':
|
case ':':
|
||||||
@ -1319,7 +1319,7 @@ window_tree_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
data->references++;
|
data->references++;
|
||||||
status_prompt_set(c, NULL, prompt, "",
|
status_prompt_set(c, NULL, prompt, "",
|
||||||
window_tree_command_callback, window_tree_command_free,
|
window_tree_command_callback, window_tree_command_free,
|
||||||
data, PROMPT_NOFORMAT);
|
data, PROMPT_NOFORMAT, PROMPT_TYPE_COMMAND);
|
||||||
free(prompt);
|
free(prompt);
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
|
Loading…
Reference in New Issue
Block a user