aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/mbyte.c3
-rw-r--r--src/nvim/ops.c10
-rw-r--r--test/functional/legacy/039_visual_block_mode_commands_spec.lua12
-rw-r--r--test/old/testdir/test_normal.vim14
-rw-r--r--test/old/testdir/test_utf8_comparisons.vim37
-rw-r--r--test/old/testdir/test_visual.vim6
6 files changed, 61 insertions, 21 deletions
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index fd353d8a67..f8451e62e2 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -1323,6 +1323,9 @@ int utf_fold(int a)
// invalid values or can't handle latin1 when the locale is C.
// Speed is most important here.
+// Note: UnicodeData.txt does not define U+1E9E as being the corresponding upper
+// case letter for U+00DF (ß), however it is part of the toLower table
+
/// Return the upper-case equivalent of "a", which is a UCS-4 character. Use
/// simple case folding.
int mb_toupper(int a)
diff --git a/src/nvim/ops.c b/src/nvim/ops.c
index d785be54e5..f91df49e4f 100644
--- a/src/nvim/ops.c
+++ b/src/nvim/ops.c
@@ -2165,16 +2165,16 @@ bool swapchar(int op_type, pos_T *pos)
return false;
}
- if (op_type == OP_UPPER && c == 0xdf) {
+ // ~ is OP_NOP, g~ is OP_TILDE, gU is OP_UPPER
+ if ((op_type == OP_UPPER || op_type == OP_NOP || op_type == OP_TILDE) && c == 0xdf) {
pos_T sp = curwin->w_cursor;
- // Special handling of German sharp s: change to "SS".
+ // Special handling for lowercase German sharp s (ß): convert to uppercase (ẞ).
curwin->w_cursor = *pos;
del_char(false);
- ins_char('S');
- ins_char('S');
+ ins_char(0x1E9E);
curwin->w_cursor = sp;
- inc(pos);
+ return true;
}
int nc = c;
diff --git a/test/functional/legacy/039_visual_block_mode_commands_spec.lua b/test/functional/legacy/039_visual_block_mode_commands_spec.lua
index 626035d74c..bc3fea765c 100644
--- a/test/functional/legacy/039_visual_block_mode_commands_spec.lua
+++ b/test/functional/legacy/039_visual_block_mode_commands_spec.lua
@@ -134,7 +134,7 @@ describe('Visual block mode', function()
end)
it('should make a selected part uppercase', function()
- -- GUe must uppercase a whole word, also when ß changes to SS.
+ -- GUe must uppercase a whole word, also when ß changes to ẞ.
feed('Gothe youtußeuu end<ESC>Ypk0wgUe<CR>')
-- GUfx must uppercase until x, inclusive.
feed('O- youßtußexu -<ESC>0fogUfx<CR>')
@@ -150,13 +150,13 @@ describe('Visual block mode', function()
expect([[
- the YOUTUSSEUU end
- - yOUSSTUSSEXu -
- THE YOUTUSSEUU END
- 111THE YOUTUSSEUU END
+ the YOUTUẞEUU end
+ - yOUẞTUẞEXu -
+ THE YOUTUẞEUU END
+ 111THE YOUTUẞEUU END
BLAH DI
DOH DUT
- 222the yoUTUSSEUU END
+ 222the yoUTUẞEUU END
333THE YOUTUßeuu end]])
end)
diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim
index b98547061e..91c058df9e 100644
--- a/test/old/testdir/test_normal.vim
+++ b/test/old/testdir/test_normal.vim
@@ -2353,19 +2353,19 @@ func Test_normal30_changecase()
norm! 1ggVu
call assert_equal('this is a simple test: äüöß', getline('.'))
norm! VU
- call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
norm! guu
- call assert_equal('this is a simple test: äüöss', getline('.'))
+ call assert_equal('this is a simple test: äüöß', getline('.'))
norm! gUgU
- call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
norm! gugu
- call assert_equal('this is a simple test: äüöss', getline('.'))
+ call assert_equal('this is a simple test: äüöß', getline('.'))
norm! gUU
- call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖSS', getline('.'))
+ call assert_equal('THIS IS A SIMPLE TEST: ÄÜÖẞ', getline('.'))
norm! 010~
- call assert_equal('this is a SIMPLE TEST: ÄÜÖSS', getline('.'))
+ call assert_equal('this is a SIMPLE TEST: ÄÜÖẞ', getline('.'))
norm! V~
- call assert_equal('THIS IS A simple test: äüöss', getline('.'))
+ call assert_equal('THIS IS A simple test: äüöß', getline('.'))
call assert_beeps('norm! c~')
%d
call assert_beeps('norm! ~')
diff --git a/test/old/testdir/test_utf8_comparisons.vim b/test/old/testdir/test_utf8_comparisons.vim
index f3c86b44fb..20b5762c9d 100644
--- a/test/old/testdir/test_utf8_comparisons.vim
+++ b/test/old/testdir/test_utf8_comparisons.vim
@@ -92,3 +92,40 @@ func Test_gap()
call feedkeys("gg0g~ap", "tx")
call assert_equal(["ABCD", "", "defg"], getline(1,3))
endfunc
+
+" test that g~, ~ and gU correclty upper-cases ß
+func Test_uppercase_sharp_ss()
+ new
+ call setline(1, repeat(['ß'], 4))
+
+ call cursor(1, 1)
+ norm! ~
+ call assert_equal('ẞ', getline(line('.')))
+ norm! ~
+ call assert_equal('ß', getline(line('.')))
+
+ call cursor(2, 1)
+ norm! g~l
+ call assert_equal('ẞ', getline(line('.')))
+ norm! g~l
+ call assert_equal('ß', getline(line('.')))
+
+ call cursor(3, 1)
+ norm! gUl
+ call assert_equal('ẞ', getline(line('.')))
+ norm! vgU
+ call assert_equal('ẞ', getline(line('.')))
+ norm! vgu
+ call assert_equal('ß', getline(line('.')))
+ norm! gul
+ call assert_equal('ß', getline(line('.')))
+
+ call cursor(4, 1)
+ norm! vgU
+ call assert_equal('ẞ', getline(line('.')))
+ norm! vgu
+ call assert_equal('ß', getline(line('.')))
+ bw!
+endfunc
+
+" vim: shiftwidth=2 sts=2 expandtab
diff --git a/test/old/testdir/test_visual.vim b/test/old/testdir/test_visual.vim
index 983f07a375..94b8009534 100644
--- a/test/old/testdir/test_visual.vim
+++ b/test/old/testdir/test_visual.vim
@@ -1022,9 +1022,9 @@ func Test_visual_change_case()
exe "normal Oblah di\rdoh dut\<Esc>VkUj\r"
" Uppercase part of two lines
exe "normal ddppi333\<Esc>k0i222\<Esc>fyllvjfuUk"
- call assert_equal(['the YOUTUSSEUU end', '- yOUSSTUSSEXu -',
- \ 'THE YOUTUSSEUU END', '111THE YOUTUSSEUU END', 'BLAH DI', 'DOH DUT',
- \ '222the yoUTUSSEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
+ call assert_equal(['the YOUTUẞEUU end', '- yOUẞTUẞEXu -',
+ \ 'THE YOUTUẞEUU END', '111THE YOUTUẞEUU END', 'BLAH DI', 'DOH DUT',
+ \ '222the yoUTUẞEUU END', '333THE YOUTUßeuu end'], getline(2, '$'))
bwipe!
endfunc