From: Johannes Thyssen Tishman Subject: Re: ksh: yank on 'change' in vi-mode To: tech@openbsd.org Date: Sat, 28 Mar 2026 20:09:10 +0000 2026-03-28T17:25:27+0000 Johannes Thyssen Tishman : > Currently, only 'delete' operations in ksh's vi mode yank the deleted > range to the yank buffer. The diff below modifies 'change' operations to > do the same. This is consistent vi(1)'s behavior. Here's the diff again including regression tests. I reused the existing tests for the 'paste' command that used 'delete' operations and modified them to use equivalent 'change' operations, e.g., C instead of D and cl instead of x. Additionally, I added more tests for 'paste' that use the commands cc, cw and cf. script(1) was very useful to create and verify these tests in case anyone wants to check them. diff /usr/src path + /usr/src commit - cc88cbeddb7d5a75202cbffeb7b3d5e6cd8cbbc0 blob - d296e018c606ebfd1e47887ea563364758d45bc1 file + bin/ksh/vi.c --- bin/ksh/vi.c +++ bin/ksh/vi.c @@ -819,7 +819,7 @@ vi_cmd(int argcnt, const char *cmd) c2++; } } - if (*cmd != 'c' && c1 != c2) + if (c1 != c2) yank_range(c1, c2); if (*cmd != 'y') { del_range(c1, c2); @@ -858,6 +858,7 @@ vi_cmd(int argcnt, const char *cmd) case 'C': modified = 1; hnum = hlast; + yank_range(es->cursor, es->linelen); del_range(es->cursor, es->linelen); insert = INSERT; break; commit - cc88cbeddb7d5a75202cbffeb7b3d5e6cd8cbbc0 blob - a4baa9ccf60d8720ed5dc262b3d983a9f2861951 file + regress/bin/ksh/edit/vi.sh --- regress/bin/ksh/edit/vi.sh +++ regress/bin/ksh/edit/vi.sh @@ -122,7 +122,7 @@ testseq "ab\0033Lx" " # ab\b\a \b\b" testseq "abc\003302l~" " # abc\b\b\babC\b" testseq "abc\00330 rx" " # abc\b\b\bax\b" -# P: Paste at current position. +# P: Paste at current position after delete. testseq "abcde\0033hDhP" " # abcde\b\b \b\b\b\bdebc\b\b\b" testseq "abcde\0033hDh2P" " # abcde\b\b \b\b\b\bdedebc\b\b\b" testseq "A\0033xa\0303\0200\00332Px" \ @@ -132,15 +132,47 @@ testseq "\0302\0251\0033xaA\0033Px" \ testseq "\0302\0251\0033xa\0303\0200\0033Px" \ " # \0302\0251\b \b\b\0303\0200\b\0302\0251\0303\0200\b\b\0303\0200 \b\b\b" -# p: Paste after current position. +# P: Paste at current position after change. +testseq "abcde\0033hC\0033hP" " # abcde\b\b \b\b\b\bdebc\b\b\b" +testseq "abcde\0033hC\0033h2P" " # abcde\b\b \b\b\b\bdedebc\b\b\b" +testseq "A\0033cl\0033a\0303\0200\00332Pcl\0033" \ + " # A\b \b\0303\0200\bAA\0303\0200\b\b\0303\0200 \b\b\b" +testseq "\0302\0251\0033cl\0033aA\0033Pcl\0033" \ + " # \0302\0251\b \b\bA\b\0302\0251A\b\bA \b\b\b" +testseq "\0302\0251\0033cl\0033a\0303\0200\0033Pcl\0033" \ + " # \0302\0251\b \b\b\0303\0200\b\0302\0251\0303\0200\b\b\0303\0200 \b\b\b" +testseq "one two \0033ccthree\00330P" \ + " # one two \b\r # \r # three\b\b\b\b\bone two three\b\b\b\b\b\b" +testseq "one zero\0033bcw\00330Pa \0033" \ + " # one zero\b\b\b\b \b\b\b\b\b\b\b\bzeroone\b\b\b\bo one\b\b\b\b" +testseq "one zero \0033bcf \00330P" \ + " # one zero \b\b\b\b\b \b\b\b\b\b\b\b\bzero one\b\b\b\b" + +# p: Paste after current position after delete. testseq "abcd\0033hDhp" " # abcd\b\b \b\b\b\bacdb\b\b" testseq "abcd\0033hDh2p" " # abcd\b\b \b\b\b\bacdcdb\b\b" testseq "A\0033xa\0303\0200\0033px" " # A\b \b\0303\0200\b\0303\0200A\b \b\b" testseq "\0302\0251\0033xaA\0033px" \ - " # \0302\0251\b \b\bA\bA\0302\0251\b \b\b\b" + " # \0302\0251\b \b\bA\bA\0302\0251\b \b\b\b" testseq "\0302\0251\0033xa\0303\0200\0033px" \ " # \0302\0251\b \b\b\0303\0200\b\0303\0200\0302\0251\b \b\b\b" +# p: Paste after current position after change. +testseq "abcd\0033hC\0033hp" " # abcd\b\b \b\b\b\bacdb\b\b" +testseq "abcd\0033hC\0033h2p" " # abcd\b\b \b\b\b\bacdcdb\b\b" +testseq "A\0033cl\0033a\0303\0200\0033pcl\0033" \ + " # A\b \b\0303\0200\b\0303\0200A\b \b\b" +testseq "\0302\0251\0033cl\0033aA\0033pcl\0033" \ + " # \0302\0251\b \b\bA\bA\0302\0251\b \b\b\b" +testseq "\0302\0251\0033cl\0033a\0303\0200\0033pcl\0033" \ + " # \0302\0251\b \b\b\0303\0200\b\0303\0200\0302\0251\b \b\b\b" +testseq "one two\0033cczero \0033p" \ + " # one two\b\r # \r # zero \b one two\b" +testseq "one zero\00330cw\0033\$a \0033p" \ + " # one zero\b\r # zero \r # zero \b one\b" +testseq "one zero\00330cf \0033\$a \0033p" \ + " # one zero\b\r # zero \r # zero \b one" + # R: Replace. testseq "abcd\00332h2Rx\0033" " # abcd\b\b\bxx\b" testseq "abcdef\00334h2Rxy\0033" " # abcdef\b\b\b\b\bxyxy\b"