use crate::*;
const SPLIT_WINDOW_TEMPLATE: *const u8 = c!("#{session_name}:#{window_index}.#{pane_index}");
pub static CMD_SPLIT_WINDOW_ENTRY: cmd_entry = cmd_entry {
name: "split-window",
alias: Some("splitw"),
args: args_parse::new("bc:de:EfF:hIkl:m:p:PR:s:S:t:T:vWZ", 0, -1, None),
usage: "[-bdefhIklPvWZ] [-c start-directory] [-e environment] [-F format] [-l size] [-m message] [-p percentage] [-s style] [-S active-border-style] [-R inactive-border-style] [-T title] [-t target-pane] [shell-command [argument ...]]",
target: cmd_entry_flag::new(b't', cmd_find_type::CMD_FIND_PANE, cmd_find_flags::empty()),
flags: cmd_flag::empty(),
exec: cmd_split_window_exec,
source: cmd_entry_flag::zeroed(),
};
pub static CMD_NEW_PANE_ENTRY: cmd_entry = cmd_entry {
name: "new-pane",
alias: Some("newp"),
args: args_parse::new("bB:c:de:EfF:hIkl:Lm:p:PR:s:S:t:T:vWx:X:y:Y:Z", 0, -1, None),
usage: "[-bdefhIklPvWZ] [-B border-lines] [-c start-directory] [-e environment] [-F format] [-l size] [-m message] [-p percentage] [-s style] [-S active-border-style] [-R inactive-border-style] [-T title] [-x width] [-y height] [-X x-position] [-Y y-position] [-t target-pane] [shell-command [argument ...]]",
target: cmd_entry_flag::new(b't', cmd_find_type::CMD_FIND_PANE, cmd_find_flags::empty()),
flags: cmd_flag::empty(),
exec: cmd_split_window_exec,
source: cmd_entry_flag::zeroed(),
};
unsafe fn cmd_split_window_exec(self_: *mut cmd, item: *mut cmdq_item) -> cmd_retval {
unsafe {
let args = cmd_get_args(self_);
let current = cmdq_get_current(item);
let target = cmdq_get_target(item);
let tc = cmdq_get_target_client(item);
let s = (*target).s;
let wl = (*target).wl;
let w = (*wl).window;
let wp = (*target).wp;
let mut cause = null_mut();
let count = args_count(args);
let mut curval = 0;
let mut type_ = layout_type::LAYOUT_TOPBOTTOM;
if args_has(args, 'h') {
type_ = layout_type::LAYOUT_LEFTRIGHT;
}
if args_has(args, 'l') || args_has(args, 'p') {
if args_has(args, 'f') {
match type_ {
layout_type::LAYOUT_TOPBOTTOM => curval = (*w).sy,
_ => curval = (*w).sx,
}
} else {
match type_ {
layout_type::LAYOUT_TOPBOTTOM => curval = (*wp).sy,
_ => curval = (*wp).sx,
}
}
}
let mut size: i32 = -1;
if args_has(args, 'l') {
size = args_percentage_and_expand(
args,
b'l',
0,
i32::MAX as i64,
curval as _,
item,
&raw mut cause,
) as _;
} else if args_has(args, 'p') {
size = args_strtonum_and_expand(args, b'p', 0, 100, item, &raw mut cause) as _;
if cause.is_null() {
size = curval as i32 * size / 100;
}
}
if !cause.is_null() {
cmdq_error!(item, "size {}", _s(cause));
free_(cause);
return cmd_retval::CMD_RETURN_ERROR;
}
window_push_zoom((*wp).window, true, args_has(args, 'Z'));
let mut input = args_has(args, 'I') && count == 0;
let mut flags = spawn_flags::empty();
if args_has(args, 'b') {
flags |= SPAWN_BEFORE;
}
if args_has(args, 'f') {
flags |= SPAWN_FULLSIZE;
}
if input || (count == 1 && *args_string(args, 0) == b'\0') {
flags |= SPAWN_EMPTY;
}
let is_floating = if std::ptr::eq(cmd_get_entry(self_), &raw const CMD_NEW_PANE_ENTRY) {
!args_has(args, 'L')
} else {
window_pane_is_floating(wp) != 0
};
if is_floating {
flags |= SPAWN_FLOATING;
}
let lc = if is_floating {
let lines = window_get_pane_lines(w);
layout_get_floating_cell(item, args, lines, w, wp, &raw mut cause)
} else {
layout_split_pane(wp, type_, size, flags)
};
if lc.is_null() {
if !cause.is_null() {
cmdq_error!(item, "{}", _s(cause));
free_(cause);
} else {
cmdq_error!(item, "no space for new pane");
}
return cmd_retval::CMD_RETURN_ERROR;
}
let mut sc: spawn_context = zeroed();
sc.item = item;
sc.s = s;
sc.wl = wl;
sc.wp0 = wp;
sc.lc = lc;
args_to_vector(args, &raw mut sc.argc, &raw mut sc.argv);
sc.environ = environ_create().as_ptr();
let mut av = args_first_value(args, b'e');
while !av.is_null() {
environ_put(sc.environ, (*av).union_.string, environ_flags::empty());
av = args_next_value(av);
}
sc.idx = -1;
sc.cwd = args_get_(args, 'c');
sc.flags = flags;
if args_has(args, 'd') {
sc.flags |= SPAWN_DETACHED;
}
if args_has(args, 'Z') {
sc.flags |= SPAWN_ZOOM;
}
let new_wp = spawn_pane(&raw mut sc, &raw mut cause);
if new_wp.is_null() {
cmdq_error!(item, "create pane failed: {}", _s(cause));
free_(cause);
if !sc.argv.is_null() {
cmd_free_argv(sc.argc, sc.argv);
}
environ_free(sc.environ);
return cmd_retval::CMD_RETURN_ERROR;
}
if input {
match window_pane_start_input(new_wp, item, &raw mut cause) {
-1 => {
server_client_remove_pane(new_wp);
layout_close_pane(new_wp);
window_remove_pane((*wp).window, new_wp);
cmdq_error!(item, "{}", _s(cause));
free_(cause);
if !sc.argv.is_null() {
cmd_free_argv(sc.argc, sc.argv);
}
environ_free(sc.environ);
return cmd_retval::CMD_RETURN_ERROR;
}
1 => {
input = false;
}
_ => (),
}
}
if !args_has(args, 'd') {
cmd_find_from_winlink_pane(current, wl, new_wp, cmd_find_flags::empty());
}
window_pop_zoom((*wp).window);
server_redraw_window((*wp).window);
server_status_session(s);
if args_has(args, 'P') {
let mut template = args_get_(args, 'F');
if template.is_null() {
template = SPLIT_WINDOW_TEMPLATE;
}
let cp = format_single(item, cstr_to_str(template), tc, s, wl, new_wp);
cmdq_print!(item, "{}", _s(cp));
free_(cp);
}
let mut fs: cmd_find_state = zeroed(); cmd_find_from_winlink_pane(&raw mut fs, wl, new_wp, cmd_find_flags::empty());
cmdq_insert_hook!(s, item, &raw mut fs, "after-split-window");
if !sc.argv.is_null() {
cmd_free_argv(sc.argc, sc.argv);
}
environ_free(sc.environ);
if input {
return cmd_retval::CMD_RETURN_WAIT;
}
cmd_retval::CMD_RETURN_NORMAL
}
}