# HG changeset patch # User Bram Moolenaar # Date 1666026904 -7200 # Node ID 2ee5b79038f03227f281c20f5aebe3ae8f5db02a # Parent 0e58f1fab65c622d73aa6e9503d67b4fdaaf3702 patch 9.0.0783: ":!" doesn't do anything but does update the previous command Commit: https://github.com/vim/vim/commit/8107a2a8af80a53a61734b600539c5beb4782991 Author: Bram Moolenaar Date: Mon Oct 17 18:00:23 2022 +0100 patch 9.0.0783: ":!" doesn't do anything but does update the previous command Problem: ":!" doesn't do anything but does update the previous command. Solution: Do not have ":!" change the previous command. (Martin Tournoij, closes #11372) diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -85,6 +85,7 @@ src/testdir/messages src/testdir/viminfo src/testdir/opt_test.vim src/testdir/failed +src/testdir/starttime runtime/indent/testdir/*.out runtime/indent/testdir/*.fail src/memfile_test diff --git a/runtime/doc/various.txt b/runtime/doc/various.txt --- a/runtime/doc/various.txt +++ b/runtime/doc/various.txt @@ -249,7 +249,8 @@ 8g8 Find an illegal UTF-8 byte sequenc *:!cmd* *:!* :!{cmd} Execute {cmd} with the shell. See also the 'shell' - and 'shelltype' option. + and 'shelltype' option. `:!` without a {cmd} is a no-op, + it does nothing. *E34* Any '!' in {cmd} is replaced with the previous external command (see also 'cpoptions'). But not when diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -957,6 +957,11 @@ do_bang( } } while (trailarg != NULL); + // Don't do anything if there is no command as there isn't really anything + // useful in running "sh -c ''". Avoids changing "prevcmd". + if (STRLEN(newcmd) == 0) + return; + vim_free(prevcmd); prevcmd = newcmd; diff --git a/src/testdir/test_shell.vim b/src/testdir/test_shell.vim --- a/src/testdir/test_shell.vim +++ b/src/testdir/test_shell.vim @@ -251,4 +251,35 @@ func Test_set_shell() call delete('Xtestout') endfunc +func Test_shell_repeat() + CheckUnix + + let save_shell = &shell + + call writefile(['#!/bin/sh', 'echo "Cmd: [$*]" > Xlog'], 'Xtestshell', 'D') + call setfperm('Xtestshell', "r-x------") + set shell=./Xtestshell + defer delete('Xlog') + + call feedkeys(":!echo coconut\", 'xt') " Run command + call assert_equal(['Cmd: [-c echo coconut]'], readfile('Xlog')) + + call feedkeys(":!!\", 'xt') " Re-run previous + call assert_equal(['Cmd: [-c echo coconut]'], readfile('Xlog')) + + call writefile(['empty'], 'Xlog') + call feedkeys(":!\", 'xt') " :! is a no-op + call assert_equal(['empty'], readfile('Xlog')) + + call feedkeys(":!!\", 'xt') " :! doesn't clear previous command + call assert_equal(['Cmd: [-c echo coconut]'], readfile('Xlog')) + + call feedkeys(":!echo banana\", 'xt') " Make sure setting previous command keeps working after a :! no-op + call assert_equal(['Cmd: [-c echo banana]'], readfile('Xlog')) + call feedkeys(":!!\", 'xt') + call assert_equal(['Cmd: [-c echo banana]'], readfile('Xlog')) + + let &shell = save_shell +endfunc + " vim: shiftwidth=2 sts=2 expandtab diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 783, +/**/ 782, /**/ 781,