cmd-break-pane.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. /* $OpenBSD$ */
  2. /*
  3. * Copyright (c) 2009 Nicholas Marriott <nicholas.marriott@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
  14. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
  15. * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include <sys/types.h>
  18. #include <stdlib.h>
  19. #include "tmux.h"
  20. /*
  21. * Break pane off into a window.
  22. */
  23. #define BREAK_PANE_TEMPLATE "#{session_name}:#{window_index}.#{pane_index}"
  24. enum cmd_retval cmd_break_pane_exec(struct cmd *, struct cmd_q *);
  25. const struct cmd_entry cmd_break_pane_entry = {
  26. .name = "break-pane",
  27. .alias = "breakp",
  28. .args = { "dPF:s:t:", 0, 0 },
  29. .usage = "[-dP] [-F format] [-s src-pane] [-t dst-window]",
  30. .sflag = CMD_PANE,
  31. .tflag = CMD_WINDOW_INDEX,
  32. .flags = 0,
  33. .exec = cmd_break_pane_exec
  34. };
  35. enum cmd_retval
  36. cmd_break_pane_exec(struct cmd *self, struct cmd_q *cmdq)
  37. {
  38. #ifdef TMATE
  39. cmdq_error(cmdq, "break pane is not supported with tmate");
  40. return (CMD_RETURN_ERROR);
  41. #else
  42. struct args *args = self->args;
  43. struct winlink *wl = cmdq->state.sflag.wl;
  44. struct session *src_s = cmdq->state.sflag.s;
  45. struct session *dst_s = cmdq->state.tflag.s;
  46. struct window_pane *wp = cmdq->state.sflag.wp;
  47. struct window *w = wl->window;
  48. char *name;
  49. char *cause;
  50. int idx = cmdq->state.tflag.idx;
  51. struct format_tree *ft;
  52. const char *template;
  53. char *cp;
  54. if (idx != -1 && winlink_find_by_index(&dst_s->windows, idx) != NULL) {
  55. cmdq_error(cmdq, "index %d already in use", idx);
  56. return (CMD_RETURN_ERROR);
  57. }
  58. if (window_count_panes(w) == 1) {
  59. cmdq_error(cmdq, "can't break with only one pane");
  60. return (CMD_RETURN_ERROR);
  61. }
  62. server_unzoom_window(w);
  63. TAILQ_REMOVE(&w->panes, wp, entry);
  64. window_lost_pane(w, wp);
  65. layout_close_pane(wp);
  66. w = wp->window = window_create1(dst_s->sx, dst_s->sy);
  67. TAILQ_INSERT_HEAD(&w->panes, wp, entry);
  68. w->active = wp;
  69. name = default_window_name(w);
  70. window_set_name(w, name);
  71. free(name);
  72. layout_init(w, wp);
  73. wp->flags |= PANE_CHANGED;
  74. if (idx == -1)
  75. idx = -1 - options_get_number(dst_s->options, "base-index");
  76. wl = session_attach(dst_s, w, idx, &cause); /* can't fail */
  77. if (!args_has(self->args, 'd'))
  78. session_select(dst_s, wl->idx);
  79. server_redraw_session(src_s);
  80. if (src_s != dst_s)
  81. server_redraw_session(dst_s);
  82. server_status_session_group(src_s);
  83. if (src_s != dst_s)
  84. server_status_session_group(dst_s);
  85. if (args_has(args, 'P')) {
  86. if ((template = args_get(args, 'F')) == NULL)
  87. template = BREAK_PANE_TEMPLATE;
  88. ft = format_create(cmdq, 0);
  89. format_defaults(ft, cmdq->state.c, dst_s, wl, wp);
  90. cp = format_expand(ft, template);
  91. cmdq_print(cmdq, "%s", cp);
  92. free(cp);
  93. format_free(ft);
  94. }
  95. return (CMD_RETURN_NORMAL);
  96. #endif
  97. }