mirror of
https://github.com/tmux/tmux.git
synced 2026-03-11 19:15:45 +00:00
Compare commits
110 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ac44566c9c | ||
|
|
64f1076d97 | ||
|
|
489c69f5ed | ||
|
|
f897049935 | ||
|
|
d8b66110f7 | ||
|
|
8b1a3bb2e5 | ||
|
|
37771a5a8d | ||
|
|
3a8a31d8d2 | ||
|
|
c36ffcbe56 | ||
|
|
3d8ead8a97 | ||
|
|
141cd78407 | ||
|
|
d0c8124661 | ||
|
|
2917bc5274 | ||
|
|
2d1e93447e | ||
|
|
31b6c9356c | ||
|
|
9e2a7c28f5 | ||
|
|
73b2277af8 | ||
|
|
a84c109604 | ||
|
|
4823acca8f | ||
|
|
34807388b0 | ||
|
|
08be883297 | ||
|
|
13bd0e46db | ||
|
|
6e9a914014 | ||
|
|
7990e5fa8f | ||
|
|
4860a58d07 | ||
|
|
99af9f23bd | ||
|
|
9ebbe2cca7 | ||
|
|
692bae9ea6 | ||
|
|
a6645c4de4 | ||
|
|
06292baadc | ||
|
|
ceda0a68ae | ||
|
|
4fa90c9acf | ||
|
|
c7e61a01e5 | ||
|
|
963e824f5f | ||
|
|
de6bce057a | ||
|
|
937ba1d8dd | ||
|
|
651891c3bd | ||
|
|
4008e2ff6d | ||
|
|
b88130d24b | ||
|
|
fc7ee7efc7 | ||
|
|
d0eb3fe543 | ||
|
|
2ac0faf119 | ||
|
|
775789fbd5 | ||
|
|
7b6fbe7262 | ||
|
|
109d2bda1a | ||
|
|
ddd4e57c65 | ||
|
|
3c2621b41b | ||
|
|
5039be657c | ||
|
|
d02254f754 | ||
|
|
aa1353947e | ||
|
|
171004dfd0 | ||
|
|
c773fe89e7 | ||
|
|
093b5a5518 | ||
|
|
db1665868f | ||
|
|
c07e856d24 | ||
|
|
692ce59bce | ||
|
|
9e7c1aee48 | ||
|
|
4c2eedca5a | ||
|
|
ac6c1e9589 | ||
|
|
0903790b00 | ||
|
|
03de52653e | ||
|
|
da06719309 | ||
|
|
fc84097379 | ||
|
|
4fd725c6e1 | ||
|
|
d39dcea30a | ||
|
|
bfd65398a9 | ||
|
|
452d987e0e | ||
|
|
8ef899f315 | ||
|
|
a18d1146aa | ||
|
|
5b5004e5ac | ||
|
|
6ff8f8fbf9 | ||
|
|
c9616700ca | ||
|
|
4c928dce74 | ||
|
|
fb37d52dde | ||
|
|
363d9c401e | ||
|
|
8643ece345 | ||
|
|
9ba433e521 | ||
|
|
3823fa2c57 | ||
|
|
0a8571b6fe | ||
|
|
ea9f416c99 | ||
|
|
036d8993e6 | ||
|
|
e8530c9fee | ||
|
|
dd4c0109a9 | ||
|
|
43530d4397 | ||
|
|
553d4cba79 | ||
|
|
c62a9ca16b | ||
|
|
424f13fe13 | ||
|
|
4bb6da75ba | ||
|
|
a28175dbfd | ||
|
|
fc204bb5e5 | ||
|
|
6207a45139 | ||
|
|
3c3643f580 | ||
|
|
89c1c43ef9 | ||
|
|
2e9d7ebf15 | ||
|
|
d8ddeec7db | ||
|
|
6f0254e6a8 | ||
|
|
aa17f0e0c1 | ||
|
|
0ae8b681b2 | ||
|
|
6c0067c103 | ||
|
|
5458cb2850 | ||
|
|
0c374868ca | ||
|
|
bf5d3f2e26 | ||
|
|
d5ef837f63 | ||
|
|
b79e28b2c3 | ||
|
|
8ffd5458ff | ||
|
|
b54e1fc4f7 | ||
|
|
bdb6321229 | ||
|
|
bd29a48b56 | ||
|
|
f3f1c3db58 | ||
|
|
608d113486 |
29
.github/workflows/lock.yml
vendored
29
.github/workflows/lock.yml
vendored
@@ -3,27 +3,32 @@ name: 'Lock Threads'
|
|||||||
on:
|
on:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: '0 0 * * *'
|
- cron: '0 0 * * *'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: lock-threads
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
lock:
|
action:
|
||||||
permissions:
|
|
||||||
issues: write # for dessant/lock-threads to lock issues
|
|
||||||
pull-requests: write # for dessant/lock-threads to lock PRs
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: dessant/lock-threads@v2
|
- uses: dessant/lock-threads@v5
|
||||||
with:
|
with:
|
||||||
github-token: ${{ github.token }}
|
github-token: ${{ github.token }}
|
||||||
issue-lock-inactive-days: '30'
|
issue-inactive-days: '30'
|
||||||
pr-lock-inactive-days: '60'
|
issue-comment: >
|
||||||
issue-lock-comment: >
|
|
||||||
This issue has been automatically locked since there
|
This issue has been automatically locked since there
|
||||||
has not been any recent activity after it was closed.
|
has not been any recent activity after it was closed.
|
||||||
Please open a new issue for related bugs.
|
pr-inactive-days: '60'
|
||||||
pr-lock-comment: >
|
pr-comment: >
|
||||||
This pull request has been automatically locked since there
|
This pull request has been automatically locked since there
|
||||||
has not been any recent activity after it was closed.
|
has not been any recent activity after it was closed.
|
||||||
Please open a new issue for related bugs.
|
discussion-inactive-days: '60'
|
||||||
|
discussion-comment: >
|
||||||
|
This discussion has been automatically locked since there
|
||||||
|
has not been any recent activity after it was closed.
|
||||||
|
|||||||
93
CHANGES
93
CHANGES
@@ -1,4 +1,93 @@
|
|||||||
CHANGES FROM 3.3a to 3.4
|
CHANGES FROM 3.4 TO 3.5
|
||||||
|
|
||||||
|
* Revamp extended keys support to more closely match xterm and support mode 2
|
||||||
|
as well as mode 1. This is a substantial change to key handling which changes
|
||||||
|
tmux to always request mode 2 from parent terminal, changes to an unambiguous
|
||||||
|
internal representation of keys, and adds an option (extended-keys-format) to
|
||||||
|
control the format similar to the xterm(1) formatOtherKeys resource.
|
||||||
|
|
||||||
|
* Clear an overlay (popup or menu) when command prompt is entered.
|
||||||
|
|
||||||
|
* Add copy-mode -d flag to scroll a page down if in copy mode already (matching
|
||||||
|
-e).
|
||||||
|
|
||||||
|
* Display hyperlinks in copy mode and add copy_cursor_hyperlink format to get
|
||||||
|
the hyperlink under the cursor.
|
||||||
|
|
||||||
|
* Add a prefix timeout option.
|
||||||
|
|
||||||
|
* Mouse move keys are not useful as key bindings because we do not turn them on
|
||||||
|
unless the application requests them. Ignore them so they do not cause the
|
||||||
|
prefix to be canceled
|
||||||
|
|
||||||
|
* Add search_count and search_count_partial formats in copy mode.
|
||||||
|
|
||||||
|
* Do not reset mouse pane if clicked on status line,
|
||||||
|
|
||||||
|
* Add mirrored versions of the main-horizontal and main-vertical layouts where
|
||||||
|
the main pane is bottom or right instead of top or left.
|
||||||
|
|
||||||
|
* Allow REP to work with Unicode characters.
|
||||||
|
|
||||||
|
* Fix size calculation of terminators for clipboard escape sequences.
|
||||||
|
|
||||||
|
* Treat CRLF as LF in config files where it is easy to do so.
|
||||||
|
|
||||||
|
* The Linux console has some bugs with bright colours, so add some workarounds
|
||||||
|
for it.
|
||||||
|
|
||||||
|
* If built with systemd, remove some environment variables it uses.
|
||||||
|
|
||||||
|
* Adjust the logic when deleting last buffer to better preserve the selection:
|
||||||
|
if selecting the element below the deleted one fails (because as the last
|
||||||
|
one), select the one above it instead.
|
||||||
|
|
||||||
|
* Add --enable-jemalloc to build with jemalloc memory allocator (since glibc
|
||||||
|
malloc is so poor).
|
||||||
|
|
||||||
|
* Add a way (refresh-client -r) for control mode clients to provide OSC 10 and
|
||||||
|
11 responses to tmux so they can set the default foreground and background
|
||||||
|
colours.
|
||||||
|
|
||||||
|
* Add N to search backwards in tree modes.
|
||||||
|
|
||||||
|
* Use default-shell for command prompt, #() and popups.
|
||||||
|
|
||||||
|
* Revert part of a change intended to improve search performance by skipping
|
||||||
|
parts of lines already searched, but which in fact skipped the ends of lines
|
||||||
|
altogether.
|
||||||
|
|
||||||
|
* Add a command-error hook when a command fails.
|
||||||
|
|
||||||
|
* Add an option allow-set-title to forbid applications from changing the pane
|
||||||
|
title.
|
||||||
|
|
||||||
|
* Correct handling of mouse up events (don't ignore all but the last released
|
||||||
|
button), and always process down event for double click.
|
||||||
|
|
||||||
|
* Fix a crash if focusing a pane that is exiting.
|
||||||
|
|
||||||
|
* Pick newest session (as documented) when looking for next session for
|
||||||
|
detach-on-destroy.
|
||||||
|
|
||||||
|
* Reduce default escape-time to 10 milliseconds.
|
||||||
|
|
||||||
|
* Add display-menu -M to always turn mouse on in a menu.
|
||||||
|
|
||||||
|
* Look for feature code 21 for DECSLRM and 28 for DECFRA in the device
|
||||||
|
attributes and also accept level 1.
|
||||||
|
|
||||||
|
* Fix crash if built with SIXEL and the SIXEL colour register is invalid; also
|
||||||
|
remove SIXEL images before reflow.
|
||||||
|
|
||||||
|
* Do not notify window-layout-changed if the window is about to be destroyed.
|
||||||
|
|
||||||
|
* Do not consider a selection present if it is empty for the selection_active
|
||||||
|
and selection_present format variables.
|
||||||
|
|
||||||
|
* Fix split-window -p.
|
||||||
|
|
||||||
|
CHANGES FROM 3.3a TO 3.4
|
||||||
|
|
||||||
* Add options keep-last and keep-group to destroy-unattached to keep the last
|
* Add options keep-last and keep-group to destroy-unattached to keep the last
|
||||||
session whether in a group.
|
session whether in a group.
|
||||||
@@ -84,7 +173,7 @@ CHANGES FROM 3.3a to 3.4
|
|||||||
|
|
||||||
* Add message-line option to control where message and prompt go.
|
* Add message-line option to control where message and prompt go.
|
||||||
|
|
||||||
* Notification when a when a paste buffer is deleted.
|
* Notification when a paste buffer is deleted.
|
||||||
|
|
||||||
* Add a Nobr terminfo(5) capability to tell tmux the terminal does not use bright
|
* Add a Nobr terminfo(5) capability to tell tmux the terminal does not use bright
|
||||||
colours for bold.
|
colours for bold.
|
||||||
|
|||||||
@@ -164,10 +164,14 @@ args_parse_flag_argument(struct args_value *values, u_int count, char **cause,
|
|||||||
argument = &values[*i];
|
argument = &values[*i];
|
||||||
if (argument->type != ARGS_STRING) {
|
if (argument->type != ARGS_STRING) {
|
||||||
xasprintf(cause, "-%c argument must be a string", flag);
|
xasprintf(cause, "-%c argument must be a string", flag);
|
||||||
|
args_free_value(new);
|
||||||
|
free(new);
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (argument == NULL) {
|
if (argument == NULL) {
|
||||||
|
args_free_value(new);
|
||||||
|
free(new);
|
||||||
if (optional_argument) {
|
if (optional_argument) {
|
||||||
log_debug("%s: -%c (optional)", __func__, flag);
|
log_debug("%s: -%c (optional)", __func__, flag);
|
||||||
args_set(args, flag, NULL, ARGS_ENTRY_OPTIONAL_VALUE);
|
args_set(args, flag, NULL, ARGS_ENTRY_OPTIONAL_VALUE);
|
||||||
@@ -662,6 +666,8 @@ args_set(struct args *args, u_char flag, struct args_value *value, int flags)
|
|||||||
entry->count++;
|
entry->count++;
|
||||||
if (value != NULL && value->type != ARGS_NONE)
|
if (value != NULL && value->type != ARGS_NONE)
|
||||||
TAILQ_INSERT_TAIL(&entry->values, value, entry);
|
TAILQ_INSERT_TAIL(&entry->values, value, entry);
|
||||||
|
else
|
||||||
|
free(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get argument value. Will be NULL if it isn't present. */
|
/* Get argument value. Will be NULL if it isn't present. */
|
||||||
|
|||||||
19
client.c
19
client.c
@@ -452,11 +452,12 @@ client_send_identify(const char *ttynam, const char *termname, char **caps,
|
|||||||
{
|
{
|
||||||
char **ss;
|
char **ss;
|
||||||
size_t sslen;
|
size_t sslen;
|
||||||
int fd, flags = client_flags;
|
int fd;
|
||||||
|
uint64_t flags = client_flags;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
u_int i;
|
u_int i;
|
||||||
|
|
||||||
proc_send(client_peer, MSG_IDENTIFY_FLAGS, -1, &flags, sizeof flags);
|
proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &flags, sizeof flags);
|
||||||
proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags,
|
proc_send(client_peer, MSG_IDENTIFY_LONGFLAGS, -1, &client_flags,
|
||||||
sizeof client_flags);
|
sizeof client_flags);
|
||||||
|
|
||||||
@@ -497,20 +498,10 @@ client_send_identify(const char *ttynam, const char *termname, char **caps,
|
|||||||
static __dead void
|
static __dead void
|
||||||
client_exec(const char *shell, const char *shellcmd)
|
client_exec(const char *shell, const char *shellcmd)
|
||||||
{
|
{
|
||||||
const char *name, *ptr;
|
char *argv0;
|
||||||
char *argv0;
|
|
||||||
|
|
||||||
log_debug("shell %s, command %s", shell, shellcmd);
|
log_debug("shell %s, command %s", shell, shellcmd);
|
||||||
|
argv0 = shell_argv0(shell, !!(client_flags & CLIENT_LOGIN));
|
||||||
ptr = strrchr(shell, '/');
|
|
||||||
if (ptr != NULL && *(ptr + 1) != '\0')
|
|
||||||
name = ptr + 1;
|
|
||||||
else
|
|
||||||
name = shell;
|
|
||||||
if (client_flags & CLIENT_LOGIN)
|
|
||||||
xasprintf(&argv0, "-%s", name);
|
|
||||||
else
|
|
||||||
xasprintf(&argv0, "%s", name);
|
|
||||||
setenv("SHELL", shell, 1);
|
setenv("SHELL", shell, 1);
|
||||||
|
|
||||||
proc_clear_signals(client_proc, 1);
|
proc_clear_signals(client_proc, 1);
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ cmd_command_prompt_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cdata->prompt_type = status_prompt_type(type);
|
cdata->prompt_type = status_prompt_type(type);
|
||||||
if (cdata->prompt_type == PROMPT_TYPE_INVALID) {
|
if (cdata->prompt_type == PROMPT_TYPE_INVALID) {
|
||||||
cmdq_error(item, "unknown type: %s", type);
|
cmdq_error(item, "unknown type: %s", type);
|
||||||
|
cmd_command_prompt_free(cdata);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
|||||||
@@ -76,8 +76,10 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
cdata = xcalloc(1, sizeof *cdata);
|
cdata = xcalloc(1, sizeof *cdata);
|
||||||
cdata->cmdlist = args_make_commands_now(self, item, 0, 1);
|
cdata->cmdlist = args_make_commands_now(self, item, 0, 1);
|
||||||
if (cdata->cmdlist == NULL)
|
if (cdata->cmdlist == NULL) {
|
||||||
|
free(cdata);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
if (wait)
|
if (wait)
|
||||||
cdata->item = item;
|
cdata->item = item;
|
||||||
@@ -90,6 +92,7 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
cdata->confirm_key = confirm_key[0];
|
cdata->confirm_key = confirm_key[0];
|
||||||
else {
|
else {
|
||||||
cmdq_error(item, "invalid confirm key");
|
cmdq_error(item, "invalid confirm key");
|
||||||
|
free(cdata);
|
||||||
return (CMD_RETURN_ERROR);
|
return (CMD_RETURN_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,8 +103,8 @@ cmd_confirm_before_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
xasprintf(&new_prompt, "%s ", prompt);
|
xasprintf(&new_prompt, "%s ", prompt);
|
||||||
else {
|
else {
|
||||||
cmd = cmd_get_entry(cmd_list_first(cdata->cmdlist))->name;
|
cmd = cmd_get_entry(cmd_list_first(cdata->cmdlist))->name;
|
||||||
xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ",
|
xasprintf(&new_prompt, "Confirm '%s'? (%c/n) ", cmd,
|
||||||
cmd, cdata->confirm_key);
|
cdata->confirm_key);
|
||||||
}
|
}
|
||||||
|
|
||||||
status_prompt_set(tc, target, new_prompt, NULL,
|
status_prompt_set(tc, target, new_prompt, NULL,
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ const struct cmd_entry cmd_copy_mode_entry = {
|
|||||||
.name = "copy-mode",
|
.name = "copy-mode",
|
||||||
.alias = NULL,
|
.alias = NULL,
|
||||||
|
|
||||||
.args = { "eHMs:t:uq", 0, 0, NULL },
|
.args = { "deHMs:t:uq", 0, 0, NULL },
|
||||||
.usage = "[-eHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE,
|
.usage = "[-deHMuq] [-s src-pane] " CMD_TARGET_PANE_USAGE,
|
||||||
|
|
||||||
.source = { 's', CMD_FIND_PANE, 0 },
|
.source = { 's', CMD_FIND_PANE, 0 },
|
||||||
.target = { 't', CMD_FIND_PANE, 0 },
|
.target = { 't', CMD_FIND_PANE, 0 },
|
||||||
@@ -91,6 +91,8 @@ cmd_copy_mode_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
}
|
}
|
||||||
if (args_has(args, 'u'))
|
if (args_has(args, 'u'))
|
||||||
window_copy_pageup(wp, 0);
|
window_copy_pageup(wp, 0);
|
||||||
|
if (args_has(args, 'd'))
|
||||||
|
window_copy_pagedown(wp, 0, args_has(args, 'e'));
|
||||||
|
|
||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ const struct cmd_entry cmd_display_menu_entry = {
|
|||||||
.name = "display-menu",
|
.name = "display-menu",
|
||||||
.alias = "menu",
|
.alias = "menu",
|
||||||
|
|
||||||
.args = { "b:c:C:H:s:S:Ot:T:x:y:", 1, -1, cmd_display_menu_args_parse },
|
.args = { "b:c:C:H:s:S:MOt:T:x:y:", 1, -1, cmd_display_menu_args_parse },
|
||||||
.usage = "[-O] [-b border-lines] [-c target-client] "
|
.usage = "[-MO] [-b border-lines] [-c target-client] "
|
||||||
"[-C starting-choice] [-H selected-style] [-s style] "
|
"[-C starting-choice] [-H selected-style] [-s style] "
|
||||||
"[-S border-style] " CMD_TARGET_PANE_USAGE "[-T title] "
|
"[-S border-style] " CMD_TARGET_PANE_USAGE "[-T title] "
|
||||||
"[-x position] [-y position] name key command ...",
|
"[-x position] [-y position] name key command ...",
|
||||||
@@ -373,7 +373,7 @@ cmd_display_menu_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (args_has(args, 'O'))
|
if (args_has(args, 'O'))
|
||||||
flags |= MENU_STAYOPEN;
|
flags |= MENU_STAYOPEN;
|
||||||
if (!event->m.valid)
|
if (!event->m.valid && !args_has(args, 'M'))
|
||||||
flags |= MENU_NOMOUSE;
|
flags |= MENU_NOMOUSE;
|
||||||
if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
|
if (menu_display(menu, flags, starting_choice, item, px, py, tc, lines,
|
||||||
style, selected_style, border_style, target, NULL, NULL) != 0)
|
style, selected_style, border_style, target, NULL, NULL) != 0)
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ cmd_display_panes_key(struct client *c, void *data, struct key_event *event)
|
|||||||
wp = window_pane_at_index(w, index);
|
wp = window_pane_at_index(w, index);
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return (1);
|
return (1);
|
||||||
window_unzoom(w);
|
window_unzoom(w, 1);
|
||||||
|
|
||||||
xasprintf(&expanded, "%%%u", wp->id);
|
xasprintf(&expanded, "%%%u", wp->id);
|
||||||
|
|
||||||
|
|||||||
17
cmd-parse.y
17
cmd-parse.y
@@ -1273,6 +1273,16 @@ yylex(void)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ch == '\r') {
|
||||||
|
/*
|
||||||
|
* Treat \r\n as \n.
|
||||||
|
*/
|
||||||
|
ch = yylex_getc();
|
||||||
|
if (ch != '\n') {
|
||||||
|
yylex_ungetc(ch);
|
||||||
|
ch = '\r';
|
||||||
|
}
|
||||||
|
}
|
||||||
if (ch == '\n') {
|
if (ch == '\n') {
|
||||||
/*
|
/*
|
||||||
* End of line. Update the line number.
|
* End of line. Update the line number.
|
||||||
@@ -1619,6 +1629,13 @@ yylex_token(int ch)
|
|||||||
log_debug("%s: end at EOF", __func__);
|
log_debug("%s: end at EOF", __func__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (state == NONE && ch == '\r') {
|
||||||
|
ch = yylex_getc();
|
||||||
|
if (ch != '\n') {
|
||||||
|
yylex_ungetc(ch);
|
||||||
|
ch = '\r';
|
||||||
|
}
|
||||||
|
}
|
||||||
if (state == NONE && ch == '\n') {
|
if (state == NONE && ch == '\n') {
|
||||||
log_debug("%s: end at EOL", __func__);
|
log_debug("%s: end at EOL", __func__);
|
||||||
break;
|
break;
|
||||||
|
|||||||
21
cmd-queue.c
21
cmd-queue.c
@@ -664,9 +664,18 @@ cmdq_fire_command(struct cmdq_item *item)
|
|||||||
|
|
||||||
out:
|
out:
|
||||||
item->client = saved;
|
item->client = saved;
|
||||||
if (retval == CMD_RETURN_ERROR)
|
if (retval == CMD_RETURN_ERROR) {
|
||||||
|
fsp = NULL;
|
||||||
|
if (cmd_find_valid_state(&item->target))
|
||||||
|
fsp = &item->target;
|
||||||
|
else if (cmd_find_valid_state(&item->state->current))
|
||||||
|
fsp = &item->state->current;
|
||||||
|
else if (cmd_find_from_client(&fs, item->client, 0) == 0)
|
||||||
|
fsp = &fs;
|
||||||
|
cmdq_insert_hook(fsp != NULL ? fsp->s : NULL, item, fsp,
|
||||||
|
"command-error");
|
||||||
cmdq_guard(item, "error", flags);
|
cmdq_guard(item, "error", flags);
|
||||||
else
|
} else
|
||||||
cmdq_guard(item, "end", flags);
|
cmdq_guard(item, "end", flags);
|
||||||
return (retval);
|
return (retval);
|
||||||
}
|
}
|
||||||
@@ -805,10 +814,10 @@ cmdq_running(struct client *c)
|
|||||||
struct cmdq_list *queue = cmdq_get(c);
|
struct cmdq_list *queue = cmdq_get(c);
|
||||||
|
|
||||||
if (queue->item == NULL)
|
if (queue->item == NULL)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
if (queue->item->flags & CMDQ_WAITING)
|
if (queue->item->flags & CMDQ_WAITING)
|
||||||
return (NULL);
|
return (NULL);
|
||||||
return (queue->item);
|
return (queue->item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Print a guard line. */
|
/* Print a guard line. */
|
||||||
|
|||||||
@@ -34,9 +34,10 @@ const struct cmd_entry cmd_refresh_client_entry = {
|
|||||||
.name = "refresh-client",
|
.name = "refresh-client",
|
||||||
.alias = "refresh",
|
.alias = "refresh",
|
||||||
|
|
||||||
.args = { "A:B:cC:Df:F:l::LRSt:U", 0, 1, NULL },
|
.args = { "A:B:cC:Df:r:F:l::LRSt:U", 0, 1, NULL },
|
||||||
.usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] "
|
.usage = "[-cDlLRSU] [-A pane:state] [-B name:what:format] "
|
||||||
"[-C XxY] [-f flags] " CMD_TARGET_CLIENT_USAGE " [adjustment]",
|
"[-C XxY] [-f flags] [-r pane:report]" CMD_TARGET_CLIENT_USAGE
|
||||||
|
" [adjustment]",
|
||||||
|
|
||||||
.flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG,
|
.flags = CMD_AFTERHOOK|CMD_CLIENT_TFLAG,
|
||||||
.exec = cmd_refresh_client_exec
|
.exec = cmd_refresh_client_exec
|
||||||
@@ -193,6 +194,34 @@ cmd_refresh_client_clipboard(struct cmd *self, struct cmdq_item *item)
|
|||||||
return (CMD_RETURN_NORMAL);
|
return (CMD_RETURN_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
cmd_refresh_report(struct tty *tty, const char *value)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
u_int pane;
|
||||||
|
size_t size = 0;
|
||||||
|
char *copy, *split;
|
||||||
|
|
||||||
|
if (*value != '%')
|
||||||
|
return;
|
||||||
|
copy = xstrdup(value);
|
||||||
|
if ((split = strchr(copy, ':')) == NULL)
|
||||||
|
goto out;
|
||||||
|
*split++ = '\0';
|
||||||
|
|
||||||
|
if (sscanf(copy, "%%%u", &pane) != 1)
|
||||||
|
goto out;
|
||||||
|
wp = window_pane_find_by_id(pane);
|
||||||
|
if (wp == NULL)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
tty_keys_colours(tty, split, strlen(split), &size, &wp->control_fg,
|
||||||
|
&wp->control_bg);
|
||||||
|
|
||||||
|
out:
|
||||||
|
free(copy);
|
||||||
|
}
|
||||||
|
|
||||||
static enum cmd_retval
|
static enum cmd_retval
|
||||||
cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
|
cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
|
||||||
{
|
{
|
||||||
@@ -262,6 +291,8 @@ cmd_refresh_client_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
server_client_set_flags(tc, args_get(args, 'F'));
|
server_client_set_flags(tc, args_get(args, 'F'));
|
||||||
if (args_has(args, 'f'))
|
if (args_has(args, 'f'))
|
||||||
server_client_set_flags(tc, args_get(args, 'f'));
|
server_client_set_flags(tc, args_get(args, 'f'));
|
||||||
|
if (args_has(args, 'r'))
|
||||||
|
cmd_refresh_report(tty, args_get(args, 'r'));
|
||||||
|
|
||||||
if (args_has(args, 'A')) {
|
if (args_has(args, 'A')) {
|
||||||
if (~tc->flags & CLIENT_CONTROL)
|
if (~tc->flags & CLIENT_CONTROL)
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ cmd_resize_pane_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
|
|
||||||
if (args_has(args, 'Z')) {
|
if (args_has(args, 'Z')) {
|
||||||
if (w->flags & WINDOW_ZOOMED)
|
if (w->flags & WINDOW_ZOOMED)
|
||||||
window_unzoom(w);
|
window_unzoom(w, 1);
|
||||||
else
|
else
|
||||||
window_zoom(wp);
|
window_zoom(wp);
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
|
|||||||
@@ -85,12 +85,18 @@ cmd_run_shell_print(struct job *job, const char *msg)
|
|||||||
|
|
||||||
if (cdata->wp_id != -1)
|
if (cdata->wp_id != -1)
|
||||||
wp = window_pane_find_by_id(cdata->wp_id);
|
wp = window_pane_find_by_id(cdata->wp_id);
|
||||||
if (wp == NULL && cdata->item != NULL && cdata->client != NULL)
|
if (wp == NULL) {
|
||||||
wp = server_client_get_pane(cdata->client);
|
if (cdata->item != NULL) {
|
||||||
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
|
cmdq_print(cdata->item, "%s", msg);
|
||||||
wp = fs.wp;
|
return;
|
||||||
if (wp == NULL)
|
}
|
||||||
return;
|
if (cdata->item != NULL && cdata->client != NULL)
|
||||||
|
wp = server_client_get_pane(cdata->client);
|
||||||
|
if (wp == NULL && cmd_find_from_nothing(&fs, 0) == 0)
|
||||||
|
wp = fs.wp;
|
||||||
|
if (wp == NULL)
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
wme = TAILQ_FIRST(&wp->modes);
|
wme = TAILQ_FIRST(&wp->modes);
|
||||||
if (wme == NULL || wme->mode != &window_view_mode)
|
if (wme == NULL || wme->mode != &window_view_mode)
|
||||||
|
|||||||
@@ -93,10 +93,10 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
|||||||
size = -1;
|
size = -1;
|
||||||
if (args_has(args, 'l')) {
|
if (args_has(args, 'l')) {
|
||||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||||
item, &cause);
|
item, &cause);
|
||||||
} else if (args_has(args, 'p')) {
|
} else if (args_has(args, 'p')) {
|
||||||
size = args_strtonum_and_expand(args, 'l', 0, 100, item,
|
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||||
&cause);
|
&cause);
|
||||||
if (cause == NULL)
|
if (cause == NULL)
|
||||||
size = curval * size / 100;
|
size = curval * size / 100;
|
||||||
}
|
}
|
||||||
|
|||||||
2
cmd.c
2
cmd.c
@@ -47,7 +47,6 @@ extern const struct cmd_entry cmd_display_menu_entry;
|
|||||||
extern const struct cmd_entry cmd_display_message_entry;
|
extern const struct cmd_entry cmd_display_message_entry;
|
||||||
extern const struct cmd_entry cmd_display_popup_entry;
|
extern const struct cmd_entry cmd_display_popup_entry;
|
||||||
extern const struct cmd_entry cmd_display_panes_entry;
|
extern const struct cmd_entry cmd_display_panes_entry;
|
||||||
extern const struct cmd_entry cmd_down_pane_entry;
|
|
||||||
extern const struct cmd_entry cmd_find_window_entry;
|
extern const struct cmd_entry cmd_find_window_entry;
|
||||||
extern const struct cmd_entry cmd_has_session_entry;
|
extern const struct cmd_entry cmd_has_session_entry;
|
||||||
extern const struct cmd_entry cmd_if_shell_entry;
|
extern const struct cmd_entry cmd_if_shell_entry;
|
||||||
@@ -117,7 +116,6 @@ extern const struct cmd_entry cmd_swap_window_entry;
|
|||||||
extern const struct cmd_entry cmd_switch_client_entry;
|
extern const struct cmd_entry cmd_switch_client_entry;
|
||||||
extern const struct cmd_entry cmd_unbind_key_entry;
|
extern const struct cmd_entry cmd_unbind_key_entry;
|
||||||
extern const struct cmd_entry cmd_unlink_window_entry;
|
extern const struct cmd_entry cmd_unlink_window_entry;
|
||||||
extern const struct cmd_entry cmd_up_pane_entry;
|
|
||||||
extern const struct cmd_entry cmd_wait_for_entry;
|
extern const struct cmd_entry cmd_wait_for_entry;
|
||||||
|
|
||||||
const struct cmd_entry *cmd_table[] = {
|
const struct cmd_entry *cmd_table[] = {
|
||||||
|
|||||||
14
colour.c
14
colour.c
@@ -942,13 +942,17 @@ colour_byname(const char *name)
|
|||||||
{ "yellow3", 0xcdcd00 },
|
{ "yellow3", 0xcdcd00 },
|
||||||
{ "yellow4", 0x8b8b00 }
|
{ "yellow4", 0x8b8b00 }
|
||||||
};
|
};
|
||||||
u_int i;
|
u_int i;
|
||||||
int c;
|
int c;
|
||||||
|
const char *errstr;
|
||||||
|
|
||||||
if (strncmp(name, "grey", 4) == 0 || strncmp(name, "gray", 4) == 0) {
|
if (strncmp(name, "grey", 4) == 0 || strncmp(name, "gray", 4) == 0) {
|
||||||
if (!isdigit((u_char)name[4]))
|
if (name[4] == '\0')
|
||||||
return (0xbebebe|COLOUR_FLAG_RGB);
|
return (-1);
|
||||||
c = round(2.55 * atoi(name + 4));
|
c = strtonum(name + 4, 0, 100, &errstr);
|
||||||
|
if (errstr != NULL)
|
||||||
|
return (-1);
|
||||||
|
c = round(2.55 * c);
|
||||||
if (c < 0 || c > 255)
|
if (c < 0 || c > 255)
|
||||||
return (-1);
|
return (-1);
|
||||||
return (colour_join_rgb(c, c, c));
|
return (colour_join_rgb(c, c, c));
|
||||||
|
|||||||
5
compat.h
5
compat.h
@@ -289,6 +289,11 @@ void explicit_bzero(void *, size_t);
|
|||||||
int getdtablecount(void);
|
int getdtablecount(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_GETDTABLESIZE
|
||||||
|
/* getdtablesize.c */
|
||||||
|
int getdtablesize(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_CLOSEFROM
|
#ifndef HAVE_CLOSEFROM
|
||||||
/* closefrom.c */
|
/* closefrom.c */
|
||||||
void closefrom(int);
|
void closefrom(int);
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <arpa/inet.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_QUEUE_H_
|
#ifndef _COMPAT_QUEUE_H_
|
||||||
#define _SYS_QUEUE_H_
|
#define _COMPAT_QUEUE_H_
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This file defines five types of data structures: singly-linked lists,
|
* This file defines five types of data structures: singly-linked lists,
|
||||||
@@ -530,4 +530,4 @@ struct { \
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#endif /* !_SYS_QUEUE_H_ */
|
#endif /* !_COMPAT_QUEUE_H_ */
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
|
|||||||
@@ -24,7 +24,9 @@
|
|||||||
#include <systemd/sd-login.h>
|
#include <systemd/sd-login.h>
|
||||||
#include <systemd/sd-id128.h>
|
#include <systemd/sd-id128.h>
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
@@ -142,6 +144,17 @@ systemd_move_pid_to_new_cgroup(pid_t pid, char **cause)
|
|||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make sure that the session shells are terminated with SIGHUP since
|
||||||
|
* bash and friends tend to ignore SIGTERM.
|
||||||
|
*/
|
||||||
|
r = sd_bus_message_append(m, "(sv)", "SendSIGHUP", "b", 1);
|
||||||
|
if (r < 0) {
|
||||||
|
xasprintf(cause, "failed to append to properties: %s",
|
||||||
|
strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Inherit the slice from the parent process, or default to
|
* Inherit the slice from the parent process, or default to
|
||||||
* "app-tmux.slice" if that fails.
|
* "app-tmux.slice" if that fails.
|
||||||
|
|||||||
32
configure.ac
32
configure.ac
@@ -1,6 +1,6 @@
|
|||||||
# configure.ac
|
# configure.ac
|
||||||
|
|
||||||
AC_INIT([tmux], 3.4)
|
AC_INIT([tmux], 3.5)
|
||||||
AC_PREREQ([2.60])
|
AC_PREREQ([2.60])
|
||||||
|
|
||||||
AC_CONFIG_AUX_DIR(etc)
|
AC_CONFIG_AUX_DIR(etc)
|
||||||
@@ -56,10 +56,11 @@ AC_USE_SYSTEM_EXTENSIONS
|
|||||||
test "$sysconfdir" = '${prefix}/etc' && sysconfdir=/etc
|
test "$sysconfdir" = '${prefix}/etc' && sysconfdir=/etc
|
||||||
|
|
||||||
# Is this --enable-debug?
|
# Is this --enable-debug?
|
||||||
case "x$VERSION" in xnext*) enable_debug=yes;; esac
|
|
||||||
AC_ARG_ENABLE(
|
AC_ARG_ENABLE(
|
||||||
debug,
|
debug,
|
||||||
AS_HELP_STRING(--enable-debug, enable debug build flags),
|
AS_HELP_STRING(--enable-debug, enable debug build flags),
|
||||||
|
,
|
||||||
|
[case "x$VERSION" in xnext*) enable_debug=yes;; esac]
|
||||||
)
|
)
|
||||||
AM_CONDITIONAL(IS_DEBUG, test "x$enable_debug" = xyes)
|
AM_CONDITIONAL(IS_DEBUG, test "x$enable_debug" = xyes)
|
||||||
|
|
||||||
@@ -548,6 +549,24 @@ if test "x$found_malloc_trim" = xyes; then
|
|||||||
AC_DEFINE(HAVE_MALLOC_TRIM)
|
AC_DEFINE(HAVE_MALLOC_TRIM)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Build against jemalloc if requested.
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
jemalloc,
|
||||||
|
AS_HELP_STRING(--enable-jemalloc, use jemalloc if it is installed)
|
||||||
|
)
|
||||||
|
if test "x$enable_jemalloc" = xyes; then
|
||||||
|
PKG_CHECK_MODULES(
|
||||||
|
JEMALLOC,
|
||||||
|
jemalloc,
|
||||||
|
[
|
||||||
|
AM_CPPFLAGS="$JEMALLOC_CFLAGS $AM_CPPFLAGS"
|
||||||
|
CPPFLAGS="$AM_CPPFLAGS $SAVED_CPPFLAGS"
|
||||||
|
LIBS="$LIBS $JEMALLOC_LIBS"
|
||||||
|
],
|
||||||
|
AC_MSG_ERROR("jemalloc not found")
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
|
||||||
# Check for CMSG_DATA. On some platforms like HP-UX this requires UNIX 95
|
# Check for CMSG_DATA. On some platforms like HP-UX this requires UNIX 95
|
||||||
# (_XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED) (see xopen_networking(7)). On
|
# (_XOPEN_SOURCE and _XOPEN_SOURCE_EXTENDED) (see xopen_networking(7)). On
|
||||||
# others, UNIX 03 (_XOPEN_SOURCE 600, see standards(7) on Solaris).
|
# others, UNIX 03 (_XOPEN_SOURCE 600, see standards(7) on Solaris).
|
||||||
@@ -926,8 +945,13 @@ case "$host_os" in
|
|||||||
MANFORMAT=mdoc
|
MANFORMAT=mdoc
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
# Solaris 2.0 to 11.3 use AT&T nroff.
|
if test `uname -o 2>/dev/null` = illumos; then
|
||||||
MANFORMAT=man
|
# Illumos uses mandoc.
|
||||||
|
MANFORMAT=mdoc
|
||||||
|
else
|
||||||
|
# Solaris 2.0 to 11.3 use AT&T nroff.
|
||||||
|
MANFORMAT=man
|
||||||
|
fi
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -264,6 +264,12 @@ environ_for_session(struct session *s, int no_TERM)
|
|||||||
environ_set(env, "TERM_PROGRAM_VERSION", 0, "%s", getversion());
|
environ_set(env, "TERM_PROGRAM_VERSION", 0, "%s", getversion());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_SYSTEMD
|
||||||
|
environ_clear(env, "LISTEN_PID");
|
||||||
|
environ_clear(env, "LISTEN_FDS");
|
||||||
|
environ_clear(env, "LISTEN_FDNAMES");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (s != NULL)
|
if (s != NULL)
|
||||||
idx = s->id;
|
idx = s->id;
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ set -g status-bg red
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
# Enable RGB colour if running in xterm(1)
|
# Enable RGB colour if running in xterm(1)
|
||||||
set-option -sa terminal-overrides ",xterm*:Tc"
|
set-option -sa terminal-features ",xterm*:RGB"
|
||||||
|
|
||||||
# Change the default $TERM to tmux-256color
|
# Change the default $TERM to tmux-256color
|
||||||
set -g default-terminal "tmux-256color"
|
set -g default-terminal "tmux-256color"
|
||||||
|
|||||||
26
format.c
26
format.c
@@ -1136,8 +1136,7 @@ format_cb_mouse_word(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (!TAILQ_EMPTY(&wp->modes)) {
|
if (!TAILQ_EMPTY(&wp->modes)) {
|
||||||
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
|
if (window_pane_mode(wp) != WINDOW_PANE_NO_MODE)
|
||||||
TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
|
|
||||||
return (window_copy_get_word(wp, x, y));
|
return (window_copy_get_word(wp, x, y));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@@ -1181,8 +1180,7 @@ format_cb_mouse_line(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
|
|
||||||
if (!TAILQ_EMPTY(&wp->modes)) {
|
if (!TAILQ_EMPTY(&wp->modes)) {
|
||||||
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode ||
|
if (window_pane_mode(wp) != WINDOW_PANE_NO_MODE)
|
||||||
TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
|
|
||||||
return (window_copy_get_line(wp, y));
|
return (window_copy_get_line(wp, y));
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
@@ -1962,6 +1960,23 @@ format_cb_pane_unseen_changes(struct format_tree *ft)
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Callback for pane_key_mode. */
|
||||||
|
static void *
|
||||||
|
format_cb_pane_key_mode(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
if (ft->wp != NULL && ft->wp->screen != NULL) {
|
||||||
|
switch (ft->wp->screen->mode & EXTENDED_KEY_MODES) {
|
||||||
|
case MODE_KEYS_EXTENDED:
|
||||||
|
return (xstrdup("Ext 1"));
|
||||||
|
case MODE_KEYS_EXTENDED_2:
|
||||||
|
return (xstrdup("Ext 2"));
|
||||||
|
default:
|
||||||
|
return (xstrdup("VT10x"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
/* Callback for pane_last. */
|
/* Callback for pane_last. */
|
||||||
static void *
|
static void *
|
||||||
format_cb_pane_last(struct format_tree *ft)
|
format_cb_pane_last(struct format_tree *ft)
|
||||||
@@ -2997,6 +3012,9 @@ static const struct format_table_entry format_table[] = {
|
|||||||
{ "pane_input_off", FORMAT_TABLE_STRING,
|
{ "pane_input_off", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_input_off
|
format_cb_pane_input_off
|
||||||
},
|
},
|
||||||
|
{ "pane_key_mode", FORMAT_TABLE_STRING,
|
||||||
|
format_cb_pane_key_mode
|
||||||
|
},
|
||||||
{ "pane_last", FORMAT_TABLE_STRING,
|
{ "pane_last", FORMAT_TABLE_STRING,
|
||||||
format_cb_pane_last
|
format_cb_pane_last
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ LLVMFuzzerTestOneInput(const u_char *data, size_t size)
|
|||||||
int error;
|
int error;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Since AFL doesn't support -max_len paramenter we have to
|
* Since AFL doesn't support -max_len parameter we have to
|
||||||
* discard long inputs manually.
|
* discard long inputs manually.
|
||||||
*/
|
*/
|
||||||
if (size > FUZZER_MAXLEN)
|
if (size > FUZZER_MAXLEN)
|
||||||
|
|||||||
2
grid.c
2
grid.c
@@ -88,7 +88,7 @@ grid_need_extended_cell(const struct grid_cell_entry *gce,
|
|||||||
return (1);
|
return (1);
|
||||||
if ((gc->fg & COLOUR_FLAG_RGB) || (gc->bg & COLOUR_FLAG_RGB))
|
if ((gc->fg & COLOUR_FLAG_RGB) || (gc->bg & COLOUR_FLAG_RGB))
|
||||||
return (1);
|
return (1);
|
||||||
if (gc->us != 0) /* only supports 256 or RGB */
|
if (gc->us != 8) /* only supports 256 or RGB */
|
||||||
return (1);
|
return (1);
|
||||||
if (gc->link != 0)
|
if (gc->link != 0)
|
||||||
return (1);
|
return (1);
|
||||||
|
|||||||
16
hyperlinks.c
16
hyperlinks.c
@@ -68,6 +68,7 @@ struct hyperlinks {
|
|||||||
u_int next_inner;
|
u_int next_inner;
|
||||||
struct hyperlinks_by_inner_tree by_inner;
|
struct hyperlinks_by_inner_tree by_inner;
|
||||||
struct hyperlinks_by_uri_tree by_uri;
|
struct hyperlinks_by_uri_tree by_uri;
|
||||||
|
u_int references;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -205,6 +206,15 @@ hyperlinks_init(void)
|
|||||||
hl->next_inner = 1;
|
hl->next_inner = 1;
|
||||||
RB_INIT(&hl->by_uri);
|
RB_INIT(&hl->by_uri);
|
||||||
RB_INIT(&hl->by_inner);
|
RB_INIT(&hl->by_inner);
|
||||||
|
hl->references = 1;
|
||||||
|
return (hl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy hyperlink set. */
|
||||||
|
struct hyperlinks *
|
||||||
|
hyperlinks_copy(struct hyperlinks *hl)
|
||||||
|
{
|
||||||
|
hl->references++;
|
||||||
return (hl);
|
return (hl);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,6 +232,8 @@ hyperlinks_reset(struct hyperlinks *hl)
|
|||||||
void
|
void
|
||||||
hyperlinks_free(struct hyperlinks *hl)
|
hyperlinks_free(struct hyperlinks *hl)
|
||||||
{
|
{
|
||||||
hyperlinks_reset(hl);
|
if (--hl->references == 0) {
|
||||||
free(hl);
|
hyperlinks_reset(hl);
|
||||||
|
free(hl);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -489,6 +489,9 @@ sixel_print(struct sixel_image *si, struct sixel_image *map, size_t *size)
|
|||||||
colours = si->colours;
|
colours = si->colours;
|
||||||
ncolours = si->ncolours;
|
ncolours = si->ncolours;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ncolours == 0)
|
||||||
|
return (NULL);
|
||||||
contains = xcalloc(1, ncolours);
|
contains = xcalloc(1, ncolours);
|
||||||
|
|
||||||
len = 8192;
|
len = 8192;
|
||||||
|
|||||||
380
input-keys.c
380
input-keys.c
@@ -307,20 +307,6 @@ static struct input_key_entry input_key_defaults[] = {
|
|||||||
{ .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
|
{ .key = KEYC_DC|KEYC_BUILD_MODIFIERS,
|
||||||
.data = "\033[3;_~"
|
.data = "\033[3;_~"
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Tab and modifiers. */
|
|
||||||
{ .key = '\011'|KEYC_CTRL,
|
|
||||||
.data = "\011"
|
|
||||||
},
|
|
||||||
{ .key = '\011'|KEYC_CTRL|KEYC_EXTENDED,
|
|
||||||
.data = "\033[9;5u"
|
|
||||||
},
|
|
||||||
{ .key = '\011'|KEYC_CTRL|KEYC_SHIFT,
|
|
||||||
.data = "\033[Z"
|
|
||||||
},
|
|
||||||
{ .key = '\011'|KEYC_CTRL|KEYC_SHIFT|KEYC_EXTENDED,
|
|
||||||
.data = "\033[1;5Z"
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
static const key_code input_key_modifiers[] = {
|
static const key_code input_key_modifiers[] = {
|
||||||
0,
|
0,
|
||||||
@@ -426,126 +412,18 @@ input_key_write(const char *from, struct bufferevent *bev, const char *data,
|
|||||||
bufferevent_write(bev, data, size);
|
bufferevent_write(bev, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate a key code into an output key sequence. */
|
/*
|
||||||
int
|
* Encode and write an extended key escape sequence in one of the two
|
||||||
input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
* possible formats, depending on the configured output mode.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
input_key_extended(struct bufferevent *bev, key_code key)
|
||||||
{
|
{
|
||||||
struct input_key_entry *ike = NULL;
|
char tmp[64], modifier;
|
||||||
key_code justkey, newkey, outkey, modifiers;
|
struct utf8_data ud;
|
||||||
struct utf8_data ud;
|
wchar_t wc;
|
||||||
char tmp[64], modifier;
|
|
||||||
|
|
||||||
/* Mouse keys need a pane. */
|
switch (key & KEYC_MASK_MODIFIERS) {
|
||||||
if (KEYC_IS_MOUSE(key))
|
|
||||||
return (0);
|
|
||||||
|
|
||||||
/* Literal keys go as themselves (can't be more than eight bits). */
|
|
||||||
if (key & KEYC_LITERAL) {
|
|
||||||
ud.data[0] = (u_char)key;
|
|
||||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Is this backspace? */
|
|
||||||
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
|
|
||||||
newkey = options_get_number(global_options, "backspace");
|
|
||||||
if (newkey >= 0x7f)
|
|
||||||
newkey = '\177';
|
|
||||||
key = newkey|(key & (KEYC_MASK_MODIFIERS|KEYC_MASK_FLAGS));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If this is a normal 7-bit key, just send it, with a leading escape
|
|
||||||
* if necessary. If it is a UTF-8 key, split it and send it.
|
|
||||||
*/
|
|
||||||
justkey = (key & ~(KEYC_META|KEYC_IMPLIED_META));
|
|
||||||
if (justkey <= 0x7f) {
|
|
||||||
if (key & KEYC_META)
|
|
||||||
input_key_write(__func__, bev, "\033", 1);
|
|
||||||
ud.data[0] = justkey;
|
|
||||||
input_key_write(__func__, bev, &ud.data[0], 1);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
if (KEYC_IS_UNICODE(justkey)) {
|
|
||||||
if (key & KEYC_META)
|
|
||||||
input_key_write(__func__, bev, "\033", 1);
|
|
||||||
utf8_to_data(justkey, &ud);
|
|
||||||
input_key_write(__func__, bev, ud.data, ud.size);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Look up in the tree. If not in application keypad or cursor mode,
|
|
||||||
* remove the flags from the key.
|
|
||||||
*/
|
|
||||||
if (~s->mode & MODE_KKEYPAD)
|
|
||||||
key &= ~KEYC_KEYPAD;
|
|
||||||
if (~s->mode & MODE_KCURSOR)
|
|
||||||
key &= ~KEYC_CURSOR;
|
|
||||||
if (s->mode & MODE_KEXTENDED)
|
|
||||||
ike = input_key_get(key|KEYC_EXTENDED);
|
|
||||||
if (ike == NULL)
|
|
||||||
ike = input_key_get(key);
|
|
||||||
if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
|
||||||
ike = input_key_get(key & ~KEYC_META);
|
|
||||||
if (ike == NULL && (key & KEYC_CURSOR))
|
|
||||||
ike = input_key_get(key & ~KEYC_CURSOR);
|
|
||||||
if (ike == NULL && (key & KEYC_KEYPAD))
|
|
||||||
ike = input_key_get(key & ~KEYC_KEYPAD);
|
|
||||||
if (ike == NULL && (key & KEYC_EXTENDED))
|
|
||||||
ike = input_key_get(key & ~KEYC_EXTENDED);
|
|
||||||
if (ike != NULL) {
|
|
||||||
log_debug("found key 0x%llx: \"%s\"", key, ike->data);
|
|
||||||
if ((key == KEYC_PASTE_START || key == KEYC_PASTE_END) &&
|
|
||||||
(~s->mode & MODE_BRACKETPASTE))
|
|
||||||
return (0);
|
|
||||||
if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
|
||||||
input_key_write(__func__, bev, "\033", 1);
|
|
||||||
input_key_write(__func__, bev, ike->data, strlen(ike->data));
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* No builtin key sequence; construct an extended key sequence. */
|
|
||||||
if (~s->mode & MODE_KEXTENDED) {
|
|
||||||
if ((key & KEYC_MASK_MODIFIERS) != KEYC_CTRL)
|
|
||||||
goto missing;
|
|
||||||
justkey = (key & KEYC_MASK_KEY);
|
|
||||||
switch (justkey) {
|
|
||||||
case ' ':
|
|
||||||
case '2':
|
|
||||||
key = 0|(key & ~KEYC_MASK_KEY);
|
|
||||||
break;
|
|
||||||
case '|':
|
|
||||||
key = 28|(key & ~KEYC_MASK_KEY);
|
|
||||||
break;
|
|
||||||
case '6':
|
|
||||||
key = 30|(key & ~KEYC_MASK_KEY);
|
|
||||||
break;
|
|
||||||
case '-':
|
|
||||||
case '/':
|
|
||||||
key = 31|(key & ~KEYC_MASK_KEY);
|
|
||||||
break;
|
|
||||||
case '?':
|
|
||||||
key = 127|(key & ~KEYC_MASK_KEY);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (justkey >= 'A' && justkey <= '_')
|
|
||||||
key = (justkey - 'A')|(key & ~KEYC_MASK_KEY);
|
|
||||||
else if (justkey >= 'a' && justkey <= '~')
|
|
||||||
key = (justkey - 96)|(key & ~KEYC_MASK_KEY);
|
|
||||||
else
|
|
||||||
return (0);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return (input_key(s, bev, key & ~KEYC_CTRL));
|
|
||||||
}
|
|
||||||
outkey = (key & KEYC_MASK_KEY);
|
|
||||||
modifiers = (key & KEYC_MASK_MODIFIERS);
|
|
||||||
if (outkey < 32 && outkey != 9 && outkey != 13 && outkey != 27) {
|
|
||||||
outkey = 64 + outkey;
|
|
||||||
modifiers |= KEYC_CTRL;
|
|
||||||
}
|
|
||||||
switch (modifiers) {
|
|
||||||
case KEYC_SHIFT:
|
case KEYC_SHIFT:
|
||||||
modifier = '2';
|
modifier = '2';
|
||||||
break;
|
break;
|
||||||
@@ -568,17 +446,247 @@ input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
|||||||
modifier = '8';
|
modifier = '8';
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
goto missing;
|
return (-1);
|
||||||
}
|
}
|
||||||
xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", outkey, modifier);
|
|
||||||
|
if (KEYC_IS_UNICODE(key)) {
|
||||||
|
utf8_to_data(key & KEYC_MASK_KEY, &ud);
|
||||||
|
if (utf8_towc(&ud, &wc) == UTF8_DONE)
|
||||||
|
key = wc;
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
} else
|
||||||
|
key &= KEYC_MASK_KEY;
|
||||||
|
|
||||||
|
if (options_get_number(global_options, "extended-keys-format") == 1)
|
||||||
|
xsnprintf(tmp, sizeof tmp, "\033[27;%c;%llu~", modifier, key);
|
||||||
|
else
|
||||||
|
xsnprintf(tmp, sizeof tmp, "\033[%llu;%cu", key, modifier);
|
||||||
|
|
||||||
input_key_write(__func__, bev, tmp, strlen(tmp));
|
input_key_write(__func__, bev, tmp, strlen(tmp));
|
||||||
return (0);
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Outputs the key in the "standard" mode. This is by far the most
|
||||||
|
* complicated output mode, with a lot of remapping in order to
|
||||||
|
* emulate quirks of terminals that today can be only found in museums.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
input_key_vt10x(struct bufferevent *bev, key_code key)
|
||||||
|
{
|
||||||
|
struct utf8_data ud;
|
||||||
|
key_code onlykey;
|
||||||
|
char *p;
|
||||||
|
static const char *standard_map[2] = {
|
||||||
|
"1!9(0)=+;:'\",<.>/-8? 2",
|
||||||
|
"119900=+;;'',,..\x1f\x1f\x7f\x7f\0\0",
|
||||||
|
};
|
||||||
|
|
||||||
|
log_debug("%s: key in %llx", __func__, key);
|
||||||
|
|
||||||
|
if (key & KEYC_META)
|
||||||
|
input_key_write(__func__, bev, "\033", 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* There's no way to report modifiers for unicode keys in standard mode
|
||||||
|
* so lose the modifiers.
|
||||||
|
*/
|
||||||
|
if (KEYC_IS_UNICODE(key)) {
|
||||||
|
utf8_to_data(key, &ud);
|
||||||
|
input_key_write(__func__, bev, ud.data, ud.size);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prevent TAB and RET from being swallowed by C0 remapping logic. */
|
||||||
|
onlykey = key & KEYC_MASK_KEY;
|
||||||
|
if (onlykey == '\r' || onlykey == '\t')
|
||||||
|
key &= ~KEYC_CTRL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Convert keys with Ctrl modifier into corresponding C0 control codes,
|
||||||
|
* with the exception of *some* keys, which are remapped into printable
|
||||||
|
* ASCII characters.
|
||||||
|
*
|
||||||
|
* There is no special handling for Shift modifier, which is pretty
|
||||||
|
* much redundant anyway, as no terminal will send <base key>|SHIFT,
|
||||||
|
* but only <shifted key>|SHIFT.
|
||||||
|
*/
|
||||||
|
if (key & KEYC_CTRL) {
|
||||||
|
p = strchr(standard_map[0], onlykey);
|
||||||
|
if (p != NULL)
|
||||||
|
key = standard_map[1][p - standard_map[0]];
|
||||||
|
else if (onlykey >= '3' && onlykey <= '7')
|
||||||
|
key = onlykey - '\030';
|
||||||
|
else if (onlykey >= '@' && onlykey <= '~')
|
||||||
|
key = onlykey & 0x1f;
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
log_debug("%s: key out %llx", __func__, key);
|
||||||
|
|
||||||
|
ud.data[0] = key & 0x7f;
|
||||||
|
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pick keys that are reported as vt10x keys in modifyOtherKeys=1 mode. */
|
||||||
|
static int
|
||||||
|
input_key_mode1(struct bufferevent *bev, key_code key)
|
||||||
|
{
|
||||||
|
key_code onlykey;
|
||||||
|
|
||||||
|
log_debug("%s: key in %llx", __func__, key);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* As per
|
||||||
|
* https://invisible-island.net/xterm/modified-keys-us-pc105.html.
|
||||||
|
*/
|
||||||
|
onlykey = key & KEYC_MASK_KEY;
|
||||||
|
if ((key & (KEYC_META | KEYC_CTRL)) == KEYC_CTRL &&
|
||||||
|
(onlykey == ' ' ||
|
||||||
|
onlykey == '/' ||
|
||||||
|
onlykey == '@' ||
|
||||||
|
onlykey == '^' ||
|
||||||
|
(onlykey >= '2' && onlykey <= '8') ||
|
||||||
|
(onlykey >= '@' && onlykey <= '~')))
|
||||||
|
return (input_key_vt10x(bev, key));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A regular key + Meta. In the absence of a standard to back this, we
|
||||||
|
* mimic what iTerm 2 does.
|
||||||
|
*/
|
||||||
|
if ((key & (KEYC_CTRL | KEYC_META)) == KEYC_META)
|
||||||
|
return (input_key_vt10x(bev, key));
|
||||||
|
|
||||||
missing:
|
|
||||||
log_debug("key 0x%llx missing", key);
|
|
||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Translate a key code into an output key sequence. */
|
||||||
|
int
|
||||||
|
input_key(struct screen *s, struct bufferevent *bev, key_code key)
|
||||||
|
{
|
||||||
|
struct input_key_entry *ike = NULL;
|
||||||
|
key_code newkey;
|
||||||
|
struct utf8_data ud;
|
||||||
|
|
||||||
|
/* Mouse keys need a pane. */
|
||||||
|
if (KEYC_IS_MOUSE(key))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
/* Literal keys go as themselves (can't be more than eight bits). */
|
||||||
|
if (key & KEYC_LITERAL) {
|
||||||
|
ud.data[0] = (u_char)key;
|
||||||
|
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is this backspace? */
|
||||||
|
if ((key & KEYC_MASK_KEY) == KEYC_BSPACE) {
|
||||||
|
newkey = options_get_number(global_options, "backspace");
|
||||||
|
if (newkey >= 0x7f)
|
||||||
|
newkey = '\177';
|
||||||
|
key = newkey|(key & (KEYC_MASK_MODIFIERS|KEYC_MASK_FLAGS));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Is this backtab? */
|
||||||
|
if ((key & KEYC_MASK_KEY) == KEYC_BTAB) {
|
||||||
|
if ((s->mode & EXTENDED_KEY_MODES) != 0) {
|
||||||
|
/* When in xterm extended mode, remap into S-Tab. */
|
||||||
|
key = '\011' | (key & ~KEYC_MASK_KEY) | KEYC_SHIFT;
|
||||||
|
} else {
|
||||||
|
/* Otherwise clear modifiers. */
|
||||||
|
key &= ~KEYC_MASK_MODIFIERS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* A trivial case, that is a 7-bit key, excluding C0 control characters
|
||||||
|
* that can't be entered from the keyboard, and no modifiers; or a UTF-8
|
||||||
|
* key and no modifiers.
|
||||||
|
*/
|
||||||
|
if (!(key & ~KEYC_MASK_KEY)) {
|
||||||
|
if (key == C0_HT ||
|
||||||
|
key == C0_CR ||
|
||||||
|
key == C0_ESC ||
|
||||||
|
(key >= 0x20 && key <= 0x7f)) {
|
||||||
|
ud.data[0] = key;
|
||||||
|
input_key_write(__func__, bev, &ud.data[0], 1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (KEYC_IS_UNICODE(key)) {
|
||||||
|
utf8_to_data(key, &ud);
|
||||||
|
input_key_write(__func__, bev, ud.data, ud.size);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Look up the standard VT10x keys in the tree. If not in application
|
||||||
|
* keypad or cursor mode, remove the respective flags from the key.
|
||||||
|
*/
|
||||||
|
if (~s->mode & MODE_KKEYPAD)
|
||||||
|
key &= ~KEYC_KEYPAD;
|
||||||
|
if (~s->mode & MODE_KCURSOR)
|
||||||
|
key &= ~KEYC_CURSOR;
|
||||||
|
if (ike == NULL)
|
||||||
|
ike = input_key_get(key);
|
||||||
|
if (ike == NULL && (key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||||
|
ike = input_key_get(key & ~KEYC_META);
|
||||||
|
if (ike == NULL && (key & KEYC_CURSOR))
|
||||||
|
ike = input_key_get(key & ~KEYC_CURSOR);
|
||||||
|
if (ike == NULL && (key & KEYC_KEYPAD))
|
||||||
|
ike = input_key_get(key & ~KEYC_KEYPAD);
|
||||||
|
if (ike != NULL) {
|
||||||
|
log_debug("%s: found key 0x%llx: \"%s\"", __func__, key,
|
||||||
|
ike->data);
|
||||||
|
if ((key == KEYC_PASTE_START || key == KEYC_PASTE_END) &&
|
||||||
|
(~s->mode & MODE_BRACKETPASTE))
|
||||||
|
return (0);
|
||||||
|
if ((key & KEYC_META) && (~key & KEYC_IMPLIED_META))
|
||||||
|
input_key_write(__func__, bev, "\033", 1);
|
||||||
|
input_key_write(__func__, bev, ike->data, strlen(ike->data));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ignore internal function key codes. */
|
||||||
|
if ((key >= KEYC_BASE && key < KEYC_BASE_END) ||
|
||||||
|
(key >= KEYC_USER && key < KEYC_USER_END)) {
|
||||||
|
log_debug("%s: ignoring key 0x%llx", __func__, key);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No builtin key sequence; construct an extended key sequence
|
||||||
|
* depending on the client mode.
|
||||||
|
*
|
||||||
|
* If something invalid reaches here, an invalid output may be
|
||||||
|
* produced. For example Ctrl-Shift-2 is invalid (as there's
|
||||||
|
* no way to enter it). The correct form is Ctrl-Shift-@, at
|
||||||
|
* least in US English keyboard layout.
|
||||||
|
*/
|
||||||
|
switch (s->mode & EXTENDED_KEY_MODES) {
|
||||||
|
case MODE_KEYS_EXTENDED_2:
|
||||||
|
/*
|
||||||
|
* The simplest mode to handle - *all* modified keys are
|
||||||
|
* reported in the extended form.
|
||||||
|
*/
|
||||||
|
return (input_key_extended(bev, key));
|
||||||
|
case MODE_KEYS_EXTENDED:
|
||||||
|
/*
|
||||||
|
* Some keys are still reported in standard mode, to maintain
|
||||||
|
* compatibility with applications unaware of extended keys.
|
||||||
|
*/
|
||||||
|
if (input_key_mode1(bev, key) == -1)
|
||||||
|
return (input_key_extended(bev, key));
|
||||||
|
return (0);
|
||||||
|
default:
|
||||||
|
/* The standard mode. */
|
||||||
|
return (input_key_vt10x(bev, key));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Get mouse event string. */
|
/* Get mouse event string. */
|
||||||
int
|
int
|
||||||
input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
|
input_key_get_mouse(struct screen *s, struct mouse_event *m, u_int x, u_int y,
|
||||||
|
|||||||
140
input.c
140
input.c
@@ -109,10 +109,11 @@ struct input_ctx {
|
|||||||
int utf8started;
|
int utf8started;
|
||||||
|
|
||||||
int ch;
|
int ch;
|
||||||
int last;
|
struct utf8_data last;
|
||||||
|
|
||||||
int flags;
|
int flags;
|
||||||
#define INPUT_DISCARD 0x1
|
#define INPUT_DISCARD 0x1
|
||||||
|
#define INPUT_LAST 0x2
|
||||||
|
|
||||||
const struct input_state *state;
|
const struct input_state *state;
|
||||||
|
|
||||||
@@ -867,8 +868,6 @@ input_reset(struct input_ctx *ictx, int clear)
|
|||||||
|
|
||||||
input_clear(ictx);
|
input_clear(ictx);
|
||||||
|
|
||||||
ictx->last = -1;
|
|
||||||
|
|
||||||
ictx->state = &input_state_ground;
|
ictx->state = &input_state_ground;
|
||||||
ictx->flags = 0;
|
ictx->flags = 0;
|
||||||
}
|
}
|
||||||
@@ -1149,7 +1148,9 @@ input_print(struct input_ctx *ictx)
|
|||||||
|
|
||||||
utf8_set(&ictx->cell.cell.data, ictx->ch);
|
utf8_set(&ictx->cell.cell.data, ictx->ch);
|
||||||
screen_write_collect_add(sctx, &ictx->cell.cell);
|
screen_write_collect_add(sctx, &ictx->cell.cell);
|
||||||
ictx->last = ictx->ch;
|
|
||||||
|
utf8_copy(&ictx->last, &ictx->cell.cell.data);
|
||||||
|
ictx->flags |= INPUT_LAST;
|
||||||
|
|
||||||
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
ictx->cell.cell.attr &= ~GRID_ATTR_CHARSET;
|
||||||
|
|
||||||
@@ -1261,7 +1262,7 @@ input_c0_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1337,7 +1338,7 @@ input_esc_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1348,7 +1349,7 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
struct screen *s = sctx->s;
|
struct screen *s = sctx->s;
|
||||||
struct input_table_entry *entry;
|
struct input_table_entry *entry;
|
||||||
int i, n, m;
|
int i, n, m, ek;
|
||||||
u_int cx, bg = ictx->cell.cell.bg;
|
u_int cx, bg = ictx->cell.cell.bg;
|
||||||
|
|
||||||
if (ictx->flags & INPUT_DISCARD)
|
if (ictx->flags & INPUT_DISCARD)
|
||||||
@@ -1406,18 +1407,36 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
break;
|
break;
|
||||||
case INPUT_CSI_MODSET:
|
case INPUT_CSI_MODSET:
|
||||||
n = input_get(ictx, 0, 0, 0);
|
n = input_get(ictx, 0, 0, 0);
|
||||||
m = input_get(ictx, 1, 0, 0);
|
if (n != 4)
|
||||||
if (options_get_number(global_options, "extended-keys") == 2)
|
|
||||||
break;
|
break;
|
||||||
if (n == 0 || (n == 4 && m == 0))
|
m = input_get(ictx, 1, 0, 0);
|
||||||
screen_write_mode_clear(sctx, MODE_KEXTENDED);
|
|
||||||
else if (n == 4 && (m == 1 || m == 2))
|
/*
|
||||||
screen_write_mode_set(sctx, MODE_KEXTENDED);
|
* Set the extended key reporting mode as per the client
|
||||||
|
* request, unless "extended-keys" is set to "off".
|
||||||
|
*/
|
||||||
|
ek = options_get_number(global_options, "extended-keys");
|
||||||
|
if (ek == 0)
|
||||||
|
break;
|
||||||
|
screen_write_mode_clear(sctx, EXTENDED_KEY_MODES);
|
||||||
|
if (m == 2)
|
||||||
|
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED_2);
|
||||||
|
else if (m == 1 || ek == 2)
|
||||||
|
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_MODOFF:
|
case INPUT_CSI_MODOFF:
|
||||||
n = input_get(ictx, 0, 0, 0);
|
n = input_get(ictx, 0, 0, 0);
|
||||||
if (n == 4)
|
if (n != 4)
|
||||||
screen_write_mode_clear(sctx, MODE_KEXTENDED);
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Clear the extended key reporting mode as per the client
|
||||||
|
* request, unless "extended-keys always" forces into mode 1.
|
||||||
|
*/
|
||||||
|
screen_write_mode_clear(sctx,
|
||||||
|
MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2);
|
||||||
|
if (options_get_number(global_options, "extended-keys") == 2)
|
||||||
|
screen_write_mode_set(sctx, MODE_KEYS_EXTENDED);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_WINOPS:
|
case INPUT_CSI_WINOPS:
|
||||||
input_csi_dispatch_winops(ictx);
|
input_csi_dispatch_winops(ictx);
|
||||||
@@ -1574,12 +1593,12 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
if (n > m)
|
if (n > m)
|
||||||
n = m;
|
n = m;
|
||||||
|
|
||||||
if (ictx->last == -1)
|
if (~ictx->flags & INPUT_LAST)
|
||||||
break;
|
break;
|
||||||
ictx->ch = ictx->last;
|
|
||||||
|
|
||||||
|
utf8_copy(&ictx->cell.cell.data, &ictx->last);
|
||||||
for (i = 0; i < n; i++)
|
for (i = 0; i < n; i++)
|
||||||
input_print(ictx);
|
screen_write_collect_add(sctx, &ictx->cell.cell);
|
||||||
break;
|
break;
|
||||||
case INPUT_CSI_RCP:
|
case INPUT_CSI_RCP:
|
||||||
input_restore_state(ictx);
|
input_restore_state(ictx);
|
||||||
@@ -1649,7 +1668,7 @@ input_csi_dispatch(struct input_ctx *ictx)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1839,7 +1858,7 @@ input_csi_dispatch_sm_private(struct input_ctx *ictx)
|
|||||||
|
|
||||||
/* Handle CSI graphics SM. */
|
/* Handle CSI graphics SM. */
|
||||||
static void
|
static void
|
||||||
input_csi_dispatch_sm_graphics(struct input_ctx *ictx)
|
input_csi_dispatch_sm_graphics(__unused struct input_ctx *ictx)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
int n, m, o;
|
int n, m, o;
|
||||||
@@ -2284,7 +2303,7 @@ input_enter_dcs(struct input_ctx *ictx)
|
|||||||
|
|
||||||
input_clear(ictx);
|
input_clear(ictx);
|
||||||
input_start_timer(ictx);
|
input_start_timer(ictx);
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* DCS terminator (ST) received. */
|
/* DCS terminator (ST) received. */
|
||||||
@@ -2341,7 +2360,7 @@ input_enter_osc(struct input_ctx *ictx)
|
|||||||
|
|
||||||
input_clear(ictx);
|
input_clear(ictx);
|
||||||
input_start_timer(ictx);
|
input_start_timer(ictx);
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSC terminator (ST) received. */
|
/* OSC terminator (ST) received. */
|
||||||
@@ -2372,7 +2391,9 @@ input_exit_osc(struct input_ctx *ictx)
|
|||||||
switch (option) {
|
switch (option) {
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
if (screen_set_title(sctx->s, p) && wp != NULL) {
|
if (wp != NULL &&
|
||||||
|
options_get_number(wp->options, "allow-set-title") &&
|
||||||
|
screen_set_title(sctx->s, p)) {
|
||||||
notify_pane("pane-title-changed", wp);
|
notify_pane("pane-title-changed", wp);
|
||||||
server_redraw_window_borders(wp->window);
|
server_redraw_window_borders(wp->window);
|
||||||
server_status_window(wp->window);
|
server_status_window(wp->window);
|
||||||
@@ -2434,7 +2455,7 @@ input_enter_apc(struct input_ctx *ictx)
|
|||||||
|
|
||||||
input_clear(ictx);
|
input_clear(ictx);
|
||||||
input_start_timer(ictx);
|
input_start_timer(ictx);
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* APC terminator (ST) received. */
|
/* APC terminator (ST) received. */
|
||||||
@@ -2463,7 +2484,7 @@ input_enter_rename(struct input_ctx *ictx)
|
|||||||
|
|
||||||
input_clear(ictx);
|
input_clear(ictx);
|
||||||
input_start_timer(ictx);
|
input_start_timer(ictx);
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Rename terminator (ST) received. */
|
/* Rename terminator (ST) received. */
|
||||||
@@ -2507,7 +2528,7 @@ input_top_bit_set(struct input_ctx *ictx)
|
|||||||
struct screen_write_ctx *sctx = &ictx->ctx;
|
struct screen_write_ctx *sctx = &ictx->ctx;
|
||||||
struct utf8_data *ud = &ictx->utf8data;
|
struct utf8_data *ud = &ictx->utf8data;
|
||||||
|
|
||||||
ictx->last = -1;
|
ictx->flags &= ~INPUT_LAST;
|
||||||
|
|
||||||
if (!ictx->utf8started) {
|
if (!ictx->utf8started) {
|
||||||
if (utf8_open(ud, ictx->ch) != UTF8_MORE)
|
if (utf8_open(ud, ictx->ch) != UTF8_MORE)
|
||||||
@@ -2533,6 +2554,9 @@ input_top_bit_set(struct input_ctx *ictx)
|
|||||||
utf8_copy(&ictx->cell.cell.data, ud);
|
utf8_copy(&ictx->cell.cell.data, ud);
|
||||||
screen_write_collect_add(sctx, &ictx->cell.cell);
|
screen_write_collect_add(sctx, &ictx->cell.cell);
|
||||||
|
|
||||||
|
utf8_copy(&ictx->last, &ictx->cell.cell.data);
|
||||||
|
ictx->flags |= INPUT_LAST;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2681,6 +2705,44 @@ input_get_bg_client(struct window_pane *wp)
|
|||||||
return (-1);
|
return (-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any control mode client exists that has provided a bg color, return it.
|
||||||
|
* Otherwise, return -1.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
input_get_bg_control_client(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct client *c;
|
||||||
|
|
||||||
|
if (wp->control_bg == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
|
if (c->flags & CLIENT_CONTROL)
|
||||||
|
return (wp->control_bg);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If any control mode client exists that has provided a fg color, return it.
|
||||||
|
* Otherwise, return -1.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
input_get_fg_control_client(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
struct client *c;
|
||||||
|
|
||||||
|
if (wp->control_fg == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
TAILQ_FOREACH(c, &clients, entry) {
|
||||||
|
if (c->flags & CLIENT_CONTROL)
|
||||||
|
return (wp->control_fg);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle the OSC 10 sequence for setting and querying foreground colour. */
|
/* Handle the OSC 10 sequence for setting and querying foreground colour. */
|
||||||
static void
|
static void
|
||||||
input_osc_10(struct input_ctx *ictx, const char *p)
|
input_osc_10(struct input_ctx *ictx, const char *p)
|
||||||
@@ -2692,11 +2754,14 @@ input_osc_10(struct input_ctx *ictx, const char *p)
|
|||||||
if (strcmp(p, "?") == 0) {
|
if (strcmp(p, "?") == 0) {
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return;
|
return;
|
||||||
tty_default_colours(&defaults, wp);
|
c = input_get_fg_control_client(wp);
|
||||||
if (COLOUR_DEFAULT(defaults.fg))
|
if (c == -1) {
|
||||||
c = input_get_fg_client(wp);
|
tty_default_colours(&defaults, wp);
|
||||||
else
|
if (COLOUR_DEFAULT(defaults.fg))
|
||||||
c = defaults.fg;
|
c = input_get_fg_client(wp);
|
||||||
|
else
|
||||||
|
c = defaults.fg;
|
||||||
|
}
|
||||||
input_osc_colour_reply(ictx, 10, c);
|
input_osc_colour_reply(ictx, 10, c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -2740,11 +2805,14 @@ input_osc_11(struct input_ctx *ictx, const char *p)
|
|||||||
if (strcmp(p, "?") == 0) {
|
if (strcmp(p, "?") == 0) {
|
||||||
if (wp == NULL)
|
if (wp == NULL)
|
||||||
return;
|
return;
|
||||||
tty_default_colours(&defaults, wp);
|
c = input_get_bg_control_client(wp);
|
||||||
if (COLOUR_DEFAULT(defaults.bg))
|
if (c == -1) {
|
||||||
c = input_get_bg_client(wp);
|
tty_default_colours(&defaults, wp);
|
||||||
else
|
if (COLOUR_DEFAULT(defaults.bg))
|
||||||
c = defaults.bg;
|
c = input_get_bg_client(wp);
|
||||||
|
else
|
||||||
|
c = defaults.bg;
|
||||||
|
}
|
||||||
input_osc_colour_reply(ictx, 11, c);
|
input_osc_colour_reply(ictx, 11, c);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
31
job.c
31
job.c
@@ -77,19 +77,28 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
|
|||||||
struct environ *env;
|
struct environ *env;
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
int nullfd, out[2], master;
|
int nullfd, out[2], master;
|
||||||
const char *home;
|
const char *home, *shell;
|
||||||
sigset_t set, oldset;
|
sigset_t set, oldset;
|
||||||
struct winsize ws;
|
struct winsize ws;
|
||||||
char **argvp, tty[TTY_NAME_MAX];
|
char **argvp, tty[TTY_NAME_MAX], *argv0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not set TERM during .tmux.conf, it is nice to be able to use
|
* Do not set TERM during .tmux.conf (second argument here), it is nice
|
||||||
* if-shell to decide on default-terminal based on outside TERM.
|
* to be able to use if-shell to decide on default-terminal based on
|
||||||
|
* outside TERM.
|
||||||
*/
|
*/
|
||||||
env = environ_for_session(s, !cfg_finished);
|
env = environ_for_session(s, !cfg_finished);
|
||||||
if (e != NULL)
|
if (e != NULL)
|
||||||
environ_copy(e, env);
|
environ_copy(e, env);
|
||||||
|
|
||||||
|
if (s != NULL)
|
||||||
|
shell = options_get_string(s->options, "default-shell");
|
||||||
|
else
|
||||||
|
shell = options_get_string(global_s_options, "default-shell");
|
||||||
|
if (!checkshell(shell))
|
||||||
|
shell = _PATH_BSHELL;
|
||||||
|
argv0 = shell_argv0(shell, 0);
|
||||||
|
|
||||||
sigfillset(&set);
|
sigfillset(&set);
|
||||||
sigprocmask(SIG_BLOCK, &set, &oldset);
|
sigprocmask(SIG_BLOCK, &set, &oldset);
|
||||||
|
|
||||||
@@ -105,10 +114,11 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
|
|||||||
}
|
}
|
||||||
if (cmd == NULL) {
|
if (cmd == NULL) {
|
||||||
cmd_log_argv(argc, argv, "%s:", __func__);
|
cmd_log_argv(argc, argv, "%s:", __func__);
|
||||||
log_debug("%s: cwd=%s", __func__, cwd == NULL ? "" : cwd);
|
log_debug("%s: cwd=%s, shell=%s", __func__,
|
||||||
|
cwd == NULL ? "" : cwd, shell);
|
||||||
} else {
|
} else {
|
||||||
log_debug("%s: cmd=%s, cwd=%s", __func__, cmd,
|
log_debug("%s: cmd=%s, cwd=%s, shell=%s", __func__, cmd,
|
||||||
cwd == NULL ? "" : cwd);
|
cwd == NULL ? "" : cwd, shell);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (pid) {
|
switch (pid) {
|
||||||
@@ -150,7 +160,8 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
|
|||||||
closefrom(STDERR_FILENO + 1);
|
closefrom(STDERR_FILENO + 1);
|
||||||
|
|
||||||
if (cmd != NULL) {
|
if (cmd != NULL) {
|
||||||
execl(_PATH_BSHELL, "sh", "-c", cmd, (char *) NULL);
|
setenv("SHELL", shell, 1);
|
||||||
|
execl(shell, argv0, "-c", cmd, (char *)NULL);
|
||||||
fatal("execl failed");
|
fatal("execl failed");
|
||||||
} else {
|
} else {
|
||||||
argvp = cmd_copy_argv(argc, argv);
|
argvp = cmd_copy_argv(argc, argv);
|
||||||
@@ -161,6 +172,7 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
|
|||||||
|
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
environ_free(env);
|
environ_free(env);
|
||||||
|
free(argv0);
|
||||||
|
|
||||||
job = xmalloc(sizeof *job);
|
job = xmalloc(sizeof *job);
|
||||||
job->state = JOB_RUNNING;
|
job->state = JOB_RUNNING;
|
||||||
@@ -194,12 +206,13 @@ job_run(const char *cmd, int argc, char **argv, struct environ *e, struct sessio
|
|||||||
fatalx("out of memory");
|
fatalx("out of memory");
|
||||||
bufferevent_enable(job->event, EV_READ|EV_WRITE);
|
bufferevent_enable(job->event, EV_READ|EV_WRITE);
|
||||||
|
|
||||||
log_debug("run job %p: %s, pid %ld", job, job->cmd, (long) job->pid);
|
log_debug("run job %p: %s, pid %ld", job, job->cmd, (long)job->pid);
|
||||||
return (job);
|
return (job);
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
sigprocmask(SIG_SETMASK, &oldset, NULL);
|
||||||
environ_free(env);
|
environ_free(env);
|
||||||
|
free(argv0);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -413,6 +413,8 @@ key_bindings_init(void)
|
|||||||
"bind -N 'Set the main-horizontal layout' M-3 { select-layout main-horizontal }",
|
"bind -N 'Set the main-horizontal layout' M-3 { select-layout main-horizontal }",
|
||||||
"bind -N 'Set the main-vertical layout' M-4 { select-layout main-vertical }",
|
"bind -N 'Set the main-vertical layout' M-4 { select-layout main-vertical }",
|
||||||
"bind -N 'Select the tiled layout' M-5 { select-layout tiled }",
|
"bind -N 'Select the tiled layout' M-5 { select-layout tiled }",
|
||||||
|
"bind -N 'Set the main-horizontal-mirrored layout' M-6 { select-layout main-horizontal-mirrored }",
|
||||||
|
"bind -N 'Set the main-vertical-mirrored layout' M-7 { select-layout main-vertical-mirrored }",
|
||||||
"bind -N 'Select the next window with an alert' M-n { next-window -a }",
|
"bind -N 'Select the next window with an alert' M-n { next-window -a }",
|
||||||
"bind -N 'Rotate through the panes in reverse' M-o { rotate-window -D }",
|
"bind -N 'Rotate through the panes in reverse' M-o { rotate-window -D }",
|
||||||
"bind -N 'Select the previous window with an alert' M-p { previous-window -a }",
|
"bind -N 'Select the previous window with an alert' M-p { previous-window -a }",
|
||||||
|
|||||||
89
key-string.c
89
key-string.c
@@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
@@ -56,12 +57,47 @@ static const struct {
|
|||||||
{ "PPage", KEYC_PPAGE|KEYC_IMPLIED_META },
|
{ "PPage", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||||
{ "PageUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
{ "PageUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||||
{ "PgUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
{ "PgUp", KEYC_PPAGE|KEYC_IMPLIED_META },
|
||||||
{ "Tab", '\011' },
|
|
||||||
{ "BTab", KEYC_BTAB },
|
{ "BTab", KEYC_BTAB },
|
||||||
{ "Space", ' ' },
|
{ "Space", ' ' },
|
||||||
{ "BSpace", KEYC_BSPACE },
|
{ "BSpace", KEYC_BSPACE },
|
||||||
{ "Enter", '\r' },
|
|
||||||
{ "Escape", '\033' },
|
/*
|
||||||
|
* C0 control characters, with the exception of Tab, Enter,
|
||||||
|
* and Esc, should never appear as keys. We still render them,
|
||||||
|
* so to be able to spot them in logs in case of an abnormality.
|
||||||
|
*/
|
||||||
|
{ "[NUL]", C0_NUL },
|
||||||
|
{ "[SOH]", C0_SOH },
|
||||||
|
{ "[STX]", C0_STX },
|
||||||
|
{ "[ETX]", C0_ETX },
|
||||||
|
{ "[EOT]", C0_EOT },
|
||||||
|
{ "[ENQ]", C0_ENQ },
|
||||||
|
{ "[ASC]", C0_ASC },
|
||||||
|
{ "[BEL]", C0_BEL },
|
||||||
|
{ "[BS]", C0_BS },
|
||||||
|
{ "Tab", C0_HT },
|
||||||
|
{ "[LF]", C0_LF },
|
||||||
|
{ "[VT]", C0_VT },
|
||||||
|
{ "[FF]", C0_FF },
|
||||||
|
{ "Enter", C0_CR },
|
||||||
|
{ "[SO]", C0_SO },
|
||||||
|
{ "[SI]", C0_SI },
|
||||||
|
{ "[DLE]", C0_DLE },
|
||||||
|
{ "[DC1]", C0_DC1 },
|
||||||
|
{ "[DC2]", C0_DC2 },
|
||||||
|
{ "[DC3]", C0_DC3 },
|
||||||
|
{ "[DC4]", C0_DC4 },
|
||||||
|
{ "[NAK]", C0_NAK },
|
||||||
|
{ "[SYN]", C0_SYN },
|
||||||
|
{ "[ETB]", C0_ETB },
|
||||||
|
{ "[CAN]", C0_CAN },
|
||||||
|
{ "[EM]", C0_EM },
|
||||||
|
{ "[SUB]", C0_SUB },
|
||||||
|
{ "Escape", C0_ESC },
|
||||||
|
{ "[FS]", C0_FS },
|
||||||
|
{ "[GS]", C0_GS },
|
||||||
|
{ "[RS]", C0_RS },
|
||||||
|
{ "[US]", C0_US },
|
||||||
|
|
||||||
/* Arrow keys. */
|
/* Arrow keys. */
|
||||||
{ "Up", KEYC_UP|KEYC_CURSOR|KEYC_IMPLIED_META },
|
{ "Up", KEYC_UP|KEYC_CURSOR|KEYC_IMPLIED_META },
|
||||||
@@ -206,8 +242,7 @@ key_string_get_modifiers(const char **string)
|
|||||||
key_code
|
key_code
|
||||||
key_string_lookup_string(const char *string)
|
key_string_lookup_string(const char *string)
|
||||||
{
|
{
|
||||||
static const char *other = "!#()+,-.0123456789:;<=>'\r\t\177`/";
|
key_code key, modifiers = 0;
|
||||||
key_code key, modifiers;
|
|
||||||
u_int u, i;
|
u_int u, i;
|
||||||
struct utf8_data ud, *udp;
|
struct utf8_data ud, *udp;
|
||||||
enum utf8_state more;
|
enum utf8_state more;
|
||||||
@@ -244,12 +279,15 @@ key_string_lookup_string(const char *string)
|
|||||||
return (uc);
|
return (uc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for modifiers. */
|
/* Check for short Ctrl key. */
|
||||||
modifiers = 0;
|
|
||||||
if (string[0] == '^' && string[1] != '\0') {
|
if (string[0] == '^' && string[1] != '\0') {
|
||||||
|
if (string[2] == '\0')
|
||||||
|
return (tolower((u_char)string[1])|KEYC_CTRL);
|
||||||
modifiers |= KEYC_CTRL;
|
modifiers |= KEYC_CTRL;
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check for modifiers. */
|
||||||
modifiers |= key_string_get_modifiers(&string);
|
modifiers |= key_string_get_modifiers(&string);
|
||||||
if (string == NULL || string[0] == '\0')
|
if (string == NULL || string[0] == '\0')
|
||||||
return (KEYC_UNKNOWN);
|
return (KEYC_UNKNOWN);
|
||||||
@@ -281,26 +319,6 @@ key_string_lookup_string(const char *string)
|
|||||||
key &= ~KEYC_IMPLIED_META;
|
key &= ~KEYC_IMPLIED_META;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert the standard control keys. */
|
|
||||||
if (key <= 127 &&
|
|
||||||
(modifiers & KEYC_CTRL) &&
|
|
||||||
strchr(other, key) == NULL &&
|
|
||||||
key != 9 &&
|
|
||||||
key != 13 &&
|
|
||||||
key != 27) {
|
|
||||||
if (key >= 97 && key <= 122)
|
|
||||||
key -= 96;
|
|
||||||
else if (key >= 64 && key <= 95)
|
|
||||||
key -= 64;
|
|
||||||
else if (key == 32)
|
|
||||||
key = 0;
|
|
||||||
else if (key == 63)
|
|
||||||
key = 127;
|
|
||||||
else
|
|
||||||
return (KEYC_UNKNOWN);
|
|
||||||
modifiers &= ~KEYC_CTRL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (key|modifiers);
|
return (key|modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,10 +342,6 @@ key_string_lookup_key(key_code key, int with_flags)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Display C-@ as C-Space. */
|
|
||||||
if ((key & (KEYC_MASK_KEY|KEYC_MASK_MODIFIERS)) == 0)
|
|
||||||
key = ' '|KEYC_CTRL;
|
|
||||||
|
|
||||||
/* Fill in the modifiers. */
|
/* Fill in the modifiers. */
|
||||||
if (key & KEYC_CTRL)
|
if (key & KEYC_CTRL)
|
||||||
strlcat(out, "C-", sizeof out);
|
strlcat(out, "C-", sizeof out);
|
||||||
@@ -396,7 +410,7 @@ key_string_lookup_key(key_code key, int with_flags)
|
|||||||
s = "MouseMoveBorder";
|
s = "MouseMoveBorder";
|
||||||
goto append;
|
goto append;
|
||||||
}
|
}
|
||||||
if (key >= KEYC_USER && key < KEYC_USER + KEYC_NUSER) {
|
if (key >= KEYC_USER && key < KEYC_USER_END) {
|
||||||
snprintf(tmp, sizeof tmp, "User%u", (u_int)(key - KEYC_USER));
|
snprintf(tmp, sizeof tmp, "User%u", (u_int)(key - KEYC_USER));
|
||||||
strlcat(out, tmp, sizeof out);
|
strlcat(out, tmp, sizeof out);
|
||||||
goto out;
|
goto out;
|
||||||
@@ -427,13 +441,8 @@ key_string_lookup_key(key_code key, int with_flags)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for standard or control key. */
|
/* Printable ASCII keys. */
|
||||||
if (key <= 32) {
|
if (key > 32 && key <= 126) {
|
||||||
if (key == 0 || key > 26)
|
|
||||||
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(64 + key));
|
|
||||||
else
|
|
||||||
xsnprintf(tmp, sizeof tmp, "C-%c", (int)(96 + key));
|
|
||||||
} else if (key >= 32 && key <= 126) {
|
|
||||||
tmp[0] = key;
|
tmp[0] = key;
|
||||||
tmp[1] = '\0';
|
tmp[1] = '\0';
|
||||||
} else if (key == 127)
|
} else if (key == 127)
|
||||||
@@ -460,8 +469,6 @@ out:
|
|||||||
strlcat(out, "I", sizeof out);
|
strlcat(out, "I", sizeof out);
|
||||||
if (saved & KEYC_BUILD_MODIFIERS)
|
if (saved & KEYC_BUILD_MODIFIERS)
|
||||||
strlcat(out, "B", sizeof out);
|
strlcat(out, "B", sizeof out);
|
||||||
if (saved & KEYC_EXTENDED)
|
|
||||||
strlcat(out, "E", sizeof out);
|
|
||||||
if (saved & KEYC_SENT)
|
if (saved & KEYC_SENT)
|
||||||
strlcat(out, "S", sizeof out);
|
strlcat(out, "S", sizeof out);
|
||||||
strlcat(out, "]", sizeof out);
|
strlcat(out, "]", sizeof out);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
|||||||
/* Check the new layout. */
|
/* Check the new layout. */
|
||||||
if (!layout_check(lc)) {
|
if (!layout_check(lc)) {
|
||||||
*cause = xstrdup("size mismatch after applying layout");
|
*cause = xstrdup("size mismatch after applying layout");
|
||||||
return (-1);
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resize to the layout size. */
|
/* Resize to the layout size. */
|
||||||
|
|||||||
204
layout-set.c
204
layout-set.c
@@ -31,7 +31,9 @@
|
|||||||
static void layout_set_even_h(struct window *);
|
static void layout_set_even_h(struct window *);
|
||||||
static void layout_set_even_v(struct window *);
|
static void layout_set_even_v(struct window *);
|
||||||
static void layout_set_main_h(struct window *);
|
static void layout_set_main_h(struct window *);
|
||||||
|
static void layout_set_main_h_mirrored(struct window *);
|
||||||
static void layout_set_main_v(struct window *);
|
static void layout_set_main_v(struct window *);
|
||||||
|
static void layout_set_main_v_mirrored(struct window *);
|
||||||
static void layout_set_tiled(struct window *);
|
static void layout_set_tiled(struct window *);
|
||||||
|
|
||||||
static const struct {
|
static const struct {
|
||||||
@@ -41,7 +43,9 @@ static const struct {
|
|||||||
{ "even-horizontal", layout_set_even_h },
|
{ "even-horizontal", layout_set_even_h },
|
||||||
{ "even-vertical", layout_set_even_v },
|
{ "even-vertical", layout_set_even_v },
|
||||||
{ "main-horizontal", layout_set_main_h },
|
{ "main-horizontal", layout_set_main_h },
|
||||||
|
{ "main-horizontal-mirrored", layout_set_main_h_mirrored },
|
||||||
{ "main-vertical", layout_set_main_v },
|
{ "main-vertical", layout_set_main_v },
|
||||||
|
{ "main-vertical-mirrored", layout_set_main_v_mirrored },
|
||||||
{ "tiled", layout_set_tiled },
|
{ "tiled", layout_set_tiled },
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,6 +55,10 @@ layout_set_lookup(const char *name)
|
|||||||
u_int i;
|
u_int i;
|
||||||
int matched = -1;
|
int matched = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < nitems(layout_sets); i++) {
|
||||||
|
if (strcmp(layout_sets[i].name, name) == 0)
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
for (i = 0; i < nitems(layout_sets); i++) {
|
for (i = 0; i < nitems(layout_sets); i++) {
|
||||||
if (strncmp(layout_sets[i].name, name, strlen(name)) == 0) {
|
if (strncmp(layout_sets[i].name, name, strlen(name)) == 0) {
|
||||||
if (matched != -1) /* ambiguous */
|
if (matched != -1) /* ambiguous */
|
||||||
@@ -279,6 +287,104 @@ layout_set_main_h(struct window *w)
|
|||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_set_main_h_mirrored(struct window *w)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct layout_cell *lc, *lcmain, *lcother, *lcchild;
|
||||||
|
u_int n, mainh, otherh, sx, sy;
|
||||||
|
char *cause;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
|
/* Get number of panes. */
|
||||||
|
n = window_count_panes(w);
|
||||||
|
if (n <= 1)
|
||||||
|
return;
|
||||||
|
n--; /* take off main pane */
|
||||||
|
|
||||||
|
/* Find available height - take off one line for the border. */
|
||||||
|
sy = w->sy - 1;
|
||||||
|
|
||||||
|
/* Get the main pane height. */
|
||||||
|
s = options_get_string(w->options, "main-pane-height");
|
||||||
|
mainh = args_string_percentage(s, 0, sy, sy, &cause);
|
||||||
|
if (cause != NULL) {
|
||||||
|
mainh = 24;
|
||||||
|
free(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Work out the other pane height. */
|
||||||
|
if (mainh + PANE_MINIMUM >= sy) {
|
||||||
|
if (sy <= PANE_MINIMUM + PANE_MINIMUM)
|
||||||
|
mainh = PANE_MINIMUM;
|
||||||
|
else
|
||||||
|
mainh = sy - PANE_MINIMUM;
|
||||||
|
otherh = PANE_MINIMUM;
|
||||||
|
} else {
|
||||||
|
s = options_get_string(w->options, "other-pane-height");
|
||||||
|
otherh = args_string_percentage(s, 0, sy, sy, &cause);
|
||||||
|
if (cause != NULL || otherh == 0) {
|
||||||
|
otherh = sy - mainh;
|
||||||
|
free(cause);
|
||||||
|
} else if (otherh > sy || sy - otherh < mainh)
|
||||||
|
otherh = sy - mainh;
|
||||||
|
else
|
||||||
|
mainh = sy - otherh;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Work out what width is needed. */
|
||||||
|
sx = (n * (PANE_MINIMUM + 1)) - 1;
|
||||||
|
if (sx < w->sx)
|
||||||
|
sx = w->sx;
|
||||||
|
|
||||||
|
/* Free old tree and create a new root. */
|
||||||
|
layout_free(w);
|
||||||
|
lc = w->layout_root = layout_create_cell(NULL);
|
||||||
|
layout_set_size(lc, sx, mainh + otherh + 1, 0, 0);
|
||||||
|
layout_make_node(lc, LAYOUT_TOPBOTTOM);
|
||||||
|
|
||||||
|
/* Create the other pane. */
|
||||||
|
lcother = layout_create_cell(lc);
|
||||||
|
layout_set_size(lcother, sx, otherh, 0, 0);
|
||||||
|
if (n == 1) {
|
||||||
|
wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
|
||||||
|
layout_make_leaf(lcother, wp);
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||||
|
} else {
|
||||||
|
layout_make_node(lcother, LAYOUT_LEFTRIGHT);
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||||
|
|
||||||
|
/* Add the remaining panes as children. */
|
||||||
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
|
if (wp == TAILQ_FIRST(&w->panes))
|
||||||
|
continue;
|
||||||
|
lcchild = layout_create_cell(lcother);
|
||||||
|
layout_set_size(lcchild, PANE_MINIMUM, otherh, 0, 0);
|
||||||
|
layout_make_leaf(lcchild, wp);
|
||||||
|
TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
|
||||||
|
}
|
||||||
|
layout_spread_cell(w, lcother);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the main pane. */
|
||||||
|
lcmain = layout_create_cell(lc);
|
||||||
|
layout_set_size(lcmain, sx, mainh, 0, 0);
|
||||||
|
layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
|
||||||
|
|
||||||
|
/* Fix cell offsets. */
|
||||||
|
layout_fix_offsets(w);
|
||||||
|
layout_fix_panes(w, NULL);
|
||||||
|
|
||||||
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
|
window_resize(w, lc->sx, lc->sy, -1, -1);
|
||||||
|
notify_window("window-layout-changed", w);
|
||||||
|
server_redraw_window(w);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
layout_set_main_v(struct window *w)
|
layout_set_main_v(struct window *w)
|
||||||
{
|
{
|
||||||
@@ -377,6 +483,104 @@ layout_set_main_v(struct window *w)
|
|||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
layout_set_main_v_mirrored(struct window *w)
|
||||||
|
{
|
||||||
|
struct window_pane *wp;
|
||||||
|
struct layout_cell *lc, *lcmain, *lcother, *lcchild;
|
||||||
|
u_int n, mainw, otherw, sx, sy;
|
||||||
|
char *cause;
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
|
/* Get number of panes. */
|
||||||
|
n = window_count_panes(w);
|
||||||
|
if (n <= 1)
|
||||||
|
return;
|
||||||
|
n--; /* take off main pane */
|
||||||
|
|
||||||
|
/* Find available width - take off one line for the border. */
|
||||||
|
sx = w->sx - 1;
|
||||||
|
|
||||||
|
/* Get the main pane width. */
|
||||||
|
s = options_get_string(w->options, "main-pane-width");
|
||||||
|
mainw = args_string_percentage(s, 0, sx, sx, &cause);
|
||||||
|
if (cause != NULL) {
|
||||||
|
mainw = 80;
|
||||||
|
free(cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Work out the other pane width. */
|
||||||
|
if (mainw + PANE_MINIMUM >= sx) {
|
||||||
|
if (sx <= PANE_MINIMUM + PANE_MINIMUM)
|
||||||
|
mainw = PANE_MINIMUM;
|
||||||
|
else
|
||||||
|
mainw = sx - PANE_MINIMUM;
|
||||||
|
otherw = PANE_MINIMUM;
|
||||||
|
} else {
|
||||||
|
s = options_get_string(w->options, "other-pane-width");
|
||||||
|
otherw = args_string_percentage(s, 0, sx, sx, &cause);
|
||||||
|
if (cause != NULL || otherw == 0) {
|
||||||
|
otherw = sx - mainw;
|
||||||
|
free(cause);
|
||||||
|
} else if (otherw > sx || sx - otherw < mainw)
|
||||||
|
otherw = sx - mainw;
|
||||||
|
else
|
||||||
|
mainw = sx - otherw;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Work out what height is needed. */
|
||||||
|
sy = (n * (PANE_MINIMUM + 1)) - 1;
|
||||||
|
if (sy < w->sy)
|
||||||
|
sy = w->sy;
|
||||||
|
|
||||||
|
/* Free old tree and create a new root. */
|
||||||
|
layout_free(w);
|
||||||
|
lc = w->layout_root = layout_create_cell(NULL);
|
||||||
|
layout_set_size(lc, mainw + otherw + 1, sy, 0, 0);
|
||||||
|
layout_make_node(lc, LAYOUT_LEFTRIGHT);
|
||||||
|
|
||||||
|
/* Create the other pane. */
|
||||||
|
lcother = layout_create_cell(lc);
|
||||||
|
layout_set_size(lcother, otherw, sy, 0, 0);
|
||||||
|
if (n == 1) {
|
||||||
|
wp = TAILQ_NEXT(TAILQ_FIRST(&w->panes), entry);
|
||||||
|
layout_make_leaf(lcother, wp);
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||||
|
} else {
|
||||||
|
layout_make_node(lcother, LAYOUT_TOPBOTTOM);
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcother, entry);
|
||||||
|
|
||||||
|
/* Add the remaining panes as children. */
|
||||||
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
|
if (wp == TAILQ_FIRST(&w->panes))
|
||||||
|
continue;
|
||||||
|
lcchild = layout_create_cell(lcother);
|
||||||
|
layout_set_size(lcchild, otherw, PANE_MINIMUM, 0, 0);
|
||||||
|
layout_make_leaf(lcchild, wp);
|
||||||
|
TAILQ_INSERT_TAIL(&lcother->cells, lcchild, entry);
|
||||||
|
}
|
||||||
|
layout_spread_cell(w, lcother);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the main pane. */
|
||||||
|
lcmain = layout_create_cell(lc);
|
||||||
|
layout_set_size(lcmain, mainw, sy, 0, 0);
|
||||||
|
layout_make_leaf(lcmain, TAILQ_FIRST(&w->panes));
|
||||||
|
TAILQ_INSERT_TAIL(&lc->cells, lcmain, entry);
|
||||||
|
|
||||||
|
/* Fix cell offsets. */
|
||||||
|
layout_fix_offsets(w);
|
||||||
|
layout_fix_panes(w, NULL);
|
||||||
|
|
||||||
|
layout_print_cell(w->layout_root, __func__, 1);
|
||||||
|
|
||||||
|
window_resize(w, lc->sx, lc->sy, -1, -1);
|
||||||
|
notify_window("window-layout-changed", w);
|
||||||
|
server_redraw_window(w);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
layout_set_tiled(struct window *w)
|
layout_set_tiled(struct window *w)
|
||||||
{
|
{
|
||||||
|
|||||||
8
menu.c
8
menu.c
@@ -335,7 +335,7 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
|
|||||||
c->flags |= CLIENT_REDRAWOVERLAY;
|
c->flags |= CLIENT_REDRAWOVERLAY;
|
||||||
return (0);
|
return (0);
|
||||||
case KEYC_PPAGE:
|
case KEYC_PPAGE:
|
||||||
case '\002': /* C-b */
|
case 'b'|KEYC_CTRL:
|
||||||
if (md->choice < 6)
|
if (md->choice < 6)
|
||||||
md->choice = 0;
|
md->choice = 0;
|
||||||
else {
|
else {
|
||||||
@@ -394,13 +394,13 @@ menu_key_cb(struct client *c, void *data, struct key_event *event)
|
|||||||
}
|
}
|
||||||
c->flags |= CLIENT_REDRAWOVERLAY;
|
c->flags |= CLIENT_REDRAWOVERLAY;
|
||||||
break;
|
break;
|
||||||
case '\006': /* C-f */
|
case 'f'|KEYC_CTRL:
|
||||||
break;
|
break;
|
||||||
case '\r':
|
case '\r':
|
||||||
goto chosen;
|
goto chosen;
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
case '\003': /* C-c */
|
case 'c'|KEYC_CTRL:
|
||||||
case '\007': /* C-g */
|
case 'g'|KEYC_CTRL:
|
||||||
case 'q':
|
case 'q':
|
||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|||||||
80
mode-tree.c
80
mode-tree.c
@@ -25,6 +25,11 @@
|
|||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
|
enum mode_tree_search_dir {
|
||||||
|
MODE_TREE_SEARCH_FORWARD,
|
||||||
|
MODE_TREE_SEARCH_BACKWARD
|
||||||
|
};
|
||||||
|
|
||||||
struct mode_tree_item;
|
struct mode_tree_item;
|
||||||
TAILQ_HEAD(mode_tree_list, mode_tree_item);
|
TAILQ_HEAD(mode_tree_list, mode_tree_item);
|
||||||
|
|
||||||
@@ -68,6 +73,7 @@ struct mode_tree_data {
|
|||||||
char *search;
|
char *search;
|
||||||
char *filter;
|
char *filter;
|
||||||
int no_matches;
|
int no_matches;
|
||||||
|
enum mode_tree_search_dir search_dir;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mode_tree_item {
|
struct mode_tree_item {
|
||||||
@@ -255,19 +261,21 @@ mode_tree_up(struct mode_tree_data *mtd, int wrap)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
int
|
||||||
mode_tree_down(struct mode_tree_data *mtd, int wrap)
|
mode_tree_down(struct mode_tree_data *mtd, int wrap)
|
||||||
{
|
{
|
||||||
if (mtd->current == mtd->line_size - 1) {
|
if (mtd->current == mtd->line_size - 1) {
|
||||||
if (wrap) {
|
if (wrap) {
|
||||||
mtd->current = 0;
|
mtd->current = 0;
|
||||||
mtd->offset = 0;
|
mtd->offset = 0;
|
||||||
}
|
} else
|
||||||
|
return (0);
|
||||||
} else {
|
} else {
|
||||||
mtd->current++;
|
mtd->current++;
|
||||||
if (mtd->current > mtd->offset + mtd->height - 1)
|
if (mtd->current > mtd->offset + mtd->height - 1)
|
||||||
mtd->offset++;
|
mtd->offset++;
|
||||||
}
|
}
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
void *
|
||||||
@@ -786,7 +794,49 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct mode_tree_item *
|
static struct mode_tree_item *
|
||||||
mode_tree_search_for(struct mode_tree_data *mtd)
|
mode_tree_search_backward(struct mode_tree_data *mtd)
|
||||||
|
{
|
||||||
|
struct mode_tree_item *mti, *last, *prev;
|
||||||
|
|
||||||
|
if (mtd->search == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
mti = last = mtd->line_list[mtd->current].item;
|
||||||
|
for (;;) {
|
||||||
|
if ((prev = TAILQ_PREV(mti, mode_tree_list, entry)) != NULL) {
|
||||||
|
/* Point to the last child in the previous subtree. */
|
||||||
|
while (!TAILQ_EMPTY(&prev->children))
|
||||||
|
prev = TAILQ_LAST(&prev->children, mode_tree_list);
|
||||||
|
mti = prev;
|
||||||
|
} else {
|
||||||
|
/* If prev is NULL, jump to the parent. */
|
||||||
|
mti = mti->parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mti == NULL) {
|
||||||
|
/* Point to the last child in the last root subtree. */
|
||||||
|
prev = TAILQ_LAST(&mtd->children, mode_tree_list);
|
||||||
|
while (!TAILQ_EMPTY(&prev->children))
|
||||||
|
prev = TAILQ_LAST(&prev->children, mode_tree_list);
|
||||||
|
mti = prev;
|
||||||
|
}
|
||||||
|
if (mti == last)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (mtd->searchcb == NULL) {
|
||||||
|
if (strstr(mti->name, mtd->search) != NULL)
|
||||||
|
return (mti);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mtd->searchcb(mtd->modedata, mti->itemdata, mtd->search))
|
||||||
|
return (mti);
|
||||||
|
}
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static struct mode_tree_item *
|
||||||
|
mode_tree_search_forward(struct mode_tree_data *mtd)
|
||||||
{
|
{
|
||||||
struct mode_tree_item *mti, *last, *next;
|
struct mode_tree_item *mti, *last, *next;
|
||||||
|
|
||||||
@@ -832,7 +882,10 @@ mode_tree_search_set(struct mode_tree_data *mtd)
|
|||||||
struct mode_tree_item *mti, *loop;
|
struct mode_tree_item *mti, *loop;
|
||||||
uint64_t tag;
|
uint64_t tag;
|
||||||
|
|
||||||
mti = mode_tree_search_for(mtd);
|
if (mtd->search_dir == MODE_TREE_SEARCH_FORWARD)
|
||||||
|
mti = mode_tree_search_forward(mtd);
|
||||||
|
else
|
||||||
|
mti = mode_tree_search_backward(mtd);
|
||||||
if (mti == NULL)
|
if (mti == NULL)
|
||||||
return;
|
return;
|
||||||
tag = mti->tag;
|
tag = mti->tag;
|
||||||
@@ -1035,22 +1088,22 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
switch (*key) {
|
switch (*key) {
|
||||||
case 'q':
|
case 'q':
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
case '\007': /* C-g */
|
case 'g'|KEYC_CTRL:
|
||||||
return (1);
|
return (1);
|
||||||
case KEYC_UP:
|
case KEYC_UP:
|
||||||
case 'k':
|
case 'k':
|
||||||
case KEYC_WHEELUP_PANE:
|
case KEYC_WHEELUP_PANE:
|
||||||
case '\020': /* C-p */
|
case 'p'|KEYC_CTRL:
|
||||||
mode_tree_up(mtd, 1);
|
mode_tree_up(mtd, 1);
|
||||||
break;
|
break;
|
||||||
case KEYC_DOWN:
|
case KEYC_DOWN:
|
||||||
case 'j':
|
case 'j':
|
||||||
case KEYC_WHEELDOWN_PANE:
|
case KEYC_WHEELDOWN_PANE:
|
||||||
case '\016': /* C-n */
|
case 'n'|KEYC_CTRL:
|
||||||
mode_tree_down(mtd, 1);
|
mode_tree_down(mtd, 1);
|
||||||
break;
|
break;
|
||||||
case KEYC_PPAGE:
|
case KEYC_PPAGE:
|
||||||
case '\002': /* C-b */
|
case 'b'|KEYC_CTRL:
|
||||||
for (i = 0; i < mtd->height; i++) {
|
for (i = 0; i < mtd->height; i++) {
|
||||||
if (mtd->current == 0)
|
if (mtd->current == 0)
|
||||||
break;
|
break;
|
||||||
@@ -1058,7 +1111,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYC_NPAGE:
|
case KEYC_NPAGE:
|
||||||
case '\006': /* C-f */
|
case 'f'|KEYC_CTRL:
|
||||||
for (i = 0; i < mtd->height; i++) {
|
for (i = 0; i < mtd->height; i++) {
|
||||||
if (mtd->current == mtd->line_size - 1)
|
if (mtd->current == mtd->line_size - 1)
|
||||||
break;
|
break;
|
||||||
@@ -1102,7 +1155,7 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
for (i = 0; i < mtd->line_size; i++)
|
for (i = 0; i < mtd->line_size; i++)
|
||||||
mtd->line_list[i].item->tagged = 0;
|
mtd->line_list[i].item->tagged = 0;
|
||||||
break;
|
break;
|
||||||
case '\024': /* C-t */
|
case 't'|KEYC_CTRL:
|
||||||
for (i = 0; i < mtd->line_size; i++) {
|
for (i = 0; i < mtd->line_size; i++) {
|
||||||
if ((mtd->line_list[i].item->parent == NULL &&
|
if ((mtd->line_list[i].item->parent == NULL &&
|
||||||
!mtd->line_list[i].item->no_tag) ||
|
!mtd->line_list[i].item->no_tag) ||
|
||||||
@@ -1158,13 +1211,18 @@ mode_tree_key(struct mode_tree_data *mtd, struct client *c, key_code *key,
|
|||||||
break;
|
break;
|
||||||
case '?':
|
case '?':
|
||||||
case '/':
|
case '/':
|
||||||
case '\023': /* C-s */
|
case 's'|KEYC_CTRL:
|
||||||
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_TYPE_SEARCH);
|
PROMPT_NOFORMAT, PROMPT_TYPE_SEARCH);
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
|
mtd->search_dir = MODE_TREE_SEARCH_FORWARD;
|
||||||
|
mode_tree_search_set(mtd);
|
||||||
|
break;
|
||||||
|
case 'N':
|
||||||
|
mtd->search_dir = MODE_TREE_SEARCH_BACKWARD;
|
||||||
mode_tree_search_set(mtd);
|
mode_tree_search_set(mtd);
|
||||||
break;
|
break;
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ static const char *options_table_detach_on_destroy_list[] = {
|
|||||||
static const char *options_table_extended_keys_list[] = {
|
static const char *options_table_extended_keys_list[] = {
|
||||||
"off", "on", "always", NULL
|
"off", "on", "always", NULL
|
||||||
};
|
};
|
||||||
|
static const char *options_table_extended_keys_format_list[] = {
|
||||||
|
"csi-u", "xterm", NULL
|
||||||
|
};
|
||||||
static const char *options_table_allow_passthrough_list[] = {
|
static const char *options_table_allow_passthrough_list[] = {
|
||||||
"off", "on", "all", NULL
|
"off", "on", "all", NULL
|
||||||
};
|
};
|
||||||
@@ -285,7 +288,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
.minimum = 0,
|
.minimum = 0,
|
||||||
.maximum = INT_MAX,
|
.maximum = INT_MAX,
|
||||||
.default_num = 500,
|
.default_num = 10,
|
||||||
.unit = "milliseconds",
|
.unit = "milliseconds",
|
||||||
.text = "Time to wait before assuming a key is Escape."
|
.text = "Time to wait before assuming a key is Escape."
|
||||||
},
|
},
|
||||||
@@ -314,6 +317,14 @@ const struct options_table_entry options_table[] = {
|
|||||||
"that support it."
|
"that support it."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "extended-keys-format",
|
||||||
|
.type = OPTIONS_TABLE_CHOICE,
|
||||||
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
.choices = options_table_extended_keys_format_list,
|
||||||
|
.default_num = 1,
|
||||||
|
.text = "The format of emitted extended key sequences."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "focus-events",
|
{ .name = "focus-events",
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
@@ -374,6 +385,17 @@ const struct options_table_entry options_table[] = {
|
|||||||
.text = "Maximum number of server messages to keep."
|
.text = "Maximum number of server messages to keep."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "prefix-timeout",
|
||||||
|
.type = OPTIONS_TABLE_NUMBER,
|
||||||
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
|
.minimum = 0,
|
||||||
|
.maximum = INT_MAX,
|
||||||
|
.default_num = 0,
|
||||||
|
.unit = "milliseconds",
|
||||||
|
.text = "The timeout for the prefix key if no subsequent key is "
|
||||||
|
"pressed. Zero means disabled."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "prompt-history-limit",
|
{ .name = "prompt-history-limit",
|
||||||
.type = OPTIONS_TABLE_NUMBER,
|
.type = OPTIONS_TABLE_NUMBER,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
@@ -397,7 +419,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
.type = OPTIONS_TABLE_STRING,
|
.type = OPTIONS_TABLE_STRING,
|
||||||
.scope = OPTIONS_TABLE_SERVER,
|
.scope = OPTIONS_TABLE_SERVER,
|
||||||
.flags = OPTIONS_TABLE_IS_ARRAY,
|
.flags = OPTIONS_TABLE_IS_ARRAY,
|
||||||
.default_str = "",
|
.default_str = "linux*:AX@",
|
||||||
.separator = ",",
|
.separator = ",",
|
||||||
.text = "List of terminal capabilities overrides."
|
.text = "List of terminal capabilities overrides."
|
||||||
},
|
},
|
||||||
@@ -613,7 +635,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
{ .name = "prefix",
|
{ .name = "prefix",
|
||||||
.type = OPTIONS_TABLE_KEY,
|
.type = OPTIONS_TABLE_KEY,
|
||||||
.scope = OPTIONS_TABLE_SESSION,
|
.scope = OPTIONS_TABLE_SESSION,
|
||||||
.default_num = '\002',
|
.default_num = 'b'|KEYC_CTRL,
|
||||||
.text = "The prefix key."
|
.text = "The prefix key."
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -875,6 +897,14 @@ const struct options_table_entry options_table[] = {
|
|||||||
"to rename windows."
|
"to rename windows."
|
||||||
},
|
},
|
||||||
|
|
||||||
|
{ .name = "allow-set-title",
|
||||||
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
|
.default_num = 1,
|
||||||
|
.text = "Whether applications are allowed to use the escape sequence "
|
||||||
|
"to set the pane title."
|
||||||
|
},
|
||||||
|
|
||||||
{ .name = "alternate-screen",
|
{ .name = "alternate-screen",
|
||||||
.type = OPTIONS_TABLE_FLAG,
|
.type = OPTIONS_TABLE_FLAG,
|
||||||
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
.scope = OPTIONS_TABLE_WINDOW|OPTIONS_TABLE_PANE,
|
||||||
@@ -1317,6 +1347,7 @@ const struct options_table_entry options_table[] = {
|
|||||||
OPTIONS_TABLE_HOOK("client-focus-out", ""),
|
OPTIONS_TABLE_HOOK("client-focus-out", ""),
|
||||||
OPTIONS_TABLE_HOOK("client-resized", ""),
|
OPTIONS_TABLE_HOOK("client-resized", ""),
|
||||||
OPTIONS_TABLE_HOOK("client-session-changed", ""),
|
OPTIONS_TABLE_HOOK("client-session-changed", ""),
|
||||||
|
OPTIONS_TABLE_HOOK("command-error", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-died", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-exited", ""),
|
||||||
OPTIONS_TABLE_PANE_HOOK("pane-focus-in", ""),
|
OPTIONS_TABLE_PANE_HOOK("pane-focus-in", ""),
|
||||||
|
|||||||
22
options.c
22
options.c
@@ -578,10 +578,28 @@ char *
|
|||||||
options_to_string(struct options_entry *o, int idx, int numeric)
|
options_to_string(struct options_entry *o, int idx, int numeric)
|
||||||
{
|
{
|
||||||
struct options_array_item *a;
|
struct options_array_item *a;
|
||||||
|
char *result = NULL;
|
||||||
|
char *last = NULL;
|
||||||
|
char *next;
|
||||||
|
|
||||||
if (OPTIONS_IS_ARRAY(o)) {
|
if (OPTIONS_IS_ARRAY(o)) {
|
||||||
if (idx == -1)
|
if (idx == -1) {
|
||||||
return (xstrdup(""));
|
RB_FOREACH(a, options_array, &o->value.array) {
|
||||||
|
next = options_value_to_string(o, &a->value,
|
||||||
|
numeric);
|
||||||
|
if (last == NULL)
|
||||||
|
result = next;
|
||||||
|
else {
|
||||||
|
xasprintf(&result, "%s %s", last, next);
|
||||||
|
free(last);
|
||||||
|
free(next);
|
||||||
|
}
|
||||||
|
last = result;
|
||||||
|
}
|
||||||
|
if (result == NULL)
|
||||||
|
return (xstrdup(""));
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
a = options_array_item(o, idx);
|
a = options_array_item(o, idx);
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
return (xstrdup(""));
|
return (xstrdup(""));
|
||||||
|
|||||||
4
popup.c
4
popup.c
@@ -345,7 +345,7 @@ popup_make_pane(struct popup_data *pd, enum layout_type type)
|
|||||||
u_int hlimit;
|
u_int hlimit;
|
||||||
const char *shell;
|
const char *shell;
|
||||||
|
|
||||||
window_unzoom(w);
|
window_unzoom(w, 1);
|
||||||
|
|
||||||
lc = layout_split_pane(wp, type, -1, 0);
|
lc = layout_split_pane(wp, type, -1, 0);
|
||||||
hlimit = options_get_number(s->options, "history-limit");
|
hlimit = options_get_number(s->options, "history-limit");
|
||||||
@@ -542,7 +542,7 @@ popup_key_cb(struct client *c, void *data, struct key_event *event)
|
|||||||
}
|
}
|
||||||
if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) ||
|
if ((((pd->flags & (POPUP_CLOSEEXIT|POPUP_CLOSEEXITZERO)) == 0) ||
|
||||||
pd->job == NULL) &&
|
pd->job == NULL) &&
|
||||||
(event->key == '\033' || event->key == '\003'))
|
(event->key == '\033' || event->key == ('c'|KEYC_CTRL)))
|
||||||
return (1);
|
return (1);
|
||||||
if (pd->job != NULL) {
|
if (pd->job != NULL) {
|
||||||
if (KEYC_IS_MOUSE(event->key)) {
|
if (KEYC_IS_MOUSE(event->key)) {
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ $TMUX send-keys -X begin-selection
|
|||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "words\n Indented")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "words\n Indented")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word` wraps around un-indented line breaks.
|
# Test that `next-word` wraps around un-indented line breaks.
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "line\n")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "line\n")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word-end` treats periods as letters.
|
# Test that `next-word-end` treats periods as letters.
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
@@ -63,14 +63,14 @@ $TMUX send-keys -X previous-word
|
|||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "line...\n")" ] || exit 1
|
||||||
|
|
||||||
# Test that `previous-space` and `next-space` treat periods as letters.
|
# Test that `previous-space` and `next-space` treat periods as letters.
|
||||||
$TMUX send-keys -X previous-space
|
$TMUX send-keys -X previous-space
|
||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-space
|
$TMUX send-keys -X next-space
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "line...\n")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word` and `next-word-end` treat other symbols as letters.
|
# Test that `next-word` and `next-word-end` treat other symbols as letters.
|
||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
@@ -87,7 +87,7 @@ $TMUX send-keys -X previous-word
|
|||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "\$ym_bols[]{}\n ")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "\$ym_bols[]{}\n ")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word-end` treats digits as letters
|
# Test that `next-word-end` treats digits as letters
|
||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ $TMUX send-keys -X begin-selection
|
|||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "words\n Indented")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "words\n Indented")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word` wraps around un-indented line breaks.
|
# Test that `next-word` wraps around un-indented line breaks.
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "line\nA")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "line\nA")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word-end` does not treat periods as letters.
|
# Test that `next-word-end` does not treat periods as letters.
|
||||||
$TMUX send-keys -X next-word
|
$TMUX send-keys -X next-word
|
||||||
@@ -69,7 +69,7 @@ $TMUX send-keys -X previous-space
|
|||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-space
|
$TMUX send-keys -X next-space
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "line...\n.")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "line...\n.")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word` and `next-word-end` do not treat other symbols as letters.
|
# Test that `next-word` and `next-word-end` do not treat other symbols as letters.
|
||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
@@ -85,7 +85,7 @@ $TMUX send-keys -X next-space
|
|||||||
$TMUX send-keys -X begin-selection
|
$TMUX send-keys -X begin-selection
|
||||||
$TMUX send-keys -X next-space
|
$TMUX send-keys -X next-space
|
||||||
$TMUX send-keys -X copy-selection
|
$TMUX send-keys -X copy-selection
|
||||||
[ "$($TMUX show-buffer)" = "$(echo -e "\$ym_bols[]{}\n ?")" ] || exit 1
|
[ "$($TMUX show-buffer)" = "$(printf "\$ym_bols[]{}\n ?")" ] || exit 1
|
||||||
|
|
||||||
# Test that `next-word-end` treats digits as letters
|
# Test that `next-word-end` treats digits as letters
|
||||||
$TMUX send-keys -X next-word-end
|
$TMUX send-keys -X next-word-end
|
||||||
|
|||||||
2
resize.c
2
resize.c
@@ -40,7 +40,7 @@ resize_window(struct window *w, u_int sx, u_int sy, int xpixel, int ypixel)
|
|||||||
/* If the window is zoomed, unzoom. */
|
/* If the window is zoomed, unzoom. */
|
||||||
zoomed = w->flags & WINDOW_ZOOMED;
|
zoomed = w->flags & WINDOW_ZOOMED;
|
||||||
if (zoomed)
|
if (zoomed)
|
||||||
window_unzoom(w);
|
window_unzoom(w, 1);
|
||||||
|
|
||||||
/* Resize the layout first. */
|
/* Resize the layout first. */
|
||||||
layout_resize(w, sx, sy);
|
layout_resize(w, sx, sy);
|
||||||
|
|||||||
@@ -109,12 +109,13 @@ screen_redraw_two_panes(struct window *w, int direction)
|
|||||||
|
|
||||||
/* Check if cell is on the border of a pane. */
|
/* Check if cell is on the border of a pane. */
|
||||||
static enum screen_redraw_border_type
|
static enum screen_redraw_border_type
|
||||||
screen_redraw_pane_border(struct window_pane *wp, u_int px, u_int py,
|
screen_redraw_pane_border(struct screen_redraw_ctx *ctx, struct window_pane *wp,
|
||||||
int pane_status)
|
u_int px, u_int py)
|
||||||
{
|
{
|
||||||
struct options *oo = wp->window->options;
|
struct options *oo = wp->window->options;
|
||||||
int split = 0;
|
int split = 0;
|
||||||
u_int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy;
|
u_int ex = wp->xoff + wp->sx, ey = wp->yoff + wp->sy;
|
||||||
|
int pane_status = ctx->pane_status;
|
||||||
|
|
||||||
/* Inside pane. */
|
/* Inside pane. */
|
||||||
if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey)
|
if (px >= wp->xoff && px < ex && py >= wp->yoff && py < ey)
|
||||||
@@ -189,8 +190,9 @@ screen_redraw_pane_border(struct window_pane *wp, u_int px, u_int py,
|
|||||||
|
|
||||||
/* Check if a cell is on a border. */
|
/* Check if a cell is on a border. */
|
||||||
static int
|
static int
|
||||||
screen_redraw_cell_border(struct client *c, u_int px, u_int py, int pane_status)
|
screen_redraw_cell_border(struct screen_redraw_ctx *ctx, u_int px, u_int py)
|
||||||
{
|
{
|
||||||
|
struct client *c = ctx->c;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
@@ -206,7 +208,7 @@ screen_redraw_cell_border(struct client *c, u_int px, u_int py, int pane_status)
|
|||||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||||
if (!window_pane_visible(wp))
|
if (!window_pane_visible(wp))
|
||||||
continue;
|
continue;
|
||||||
switch (screen_redraw_pane_border(wp, px, py, pane_status)) {
|
switch (screen_redraw_pane_border(ctx, wp, px, py)) {
|
||||||
case SCREEN_REDRAW_INSIDE:
|
case SCREEN_REDRAW_INSIDE:
|
||||||
return (0);
|
return (0);
|
||||||
case SCREEN_REDRAW_OUTSIDE:
|
case SCREEN_REDRAW_OUTSIDE:
|
||||||
@@ -221,9 +223,10 @@ screen_redraw_cell_border(struct client *c, u_int px, u_int py, int pane_status)
|
|||||||
|
|
||||||
/* Work out type of border cell from surrounding cells. */
|
/* Work out type of border cell from surrounding cells. */
|
||||||
static int
|
static int
|
||||||
screen_redraw_type_of_cell(struct client *c, u_int px, u_int py,
|
screen_redraw_type_of_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py)
|
||||||
int pane_status)
|
|
||||||
{
|
{
|
||||||
|
struct client *c = ctx->c;
|
||||||
|
int pane_status = ctx->pane_status;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
u_int sx = w->sx, sy = w->sy;
|
u_int sx = w->sx, sy = w->sy;
|
||||||
int borders = 0;
|
int borders = 0;
|
||||||
@@ -236,28 +239,28 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py,
|
|||||||
* Construct a bitmask of whether the cells to the left (bit 4), right,
|
* Construct a bitmask of whether the cells to the left (bit 4), right,
|
||||||
* top, and bottom (bit 1) of this cell are borders.
|
* top, and bottom (bit 1) of this cell are borders.
|
||||||
*/
|
*/
|
||||||
if (px == 0 || screen_redraw_cell_border(c, px - 1, py, pane_status))
|
if (px == 0 || screen_redraw_cell_border(ctx, px - 1, py))
|
||||||
borders |= 8;
|
borders |= 8;
|
||||||
if (px <= sx && screen_redraw_cell_border(c, px + 1, py, pane_status))
|
if (px <= sx && screen_redraw_cell_border(ctx, px + 1, py))
|
||||||
borders |= 4;
|
borders |= 4;
|
||||||
if (pane_status == PANE_STATUS_TOP) {
|
if (pane_status == PANE_STATUS_TOP) {
|
||||||
if (py != 0 &&
|
if (py != 0 &&
|
||||||
screen_redraw_cell_border(c, px, py - 1, pane_status))
|
screen_redraw_cell_border(ctx, px, py - 1))
|
||||||
borders |= 2;
|
borders |= 2;
|
||||||
if (screen_redraw_cell_border(c, px, py + 1, pane_status))
|
if (screen_redraw_cell_border(ctx, px, py + 1))
|
||||||
borders |= 1;
|
borders |= 1;
|
||||||
} else if (pane_status == PANE_STATUS_BOTTOM) {
|
} else if (pane_status == PANE_STATUS_BOTTOM) {
|
||||||
if (py == 0 ||
|
if (py == 0 ||
|
||||||
screen_redraw_cell_border(c, px, py - 1, pane_status))
|
screen_redraw_cell_border(ctx, px, py - 1))
|
||||||
borders |= 2;
|
borders |= 2;
|
||||||
if (py != sy - 1 &&
|
if (py != sy - 1 &&
|
||||||
screen_redraw_cell_border(c, px, py + 1, pane_status))
|
screen_redraw_cell_border(ctx, px, py + 1))
|
||||||
borders |= 1;
|
borders |= 1;
|
||||||
} else {
|
} else {
|
||||||
if (py == 0 ||
|
if (py == 0 ||
|
||||||
screen_redraw_cell_border(c, px, py - 1, pane_status))
|
screen_redraw_cell_border(ctx, px, py - 1))
|
||||||
borders |= 2;
|
borders |= 2;
|
||||||
if (screen_redraw_cell_border(c, px, py + 1, pane_status))
|
if (screen_redraw_cell_border(ctx, px, py + 1))
|
||||||
borders |= 1;
|
borders |= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,11 +298,13 @@ screen_redraw_type_of_cell(struct client *c, u_int px, u_int py,
|
|||||||
|
|
||||||
/* Check if cell inside a pane. */
|
/* Check if cell inside a pane. */
|
||||||
static int
|
static int
|
||||||
screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
|
screen_redraw_check_cell(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
||||||
struct window_pane **wpp)
|
struct window_pane **wpp)
|
||||||
{
|
{
|
||||||
|
struct client *c = ctx->c;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct window_pane *wp, *active;
|
struct window_pane *wp, *active;
|
||||||
|
int pane_status = ctx->pane_status;
|
||||||
int border;
|
int border;
|
||||||
u_int right, line;
|
u_int right, line;
|
||||||
|
|
||||||
@@ -308,7 +313,7 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
|
|||||||
if (px > w->sx || py > w->sy)
|
if (px > w->sx || py > w->sy)
|
||||||
return (CELL_OUTSIDE);
|
return (CELL_OUTSIDE);
|
||||||
if (px == w->sx || py == w->sy) /* window border */
|
if (px == w->sx || py == w->sy) /* window border */
|
||||||
return (screen_redraw_type_of_cell(c, px, py, pane_status));
|
return (screen_redraw_type_of_cell(ctx, px, py));
|
||||||
|
|
||||||
if (pane_status != PANE_STATUS_OFF) {
|
if (pane_status != PANE_STATUS_OFF) {
|
||||||
active = wp = server_client_get_pane(c);
|
active = wp = server_client_get_pane(c);
|
||||||
@@ -342,12 +347,12 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
|
|||||||
* If definitely inside, return. If not on border, skip.
|
* If definitely inside, return. If not on border, skip.
|
||||||
* Otherwise work out the cell.
|
* Otherwise work out the cell.
|
||||||
*/
|
*/
|
||||||
border = screen_redraw_pane_border(wp, px, py, pane_status);
|
border = screen_redraw_pane_border(ctx, wp, px, py);
|
||||||
if (border == SCREEN_REDRAW_INSIDE)
|
if (border == SCREEN_REDRAW_INSIDE)
|
||||||
return (CELL_INSIDE);
|
return (CELL_INSIDE);
|
||||||
if (border == SCREEN_REDRAW_OUTSIDE)
|
if (border == SCREEN_REDRAW_OUTSIDE)
|
||||||
goto next2;
|
goto next2;
|
||||||
return (screen_redraw_type_of_cell(c, px, py, pane_status));
|
return (screen_redraw_type_of_cell(ctx, px, py));
|
||||||
|
|
||||||
next2:
|
next2:
|
||||||
wp = TAILQ_NEXT(wp, entry);
|
wp = TAILQ_NEXT(wp, entry);
|
||||||
@@ -360,12 +365,12 @@ screen_redraw_check_cell(struct client *c, u_int px, u_int py, int pane_status,
|
|||||||
|
|
||||||
/* Check if the border of a particular pane. */
|
/* Check if the border of a particular pane. */
|
||||||
static int
|
static int
|
||||||
screen_redraw_check_is(u_int px, u_int py, int pane_status,
|
screen_redraw_check_is(struct screen_redraw_ctx *ctx, u_int px, u_int py,
|
||||||
struct window_pane *wp)
|
struct window_pane *wp)
|
||||||
{
|
{
|
||||||
enum screen_redraw_border_type border;
|
enum screen_redraw_border_type border;
|
||||||
|
|
||||||
border = screen_redraw_pane_border(wp, px, py, pane_status);
|
border = screen_redraw_pane_border(ctx, wp, px, py);
|
||||||
if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE)
|
if (border != SCREEN_REDRAW_INSIDE && border != SCREEN_REDRAW_OUTSIDE)
|
||||||
return (1);
|
return (1);
|
||||||
return (0);
|
return (0);
|
||||||
@@ -409,11 +414,11 @@ screen_redraw_make_pane_status(struct client *c, struct window_pane *wp,
|
|||||||
|
|
||||||
for (i = 0; i < width; i++) {
|
for (i = 0; i < width; i++) {
|
||||||
px = wp->xoff + 2 + i;
|
px = wp->xoff + 2 + i;
|
||||||
if (rctx->pane_status == PANE_STATUS_TOP)
|
if (pane_status == PANE_STATUS_TOP)
|
||||||
py = wp->yoff - 1;
|
py = wp->yoff - 1;
|
||||||
else
|
else
|
||||||
py = wp->yoff + wp->sy;
|
py = wp->yoff + wp->sy;
|
||||||
cell_type = screen_redraw_type_of_cell(c, px, py, pane_status);
|
cell_type = screen_redraw_type_of_cell(rctx, px, py);
|
||||||
screen_redraw_border_set(w, wp, pane_lines, cell_type, &gc);
|
screen_redraw_border_set(w, wp, pane_lines, cell_type, &gc);
|
||||||
screen_write_cell(&ctx, &gc);
|
screen_write_cell(&ctx, &gc);
|
||||||
}
|
}
|
||||||
@@ -496,8 +501,8 @@ screen_redraw_draw_pane_status(struct screen_redraw_ctx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Update status line and change flags if unchanged. */
|
/* Update status line and change flags if unchanged. */
|
||||||
static int
|
static uint64_t
|
||||||
screen_redraw_update(struct client *c, int flags)
|
screen_redraw_update(struct client *c, uint64_t flags)
|
||||||
{
|
{
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
@@ -567,7 +572,7 @@ void
|
|||||||
screen_redraw_screen(struct client *c)
|
screen_redraw_screen(struct client *c)
|
||||||
{
|
{
|
||||||
struct screen_redraw_ctx ctx;
|
struct screen_redraw_ctx ctx;
|
||||||
int flags;
|
uint64_t flags;
|
||||||
|
|
||||||
if (c->flags & CLIENT_SUSPENDED)
|
if (c->flags & CLIENT_SUSPENDED)
|
||||||
return;
|
return;
|
||||||
@@ -638,7 +643,7 @@ screen_redraw_draw_borders_style(struct screen_redraw_ctx *ctx, u_int x,
|
|||||||
wp->border_gc_set = 1;
|
wp->border_gc_set = 1;
|
||||||
|
|
||||||
ft = format_create_defaults(NULL, c, s, s->curw, wp);
|
ft = format_create_defaults(NULL, c, s, s->curw, wp);
|
||||||
if (screen_redraw_check_is(x, y, ctx->pane_status, active))
|
if (screen_redraw_check_is(ctx, x, y, active))
|
||||||
style_apply(&wp->border_gc, oo, "pane-active-border-style", ft);
|
style_apply(&wp->border_gc, oo, "pane-active-border-style", ft);
|
||||||
else
|
else
|
||||||
style_apply(&wp->border_gc, oo, "pane-border-style", ft);
|
style_apply(&wp->border_gc, oo, "pane-border-style", ft);
|
||||||
@@ -663,7 +668,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
struct overlay_ranges r;
|
struct overlay_ranges r;
|
||||||
u_int cell_type, x = ctx->ox + i, y = ctx->oy + j;
|
u_int cell_type, x = ctx->ox + i, y = ctx->oy + j;
|
||||||
int arrows = 0, border;
|
int arrows = 0, border;
|
||||||
int pane_status = ctx->pane_status, isolates;
|
int isolates;
|
||||||
|
|
||||||
if (c->overlay_check != NULL) {
|
if (c->overlay_check != NULL) {
|
||||||
c->overlay_check(c, c->overlay_data, x, y, 1, &r);
|
c->overlay_check(c, c->overlay_data, x, y, 1, &r);
|
||||||
@@ -671,7 +676,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
cell_type = screen_redraw_check_cell(c, x, y, pane_status, &wp);
|
cell_type = screen_redraw_check_cell(ctx, x, y, &wp);
|
||||||
if (cell_type == CELL_INSIDE)
|
if (cell_type == CELL_INSIDE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -692,7 +697,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
memcpy(&gc, tmp, sizeof gc);
|
memcpy(&gc, tmp, sizeof gc);
|
||||||
|
|
||||||
if (server_is_marked(s, s->curw, marked_pane.wp) &&
|
if (server_is_marked(s, s->curw, marked_pane.wp) &&
|
||||||
screen_redraw_check_is(x, y, pane_status, marked_pane.wp))
|
screen_redraw_check_is(ctx, x, y, marked_pane.wp))
|
||||||
gc.attr ^= GRID_ATTR_REVERSE;
|
gc.attr ^= GRID_ATTR_REVERSE;
|
||||||
}
|
}
|
||||||
screen_redraw_border_set(w, wp, ctx->pane_lines, cell_type, &gc);
|
screen_redraw_border_set(w, wp, ctx->pane_lines, cell_type, &gc);
|
||||||
@@ -719,7 +724,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (wp != NULL && arrows) {
|
if (wp != NULL && arrows) {
|
||||||
border = screen_redraw_pane_border(active, x, y, pane_status);
|
border = screen_redraw_pane_border(ctx, active, x, y);
|
||||||
if (((i == wp->xoff + 1 &&
|
if (((i == wp->xoff + 1 &&
|
||||||
(cell_type == CELL_LEFTRIGHT ||
|
(cell_type == CELL_LEFTRIGHT ||
|
||||||
(cell_type == CELL_TOPJOIN &&
|
(cell_type == CELL_TOPJOIN &&
|
||||||
@@ -732,7 +737,7 @@ screen_redraw_draw_borders_cell(struct screen_redraw_ctx *ctx, u_int i, u_int j)
|
|||||||
border == SCREEN_REDRAW_BORDER_RIGHT) ||
|
border == SCREEN_REDRAW_BORDER_RIGHT) ||
|
||||||
(cell_type == CELL_RIGHTJOIN &&
|
(cell_type == CELL_RIGHTJOIN &&
|
||||||
border == SCREEN_REDRAW_BORDER_LEFT)))) &&
|
border == SCREEN_REDRAW_BORDER_LEFT)))) &&
|
||||||
screen_redraw_check_is(x, y, pane_status, active)) {
|
screen_redraw_check_is(ctx, x, y, active)) {
|
||||||
gc.attr |= GRID_ATTR_CHARSET;
|
gc.attr |= GRID_ATTR_CHARSET;
|
||||||
utf8_set(&gc.data, BORDER_MARKERS[border]);
|
utf8_set(&gc.data, BORDER_MARKERS[border]);
|
||||||
}
|
}
|
||||||
@@ -751,7 +756,7 @@ screen_redraw_draw_borders(struct screen_redraw_ctx *ctx)
|
|||||||
struct session *s = c->session;
|
struct session *s = c->session;
|
||||||
struct window *w = s->curw->window;
|
struct window *w = s->curw->window;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
u_int i, j;
|
u_int i, j;
|
||||||
|
|
||||||
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
log_debug("%s: %s @%u", __func__, c->name, w->id);
|
||||||
|
|
||||||
|
|||||||
@@ -326,8 +326,9 @@ screen_write_reset(struct screen_write_ctx *ctx)
|
|||||||
screen_write_scrollregion(ctx, 0, screen_size_y(s) - 1);
|
screen_write_scrollregion(ctx, 0, screen_size_y(s) - 1);
|
||||||
|
|
||||||
s->mode = MODE_CURSOR|MODE_WRAP;
|
s->mode = MODE_CURSOR|MODE_WRAP;
|
||||||
|
|
||||||
if (options_get_number(global_options, "extended-keys") == 2)
|
if (options_get_number(global_options, "extended-keys") == 2)
|
||||||
s->mode |= MODE_KEXTENDED;
|
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||||
|
|
||||||
screen_write_clearscreen(ctx, 8);
|
screen_write_clearscreen(ctx, 8);
|
||||||
screen_write_set_cursor(ctx, 0, 0);
|
screen_write_set_cursor(ctx, 0, 0);
|
||||||
@@ -2148,7 +2149,7 @@ screen_write_combine(struct screen_write_ctx *ctx, const struct grid_cell *gc)
|
|||||||
/* Set the new cell. */
|
/* Set the new cell. */
|
||||||
grid_view_set_cell(gd, cx - n, cy, &last);
|
grid_view_set_cell(gd, cx - n, cy, &last);
|
||||||
if (force_wide)
|
if (force_wide)
|
||||||
grid_view_set_padding(gd, cx, cy);
|
grid_view_set_padding(gd, cx - 1, cy);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Redraw the combined cell. If forcing the cell to width 2, reset the
|
* Redraw the combined cell. If forcing the cell to width 2, reset the
|
||||||
@@ -2283,6 +2284,10 @@ screen_write_sixelimage(struct screen_write_ctx *ctx, struct sixel_image *si,
|
|||||||
new = sixel_scale(si, 0, 0, 0, y - sy, sx, sy, 1);
|
new = sixel_scale(si, 0, 0, 0, y - sy, sx, sy, 1);
|
||||||
sixel_free(si);
|
sixel_free(si);
|
||||||
si = new;
|
si = new;
|
||||||
|
|
||||||
|
/* Bail out if the image cannot be scaled. */
|
||||||
|
if (si == NULL)
|
||||||
|
return;
|
||||||
sixel_size_in_cells(si, &x, &y);
|
sixel_size_in_cells(si, &x, &y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
screen.c
17
screen.c
@@ -110,8 +110,9 @@ screen_reinit(struct screen *s)
|
|||||||
s->rlower = screen_size_y(s) - 1;
|
s->rlower = screen_size_y(s) - 1;
|
||||||
|
|
||||||
s->mode = MODE_CURSOR|MODE_WRAP|(s->mode & MODE_CRLF);
|
s->mode = MODE_CURSOR|MODE_WRAP|(s->mode & MODE_CRLF);
|
||||||
|
|
||||||
if (options_get_number(global_options, "extended-keys") == 2)
|
if (options_get_number(global_options, "extended-keys") == 2)
|
||||||
s->mode |= MODE_KEXTENDED;
|
s->mode = (s->mode & ~EXTENDED_KEY_MODES)|MODE_KEYS_EXTENDED;
|
||||||
|
|
||||||
if (s->saved_grid != NULL)
|
if (s->saved_grid != NULL)
|
||||||
screen_alternate_off(s, NULL, 0);
|
screen_alternate_off(s, NULL, 0);
|
||||||
@@ -308,12 +309,12 @@ screen_resize_cursor(struct screen *s, u_int sx, u_int sy, int reflow,
|
|||||||
if (sy != screen_size_y(s))
|
if (sy != screen_size_y(s))
|
||||||
screen_resize_y(s, sy, eat_empty, &cy);
|
screen_resize_y(s, sy, eat_empty, &cy);
|
||||||
|
|
||||||
if (reflow) {
|
|
||||||
#ifdef ENABLE_SIXEL
|
#ifdef ENABLE_SIXEL
|
||||||
image_free_all(s);
|
image_free_all(s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (reflow)
|
||||||
screen_reflow(s, sx, &cx, &cy, cursor);
|
screen_reflow(s, sx, &cx, &cy, cursor);
|
||||||
}
|
|
||||||
|
|
||||||
if (cy >= s->grid->hsize) {
|
if (cy >= s->grid->hsize) {
|
||||||
s->cx = cx;
|
s->cx = cx;
|
||||||
@@ -400,7 +401,7 @@ screen_resize_y(struct screen *s, u_int sy, int eat_empty, u_int *cy)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Try to pull as much as possible out of scrolled history, if
|
* Try to pull as much as possible out of scrolled history, if
|
||||||
* is is enabled.
|
* it is enabled.
|
||||||
*/
|
*/
|
||||||
available = gd->hscrolled;
|
available = gd->hscrolled;
|
||||||
if (gd->flags & GRID_HISTORY && available > 0) {
|
if (gd->flags & GRID_HISTORY && available > 0) {
|
||||||
@@ -730,8 +731,10 @@ screen_mode_to_string(int mode)
|
|||||||
strlcat(tmp, "ORIGIN,", sizeof tmp);
|
strlcat(tmp, "ORIGIN,", sizeof tmp);
|
||||||
if (mode & MODE_CRLF)
|
if (mode & MODE_CRLF)
|
||||||
strlcat(tmp, "CRLF,", sizeof tmp);
|
strlcat(tmp, "CRLF,", sizeof tmp);
|
||||||
if (mode & MODE_KEXTENDED)
|
if (mode & MODE_KEYS_EXTENDED)
|
||||||
strlcat(tmp, "KEXTENDED,", sizeof tmp);
|
strlcat(tmp, "KEYS_EXTENDED,", sizeof tmp);
|
||||||
|
if (mode & MODE_KEYS_EXTENDED_2)
|
||||||
|
strlcat(tmp, "KEYS_EXTENDED_2,", sizeof tmp);
|
||||||
tmp[strlen(tmp) - 1] = '\0';
|
tmp[strlen(tmp) - 1] = '\0';
|
||||||
return (tmp);
|
return (tmp);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -222,6 +222,17 @@ server_client_set_key_table(struct client *c, const char *name)
|
|||||||
key_bindings_unref_table(c->keytable);
|
key_bindings_unref_table(c->keytable);
|
||||||
c->keytable = key_bindings_get_table(name, 1);
|
c->keytable = key_bindings_get_table(name, 1);
|
||||||
c->keytable->references++;
|
c->keytable->references++;
|
||||||
|
if (gettimeofday(&c->keytable->activity_time, NULL) != 0)
|
||||||
|
fatal("gettimeofday failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t
|
||||||
|
server_client_key_table_activity_diff(struct client *c)
|
||||||
|
{
|
||||||
|
struct timeval diff;
|
||||||
|
|
||||||
|
timersub(&c->activity_time, &c->keytable->activity_time, &diff);
|
||||||
|
return ((diff.tv_sec * 1000ULL) + (diff.tv_usec / 1000ULL));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get default key table. */
|
/* Get default key table. */
|
||||||
@@ -622,6 +633,8 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
|||||||
} else if (MOUSE_RELEASE(m->b)) {
|
} else if (MOUSE_RELEASE(m->b)) {
|
||||||
type = UP;
|
type = UP;
|
||||||
x = m->x, y = m->y, b = m->lb;
|
x = m->x, y = m->y, b = m->lb;
|
||||||
|
if (m->sgr_type == 'm')
|
||||||
|
b = m->sgr_b;
|
||||||
log_debug("up at %u,%u", x, y);
|
log_debug("up at %u,%u", x, y);
|
||||||
} else {
|
} else {
|
||||||
if (c->flags & CLIENT_DOUBLECLICK) {
|
if (c->flags & CLIENT_DOUBLECLICK) {
|
||||||
@@ -642,7 +655,10 @@ server_client_check_mouse(struct client *c, struct key_event *event)
|
|||||||
log_debug("triple-click at %u,%u", x, y);
|
log_debug("triple-click at %u,%u", x, y);
|
||||||
goto have_event;
|
goto have_event;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
/* DOWN is the only remaining event type. */
|
||||||
|
if (type == NOTYPE) {
|
||||||
type = DOWN;
|
type = DOWN;
|
||||||
x = m->x, y = m->y, b = m->b;
|
x = m->x, y = m->y, b = m->b;
|
||||||
log_debug("down at %u,%u", x, y);
|
log_debug("down at %u,%u", x, y);
|
||||||
@@ -774,8 +790,7 @@ have_event:
|
|||||||
log_debug("mouse on pane %%%u border", wp->id);
|
log_debug("mouse on pane %%%u border", wp->id);
|
||||||
m->wp = wp->id;
|
m->wp = wp->id;
|
||||||
m->w = wp->window->id;
|
m->w = wp->window->id;
|
||||||
} else
|
}
|
||||||
m->wp = -1;
|
|
||||||
|
|
||||||
/* Stop dragging if needed. */
|
/* Stop dragging if needed. */
|
||||||
if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag != 0) {
|
if (type != DRAG && type != WHEEL && c->tty.mouse_drag_flag != 0) {
|
||||||
@@ -1861,7 +1876,8 @@ server_client_key_callback(struct cmdq_item *item, void *data)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
struct key_table *table, *first;
|
struct key_table *table, *first;
|
||||||
struct key_binding *bd;
|
struct key_binding *bd;
|
||||||
int xtimeout, flags;
|
int xtimeout;
|
||||||
|
uint64_t flags, prefix_delay;
|
||||||
struct cmd_find_state fs;
|
struct cmd_find_state fs;
|
||||||
key_code key0, prefix, prefix2;
|
key_code key0, prefix, prefix2;
|
||||||
|
|
||||||
@@ -1956,8 +1972,34 @@ try_again:
|
|||||||
if (c->flags & CLIENT_REPEAT)
|
if (c->flags & CLIENT_REPEAT)
|
||||||
log_debug("currently repeating");
|
log_debug("currently repeating");
|
||||||
|
|
||||||
/* Try to see if there is a key binding in the current table. */
|
|
||||||
bd = key_bindings_get(table, key0);
|
bd = key_bindings_get(table, key0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If prefix-timeout is enabled and we're in the prefix table, see if
|
||||||
|
* the timeout has been exceeded. Revert to the root table if so.
|
||||||
|
*/
|
||||||
|
prefix_delay = options_get_number(global_options, "prefix-timeout");
|
||||||
|
if (prefix_delay > 0 &&
|
||||||
|
strcmp(table->name, "prefix") == 0 &&
|
||||||
|
server_client_key_table_activity_diff(c) > prefix_delay) {
|
||||||
|
/*
|
||||||
|
* If repeating is active and this is a repeating binding,
|
||||||
|
* ignore the timeout.
|
||||||
|
*/
|
||||||
|
if (bd != NULL &&
|
||||||
|
(c->flags & CLIENT_REPEAT) &&
|
||||||
|
(bd->flags & KEY_BINDING_REPEAT)) {
|
||||||
|
log_debug("prefix timeout ignored, repeat is active");
|
||||||
|
} else {
|
||||||
|
log_debug("prefix timeout exceeded");
|
||||||
|
server_client_set_key_table(c, NULL);
|
||||||
|
first = table = c->keytable;
|
||||||
|
server_status_client(c);
|
||||||
|
goto table_changed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Try to see if there is a key binding in the current table. */
|
||||||
if (bd != NULL) {
|
if (bd != NULL) {
|
||||||
/*
|
/*
|
||||||
* Key was matched in this table. If currently repeating but a
|
* Key was matched in this table. If currently repeating but a
|
||||||
@@ -2015,7 +2057,19 @@ try_again:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* No match in this table. If not in the root table or if repeating,
|
* Binding movement keys is useless since we only turn them on when the
|
||||||
|
* application requests, so don't let them exit the prefix table.
|
||||||
|
*/
|
||||||
|
if (key == KEYC_MOUSEMOVE_PANE ||
|
||||||
|
key == KEYC_MOUSEMOVE_STATUS ||
|
||||||
|
key == KEYC_MOUSEMOVE_STATUS_LEFT ||
|
||||||
|
key == KEYC_MOUSEMOVE_STATUS_RIGHT ||
|
||||||
|
key == KEYC_MOUSEMOVE_STATUS_DEFAULT ||
|
||||||
|
key == KEYC_MOUSEMOVE_BORDER)
|
||||||
|
goto forward_key;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* No match in this table. If not in the root table or if repeating
|
||||||
* switch the client back to the root table and try again.
|
* switch the client back to the root table and try again.
|
||||||
*/
|
*/
|
||||||
log_debug("not found in key table %s", table->name);
|
log_debug("not found in key table %s", table->name);
|
||||||
@@ -2560,7 +2614,8 @@ server_client_check_redraw(struct client *c)
|
|||||||
struct tty *tty = &c->tty;
|
struct tty *tty = &c->tty;
|
||||||
struct window *w = c->session->curw->window;
|
struct window *w = c->session->curw->window;
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
int needed, flags, mode = tty->mode, new_flags = 0;
|
int needed, tty_flags, mode = tty->mode;
|
||||||
|
uint64_t client_flags = 0;
|
||||||
int redraw;
|
int redraw;
|
||||||
u_int bit = 0;
|
u_int bit = 0;
|
||||||
struct timeval tv = { .tv_usec = 1000 };
|
struct timeval tv = { .tv_usec = 1000 };
|
||||||
@@ -2594,7 +2649,7 @@ server_client_check_redraw(struct client *c)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (needed)
|
if (needed)
|
||||||
new_flags |= CLIENT_REDRAWPANES;
|
client_flags |= CLIENT_REDRAWPANES;
|
||||||
}
|
}
|
||||||
if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) {
|
if (needed && (left = EVBUFFER_LENGTH(tty->out)) != 0) {
|
||||||
log_debug("%s: redraw deferred (%zu left)", c->name, left);
|
log_debug("%s: redraw deferred (%zu left)", c->name, left);
|
||||||
@@ -2617,20 +2672,20 @@ server_client_check_redraw(struct client *c)
|
|||||||
* If more that 64 panes, give up and
|
* If more that 64 panes, give up and
|
||||||
* just redraw the window.
|
* just redraw the window.
|
||||||
*/
|
*/
|
||||||
new_flags &= CLIENT_REDRAWPANES;
|
client_flags &= CLIENT_REDRAWPANES;
|
||||||
new_flags |= CLIENT_REDRAWWINDOW;
|
client_flags |= CLIENT_REDRAWWINDOW;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (c->redraw_panes != 0)
|
if (c->redraw_panes != 0)
|
||||||
c->flags |= CLIENT_REDRAWPANES;
|
c->flags |= CLIENT_REDRAWPANES;
|
||||||
}
|
}
|
||||||
c->flags |= new_flags;
|
c->flags |= client_flags;
|
||||||
return;
|
return;
|
||||||
} else if (needed)
|
} else if (needed)
|
||||||
log_debug("%s: redraw needed", c->name);
|
log_debug("%s: redraw needed", c->name);
|
||||||
|
|
||||||
flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR);
|
tty_flags = tty->flags & (TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR);
|
||||||
tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE))|TTY_NOCURSOR;
|
tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE))|TTY_NOCURSOR;
|
||||||
|
|
||||||
if (~c->flags & CLIENT_REDRAWWINDOW) {
|
if (~c->flags & CLIENT_REDRAWWINDOW) {
|
||||||
@@ -2662,9 +2717,10 @@ server_client_check_redraw(struct client *c)
|
|||||||
screen_redraw_screen(c);
|
screen_redraw_screen(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
tty->flags = (tty->flags & ~TTY_NOCURSOR)|(flags & TTY_NOCURSOR);
|
tty->flags = (tty->flags & ~TTY_NOCURSOR)|(tty_flags & TTY_NOCURSOR);
|
||||||
tty_update_mode(tty, mode, NULL);
|
tty_update_mode(tty, mode, NULL);
|
||||||
tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR))|flags;
|
tty->flags = (tty->flags & ~(TTY_BLOCK|TTY_FREEZE|TTY_NOCURSOR))|
|
||||||
|
tty_flags;
|
||||||
|
|
||||||
c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE);
|
c->flags &= ~(CLIENT_ALLREDRAWFLAGS|CLIENT_STATUSFORCE);
|
||||||
|
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ server_find_session(struct session *s,
|
|||||||
static int
|
static int
|
||||||
server_newer_session(struct session *s_loop, struct session *s_out)
|
server_newer_session(struct session *s_loop, struct session *s_out)
|
||||||
{
|
{
|
||||||
return (timercmp(&s_loop->activity_time, &s_out->activity_time, <));
|
return (timercmp(&s_loop->activity_time, &s_out->activity_time, >));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -488,6 +488,6 @@ server_check_unattached(void)
|
|||||||
void
|
void
|
||||||
server_unzoom_window(struct window *w)
|
server_unzoom_window(struct window *w)
|
||||||
{
|
{
|
||||||
if (window_unzoom(w) == 0)
|
if (window_unzoom(w, 1) == 0)
|
||||||
server_redraw_window(w);
|
server_redraw_window(w);
|
||||||
}
|
}
|
||||||
|
|||||||
6
server.c
6
server.c
@@ -103,7 +103,7 @@ server_check_marked(void)
|
|||||||
|
|
||||||
/* Create server socket. */
|
/* Create server socket. */
|
||||||
int
|
int
|
||||||
server_create_socket(int flags, char **cause)
|
server_create_socket(uint64_t flags, char **cause)
|
||||||
{
|
{
|
||||||
struct sockaddr_un sa;
|
struct sockaddr_un sa;
|
||||||
size_t size;
|
size_t size;
|
||||||
@@ -172,7 +172,7 @@ server_tidy_event(__unused int fd, __unused short events, __unused void *data)
|
|||||||
|
|
||||||
/* Fork new server. */
|
/* Fork new server. */
|
||||||
int
|
int
|
||||||
server_start(struct tmuxproc *client, int flags, struct event_base *base,
|
server_start(struct tmuxproc *client, uint64_t flags, struct event_base *base,
|
||||||
int lockfd, char *lockfile)
|
int lockfd, char *lockfile)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
@@ -264,7 +264,7 @@ server_loop(void)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
u_int items;
|
u_int items;
|
||||||
|
|
||||||
current_time = time (NULL);
|
current_time = time(NULL);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
items = cmdq_next(NULL);
|
items = cmdq_next(NULL);
|
||||||
|
|||||||
119
status.c
119
status.c
@@ -607,6 +607,8 @@ status_prompt_set(struct client *c, struct cmd_find_state *fs,
|
|||||||
struct format_tree *ft;
|
struct format_tree *ft;
|
||||||
char *tmp;
|
char *tmp;
|
||||||
|
|
||||||
|
server_client_clear_overlay(c);
|
||||||
|
|
||||||
if (fs != NULL)
|
if (fs != NULL)
|
||||||
ft = format_create_from_state(NULL, c, fs);
|
ft = format_create_from_state(NULL, c, fs);
|
||||||
else
|
else
|
||||||
@@ -839,19 +841,19 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
{
|
{
|
||||||
if (c->prompt_mode == PROMPT_ENTRY) {
|
if (c->prompt_mode == PROMPT_ENTRY) {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case '\001': /* C-a */
|
case 'a'|KEYC_CTRL:
|
||||||
case '\003': /* C-c */
|
case 'c'|KEYC_CTRL:
|
||||||
case '\005': /* C-e */
|
case 'e'|KEYC_CTRL:
|
||||||
case '\007': /* C-g */
|
case 'g'|KEYC_CTRL:
|
||||||
case '\010': /* C-h */
|
case 'h'|KEYC_CTRL:
|
||||||
case '\011': /* Tab */
|
case '\011': /* Tab */
|
||||||
case '\013': /* C-k */
|
case 'k'|KEYC_CTRL:
|
||||||
case '\016': /* C-n */
|
case 'n'|KEYC_CTRL:
|
||||||
case '\020': /* C-p */
|
case 'p'|KEYC_CTRL:
|
||||||
case '\024': /* C-t */
|
case 't'|KEYC_CTRL:
|
||||||
case '\025': /* C-u */
|
case 'u'|KEYC_CTRL:
|
||||||
case '\027': /* C-w */
|
case 'w'|KEYC_CTRL:
|
||||||
case '\031': /* C-y */
|
case 'y'|KEYC_CTRL:
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
case KEYC_LEFT|KEYC_CTRL:
|
case KEYC_LEFT|KEYC_CTRL:
|
||||||
@@ -890,7 +892,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
case 'S':
|
case 'S':
|
||||||
c->prompt_mode = PROMPT_ENTRY;
|
c->prompt_mode = PROMPT_ENTRY;
|
||||||
c->flags |= CLIENT_REDRAWSTATUS;
|
c->flags |= CLIENT_REDRAWSTATUS;
|
||||||
*new_key = '\025'; /* C-u */
|
*new_key = 'u'|KEYC_CTRL;
|
||||||
return (1);
|
return (1);
|
||||||
case 'i':
|
case 'i':
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
@@ -911,7 +913,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
return (1);
|
return (1);
|
||||||
case 'C':
|
case 'C':
|
||||||
case 'D':
|
case 'D':
|
||||||
*new_key = '\013'; /* C-k */
|
*new_key = 'k'|KEYC_CTRL;
|
||||||
return (1);
|
return (1);
|
||||||
case KEYC_BSPACE:
|
case KEYC_BSPACE:
|
||||||
case 'X':
|
case 'X':
|
||||||
@@ -924,7 +926,7 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
*new_key = 'B'|KEYC_VI;
|
*new_key = 'B'|KEYC_VI;
|
||||||
return (1);
|
return (1);
|
||||||
case 'd':
|
case 'd':
|
||||||
*new_key = '\025'; /* C-u */
|
*new_key = 'u'|KEYC_CTRL;
|
||||||
return (1);
|
return (1);
|
||||||
case 'e':
|
case 'e':
|
||||||
*new_key = 'e'|KEYC_VI;
|
*new_key = 'e'|KEYC_VI;
|
||||||
@@ -939,10 +941,10 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
*new_key = 'W'|KEYC_VI;
|
*new_key = 'W'|KEYC_VI;
|
||||||
return (1);
|
return (1);
|
||||||
case 'p':
|
case 'p':
|
||||||
*new_key = '\031'; /* C-y */
|
*new_key = 'y'|KEYC_CTRL;
|
||||||
return (1);
|
return (1);
|
||||||
case 'q':
|
case 'q':
|
||||||
*new_key = '\003'; /* C-c */
|
*new_key = 'c'|KEYC_CTRL;
|
||||||
return (1);
|
return (1);
|
||||||
case 's':
|
case 's':
|
||||||
case KEYC_DC:
|
case KEYC_DC:
|
||||||
@@ -966,8 +968,8 @@ status_prompt_translate_key(struct client *c, key_code key, key_code *new_key)
|
|||||||
case 'k':
|
case 'k':
|
||||||
*new_key = KEYC_UP;
|
*new_key = KEYC_UP;
|
||||||
return (1);
|
return (1);
|
||||||
case '\010' /* C-h */:
|
case 'h'|KEYC_CTRL:
|
||||||
case '\003' /* C-c */:
|
case 'c'|KEYC_CTRL:
|
||||||
case '\n':
|
case '\n':
|
||||||
case '\r':
|
case '\r':
|
||||||
return (1);
|
return (1);
|
||||||
@@ -994,8 +996,7 @@ status_prompt_paste(struct client *c)
|
|||||||
if ((pb = paste_get_top(NULL)) == NULL)
|
if ((pb = paste_get_top(NULL)) == NULL)
|
||||||
return (0);
|
return (0);
|
||||||
bufdata = paste_buffer_data(pb, &bufsize);
|
bufdata = paste_buffer_data(pb, &bufsize);
|
||||||
ud = xreallocarray(NULL, bufsize + 1, sizeof *ud);
|
ud = udp = xreallocarray(NULL, bufsize + 1, sizeof *ud);
|
||||||
udp = ud;
|
|
||||||
for (i = 0; i != bufsize; /* nothing */) {
|
for (i = 0; i != bufsize; /* nothing */) {
|
||||||
more = utf8_open(udp, bufdata[i]);
|
more = utf8_open(udp, bufdata[i]);
|
||||||
if (more == UTF8_MORE) {
|
if (more == UTF8_MORE) {
|
||||||
@@ -1016,25 +1017,24 @@ status_prompt_paste(struct client *c)
|
|||||||
udp->size = 0;
|
udp->size = 0;
|
||||||
n = udp - ud;
|
n = udp - ud;
|
||||||
}
|
}
|
||||||
if (n == 0)
|
if (n != 0) {
|
||||||
return (0);
|
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
|
||||||
|
sizeof *c->prompt_buffer);
|
||||||
c->prompt_buffer = xreallocarray(c->prompt_buffer, size + n + 1,
|
if (c->prompt_index == size) {
|
||||||
sizeof *c->prompt_buffer);
|
memcpy(c->prompt_buffer + c->prompt_index, ud,
|
||||||
if (c->prompt_index == size) {
|
n * sizeof *c->prompt_buffer);
|
||||||
memcpy(c->prompt_buffer + c->prompt_index, ud,
|
c->prompt_index += n;
|
||||||
n * sizeof *c->prompt_buffer);
|
c->prompt_buffer[c->prompt_index].size = 0;
|
||||||
c->prompt_index += n;
|
} else {
|
||||||
c->prompt_buffer[c->prompt_index].size = 0;
|
memmove(c->prompt_buffer + c->prompt_index + n,
|
||||||
} else {
|
c->prompt_buffer + c->prompt_index,
|
||||||
memmove(c->prompt_buffer + c->prompt_index + n,
|
(size + 1 - c->prompt_index) *
|
||||||
c->prompt_buffer + c->prompt_index,
|
sizeof *c->prompt_buffer);
|
||||||
(size + 1 - c->prompt_index) * sizeof *c->prompt_buffer);
|
memcpy(c->prompt_buffer + c->prompt_index, ud,
|
||||||
memcpy(c->prompt_buffer + c->prompt_index, ud,
|
n * sizeof *c->prompt_buffer);
|
||||||
n * sizeof *c->prompt_buffer);
|
c->prompt_index += n;
|
||||||
c->prompt_index += n;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ud != c->prompt_saved)
|
if (ud != c->prompt_saved)
|
||||||
free(ud);
|
free(ud);
|
||||||
return (1);
|
return (1);
|
||||||
@@ -1265,28 +1265,28 @@ status_prompt_key(struct client *c, key_code key)
|
|||||||
process_key:
|
process_key:
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case KEYC_LEFT:
|
case KEYC_LEFT:
|
||||||
case '\002': /* C-b */
|
case 'b'|KEYC_CTRL:
|
||||||
if (c->prompt_index > 0) {
|
if (c->prompt_index > 0) {
|
||||||
c->prompt_index--;
|
c->prompt_index--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYC_RIGHT:
|
case KEYC_RIGHT:
|
||||||
case '\006': /* C-f */
|
case 'f'|KEYC_CTRL:
|
||||||
if (c->prompt_index < size) {
|
if (c->prompt_index < size) {
|
||||||
c->prompt_index++;
|
c->prompt_index++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYC_HOME:
|
case KEYC_HOME:
|
||||||
case '\001': /* C-a */
|
case 'a'|KEYC_CTRL:
|
||||||
if (c->prompt_index != 0) {
|
if (c->prompt_index != 0) {
|
||||||
c->prompt_index = 0;
|
c->prompt_index = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYC_END:
|
case KEYC_END:
|
||||||
case '\005': /* C-e */
|
case 'e'|KEYC_CTRL:
|
||||||
if (c->prompt_index != size) {
|
if (c->prompt_index != size) {
|
||||||
c->prompt_index = size;
|
c->prompt_index = size;
|
||||||
break;
|
break;
|
||||||
@@ -1297,7 +1297,7 @@ process_key:
|
|||||||
goto changed;
|
goto changed;
|
||||||
break;
|
break;
|
||||||
case KEYC_BSPACE:
|
case KEYC_BSPACE:
|
||||||
case '\010': /* C-h */
|
case 'h'|KEYC_CTRL:
|
||||||
if (c->prompt_index != 0) {
|
if (c->prompt_index != 0) {
|
||||||
if (c->prompt_index == size)
|
if (c->prompt_index == size)
|
||||||
c->prompt_buffer[--c->prompt_index].size = 0;
|
c->prompt_buffer[--c->prompt_index].size = 0;
|
||||||
@@ -1312,7 +1312,7 @@ process_key:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEYC_DC:
|
case KEYC_DC:
|
||||||
case '\004': /* C-d */
|
case 'd'|KEYC_CTRL:
|
||||||
if (c->prompt_index != size) {
|
if (c->prompt_index != size) {
|
||||||
memmove(c->prompt_buffer + c->prompt_index,
|
memmove(c->prompt_buffer + c->prompt_index,
|
||||||
c->prompt_buffer + c->prompt_index + 1,
|
c->prompt_buffer + c->prompt_index + 1,
|
||||||
@@ -1321,17 +1321,17 @@ process_key:
|
|||||||
goto changed;
|
goto changed;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\025': /* C-u */
|
case 'u'|KEYC_CTRL:
|
||||||
c->prompt_buffer[0].size = 0;
|
c->prompt_buffer[0].size = 0;
|
||||||
c->prompt_index = 0;
|
c->prompt_index = 0;
|
||||||
goto changed;
|
goto changed;
|
||||||
case '\013': /* C-k */
|
case 'k'|KEYC_CTRL:
|
||||||
if (c->prompt_index < size) {
|
if (c->prompt_index < size) {
|
||||||
c->prompt_buffer[c->prompt_index].size = 0;
|
c->prompt_buffer[c->prompt_index].size = 0;
|
||||||
goto changed;
|
goto changed;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '\027': /* C-w */
|
case 'w'|KEYC_CTRL:
|
||||||
separators = options_get_string(oo, "word-separators");
|
separators = options_get_string(oo, "word-separators");
|
||||||
idx = c->prompt_index;
|
idx = c->prompt_index;
|
||||||
|
|
||||||
@@ -1399,7 +1399,7 @@ process_key:
|
|||||||
status_prompt_backward_word(c, separators);
|
status_prompt_backward_word(c, separators);
|
||||||
goto changed;
|
goto changed;
|
||||||
case KEYC_UP:
|
case KEYC_UP:
|
||||||
case '\020': /* C-p */
|
case 'p'|KEYC_CTRL:
|
||||||
histstr = status_prompt_up_history(c->prompt_hindex,
|
histstr = status_prompt_up_history(c->prompt_hindex,
|
||||||
c->prompt_type);
|
c->prompt_type);
|
||||||
if (histstr == NULL)
|
if (histstr == NULL)
|
||||||
@@ -1409,7 +1409,7 @@ process_key:
|
|||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
goto changed;
|
goto changed;
|
||||||
case KEYC_DOWN:
|
case KEYC_DOWN:
|
||||||
case '\016': /* C-n */
|
case 'n'|KEYC_CTRL:
|
||||||
histstr = status_prompt_down_history(c->prompt_hindex,
|
histstr = status_prompt_down_history(c->prompt_hindex,
|
||||||
c->prompt_type);
|
c->prompt_type);
|
||||||
if (histstr == NULL)
|
if (histstr == NULL)
|
||||||
@@ -1418,11 +1418,11 @@ process_key:
|
|||||||
c->prompt_buffer = utf8_fromcstr(histstr);
|
c->prompt_buffer = utf8_fromcstr(histstr);
|
||||||
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
c->prompt_index = utf8_strlen(c->prompt_buffer);
|
||||||
goto changed;
|
goto changed;
|
||||||
case '\031': /* C-y */
|
case 'y'|KEYC_CTRL:
|
||||||
if (status_prompt_paste(c))
|
if (status_prompt_paste(c))
|
||||||
goto changed;
|
goto changed;
|
||||||
break;
|
break;
|
||||||
case '\024': /* C-t */
|
case 't'|KEYC_CTRL:
|
||||||
idx = c->prompt_index;
|
idx = c->prompt_index;
|
||||||
if (idx < size)
|
if (idx < size)
|
||||||
idx++;
|
idx++;
|
||||||
@@ -1445,12 +1445,12 @@ process_key:
|
|||||||
free(s);
|
free(s);
|
||||||
break;
|
break;
|
||||||
case '\033': /* Escape */
|
case '\033': /* Escape */
|
||||||
case '\003': /* C-c */
|
case 'c'|KEYC_CTRL:
|
||||||
case '\007': /* C-g */
|
case 'g'|KEYC_CTRL:
|
||||||
if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
|
if (c->prompt_inputcb(c, c->prompt_data, NULL, 1) == 0)
|
||||||
status_prompt_clear(c);
|
status_prompt_clear(c);
|
||||||
break;
|
break;
|
||||||
case '\022': /* C-r */
|
case 'r'|KEYC_CTRL:
|
||||||
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
||||||
break;
|
break;
|
||||||
if (c->prompt_buffer[0].size == 0) {
|
if (c->prompt_buffer[0].size == 0) {
|
||||||
@@ -1461,7 +1461,7 @@ process_key:
|
|||||||
} else
|
} else
|
||||||
prefix = '-';
|
prefix = '-';
|
||||||
goto changed;
|
goto changed;
|
||||||
case '\023': /* C-s */
|
case 's'|KEYC_CTRL:
|
||||||
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
if (~c->prompt_flags & PROMPT_INCREMENTAL)
|
||||||
break;
|
break;
|
||||||
if (c->prompt_buffer[0].size == 0) {
|
if (c->prompt_buffer[0].size == 0) {
|
||||||
@@ -1628,8 +1628,9 @@ status_prompt_complete_list(u_int *size, const char *s, int at_start)
|
|||||||
struct options_entry *o;
|
struct options_entry *o;
|
||||||
struct options_array_item *a;
|
struct options_array_item *a;
|
||||||
const char *layouts[] = {
|
const char *layouts[] = {
|
||||||
"even-horizontal", "even-vertical", "main-horizontal",
|
"even-horizontal", "even-vertical",
|
||||||
"main-vertical", "tiled", NULL
|
"main-horizontal", "main-horizontal-mirrored",
|
||||||
|
"main-vertical", "main-vertical-mirrored", "tiled", NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
@@ -1839,6 +1840,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
|
|||||||
}
|
}
|
||||||
if (size == 0) {
|
if (size == 0) {
|
||||||
menu_free(menu);
|
menu_free(menu);
|
||||||
|
free(spm);
|
||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
if (size == 1) {
|
if (size == 1) {
|
||||||
@@ -1849,6 +1851,7 @@ status_prompt_complete_window_menu(struct client *c, struct session *s,
|
|||||||
} else
|
} else
|
||||||
tmp = list[0];
|
tmp = list[0];
|
||||||
free(list);
|
free(list);
|
||||||
|
free(spm);
|
||||||
return (tmp);
|
return (tmp);
|
||||||
}
|
}
|
||||||
if (height > size)
|
if (height > size)
|
||||||
|
|||||||
30
style.c
30
style.c
@@ -58,10 +58,11 @@ int
|
|||||||
style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
||||||
{
|
{
|
||||||
struct style saved;
|
struct style saved;
|
||||||
const char delimiters[] = " ,\n", *cp;
|
const char delimiters[] = " ,\n", *errstr;
|
||||||
char tmp[256], *found;
|
char tmp[256], *found;
|
||||||
int value;
|
int value;
|
||||||
size_t end;
|
size_t end;
|
||||||
|
u_int n;
|
||||||
|
|
||||||
if (*in == '\0')
|
if (*in == '\0')
|
||||||
return (0);
|
return (0);
|
||||||
@@ -137,34 +138,31 @@ style_parse(struct style *sy, const struct grid_cell *base, const char *in)
|
|||||||
goto error;
|
goto error;
|
||||||
if (*found != '%' || found[1] == '\0')
|
if (*found != '%' || found[1] == '\0')
|
||||||
goto error;
|
goto error;
|
||||||
for (cp = found + 1; *cp != '\0'; cp++) {
|
n = strtonum(found + 1, 0, UINT_MAX, &errstr);
|
||||||
if (!isdigit((u_char)*cp))
|
if (errstr != NULL)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
sy->range_type = STYLE_RANGE_PANE;
|
sy->range_type = STYLE_RANGE_PANE;
|
||||||
sy->range_argument = atoi(found + 1);
|
sy->range_argument = n;
|
||||||
style_set_range_string(sy, "");
|
style_set_range_string(sy, "");
|
||||||
} else if (strcasecmp(tmp + 6, "window") == 0) {
|
} else if (strcasecmp(tmp + 6, "window") == 0) {
|
||||||
if (found == NULL)
|
if (found == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
for (cp = found; *cp != '\0'; cp++) {
|
n = strtonum(found, 0, UINT_MAX, &errstr);
|
||||||
if (!isdigit((u_char)*cp))
|
if (errstr != NULL)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
sy->range_type = STYLE_RANGE_WINDOW;
|
sy->range_type = STYLE_RANGE_WINDOW;
|
||||||
sy->range_argument = atoi(found);
|
sy->range_argument = n;
|
||||||
style_set_range_string(sy, "");
|
style_set_range_string(sy, "");
|
||||||
} else if (strcasecmp(tmp + 6, "session") == 0) {
|
} else if (strcasecmp(tmp + 6, "session") == 0) {
|
||||||
if (found == NULL)
|
if (found == NULL)
|
||||||
goto error;
|
goto error;
|
||||||
if (*found != '$' || found[1] == '\0')
|
if (*found != '$' || found[1] == '\0')
|
||||||
goto error;
|
goto error;
|
||||||
for (cp = found + 1; *cp != '\0'; cp++) {
|
n = strtonum(found + 1, 0, UINT_MAX, &errstr);
|
||||||
if (!isdigit((u_char)*cp))
|
if (errstr != NULL)
|
||||||
goto error;
|
goto error;
|
||||||
}
|
|
||||||
sy->range_type = STYLE_RANGE_SESSION;
|
sy->range_type = STYLE_RANGE_SESSION;
|
||||||
sy->range_argument = atoi(found + 1);
|
sy->range_argument = n;
|
||||||
style_set_range_string(sy, "");
|
style_set_range_string(sy, "");
|
||||||
} else if (strcasecmp(tmp + 6, "user") == 0) {
|
} else if (strcasecmp(tmp + 6, "user") == 0) {
|
||||||
if (found == NULL)
|
if (found == NULL)
|
||||||
|
|||||||
472
tmux.1
472
tmux.1
@@ -140,10 +140,9 @@ By default,
|
|||||||
loads the system configuration file from
|
loads the system configuration file from
|
||||||
.Pa @SYSCONFDIR@/tmux.conf ,
|
.Pa @SYSCONFDIR@/tmux.conf ,
|
||||||
if present, then looks for a user configuration file at
|
if present, then looks for a user configuration file at
|
||||||
.Pa \[ti]/.tmux.conf,
|
.Pa \[ti]/.tmux.conf
|
||||||
.Pa $XDG_CONFIG_HOME/tmux/tmux.conf
|
|
||||||
or
|
or
|
||||||
.Pa \[ti]/.tmux.conf .
|
.Pa $XDG_CONFIG_HOME/tmux/tmux.conf .
|
||||||
.Pp
|
.Pp
|
||||||
The configuration file is a set of
|
The configuration file is a set of
|
||||||
.Nm
|
.Nm
|
||||||
@@ -373,8 +372,10 @@ Enter copy mode and scroll one page up.
|
|||||||
Change to the pane above, below, to the left, or to the right of the current
|
Change to the pane above, below, to the left, or to the right of the current
|
||||||
pane.
|
pane.
|
||||||
.It M-1 to M-5
|
.It M-1 to M-5
|
||||||
Arrange panes in one of the five preset layouts: even-horizontal,
|
Arrange panes in one of the seven preset layouts:
|
||||||
even-vertical, main-horizontal, main-vertical, or tiled.
|
even-horizontal, even-vertical,
|
||||||
|
main-horizontal, main-horizontal-mirrored,
|
||||||
|
main-vertical, main-vertical, or tiled.
|
||||||
.It Space
|
.It Space
|
||||||
Arrange the current window in the next preset layout.
|
Arrange the current window in the next preset layout.
|
||||||
.It M-n
|
.It M-n
|
||||||
@@ -1039,9 +1040,17 @@ The following commands are available to manage clients and sessions:
|
|||||||
.D1 Pq alias: Ic attach
|
.D1 Pq alias: Ic attach
|
||||||
If run from outside
|
If run from outside
|
||||||
.Nm ,
|
.Nm ,
|
||||||
create a new client in the current terminal and attach it to
|
attach to
|
||||||
|
.Ar target-session
|
||||||
|
in the current terminal.
|
||||||
|
.Ar target-session
|
||||||
|
must already exist - to create a new session, see the
|
||||||
|
.Ic new-session
|
||||||
|
command (with
|
||||||
|
.Fl A
|
||||||
|
to create or attach).
|
||||||
|
If used from inside, switch the currently attached session to
|
||||||
.Ar target-session .
|
.Ar target-session .
|
||||||
If used from inside, switch the current client.
|
|
||||||
If
|
If
|
||||||
.Fl d
|
.Fl d
|
||||||
is specified, any other clients attached to the session are detached.
|
is specified, any other clients attached to the session are detached.
|
||||||
@@ -1353,6 +1362,7 @@ specified multiple times.
|
|||||||
.Op Fl C Ar size
|
.Op Fl C Ar size
|
||||||
.Op Fl f Ar flags
|
.Op Fl f Ar flags
|
||||||
.Op Fl l Op Ar target-pane
|
.Op Fl l Op Ar target-pane
|
||||||
|
.Op Fl r Ar pane:report
|
||||||
.Op Fl t Ar target-client
|
.Op Fl t Ar target-client
|
||||||
.Op Ar adjustment
|
.Op Ar adjustment
|
||||||
.Xc
|
.Xc
|
||||||
@@ -1462,6 +1472,12 @@ for all windows in the attached session.
|
|||||||
.Fl f
|
.Fl f
|
||||||
sets a comma-separated list of client flags, see
|
sets a comma-separated list of client flags, see
|
||||||
.Ic attach-session .
|
.Ic attach-session .
|
||||||
|
.Fl r
|
||||||
|
allows a control mode client to provide information about a pane via a report
|
||||||
|
(such as the response to OSC 10).
|
||||||
|
The argument is a pane ID (with a leading
|
||||||
|
.Ql % ) ,
|
||||||
|
a colon, then a report escape sequence.
|
||||||
.Pp
|
.Pp
|
||||||
.Fl l
|
.Fl l
|
||||||
requests the clipboard from the client using the
|
requests the clipboard from the client using the
|
||||||
@@ -1798,6 +1814,23 @@ is used to name the new paste buffer.
|
|||||||
.Xc
|
.Xc
|
||||||
Copy from the cursor position and exit copy mode.
|
Copy from the cursor position and exit copy mode.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic copy-pipe-end-of-line
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Copy from the cursor position to the end of the line and pipe the text to
|
||||||
|
.Ar command .
|
||||||
|
.Ar prefix
|
||||||
|
is used to name the new paste buffer.
|
||||||
|
.It Xo
|
||||||
|
.Ic copy-pipe-end-of-line-and-cancel
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic copy-pipe-end-of-line
|
||||||
|
but also exit copy mode.
|
||||||
|
.It Xo
|
||||||
.Ic copy-line
|
.Ic copy-line
|
||||||
.Op Ar prefix
|
.Op Ar prefix
|
||||||
.Xc
|
.Xc
|
||||||
@@ -1808,11 +1841,60 @@ Copy the entire line.
|
|||||||
.Xc
|
.Xc
|
||||||
Copy the entire line and exit copy mode.
|
Copy the entire line and exit copy mode.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic copy-pipe-line
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Copy the entire line and pipe the text to
|
||||||
|
.Ar command .
|
||||||
|
.Ar prefix
|
||||||
|
is used to name the new paste buffer.
|
||||||
|
.It Xo
|
||||||
|
.Ic copy-pipe-line-and-cancel
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic copy-pipe-line
|
||||||
|
but also exit copy mode.
|
||||||
|
.It Xo
|
||||||
|
.Ic copy-pipe
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Copy the selection, clear it and pipe its text to
|
||||||
|
.Ar command .
|
||||||
|
.Ar prefix
|
||||||
|
is used to name the new paste buffer.
|
||||||
|
.It Xo
|
||||||
|
.Ic copy-pipe-no-clear
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic copy-pipe
|
||||||
|
but do not clear the selection.
|
||||||
|
.It Xo
|
||||||
|
.Ic copy-pipe-and-cancel
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic copy-pipe
|
||||||
|
but also exit copy mode.
|
||||||
|
.It Xo
|
||||||
.Ic copy-selection
|
.Ic copy-selection
|
||||||
.Op Ar prefix
|
.Op Ar prefix
|
||||||
.Xc
|
.Xc
|
||||||
Copies the current selection.
|
Copies the current selection.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic copy-selection-no-clear
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic copy-selection
|
||||||
|
but do not clear the selection.
|
||||||
|
.It Xo
|
||||||
.Ic copy-selection-and-cancel
|
.Ic copy-selection-and-cancel
|
||||||
.Op Ar prefix
|
.Op Ar prefix
|
||||||
(vi: Enter)
|
(vi: Enter)
|
||||||
@@ -1826,6 +1908,12 @@ Copy the current selection and exit copy mode.
|
|||||||
.Xc
|
.Xc
|
||||||
Move the cursor down.
|
Move the cursor down.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic cursor-down-and-cancel
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic cursor-down
|
||||||
|
but also exit copy mode if reaching the bottom.
|
||||||
|
.It Xo
|
||||||
.Ic cursor-left
|
.Ic cursor-left
|
||||||
(vi: h)
|
(vi: h)
|
||||||
(emacs: Left)
|
(emacs: Left)
|
||||||
@@ -1857,6 +1945,24 @@ Move the cursor to the end of the line.
|
|||||||
.Xc
|
.Xc
|
||||||
Move the cursor to a specific line.
|
Move the cursor to a specific line.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic halfpage-down
|
||||||
|
(vi: C-d)
|
||||||
|
(emacs: M-Down)
|
||||||
|
.Xc
|
||||||
|
Scroll down by half a page.
|
||||||
|
.It Xo
|
||||||
|
.Ic halfpage-down-and-cancel
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic halfpage-down
|
||||||
|
but also exit copy mode if reaching the bottom.
|
||||||
|
.It Xo
|
||||||
|
.Ic halfpage-up
|
||||||
|
(vi: C-u)
|
||||||
|
(emacs: M-Up)
|
||||||
|
.Xc
|
||||||
|
Scroll up by half a page.
|
||||||
|
.It Xo
|
||||||
.Ic history-bottom
|
.Ic history-bottom
|
||||||
(vi: G)
|
(vi: G)
|
||||||
(emacs: M->)
|
(emacs: M->)
|
||||||
@@ -1889,6 +1995,27 @@ Jump backwards to the specified text.
|
|||||||
.Xc
|
.Xc
|
||||||
Jump forward to the specified text.
|
Jump forward to the specified text.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic jump-reverse
|
||||||
|
(vi: ,)
|
||||||
|
(emacs: ,)
|
||||||
|
.Xc
|
||||||
|
Repeat the last jump in the reverse direction (forward becomes backward and
|
||||||
|
backward becomes forward).
|
||||||
|
.It Xo
|
||||||
|
.Ic jump-to-backward
|
||||||
|
.Ar to
|
||||||
|
(vi: T)
|
||||||
|
.Xc
|
||||||
|
Jump backwards, but one character less, placing the cursor on the character
|
||||||
|
after the target.
|
||||||
|
.It Xo
|
||||||
|
.Ic jump-to-forward
|
||||||
|
.Ar to
|
||||||
|
(vi: t)
|
||||||
|
.Xc
|
||||||
|
Jump forward, but one character less, placing the cursor on the character
|
||||||
|
before the target.
|
||||||
|
.It Xo
|
||||||
.Ic jump-to-mark
|
.Ic jump-to-mark
|
||||||
(vi: M-x)
|
(vi: M-x)
|
||||||
(emacs: M-x)
|
(emacs: M-x)
|
||||||
@@ -1923,18 +2050,71 @@ Move to the next prompt.
|
|||||||
.Xc
|
.Xc
|
||||||
Move to the next word.
|
Move to the next word.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic next-word-end
|
||||||
|
(vi: e)
|
||||||
|
(emacs: M-f)
|
||||||
|
.Xc
|
||||||
|
Move to the end of the next word.
|
||||||
|
.It Xo
|
||||||
|
.Ic next-space
|
||||||
|
(vi: W)
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic next-word
|
||||||
|
but use a space alone as the word separator.
|
||||||
|
.It Xo
|
||||||
|
.Ic next-space-end
|
||||||
|
(vi: E)
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic next-word-end
|
||||||
|
but use a space alone as the word separator.
|
||||||
|
.It Xo
|
||||||
|
.Ic other-end
|
||||||
|
(vi: o)
|
||||||
|
.Xc
|
||||||
|
Switch at which end of the selection the cursor sits.
|
||||||
|
.It Xo
|
||||||
.Ic page-down
|
.Ic page-down
|
||||||
(vi: C-f)
|
(vi: C-f)
|
||||||
(emacs: PageDown)
|
(emacs: PageDown)
|
||||||
.Xc
|
.Xc
|
||||||
Scroll down by one page.
|
Scroll down by one page.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic page-down-and-cancel
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic page-down
|
||||||
|
but also exit copy mode if reaching the bottom.
|
||||||
|
.It Xo
|
||||||
.Ic page-up
|
.Ic page-up
|
||||||
(vi: C-b)
|
(vi: C-b)
|
||||||
(emacs: PageUp)
|
(emacs: PageUp)
|
||||||
.Xc
|
.Xc
|
||||||
Scroll up by one page.
|
Scroll up by one page.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic pipe
|
||||||
|
.Op Ar command
|
||||||
|
.Xc
|
||||||
|
Pipe the selected text to
|
||||||
|
.Ar command
|
||||||
|
and clear the selection.
|
||||||
|
.It Xo
|
||||||
|
.Ic pipe-no-clear
|
||||||
|
.Op Ar command
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic pipe
|
||||||
|
but do not clear the selection.
|
||||||
|
.It Xo
|
||||||
|
.Ic pipe-and-cancel
|
||||||
|
.Op Ar command
|
||||||
|
.Op Ar prefix
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic pipe
|
||||||
|
but also exit copy mode.
|
||||||
|
.It Xo
|
||||||
.Ic previous-matching-bracket
|
.Ic previous-matching-bracket
|
||||||
(emacs: M-C-b)
|
(emacs: M-C-b)
|
||||||
.Xc
|
.Xc
|
||||||
@@ -1957,6 +2137,21 @@ Move to the previous prompt.
|
|||||||
.Xc
|
.Xc
|
||||||
Move to the previous word.
|
Move to the previous word.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic previous-space
|
||||||
|
(vi: B)
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic previous-word
|
||||||
|
but use a space alone as the word separator.
|
||||||
|
.It Xo
|
||||||
|
.Ic rectangle-on
|
||||||
|
.Xc
|
||||||
|
Turn on rectangle selection mode.
|
||||||
|
.It Xo
|
||||||
|
.Ic rectangle-off
|
||||||
|
.Xc
|
||||||
|
Turn off rectangle selection mode.
|
||||||
|
.It Xo
|
||||||
.Ic rectangle-toggle
|
.Ic rectangle-toggle
|
||||||
(vi: v)
|
(vi: v)
|
||||||
(emacs: R)
|
(emacs: R)
|
||||||
@@ -1969,6 +2164,40 @@ Toggle rectangle selection mode.
|
|||||||
.Xc
|
.Xc
|
||||||
Refresh the content from the pane.
|
Refresh the content from the pane.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic scroll-bottom
|
||||||
|
.Xc
|
||||||
|
Scroll up until the current line is at the bottom while keeping the cursor on
|
||||||
|
that line.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-down
|
||||||
|
(vi: C-e)
|
||||||
|
(emacs: C-Down)
|
||||||
|
.Xc
|
||||||
|
Scroll down.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-down-and-cancel
|
||||||
|
.Xc
|
||||||
|
Same as
|
||||||
|
.Ic scroll-down
|
||||||
|
but also exit copy mode if the cursor reaches the bottom.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-middle
|
||||||
|
(vi: z)
|
||||||
|
.Xc
|
||||||
|
Scroll so that the current line becomes the middle one while keeping the
|
||||||
|
cursor on that line.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-top
|
||||||
|
.Xc
|
||||||
|
Scroll down until the current line is at the top while keeping the cursor on
|
||||||
|
that line.
|
||||||
|
.It Xo
|
||||||
|
.Ic scroll-up
|
||||||
|
(vi: C-y)
|
||||||
|
(emacs: C-Up)
|
||||||
|
.Xc
|
||||||
|
Scroll up.
|
||||||
|
.It Xo
|
||||||
.Ic search-again
|
.Ic search-again
|
||||||
(vi: n)
|
(vi: n)
|
||||||
(emacs: n)
|
(emacs: n)
|
||||||
@@ -1981,12 +2210,51 @@ Repeat the last search.
|
|||||||
.Xc
|
.Xc
|
||||||
Search backwards for the specified text.
|
Search backwards for the specified text.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic search-backward-incremental
|
||||||
|
.Ar text
|
||||||
|
(emacs: C-r)
|
||||||
|
.Xc
|
||||||
|
Search backwards incrementally for the specified text.
|
||||||
|
Is expected to be used with the
|
||||||
|
.Fl i
|
||||||
|
flag to the
|
||||||
|
.Ic command-prompt
|
||||||
|
command.
|
||||||
|
.It Xo
|
||||||
|
.Ic search-backward-text
|
||||||
|
.Ar text
|
||||||
|
.Xc
|
||||||
|
Search backwards for the specified plain text.
|
||||||
|
.It Xo
|
||||||
.Ic search-forward
|
.Ic search-forward
|
||||||
.Ar text
|
.Ar text
|
||||||
(vi: /)
|
(vi: /)
|
||||||
.Xc
|
.Xc
|
||||||
Search forward for the specified text.
|
Search forward for the specified text.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic search-forward-incremental
|
||||||
|
.Ar text
|
||||||
|
(emacs: C-s)
|
||||||
|
.Xc
|
||||||
|
Search forward incrementally for the specified text.
|
||||||
|
Is expected to be used with the
|
||||||
|
.Fl i
|
||||||
|
flag to the
|
||||||
|
.Ic command-prompt
|
||||||
|
command.
|
||||||
|
.It Xo
|
||||||
|
.Ic search-forward-text
|
||||||
|
.Ar text
|
||||||
|
.Xc
|
||||||
|
Search forward for the specified plain text.
|
||||||
|
.It Xo
|
||||||
|
.Ic search-reverse
|
||||||
|
(vi: N)
|
||||||
|
(emacs: N)
|
||||||
|
.Xc
|
||||||
|
Repeat the last search in the reverse direction (forward becomes backward and
|
||||||
|
backward becomes forward).
|
||||||
|
.It Xo
|
||||||
.Ic select-line
|
.Ic select-line
|
||||||
(vi: V)
|
(vi: V)
|
||||||
.Xc
|
.Xc
|
||||||
@@ -1996,12 +2264,28 @@ Select the current line.
|
|||||||
.Xc
|
.Xc
|
||||||
Select the current word.
|
Select the current word.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic set-mark
|
||||||
|
(vi: X)
|
||||||
|
(emacs: X)
|
||||||
|
.Xc
|
||||||
|
Mark the current line.
|
||||||
|
.It Xo
|
||||||
.Ic start-of-line
|
.Ic start-of-line
|
||||||
(vi: 0)
|
(vi: 0)
|
||||||
(emacs: C-a)
|
(emacs: C-a)
|
||||||
.Xc
|
.Xc
|
||||||
Move the cursor to the start of the line.
|
Move the cursor to the start of the line.
|
||||||
.It Xo
|
.It Xo
|
||||||
|
.Ic stop-selection
|
||||||
|
.Xc
|
||||||
|
Stop selecting without clearing the current selection.
|
||||||
|
.It Xo
|
||||||
|
.Ic toggle-position
|
||||||
|
(vi: P)
|
||||||
|
(emacs: P)
|
||||||
|
.Xc
|
||||||
|
Toggle the visibility of the position indicator in the top right.
|
||||||
|
.It Xo
|
||||||
.Ic top-line
|
.Ic top-line
|
||||||
(vi: H)
|
(vi: H)
|
||||||
(emacs: M-R)
|
(emacs: M-R)
|
||||||
@@ -2094,14 +2378,15 @@ The synopsis for the
|
|||||||
command is:
|
command is:
|
||||||
.Bl -tag -width Ds
|
.Bl -tag -width Ds
|
||||||
.It Xo Ic copy-mode
|
.It Xo Ic copy-mode
|
||||||
.Op Fl eHMqu
|
.Op Fl deHMqu
|
||||||
.Op Fl s Ar src-pane
|
.Op Fl s Ar src-pane
|
||||||
.Op Fl t Ar target-pane
|
.Op Fl t Ar target-pane
|
||||||
.Xc
|
.Xc
|
||||||
Enter copy mode.
|
Enter copy mode.
|
||||||
The
|
|
||||||
.Fl u
|
.Fl u
|
||||||
option scrolls one page up.
|
also scrolls one page up after entering and
|
||||||
|
.Fl d
|
||||||
|
one page down if already in copy mode.
|
||||||
.Fl M
|
.Fl M
|
||||||
begins a mouse drag (only valid if bound to a mouse key binding, see
|
begins a mouse drag (only valid if bound to a mouse key binding, see
|
||||||
.Sx MOUSE SUPPORT ) .
|
.Sx MOUSE SUPPORT ) .
|
||||||
@@ -2124,6 +2409,7 @@ This is intended to allow fast scrolling through a pane's history, for
|
|||||||
example with:
|
example with:
|
||||||
.Bd -literal -offset indent
|
.Bd -literal -offset indent
|
||||||
bind PageUp copy-mode -eu
|
bind PageUp copy-mode -eu
|
||||||
|
bind PageDown copy-mode -ed
|
||||||
.Ed
|
.Ed
|
||||||
.El
|
.El
|
||||||
.Pp
|
.Pp
|
||||||
@@ -2150,14 +2436,20 @@ are spread from left to right in the leftover space at the bottom.
|
|||||||
Use the
|
Use the
|
||||||
.Em main-pane-height
|
.Em main-pane-height
|
||||||
window option to specify the height of the top pane.
|
window option to specify the height of the top pane.
|
||||||
.It Ic main-vertical
|
.It Ic main-horizontal-mirrored
|
||||||
Similar to
|
The same as
|
||||||
.Ic main-horizontal
|
.Ic main-horizontal
|
||||||
but the large pane is placed on the left and the others spread from top to
|
but mirrored so the main pane is at the bottom of the window.
|
||||||
bottom along the right.
|
.It Ic main-vertical
|
||||||
See the
|
A large (main) pane is shown on the left of the window and the remaining panes
|
||||||
|
are spread from top to bottom in the leftover space on the right.
|
||||||
|
Use the
|
||||||
.Em main-pane-width
|
.Em main-pane-width
|
||||||
window option.
|
window option to specify the width of the left pane.
|
||||||
|
.It Ic main-vertical-mirrored
|
||||||
|
The same as
|
||||||
|
.Ic main-vertical
|
||||||
|
but mirrored so the main pane is on the right of the window.
|
||||||
.It Ic tiled
|
.It Ic tiled
|
||||||
Panes are spread out as evenly as possible over the window in both rows and
|
Panes are spread out as evenly as possible over the window in both rows and
|
||||||
columns.
|
columns.
|
||||||
@@ -2290,7 +2582,8 @@ The following keys may be used in client mode:
|
|||||||
.It Li "Up" Ta "Select previous client"
|
.It Li "Up" Ta "Select previous client"
|
||||||
.It Li "Down" Ta "Select next client"
|
.It Li "Down" Ta "Select next client"
|
||||||
.It Li "C-s" Ta "Search by name"
|
.It Li "C-s" Ta "Search by name"
|
||||||
.It Li "n" Ta "Repeat last search"
|
.It Li "n" Ta "Repeat last search forwards"
|
||||||
|
.It Li "N" Ta "Repeat last search backwards"
|
||||||
.It Li "t" Ta "Toggle if client is tagged"
|
.It Li "t" Ta "Toggle if client is tagged"
|
||||||
.It Li "T" Ta "Tag no clients"
|
.It Li "T" Ta "Tag no clients"
|
||||||
.It Li "C-t" Ta "Tag all clients"
|
.It Li "C-t" Ta "Tag all clients"
|
||||||
@@ -2377,7 +2670,8 @@ The following keys may be used in tree mode:
|
|||||||
.It Li "C-s" Ta "Search by name"
|
.It Li "C-s" Ta "Search by name"
|
||||||
.It Li "m" Ta "Set the marked pane"
|
.It Li "m" Ta "Set the marked pane"
|
||||||
.It Li "M" Ta "Clear the marked pane"
|
.It Li "M" Ta "Clear the marked pane"
|
||||||
.It Li "n" Ta "Repeat last search"
|
.It Li "n" Ta "Repeat last search forwards"
|
||||||
|
.It Li "N" Ta "Repeat last search backwards"
|
||||||
.It Li "t" Ta "Toggle if item is tagged"
|
.It Li "t" Ta "Toggle if item is tagged"
|
||||||
.It Li "T" Ta "Tag no items"
|
.It Li "T" Ta "Tag no items"
|
||||||
.It Li "C-t" Ta "Tag all items"
|
.It Li "C-t" Ta "Tag all items"
|
||||||
@@ -2455,7 +2749,8 @@ The following keys may be used in customize mode:
|
|||||||
.It Li "u" Ta "Unset an option (set to default value if global) or unbind a key"
|
.It Li "u" Ta "Unset an option (set to default value if global) or unbind a key"
|
||||||
.It Li "U" Ta "Unset tagged options and unbind tagged keys"
|
.It Li "U" Ta "Unset tagged options and unbind tagged keys"
|
||||||
.It Li "C-s" Ta "Search by name"
|
.It Li "C-s" Ta "Search by name"
|
||||||
.It Li "n" Ta "Repeat last search"
|
.It Li "n" Ta "Repeat last search forwards"
|
||||||
|
.It Li "N" Ta "Repeat last search backwards"
|
||||||
.It Li "t" Ta "Toggle if item is tagged"
|
.It Li "t" Ta "Toggle if item is tagged"
|
||||||
.It Li "T" Ta "Tag no items"
|
.It Li "T" Ta "Tag no items"
|
||||||
.It Li "C-t" Ta "Tag all items"
|
.It Li "C-t" Ta "Tag all items"
|
||||||
@@ -3718,6 +4013,10 @@ Note that aliases are expanded when a command is parsed rather than when it is
|
|||||||
executed, so binding an alias with
|
executed, so binding an alias with
|
||||||
.Ic bind-key
|
.Ic bind-key
|
||||||
will bind the expanded form.
|
will bind the expanded form.
|
||||||
|
.It Ic copy-command Ar shell-command
|
||||||
|
Give the command to pipe to if the
|
||||||
|
.Ic copy-pipe
|
||||||
|
copy mode command is used without arguments.
|
||||||
.It Ic default-terminal Ar terminal
|
.It Ic default-terminal Ar terminal
|
||||||
Set the default terminal for new windows created in this session - the
|
Set the default terminal for new windows created in this session - the
|
||||||
default value of the
|
default value of the
|
||||||
@@ -3731,16 +4030,11 @@ be set to
|
|||||||
.Ql screen ,
|
.Ql screen ,
|
||||||
.Ql tmux
|
.Ql tmux
|
||||||
or a derivative of them.
|
or a derivative of them.
|
||||||
.It Ic copy-command Ar shell-command
|
|
||||||
Give the command to pipe to if the
|
|
||||||
.Ic copy-pipe
|
|
||||||
copy mode command is used without arguments.
|
|
||||||
.It Ic escape-time Ar time
|
.It Ic escape-time Ar time
|
||||||
Set the time in milliseconds for which
|
Set the time in milliseconds for which
|
||||||
.Nm
|
.Nm
|
||||||
waits after an escape is input to determine if it is part of a function or meta
|
waits after an escape is input to determine if it is part of a function or meta
|
||||||
key sequences.
|
key sequences.
|
||||||
The default is 500 milliseconds.
|
|
||||||
.It Ic editor Ar shell-command
|
.It Ic editor Ar shell-command
|
||||||
Set the command used when
|
Set the command used when
|
||||||
.Nm
|
.Nm
|
||||||
@@ -3757,22 +4051,54 @@ If enabled, the server will exit when there are no attached clients.
|
|||||||
.It Xo Ic extended-keys
|
.It Xo Ic extended-keys
|
||||||
.Op Ic on | off | always
|
.Op Ic on | off | always
|
||||||
.Xc
|
.Xc
|
||||||
When
|
Controls how modified keys (keys pressed together with Control, Meta, or Shift)
|
||||||
.Ic on
|
are reported.
|
||||||
or
|
This is the equivalent of the
|
||||||
.Ic always ,
|
.Ic modifyOtherKeys
|
||||||
the escape sequence to enable extended keys is sent to the terminal, if
|
.Xr xterm 1
|
||||||
.Nm
|
resource.
|
||||||
knows that it is supported.
|
.Pp
|
||||||
.Nm
|
When set to
|
||||||
always recognises extended keys itself.
|
|
||||||
If this option is
|
|
||||||
.Ic on ,
|
.Ic on ,
|
||||||
.Nm
|
the program inside the pane can request one of two modes: mode 1 which changes
|
||||||
will only forward extended keys to applications when they request them; if
|
the sequence for only keys which lack an existing well-known representation; or
|
||||||
|
mode 2 which changes the sequence for all keys.
|
||||||
|
When set to
|
||||||
.Ic always ,
|
.Ic always ,
|
||||||
|
modes 1 and 2 can still be requested by applications, but mode 1 will be forced
|
||||||
|
instead of the standard mode.
|
||||||
|
When set to
|
||||||
|
.Ic off ,
|
||||||
|
this feature is disabled and only standard keys are reported.
|
||||||
|
.Pp
|
||||||
.Nm
|
.Nm
|
||||||
will always forward the keys.
|
will always request extended keys itself if the terminal supports them.
|
||||||
|
See also the
|
||||||
|
.Ic extkeys
|
||||||
|
feature for the
|
||||||
|
.Ic terminal-features
|
||||||
|
option, the
|
||||||
|
.Ic extended-keys-format
|
||||||
|
option and the
|
||||||
|
.Ic pane_key_mode
|
||||||
|
variable.
|
||||||
|
.It Xo Ic extended-keys-format
|
||||||
|
.Op Ic csi-u | xterm
|
||||||
|
.Xc
|
||||||
|
Selects one of the two possible formats for reporting modified keys to
|
||||||
|
applications.
|
||||||
|
This is the equivalent of the
|
||||||
|
.Ic formatOtherKeys
|
||||||
|
.Xr xterm 1
|
||||||
|
resource.
|
||||||
|
For example, C-S-a will be reported as
|
||||||
|
.Ql ^[[27;6;65~
|
||||||
|
when set to
|
||||||
|
.Ic xterm ,
|
||||||
|
and as
|
||||||
|
.Ql ^[[65;6u
|
||||||
|
when set to
|
||||||
|
.Ic csi-u .
|
||||||
.It Xo Ic focus-events
|
.It Xo Ic focus-events
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
@@ -4036,10 +4362,12 @@ If
|
|||||||
(the default), leave the session orphaned.
|
(the default), leave the session orphaned.
|
||||||
If
|
If
|
||||||
.Ic keep-last ,
|
.Ic keep-last ,
|
||||||
destroy the session only if it is in a group and has other sessions in that group.
|
destroy the session only if it is in a group and has other sessions in that
|
||||||
|
group.
|
||||||
If
|
If
|
||||||
.Ic keep-group ,
|
.Ic keep-group ,
|
||||||
destroy the session unless it is in a group and is the only session in that group.
|
destroy the session unless it is in a group and is the only session in that
|
||||||
|
group.
|
||||||
.It Xo Ic detach-on-destroy
|
.It Xo Ic detach-on-destroy
|
||||||
.Op Ic off | on | no-detached | previous | next
|
.Op Ic off | on | no-detached | previous | next
|
||||||
.Xc
|
.Xc
|
||||||
@@ -4173,6 +4501,13 @@ Like
|
|||||||
.Ic prefix2
|
.Ic prefix2
|
||||||
can be set to
|
can be set to
|
||||||
.Ql None .
|
.Ql None .
|
||||||
|
.It Ic prefix-timeout Ar time
|
||||||
|
Set the time in milliseconds for which
|
||||||
|
.Nm
|
||||||
|
waits after
|
||||||
|
.Ic prefix
|
||||||
|
is input before dismissing it.
|
||||||
|
Can be set to zero to disable any timeout.
|
||||||
.It Xo Ic renumber-windows
|
.It Xo Ic renumber-windows
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
@@ -4438,9 +4773,11 @@ Set the character used to fill areas of the terminal unused by a window.
|
|||||||
.It Ic main-pane-height Ar height
|
.It Ic main-pane-height Ar height
|
||||||
.It Ic main-pane-width Ar width
|
.It Ic main-pane-width Ar width
|
||||||
Set the width or height of the main (left or top) pane in the
|
Set the width or height of the main (left or top) pane in the
|
||||||
.Ic main-horizontal
|
.Ic main-horizontal ,
|
||||||
|
.Ic main-horizontal-mirrored ,
|
||||||
|
.Ic main-vertical ,
|
||||||
or
|
or
|
||||||
.Ic main-vertical
|
.Ic main-vertical-mirrored
|
||||||
layouts.
|
layouts.
|
||||||
If suffixed by
|
If suffixed by
|
||||||
.Ql % ,
|
.Ql % ,
|
||||||
@@ -4514,7 +4851,9 @@ An interval of zero disables the monitoring.
|
|||||||
.It Ic other-pane-height Ar height
|
.It Ic other-pane-height Ar height
|
||||||
Set the height of the other panes (not the main pane) in the
|
Set the height of the other panes (not the main pane) in the
|
||||||
.Ic main-horizontal
|
.Ic main-horizontal
|
||||||
layout.
|
and
|
||||||
|
.Ic main-horizontal-mirrored
|
||||||
|
layouts.
|
||||||
If this option is set to 0 (the default), it will have no effect.
|
If this option is set to 0 (the default), it will have no effect.
|
||||||
If both the
|
If both the
|
||||||
.Ic main-pane-height
|
.Ic main-pane-height
|
||||||
@@ -4531,7 +4870,9 @@ Like
|
|||||||
.Ic other-pane-height ,
|
.Ic other-pane-height ,
|
||||||
but set the width of other panes in the
|
but set the width of other panes in the
|
||||||
.Ic main-vertical
|
.Ic main-vertical
|
||||||
layout.
|
and
|
||||||
|
.Ic main-vertical-mirrored
|
||||||
|
layouts.
|
||||||
.Pp
|
.Pp
|
||||||
.It Ic pane-active-border-style Ar style
|
.It Ic pane-active-border-style Ar style
|
||||||
Set the pane border style for the currently active pane.
|
Set the pane border style for the currently active pane.
|
||||||
@@ -4746,6 +5087,12 @@ they will be allowed even if the pane is invisible.
|
|||||||
Allow programs in the pane to change the window name using a terminal escape
|
Allow programs in the pane to change the window name using a terminal escape
|
||||||
sequence (\eek...\ee\e\e).
|
sequence (\eek...\ee\e\e).
|
||||||
.Pp
|
.Pp
|
||||||
|
.It Xo Ic allow-set-title
|
||||||
|
.Op Ic on | off
|
||||||
|
.Xc
|
||||||
|
Allow programs in the pane to change the title using the terminal escape
|
||||||
|
sequences (\ee]2;...\ee\e\e or \ee]0;...\ee\e\e).
|
||||||
|
.Pp
|
||||||
.It Xo Ic alternate-screen
|
.It Xo Ic alternate-screen
|
||||||
.Op Ic on | off
|
.Op Ic on | off
|
||||||
.Xc
|
.Xc
|
||||||
@@ -4871,6 +5218,14 @@ layout after every
|
|||||||
set-hook -g after-split-window "selectl even-vertical"
|
set-hook -g after-split-window "selectl even-vertical"
|
||||||
.Ed
|
.Ed
|
||||||
.Pp
|
.Pp
|
||||||
|
If a command fails, the
|
||||||
|
.Ql command-error
|
||||||
|
hook will be fired.
|
||||||
|
For example, this could be used to write to a log file:
|
||||||
|
.Bd -literal -offset indent
|
||||||
|
set-hook -g command-error "run-shell \\"echo 'a tmux command failed' >>/tmp/log\\""
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
All the notifications listed in the
|
All the notifications listed in the
|
||||||
.Sx CONTROL MODE
|
.Sx CONTROL MODE
|
||||||
section are hooks (without any arguments), except
|
section are hooks (without any arguments), except
|
||||||
@@ -4903,6 +5258,8 @@ Run when focus exits a client
|
|||||||
Run when a client is resized.
|
Run when a client is resized.
|
||||||
.It client-session-changed
|
.It client-session-changed
|
||||||
Run when a client's attached session is changed.
|
Run when a client's attached session is changed.
|
||||||
|
.It command-error
|
||||||
|
Run when a command fails.
|
||||||
.It pane-died
|
.It pane-died
|
||||||
Run when the program running in a pane exits, but
|
Run when the program running in a pane exits, but
|
||||||
.Ic remain-on-exit
|
.Ic remain-on-exit
|
||||||
@@ -5421,6 +5778,7 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "command_list_name" Ta "" Ta "Command name if listing commands"
|
.It Li "command_list_name" Ta "" Ta "Command name if listing commands"
|
||||||
.It Li "command_list_usage" Ta "" Ta "Command usage if listing commands"
|
.It Li "command_list_usage" Ta "" Ta "Command usage if listing commands"
|
||||||
.It Li "config_files" Ta "" Ta "List of configuration files loaded"
|
.It Li "config_files" Ta "" Ta "List of configuration files loaded"
|
||||||
|
.It Li "copy_cursor_hyperlink" Ta "" Ta "Hyperlink under cursor in copy mode"
|
||||||
.It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode"
|
.It Li "copy_cursor_line" Ta "" Ta "Line the cursor is on in copy mode"
|
||||||
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
.It Li "copy_cursor_word" Ta "" Ta "Word under cursor in copy mode"
|
||||||
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
.It Li "copy_cursor_x" Ta "" Ta "Cursor X position in copy mode"
|
||||||
@@ -5482,6 +5840,7 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode"
|
.It Li "pane_in_mode" Ta "" Ta "1 if pane is in a mode"
|
||||||
.It Li "pane_index" Ta "#P" Ta "Index of pane"
|
.It Li "pane_index" Ta "#P" Ta "Index of pane"
|
||||||
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
|
.It Li "pane_input_off" Ta "" Ta "1 if input to pane is disabled"
|
||||||
|
.It Li "pane_key_mode" Ta "" Ta "Extended key reporting mode in this pane"
|
||||||
.It Li "pane_last" Ta "" Ta "1 if last pane"
|
.It Li "pane_last" Ta "" Ta "1 if last pane"
|
||||||
.It Li "pane_left" Ta "" Ta "Left of pane"
|
.It Li "pane_left" Ta "" Ta "Left of pane"
|
||||||
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
.It Li "pane_marked" Ta "" Ta "1 if this is the marked pane"
|
||||||
@@ -5506,6 +5865,8 @@ The following variables are available, where appropriate:
|
|||||||
.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
|
.It Li "scroll_position" Ta "" Ta "Scroll position in copy mode"
|
||||||
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
.It Li "scroll_region_lower" Ta "" Ta "Bottom of scroll region in pane"
|
||||||
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
.It Li "scroll_region_upper" Ta "" Ta "Top of scroll region in pane"
|
||||||
|
.It Li "search_count" Ta "" Ta "Count of search results"
|
||||||
|
.It Li "search_count_partial" Ta "" Ta "1 if search count is partial count"
|
||||||
.It Li "search_match" Ta "" Ta "Search match if any"
|
.It Li "search_match" Ta "" Ta "Search match if any"
|
||||||
.It Li "search_present" Ta "" Ta "1 if search started in copy mode"
|
.It Li "search_present" Ta "" Ta "1 if search started in copy mode"
|
||||||
.It Li "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode"
|
.It Li "selection_active" Ta "" Ta "1 if selection started and changes with the cursor in copy mode"
|
||||||
@@ -6111,7 +6472,7 @@ the default is
|
|||||||
.Ql y .
|
.Ql y .
|
||||||
.Tg menu
|
.Tg menu
|
||||||
.It Xo Ic display-menu
|
.It Xo Ic display-menu
|
||||||
.Op Fl O
|
.Op Fl OM
|
||||||
.Op Fl b Ar border-lines
|
.Op Fl b Ar border-lines
|
||||||
.Op Fl c Ar target-client
|
.Op Fl c Ar target-client
|
||||||
.Op Fl C Ar starting-choice
|
.Op Fl C Ar starting-choice
|
||||||
@@ -6218,7 +6579,13 @@ changes this behaviour so that the menu does not close when the mouse button is
|
|||||||
released without an item selected the menu is not closed and a mouse button
|
released without an item selected the menu is not closed and a mouse button
|
||||||
must be clicked to choose an item.
|
must be clicked to choose an item.
|
||||||
.Pp
|
.Pp
|
||||||
The following keys are also available:
|
.Fl M
|
||||||
|
tells
|
||||||
|
.Nm
|
||||||
|
the menu should handle mouse events; by default only menus opened from mouse
|
||||||
|
key bindings do so.
|
||||||
|
.Pp
|
||||||
|
The following keys are available in menus:
|
||||||
.Bl -column "Key" "Function" -offset indent
|
.Bl -column "Key" "Function" -offset indent
|
||||||
.It Sy "Key" Ta Sy "Function"
|
.It Sy "Key" Ta Sy "Function"
|
||||||
.It Li "Enter" Ta "Choose selected item"
|
.It Li "Enter" Ta "Choose selected item"
|
||||||
@@ -6441,7 +6808,8 @@ The following keys may be used in buffer mode:
|
|||||||
.It Li "Up" Ta "Select previous buffer"
|
.It Li "Up" Ta "Select previous buffer"
|
||||||
.It Li "Down" Ta "Select next buffer"
|
.It Li "Down" Ta "Select next buffer"
|
||||||
.It Li "C-s" Ta "Search by name or content"
|
.It Li "C-s" Ta "Search by name or content"
|
||||||
.It Li "n" Ta "Repeat last search"
|
.It Li "n" Ta "Repeat last search forwards"
|
||||||
|
.It Li "N" Ta "Repeat last search backwards"
|
||||||
.It Li "t" Ta "Toggle if buffer is tagged"
|
.It Li "t" Ta "Toggle if buffer is tagged"
|
||||||
.It Li "T" Ta "Tag no buffers"
|
.It Li "T" Ta "Tag no buffers"
|
||||||
.It Li "C-t" Ta "Tag all buffers"
|
.It Li "C-t" Ta "Tag all buffers"
|
||||||
@@ -6464,7 +6832,7 @@ is replaced by the buffer name in
|
|||||||
and the result executed as a command.
|
and the result executed as a command.
|
||||||
If
|
If
|
||||||
.Ar template
|
.Ar template
|
||||||
is not given, "paste-buffer -b \[aq]%%\[aq]" is used.
|
is not given, "paste-buffer -p -b \[aq]%%\[aq]" is used.
|
||||||
.Pp
|
.Pp
|
||||||
.Fl O
|
.Fl O
|
||||||
specifies the initial sort field: one of
|
specifies the initial sort field: one of
|
||||||
@@ -6533,6 +6901,11 @@ is given, the buffer is also sent to the clipboard for
|
|||||||
using the
|
using the
|
||||||
.Xr xterm 1
|
.Xr xterm 1
|
||||||
escape sequence, if possible.
|
escape sequence, if possible.
|
||||||
|
If
|
||||||
|
.Ar path
|
||||||
|
is
|
||||||
|
.Ql - ,
|
||||||
|
the contents are read from stdin.
|
||||||
.Tg pasteb
|
.Tg pasteb
|
||||||
.It Xo Ic paste-buffer
|
.It Xo Ic paste-buffer
|
||||||
.Op Fl dpr
|
.Op Fl dpr
|
||||||
@@ -6570,6 +6943,11 @@ Save the contents of the specified paste buffer to
|
|||||||
The
|
The
|
||||||
.Fl a
|
.Fl a
|
||||||
option appends to rather than overwriting the file.
|
option appends to rather than overwriting the file.
|
||||||
|
If
|
||||||
|
.Ar path
|
||||||
|
is
|
||||||
|
.Ql - ,
|
||||||
|
the contents are read from stdin.
|
||||||
.It Xo Ic set-buffer
|
.It Xo Ic set-buffer
|
||||||
.Op Fl aw
|
.Op Fl aw
|
||||||
.Op Fl b Ar buffer-name
|
.Op Fl b Ar buffer-name
|
||||||
|
|||||||
18
tmux.c
18
tmux.c
@@ -235,6 +235,24 @@ fail:
|
|||||||
return (NULL);
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
shell_argv0(const char *shell, int is_login)
|
||||||
|
{
|
||||||
|
const char *slash, *name;
|
||||||
|
char *argv0;
|
||||||
|
|
||||||
|
slash = strrchr(shell, '/');
|
||||||
|
if (slash != NULL && slash[1] != '\0')
|
||||||
|
name = slash + 1;
|
||||||
|
else
|
||||||
|
name = shell;
|
||||||
|
if (is_login)
|
||||||
|
xasprintf(&argv0, "-%s", name);
|
||||||
|
else
|
||||||
|
xasprintf(&argv0, "%s", name);
|
||||||
|
return (argv0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
setblocking(int fd, int state)
|
setblocking(int fd, int state)
|
||||||
{
|
{
|
||||||
|
|||||||
81
tmux.h
81
tmux.h
@@ -134,6 +134,7 @@ struct winlink;
|
|||||||
*/
|
*/
|
||||||
#define KEYC_BASE 0x0000000010e000ULL
|
#define KEYC_BASE 0x0000000010e000ULL
|
||||||
#define KEYC_USER 0x0000000010f000ULL
|
#define KEYC_USER 0x0000000010f000ULL
|
||||||
|
#define KEYC_USER_END (KEYC_USER + KEYC_NUSER)
|
||||||
|
|
||||||
/* Key modifier bits. */
|
/* Key modifier bits. */
|
||||||
#define KEYC_META 0x00100000000000ULL
|
#define KEYC_META 0x00100000000000ULL
|
||||||
@@ -147,8 +148,7 @@ struct winlink;
|
|||||||
#define KEYC_IMPLIED_META 0x08000000000000ULL
|
#define KEYC_IMPLIED_META 0x08000000000000ULL
|
||||||
#define KEYC_BUILD_MODIFIERS 0x10000000000000ULL
|
#define KEYC_BUILD_MODIFIERS 0x10000000000000ULL
|
||||||
#define KEYC_VI 0x20000000000000ULL
|
#define KEYC_VI 0x20000000000000ULL
|
||||||
#define KEYC_EXTENDED 0x40000000000000ULL
|
#define KEYC_SENT 0x40000000000000ULL
|
||||||
#define KEYC_SENT 0x80000000000000ULL
|
|
||||||
|
|
||||||
/* Masks for key bits. */
|
/* Masks for key bits. */
|
||||||
#define KEYC_MASK_MODIFIERS 0x00f00000000000ULL
|
#define KEYC_MASK_MODIFIERS 0x00f00000000000ULL
|
||||||
@@ -169,7 +169,7 @@ struct winlink;
|
|||||||
(((key) & KEYC_MASK_KEY) < KEYC_BASE || \
|
(((key) & KEYC_MASK_KEY) < KEYC_BASE || \
|
||||||
((key) & KEYC_MASK_KEY) >= KEYC_BASE_END) && \
|
((key) & KEYC_MASK_KEY) >= KEYC_BASE_END) && \
|
||||||
(((key) & KEYC_MASK_KEY) < KEYC_USER || \
|
(((key) & KEYC_MASK_KEY) < KEYC_USER || \
|
||||||
((key) & KEYC_MASK_KEY) >= KEYC_USER + KEYC_NUSER))
|
((key) & KEYC_MASK_KEY) >= KEYC_USER_END))
|
||||||
|
|
||||||
/* Multiple click timeout. */
|
/* Multiple click timeout. */
|
||||||
#define KEYC_CLICK_TIMEOUT 300
|
#define KEYC_CLICK_TIMEOUT 300
|
||||||
@@ -196,6 +196,42 @@ struct winlink;
|
|||||||
*/
|
*/
|
||||||
typedef unsigned long long key_code;
|
typedef unsigned long long key_code;
|
||||||
|
|
||||||
|
/* C0 control characters */
|
||||||
|
enum {
|
||||||
|
C0_NUL,
|
||||||
|
C0_SOH,
|
||||||
|
C0_STX,
|
||||||
|
C0_ETX,
|
||||||
|
C0_EOT,
|
||||||
|
C0_ENQ,
|
||||||
|
C0_ASC,
|
||||||
|
C0_BEL,
|
||||||
|
C0_BS,
|
||||||
|
C0_HT,
|
||||||
|
C0_LF,
|
||||||
|
C0_VT,
|
||||||
|
C0_FF,
|
||||||
|
C0_CR,
|
||||||
|
C0_SO,
|
||||||
|
C0_SI,
|
||||||
|
C0_DLE,
|
||||||
|
C0_DC1,
|
||||||
|
C0_DC2,
|
||||||
|
C0_DC3,
|
||||||
|
C0_DC4,
|
||||||
|
C0_NAK,
|
||||||
|
C0_SYN,
|
||||||
|
C0_ETB,
|
||||||
|
C0_CAN,
|
||||||
|
C0_EM,
|
||||||
|
C0_SUB,
|
||||||
|
C0_ESC,
|
||||||
|
C0_FS,
|
||||||
|
C0_GS,
|
||||||
|
C0_RS,
|
||||||
|
C0_US
|
||||||
|
};
|
||||||
|
|
||||||
/* Special key codes. */
|
/* Special key codes. */
|
||||||
enum {
|
enum {
|
||||||
/* Focus events. */
|
/* Focus events. */
|
||||||
@@ -591,14 +627,16 @@ enum tty_code_code {
|
|||||||
#define MODE_MOUSE_ALL 0x1000
|
#define MODE_MOUSE_ALL 0x1000
|
||||||
#define MODE_ORIGIN 0x2000
|
#define MODE_ORIGIN 0x2000
|
||||||
#define MODE_CRLF 0x4000
|
#define MODE_CRLF 0x4000
|
||||||
#define MODE_KEXTENDED 0x8000
|
#define MODE_KEYS_EXTENDED 0x8000
|
||||||
#define MODE_CURSOR_VERY_VISIBLE 0x10000
|
#define MODE_CURSOR_VERY_VISIBLE 0x10000
|
||||||
#define MODE_CURSOR_BLINKING_SET 0x20000
|
#define MODE_CURSOR_BLINKING_SET 0x20000
|
||||||
|
#define MODE_KEYS_EXTENDED_2 0x40000
|
||||||
|
|
||||||
#define ALL_MODES 0xffffff
|
#define ALL_MODES 0xffffff
|
||||||
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
#define ALL_MOUSE_MODES (MODE_MOUSE_STANDARD|MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
||||||
#define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
#define MOTION_MOUSE_MODES (MODE_MOUSE_BUTTON|MODE_MOUSE_ALL)
|
||||||
#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)
|
#define CURSOR_MODES (MODE_CURSOR|MODE_CURSOR_BLINKING|MODE_CURSOR_VERY_VISIBLE)
|
||||||
|
#define EXTENDED_KEY_MODES (MODE_KEYS_EXTENDED|MODE_KEYS_EXTENDED_2)
|
||||||
|
|
||||||
/* Mouse protocol constants. */
|
/* Mouse protocol constants. */
|
||||||
#define MOUSE_PARAM_MAX 0xff
|
#define MOUSE_PARAM_MAX 0xff
|
||||||
@@ -877,7 +915,7 @@ struct screen_sel;
|
|||||||
struct screen_titles;
|
struct screen_titles;
|
||||||
struct screen {
|
struct screen {
|
||||||
char *title;
|
char *title;
|
||||||
char *path;
|
char *path;
|
||||||
struct screen_titles *titles;
|
struct screen_titles *titles;
|
||||||
|
|
||||||
struct grid *grid; /* grid data */
|
struct grid *grid; /* grid data */
|
||||||
@@ -959,6 +997,11 @@ enum pane_lines {
|
|||||||
#define PANE_BORDER_ARROWS 2
|
#define PANE_BORDER_ARROWS 2
|
||||||
#define PANE_BORDER_BOTH 3
|
#define PANE_BORDER_BOTH 3
|
||||||
|
|
||||||
|
/* Mode returned by window_pane_mode function. */
|
||||||
|
#define WINDOW_PANE_NO_MODE 0
|
||||||
|
#define WINDOW_PANE_COPY_MODE 1
|
||||||
|
#define WINDOW_PANE_VIEW_MODE 2
|
||||||
|
|
||||||
/* Screen redraw context. */
|
/* Screen redraw context. */
|
||||||
struct screen_redraw_ctx {
|
struct screen_redraw_ctx {
|
||||||
struct client *c;
|
struct client *c;
|
||||||
@@ -1131,6 +1174,9 @@ struct window_pane {
|
|||||||
int border_gc_set;
|
int border_gc_set;
|
||||||
struct grid_cell border_gc;
|
struct grid_cell border_gc;
|
||||||
|
|
||||||
|
int control_bg;
|
||||||
|
int control_fg;
|
||||||
|
|
||||||
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
|
TAILQ_ENTRY(window_pane) entry; /* link in list of all panes */
|
||||||
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
|
TAILQ_ENTRY(window_pane) sentry; /* link in list of last visited */
|
||||||
RB_ENTRY(window_pane) tree_entry;
|
RB_ENTRY(window_pane) tree_entry;
|
||||||
@@ -1970,6 +2016,7 @@ RB_HEAD(key_bindings, key_binding);
|
|||||||
|
|
||||||
struct key_table {
|
struct key_table {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
struct timeval activity_time;
|
||||||
struct key_bindings key_bindings;
|
struct key_bindings key_bindings;
|
||||||
struct key_bindings default_key_bindings;
|
struct key_bindings default_key_bindings;
|
||||||
|
|
||||||
@@ -2096,6 +2143,7 @@ extern int ptm_fd;
|
|||||||
extern const char *shell_command;
|
extern const char *shell_command;
|
||||||
int checkshell(const char *);
|
int checkshell(const char *);
|
||||||
void setblocking(int, int);
|
void setblocking(int, int);
|
||||||
|
char *shell_argv0(const char *, int);
|
||||||
uint64_t get_timer(void);
|
uint64_t get_timer(void);
|
||||||
const char *sig2name(int);
|
const char *sig2name(int);
|
||||||
const char *find_cwd(void);
|
const char *find_cwd(void);
|
||||||
@@ -2390,7 +2438,6 @@ void tty_cmd_clearstartofscreen(struct tty *, const struct tty_ctx *);
|
|||||||
void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *);
|
void tty_cmd_deletecharacter(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *);
|
void tty_cmd_clearcharacter(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_deleteline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_deleteline(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_erasecharacter(struct tty *, const struct tty_ctx *);
|
|
||||||
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
|
void tty_cmd_insertcharacter(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
|
void tty_cmd_insertline(struct tty *, const struct tty_ctx *);
|
||||||
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
|
void tty_cmd_linefeed(struct tty *, const struct tty_ctx *);
|
||||||
@@ -2451,6 +2498,8 @@ const struct utf8_data *tty_acs_rounded_borders(int);
|
|||||||
void tty_keys_build(struct tty *);
|
void tty_keys_build(struct tty *);
|
||||||
void tty_keys_free(struct tty *);
|
void tty_keys_free(struct tty *);
|
||||||
int tty_keys_next(struct tty *);
|
int tty_keys_next(struct tty *);
|
||||||
|
int tty_keys_colours(struct tty *, const char *, size_t, size_t *,
|
||||||
|
int *, int *);
|
||||||
|
|
||||||
/* arguments.c */
|
/* arguments.c */
|
||||||
void args_set(struct args *, u_char, struct args_value *, int);
|
void args_set(struct args *, u_char, struct args_value *, int);
|
||||||
@@ -2567,7 +2616,6 @@ enum cmd_retval cmd_attach_session(struct cmdq_item *, const char *, int, int,
|
|||||||
int, const char *, int, const char *);
|
int, const char *, int, const char *);
|
||||||
|
|
||||||
/* cmd-parse.c */
|
/* cmd-parse.c */
|
||||||
void cmd_parse_empty(struct cmd_parse_input *);
|
|
||||||
struct cmd_parse_result *cmd_parse_from_file(FILE *, struct cmd_parse_input *);
|
struct cmd_parse_result *cmd_parse_from_file(FILE *, struct cmd_parse_input *);
|
||||||
struct cmd_parse_result *cmd_parse_from_string(const char *,
|
struct cmd_parse_result *cmd_parse_from_string(const char *,
|
||||||
struct cmd_parse_input *);
|
struct cmd_parse_input *);
|
||||||
@@ -2700,11 +2748,12 @@ void server_clear_marked(void);
|
|||||||
int server_is_marked(struct session *, struct winlink *,
|
int server_is_marked(struct session *, struct winlink *,
|
||||||
struct window_pane *);
|
struct window_pane *);
|
||||||
int server_check_marked(void);
|
int server_check_marked(void);
|
||||||
int server_start(struct tmuxproc *, int, struct event_base *, int, char *);
|
int server_start(struct tmuxproc *, uint64_t, struct event_base *, int,
|
||||||
|
char *);
|
||||||
void server_update_socket(void);
|
void server_update_socket(void);
|
||||||
void server_add_accept(int);
|
void server_add_accept(int);
|
||||||
void printflike(1, 2) server_add_message(const char *, ...);
|
void printflike(1, 2) server_add_message(const char *, ...);
|
||||||
int server_create_socket(int, char **);
|
int server_create_socket(uint64_t, char **);
|
||||||
|
|
||||||
/* server-client.c */
|
/* server-client.c */
|
||||||
RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp);
|
RB_PROTOTYPE(client_windows, client_window, entry, server_client_window_cmp);
|
||||||
@@ -2728,8 +2777,6 @@ void server_client_suspend(struct client *);
|
|||||||
void server_client_detach(struct client *, enum msgtype);
|
void server_client_detach(struct client *, enum msgtype);
|
||||||
void server_client_exec(struct client *, const char *);
|
void server_client_exec(struct client *, const char *);
|
||||||
void server_client_loop(void);
|
void server_client_loop(void);
|
||||||
void server_client_push_stdout(struct client *);
|
|
||||||
void server_client_push_stderr(struct client *);
|
|
||||||
const char *server_client_get_cwd(struct client *, struct session *);
|
const char *server_client_get_cwd(struct client *, struct session *);
|
||||||
void server_client_set_flags(struct client *, const char *);
|
void server_client_set_flags(struct client *, const char *);
|
||||||
const char *server_client_get_flags(struct client *);
|
const char *server_client_get_flags(struct client *);
|
||||||
@@ -3070,7 +3117,7 @@ struct window_pane *window_add_pane(struct window *, struct window_pane *,
|
|||||||
void window_resize(struct window *, u_int, u_int, int, int);
|
void window_resize(struct window *, u_int, u_int, int, int);
|
||||||
void window_pane_send_resize(struct window_pane *, u_int, u_int);
|
void window_pane_send_resize(struct window_pane *, u_int, u_int);
|
||||||
int window_zoom(struct window_pane *);
|
int window_zoom(struct window_pane *);
|
||||||
int window_unzoom(struct window *);
|
int window_unzoom(struct window *, int);
|
||||||
int window_push_zoom(struct window *, int, int);
|
int window_push_zoom(struct window *, int, int);
|
||||||
int window_pop_zoom(struct window *);
|
int window_pop_zoom(struct window *);
|
||||||
void window_lost_pane(struct window *, struct window_pane *);
|
void window_lost_pane(struct window *, struct window_pane *);
|
||||||
@@ -3121,6 +3168,7 @@ void window_pane_update_used_data(struct window_pane *,
|
|||||||
struct window_pane_offset *, size_t);
|
struct window_pane_offset *, size_t);
|
||||||
void window_set_fill_character(struct window *);
|
void window_set_fill_character(struct window *);
|
||||||
void window_pane_default_cursor(struct window_pane *);
|
void window_pane_default_cursor(struct window_pane *);
|
||||||
|
int window_pane_mode(struct window_pane *);
|
||||||
|
|
||||||
/* layout.c */
|
/* layout.c */
|
||||||
u_int layout_count_cells(struct layout_cell *);
|
u_int layout_count_cells(struct layout_cell *);
|
||||||
@@ -3185,7 +3233,7 @@ int mode_tree_set_current(struct mode_tree_data *, uint64_t);
|
|||||||
void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
|
void mode_tree_each_tagged(struct mode_tree_data *, mode_tree_each_cb,
|
||||||
struct client *, key_code, int);
|
struct client *, key_code, int);
|
||||||
void mode_tree_up(struct mode_tree_data *, int);
|
void mode_tree_up(struct mode_tree_data *, int);
|
||||||
void mode_tree_down(struct mode_tree_data *, int);
|
int mode_tree_down(struct mode_tree_data *, int);
|
||||||
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
|
struct mode_tree_data *mode_tree_start(struct window_pane *, struct args *,
|
||||||
mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
|
mode_tree_build_cb, mode_tree_draw_cb, mode_tree_search_cb,
|
||||||
mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb, void *,
|
mode_tree_menu_cb, mode_tree_height_cb, mode_tree_key_cb, void *,
|
||||||
@@ -3227,6 +3275,7 @@ void printflike(3, 4) window_copy_add(struct window_pane *, int, const char *,
|
|||||||
void printflike(3, 0) window_copy_vadd(struct window_pane *, int, const char *,
|
void printflike(3, 0) window_copy_vadd(struct window_pane *, int, const char *,
|
||||||
va_list);
|
va_list);
|
||||||
void window_copy_pageup(struct window_pane *, int);
|
void window_copy_pageup(struct window_pane *, int);
|
||||||
|
void window_copy_pagedown(struct window_pane *, int, int);
|
||||||
void window_copy_start_drag(struct client *, struct mouse_event *);
|
void window_copy_start_drag(struct client *, struct mouse_event *);
|
||||||
char *window_copy_get_word(struct window_pane *, u_int, u_int);
|
char *window_copy_get_word(struct window_pane *, u_int, u_int);
|
||||||
char *window_copy_get_line(struct window_pane *, u_int);
|
char *window_copy_get_line(struct window_pane *, u_int);
|
||||||
@@ -3259,8 +3308,6 @@ void control_add_sub(struct client *, const char *, enum control_sub_type,
|
|||||||
void control_remove_sub(struct client *, const char *);
|
void control_remove_sub(struct client *, const char *);
|
||||||
|
|
||||||
/* control-notify.c */
|
/* control-notify.c */
|
||||||
void control_notify_input(struct client *, struct window_pane *,
|
|
||||||
const u_char *, size_t);
|
|
||||||
void control_notify_pane_mode_changed(int);
|
void control_notify_pane_mode_changed(int);
|
||||||
void control_notify_window_layout_changed(struct window *);
|
void control_notify_window_layout_changed(struct window *);
|
||||||
void control_notify_window_pane_changed(struct window *);
|
void control_notify_window_pane_changed(struct window *);
|
||||||
@@ -3294,8 +3341,6 @@ char *session_check_name(const char *);
|
|||||||
void session_update_activity(struct session *, struct timeval *);
|
void session_update_activity(struct session *, struct timeval *);
|
||||||
struct session *session_next_session(struct session *);
|
struct session *session_next_session(struct session *);
|
||||||
struct session *session_previous_session(struct session *);
|
struct session *session_previous_session(struct session *);
|
||||||
struct winlink *session_new(struct session *, const char *, int, char **,
|
|
||||||
const char *, const char *, int, char **);
|
|
||||||
struct winlink *session_attach(struct session *, struct window *, int,
|
struct winlink *session_attach(struct session *, struct window *, int,
|
||||||
char **);
|
char **);
|
||||||
int session_detach(struct session *, struct winlink *);
|
int session_detach(struct session *, struct winlink *);
|
||||||
@@ -3318,6 +3363,7 @@ void session_renumber_windows(struct session *);
|
|||||||
|
|
||||||
/* utf8.c */
|
/* utf8.c */
|
||||||
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
|
enum utf8_state utf8_towc (const struct utf8_data *, wchar_t *);
|
||||||
|
enum utf8_state utf8_fromwc(wchar_t wc, struct utf8_data *);
|
||||||
int utf8_in_table(wchar_t, const wchar_t *, u_int);
|
int utf8_in_table(wchar_t, const wchar_t *, u_int);
|
||||||
utf8_char utf8_build_one(u_char);
|
utf8_char utf8_build_one(u_char);
|
||||||
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
|
enum utf8_state utf8_from_data(const struct utf8_data *, utf8_char *);
|
||||||
@@ -3463,6 +3509,7 @@ u_int hyperlinks_put(struct hyperlinks *, const char *,
|
|||||||
int hyperlinks_get(struct hyperlinks *, u_int,
|
int hyperlinks_get(struct hyperlinks *, u_int,
|
||||||
const char **, const char **, const char **);
|
const char **, const char **, const char **);
|
||||||
struct hyperlinks *hyperlinks_init(void);
|
struct hyperlinks *hyperlinks_init(void);
|
||||||
|
struct hyperlinks *hyperlinks_copy(struct hyperlinks *);
|
||||||
void hyperlinks_reset(struct hyperlinks *);
|
void hyperlinks_reset(struct hyperlinks *);
|
||||||
void hyperlinks_free(struct hyperlinks *);
|
void hyperlinks_free(struct hyperlinks *);
|
||||||
|
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ static const struct tty_feature tty_feature_sync = {
|
|||||||
|
|
||||||
/* Terminal supports extended keys. */
|
/* Terminal supports extended keys. */
|
||||||
static const char *const tty_feature_extkeys_capabilities[] = {
|
static const char *const tty_feature_extkeys_capabilities[] = {
|
||||||
"Eneks=\\E[>4;1m",
|
"Eneks=\\E[>4;2m",
|
||||||
"Dseks=\\E[>4m",
|
"Dseks=\\E[>4m",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|||||||
118
tty-keys.c
118
tty-keys.c
@@ -59,7 +59,6 @@ static int tty_keys_device_attributes2(struct tty *, const char *, size_t,
|
|||||||
size_t *);
|
size_t *);
|
||||||
static int tty_keys_extended_device_attributes(struct tty *, const char *,
|
static int tty_keys_extended_device_attributes(struct tty *, const char *,
|
||||||
size_t, size_t *);
|
size_t, size_t *);
|
||||||
static int tty_keys_colours(struct tty *, const char *, size_t, size_t *);
|
|
||||||
|
|
||||||
/* A key tree entry. */
|
/* A key tree entry. */
|
||||||
struct tty_key {
|
struct tty_key {
|
||||||
@@ -665,7 +664,7 @@ tty_keys_next(struct tty *tty)
|
|||||||
size_t len, size;
|
size_t len, size;
|
||||||
cc_t bspace;
|
cc_t bspace;
|
||||||
int delay, expired = 0, n;
|
int delay, expired = 0, n;
|
||||||
key_code key;
|
key_code key, onlykey;
|
||||||
struct mouse_event m = { 0 };
|
struct mouse_event m = { 0 };
|
||||||
struct key_event *event;
|
struct key_event *event;
|
||||||
|
|
||||||
@@ -721,7 +720,7 @@ tty_keys_next(struct tty *tty)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Is this a colours response? */
|
/* Is this a colours response? */
|
||||||
switch (tty_keys_colours(tty, buf, len, &size)) {
|
switch (tty_keys_colours(tty, buf, len, &size, &tty->fg, &tty->bg)) {
|
||||||
case 0: /* yes */
|
case 0: /* yes */
|
||||||
key = KEYC_UNKNOWN;
|
key = KEYC_UNKNOWN;
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
@@ -802,6 +801,27 @@ first_key:
|
|||||||
key = (u_char)buf[0];
|
key = (u_char)buf[0];
|
||||||
size = 1;
|
size = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* C-Space is special. */
|
||||||
|
if ((key & KEYC_MASK_KEY) == C0_NUL)
|
||||||
|
key = ' ' | KEYC_CTRL | (key & KEYC_META);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix up all C0 control codes that don't have a dedicated key into
|
||||||
|
* corresponding Ctrl keys. Convert characters in the A-Z range into
|
||||||
|
* lowercase, so ^A becomes a|CTRL.
|
||||||
|
*/
|
||||||
|
onlykey = key & KEYC_MASK_KEY;
|
||||||
|
if (onlykey < 0x20 &&
|
||||||
|
onlykey != C0_HT &&
|
||||||
|
onlykey != C0_CR &&
|
||||||
|
onlykey != C0_ESC) {
|
||||||
|
onlykey |= 0x40;
|
||||||
|
if (onlykey >= 'A' && onlykey <= 'Z')
|
||||||
|
onlykey |= 0x20;
|
||||||
|
key = onlykey | KEYC_CTRL | (key & KEYC_META);
|
||||||
|
}
|
||||||
|
|
||||||
goto complete_key;
|
goto complete_key;
|
||||||
|
|
||||||
partial_key:
|
partial_key:
|
||||||
@@ -911,7 +931,8 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
|||||||
char tmp[64];
|
char tmp[64];
|
||||||
cc_t bspace;
|
cc_t bspace;
|
||||||
key_code nkey;
|
key_code nkey;
|
||||||
key_code onlykey;
|
struct utf8_data ud;
|
||||||
|
utf8_char uc;
|
||||||
|
|
||||||
*size = 0;
|
*size = 0;
|
||||||
|
|
||||||
@@ -961,10 +982,25 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
|||||||
else
|
else
|
||||||
nkey = number;
|
nkey = number;
|
||||||
|
|
||||||
|
/* Convert UTF-32 codepoint into internal representation. */
|
||||||
|
if (nkey & ~0x7f) {
|
||||||
|
if (utf8_fromwc(nkey, &ud) == UTF8_DONE &&
|
||||||
|
utf8_from_data(&ud, &uc) == UTF8_DONE)
|
||||||
|
nkey = uc;
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
/* Update the modifiers. */
|
/* Update the modifiers. */
|
||||||
if (modifiers > 0) {
|
if (modifiers > 0) {
|
||||||
modifiers--;
|
modifiers--;
|
||||||
if (modifiers & 1)
|
/*
|
||||||
|
* The Shift modifier may not be reported in some input modes,
|
||||||
|
* which is unfortunate, as in general case determining if a
|
||||||
|
* character is shifted or not requires knowing the input
|
||||||
|
* keyboard layout. So we only fix up the trivial case.
|
||||||
|
*/
|
||||||
|
if (modifiers & 1 || (nkey >= 'A' && nkey <= 'Z'))
|
||||||
nkey |= KEYC_SHIFT;
|
nkey |= KEYC_SHIFT;
|
||||||
if (modifiers & 2)
|
if (modifiers & 2)
|
||||||
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */
|
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Alt */
|
||||||
@@ -974,34 +1010,15 @@ tty_keys_extended_key(struct tty *tty, const char *buf, size_t len,
|
|||||||
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Meta */
|
nkey |= (KEYC_META|KEYC_IMPLIED_META); /* Meta */
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Convert S-Tab into Backtab. */
|
||||||
* Don't allow both KEYC_CTRL and as an implied modifier. Also convert
|
if ((nkey & KEYC_MASK_KEY) == '\011' && (nkey & KEYC_SHIFT))
|
||||||
* C-X into C-x and so on.
|
nkey = KEYC_BTAB | (nkey & ~KEYC_MASK_KEY & ~KEYC_SHIFT);
|
||||||
*/
|
|
||||||
if (nkey & KEYC_CTRL) {
|
|
||||||
onlykey = (nkey & KEYC_MASK_KEY);
|
|
||||||
if (onlykey < 32 &&
|
|
||||||
onlykey != 9 &&
|
|
||||||
onlykey != 13 &&
|
|
||||||
onlykey != 27)
|
|
||||||
/* nothing */;
|
|
||||||
else if (onlykey >= 97 && onlykey <= 122)
|
|
||||||
onlykey -= 96;
|
|
||||||
else if (onlykey >= 64 && onlykey <= 95)
|
|
||||||
onlykey -= 64;
|
|
||||||
else if (onlykey == 32)
|
|
||||||
onlykey = 0;
|
|
||||||
else if (onlykey == 63)
|
|
||||||
onlykey = 127;
|
|
||||||
else
|
|
||||||
onlykey |= KEYC_CTRL;
|
|
||||||
nkey = onlykey|((nkey & KEYC_MASK_MODIFIERS) & ~KEYC_CTRL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (log_get_level() != 0) {
|
if (log_get_level() != 0) {
|
||||||
log_debug("%s: extended key %.*s is %llx (%s)", c->name,
|
log_debug("%s: extended key %.*s is %llx (%s)", c->name,
|
||||||
(int)*size, buf, nkey, key_string_lookup_key(nkey, 1));
|
(int)*size, buf, nkey, key_string_lookup_key(nkey, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
*key = nkey;
|
*key = nkey;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -1202,7 +1219,7 @@ tty_keys_clipboard(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
}
|
}
|
||||||
if (end == len)
|
if (end == len)
|
||||||
return (1);
|
return (1);
|
||||||
*size = end + terminator;
|
*size = end + 1;
|
||||||
|
|
||||||
/* Skip the initial part. */
|
/* Skip the initial part. */
|
||||||
buf += 5;
|
buf += 5;
|
||||||
@@ -1314,26 +1331,21 @@ tty_keys_device_attributes(struct tty *tty, const char *buf, size_t len,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* Add terminal features. */
|
||||||
* Add terminal features. Hardware level 5 does not offer SIXEL but
|
|
||||||
* some terminal emulators report it anyway and it does not harm
|
|
||||||
* to check it here.
|
|
||||||
*
|
|
||||||
* DECSLRM and DECFRA should be supported by level 5 as well as level
|
|
||||||
* 4, but VTE has rather ruined it by advertising level 5 despite not
|
|
||||||
* supporting them.
|
|
||||||
*/
|
|
||||||
switch (p[0]) {
|
switch (p[0]) {
|
||||||
case 64: /* level 4 */
|
case 61: /* level 1 */
|
||||||
tty_add_features(features, "margins,rectfill", ",");
|
|
||||||
/* FALLTHROUGH */
|
|
||||||
case 62: /* level 2 */
|
case 62: /* level 2 */
|
||||||
case 63: /* level 3 */
|
case 63: /* level 3 */
|
||||||
|
case 64: /* level 4 */
|
||||||
case 65: /* level 5 */
|
case 65: /* level 5 */
|
||||||
for (i = 1; i < n; i++) {
|
for (i = 1; i < n; i++) {
|
||||||
log_debug("%s: DA feature: %d", c->name, p[i]);
|
log_debug("%s: DA feature: %d", c->name, p[i]);
|
||||||
if (p[i] == 4)
|
if (p[i] == 4)
|
||||||
tty_add_features(features, "sixel", ",");
|
tty_add_features(features, "sixel", ",");
|
||||||
|
if (p[i] == 21)
|
||||||
|
tty_add_features(features, "margins", ",");
|
||||||
|
if (p[i] == 28)
|
||||||
|
tty_add_features(features, "rectfill", ",");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1405,11 +1417,6 @@ tty_keys_device_attributes2(struct tty *tty, const char *buf, size_t len,
|
|||||||
* we can't use level 5 from DA because of VTE.
|
* we can't use level 5 from DA because of VTE.
|
||||||
*/
|
*/
|
||||||
switch (p[0]) {
|
switch (p[0]) {
|
||||||
case 41: /* VT420 */
|
|
||||||
case 61: /* VT510 */
|
|
||||||
case 64: /* VT520 */
|
|
||||||
tty_add_features(features, "margins,rectfill", ",");
|
|
||||||
break;
|
|
||||||
case 'M': /* mintty */
|
case 'M': /* mintty */
|
||||||
tty_default_features(features, "mintty", 0);
|
tty_default_features(features, "mintty", 0);
|
||||||
break;
|
break;
|
||||||
@@ -1500,8 +1507,9 @@ tty_keys_extended_device_attributes(struct tty *tty, const char *buf,
|
|||||||
* Handle foreground or background input. Returns 0 for success, -1 for
|
* Handle foreground or background input. Returns 0 for success, -1 for
|
||||||
* failure, 1 for partial.
|
* failure, 1 for partial.
|
||||||
*/
|
*/
|
||||||
static int
|
int
|
||||||
tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size)
|
tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size,
|
||||||
|
int *fg, int *bg)
|
||||||
{
|
{
|
||||||
struct client *c = tty->client;
|
struct client *c = tty->client;
|
||||||
u_int i;
|
u_int i;
|
||||||
@@ -1552,11 +1560,17 @@ tty_keys_colours(struct tty *tty, const char *buf, size_t len, size_t *size)
|
|||||||
|
|
||||||
n = colour_parseX11(tmp);
|
n = colour_parseX11(tmp);
|
||||||
if (n != -1 && buf[3] == '0') {
|
if (n != -1 && buf[3] == '0') {
|
||||||
log_debug("%s: foreground is %s", c->name, colour_tostring(n));
|
if (c != NULL)
|
||||||
tty->fg = n;
|
log_debug("%s fg is %s", c->name, colour_tostring(n));
|
||||||
|
else
|
||||||
|
log_debug("fg is %s", colour_tostring(n));
|
||||||
|
*fg = n;
|
||||||
} else if (n != -1) {
|
} else if (n != -1) {
|
||||||
log_debug("%s: background is %s", c->name, colour_tostring(n));
|
if (c != NULL)
|
||||||
tty->bg = n;
|
log_debug("%s bg is %s", c->name, colour_tostring(n));
|
||||||
|
else
|
||||||
|
log_debug("bg is %s", colour_tostring(n));
|
||||||
|
*bg = n;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
|
|||||||
12
tty-term.c
12
tty-term.c
@@ -531,9 +531,10 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
|||||||
struct options_array_item *a;
|
struct options_array_item *a;
|
||||||
union options_value *ov;
|
union options_value *ov;
|
||||||
u_int i, j;
|
u_int i, j;
|
||||||
const char *s, *value;
|
const char *s, *value, *errstr;
|
||||||
size_t offset, namelen;
|
size_t offset, namelen;
|
||||||
char *first;
|
char *first;
|
||||||
|
int n;
|
||||||
|
|
||||||
log_debug("adding term %s", name);
|
log_debug("adding term %s", name);
|
||||||
|
|
||||||
@@ -567,8 +568,13 @@ tty_term_create(struct tty *tty, char *name, char **caps, u_int ncaps,
|
|||||||
code->value.string = tty_term_strip(value);
|
code->value.string = tty_term_strip(value);
|
||||||
break;
|
break;
|
||||||
case TTYCODE_NUMBER:
|
case TTYCODE_NUMBER:
|
||||||
code->type = TTYCODE_NUMBER;
|
n = strtonum(value, 0, INT_MAX, &errstr);
|
||||||
code->value.number = atoi(value);
|
if (errstr != NULL)
|
||||||
|
log_debug("%s: %s", ent->name, errstr);
|
||||||
|
else {
|
||||||
|
code->type = TTYCODE_NUMBER;
|
||||||
|
code->value.number = n;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TTYCODE_FLAG:
|
case TTYCODE_FLAG:
|
||||||
code->type = TTYCODE_FLAG;
|
code->type = TTYCODE_FLAG;
|
||||||
|
|||||||
35
tty.c
35
tty.c
@@ -28,6 +28,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <termios.h>
|
#include <termios.h>
|
||||||
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
@@ -379,13 +380,13 @@ tty_send_requests(struct tty *tty)
|
|||||||
tty_puts(tty, "\033]11;?\033\\");
|
tty_puts(tty, "\033]11;?\033\\");
|
||||||
} else
|
} else
|
||||||
tty->flags |= TTY_ALL_REQUEST_FLAGS;
|
tty->flags |= TTY_ALL_REQUEST_FLAGS;
|
||||||
tty->last_requests = time (NULL);
|
tty->last_requests = time(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
tty_repeat_requests(struct tty *tty)
|
tty_repeat_requests(struct tty *tty)
|
||||||
{
|
{
|
||||||
time_t t = time (NULL);
|
time_t t = time(NULL);
|
||||||
|
|
||||||
if (~tty->flags & TTY_STARTED)
|
if (~tty->flags & TTY_STARTED)
|
||||||
return;
|
return;
|
||||||
@@ -2777,7 +2778,6 @@ static void
|
|||||||
tty_colours(struct tty *tty, const struct grid_cell *gc)
|
tty_colours(struct tty *tty, const struct grid_cell *gc)
|
||||||
{
|
{
|
||||||
struct grid_cell *tc = &tty->cell;
|
struct grid_cell *tc = &tty->cell;
|
||||||
int have_ax;
|
|
||||||
|
|
||||||
/* No changes? Nothing is necessary. */
|
/* No changes? Nothing is necessary. */
|
||||||
if (gc->fg == tc->fg && gc->bg == tc->bg && gc->us == tc->us)
|
if (gc->fg == tc->fg && gc->bg == tc->bg && gc->us == tc->us)
|
||||||
@@ -2791,28 +2791,18 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
|||||||
*/
|
*/
|
||||||
if (COLOUR_DEFAULT(gc->fg) || COLOUR_DEFAULT(gc->bg)) {
|
if (COLOUR_DEFAULT(gc->fg) || COLOUR_DEFAULT(gc->bg)) {
|
||||||
/*
|
/*
|
||||||
* If don't have AX but do have op, send sgr0 (op can't
|
* If don't have AX, send sgr0. This resets both colours to default.
|
||||||
* actually be used because it is sometimes the same as sgr0
|
|
||||||
* and sometimes isn't). This resets both colours to default.
|
|
||||||
*
|
|
||||||
* Otherwise, try to set the default colour only as needed.
|
* Otherwise, try to set the default colour only as needed.
|
||||||
*/
|
*/
|
||||||
have_ax = tty_term_flag(tty->term, TTYC_AX);
|
if (!tty_term_flag(tty->term, TTYC_AX))
|
||||||
if (!have_ax && tty_term_has(tty->term, TTYC_OP))
|
|
||||||
tty_reset(tty);
|
tty_reset(tty);
|
||||||
else {
|
else {
|
||||||
if (COLOUR_DEFAULT(gc->fg) && !COLOUR_DEFAULT(tc->fg)) {
|
if (COLOUR_DEFAULT(gc->fg) && !COLOUR_DEFAULT(tc->fg)) {
|
||||||
if (have_ax)
|
tty_puts(tty, "\033[39m");
|
||||||
tty_puts(tty, "\033[39m");
|
|
||||||
else if (tc->fg != 7)
|
|
||||||
tty_putcode_i(tty, TTYC_SETAF, 7);
|
|
||||||
tc->fg = gc->fg;
|
tc->fg = gc->fg;
|
||||||
}
|
}
|
||||||
if (COLOUR_DEFAULT(gc->bg) && !COLOUR_DEFAULT(tc->bg)) {
|
if (COLOUR_DEFAULT(gc->bg) && !COLOUR_DEFAULT(tc->bg)) {
|
||||||
if (have_ax)
|
tty_puts(tty, "\033[49m");
|
||||||
tty_puts(tty, "\033[49m");
|
|
||||||
else if (tc->bg != 0)
|
|
||||||
tty_putcode_i(tty, TTYC_SETAB, 0);
|
|
||||||
tc->bg = gc->bg;
|
tc->bg = gc->bg;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2824,7 +2814,7 @@ tty_colours(struct tty *tty, const struct grid_cell *gc)
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* Set the background colour. This must come after the foreground as
|
* Set the background colour. This must come after the foreground as
|
||||||
* tty_colour_fg() can call tty_reset().
|
* tty_colours_fg() can call tty_reset().
|
||||||
*/
|
*/
|
||||||
if (!COLOUR_DEFAULT(gc->bg) && gc->bg != tc->bg)
|
if (!COLOUR_DEFAULT(gc->bg) && gc->bg != tc->bg)
|
||||||
tty_colours_bg(tty, gc);
|
tty_colours_bg(tty, gc);
|
||||||
@@ -2972,6 +2962,15 @@ tty_colours_fg(struct tty *tty, const struct grid_cell *gc)
|
|||||||
struct grid_cell *tc = &tty->cell;
|
struct grid_cell *tc = &tty->cell;
|
||||||
char s[32];
|
char s[32];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the current colour is an aixterm bright colour and the new is not,
|
||||||
|
* reset because some terminals do not clear bright correctly.
|
||||||
|
*/
|
||||||
|
if (tty->cell.fg >= 90 &&
|
||||||
|
tty->cell.bg <= 97 &&
|
||||||
|
(gc->fg < 90 || gc->fg > 97))
|
||||||
|
tty_reset(tty);
|
||||||
|
|
||||||
/* Is this a 24-bit or 256-colour colour? */
|
/* Is this a 24-bit or 256-colour colour? */
|
||||||
if (gc->fg & COLOUR_FLAG_RGB || gc->fg & COLOUR_FLAG_256) {
|
if (gc->fg & COLOUR_FLAG_RGB || gc->fg & COLOUR_FLAG_256) {
|
||||||
if (tty_try_colour(tty, gc->fg, "38") == 0)
|
if (tty_try_colour(tty, gc->fg, "38") == 0)
|
||||||
|
|||||||
29
utf8.c
29
utf8.c
@@ -24,6 +24,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
|
#include "compat.h"
|
||||||
#include "tmux.h"
|
#include "tmux.h"
|
||||||
|
|
||||||
static const wchar_t utf8_force_wide[] = {
|
static const wchar_t utf8_force_wide[] = {
|
||||||
@@ -449,6 +450,32 @@ utf8_towc(const struct utf8_data *ud, wchar_t *wc)
|
|||||||
return (UTF8_DONE);
|
return (UTF8_DONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Convert wide character to UTF-8 character. */
|
||||||
|
enum utf8_state
|
||||||
|
utf8_fromwc(wchar_t wc, struct utf8_data *ud)
|
||||||
|
{
|
||||||
|
int size, width;
|
||||||
|
|
||||||
|
#ifdef HAVE_UTF8PROC
|
||||||
|
size = utf8proc_wctomb(ud->data, wc);
|
||||||
|
#else
|
||||||
|
size = wctomb(ud->data, wc);
|
||||||
|
#endif
|
||||||
|
if (size < 0) {
|
||||||
|
log_debug("UTF-8 %d, wctomb() %d", wc, errno);
|
||||||
|
wctomb(NULL, 0);
|
||||||
|
return (UTF8_ERROR);
|
||||||
|
}
|
||||||
|
if (size == 0)
|
||||||
|
return (UTF8_ERROR);
|
||||||
|
ud->size = ud->have = size;
|
||||||
|
if (utf8_width(ud, &width) == UTF8_DONE) {
|
||||||
|
ud->width = width;
|
||||||
|
return (UTF8_DONE);
|
||||||
|
}
|
||||||
|
return (UTF8_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Open UTF-8 sequence.
|
* Open UTF-8 sequence.
|
||||||
*
|
*
|
||||||
@@ -525,7 +552,7 @@ utf8_strvis(char *dst, const char *src, size_t len, int flag)
|
|||||||
/* Not a complete, valid UTF-8 character. */
|
/* Not a complete, valid UTF-8 character. */
|
||||||
src -= ud.have;
|
src -= ud.have;
|
||||||
}
|
}
|
||||||
if (src[0] == '$' && src < end - 1) {
|
if ((flag & VIS_DQ) && src[0] == '$' && src < end - 1) {
|
||||||
if (isalpha((u_char)src[1]) ||
|
if (isalpha((u_char)src[1]) ||
|
||||||
src[1] == '_' ||
|
src[1] == '_' ||
|
||||||
src[1] == '{')
|
src[1] == '{')
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ static void window_buffer_key(struct window_mode_entry *,
|
|||||||
struct client *, struct session *,
|
struct client *, struct session *,
|
||||||
struct winlink *, key_code, struct mouse_event *);
|
struct winlink *, key_code, struct mouse_event *);
|
||||||
|
|
||||||
#define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -b '%%'"
|
#define WINDOW_BUFFER_DEFAULT_COMMAND "paste-buffer -p -b '%%'"
|
||||||
|
|
||||||
#define WINDOW_BUFFER_DEFAULT_FORMAT \
|
#define WINDOW_BUFFER_DEFAULT_FORMAT \
|
||||||
"#{t/p:buffer_created}: #{buffer_sample}"
|
"#{t/p:buffer_created}: #{buffer_sample}"
|
||||||
@@ -408,8 +408,17 @@ window_buffer_do_delete(void *modedata, void *itemdata,
|
|||||||
struct window_buffer_itemdata *item = itemdata;
|
struct window_buffer_itemdata *item = itemdata;
|
||||||
struct paste_buffer *pb;
|
struct paste_buffer *pb;
|
||||||
|
|
||||||
if (item == mode_tree_get_current(data->data))
|
if (item == mode_tree_get_current(data->data) &&
|
||||||
mode_tree_down(data->data, 0);
|
!mode_tree_down(data->data, 0)) {
|
||||||
|
/*
|
||||||
|
*If we were unable to select the item further down we are at
|
||||||
|
* the end of the list. Move one element up instead, to make
|
||||||
|
* sure that we preserve a valid selection or we risk having
|
||||||
|
* the tree build logic reset it to the first item.
|
||||||
|
*/
|
||||||
|
mode_tree_up(data->data, 0);
|
||||||
|
}
|
||||||
|
|
||||||
if ((pb = paste_get_name(item->name)) != NULL)
|
if ((pb = paste_get_name(item->name)) != NULL)
|
||||||
paste_free(pb);
|
paste_free(pb);
|
||||||
}
|
}
|
||||||
@@ -508,7 +517,7 @@ window_buffer_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
struct window_buffer_itemdata *item;
|
struct window_buffer_itemdata *item;
|
||||||
int finished;
|
int finished;
|
||||||
|
|
||||||
if (paste_get_top(NULL) == NULL) {
|
if (paste_is_empty()) {
|
||||||
finished = 1;
|
finished = 1;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
@@ -541,7 +550,7 @@ window_buffer_key(struct window_mode_entry *wme, struct client *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (finished || paste_get_top(NULL) == NULL)
|
if (finished || paste_is_empty())
|
||||||
window_pane_reset_mode(wp);
|
window_pane_reset_mode(wp);
|
||||||
else {
|
else {
|
||||||
mode_tree_draw(mtd);
|
mode_tree_draw(mtd);
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ static void window_copy_resize(struct window_mode_entry *, u_int, u_int);
|
|||||||
static void window_copy_formats(struct window_mode_entry *,
|
static void window_copy_formats(struct window_mode_entry *,
|
||||||
struct format_tree *);
|
struct format_tree *);
|
||||||
static void window_copy_pageup1(struct window_mode_entry *, int);
|
static void window_copy_pageup1(struct window_mode_entry *, int);
|
||||||
static int window_copy_pagedown(struct window_mode_entry *, int, int);
|
static int window_copy_pagedown1(struct window_mode_entry *, int, int);
|
||||||
static void window_copy_next_paragraph(struct window_mode_entry *);
|
static void window_copy_next_paragraph(struct window_mode_entry *);
|
||||||
static void window_copy_previous_paragraph(struct window_mode_entry *);
|
static void window_copy_previous_paragraph(struct window_mode_entry *);
|
||||||
static void window_copy_redraw_selection(struct window_mode_entry *, u_int);
|
static void window_copy_redraw_selection(struct window_mode_entry *, u_int);
|
||||||
@@ -450,6 +450,8 @@ window_copy_init(struct window_mode_entry *wme,
|
|||||||
data->scroll_exit = args_has(args, 'e');
|
data->scroll_exit = args_has(args, 'e');
|
||||||
data->hide_position = args_has(args, 'H');
|
data->hide_position = args_has(args, 'H');
|
||||||
|
|
||||||
|
if (base->hyperlinks != NULL)
|
||||||
|
data->screen.hyperlinks = hyperlinks_copy(base->hyperlinks);
|
||||||
data->screen.cx = data->cx;
|
data->screen.cx = data->cx;
|
||||||
data->screen.cy = data->cy;
|
data->screen.cy = data->cy;
|
||||||
data->mx = data->cx;
|
data->mx = data->cx;
|
||||||
@@ -646,8 +648,18 @@ window_copy_pageup1(struct window_mode_entry *wme, int half_page)
|
|||||||
window_copy_redraw_screen(wme);
|
window_copy_redraw_screen(wme);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
window_copy_pagedown(struct window_pane *wp, int half_page, int scroll_exit)
|
||||||
|
{
|
||||||
|
if (window_copy_pagedown1(TAILQ_FIRST(&wp->modes), half_page,
|
||||||
|
scroll_exit)) {
|
||||||
|
window_pane_reset_mode(wp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
window_copy_pagedown(struct window_mode_entry *wme, int half_page,
|
window_copy_pagedown1(struct window_mode_entry *wme, int half_page,
|
||||||
int scroll_exit)
|
int scroll_exit)
|
||||||
{
|
{
|
||||||
struct window_copy_mode_data *data = wme->data;
|
struct window_copy_mode_data *data = wme->data;
|
||||||
@@ -754,6 +766,18 @@ window_copy_get_line(struct window_pane *wp, u_int y)
|
|||||||
return (format_grid_line(gd, gd->hsize + y));
|
return (format_grid_line(gd, gd->hsize + y));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
window_copy_cursor_hyperlink_cb(struct format_tree *ft)
|
||||||
|
{
|
||||||
|
struct window_pane *wp = format_get_pane(ft);
|
||||||
|
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
|
||||||
|
struct window_copy_mode_data *data = wme->data;
|
||||||
|
struct grid *gd = data->screen.grid;
|
||||||
|
|
||||||
|
return (format_grid_hyperlink(gd, data->cx, gd->hsize + data->cy,
|
||||||
|
&data->screen));
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
window_copy_cursor_word_cb(struct format_tree *ft)
|
window_copy_cursor_word_cb(struct format_tree *ft)
|
||||||
{
|
{
|
||||||
@@ -795,22 +819,36 @@ window_copy_formats(struct window_mode_entry *wme, struct format_tree *ft)
|
|||||||
format_add(ft, "copy_cursor_x", "%d", data->cx);
|
format_add(ft, "copy_cursor_x", "%d", data->cx);
|
||||||
format_add(ft, "copy_cursor_y", "%d", data->cy);
|
format_add(ft, "copy_cursor_y", "%d", data->cy);
|
||||||
|
|
||||||
format_add(ft, "selection_present", "%d", data->screen.sel != NULL);
|
|
||||||
if (data->screen.sel != NULL) {
|
if (data->screen.sel != NULL) {
|
||||||
format_add(ft, "selection_start_x", "%d", data->selx);
|
format_add(ft, "selection_start_x", "%d", data->selx);
|
||||||
format_add(ft, "selection_start_y", "%d", data->sely);
|
format_add(ft, "selection_start_y", "%d", data->sely);
|
||||||
format_add(ft, "selection_end_x", "%d", data->endselx);
|
format_add(ft, "selection_end_x", "%d", data->endselx);
|
||||||
format_add(ft, "selection_end_y", "%d", data->endsely);
|
format_add(ft, "selection_end_y", "%d", data->endsely);
|
||||||
format_add(ft, "selection_active", "%d",
|
|
||||||
data->cursordrag != CURSORDRAG_NONE);
|
if (data->cursordrag != CURSORDRAG_NONE)
|
||||||
} else
|
format_add(ft, "selection_active", "1");
|
||||||
format_add(ft, "selection_active", "%d", 0);
|
else
|
||||||
|
format_add(ft, "selection_active", "0");
|
||||||
|
if (data->endselx != data->selx || data->endsely != data->sely)
|
||||||
|
format_add(ft, "selection_present", "1");
|
||||||
|
else
|
||||||
|
format_add(ft, "selection_present", "0");
|
||||||
|
} else {
|
||||||
|
format_add(ft, "selection_active", "0");
|
||||||
|
format_add(ft, "selection_present", "0");
|
||||||
|
}
|
||||||
|
|
||||||
format_add(ft, "search_present", "%d", data->searchmark != NULL);
|
format_add(ft, "search_present", "%d", data->searchmark != NULL);
|
||||||
|
if (data->searchcount != -1) {
|
||||||
|
format_add(ft, "search_count", "%d", data->searchcount);
|
||||||
|
format_add(ft, "search_count_partial", "%d", data->searchmore);
|
||||||
|
}
|
||||||
format_add_cb(ft, "search_match", window_copy_search_match_cb);
|
format_add_cb(ft, "search_match", window_copy_search_match_cb);
|
||||||
|
|
||||||
format_add_cb(ft, "copy_cursor_word", window_copy_cursor_word_cb);
|
format_add_cb(ft, "copy_cursor_word", window_copy_cursor_word_cb);
|
||||||
format_add_cb(ft, "copy_cursor_line", window_copy_cursor_line_cb);
|
format_add_cb(ft, "copy_cursor_line", window_copy_cursor_line_cb);
|
||||||
|
format_add_cb(ft, "copy_cursor_hyperlink",
|
||||||
|
window_copy_cursor_hyperlink_cb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1339,7 +1377,7 @@ window_copy_cmd_halfpage_down(struct window_copy_cmd_state *cs)
|
|||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
for (; np != 0; np--) {
|
for (; np != 0; np--) {
|
||||||
if (window_copy_pagedown(wme, 1, data->scroll_exit))
|
if (window_copy_pagedown1(wme, 1, data->scroll_exit))
|
||||||
return (WINDOW_COPY_CMD_CANCEL);
|
return (WINDOW_COPY_CMD_CANCEL);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
@@ -1353,7 +1391,7 @@ window_copy_cmd_halfpage_down_and_cancel(struct window_copy_cmd_state *cs)
|
|||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
for (; np != 0; np--) {
|
for (; np != 0; np--) {
|
||||||
if (window_copy_pagedown(wme, 1, 1))
|
if (window_copy_pagedown1(wme, 1, 1))
|
||||||
return (WINDOW_COPY_CMD_CANCEL);
|
return (WINDOW_COPY_CMD_CANCEL);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
@@ -1781,7 +1819,7 @@ window_copy_cmd_page_down(struct window_copy_cmd_state *cs)
|
|||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
for (; np != 0; np--) {
|
for (; np != 0; np--) {
|
||||||
if (window_copy_pagedown(wme, 0, data->scroll_exit))
|
if (window_copy_pagedown1(wme, 0, data->scroll_exit))
|
||||||
return (WINDOW_COPY_CMD_CANCEL);
|
return (WINDOW_COPY_CMD_CANCEL);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
@@ -1794,7 +1832,7 @@ window_copy_cmd_page_down_and_cancel(struct window_copy_cmd_state *cs)
|
|||||||
u_int np = wme->prefix;
|
u_int np = wme->prefix;
|
||||||
|
|
||||||
for (; np != 0; np--) {
|
for (; np != 0; np--) {
|
||||||
if (window_copy_pagedown(wme, 0, 1))
|
if (window_copy_pagedown1(wme, 0, 1))
|
||||||
return (WINDOW_COPY_CMD_CANCEL);
|
return (WINDOW_COPY_CMD_CANCEL);
|
||||||
}
|
}
|
||||||
return (WINDOW_COPY_CMD_NOTHING);
|
return (WINDOW_COPY_CMD_NOTHING);
|
||||||
@@ -2464,7 +2502,8 @@ window_copy_cmd_refresh_from_pane(struct window_copy_cmd_state *cs)
|
|||||||
|
|
||||||
screen_free(data->backing);
|
screen_free(data->backing);
|
||||||
free(data->backing);
|
free(data->backing);
|
||||||
data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL, NULL, wme->swp != wme->wp);
|
data->backing = window_copy_clone_screen(&wp->base, &data->screen, NULL,
|
||||||
|
NULL, wme->swp != wme->wp);
|
||||||
|
|
||||||
window_copy_size_changed(wme);
|
window_copy_size_changed(wme);
|
||||||
return (WINDOW_COPY_CMD_REDRAW);
|
return (WINDOW_COPY_CMD_REDRAW);
|
||||||
@@ -3606,11 +3645,10 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
|
|||||||
struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
|
struct grid *sgd, u_int fx, u_int fy, u_int endline, int cis, int wrap,
|
||||||
int direction, int regex)
|
int direction, int regex)
|
||||||
{
|
{
|
||||||
u_int i, px, sx, ssize = 1;
|
u_int i, px, sx, ssize = 1;
|
||||||
int found = 0, cflags = REG_EXTENDED;
|
int found = 0, cflags = REG_EXTENDED;
|
||||||
char *sbuf;
|
char *sbuf;
|
||||||
regex_t reg;
|
regex_t reg;
|
||||||
struct grid_line *gl;
|
|
||||||
|
|
||||||
if (regex) {
|
if (regex) {
|
||||||
sbuf = xmalloc(ssize);
|
sbuf = xmalloc(ssize);
|
||||||
@@ -3627,9 +3665,6 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
|
|||||||
|
|
||||||
if (direction) {
|
if (direction) {
|
||||||
for (i = fy; i <= endline; i++) {
|
for (i = fy; i <= endline; i++) {
|
||||||
gl = grid_get_line(gd, i);
|
|
||||||
if (i != endline && gl->flags & GRID_LINE_WRAPPED)
|
|
||||||
continue;
|
|
||||||
if (regex) {
|
if (regex) {
|
||||||
found = window_copy_search_lr_regex(gd,
|
found = window_copy_search_lr_regex(gd,
|
||||||
&px, &sx, i, fx, gd->sx, ®);
|
&px, &sx, i, fx, gd->sx, ®);
|
||||||
@@ -3643,9 +3678,6 @@ window_copy_search_jump(struct window_mode_entry *wme, struct grid *gd,
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = fy + 1; endline < i; i--) {
|
for (i = fy + 1; endline < i; i--) {
|
||||||
gl = grid_get_line(gd, i - 1);
|
|
||||||
if (i != endline && gl->flags & GRID_LINE_WRAPPED)
|
|
||||||
continue;
|
|
||||||
if (regex) {
|
if (regex) {
|
||||||
found = window_copy_search_rl_regex(gd,
|
found = window_copy_search_rl_regex(gd,
|
||||||
&px, &sx, i - 1, 0, fx + 1, ®);
|
&px, &sx, i - 1, 0, fx + 1, ®);
|
||||||
@@ -4686,7 +4718,7 @@ window_copy_get_selection(struct window_mode_entry *wme, size_t *len)
|
|||||||
if (keys == MODEKEY_EMACS || lastex <= ey_last) {
|
if (keys == MODEKEY_EMACS || lastex <= ey_last) {
|
||||||
if (~grid_get_line(data->backing->grid, ey)->flags &
|
if (~grid_get_line(data->backing->grid, ey)->flags &
|
||||||
GRID_LINE_WRAPPED || lastex != ey_last)
|
GRID_LINE_WRAPPED || lastex != ey_last)
|
||||||
off -= 1;
|
off -= 1;
|
||||||
}
|
}
|
||||||
*len = off;
|
*len = off;
|
||||||
return (buf);
|
return (buf);
|
||||||
|
|||||||
27
window.c
27
window.c
@@ -338,7 +338,7 @@ window_destroy(struct window *w)
|
|||||||
{
|
{
|
||||||
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
log_debug("window @%u destroyed (%d references)", w->id, w->references);
|
||||||
|
|
||||||
window_unzoom(w);
|
window_unzoom(w, 0);
|
||||||
RB_REMOVE(windows, &windows, w);
|
RB_REMOVE(windows, &windows, w);
|
||||||
|
|
||||||
if (w->layout_root != NULL)
|
if (w->layout_root != NULL)
|
||||||
@@ -481,7 +481,7 @@ window_pane_update_focus(struct window_pane *wp)
|
|||||||
struct client *c;
|
struct client *c;
|
||||||
int focused = 0;
|
int focused = 0;
|
||||||
|
|
||||||
if (wp != NULL) {
|
if (wp != NULL && (~wp->flags & PANE_EXITED)) {
|
||||||
if (wp != wp->window->active)
|
if (wp != wp->window->active)
|
||||||
focused = 0;
|
focused = 0;
|
||||||
else {
|
else {
|
||||||
@@ -673,7 +673,7 @@ window_zoom(struct window_pane *wp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
window_unzoom(struct window *w)
|
window_unzoom(struct window *w, int notify)
|
||||||
{
|
{
|
||||||
struct window_pane *wp;
|
struct window_pane *wp;
|
||||||
|
|
||||||
@@ -690,7 +690,9 @@ window_unzoom(struct window *w)
|
|||||||
wp->saved_layout_cell = NULL;
|
wp->saved_layout_cell = NULL;
|
||||||
}
|
}
|
||||||
layout_fix_panes(w, NULL);
|
layout_fix_panes(w, NULL);
|
||||||
notify_window("window-layout-changed", w);
|
|
||||||
|
if (notify)
|
||||||
|
notify_window("window-layout-changed", w);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@@ -704,7 +706,7 @@ window_push_zoom(struct window *w, int always, int flag)
|
|||||||
w->flags |= WINDOW_WASZOOMED;
|
w->flags |= WINDOW_WASZOOMED;
|
||||||
else
|
else
|
||||||
w->flags &= ~WINDOW_WASZOOMED;
|
w->flags &= ~WINDOW_WASZOOMED;
|
||||||
return (window_unzoom(w) == 0);
|
return (window_unzoom(w, 1) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -942,6 +944,9 @@ window_pane_create(struct window *w, u_int sx, u_int sy, u_int hlimit)
|
|||||||
|
|
||||||
wp->pipe_fd = -1;
|
wp->pipe_fd = -1;
|
||||||
|
|
||||||
|
wp->control_bg = -1;
|
||||||
|
wp->control_fg = -1;
|
||||||
|
|
||||||
colour_palette_init(&wp->palette);
|
colour_palette_init(&wp->palette);
|
||||||
colour_palette_from_option(&wp->palette, wp->options);
|
colour_palette_from_option(&wp->palette, wp->options);
|
||||||
|
|
||||||
@@ -1667,3 +1672,15 @@ window_pane_default_cursor(struct window_pane *wp)
|
|||||||
s->default_mode = 0;
|
s->default_mode = 0;
|
||||||
screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
|
screen_set_cursor_style(c, &s->default_cstyle, &s->default_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
window_pane_mode(struct window_pane *wp)
|
||||||
|
{
|
||||||
|
if (TAILQ_FIRST(&wp->modes) != NULL) {
|
||||||
|
if (TAILQ_FIRST(&wp->modes)->mode == &window_copy_mode)
|
||||||
|
return (WINDOW_PANE_COPY_MODE);
|
||||||
|
if (TAILQ_FIRST(&wp->modes)->mode == &window_view_mode)
|
||||||
|
return (WINDOW_PANE_VIEW_MODE);
|
||||||
|
}
|
||||||
|
return (WINDOW_PANE_NO_MODE);
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user