Coverage Report

Created: 2023-06-07 06:04

/src/tmux/cmd-break-pane.c
Line
Count
Source (jump to first uncovered line)
1
/* $OpenBSD$ */
2
3
/*
4
 * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
5
 *
6
 * Permission to use, copy, modify, and distribute this software for any
7
 * purpose with or without fee is hereby granted, provided that the above
8
 * copyright notice and this permission notice appear in all copies.
9
 *
10
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14
 * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
15
 * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
16
 * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17
 */
18
19
#include <sys/types.h>
20
21
#include <stdlib.h>
22
23
#include "tmux.h"
24
25
/*
26
 * Break pane off into a window.
27
 */
28
29
0
#define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
30
31
static enum cmd_retval  cmd_break_pane_exec(struct cmd *, struct cmdq_item *);
32
33
const struct cmd_entry cmd_break_pane_entry = {
34
  .name = "break-pane",
35
  .alias = "breakp",
36
37
  .args = { "abdPF:n:s:t:", 0, 0, NULL },
38
  .usage = "[-abdP] [-F format] [-n window-name] [-s src-pane] "
39
     "[-t dst-window]",
40
41
  .source = { 's', CMD_FIND_PANE, 0 },
42
  .target = { 't', CMD_FIND_WINDOW, CMD_FIND_WINDOW_INDEX },
43
44
  .flags = 0,
45
  .exec = cmd_break_pane_exec
46
};
47
48
static enum cmd_retval
49
cmd_break_pane_exec(struct cmd *self, struct cmdq_item *item)
50
0
{
51
0
  struct args   *args = cmd_get_args(self);
52
0
  struct cmd_find_state *current = cmdq_get_current(item);
53
0
  struct cmd_find_state *target = cmdq_get_target(item);
54
0
  struct cmd_find_state *source = cmdq_get_source(item);
55
0
  struct client   *tc = cmdq_get_target_client(item);
56
0
  struct winlink    *wl = source->wl;
57
0
  struct session    *src_s = source->s;
58
0
  struct session    *dst_s = target->s;
59
0
  struct window_pane  *wp = source->wp;
60
0
  struct window   *w = wl->window;
61
0
  char      *name, *cause, *cp;
62
0
  int      idx = target->idx, before;
63
0
  const char    *template;
64
65
0
  before = args_has(args, 'b');
66
0
  if (args_has(args, 'a') || before) {
67
0
    if (target->wl != NULL)
68
0
      idx = winlink_shuffle_up(dst_s, target->wl, before);
69
0
    else
70
0
      idx = winlink_shuffle_up(dst_s, dst_s->curw, before);
71
0
    if (idx == -1)
72
0
      return (CMD_RETURN_ERROR);
73
0
  }
74
0
  server_unzoom_window(w);
75
76
0
  if (window_count_panes(w) == 1) {
77
0
    if (server_link_window(src_s, wl, dst_s, idx, 0,
78
0
        !args_has(args, 'd'), &cause) != 0) {
79
0
      cmdq_error(item, "%s", cause);
80
0
      free(cause);
81
0
      return (CMD_RETURN_ERROR);
82
0
    }
83
0
    if (args_has(args, 'n')) {
84
0
      window_set_name(w, args_get(args, 'n'));
85
0
      options_set_number(w->options, "automatic-rename", 0);
86
0
    }
87
0
    server_unlink_window(src_s, wl);
88
0
    return (CMD_RETURN_NORMAL);
89
0
  }
90
0
  if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
91
0
    cmdq_error(item, "index in use: %d", idx);
92
0
    return (CMD_RETURN_ERROR);
93
0
  }
94
95
0
  TAILQ_REMOVE(&w->panes, wp, entry);
96
0
  server_client_remove_pane(wp);
97
0
  window_lost_pane(w, wp);
98
0
  layout_close_pane(wp);
99
100
0
  w = wp->window = window_create(w->sx, w->sy, w->xpixel, w->ypixel);
101
0
  options_set_parent(wp->options, w->options);
102
0
  wp->flags |= PANE_STYLECHANGED;
103
0
  TAILQ_INSERT_HEAD(&w->panes, wp, entry);
104
0
  w->active = wp;
105
0
  w->latest = tc;
106
107
0
  if (!args_has(args, 'n')) {
108
0
    name = default_window_name(w);
109
0
    window_set_name(w, name);
110
0
    free(name);
111
0
  } else {
112
0
    window_set_name(w, args_get(args, 'n'));
113
0
    options_set_number(w->options, "automatic-rename", 0);
114
0
  }
115
116
0
  layout_init(w, wp);
117
0
  wp->flags |= PANE_CHANGED;
118
0
  colour_palette_from_option(&wp->palette, wp->options);
119
120
0
  if (idx == -1)
121
0
    idx = -1 - options_get_number(dst_s->options, "base-index");
122
0
  wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
123
0
  if (!args_has(args, 'd')) {
124
0
    session_select(dst_s, wl->idx);
125
0
    cmd_find_from_session(current, dst_s, 0);
126
0
  }
127
128
0
  server_redraw_session(src_s);
129
0
  if (src_s != dst_s)
130
0
    server_redraw_session(dst_s);
131
0
  server_status_session_group(src_s);
132
0
  if (src_s != dst_s)
133
0
    server_status_session_group(dst_s);
134
135
0
  if (args_has(args, 'P')) {
136
0
    if ((template = args_get(args, 'F')) == NULL)
137
0
      template = BREAK_PANE_TEMPLATE;
138
0
    cp = format_single(item, template, tc, dst_s, wl, wp);
139
0
    cmdq_print(item, "%s", cp);
140
0
    free(cp);
141
0
  }
142
0
  return (CMD_RETURN_NORMAL);
143
0
}