Download raw body.
ksh: yank on 'change' in vi-mode
2026-03-28T17:25:27+0000 Johannes Thyssen Tishman <jtt@openbsd.org>:
> 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<Esc> instead of D
and cl<Esc> instead of x. Additionally, I added more tests for 'paste'
that use the commands cc, cw and cf<char>.
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"
ksh: yank on 'change' in vi-mode