Merge branch 'master' into sixel

topcat001 2022-10-27 16:01:35 -07:00
commit 2a1e16a24d
20 changed files with 215 additions and 81 deletions

View File

@ -284,6 +284,12 @@ client_main(struct event_base *base, int argc, char **argv, uint64_t flags,
log_debug("flags are %#llx", (unsigned long long)client_flags); log_debug("flags are %#llx", (unsigned long long)client_flags);
/* Initialize the client socket and start the server. */ /* Initialize the client socket and start the server. */
#ifdef HAVE_SYSTEMD
if (systemd_activated()) {
/* socket-based activation, do not even try to be a client. */
fd = server_start(client_proc, flags, base, 0, NULL);
} else
#endif
fd = client_connect(base, socket_path, client_flags); fd = client_connect(base, socket_path, client_flags);
if (fd == -1) { if (fd == -1) {
if (errno == ECONNREFUSED) { if (errno == ECONNREFUSED) {

View File

@ -40,7 +40,7 @@ const struct cmd_entry cmd_capture_pane_entry = {
.alias = "capturep", .alias = "capturep",
.args = { "ab:CeE:JNpPqS:t:", 0, 0, NULL }, .args = { "ab:CeE:JNpPqS:t:", 0, 0, NULL },
.usage = "[-aCeJNpPq] " CMD_BUFFER_USAGE " [-E end-line] " .usage = "[-aCeJNpPqT] " CMD_BUFFER_USAGE " [-E end-line] "
"[-S start-line] " CMD_TARGET_PANE_USAGE, "[-S start-line] " CMD_TARGET_PANE_USAGE,
.target = { 't', CMD_FIND_PANE, 0 }, .target = { 't', CMD_FIND_PANE, 0 },
@ -110,7 +110,7 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
struct grid *gd; struct grid *gd;
const struct grid_line *gl; const struct grid_line *gl;
struct grid_cell *gc = NULL; struct grid_cell *gc = NULL;
int n, with_codes, escape_c0, join_lines, no_trim; int n, join_lines, flags = 0;
u_int i, sx, top, bottom, tmp; u_int i, sx, top, bottom, tmp;
char *cause, *buf, *line; char *cause, *buf, *line;
const char *Sflag, *Eflag; const char *Sflag, *Eflag;
@ -169,15 +169,19 @@ cmd_capture_pane_history(struct args *args, struct cmdq_item *item,
top = tmp; top = tmp;
} }
with_codes = args_has(args, 'e');
escape_c0 = args_has(args, 'C');
join_lines = args_has(args, 'J'); join_lines = args_has(args, 'J');
no_trim = args_has(args, 'N'); if (args_has(args, 'e'))
flags |= GRID_STRING_WITH_SEQUENCES;
if (args_has(args, 'C'))
flags |= GRID_STRING_ESCAPE_SEQUENCES;
if (!join_lines && !args_has(args, 'T'))
flags |= GRID_STRING_EMPTY_CELLS;
if (!join_lines && !args_has(args, 'N'))
flags |= GRID_STRING_TRIM_SPACES;
buf = NULL; buf = NULL;
for (i = top; i <= bottom; i++) { for (i = top; i <= bottom; i++) {
line = grid_string_cells(gd, 0, i, sx, &gc, with_codes, line = grid_string_cells(gd, 0, i, sx, &gc, flags, wp->screen);
escape_c0, !join_lines && !no_trim, wp->screen);
linelen = strlen(line); linelen = strlen(line);
buf = cmd_capture_pane_append(buf, len, line, linelen); buf = cmd_capture_pane_append(buf, len, line, linelen);

View File

@ -1086,7 +1086,8 @@ cmd_parse_from_arguments(struct args_value *values, u_int count,
arg->type = CMD_PARSE_STRING; arg->type = CMD_PARSE_STRING;
arg->string = copy; arg->string = copy;
TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry); TAILQ_INSERT_TAIL(&cmd->arguments, arg, entry);
} } else
free(copy);
} else if (values[i].type == ARGS_COMMANDS) { } else if (values[i].type == ARGS_COMMANDS) {
arg = xcalloc(1, sizeof *arg); arg = xcalloc(1, sizeof *arg);
arg->type = CMD_PARSE_PARSED_COMMANDS; arg->type = CMD_PARSE_PARSED_COMMANDS;

View File

@ -423,6 +423,7 @@ void *recallocarray(void *, size_t, size_t, size_t);
#ifdef HAVE_SYSTEMD #ifdef HAVE_SYSTEMD
/* systemd.c */ /* systemd.c */
int systemd_activated(void);
int systemd_create_socket(int, char **); int systemd_create_socket(int, char **);
#endif #endif

View File

@ -21,15 +21,23 @@
#include <systemd/sd-daemon.h> #include <systemd/sd-daemon.h>
#include <string.h>
#include "tmux.h" #include "tmux.h"
int
systemd_activated(void)
{
return (sd_listen_fds(0) >= 1);
}
int int
systemd_create_socket(int flags, char **cause) systemd_create_socket(int flags, char **cause)
{ {
int fds; int fds;
int fd; int fd;
struct sockaddr_un sa; struct sockaddr_un sa;
int addrlen = sizeof sa; socklen_t addrlen = sizeof sa;
fds = sd_listen_fds(0); fds = sd_listen_fds(0);
if (fds > 1) { /* too many file descriptors */ if (fds > 1) { /* too many file descriptors */

View File

@ -231,5 +231,5 @@ grid_view_string_cells(struct grid *gd, u_int px, u_int py, u_int nx)
px = grid_view_x(gd, px); px = grid_view_x(gd, px);
py = grid_view_y(gd, py); py = grid_view_y(gd, py);
return (grid_string_cells(gd, px, py, nx, NULL, 0, 0, 0, NULL)); return (grid_string_cells(gd, px, py, nx, NULL, 0, NULL));
} }

86
grid.c
View File

@ -861,40 +861,45 @@ grid_string_cells_us(const struct grid_cell *gc, int *values)
/* Add on SGR code. */ /* Add on SGR code. */
static void static void
grid_string_cells_add_code(char *buf, size_t len, u_int n, int *s, int *newc, grid_string_cells_add_code(char *buf, size_t len, u_int n, int *s, int *newc,
int *oldc, size_t nnewc, size_t noldc, int escape_c0) int *oldc, size_t nnewc, size_t noldc, int flags)
{ {
u_int i; u_int i;
char tmp[64]; char tmp[64];
int reset = (n != 0 && s[0] == 0);
if (nnewc != 0 && if (nnewc == 0)
(nnewc != noldc || return; /* no code to add */
memcmp(newc, oldc, nnewc * sizeof newc[0]) != 0 || if (!reset &&
(n != 0 && s[0] == 0))) { nnewc == noldc &&
if (escape_c0) memcmp(newc, oldc, nnewc * sizeof newc[0]) == 0)
strlcat(buf, "\\033[", len); return; /* no reset and colour unchanged */
if (reset && (newc[0] == 49 || newc[0] == 39))
return; /* reset and colour default */
if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\033[", len);
else
strlcat(buf, "\033[", len);
for (i = 0; i < nnewc; i++) {
if (i + 1 < nnewc)
xsnprintf(tmp, sizeof tmp, "%d;", newc[i]);
else else
strlcat(buf, "\033[", len); xsnprintf(tmp, sizeof tmp, "%d", newc[i]);
for (i = 0; i < nnewc; i++) { strlcat(buf, tmp, len);
if (i + 1 < nnewc)
xsnprintf(tmp, sizeof tmp, "%d;", newc[i]);
else
xsnprintf(tmp, sizeof tmp, "%d", newc[i]);
strlcat(buf, tmp, len);
}
strlcat(buf, "m", len);
} }
strlcat(buf, "m", len);
} }
static int static int
grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id, grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id,
const char *uri, int escape_c0) const char *uri, int flags)
{ {
char *tmp; char *tmp;
if (strlen(uri) + strlen(id) + 17 >= len) if (strlen(uri) + strlen(id) + 17 >= len)
return (0); return (0);
if (escape_c0) if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\033]8;", len); strlcat(buf, "\\033]8;", len);
else else
strlcat(buf, "\033]8;", len); strlcat(buf, "\033]8;", len);
@ -905,7 +910,7 @@ grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id,
} else } else
strlcat(buf, ";", len); strlcat(buf, ";", len);
strlcat(buf, uri, len); strlcat(buf, uri, len);
if (escape_c0) if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\033\\\\", len); strlcat(buf, "\\033\\\\", len);
else else
strlcat(buf, "\033\\", len); strlcat(buf, "\033\\", len);
@ -918,7 +923,7 @@ grid_string_cells_add_hyperlink(char *buf, size_t len, const char *id,
*/ */
static void static void
grid_string_cells_code(const struct grid_cell *lastgc, grid_string_cells_code(const struct grid_cell *lastgc,
const struct grid_cell *gc, char *buf, size_t len, int escape_c0, const struct grid_cell *gc, char *buf, size_t len, int flags,
struct screen *sc, int *has_link) struct screen *sc, int *has_link)
{ {
int oldc[64], newc[64], s[128]; int oldc[64], newc[64], s[128];
@ -927,7 +932,7 @@ grid_string_cells_code(const struct grid_cell *lastgc,
char tmp[64]; char tmp[64];
const char *uri, *id; const char *uri, *id;
struct { static const struct {
u_int mask; u_int mask;
u_int code; u_int code;
} attrs[] = { } attrs[] = {
@ -966,7 +971,7 @@ grid_string_cells_code(const struct grid_cell *lastgc,
/* Write the attributes. */ /* Write the attributes. */
*buf = '\0'; *buf = '\0';
if (n > 0) { if (n > 0) {
if (escape_c0) if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\033[", len); strlcat(buf, "\\033[", len);
else else
strlcat(buf, "\033[", len); strlcat(buf, "\033[", len);
@ -988,29 +993,29 @@ grid_string_cells_code(const struct grid_cell *lastgc,
nnewc = grid_string_cells_fg(gc, newc); nnewc = grid_string_cells_fg(gc, newc);
noldc = grid_string_cells_fg(lastgc, oldc); noldc = grid_string_cells_fg(lastgc, oldc);
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
escape_c0); flags);
/* If the background colour changed, append its parameters. */ /* If the background colour changed, append its parameters. */
nnewc = grid_string_cells_bg(gc, newc); nnewc = grid_string_cells_bg(gc, newc);
noldc = grid_string_cells_bg(lastgc, oldc); noldc = grid_string_cells_bg(lastgc, oldc);
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
escape_c0); flags);
/* If the underscore colour changed, append its parameters. */ /* If the underscore colour changed, append its parameters. */
nnewc = grid_string_cells_us(gc, newc); nnewc = grid_string_cells_us(gc, newc);
noldc = grid_string_cells_us(lastgc, oldc); noldc = grid_string_cells_us(lastgc, oldc);
grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc, grid_string_cells_add_code(buf, len, n, s, newc, oldc, nnewc, noldc,
escape_c0); flags);
/* Append shift in/shift out if needed. */ /* Append shift in/shift out if needed. */
if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) { if ((attr & GRID_ATTR_CHARSET) && !(lastattr & GRID_ATTR_CHARSET)) {
if (escape_c0) if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\016", len); /* SO */ strlcat(buf, "\\016", len); /* SO */
else else
strlcat(buf, "\016", len); /* SO */ strlcat(buf, "\016", len); /* SO */
} }
if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET)) { if (!(attr & GRID_ATTR_CHARSET) && (lastattr & GRID_ATTR_CHARSET)) {
if (escape_c0) if (flags & GRID_STRING_ESCAPE_SEQUENCES)
strlcat(buf, "\\017", len); /* SI */ strlcat(buf, "\\017", len); /* SI */
else else
strlcat(buf, "\017", len); /* SI */ strlcat(buf, "\017", len); /* SI */
@ -1020,10 +1025,10 @@ grid_string_cells_code(const struct grid_cell *lastgc,
if (sc != NULL && sc->hyperlinks != NULL && lastgc->link != gc->link) { if (sc != NULL && sc->hyperlinks != NULL && lastgc->link != gc->link) {
if (hyperlinks_get(sc->hyperlinks, gc->link, &uri, &id, NULL)) { if (hyperlinks_get(sc->hyperlinks, gc->link, &uri, &id, NULL)) {
*has_link = grid_string_cells_add_hyperlink(buf, len, *has_link = grid_string_cells_add_hyperlink(buf, len,
id, uri, escape_c0); id, uri, flags);
} else if (*has_link) { } else if (*has_link) {
grid_string_cells_add_hyperlink(buf, len, "", "", grid_string_cells_add_hyperlink(buf, len, "", "",
escape_c0); flags);
*has_link = 0; *has_link = 0;
} }
} }
@ -1032,15 +1037,14 @@ grid_string_cells_code(const struct grid_cell *lastgc,
/* Convert cells into a string. */ /* Convert cells into a string. */
char * char *
grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx, grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
struct grid_cell **lastgc, int with_codes, int escape_c0, int trim, struct grid_cell **lastgc, int flags, struct screen *s)
struct screen *s)
{ {
struct grid_cell gc; struct grid_cell gc;
static struct grid_cell lastgc1; static struct grid_cell lastgc1;
const char *data; const char *data;
char *buf, code[8192]; char *buf, code[8192];
size_t len, off, size, codelen; size_t len, off, size, codelen;
u_int xx, has_link = 0; u_int xx, has_link = 0, end;
const struct grid_line *gl; const struct grid_line *gl;
if (lastgc != NULL && *lastgc == NULL) { if (lastgc != NULL && *lastgc == NULL) {
@ -1053,16 +1057,20 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
off = 0; off = 0;
gl = grid_peek_line(gd, py); gl = grid_peek_line(gd, py);
if (flags & GRID_STRING_EMPTY_CELLS)
end = gl->cellsize;
else
end = gl->cellused;
for (xx = px; xx < px + nx; xx++) { for (xx = px; xx < px + nx; xx++) {
if (gl == NULL || xx >= gl->cellused) if (gl == NULL || xx >= end)
break; break;
grid_get_cell(gd, xx, py, &gc); grid_get_cell(gd, xx, py, &gc);
if (gc.flags & GRID_FLAG_PADDING) if (gc.flags & GRID_FLAG_PADDING)
continue; continue;
if (with_codes) { if (flags & GRID_STRING_WITH_SEQUENCES) {
grid_string_cells_code(*lastgc, &gc, code, sizeof code, grid_string_cells_code(*lastgc, &gc, code, sizeof code,
escape_c0, s, &has_link); flags, s, &has_link);
codelen = strlen(code); codelen = strlen(code);
memcpy(*lastgc, &gc, sizeof **lastgc); memcpy(*lastgc, &gc, sizeof **lastgc);
} else } else
@ -1070,7 +1078,9 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
data = gc.data.data; data = gc.data.data;
size = gc.data.size; size = gc.data.size;
if (escape_c0 && size == 1 && *data == '\\') { if ((flags & GRID_STRING_ESCAPE_SEQUENCES) &&
size == 1 &&
*data == '\\') {
data = "\\\\"; data = "\\\\";
size = 2; size = 2;
} }
@ -1090,7 +1100,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
if (has_link) { if (has_link) {
grid_string_cells_add_hyperlink(code, sizeof code, "", "", grid_string_cells_add_hyperlink(code, sizeof code, "", "",
escape_c0); flags);
codelen = strlen(code); codelen = strlen(code);
while (len < off + size + codelen + 1) { while (len < off + size + codelen + 1) {
buf = xreallocarray(buf, 2, len); buf = xreallocarray(buf, 2, len);
@ -1100,7 +1110,7 @@ grid_string_cells(struct grid *gd, u_int px, u_int py, u_int nx,
off += codelen; off += codelen;
} }
if (trim) { if (flags & GRID_STRING_TRIM_SPACES) {
while (off > 0 && buf[off - 1] == ' ') while (off > 0 && buf[off - 1] == ' ')
off--; off--;
} }

View File

@ -1899,7 +1899,7 @@ input_csi_dispatch_winops(struct input_ctx *ictx)
} }
break; break;
case 18: case 18:
input_reply(ictx, "\033[8;%u;%ut", x, y); input_reply(ictx, "\033[8;%u;%ut", y, x);
break; break;
default: default:
log_debug("%s: unknown '%c'", __func__, ictx->ch); log_debug("%s: unknown '%c'", __func__, ictx->ch);
@ -2242,7 +2242,6 @@ static int
input_dcs_dispatch(struct input_ctx *ictx) input_dcs_dispatch(struct input_ctx *ictx)
{ {
struct window_pane *wp = ictx->wp; struct window_pane *wp = ictx->wp;
struct options *oo = wp->options;
struct screen_write_ctx *sctx = &ictx->ctx; struct screen_write_ctx *sctx = &ictx->ctx;
struct window *w = wp->window; struct window *w = wp->window;
u_char *buf = ictx->input_buf; u_char *buf = ictx->input_buf;
@ -2256,7 +2255,8 @@ input_dcs_dispatch(struct input_ctx *ictx)
return (0); return (0);
if (ictx->flags & INPUT_DISCARD) if (ictx->flags & INPUT_DISCARD)
return (0); return (0);
allow_passthrough = options_get_number(oo, "allow-passthrough"); allow_passthrough = options_get_number(wp->options,
"allow-passthrough");
if (!allow_passthrough) if (!allow_passthrough)
return (0); return (0);
log_debug("%s: \"%s\"", __func__, buf); log_debug("%s: \"%s\"", __func__, buf);

View File

@ -41,6 +41,9 @@ static const char *options_table_clock_mode_style_list[] = {
static const char *options_table_status_list[] = { static const char *options_table_status_list[] = {
"off", "on", "2", "3", "4", "5", NULL "off", "on", "2", "3", "4", "5", NULL
}; };
static const char *options_table_message_line_list[] = {
"0", "1", "2", "3", "4", NULL
};
static const char *options_table_status_keys_list[] = { static const char *options_table_status_keys_list[] = {
"emacs", "vi", NULL "emacs", "vi", NULL
}; };
@ -541,13 +544,21 @@ const struct options_table_entry options_table[] = {
"'mode-keys' is set to 'vi'." "'mode-keys' is set to 'vi'."
}, },
{ .name = "message-line",
.type = OPTIONS_TABLE_CHOICE,
.scope = OPTIONS_TABLE_SESSION,
.choices = options_table_message_line_list,
.default_num = 0,
.text = "Position (line) of messages and the command prompt."
},
{ .name = "message-style", { .name = "message-style",
.type = OPTIONS_TABLE_STRING, .type = OPTIONS_TABLE_STRING,
.scope = OPTIONS_TABLE_SESSION, .scope = OPTIONS_TABLE_SESSION,
.default_str = "bg=yellow,fg=black", .default_str = "bg=yellow,fg=black",
.flags = OPTIONS_TABLE_IS_STYLE, .flags = OPTIONS_TABLE_IS_STYLE,
.separator = ",", .separator = ",",
.text = "Style of the command prompt." .text = "Style of messages and the command prompt."
}, },
{ .name = "mouse", { .name = "mouse",

View File

@ -12,7 +12,7 @@ set-window-option -g pane-base-index 1
unbind ^B unbind ^B
bind ^B select-pane -t :.+ bind ^B select-pane -t :.+
# Reload config wtih a key # Reload config with a key
bind-key r source-file ~/.tmux.conf \; display "Config reloaded!" bind-key r source-file ~/.tmux.conf \; display "Config reloaded!"
# Mouse works as expected # Mouse works as expected

View File

@ -24,7 +24,7 @@ set-option -g default-terminal 'screen-256color'
# allow Vim to receive focus events from terminal window # allow Vim to receive focus events from terminal window
set-option -g focus-events on set-option -g focus-events on
# allow Vim to recieve modifier keys: Shift, Control, Alt # allow Vim to receive modifier keys: Shift, Control, Alt
set-window-option -g xterm-keys on set-window-option -g xterm-keys on
# prevent tmux from catching modifier keys meant for Vim # prevent tmux from catching modifier keys meant for Vim

View File

@ -552,7 +552,7 @@ setw -g status-keys emacs
# Changelog: https://github.com/tmux/tmux/blob/master/CHANGES # Changelog: https://github.com/tmux/tmux/blob/master/CHANGES
# style colors: default, black, red, green, yellow, blue, magenta, cyan, white, # style colors: default, black, red, green, yellow, blue, magenta, cyan, white,
# colour0-colour255, hexdecimal RGB string '#ffffff' # colour0-colour255, hexadecimal RGB string '#ffffff'
# Use $SCRIPTS/bash/256-colors.sh to figure out the color number you want # Use $SCRIPTS/bash/256-colors.sh to figure out the color number you want
# style attributes: none, bold/bright, dim, underscore, blink, reverse, hidden, # style attributes: none, bold/bright, dim, underscore, blink, reverse, hidden,
# or italics # or italics

View File

@ -1,6 +1,6 @@
# none of these attempts worked, to bind keys, except sometimes during the sesssion. Oh well. # none of these attempts worked, to bind keys, except sometimes during the session. Oh well.
# I thought maybe that was because F1 is handled differently in a console than in X, but # I thought maybe that was because F1 is handled differently in a console than in X, but
# even just C-1 didnt work. Using just "a" or "x" as the key did, but not yet sure why not "C-". # even just C-1 didn't work. Using just "a" or "x" as the key did, but not yet sure why not "C-".
#bind-key -T root C-1 attach-session -t$0 #bind-key -T root C-1 attach-session -t$0
#But this one works now, only picks the wrong one? Mbe need2understand what "$1" or $0 mean, better, #But this one works now, only picks the wrong one? Mbe need2understand what "$1" or $0 mean, better,
#but with the stub maybe this doesn't matter: #but with the stub maybe this doesn't matter:
@ -47,7 +47,7 @@ select-window -t :=3
#$3 for email (mutt) #$3 for email (mutt)
new-session sula new-session sula
new-window sula ; send-keys mutt Enter new-window sula ; send-keys mutt Enter
#nah, probly betr not?: #nah, probably better not?:
#send-keys -l z #send-keys -l z
#send-keys -l "thepassifdecide" #send-keys -l "thepassifdecide"
#send-keys Enter #send-keys Enter

View File

@ -63,7 +63,7 @@ bind N command-prompt -p hosts: 'run-shell -b "bash -c \"~/lbin/nw %% >/dev/null
#05:59 < Celti> annihilannic: I believe the #{pane_in_mode} format does what you want #05:59 < Celti> annihilannic: I believe the #{pane_in_mode} format does what you want
#05:59 < Celti> put it in your statusline #05:59 < Celti> put it in your statusline
#05:59 < Celti> annihilannic: No, my mistake, I should have read farther down, you want #{pane_synchronized} #05:59 < Celti> annihilannic: No, my mistake, I should have read farther down, you want #{pane_synchronized}
# only works in tmux 2.0?, higher than 1.6.3 anyawy # only works in tmux 2.0?, higher than 1.6.3 anyway
set-option -g window-status-format ' #I:#W#F#{?pane_synchronized,S,}' set-option -g window-status-format ' #I:#W#F#{?pane_synchronized,S,}'
#set-option -g window-status-current-format ' #I:#W#{?pane_synchronized,[sync],}#F' #set-option -g window-status-current-format ' #I:#W#{?pane_synchronized,[sync],}#F'
# to highlight in red when sync is on... not sure why I did this with set-window-option instead of set-option, perhaps # to highlight in red when sync is on... not sure why I did this with set-window-option instead of set-option, perhaps

View File

@ -1561,7 +1561,8 @@ screen_write_fullredraw(struct screen_write_ctx *ctx)
screen_write_collect_flush(ctx, 0, __func__); screen_write_collect_flush(ctx, 0, __func__);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1);
ttyctx.redraw_cb(&ttyctx); if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
} }
/* Trim collected items. */ /* Trim collected items. */
@ -2241,7 +2242,8 @@ screen_write_alternateon(struct screen_write_ctx *ctx, struct grid_cell *gc,
screen_alternate_on(ctx->s, gc, cursor); screen_alternate_on(ctx->s, gc, cursor);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1);
ttyctx.redraw_cb(&ttyctx); if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
} }
/* Turn alternate screen off. */ /* Turn alternate screen off. */
@ -2259,5 +2261,6 @@ screen_write_alternateoff(struct screen_write_ctx *ctx, struct grid_cell *gc,
screen_alternate_off(ctx->s, gc, cursor); screen_alternate_off(ctx->s, gc, cursor);
screen_write_initctx(ctx, &ttyctx, 1); screen_write_initctx(ctx, &ttyctx, 1);
ttyctx.redraw_cb(&ttyctx); if (ttyctx.redraw_cb != NULL)
ttyctx.redraw_cb(&ttyctx);
} }

View File

@ -708,7 +708,7 @@ session_renumber_windows(struct session *s)
struct winlink *wl, *wl1, *wl_new; struct winlink *wl, *wl1, *wl_new;
struct winlinks old_wins; struct winlinks old_wins;
struct winlink_stack old_lastw; struct winlink_stack old_lastw;
int new_idx, new_curw_idx; int new_idx, new_curw_idx, marked_idx = -1;
/* Save and replace old window list. */ /* Save and replace old window list. */
memcpy(&old_wins, &s->windows, sizeof old_wins); memcpy(&old_wins, &s->windows, sizeof old_wins);
@ -725,6 +725,8 @@ session_renumber_windows(struct session *s)
winlink_set_window(wl_new, wl->window); winlink_set_window(wl_new, wl->window);
wl_new->flags |= wl->flags & WINLINK_ALERTFLAGS; wl_new->flags |= wl->flags & WINLINK_ALERTFLAGS;
if (wl == marked_pane.wl)
marked_idx = wl_new->idx;
if (wl == s->curw) if (wl == s->curw)
new_curw_idx = wl_new->idx; new_curw_idx = wl_new->idx;
@ -741,6 +743,11 @@ session_renumber_windows(struct session *s)
} }
/* Set the current window. */ /* Set the current window. */
if (marked_idx != -1) {
marked_pane.wl = winlink_find_by_index(&s->windows, marked_idx);
if (marked_pane.wl == NULL)
server_clear_marked();
}
s->curw = winlink_find_by_index(&s->windows, new_curw_idx); s->curw = winlink_find_by_index(&s->windows, new_curw_idx);
/* Free the old winlinks (reducing window references too). */ /* Free the old winlinks (reducing window references too). */

View File

@ -263,6 +263,17 @@ status_line_size(struct client *c)
return (s->statuslines); return (s->statuslines);
} }
/* Get the prompt line number for client's session. 1 means at the bottom. */
static u_int
status_prompt_line_at(struct client *c)
{
struct session *s = c->session;
if (c->flags & (CLIENT_STATUSOFF|CLIENT_CONTROL))
return (1);
return (options_get_number(s->options, "message-line"));
}
/* Get window at window list position. */ /* Get window at window list position. */
struct style_range * struct style_range *
status_get_range(struct client *c, u_int x, u_int y) status_get_range(struct client *c, u_int x, u_int y)
@ -533,7 +544,7 @@ status_message_redraw(struct client *c)
struct session *s = c->session; struct session *s = c->session;
struct screen old_screen; struct screen old_screen;
size_t len; size_t len;
u_int lines, offset; u_int lines, offset, messageline;
struct grid_cell gc; struct grid_cell gc;
struct format_tree *ft; struct format_tree *ft;
@ -546,6 +557,10 @@ status_message_redraw(struct client *c)
lines = 1; lines = 1;
screen_init(sl->active, c->tty.sx, lines, 0); screen_init(sl->active, c->tty.sx, lines, 0);
messageline = status_prompt_line_at(c);
if (messageline > lines - 1)
messageline = lines - 1;
len = screen_write_strlen("%s", c->message_string); len = screen_write_strlen("%s", c->message_string);
if (len > c->tty.sx) if (len > c->tty.sx)
len = c->tty.sx; len = c->tty.sx;
@ -555,11 +570,11 @@ status_message_redraw(struct client *c)
format_free(ft); format_free(ft);
screen_write_start(&ctx, sl->active); screen_write_start(&ctx, sl->active);
screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines - 1); screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines);
screen_write_cursormove(&ctx, 0, lines - 1, 0); screen_write_cursormove(&ctx, 0, messageline, 0);
for (offset = 0; offset < c->tty.sx; offset++) for (offset = 0; offset < c->tty.sx; offset++)
screen_write_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
screen_write_cursormove(&ctx, 0, lines - 1, 0); screen_write_cursormove(&ctx, 0, messageline, 0);
if (c->message_ignore_styles) if (c->message_ignore_styles)
screen_write_nputs(&ctx, len, &gc, "%s", c->message_string); screen_write_nputs(&ctx, len, &gc, "%s", c->message_string);
else else
@ -695,7 +710,7 @@ status_prompt_redraw(struct client *c)
struct session *s = c->session; struct session *s = c->session;
struct screen old_screen; struct screen old_screen;
u_int i, lines, offset, left, start, width; u_int i, lines, offset, left, start, width;
u_int pcursor, pwidth; u_int pcursor, pwidth, promptline;
struct grid_cell gc, cursorgc; struct grid_cell gc, cursorgc;
struct format_tree *ft; struct format_tree *ft;
@ -708,6 +723,10 @@ status_prompt_redraw(struct client *c)
lines = 1; lines = 1;
screen_init(sl->active, c->tty.sx, lines, 0); screen_init(sl->active, c->tty.sx, lines, 0);
promptline = status_prompt_line_at(c);
if (promptline > lines - 1)
promptline = lines - 1;
ft = format_create_defaults(NULL, c, NULL, NULL, NULL); ft = format_create_defaults(NULL, c, NULL, NULL, NULL);
if (c->prompt_mode == PROMPT_COMMAND) if (c->prompt_mode == PROMPT_COMMAND)
style_apply(&gc, s->options, "message-command-style", ft); style_apply(&gc, s->options, "message-command-style", ft);
@ -723,13 +742,13 @@ status_prompt_redraw(struct client *c)
start = c->tty.sx; start = c->tty.sx;
screen_write_start(&ctx, sl->active); screen_write_start(&ctx, sl->active);
screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines - 1); screen_write_fast_copy(&ctx, &sl->screen, 0, 0, c->tty.sx, lines);
screen_write_cursormove(&ctx, 0, lines - 1, 0); screen_write_cursormove(&ctx, 0, promptline, 0);
for (offset = 0; offset < c->tty.sx; offset++) for (offset = 0; offset < c->tty.sx; offset++)
screen_write_putc(&ctx, &gc, ' '); screen_write_putc(&ctx, &gc, ' ');
screen_write_cursormove(&ctx, 0, lines - 1, 0); screen_write_cursormove(&ctx, 0, promptline, 0);
format_draw(&ctx, &gc, start, c->prompt_string, NULL, 0); format_draw(&ctx, &gc, start, c->prompt_string, NULL, 0);
screen_write_cursormove(&ctx, start, lines - 1, 0); screen_write_cursormove(&ctx, start, promptline, 0);
left = c->tty.sx - start; left = c->tty.sx - start;
if (left == 0) if (left == 0)

15
tmux.1
View File

@ -1811,7 +1811,9 @@ The following commands are supported in copy mode:
.It Li "search-forward <for>" Ta "/" Ta "" .It Li "search-forward <for>" Ta "/" Ta ""
.It Li "search-forward-incremental <for>" Ta "" Ta "C-s" .It Li "search-forward-incremental <for>" Ta "" Ta "C-s"
.It Li "search-forward-text <for>" Ta "" Ta "" .It Li "search-forward-text <for>" Ta "" Ta ""
.It Li "scroll-bottom" Ta "" Ta ""
.It Li "scroll-middle" Ta "z" Ta "" .It Li "scroll-middle" Ta "z" Ta ""
.It Li "scroll-top" Ta "" Ta ""
.It Li "search-reverse" Ta "N" Ta "N" .It Li "search-reverse" Ta "N" Ta "N"
.It Li "select-line" Ta "V" Ta "" .It Li "select-line" Ta "V" Ta ""
.It Li "select-word" Ta "" Ta "" .It Li "select-word" Ta "" Ta ""
@ -2014,7 +2016,7 @@ but a different format may be specified with
.Fl F . .Fl F .
.Tg capturep .Tg capturep
.It Xo Ic capture-pane .It Xo Ic capture-pane
.Op Fl aepPqCJN .Op Fl aAepPqCJN
.Op Fl b Ar buffer-name .Op Fl b Ar buffer-name
.Op Fl E Ar end-line .Op Fl E Ar end-line
.Op Fl S Ar start-line .Op Fl S Ar start-line
@ -2039,10 +2041,15 @@ is given, the output includes escape sequences for text and background
attributes. attributes.
.Fl C .Fl C
also escapes non-printable characters as octal \exxx. also escapes non-printable characters as octal \exxx.
.Fl T
ignores trailing positions that do not contain a character.
.Fl N .Fl N
preserves trailing spaces at each line's end and preserves trailing spaces at each line's end and
.Fl J .Fl J
preserves trailing spaces and joins any wrapped lines. preserves trailing spaces and joins any wrapped lines;
.Fl J
implies
.Fl T .
.Fl P .Fl P
captures only any output that the pane has received that is the beginning of an captures only any output that the pane has received that is the beginning of an
as-yet incomplete escape sequence. as-yet incomplete escape sequence.
@ -3876,6 +3883,10 @@ For how to specify
see the see the
.Sx STYLES .Sx STYLES
section. section.
.It Xo Ic message-line
.Op Ic 0 | 1 | 2 | 3 | 4
.Xc
Set line on which status line messages and the command prompt are shown.
.It Ic message-style Ar style .It Ic message-style Ar style
Set status line message style. Set status line message style.
This is used for messages and for the command prompt. This is used for messages and for the command prompt.

11
tmux.h
View File

@ -670,6 +670,14 @@ struct colour_palette {
#define GRID_LINE_EXTENDED 0x2 #define GRID_LINE_EXTENDED 0x2
#define GRID_LINE_DEAD 0x4 #define GRID_LINE_DEAD 0x4
/* Grid string flags. */
#define GRID_STRING_WITH_SEQUENCES 0x1
#define GRID_STRING_ESCAPE_SEQUENCES 0x2
#define GRID_STRING_TRIM_SPACES 0x4
#define GRID_STRING_USED_ONLY 0x8
#define GRID_STRING_EMPTY_CELLS 0x10
/* Cell positions. */
#define CELL_INSIDE 0 #define CELL_INSIDE 0
#define CELL_TOPBOTTOM 1 #define CELL_TOPBOTTOM 1
#define CELL_LEFTRIGHT 2 #define CELL_LEFTRIGHT 2
@ -684,6 +692,7 @@ struct colour_palette {
#define CELL_JOIN 11 #define CELL_JOIN 11
#define CELL_OUTSIDE 12 #define CELL_OUTSIDE 12
/* Cell borders. */
#define CELL_BORDERS " xqlkmjwvtun~" #define CELL_BORDERS " xqlkmjwvtun~"
#define SIMPLE_BORDERS " |-+++++++++." #define SIMPLE_BORDERS " |-+++++++++."
#define PADDED_BORDERS " " #define PADDED_BORDERS " "
@ -2807,7 +2816,7 @@ void grid_clear_lines(struct grid *, u_int, u_int, u_int);
void grid_move_lines(struct grid *, u_int, u_int, u_int, u_int); void grid_move_lines(struct grid *, u_int, u_int, u_int, u_int);
void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int, u_int); void grid_move_cells(struct grid *, u_int, u_int, u_int, u_int, u_int);
char *grid_string_cells(struct grid *, u_int, u_int, u_int, char *grid_string_cells(struct grid *, u_int, u_int, u_int,
struct grid_cell **, int, int, int, struct screen *); struct grid_cell **, int, struct screen *);
void grid_duplicate_lines(struct grid *, u_int, struct grid *, u_int, void grid_duplicate_lines(struct grid *, u_int, struct grid *, u_int,
u_int); u_int);
void grid_reflow(struct grid *, u_int); void grid_reflow(struct grid *, u_int);

View File

@ -1250,20 +1250,23 @@ window_copy_cmd_cursor_right(struct window_copy_cmd_state *cs)
return (WINDOW_COPY_CMD_NOTHING); return (WINDOW_COPY_CMD_NOTHING);
} }
/* Scroll line containing the cursor to the given position. */
static enum window_copy_cmd_action static enum window_copy_cmd_action
window_copy_cmd_scroll_middle(struct window_copy_cmd_state *cs) window_copy_cmd_scroll_to(struct window_copy_cmd_state *cs, u_int to)
{ {
struct window_mode_entry *wme = cs->wme; struct window_mode_entry *wme = cs->wme;
struct window_copy_mode_data *data = wme->data; struct window_copy_mode_data *data = wme->data;
u_int mid_value, oy, delta; u_int oy, delta;
int scroll_up; /* >0 up, <0 down */ int scroll_up; /* >0 up, <0 down */
mid_value = (screen_size_y(&data->screen) - 1) / 2; scroll_up = data->cy - to;
scroll_up = data->cy - mid_value;
delta = abs(scroll_up); delta = abs(scroll_up);
oy = screen_hsize(data->backing) + data->cy - data->oy; oy = screen_hsize(data->backing) - data->oy;
log_debug ("XXX %u %u %u %d %u", mid_value, oy, delta, scroll_up, data->oy); /*
* oy is the maximum scroll down amount, while data->oy is the maximum
* scroll up amount.
*/
if (scroll_up > 0 && data->oy >= delta) { if (scroll_up > 0 && data->oy >= delta) {
window_copy_scroll_up(wme, delta); window_copy_scroll_up(wme, delta);
data->cy -= delta; data->cy -= delta;
@ -1276,6 +1279,35 @@ window_copy_cmd_scroll_middle(struct window_copy_cmd_state *cs)
return (WINDOW_COPY_CMD_REDRAW); return (WINDOW_COPY_CMD_REDRAW);
} }
/* Scroll line containing the cursor to the bottom. */
static enum window_copy_cmd_action
window_copy_cmd_scroll_bottom(struct window_copy_cmd_state *cs)
{
struct window_copy_mode_data *data = cs->wme->data;
u_int bottom;
bottom = screen_size_y(&data->screen) - 1;
return (window_copy_cmd_scroll_to(cs, bottom));
}
/* Scroll line containing the cursor to the middle. */
static enum window_copy_cmd_action
window_copy_cmd_scroll_middle(struct window_copy_cmd_state *cs)
{
struct window_copy_mode_data *data = cs->wme->data;
u_int mid_value;
mid_value = (screen_size_y(&data->screen) - 1) / 2;
return (window_copy_cmd_scroll_to(cs, mid_value));
}
/* Scroll line containing the cursor to the top. */
static enum window_copy_cmd_action
window_copy_cmd_scroll_top(struct window_copy_cmd_state *cs)
{
return (window_copy_cmd_scroll_to(cs, 0));
}
static enum window_copy_cmd_action static enum window_copy_cmd_action
window_copy_cmd_cursor_up(struct window_copy_cmd_state *cs) window_copy_cmd_cursor_up(struct window_copy_cmd_state *cs)
{ {
@ -2794,6 +2826,12 @@ static const struct {
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_refresh_from_pane .f = window_copy_cmd_refresh_from_pane
}, },
{ .command = "scroll-bottom",
.minargs = 0,
.maxargs = 0,
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_scroll_bottom
},
{ .command = "scroll-down", { .command = "scroll-down",
.minargs = 0, .minargs = 0,
.maxargs = 0, .maxargs = 0,
@ -2812,6 +2850,12 @@ static const struct {
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS, .clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_scroll_middle .f = window_copy_cmd_scroll_middle
}, },
{ .command = "scroll-top",
.minargs = 0,
.maxargs = 0,
.clear = WINDOW_COPY_CMD_CLEAR_ALWAYS,
.f = window_copy_cmd_scroll_top
},
{ .command = "scroll-up", { .command = "scroll-up",
.minargs = 0, .minargs = 0,
.maxargs = 0, .maxargs = 0,