mirror of
https://github.com/tmux/tmux.git
synced 2026-05-30 14:16:18 +00:00
Merge branch 'master' into floating_panes
This commit is contained in:
@@ -70,12 +70,6 @@ const struct cmd_entry cmd_split_window_entry = {
|
||||
.exec = cmd_split_window_exec
|
||||
};
|
||||
|
||||
enum new_pane_mode {
|
||||
FLOATING,
|
||||
TILED,
|
||||
NONE,
|
||||
};
|
||||
|
||||
static struct layout_cell *
|
||||
cmd_split_window_get_floating_layout_cell(struct cmdq_item *item,
|
||||
struct args *args, struct window *w)
|
||||
@@ -163,44 +157,15 @@ cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item,
|
||||
struct layout_cell *lc = NULL;
|
||||
char *cause = NULL;
|
||||
int size;
|
||||
u_int curval = 0;
|
||||
|
||||
if (wp->flags & PANE_FLOATING) {
|
||||
cmdq_error(item, "can't split a floating pane");
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'h'))
|
||||
type = LAYOUT_LEFTRIGHT;
|
||||
|
||||
/* If the 'p' flag is dropped then this bit can be moved into 'l'. */
|
||||
if (args_has(args, 'l') || args_has(args, 'p')) {
|
||||
if (args_has(args, 'f')) {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = w->sy;
|
||||
else
|
||||
curval = w->sx;
|
||||
} else {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = wp->sy;
|
||||
else
|
||||
curval = wp->sx;
|
||||
}
|
||||
}
|
||||
|
||||
size = -1;
|
||||
if (args_has(args, 'l')) {
|
||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||
item, &cause);
|
||||
} else if (args_has(args, 'p')) {
|
||||
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||
&cause);
|
||||
if (cause == NULL)
|
||||
size = curval * size / 100;
|
||||
}
|
||||
if (cause != NULL) {
|
||||
cmdq_error(item, "size %s", cause);
|
||||
if (window_pane_tile_geometry(w, wp, &size, &flags, &type, item, args,
|
||||
&cause) != 0) {
|
||||
cmdq_error(item, "invalid tiled geometry %s", cause);
|
||||
free(cause);
|
||||
return (NULL);
|
||||
}
|
||||
@@ -209,7 +174,6 @@ cmd_split_window_get_tiled_layout_cell(struct cmdq_item *item,
|
||||
lc = layout_split_pane(wp, type, size, flags);
|
||||
if (lc == NULL)
|
||||
cmdq_error(item, "no space for new pane");
|
||||
|
||||
return (lc);
|
||||
}
|
||||
|
||||
@@ -232,7 +196,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
char *cause = NULL, *cp;
|
||||
struct args_value *av;
|
||||
u_int count = args_count(args);
|
||||
enum new_pane_mode pane_mode = NONE;
|
||||
enum { FLOATING, TILED, NONE } pane_mode;
|
||||
|
||||
if (args_has(args, 'M')) {
|
||||
if (strcasecmp(args_get(args, 'M'), "f") == 0)
|
||||
@@ -250,7 +214,7 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
|
||||
input = (args_has(args, 'I') && count == 0);
|
||||
|
||||
flags = pane_mode == FLOATING ? SPAWN_FLOATING : 0;
|
||||
flags = (pane_mode == FLOATING) ? SPAWN_FLOATING : 0;
|
||||
if (args_has(args, 'b'))
|
||||
flags |= SPAWN_BEFORE;
|
||||
if (args_has(args, 'f'))
|
||||
@@ -258,13 +222,12 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (input || (count == 1 && *args_string(args, 0) == '\0'))
|
||||
flags |= SPAWN_EMPTY;
|
||||
|
||||
|
||||
if (pane_mode == FLOATING)
|
||||
lc = cmd_split_window_get_floating_layout_cell(item, args, w);
|
||||
else if (pane_mode == TILED)
|
||||
else if (pane_mode == TILED) {
|
||||
lc = cmd_split_window_get_tiled_layout_cell(item, args, w, wp,
|
||||
flags);
|
||||
else {
|
||||
} else {
|
||||
cmdq_error(item, "unrecognized pane mode '%s'",
|
||||
args_get(args, 'M'));
|
||||
return (CMD_RETURN_ERROR);
|
||||
@@ -315,7 +278,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
}
|
||||
options_set_string(new_wp->options, "window-active-style", 0,
|
||||
"%s", style);
|
||||
new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED|PANE_THEMECHANGED);
|
||||
new_wp->flags |= (PANE_REDRAW|PANE_STYLECHANGED|
|
||||
PANE_THEMECHANGED);
|
||||
}
|
||||
style = args_get(args, 'S');
|
||||
if (style != NULL) {
|
||||
@@ -329,7 +293,8 @@ cmd_split_window_exec(struct cmd *self, struct cmdq_item *item)
|
||||
if (style != NULL) {
|
||||
if (options_set_string(new_wp->options, "pane-border-style", 0,
|
||||
"%s", style) == NULL) {
|
||||
cmdq_error(item, "bad inactive border style: %s", style);
|
||||
cmdq_error(item, "bad inactive border style: %s",
|
||||
style);
|
||||
return (CMD_RETURN_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
8
file.c
8
file.c
@@ -399,6 +399,10 @@ file_read(struct client *c, const char *path, client_file_cb cb, void *cbdata)
|
||||
}
|
||||
for (;;) {
|
||||
size = fread(buffer, 1, sizeof buffer, f);
|
||||
if (ferror(f)) {
|
||||
cf->error = errno;
|
||||
goto done;
|
||||
}
|
||||
if (evbuffer_add(cf->buffer, buffer, size) != 0) {
|
||||
cf->error = ENOMEM;
|
||||
goto done;
|
||||
@@ -671,7 +675,7 @@ file_write_close(struct client_files *files, struct imsg *imsg)
|
||||
|
||||
/* Client file read error callback. */
|
||||
static void
|
||||
file_read_error_callback(__unused struct bufferevent *bev, __unused short what,
|
||||
file_read_error_callback(__unused struct bufferevent *bev, short what,
|
||||
void *arg)
|
||||
{
|
||||
struct client_file *cf = arg;
|
||||
@@ -680,7 +684,7 @@ file_read_error_callback(__unused struct bufferevent *bev, __unused short what,
|
||||
log_debug("read error file %d", cf->stream);
|
||||
|
||||
msg.stream = cf->stream;
|
||||
msg.error = 0;
|
||||
msg.error = (what & EVBUFFER_ERROR) ? EIO : 0;
|
||||
proc_send(cf->peer, MSG_READ_DONE, -1, &msg, sizeof msg);
|
||||
|
||||
bufferevent_free(cf->event);
|
||||
|
||||
12
format.c
12
format.c
@@ -2059,8 +2059,10 @@ format_cb_pane_at_right(struct format_tree *ft)
|
||||
static void *
|
||||
format_cb_pane_bottom(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%d", ft->wp->yoff + (int)ft->wp->sy - 1));
|
||||
struct window_pane *wp = ft->wp;
|
||||
|
||||
if (wp != NULL)
|
||||
return (format_printf("%d", wp->yoff + (int)wp->sy - 1));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@@ -2357,8 +2359,10 @@ format_cb_pane_pb_state(struct format_tree *ft)
|
||||
static void *
|
||||
format_cb_pane_right(struct format_tree *ft)
|
||||
{
|
||||
if (ft->wp != NULL)
|
||||
return (format_printf("%d", ft->wp->xoff + (int)ft->wp->sx - 1));
|
||||
struct window_pane *wp = ft->wp;
|
||||
|
||||
if (wp != NULL)
|
||||
return (format_printf("%d", wp->xoff + (int)wp->sx - 1));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,15 +45,20 @@ grid_reader_line_length(struct grid_reader *gr)
|
||||
|
||||
/* Move cursor forward one position. */
|
||||
void
|
||||
grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all)
|
||||
grid_reader_cursor_right(struct grid_reader *gr, int wrap, int all, int onemore)
|
||||
{
|
||||
u_int px;
|
||||
struct grid_cell gc;
|
||||
|
||||
if (all)
|
||||
px = gr->gd->sx;
|
||||
else
|
||||
else if (onemore)
|
||||
px = grid_reader_line_length(gr);
|
||||
else {
|
||||
px = grid_reader_line_length(gr);
|
||||
if (px != 0)
|
||||
px--;
|
||||
}
|
||||
|
||||
if (wrap && gr->cx >= px && gr->cy < gr->gd->hsize + gr->gd->sy - 1) {
|
||||
grid_reader_cursor_start_of_line(gr, 0);
|
||||
|
||||
@@ -62,29 +62,26 @@ char *
|
||||
layout_dump(struct window *w, struct layout_cell *root)
|
||||
{
|
||||
char layout[8192], *out;
|
||||
int braket;
|
||||
int bracket = 0;
|
||||
struct window_pane *wp;
|
||||
|
||||
*layout = '\0';
|
||||
if (layout_append(root, layout, sizeof layout) != 0)
|
||||
return (NULL);
|
||||
|
||||
braket = 0;
|
||||
TAILQ_FOREACH(wp, &w->z_index, zentry) {
|
||||
if (~wp->flags & PANE_FLOATING)
|
||||
break;
|
||||
if (!braket) {
|
||||
strcat(layout, "<");
|
||||
braket = 1;
|
||||
if (!bracket) {
|
||||
strlcat(layout, "<", sizeof layout);
|
||||
bracket = 1;
|
||||
}
|
||||
if (layout_append(wp->layout_cell, layout, sizeof layout) != 0)
|
||||
return (NULL);
|
||||
strcat(layout, ",");
|
||||
strlcat(layout, ",", sizeof layout);
|
||||
}
|
||||
if (braket) {
|
||||
/* Overwrite the trailing ','. */
|
||||
if (bracket)
|
||||
layout[strlen(layout) - 1] = '>';
|
||||
}
|
||||
|
||||
xasprintf(&out, "%04hx,%s", layout_checksum(layout), layout);
|
||||
return (out);
|
||||
@@ -146,8 +143,8 @@ layout_check(struct layout_cell *lc)
|
||||
u_int n = 0;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
case LAYOUT_FLOATING:
|
||||
case LAYOUT_WINDOWPANE:
|
||||
break;
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry) {
|
||||
@@ -213,9 +210,10 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
}
|
||||
|
||||
/* Check this window will fit into the layout. */
|
||||
for (;;) {
|
||||
npanes = window_count_panes(w, 1);
|
||||
for (;;) {
|
||||
ncells = layout_count_cells(tiled_lc);
|
||||
if (floating_lc != NULL)
|
||||
ncells += layout_count_cells(floating_lc);
|
||||
if (npanes > ncells) {
|
||||
/* Modify this to open a new pane */
|
||||
@@ -228,9 +226,9 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
|
||||
/*
|
||||
* Fewer panes than cells - close floating panes first
|
||||
* then close the bottom right until.
|
||||
* then close the bottom right until none remain.
|
||||
*/
|
||||
if (floating_lc && ! TAILQ_EMPTY(&floating_lc->cells)) {
|
||||
if (floating_lc != NULL && !TAILQ_EMPTY(&floating_lc->cells)) {
|
||||
lcchild = TAILQ_FIRST(&floating_lc->cells);
|
||||
layout_destroy_cell(w, lcchild, &floating_lc);
|
||||
} else {
|
||||
@@ -266,8 +264,6 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
}
|
||||
if (tiled_lc->type != LAYOUT_WINDOWPANE &&
|
||||
(tiled_lc->sx != sx || tiled_lc->sy != sy)) {
|
||||
log_debug("fix layout %u,%u to %u,%u", tiled_lc->sx,
|
||||
tiled_lc->sy, sx,sy);
|
||||
layout_print_cell(tiled_lc, __func__, 0);
|
||||
tiled_lc->sx = sx - 1; tiled_lc->sy = sy - 1;
|
||||
}
|
||||
@@ -288,14 +284,17 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
|
||||
/* Assign the panes into the cells. */
|
||||
wp = TAILQ_FIRST(&w->panes);
|
||||
if (tiled_lc != NULL)
|
||||
layout_assign(&wp, tiled_lc, 0);
|
||||
layout_assign(&wp, floating_lc, 1);
|
||||
if (floating_lc != NULL)
|
||||
layout_assign(&wp, floating_lc, PANE_FLOATING);
|
||||
|
||||
/* Fix z_indexes. */
|
||||
/* Fix z indexes. */
|
||||
while (!TAILQ_EMPTY(&w->z_index)) {
|
||||
wp = TAILQ_FIRST(&w->z_index);
|
||||
TAILQ_REMOVE(&w->z_index, wp, zentry);
|
||||
}
|
||||
if (floating_lc != NULL)
|
||||
layout_fix_zindexes(w, floating_lc);
|
||||
layout_fix_zindexes(w, tiled_lc);
|
||||
|
||||
@@ -303,11 +302,10 @@ layout_parse(struct window *w, const char *layout, char **cause)
|
||||
layout_fix_offsets(w);
|
||||
layout_fix_panes(w, NULL);
|
||||
recalculate_sizes();
|
||||
|
||||
layout_print_cell(tiled_lc, __func__, 0);
|
||||
layout_print_cell(floating_lc, __func__, 0);
|
||||
|
||||
/* Free the floating layout cell, no longer needed. */
|
||||
if (floating_lc != NULL)
|
||||
layout_free_cell(floating_lc);
|
||||
|
||||
notify_window("window-layout-changed", w);
|
||||
@@ -322,7 +320,7 @@ fail:
|
||||
|
||||
/* Assign panes into cells. */
|
||||
static void
|
||||
layout_assign(struct window_pane **wp, struct layout_cell *lc, int floating)
|
||||
layout_assign(struct window_pane **wp, struct layout_cell *lc, int flags)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
|
||||
@@ -332,16 +330,14 @@ layout_assign(struct window_pane **wp, struct layout_cell *lc, int floating)
|
||||
switch (lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
layout_make_leaf(lc, *wp);
|
||||
if (floating) {
|
||||
(*wp)->flags |= PANE_FLOATING;
|
||||
}
|
||||
(*wp)->flags |= flags;
|
||||
*wp = TAILQ_NEXT(*wp, entry);
|
||||
return;
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
case LAYOUT_FLOATING:
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||
layout_assign(wp, lcchild, 1);
|
||||
layout_assign(wp, lcchild, PANE_FLOATING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -394,7 +390,6 @@ layout_construct_cell(struct layout_cell *lcparent, const char **layout)
|
||||
return (lc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Given a character string layout, recursively construct cells.
|
||||
* Possible return values:
|
||||
|
||||
38
layout.c
38
layout.c
@@ -50,6 +50,7 @@ static struct layout_cell *layout_active_neighbour(struct layout_cell *, int);
|
||||
void layout_redistribute_cells(struct window *, struct layout_cell *,
|
||||
enum layout_type);
|
||||
|
||||
/* Create a new layout cell. */
|
||||
struct layout_cell *
|
||||
layout_create_cell(struct layout_cell *lcparent)
|
||||
{
|
||||
@@ -72,6 +73,7 @@ layout_create_cell(struct layout_cell *lcparent)
|
||||
return (lc);
|
||||
}
|
||||
|
||||
/* Free a layout cell. */
|
||||
void
|
||||
layout_free_cell(struct layout_cell *lc)
|
||||
{
|
||||
@@ -87,11 +89,11 @@ layout_free_cell(struct layout_cell *lc)
|
||||
}
|
||||
break;
|
||||
case LAYOUT_FLOATING:
|
||||
/* A Floating layout cell is only used temporarily
|
||||
* while select-layout constructs a layout.
|
||||
* Cleave the children from the temp layout, then
|
||||
* free temp floating layout cell. Each floating
|
||||
* pane has stub layout.
|
||||
/*
|
||||
* A floating layout cell is only used temporarily while
|
||||
* select-layout constructs a layout. Remove the children from
|
||||
* the temporary layout, then free temporary floating layout
|
||||
* cell. Each floating pane has stub layout.
|
||||
*/
|
||||
while (!TAILQ_EMPTY(&lc->cells)) {
|
||||
lcchild = TAILQ_FIRST(&lc->cells);
|
||||
@@ -110,6 +112,7 @@ layout_free_cell(struct layout_cell *lc)
|
||||
free(lc);
|
||||
}
|
||||
|
||||
/* Log a cell. */
|
||||
void
|
||||
layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
{
|
||||
@@ -151,6 +154,7 @@ layout_print_cell(struct layout_cell *lc, const char *hdr, u_int n)
|
||||
}
|
||||
}
|
||||
|
||||
/* Search for a cell by the border position. */
|
||||
struct layout_cell *
|
||||
layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||
{
|
||||
@@ -192,9 +196,9 @@ layout_search_by_border(struct layout_cell *lc, u_int x, u_int y)
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Set cell size. */
|
||||
void
|
||||
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff,
|
||||
int yoff)
|
||||
layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff, int yoff)
|
||||
{
|
||||
lc->sx = sx;
|
||||
lc->sy = sy;
|
||||
@@ -203,6 +207,7 @@ layout_set_size(struct layout_cell *lc, u_int sx, u_int sy, int xoff,
|
||||
lc->yoff = yoff;
|
||||
}
|
||||
|
||||
/* Make a cell a leaf cell. */
|
||||
void
|
||||
layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
||||
{
|
||||
@@ -214,6 +219,7 @@ layout_make_leaf(struct layout_cell *lc, struct window_pane *wp)
|
||||
lc->wp = wp;
|
||||
}
|
||||
|
||||
/* Make a cell a node cell. */
|
||||
void
|
||||
layout_make_node(struct layout_cell *lc, enum layout_type type)
|
||||
{
|
||||
@@ -372,7 +378,7 @@ layout_fix_panes(struct window *w, struct window_pane *skip)
|
||||
sx = lc->sx;
|
||||
sy = lc->sy;
|
||||
|
||||
if (~wp->flags & PANE_FLOATING &&
|
||||
if ((~wp->flags & PANE_FLOATING) &&
|
||||
layout_add_horizontal_border(w, lc, status)) {
|
||||
if (status == PANE_STATUS_TOP)
|
||||
wp->yoff++;
|
||||
@@ -412,7 +418,7 @@ u_int
|
||||
layout_count_cells(struct layout_cell *lc)
|
||||
{
|
||||
struct layout_cell *lcchild;
|
||||
u_int count;
|
||||
u_int count = 0;
|
||||
|
||||
switch (lc->type) {
|
||||
case LAYOUT_WINDOWPANE:
|
||||
@@ -420,7 +426,6 @@ layout_count_cells(struct layout_cell *lc)
|
||||
case LAYOUT_LEFTRIGHT:
|
||||
case LAYOUT_TOPBOTTOM:
|
||||
case LAYOUT_FLOATING:
|
||||
count = 0;
|
||||
TAILQ_FOREACH(lcchild, &lc->cells, entry)
|
||||
count += layout_count_cells(lcchild);
|
||||
return (count);
|
||||
@@ -637,6 +642,13 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
return;
|
||||
}
|
||||
|
||||
/* A floating cell need only be removed from the parent. */
|
||||
if (lcparent->type == LAYOUT_FLOATING) {
|
||||
TAILQ_REMOVE(&lcparent->cells, lc, entry);
|
||||
layout_free_cell(lc);
|
||||
return;
|
||||
}
|
||||
|
||||
/* In tiled layouts, merge the space into the previous or next cell. */
|
||||
if (lcparent->type != LAYOUT_FLOATING) {
|
||||
is_minimised = (lc->wp != NULL && (lc->wp->flags & PANE_MINIMISED));
|
||||
@@ -668,7 +680,9 @@ layout_destroy_cell(struct window *w, struct layout_cell *lc,
|
||||
|
||||
lc->parent = lcparent->parent;
|
||||
if (lc->parent == NULL) {
|
||||
lc->xoff = 0; lc->yoff = 0;
|
||||
lc->xoff = 0;
|
||||
lc->yoff = 0;
|
||||
|
||||
/*
|
||||
* If the sole remaining child is a minimised
|
||||
* WINDOWPANE, its stored size may be stale (it never
|
||||
@@ -754,6 +768,7 @@ layout_unminimise_cell(struct window *w, struct layout_cell *lc)
|
||||
layout_redistribute_cells(w, lcparent, lcparent->type);
|
||||
}
|
||||
|
||||
/* Initialize layout for pane. */
|
||||
void
|
||||
layout_init(struct window *w, struct window_pane *wp)
|
||||
{
|
||||
@@ -765,6 +780,7 @@ layout_init(struct window *w, struct window_pane *wp)
|
||||
layout_fix_panes(w, NULL);
|
||||
}
|
||||
|
||||
/* Free layout for pane. */
|
||||
void
|
||||
layout_free(struct window *w)
|
||||
{
|
||||
|
||||
@@ -1066,6 +1066,7 @@ server_client_is_bracket_paste(struct client *c, key_code key)
|
||||
{
|
||||
if ((key & KEYC_MASK_KEY) == KEYC_PASTE_START) {
|
||||
c->flags |= CLIENT_BRACKETPASTING;
|
||||
c->paste_time = current_time;
|
||||
log_debug("%s: bracket paste on", c->name);
|
||||
return (0);
|
||||
}
|
||||
@@ -1099,6 +1100,7 @@ server_client_is_assume_paste(struct client *c)
|
||||
if (c->flags & CLIENT_ASSUMEPASTING)
|
||||
return (1);
|
||||
c->flags |= CLIENT_ASSUMEPASTING;
|
||||
c->paste_time = current_time;
|
||||
log_debug("%s: assume paste on", c->name);
|
||||
return (0);
|
||||
}
|
||||
@@ -2591,6 +2593,13 @@ server_client_dispatch_identify(struct client *c, struct imsg *imsg)
|
||||
c->out_fd = -1;
|
||||
}
|
||||
|
||||
/* If pasting has taken too long, turn it off. */
|
||||
if (c->flags & (CLIENT_BRACKETPASTING|CLIENT_ASSUMEPASTING) &&
|
||||
current_time - c->paste_time > CLIENT_PASTE_TIME_LIMIT) {
|
||||
log_debug("%s: paste time limit exceeded", c->name);
|
||||
c->flags &= ~(CLIENT_BRACKETPASTING|CLIENT_ASSUMEPASTING);
|
||||
}
|
||||
|
||||
/*
|
||||
* If this is the first client, load configuration files. Any later
|
||||
* clients are allowed to continue with their command even if the
|
||||
|
||||
4
sort.c
4
sort.c
@@ -425,6 +425,10 @@ sort_get_clients(u_int *n, struct sort_criteria *sort_crit)
|
||||
|
||||
i = 0;
|
||||
TAILQ_FOREACH(c, &clients, entry) {
|
||||
if (c->flags & CLIENT_UNATTACHEDFLAGS)
|
||||
continue;
|
||||
if (~c->flags & CLIENT_ATTACHED)
|
||||
continue;
|
||||
if (lsz <= i) {
|
||||
lsz += 100;
|
||||
l = xreallocarray(l, lsz, sizeof *l);
|
||||
|
||||
163
tmux.1
163
tmux.1
@@ -940,6 +940,37 @@ or
|
||||
.Ic list\-panes
|
||||
commands.
|
||||
.Pp
|
||||
.Em target\-session ,
|
||||
.Em target\-window
|
||||
or
|
||||
.Em target\-pane
|
||||
each denote the
|
||||
.Ql type
|
||||
of target the command needs to work on.
|
||||
If a target is not explicitly qualified using
|
||||
.Ql \&:
|
||||
and
|
||||
.Ql \&. ,
|
||||
.Nm
|
||||
will pick what seems to be the best choice available.
|
||||
For example, if a
|
||||
.Em target-pane
|
||||
of
|
||||
.Ql 1
|
||||
is used with a current window that has only one pane,
|
||||
.Nm
|
||||
knows that the
|
||||
.Ql 1
|
||||
cannot mean a pane, so it will look for the active pane in window 1, or the
|
||||
active pane in the current window in session 1.
|
||||
Only if none of these are present will it report an error.
|
||||
If it is important that a specific pane, window or session always be used,
|
||||
such as from a script, the target should be fully qualified (for example a
|
||||
.Em target-pane
|
||||
of
|
||||
.Ql -t:.1 ) ,
|
||||
or pane, window or session IDs should be used.
|
||||
.Pp
|
||||
.Ar shell\-command
|
||||
arguments are
|
||||
.Xr sh 1
|
||||
@@ -3329,46 +3360,22 @@ but a different format may be specified with
|
||||
.Tg newp
|
||||
.It Xo Ic new\-pane
|
||||
.Op Fl bdefhIkPvZ
|
||||
.Op Fl c Ar start-directory
|
||||
.Op Fl c Ar start\-directory
|
||||
.Op Fl e Ar environment
|
||||
.Op Fl F Ar format
|
||||
.Op Fl l Ar size
|
||||
.Op Fl m Ar message
|
||||
.Op Fl M Ar mode
|
||||
.Op Fl p Ar percentage
|
||||
.Op Fl R Ar inactive-border-style
|
||||
.Op Fl R Ar inactive\-border\-style
|
||||
.Op Fl s Ar style
|
||||
.Op Fl S Ar active-border-style
|
||||
.Op Fl t Ar target-pane
|
||||
.Op Fl x Ar width
|
||||
.Op Fl X Ar x-position
|
||||
.Op Fl y Ar height
|
||||
.Op Fl Y Ar y-position
|
||||
.Op Ar shell-command Op Ar argument ...
|
||||
.Op Fl S Ar active\-border\-style
|
||||
.Op Fl t Ar target\-pane
|
||||
.Op Ar shell\-command Op Ar argument ...
|
||||
.Xc
|
||||
.D1 Pq alias: Ic newp
|
||||
Create a new pane.
|
||||
A
|
||||
.Ar mode
|
||||
may be specified with the
|
||||
.Fl M
|
||||
option and must be followed by one of the following special values:
|
||||
.Bl -column "XXXXX" -offset indent
|
||||
.It Sy "Value" Ta Sy "Meaning"
|
||||
.It Li "f" Ta "floating pane above the current layout"
|
||||
.It Li "t" Ta "tiled into the layout by splitting a pane"
|
||||
.El
|
||||
.Pp
|
||||
If no
|
||||
.Ar mode
|
||||
is specified,
|
||||
.Ic f
|
||||
is assumed.
|
||||
When creating a tiled pane, a target pane may be specified with
|
||||
.Fl t .
|
||||
Note that some options will only affect one
|
||||
.Ar mode .
|
||||
.Pp
|
||||
The new pane is created by splitting
|
||||
.Ar target\-pane .
|
||||
If
|
||||
.Fl d
|
||||
is given, the session does not make the new pane the current pane.
|
||||
@@ -3381,48 +3388,7 @@ sets the border style when the pane is active and
|
||||
.Fl R
|
||||
sets the border style when the pane is inactive (see
|
||||
.Sx STYLES ) .
|
||||
.Fl k
|
||||
keeps the pane open after the optional
|
||||
.Ar shell-command
|
||||
exits and waits for a keypress (any non-mouse key) before closing it.
|
||||
The message shown is controlled by the
|
||||
.Ic remain-on-exit-format
|
||||
option.
|
||||
.Fl m Ar message
|
||||
is equivalent to
|
||||
.Fl k
|
||||
but also sets the
|
||||
.Ic remain-on-exit-format
|
||||
option for this pane to
|
||||
.Ar message .
|
||||
An empty
|
||||
.Ar shell-command
|
||||
(\[aq]\[aq]) will create a pane with no command running in it.
|
||||
The
|
||||
.Fl I
|
||||
flag (if
|
||||
.Ar shell-command
|
||||
is not specified or empty)
|
||||
will create an empty pane and forward any output from stdin to it.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
$ make 2>&1|tmux splitw \-dI &
|
||||
.Ed
|
||||
.Pp
|
||||
For floating panes, the following options are availible:
|
||||
The
|
||||
.Fl x ,
|
||||
.Fl y ,
|
||||
.Fl X ,
|
||||
and
|
||||
.Fl Y
|
||||
options set the width, height, and position of the pane.
|
||||
If not given, the pane is sized to half the window dimensions and offset from
|
||||
the previous floating pane.
|
||||
These four options may be followed by '%' to specify a percentage of the
|
||||
current window dimensions.
|
||||
.Pp
|
||||
For tiled panes, the following options are availible:
|
||||
.Fl h
|
||||
does a horizontal split and
|
||||
.Fl v
|
||||
@@ -3437,6 +3403,8 @@ columns (for horizontal split);
|
||||
may be followed by
|
||||
.Ql %
|
||||
to specify a percentage of the available space.
|
||||
.Fl p
|
||||
is a shorthand option for this.
|
||||
The
|
||||
.Fl b
|
||||
option causes the new pane to be created to the left of or above
|
||||
@@ -3449,9 +3417,37 @@ or full window width (with
|
||||
.Fl v ) ,
|
||||
instead of splitting the active pane.
|
||||
.Pp
|
||||
.Fl k
|
||||
keeps the pane open after the optional
|
||||
.Ar shell\-command
|
||||
exits and waits for a key to be pressed before closing it.
|
||||
The message shown is controlled by the
|
||||
.Ic remain\-on\-exit\-format
|
||||
option.
|
||||
.Fl m Ar message
|
||||
is equivalent to
|
||||
.Fl k
|
||||
but also sets the
|
||||
.Ic remain\-on\-exit\-format
|
||||
option for this pane to
|
||||
.Ar message .
|
||||
.Pp
|
||||
An empty
|
||||
.Ar shell\-command
|
||||
(\[aq]\[aq]) will create a pane with no command running in it.
|
||||
The
|
||||
.Fl I
|
||||
flag (if
|
||||
.Ar shell\-command
|
||||
is not specified or empty)
|
||||
will create an empty pane and forward any output from stdin to it.
|
||||
For example:
|
||||
.Bd -literal -offset indent
|
||||
$ make 2>&1|tmux splitw \-dI &
|
||||
.Ed
|
||||
.Pp
|
||||
All other options have the same meaning as for the
|
||||
.Ic new-window
|
||||
command.
|
||||
.Ic new\-window
|
||||
.Tg nextl
|
||||
.It Ic next\-layout Op Fl t Ar target\-window
|
||||
.D1 Pq alias: Ic nextl
|
||||
@@ -3777,26 +3773,21 @@ the command behaves like
|
||||
.Tg splitw
|
||||
.It Xo Ic split\-window
|
||||
.Op Fl bdefhIkPvZ
|
||||
.Op Fl c Ar start-directory
|
||||
.Op Fl c Ar start\-directory
|
||||
.Op Fl e Ar environment
|
||||
.Op Fl F Ar format
|
||||
.Op Fl l Ar size
|
||||
.Op Fl m Ar message
|
||||
.Op Fl M Ar mode
|
||||
.Op Fl p Ar percentage
|
||||
.Op Fl R Ar inactive-border-style
|
||||
.Op Fl R Ar inactive\-border\-style
|
||||
.Op Fl s Ar style
|
||||
.Op Fl S Ar active-border-style
|
||||
.Op Fl t Ar target-pane
|
||||
.Op Fl x Ar width
|
||||
.Op Fl X Ar x-position
|
||||
.Op Fl y Ar height
|
||||
.Op Fl Y Ar y-position
|
||||
.Op Ar shell-command Op Ar argument ...
|
||||
.Op Fl S Ar active\-border\-style
|
||||
.Op Fl t Ar target\-pane
|
||||
.Op Ar shell\-command Op Ar argument ...
|
||||
.Xc
|
||||
.D1 Pq alias: Ic splitw
|
||||
Creates a new pane.
|
||||
Default behavior is to split the pane in a tiled layout.
|
||||
Creates a new pane by splitting
|
||||
.Ar target\-pane .
|
||||
Shares behavior with
|
||||
.Ic new\-pane .
|
||||
.Pp
|
||||
|
||||
9
tmux.h
9
tmux.h
@@ -2000,6 +2000,9 @@ struct client_window {
|
||||
};
|
||||
RB_HEAD(client_windows, client_window);
|
||||
|
||||
/* Maximum time to be pasting. */
|
||||
#define CLIENT_PASTE_TIME_LIMIT 5
|
||||
|
||||
/* Client connection. */
|
||||
typedef int (*prompt_input_cb)(struct client *, void *, const char *, int);
|
||||
typedef void (*prompt_free_cb)(void *);
|
||||
@@ -2139,6 +2142,7 @@ struct client {
|
||||
|
||||
struct key_table *keytable;
|
||||
key_code last_key;
|
||||
time_t paste_time;
|
||||
|
||||
uint64_t redraw_panes;
|
||||
uint64_t redraw_scrollbars;
|
||||
@@ -3225,7 +3229,7 @@ void grid_reader_start(struct grid_reader *, struct grid *, u_int, u_int);
|
||||
void grid_reader_get_cursor(struct grid_reader *, u_int *, u_int *);
|
||||
u_int grid_reader_line_length(struct grid_reader *);
|
||||
int grid_reader_in_set(struct grid_reader *, const char *);
|
||||
void grid_reader_cursor_right(struct grid_reader *, int, int);
|
||||
void grid_reader_cursor_right(struct grid_reader *, int, int, int);
|
||||
void grid_reader_cursor_left(struct grid_reader *, int);
|
||||
void grid_reader_cursor_down(struct grid_reader *);
|
||||
void grid_reader_cursor_up(struct grid_reader *);
|
||||
@@ -3487,6 +3491,9 @@ enum client_theme window_pane_get_theme(struct window_pane *);
|
||||
void window_pane_send_theme_update(struct window_pane *);
|
||||
struct style_range *window_pane_border_status_get_range(struct window_pane *,
|
||||
u_int, u_int);
|
||||
int window_pane_tile_geometry(struct window *,
|
||||
struct window_pane *, int *, int *, enum layout_type *,
|
||||
struct cmdq_item *, struct args *, char **);
|
||||
|
||||
/* layout.c */
|
||||
u_int layout_count_cells(struct layout_cell *);
|
||||
|
||||
57
tty-draw.c
57
tty-draw.c
@@ -29,7 +29,6 @@ enum tty_draw_line_state {
|
||||
TTY_DRAW_LINE_NEW2,
|
||||
TTY_DRAW_LINE_EMPTY,
|
||||
TTY_DRAW_LINE_SAME,
|
||||
TTY_DRAW_LINE_PAD,
|
||||
TTY_DRAW_LINE_DONE
|
||||
};
|
||||
static const char* tty_draw_line_states[] = {
|
||||
@@ -39,7 +38,6 @@ static const char* tty_draw_line_states[] = {
|
||||
"NEW2",
|
||||
"EMPTY",
|
||||
"SAME",
|
||||
"PAD",
|
||||
"DONE"
|
||||
};
|
||||
|
||||
@@ -100,25 +98,6 @@ tty_draw_line_clear(struct tty *tty, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
}
|
||||
|
||||
/* Is this cell empty? */
|
||||
static u_int
|
||||
tty_draw_line_get_empty(const struct grid_cell *gc, u_int nx)
|
||||
{
|
||||
u_int empty = 0;
|
||||
|
||||
if (gc->data.width != 1 && gc->data.width > nx)
|
||||
empty = nx;
|
||||
else if (gc->attr == 0 && gc->link == 0) {
|
||||
if (gc->flags & GRID_FLAG_CLEARED)
|
||||
empty = 1;
|
||||
else if (gc->flags & GRID_FLAG_TAB)
|
||||
empty = gc->data.width;
|
||||
else if (gc->data.size == 1 && *gc->data.data == ' ')
|
||||
empty = 1;
|
||||
}
|
||||
return (empty);
|
||||
}
|
||||
|
||||
/* Draw a line from screen to tty. */
|
||||
void
|
||||
tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
@@ -239,6 +218,9 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
next_state = TTY_DRAW_LINE_DONE;
|
||||
gcp = &grid_default_cell;
|
||||
} else {
|
||||
if (i > nx)
|
||||
fatalx("position %u > width %u", i, nx);
|
||||
|
||||
/* Get the current cell. */
|
||||
grid_view_get_cell(gd, px + i, py, &gc);
|
||||
|
||||
@@ -253,20 +235,36 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
|
||||
/* Work out the the empty width. */
|
||||
if (px >= ex || i >= ex - px)
|
||||
empty = 1;
|
||||
else if (gcp->bg != last.bg)
|
||||
empty = 0;
|
||||
else
|
||||
empty = tty_draw_line_get_empty(gcp, nx - i);
|
||||
if (px >= ex || i >= ex - px) {
|
||||
/* Outside the area being drawn. */
|
||||
empty = 1;
|
||||
} else if (gcp->data.width > nx - i) {
|
||||
/* Wide character that has been truncated. */
|
||||
empty = nx - i;
|
||||
} else if (gcp->flags & GRID_FLAG_PADDING) {
|
||||
/* Orphan padding cell. */
|
||||
empty = 1;
|
||||
} else if (gcp->bg == last.bg && gcp->attr == 0 &&
|
||||
gcp->link == 0) {
|
||||
/*
|
||||
* No attributes - empty if cleared, tab or
|
||||
* space.
|
||||
*/
|
||||
if (gcp->flags & GRID_FLAG_CLEARED)
|
||||
empty = 1;
|
||||
else if (gcp->flags & GRID_FLAG_TAB)
|
||||
empty = gcp->data.width;
|
||||
else if (gcp->data.size == 1 &&
|
||||
*gcp->data.data == ' ')
|
||||
empty = 1;
|
||||
}
|
||||
|
||||
/* Work out the next state. */
|
||||
if (empty != 0)
|
||||
next_state = TTY_DRAW_LINE_EMPTY;
|
||||
else if (current_state == TTY_DRAW_LINE_FIRST)
|
||||
next_state = TTY_DRAW_LINE_SAME;
|
||||
else if (gcp->flags & GRID_FLAG_PADDING)
|
||||
next_state = TTY_DRAW_LINE_PAD;
|
||||
else if (grid_cells_look_equal(gcp, &last)) {
|
||||
if (gcp->data.size > (sizeof buf) - len)
|
||||
next_state = TTY_DRAW_LINE_FLUSH;
|
||||
@@ -312,8 +310,7 @@ tty_draw_line(struct tty *tty, struct screen *s, u_int px, u_int py, u_int nx,
|
||||
}
|
||||
|
||||
/* Append the cell if it is not empty and not padding. */
|
||||
if (next_state != TTY_DRAW_LINE_EMPTY &&
|
||||
next_state != TTY_DRAW_LINE_PAD) {
|
||||
if (next_state != TTY_DRAW_LINE_EMPTY) {
|
||||
memcpy(buf + len, gcp->data.data, gcp->data.size);
|
||||
len += gcp->data.size;
|
||||
width += gcp->data.width;
|
||||
|
||||
@@ -98,7 +98,7 @@ static const char *tty_feature_hyperlinks_capabilities[] = {
|
||||
#if defined (__OpenBSD__) || (defined(NCURSES_VERSION_MAJOR) && \
|
||||
(NCURSES_VERSION_MAJOR > 5 || \
|
||||
(NCURSES_VERSION_MAJOR == 5 && NCURSES_VERSION_MINOR > 8)))
|
||||
"*:Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\",
|
||||
"Hls=\\E]8;%?%p1%l%tid=%p1%s%;;%p2%s\\E\\\\",
|
||||
#endif
|
||||
NULL
|
||||
};
|
||||
@@ -527,8 +527,13 @@ tty_default_features(int *feat, const char *name, u_int version)
|
||||
},
|
||||
{ .name = "foot",
|
||||
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||
"ccolour,"
|
||||
"cstyle,"
|
||||
"extkeys"
|
||||
"extkeys,"
|
||||
"usstyle,"
|
||||
"sync,"
|
||||
"osc7,"
|
||||
"hyperlinks"
|
||||
},
|
||||
{ .name = "WezTerm",
|
||||
.features = TTY_FEATURES_BASE_MODERN_XTERM ","
|
||||
|
||||
@@ -119,6 +119,8 @@ static void window_copy_copy_line(struct window_mode_entry *, char **,
|
||||
static int window_copy_in_set(struct window_mode_entry *, u_int, u_int,
|
||||
const char *);
|
||||
static u_int window_copy_find_length(struct window_mode_entry *, u_int);
|
||||
static u_int window_copy_cursor_limit(struct window_mode_entry *, u_int,
|
||||
int);
|
||||
static void window_copy_cursor_start_of_line(struct window_mode_entry *);
|
||||
static void window_copy_cursor_back_to_indentation(
|
||||
struct window_mode_entry *);
|
||||
@@ -906,9 +908,9 @@ window_copy_get_line(struct window_pane *wp, u_int y)
|
||||
{
|
||||
struct window_mode_entry *wme = TAILQ_FIRST(&wp->modes);
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct grid *gd = data->screen.grid;
|
||||
struct grid *gd = data->backing->grid;
|
||||
|
||||
return (format_grid_line(gd, gd->hsize + y));
|
||||
return (format_grid_line(gd, gd->hsize + y - data->oy));
|
||||
}
|
||||
|
||||
char *
|
||||
@@ -1673,7 +1675,7 @@ window_copy_cmd_history_bottom(struct window_copy_cmd_state *cs)
|
||||
window_copy_other_end(wme);
|
||||
|
||||
data->cy = screen_size_y(&data->screen) - 1;
|
||||
data->cx = window_copy_find_length(wme, screen_hsize(s) + data->cy);
|
||||
data->cx = window_copy_cursor_limit(wme, screen_hsize(s) + data->cy, 0);
|
||||
data->oy = 0;
|
||||
|
||||
if (data->searchmark != NULL && !data->timeout)
|
||||
@@ -2694,6 +2696,8 @@ window_copy_cmd_search_backward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->cx = data->searchx;
|
||||
data->cy = data->searchy;
|
||||
data->oy = data->searcho;
|
||||
data->cx = window_copy_cursor_limit(wme,
|
||||
screen_hsize(data->backing) + data->cy - data->oy, 0);
|
||||
action = WINDOW_COPY_CMD_REDRAW;
|
||||
}
|
||||
if (*arg0 == '\0') {
|
||||
@@ -2749,6 +2753,8 @@ window_copy_cmd_search_forward_incremental(struct window_copy_cmd_state *cs)
|
||||
data->cx = data->searchx;
|
||||
data->cy = data->searchy;
|
||||
data->oy = data->searcho;
|
||||
data->cx = window_copy_cursor_limit(wme,
|
||||
screen_hsize(data->backing) + data->cy - data->oy, 0);
|
||||
action = WINDOW_COPY_CMD_REDRAW;
|
||||
}
|
||||
if (*arg0 == '\0') {
|
||||
@@ -5162,7 +5168,17 @@ window_copy_update_cursor(struct window_mode_entry *wme, u_int cx, u_int cy)
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct screen *s = &data->screen;
|
||||
struct screen_write_ctx ctx;
|
||||
u_int old_cx, old_cy, width, content_sx;
|
||||
u_int old_cx, old_cy, py, width, content_sx;
|
||||
u_int maxx;
|
||||
int allow_onemore;
|
||||
|
||||
allow_onemore = (data->screen.sel != NULL && data->rectflag);
|
||||
if (cy < screen_size_y(s)) {
|
||||
py = screen_hsize(data->backing) + cy - data->oy;
|
||||
maxx = window_copy_cursor_limit(wme, py, allow_onemore);
|
||||
if (cx > maxx)
|
||||
cx = maxx;
|
||||
}
|
||||
|
||||
old_cx = data->cx; old_cy = data->cy;
|
||||
data->cx = cx; data->cy = cy;
|
||||
@@ -5655,7 +5671,7 @@ window_copy_clear_selection(struct window_mode_entry *wme)
|
||||
data->selflag = SEL_CHAR;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
px = window_copy_cursor_limit(wme, py, data->rectflag);
|
||||
if (data->cx > px)
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
}
|
||||
@@ -5677,6 +5693,22 @@ window_copy_find_length(struct window_mode_entry *wme, u_int py)
|
||||
return (grid_line_length(data->backing->grid, py));
|
||||
}
|
||||
|
||||
static u_int
|
||||
window_copy_cursor_limit(struct window_mode_entry *wme, u_int py,
|
||||
int allow_onemore)
|
||||
{
|
||||
struct options *oo = wme->wp->window->options;
|
||||
u_int len;
|
||||
|
||||
len = window_copy_find_length(wme, py);
|
||||
if (allow_onemore ||
|
||||
options_get_number(oo, "mode-keys") != MODEKEY_VI)
|
||||
return (len);
|
||||
if (len == 0)
|
||||
return (0);
|
||||
return (len - 1);
|
||||
}
|
||||
|
||||
static void
|
||||
window_copy_cursor_start_of_line(struct window_mode_entry *wme)
|
||||
{
|
||||
@@ -5734,6 +5766,8 @@ window_copy_cursor_end_of_line(struct window_mode_entry *wme)
|
||||
else
|
||||
grid_reader_cursor_end_of_line(&gr, 1, 0);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
if (data->screen.sel == NULL || !data->rectflag)
|
||||
px = window_copy_cursor_limit(wme, py, 0);
|
||||
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
|
||||
data->oy, oldy, px, py, 0);
|
||||
}
|
||||
@@ -5784,6 +5818,10 @@ window_copy_other_end(struct window_mode_entry *wme)
|
||||
data->cy = screen_size_y(s) - 1;
|
||||
} else
|
||||
data->cy = cy + sely - yy;
|
||||
yy = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
hsize = window_copy_cursor_limit(wme, yy, data->rectflag);
|
||||
if (data->cx > hsize)
|
||||
data->cx = hsize;
|
||||
|
||||
window_copy_update_selection(wme, 1, 1);
|
||||
window_copy_redraw_screen(wme);
|
||||
@@ -5811,18 +5849,22 @@ window_copy_cursor_left(struct window_mode_entry *wme)
|
||||
static void
|
||||
window_copy_cursor_right(struct window_mode_entry *wme, int all)
|
||||
{
|
||||
struct window_pane *wp = wme->wp;
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wp->window->options;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, oldy, hsize;
|
||||
int onemore;
|
||||
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
oldy = data->cy;
|
||||
onemore = (options_get_number(oo, "mode-keys") != MODEKEY_VI);
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_right(&gr, 1, all);
|
||||
grid_reader_cursor_right(&gr, 1, all, onemore);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
window_copy_acquire_cursor_down(wme, hsize, screen_size_y(back_s),
|
||||
data->oy, oldy, px, py, 0);
|
||||
@@ -6037,20 +6079,23 @@ static void
|
||||
window_copy_cursor_jump_to_back(struct window_mode_entry *wme)
|
||||
{
|
||||
struct window_copy_mode_data *data = wme->data;
|
||||
struct options *oo = wme->wp->window->options;
|
||||
struct screen *back_s = data->backing;
|
||||
struct grid_reader gr;
|
||||
u_int px, py, oldy, hsize;
|
||||
int onemore;
|
||||
|
||||
px = data->cx;
|
||||
hsize = screen_hsize(back_s);
|
||||
py = hsize + data->cy - data->oy;
|
||||
oldy = data->cy;
|
||||
onemore = (options_get_number(oo, "mode-keys") != MODEKEY_VI);
|
||||
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
grid_reader_cursor_left(&gr, 0);
|
||||
grid_reader_cursor_left(&gr, 0);
|
||||
if (grid_reader_cursor_jump_back(&gr, data->jumpchar)) {
|
||||
grid_reader_cursor_right(&gr, 1, 0);
|
||||
grid_reader_cursor_right(&gr, 1, 0, onemore);
|
||||
grid_reader_get_cursor(&gr, &px, &py);
|
||||
window_copy_acquire_cursor_up(wme, hsize, data->oy, oldy, px,
|
||||
py);
|
||||
@@ -6097,7 +6142,7 @@ window_copy_cursor_next_word_end_pos(struct window_mode_entry *wme,
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
|
||||
if (!grid_reader_in_set(&gr, WHITESPACE))
|
||||
grid_reader_cursor_right(&gr, 0, 0);
|
||||
grid_reader_cursor_right(&gr, 0, 0, 0);
|
||||
grid_reader_cursor_next_word_end(&gr, separators);
|
||||
grid_reader_cursor_left(&gr, 1);
|
||||
} else
|
||||
@@ -6127,7 +6172,7 @@ window_copy_cursor_next_word_end(struct window_mode_entry *wme,
|
||||
grid_reader_start(&gr, back_s->grid, px, py);
|
||||
if (options_get_number(oo, "mode-keys") == MODEKEY_VI) {
|
||||
if (!grid_reader_in_set(&gr, WHITESPACE))
|
||||
grid_reader_cursor_right(&gr, 0, 0);
|
||||
grid_reader_cursor_right(&gr, 0, 0, 0);
|
||||
grid_reader_cursor_next_word_end(&gr, separators);
|
||||
grid_reader_cursor_left(&gr, 1);
|
||||
} else
|
||||
@@ -6361,7 +6406,7 @@ window_copy_rectangle_set(struct window_mode_entry *wme, int rectflag)
|
||||
data->rectflag = rectflag;
|
||||
|
||||
py = screen_hsize(data->backing) + data->cy - data->oy;
|
||||
px = window_copy_find_length(wme, py);
|
||||
px = window_copy_cursor_limit(wme, py, data->rectflag);
|
||||
if (data->cx > px)
|
||||
window_copy_update_cursor(wme, px, data->cy);
|
||||
|
||||
|
||||
84
window.c
84
window.c
@@ -935,15 +935,13 @@ window_pane_index(struct window_pane *wp, u_int *i)
|
||||
}
|
||||
|
||||
u_int
|
||||
window_count_panes(struct window *w, int inc_floating)
|
||||
window_count_panes(struct window *w, int with_floating)
|
||||
{
|
||||
struct window_pane *wp;
|
||||
u_int n;
|
||||
u_int n = 0;
|
||||
|
||||
n = 0;
|
||||
TAILQ_FOREACH(wp, &w->panes, entry) {
|
||||
if ((inc_floating == 0) && (wp->flags & PANE_FLOATING))
|
||||
continue;
|
||||
if (with_floating || ~wp->flags & PANE_FLOATING)
|
||||
n++;
|
||||
}
|
||||
return (n);
|
||||
@@ -1516,11 +1514,9 @@ window_pane_find_up(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
int edge, left, right, end;
|
||||
u_int size;
|
||||
int status, found;
|
||||
int edge, left, right, end, status, found;
|
||||
int xoff, yoff;
|
||||
u_int sx, sy;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1579,11 +1575,9 @@ window_pane_find_down(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
int edge, left, right, end;
|
||||
u_int size;
|
||||
int status, found;
|
||||
int edge, left, right, end, status, found;
|
||||
int xoff, yoff;
|
||||
u_int sx, sy;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1642,11 +1636,9 @@ window_pane_find_left(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
int edge, top, bottom, end;
|
||||
u_int size;
|
||||
int found;
|
||||
int edge, top, bottom, end, found;
|
||||
int xoff, yoff;
|
||||
u_int sx, sy;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1696,11 +1688,9 @@ window_pane_find_right(struct window_pane *wp)
|
||||
{
|
||||
struct window *w;
|
||||
struct window_pane *next, *best, **list;
|
||||
int edge, top, bottom, end;
|
||||
u_int size;
|
||||
int found;
|
||||
int edge, top, bottom, end, found;
|
||||
int xoff, yoff;
|
||||
u_int sx, sy;
|
||||
u_int size, sx, sy;
|
||||
|
||||
if (wp == NULL)
|
||||
return (NULL);
|
||||
@@ -1744,6 +1734,7 @@ window_pane_find_right(struct window_pane *wp)
|
||||
return (best);
|
||||
}
|
||||
|
||||
/* Add window to stack. */
|
||||
void
|
||||
window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
||||
{
|
||||
@@ -1754,6 +1745,7 @@ window_pane_stack_push(struct window_panes *stack, struct window_pane *wp)
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove window from stack. */
|
||||
void
|
||||
window_pane_stack_remove(struct window_panes *stack, struct window_pane *wp)
|
||||
{
|
||||
@@ -2134,3 +2126,53 @@ window_pane_border_status_get_range(struct window_pane *wp, u_int x, u_int y)
|
||||
*/
|
||||
return (style_ranges_get_range(srs, x - wp->xoff - 2));
|
||||
}
|
||||
|
||||
int
|
||||
window_pane_tile_geometry(struct window *w, struct window_pane *wp,
|
||||
int *out_size, int *out_flags, enum layout_type *out_type,
|
||||
struct cmdq_item *item, struct args *args, char **cause)
|
||||
{
|
||||
int size = -1, flags = *out_flags;
|
||||
enum layout_type type;
|
||||
u_int curval = 0;
|
||||
|
||||
type = LAYOUT_TOPBOTTOM;
|
||||
if (args_has(args, 'h'))
|
||||
type = LAYOUT_LEFTRIGHT;
|
||||
|
||||
if (args_has(args, 'l') || args_has(args, 'p')) {
|
||||
if (args_has(args, 'f')) {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = w->sy;
|
||||
else
|
||||
curval = w->sx;
|
||||
} else {
|
||||
if (type == LAYOUT_TOPBOTTOM)
|
||||
curval = wp->sy;
|
||||
else
|
||||
curval = wp->sx;
|
||||
}
|
||||
}
|
||||
|
||||
if (args_has(args, 'l')) {
|
||||
size = args_percentage_and_expand(args, 'l', 0, INT_MAX, curval,
|
||||
item, cause);
|
||||
} else if (args_has(args, 'p')) {
|
||||
size = args_strtonum_and_expand(args, 'p', 0, 100, item,
|
||||
cause);
|
||||
if (cause == NULL)
|
||||
size = curval * size / 100;
|
||||
}
|
||||
if (*cause != NULL)
|
||||
return (-1);
|
||||
|
||||
if (args_has(args, 'b'))
|
||||
flags |= SPAWN_BEFORE;
|
||||
if (args_has(args, 'f'))
|
||||
flags |= SPAWN_FULLSIZE;
|
||||
|
||||
*out_size = size;
|
||||
*out_flags = flags;
|
||||
*out_type = type;
|
||||
return (0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user