feat(terminal): allow :terminal to take modifiers (#15427)

The following modifiers are all now supported:

    :tab term
    :vertical term
    :horizontal term
    :botright term
    :topleft term

Fixes: https://github.com/neovim/neovim/issues/11385
This commit is contained in:
Gregory Anders 2023-08-28 07:22:19 -05:00 committed by GitHub
parent 1ad13e07d2
commit cffdf102d4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 7 deletions

View File

@ -158,6 +158,9 @@ The following new APIs and features were added.
• Floating windows can now show footer with new `footer` and `footer_pos`
config fields. Uses |hl-FloatFooter| by default.
• The |:terminal| command now accepts some |:command-modifiers| (specifically
|:horizontal| and those that affect splitting a window).
==============================================================================
CHANGED FEATURES *news-changed*

View File

@ -243,7 +243,8 @@ and 'winminwidth' are relevant.
:hor[izontal] {cmd}
Execute {cmd}. Currently only makes a difference for
`horizontal wincmd =`, which will equalize windows only
horizontally.
horizontally, and |:terminal|, which will open a |terminal|
buffer in a split window.
:lefta[bove] {cmd} *:lefta* *:leftabove*
:abo[veleft] {cmd} *:abo* *:aboveleft*

View File

@ -7302,12 +7302,31 @@ void set_pressedreturn(bool val)
static void ex_terminal(exarg_T *eap)
{
char ex_cmd[1024];
size_t len = 0;
if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) {
bool multi_mods = false;
// ex_cmd must be a null terminated string before passing to add_win_cmd_modifiers
ex_cmd[0] = '\0';
len = add_win_cmd_modifiers(ex_cmd, &cmdmod, &multi_mods);
assert(len < sizeof(ex_cmd));
int result = snprintf(ex_cmd + len, sizeof(ex_cmd) - len, " new");
assert(result > 0);
len += (size_t)result;
} else {
int result = snprintf(ex_cmd, sizeof(ex_cmd), "enew%s", eap->forceit ? "!" : "");
assert(result > 0);
len += (size_t)result;
}
assert(len < sizeof(ex_cmd));
if (*eap->arg != NUL) { // Run {cmd} in 'shell'.
char *name = vim_strsave_escaped(eap->arg, "\"\\");
snprintf(ex_cmd, sizeof(ex_cmd),
":enew%s | call termopen(\"%s\")",
eap->forceit ? "!" : "", name);
snprintf(ex_cmd + len, sizeof(ex_cmd) - len,
" | call termopen(\"%s\")", name);
xfree(name);
} else { // No {cmd}: run the job with tokenized 'shell'.
if (*p_sh == NUL) {
@ -7327,9 +7346,8 @@ static void ex_terminal(exarg_T *eap)
}
shell_free_argv(argv);
snprintf(ex_cmd, sizeof(ex_cmd),
":enew%s | call termopen([%s])",
eap->forceit ? "!" : "", shell_argv + 1);
snprintf(ex_cmd + len, sizeof(ex_cmd) - len,
" | call termopen([%s])", shell_argv + 1);
}
do_cmdline_cmd(ex_cmd);