aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-11-08 13:08:14 +0100
committerGitHub <noreply@github.com>2024-11-08 13:08:14 +0100
commit475f9f64ef6eb41643a74d71ae01f9f65057109e (patch)
treeef61ba6ec0433a6c03128b2ff4f72c5eaa191385
parent8ab1903092f0ab193adf17ee635da838cce01dfa (diff)
parent092042b43d58254807c9e1151d8b6efb4d6410c4 (diff)
downloadrneovim-475f9f64ef6eb41643a74d71ae01f9f65057109e.tar.gz
rneovim-475f9f64ef6eb41643a74d71ae01f9f65057109e.tar.bz2
rneovim-475f9f64ef6eb41643a74d71ae01f9f65057109e.zip
Merge pull request #31073 from bfredl/cmdchar
fix(cmdline): simplify and correct grapheme cluster adjustment
-rw-r--r--src/nvim/ex_getln.c36
-rw-r--r--test/functional/editor/mode_cmdline_spec.lua21
2 files changed, 27 insertions, 30 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index dda1a18fa6..9c606c9606 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -3596,38 +3596,14 @@ void put_on_cmdline(const char *str, int len, bool redraw)
memmove(ccline.cmdbuff + ccline.cmdpos, str, (size_t)len);
ccline.cmdbuff[ccline.cmdlen] = NUL;
- {
- // When the inserted text starts with a composing character,
- // backup to the character before it. There could be two of them.
- int i = 0;
- int c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
- // TODO(bfredl): this can be corrected/simplified as utf_head_off implements the
- // correct grapheme cluster breaks
- while (ccline.cmdpos > 0 && utf_iscomposing_legacy(c)) {
- i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1;
+ // When the inserted text starts with a composing character,
+ // backup to the character before it.
+ if (ccline.cmdpos > 0 && (uint8_t)ccline.cmdbuff[ccline.cmdpos] >= 0x80) {
+ int i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos);
+ if (i != 0) {
ccline.cmdpos -= i;
len += i;
- c = utf_ptr2char(ccline.cmdbuff + ccline.cmdpos);
- }
- if (i == 0 && ccline.cmdpos > 0 && arabic_maycombine(c)) {
- // Check the previous character for Arabic combining pair.
- i = utf_head_off(ccline.cmdbuff, ccline.cmdbuff + ccline.cmdpos - 1) + 1;
- if (arabic_combine(utf_ptr2char(ccline.cmdbuff + ccline.cmdpos - i), c)) {
- ccline.cmdpos -= i;
- len += i;
- } else {
- i = 0;
- }
- }
- if (i != 0) {
- // Also backup the cursor position.
- i = ptr2cells(ccline.cmdbuff + ccline.cmdpos);
- ccline.cmdspos -= i;
- msg_col -= i;
- if (msg_col < 0) {
- msg_col += Columns;
- msg_row--;
- }
+ ccline.cmdspos = cmd_screencol(ccline.cmdpos);
}
}
diff --git a/test/functional/editor/mode_cmdline_spec.lua b/test/functional/editor/mode_cmdline_spec.lua
index efd7a37c0b..bb74dfe12f 100644
--- a/test/functional/editor/mode_cmdline_spec.lua
+++ b/test/functional/editor/mode_cmdline_spec.lua
@@ -38,6 +38,27 @@ describe('cmdline', function()
feed([[:<C-R>="foo\nbar\rbaz"<CR>]])
eq('foo\nbar\rbaz', fn.getcmdline())
end)
+
+ it('pasting handles composing chars properly', function()
+ local screen = Screen.new(60, 4)
+ -- 'arabicshape' cheats and always redraws everything which trivially works,
+ -- this test is for partial redraws in 'noarabicshape' mode.
+ command('set noarabicshape')
+ screen:attach()
+ fn.setreg('a', '💻')
+ feed(':test 🧑‍')
+ screen:expect([[
+ |
+ {1:~ }|*2
+ :test 🧑‍^ |
+ ]])
+ feed('<c-r><c-r>a')
+ screen:expect([[
+ |
+ {1:~ }|*2
+ :test 🧑‍💻^ |
+ ]])
+ end)
end)
it('Ctrl-Shift-V supports entering unsimplified key notations', function()