From 28cfd0bb61f5c60279358a7e58d5b6f68a1255f1 Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 24 Sep 2016 18:52:54 +0100 Subject: [PATCH] Fix get_column function and add some unit tests for fullwidth text --- src/buffer_utils.cc | 18 +++++++++++++----- src/highlighters.cc | 6 +++--- test/unit/codepoint-width/tab-width/cmd | 1 + test/unit/codepoint-width/tab-width/in | 2 ++ test/unit/codepoint-width/tab-width/selections | 1 + .../unit/codepoint-width/vertical-movement/cmd | 1 + test/unit/codepoint-width/vertical-movement/in | 2 ++ .../vertical-movement/selections | 1 + 8 files changed, 24 insertions(+), 8 deletions(-) create mode 100644 test/unit/codepoint-width/tab-width/cmd create mode 100644 test/unit/codepoint-width/tab-width/in create mode 100644 test/unit/codepoint-width/tab-width/selections create mode 100644 test/unit/codepoint-width/vertical-movement/cmd create mode 100644 test/unit/codepoint-width/vertical-movement/in create mode 100644 test/unit/codepoint-width/vertical-movement/selections diff --git a/src/buffer_utils.cc b/src/buffer_utils.cc index 20d24118..ff018096 100644 --- a/src/buffer_utils.cc +++ b/src/buffer_utils.cc @@ -18,13 +18,15 @@ ColumnCount get_column(const Buffer& buffer, auto line = buffer[coord.line]; auto col = 0_col; for (auto it = line.begin(); - it != line.end() and coord.column > (int)(it - line.begin()); - it = utf8::next(it, line.end())) + it != line.end() and coord.column > (int)(it - line.begin()); ) { if (*it == '\t') + { col = (col / tabstop + 1) * tabstop; + ++it; + } else - ++col; + col += get_width(utf8::read_codepoint(it, line.end())); } return col; } @@ -41,10 +43,16 @@ ByteCount get_byte_to_column(const Buffer& buffer, ColumnCount tabstop, DisplayC col = (col / tabstop + 1) * tabstop; if (col > coord.column) // the target column was in the tab break; + ++it; } else - ++col; - it = utf8::next(it, line.end()); + { + auto next = it; + col += get_width(utf8::read_codepoint(next, line.end())); + if (col > coord.column) // the target column was in the char + break; + it = next; + } } return (int)(it - line.begin()); } diff --git a/src/highlighters.cc b/src/highlighters.cc index 2ee019a4..13bbbdc5 100644 --- a/src/highlighters.cc +++ b/src/highlighters.cc @@ -648,7 +648,7 @@ HighlighterAndId create_column_highlighter(HighlighterParameters params) void expand_tabulations(const Context& context, HighlightFlags flags, DisplayBuffer& display_buffer, BufferRange) { - const int tabstop = context.options()["tabstop"].get(); + const ColumnCount tabstop = context.options()["tabstop"].get(); auto& buffer = context.buffer(); for (auto& line : display_buffer.lines()) { @@ -668,8 +668,8 @@ void expand_tabulations(const Context& context, HighlightFlags flags, DisplayBuf if (it+1 != end) atom_it = line.split(atom_it, (it+1).coord()); - int column = (int)get_column(buffer, tabstop, it.coord()); - int count = tabstop - (column % tabstop); + ColumnCount column = get_column(buffer, tabstop, it.coord()); + ColumnCount count = tabstop - (column % tabstop); String padding; for (int i = 0; i < count; ++i) padding += ' '; diff --git a/test/unit/codepoint-width/tab-width/cmd b/test/unit/codepoint-width/tab-width/cmd new file mode 100644 index 00000000..4c559f78 --- /dev/null +++ b/test/unit/codepoint-width/tab-width/cmd @@ -0,0 +1 @@ +j diff --git a/test/unit/codepoint-width/tab-width/in b/test/unit/codepoint-width/tab-width/in new file mode 100644 index 00000000..9c911221 --- /dev/null +++ b/test/unit/codepoint-width/tab-width/in @@ -0,0 +1,2 @@ +一 %(二) +1234567890 diff --git a/test/unit/codepoint-width/tab-width/selections b/test/unit/codepoint-width/tab-width/selections new file mode 100644 index 00000000..ec635144 --- /dev/null +++ b/test/unit/codepoint-width/tab-width/selections @@ -0,0 +1 @@ +9 diff --git a/test/unit/codepoint-width/vertical-movement/cmd b/test/unit/codepoint-width/vertical-movement/cmd new file mode 100644 index 00000000..b68fde2a --- /dev/null +++ b/test/unit/codepoint-width/vertical-movement/cmd @@ -0,0 +1 @@ +k diff --git a/test/unit/codepoint-width/vertical-movement/in b/test/unit/codepoint-width/vertical-movement/in new file mode 100644 index 00000000..9a4f1e62 --- /dev/null +++ b/test/unit/codepoint-width/vertical-movement/in @@ -0,0 +1,2 @@ +123456789012 +一%(二)三%(四)五六 diff --git a/test/unit/codepoint-width/vertical-movement/selections b/test/unit/codepoint-width/vertical-movement/selections new file mode 100644 index 00000000..564e0714 --- /dev/null +++ b/test/unit/codepoint-width/vertical-movement/selections @@ -0,0 +1 @@ +3:7