修复从右到左语言切换时 Atom 光标的行为
Fixing Atom cursor's behaviour when switching to right to left languages
我一直在尝试更改文本编辑器 Atom 的默认设置以支持 RTL(从右到左)语言。
所以在 class LinesTileComponent
上,我添加了一个新属性 dir="rtl"
here。
这已将整个脚本切换到右侧,如此处所示。
输入阿拉伯语时光标消失。对文本的任何点击都不会带回光标(稍后会在 GIF 中发生)。我无法 select 一个特定的单词,当我点击 RTL 文本后光标只出现在左边。
我怀疑这可能是由于 cursor.js, cursor.less or in selection.js 或其他人的代码造成的。
我正在努力修复此光标的行为。是否有任何特定文件或快速修复可以帮助您解决此问题?
这是一个很难修复的错误。已在 Github PR 上提交修复以供 RTL 检查和贡献。
总而言之,开发人员使用二分搜索算法来查找用户点击了哪个字母。二进制搜索方法假设单词的后半部分总是在右边。这与 RTL 语言相反,因为工作的后半部分在左侧。这是关于我如何制作修复原型的 snippet:
let characterIndex = 0;
{
let low = 0;
let high = containingTextNode.length - 1;
while (low <= high) {
const charIndex = low + ((high - low) >> 1);
const nextCharIndex = isPairedCharacter(
containingTextNode.textContent,
charIndex
)
? charIndex + 2
: charIndex + 1;
const rangeRect = clientRectForRange(
containingTextNode,
charIndex,
nextCharIndex
);
if (targetClientLeft < rangeRect.left && !rtl) {
high = charIndex - 1;
characterIndex = Math.max(0, charIndex - 1);
} else if (targetClientLeft > rangeRect.right && !rtl) {
low = nextCharIndex;
characterIndex = Math.min(
containingTextNode.textContent.length,
nextCharIndex
);
} else if (targetClientLeft > rangeRect.right && rtl) {
high = charIndex - 1;
characterIndex = Math.max(0, charIndex - 1);
} else if (targetClientLeft < rangeRect.left && rtl) {
low = nextCharIndex;
characterIndex = Math.min(
containingTextNode.textContent.length,
nextCharIndex
);
} else {
if (!rtl){
if (targetClientLeft <= (rangeRect.left + rangeRect.right) / 2) {
characterIndex = charIndex;
} else {
characterIndex = nextCharIndex;
}
}else{
if (targetClientLeft <= (rangeRect.left + rangeRect.right) / 2) {
characterIndex = nextCharIndex;
} else {
characterIndex = charIndex;
}
}
break;
}
}
}
不幸的是,这段代码仍然缺少一些功能,例如在同一行中处理 RTL 和 LTR 内容以及其他小错误。应该做更多的工作并开放合作,please contribute to this PR。
我一直在尝试更改文本编辑器 Atom 的默认设置以支持 RTL(从右到左)语言。
所以在 class LinesTileComponent
上,我添加了一个新属性 dir="rtl"
here。
这已将整个脚本切换到右侧,如此处所示。
输入阿拉伯语时光标消失。对文本的任何点击都不会带回光标(稍后会在 GIF 中发生)。我无法 select 一个特定的单词,当我点击 RTL 文本后光标只出现在左边。
我怀疑这可能是由于 cursor.js, cursor.less or in selection.js 或其他人的代码造成的。
我正在努力修复此光标的行为。是否有任何特定文件或快速修复可以帮助您解决此问题?
这是一个很难修复的错误。已在 Github PR 上提交修复以供 RTL 检查和贡献。
总而言之,开发人员使用二分搜索算法来查找用户点击了哪个字母。二进制搜索方法假设单词的后半部分总是在右边。这与 RTL 语言相反,因为工作的后半部分在左侧。这是关于我如何制作修复原型的 snippet:
let characterIndex = 0;
{
let low = 0;
let high = containingTextNode.length - 1;
while (low <= high) {
const charIndex = low + ((high - low) >> 1);
const nextCharIndex = isPairedCharacter(
containingTextNode.textContent,
charIndex
)
? charIndex + 2
: charIndex + 1;
const rangeRect = clientRectForRange(
containingTextNode,
charIndex,
nextCharIndex
);
if (targetClientLeft < rangeRect.left && !rtl) {
high = charIndex - 1;
characterIndex = Math.max(0, charIndex - 1);
} else if (targetClientLeft > rangeRect.right && !rtl) {
low = nextCharIndex;
characterIndex = Math.min(
containingTextNode.textContent.length,
nextCharIndex
);
} else if (targetClientLeft > rangeRect.right && rtl) {
high = charIndex - 1;
characterIndex = Math.max(0, charIndex - 1);
} else if (targetClientLeft < rangeRect.left && rtl) {
low = nextCharIndex;
characterIndex = Math.min(
containingTextNode.textContent.length,
nextCharIndex
);
} else {
if (!rtl){
if (targetClientLeft <= (rangeRect.left + rangeRect.right) / 2) {
characterIndex = charIndex;
} else {
characterIndex = nextCharIndex;
}
}else{
if (targetClientLeft <= (rangeRect.left + rangeRect.right) / 2) {
characterIndex = nextCharIndex;
} else {
characterIndex = charIndex;
}
}
break;
}
}
}
不幸的是,这段代码仍然缺少一些功能,例如在同一行中处理 RTL 和 LTR 内容以及其他小错误。应该做更多的工作并开放合作,please contribute to this PR。