有没有办法在 GNOME/GTK+ 中为文本配置系统范围的单词分隔符?

有没有办法在 GNOME/GTK+ 中为文本配置系统范围的单词分隔符?

我正在寻找一种方法来定义或查看和修改哪些字符被 GNOME 视为单词边界,类似于“按字选择”字符用于 GNOME 终端 (相关问题) 或 rxvt 中的 cutchars。

例如,当我使用 gedit 时,我可以键入abc123xyz并双击,但只能选择三个字符,因为默认情况下数字被视为边界。我在 Tomboy 以及我测试过的至少其他几个 GNOME/GTK+ 应用程序中看到了同样的行为。它也存在于 Google Chrome 的位置栏中(但不在页面内),并且特别令人讨厌。我认为 Firefox 似乎没问题,因为它的 UI 是用 XUL 编写的,它正在做它自己的事情。

请注意,我正在寻找一个通用的解决方案,如果存在的话——我已经知道有gedit 插件特别是,也许还有其他针对每个应用程序的调整,但我想知道这是否可以以影响从窗口管理器继承此行为的大多数或所有程序的方式完成(我假设?)。

答案1

显然,这个问题在 1.34.1 版本中已经修复。检查git 日志以及 1.34.0 和 1.34.1 标签之间的提交。Ubuntu 13.04 的 libpango1.0-0 版本与 sid 相同,为 1.32.5 版。因此,目前 Debian 发行版尚无好消息。如果您需要该库,可以从源代码编译它。

这是功能问题PangoLogAttr(),似乎没有人报告过有关该问题的错误。这个问题可以追溯到 2003 年,直到现在。您提供的电子邮件包括:

如果我对指南的解释是正确的,那么预计一个单词包含数字,该单词受数字的限制,与受空格和符号的限制相同,但不包括'

要报告 pango 的错误,请访问此链接https://bugzilla.gnome.org/enter_bug.cgi?product=pango

答案2

对于 Debian 7(Wheezy):

您可以从 Debian 下载源文件并自行进行更改,然后重新编译并安装创建的 .deb 包:

打开根终端:

apt-get install dpkg-dev;
apt-get build-dep libpango1.0-0;
exit;

打开常规终端:

cd; mkdir patch-libpango; cd patch-libpango;
apt-get source libpango1.0-0;

现在转到您的主文件夹并打开文件patch-libpango/pango1.0-1.30.0/pango/break.c,然后找到以下代码块:

/* ---- Word breaks ---- */

/* default to not a word start/end */
attrs[i].is_word_start = FALSE;
attrs[i].is_word_end = FALSE;

if (current_word_type != WordNone)
{
    /* Check for a word end */
    switch ((int) type)
    {
    case G_UNICODE_SPACING_MARK:
    case G_UNICODE_ENCLOSING_MARK:
    case G_UNICODE_NON_SPACING_MARK:
    case G_UNICODE_FORMAT:
        /* nothing, we just eat these up as part of the word */
        break;

    case G_UNICODE_LOWERCASE_LETTER:
    case G_UNICODE_MODIFIER_LETTER:
    case G_UNICODE_OTHER_LETTER:
    case G_UNICODE_TITLECASE_LETTER:
    case G_UNICODE_UPPERCASE_LETTER:
        if (current_word_type == WordLetters)
        {
            /* Japanese special cases for ending the word */
            if (JAPANESE (last_word_letter) ||
                    JAPANESE (wc))
            {
                if ((HIRAGANA (last_word_letter) &&
                            !HIRAGANA (wc)) ||
                        (KATAKANA (last_word_letter) &&
                            !(KATAKANA (wc) || HIRAGANA (wc))) ||
                        (KANJI (last_word_letter) &&
                            !(HIRAGANA (wc) || KANJI (wc))) ||
                        (JAPANESE (last_word_letter) &&
                            !JAPANESE (wc)) ||
                        (!JAPANESE (last_word_letter) &&
                            JAPANESE (wc)))
                attrs[i].is_word_end = TRUE;
            }
        }
        else
        {
            /* end the number word, start the letter word */
            attrs[i].is_word_end = TRUE;
            attrs[i].is_word_start = TRUE;
            current_word_type = WordLetters;
        }

        last_word_letter = wc;
        break;

    case G_UNICODE_DECIMAL_NUMBER:
    case G_UNICODE_LETTER_NUMBER:
    case G_UNICODE_OTHER_NUMBER:
        if (current_word_type != WordNumbers)
        {
            attrs[i].is_word_end = TRUE;
            attrs[i].is_word_start = TRUE;
            current_word_type = WordNumbers;
        }

        last_word_letter = wc;
        break;

    default:
        /* Punctuation, control/format chars, etc. all end a word. */
        attrs[i].is_word_end = TRUE;
        current_word_type = WordNone;
        break;
    }
}
else
{
    /* Check for a word start */
    switch ((int) type)
    {
    case G_UNICODE_LOWERCASE_LETTER:
    case G_UNICODE_MODIFIER_LETTER:
    case G_UNICODE_OTHER_LETTER:
    case G_UNICODE_TITLECASE_LETTER:
    case G_UNICODE_UPPERCASE_LETTER:
        current_word_type = WordLetters;
        last_word_letter = wc;
        attrs[i].is_word_start = TRUE;
        break;

    case G_UNICODE_DECIMAL_NUMBER:
    case G_UNICODE_LETTER_NUMBER:
    case G_UNICODE_OTHER_NUMBER:
        current_word_type = WordNumbers;
        last_word_letter = wc;
        attrs[i].is_word_start = TRUE;
        break;

    default:
        /* No word here */
        break;
    }
}

并将其替换为:

/* ---- Word breaks ---- */

/* default to not a word start/end */
attrs[i].is_word_start = FALSE;
attrs[i].is_word_end = FALSE;

if (current_word_type != WordNone)
{
    /* Check for a word end */
    switch ((int) type)
    {
    case G_UNICODE_SPACING_MARK:
    case G_UNICODE_ENCLOSING_MARK:
    case G_UNICODE_NON_SPACING_MARK:
    case G_UNICODE_FORMAT:
        /* nothing, we just eat these up as part of the word */
        break;

    case G_UNICODE_LOWERCASE_LETTER:
    case G_UNICODE_MODIFIER_LETTER:
    case G_UNICODE_OTHER_LETTER:
    case G_UNICODE_TITLECASE_LETTER:
    case G_UNICODE_UPPERCASE_LETTER:
        if (current_word_type == WordLetters)
        {
            /* Japanese special cases for ending the word */
            if (JAPANESE (last_word_letter) ||
                    JAPANESE (wc))
            {
                if ((HIRAGANA (last_word_letter) &&
                            !HIRAGANA (wc)) ||
                        (KATAKANA (last_word_letter) &&
                            !(KATAKANA (wc) || HIRAGANA (wc))) ||
                        (KANJI (last_word_letter) &&
                            !(HIRAGANA (wc) || KANJI (wc))) ||
                        (JAPANESE (last_word_letter) &&
                            !JAPANESE (wc)) ||
                        (!JAPANESE (last_word_letter) &&
                            JAPANESE (wc)))
                attrs[i].is_word_end = TRUE;
            }
        }

        last_word_letter = wc;
        break;

    case G_UNICODE_DECIMAL_NUMBER:
    case G_UNICODE_LETTER_NUMBER:
    case G_UNICODE_OTHER_NUMBER:

        last_word_letter = wc;
        break;

    default:
        if (wc == 0x005F) break; //underscore
        /* Punctuation, control/format chars, etc. all end a word. */
        attrs[i].is_word_end = TRUE;
        current_word_type = WordNone;
        break;
    }
}
else
{
    /* Check for a word start */
    switch ((int) type)
    {
    case G_UNICODE_LOWERCASE_LETTER:
    case G_UNICODE_MODIFIER_LETTER:
    case G_UNICODE_OTHER_LETTER:
    case G_UNICODE_TITLECASE_LETTER:
    case G_UNICODE_UPPERCASE_LETTER:
        current_word_type = WordLetters;
        last_word_letter = wc;
        attrs[i].is_word_start = TRUE;
        break;

    case G_UNICODE_DECIMAL_NUMBER:
    case G_UNICODE_LETTER_NUMBER:
    case G_UNICODE_OTHER_NUMBER:
        current_word_type = WordNumbers;
        last_word_letter = wc;
        attrs[i].is_word_start = TRUE;
        break;

    default:
        /* No word here */
        break;
    }
}

返回你的常规终端:

cd ~/patch-libpango/pango*;
dpkg-buildpackage -rfakeroot -uc -b;

现在转到主文件夹并打开该文件夹patch-libpango,您应该会.deb在那里找到一些文件。除了调试和文档包(文件名中带有 -dbg 和 -doc 的包)之外,安装所有文件

您现在可以删除该patch-libpango目录,并返回到您的常规终端:

cd; rm -rf patch-libpango;

完成后,您不需要重新启动系统。

注意:这也会将下划线视为单词的一部分(在编辑的代码中找到 0x005F)。

参考:

相关内容