view src/vimrun.c @ 34381:4e0da2b33607 v9.1.0117

patch 9.1.0117: Stop split-moving from firing WinNew and WinNewPre autocommands Commit: https://github.com/vim/vim/commit/96cc4aef3d47d0fd70e68908af3d48a0dce8ea70 Author: Sean Dewar <6256228+seandewar@users.noreply.github.com> Date: Tue Feb 20 21:52:31 2024 +0100 patch 9.1.0117: Stop split-moving from firing WinNew and WinNewPre autocommands Problem: win_splitmove fires WinNewPre and possibly WinNew when moving windows, even though no new windows are created. Solution: don't fire WinNew and WinNewPre when inserting an existing window, even if it isn't the current window. Improve the accuracy of related documentation. (Sean Dewar) Likewise, before this patch, WinClosed was not fired anyway (even for :wincmd H/J/K/L, which also didn't fire WinNew, but did still fire WinNewPre), despite documentation saying windows are "closed". Note that :wincmd T actually indeed works by creating a new window (and closing the old one), unlike the others. This also fixes issues where WinNewPre is fired when split-moving while curwin doesn't yet have a frame or entry in the window list, causing many things to not work (it's not considered valid at that point). This was guaranteed when using :wincmd H/J/K/L. Because WinNewPre is no longer fired when split-moving, this makes restoring the previous window layout on failure easier, as we can be sure that frames are not resized from WinNewPre autocommands if win_split_ins fails. This allows us to use a different strategy in the following commit. -- In my opinion, this leaves questions about the current usefulness of WinNewPre. A motivation described in #10635 states how creating a new window can steal room from other windows, and how WinNewPre will be useful for detecting that, but this is also true when inserting an existing window, which now doesn't fire it. Maybe the autocommand should be changed to have a better name? There are also other issues I found with the current implementation of WinNewPre that need addressing: - it allows switching windows and tabpages, which can cause incorrect windows to be split/moved, and big problems when switching tabpages. - it fires before win_split_ins checks for room, before it makes any changes to window sizes or before it considers allocating a new window. This should be changed or documented. I hope to address some of this stuff in a different PR, if possible. related: #14038 Signed-off-by: Sean Dewar <6256228+seandewar@users.noreply.github.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
author Christian Brabandt <cb@256bit.org>
date Tue, 20 Feb 2024 22:30:06 +0100
parents 2559dc02bd64
children
line wrap: on
line source

/* vi:set ts=8 sts=4 sw=4 noet:
 *
 * VIM - Vi IMproved	by Bram Moolenaar
 *			this file by Vince Negri
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 * See README.txt for an overview of the Vim source code.
 */

/*
 * vimrun.c - Tiny Win32 program to safely run an external command in a
 *	      DOS console.
 *	      This program is required to avoid that typing CTRL-C in the DOS
 *	      console kills Vim.  Now it only kills vimrun.
 */

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>

    int
main(void)
{
    const wchar_t   *p;
    wchar_t	    *cmd;
    size_t	    cmdlen;
    int		    retval;
    int		    inquote = 0;
    int		    silent = 0;
    HANDLE	    hstdout;
    DWORD	    written;

    p = (const wchar_t *)GetCommandLineW();

    /*
     * Skip the executable name, which might be in "".
     */
    while (*p)
    {
	if (*p == L'"')
	    inquote = !inquote;
	else if (!inquote && *p == L' ')
	{
	    ++p;
	    break;
	}
	++p;
    }
    while (*p == L' ')
	++p;

    /*
     * "-s" argument: don't wait for a key hit.
     */
    if (p[0] == L'-' && p[1] == L's' && p[2] == L' ')
    {
	silent = 1;
	p += 3;
	while (*p == L' ')
	    ++p;
    }

    // Print the command, including quotes and redirection.
    hstdout = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteConsoleW(hstdout, p, wcslen(p), &written, NULL);
    WriteConsoleW(hstdout, L"\r\n", 2, &written, NULL);

    // If the command starts and ends with double quotes,
    // Enclose the command in parentheses.
    cmd = NULL;
    cmdlen = wcslen(p);
    if (cmdlen >= 2 && p[0] == L'"' && p[cmdlen - 1] == L'"')
    {
	cmdlen += 3;
	cmd = malloc(cmdlen * sizeof(wchar_t));
	if (cmd == NULL)
	{
	    perror("vimrun malloc(): ");
	    return -1;
	}
	_snwprintf(cmd, cmdlen, L"(%s)", p);
	p = cmd;
    }

    /*
     * Do it!
     */
    retval = _wsystem(p);

    if (cmd)
	free(cmd);

    if (retval == -1)
	perror("vimrun system(): ");
    else if (retval != 0)
	printf("shell returned %d\n", retval);

    if (!silent)
    {
	puts("Hit any key to close this window...");

	while (_kbhit())
	    (void)_getch();
	(void)_getch();
    }

    return retval;
}