vim-patch:9.1.0677: :keepp does not retain the substitute pattern

Problem:  :keeppatterns does not retain the substitute pattern
          for a :s command
Solution: preserve the last substitute pattern when used with the
          :keeppatterns command modifier (Gregory Anders)

closes: vim/vim#15497

3b59be4ed8

Co-authored-by: Gregory Anders <greg@gpanders.com>
This commit is contained in:
zeertzjq 2024-08-16 08:32:53 +08:00
parent 4afd4061a2
commit a25dbeee10
3 changed files with 17 additions and 10 deletions

View File

@ -348,7 +348,7 @@ terminals)
:keepp[atterns] {command} *:keepp* *:keeppatterns* :keepp[atterns] {command} *:keepp* *:keeppatterns*
Execute {command}, without adding anything to the search Execute {command}, without adding anything to the search
history history or modifying the last substitute pattern.
============================================================================== ==============================================================================
2. Command-line completion *cmdline-completion* 2. Command-line completion *cmdline-completion*

View File

@ -3085,7 +3085,7 @@ void sub_set_replacement(SubReplacementString sub)
/// ///
/// @returns true if :substitute can be replaced with a join command /// @returns true if :substitute can be replaced with a join command
static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub, static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char *sub,
const char *cmd, bool save) const char *cmd, bool save, bool keeppatterns)
FUNC_ATTR_NONNULL_ARG(1, 4, 5) FUNC_ATTR_NONNULL_ARG(1, 4, 5)
{ {
// TODO(vim): find a generic solution to make line-joining operations more // TODO(vim): find a generic solution to make line-joining operations more
@ -3123,7 +3123,7 @@ static bool sub_joining_lines(exarg_T *eap, char *pat, size_t patlen, const char
} }
if (save) { if (save) {
if ((cmdmod.cmod_flags & CMOD_KEEPPATTERNS) == 0) { if (!keeppatterns) {
save_re_pat(RE_SUBST, pat, patlen, magic_isset()); save_re_pat(RE_SUBST, pat, patlen, magic_isset());
} }
// put pattern in history // put pattern in history
@ -3331,6 +3331,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
linenr_T old_line_count = curbuf->b_ml.ml_line_count; linenr_T old_line_count = curbuf->b_ml.ml_line_count;
char *sub_firstline; // allocated copy of first sub line char *sub_firstline; // allocated copy of first sub line
bool endcolumn = false; // cursor in last column when done bool endcolumn = false; // cursor in last column when done
const bool keeppatterns = cmdmod.cmod_flags & CMOD_KEEPPATTERNS;
PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 }; PreviewLines preview_lines = { KV_INITIAL_VALUE, 0 };
static int pre_hl_id = 0; static int pre_hl_id = 0;
pos_T old_cursor = curwin->w_cursor; pos_T old_cursor = curwin->w_cursor;
@ -3391,7 +3392,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
cmd = skip_substitute(cmd, delimiter); cmd = skip_substitute(cmd, delimiter);
sub = xstrdup(p); sub = xstrdup(p);
if (!eap->skip && cmdpreview_ns <= 0) { if (!eap->skip && !keeppatterns && cmdpreview_ns <= 0) {
sub_set_replacement((SubReplacementString) { sub_set_replacement((SubReplacementString) {
.sub = xstrdup(sub), .sub = xstrdup(sub),
.timestamp = os_time(), .timestamp = os_time(),
@ -3412,7 +3413,8 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n
endcolumn = (curwin->w_curswant == MAXCOL); endcolumn = (curwin->w_curswant == MAXCOL);
} }
if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0)) { if (sub != NULL && sub_joining_lines(eap, pat, patlen, sub, cmd, cmdpreview_ns <= 0,
keeppatterns)) {
xfree(sub); xfree(sub);
return 0; return 0;
} }

View File

@ -806,7 +806,7 @@ func Test_replace_keeppatterns()
a a
foobar foobar
substitute foo asdf substitute foo asdf foo
one two one two
. .
@ -815,21 +815,26 @@ one two
/^substitute /^substitute
s/foo/bar/ s/foo/bar/
call assert_equal('foo', @/) call assert_equal('foo', @/)
call assert_equal('substitute bar asdf', getline('.')) call assert_equal('substitute bar asdf foo', getline('.'))
/^substitute /^substitute
keeppatterns s/asdf/xyz/ keeppatterns s/asdf/xyz/
call assert_equal('^substitute', @/) call assert_equal('^substitute', @/)
call assert_equal('substitute bar xyz', getline('.')) call assert_equal('substitute bar xyz foo', getline('.'))
/^substitute
&
call assert_equal('^substitute', @/)
call assert_equal('substitute bar xyz bar', getline('.'))
exe "normal /bar /e\<CR>" exe "normal /bar /e\<CR>"
call assert_equal(15, col('.')) call assert_equal(15, col('.'))
normal - normal -
keeppatterns /xyz keeppatterns /xyz
call assert_equal('bar ', @/) call assert_equal('bar ', @/)
call assert_equal('substitute bar xyz', getline('.')) call assert_equal('substitute bar xyz bar', getline('.'))
exe "normal 0dn" exe "normal 0dn"
call assert_equal('xyz', getline('.')) call assert_equal('xyz bar', getline('.'))
close! close!
endfunc endfunc