mirror of
https://github.com/fish-shell/fish-shell.git
synced 2026-06-24 09:21:16 -03:00
src/screen: Only check for combining marks if necessary
line_shared_prefix explains in its comment that > If the prefix ends on a combining character, do not include the previous character in the prefix. But that's not what it does. Instead, what it appears to do is to return idx for *every* combining mark. This seems wrong to begin with, and it also requires checking wcwidth for *every* character. So instead we don't do that. If we find the mismatch, we check if it's a combining mark, and then go back to the previous character (i.e. the one before the one that the combining mark is for). My tests found no issues with this, other than a 20% reduction in pasting time.
This commit is contained in:
@@ -552,14 +552,25 @@ static size_t line_shared_prefix(const line_t &a, const line_t &b) {
|
||||
size_t idx, max = std::min(a.size(), b.size());
|
||||
for (idx = 0; idx < max; idx++) {
|
||||
wchar_t ac = a.char_at(idx), bc = b.char_at(idx);
|
||||
if (fish_wcwidth(ac) < 1 || fish_wcwidth(bc) < 1) {
|
||||
// Possible combining mark, return one index prior.
|
||||
if (idx > 0) idx--;
|
||||
break;
|
||||
}
|
||||
|
||||
// We're done if the text or colors are different.
|
||||
if (ac != bc || a.color_at(idx) != b.color_at(idx)) break;
|
||||
if (ac != bc || a.color_at(idx) != b.color_at(idx)) {
|
||||
if (idx > 0) {
|
||||
const line_t *c = nullptr;
|
||||
// Possible combining mark, go back until we hit _two_ printable characters or idx of 0.
|
||||
if (fish_wcwidth(a.char_at(idx)) < 1) {
|
||||
c = &a;
|
||||
} else if (fish_wcwidth(b.char_at(idx)) < 1) {
|
||||
c = &b;
|
||||
}
|
||||
|
||||
if (c) {
|
||||
while (idx > 1 && (fish_wcwidth(c->char_at(idx - 1)) < 1 || fish_wcwidth(c->char_at(idx)) < 1)) idx--;
|
||||
if (idx == 1 && fish_wcwidth(c->char_at(idx)) < 1) idx = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user