处理 vim 中文行禁则的一个 Patch

Vim、Emacs配置和使用
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

处理 vim 中文行禁则的一个 Patch

#1

帖子 yswzing. » 2010-10-29 13:53

这个 Patch 有两个功能,第一个是处理中文排版时的行禁则问题,第二个是去掉 Join 时 中文标点和英文之间多余的空格。目前仅支持 UTF8,是在最新 mercurial 仓库代码基础上做的 patch。

1 中文行禁则的问题

Vim 对中文的行禁则支持的不好,在写中文文本的时候,经常会出现逗号、句号等跑到行首 的情况。使用 gq 系列命令重排文本的时候,也会发生这种情况。因为英文的行禁则很简单, 只在空格处断行,而中文不同,可以在任何地方断行,但是必须遵守行禁则。vim 实现了可 以在中文的任何地方断行,但是没有考虑行禁则。

这个 Patch 在 vim 中加入了中文行禁则支持,并且支持标点符号右悬挂,即本应该在一个 句号之前断行时,不是将句号和它之前的一个字符移到下一行,而是将句号悬挂在上一行后 面。

例子(set tw=34):

原来的 vim:
---------------
Vim 对中文的行禁则支持的不好,在写
中文文本的时候,经常会出现逗号、句
号等跑到行首的情况。使用 gq 系列命
令重排文本的时候,也会发生这种情况
。因为英文的行禁则很简单,只在空格
处断行,而中文不同,可以在任何地方
断行,但是必须遵守行禁则。vim 实现
了可以在中文的任何地方断行,但是没
有考虑行禁则。
---------------
打了 Patch 之后:
---------------
Vim 对中文的行禁则支持的不好,在写
中文文本的时候,经常会出现逗号、句
号等跑到行首的情况。使用 gq 系列命
令重排文本的时候,也会发生这种情况。
因为英文的行禁则很简单,只在空格处
断行,而中文不同,可以在任何地方断
行,但是必须遵守行禁则。vim 实现了
可以在中文的任何地方断行,但是没有
考虑行禁则。
---------------

2 Join 时中文标点和英文之间多余空格问题

此 Patch 只针对在 formatoptions 选项中加了 B 标志的情况。如果你使用的是 M 标志, 那么这个 Patch 对你没有任何影响。

在使用 J 命令,或者 gq 系列命令时,会先将行连接起来。连接的时候,如果前一行尾或下一行首的两个字符,一个是中文标点或符号,另一个是英文字符,就会在中间插入一个多余的空格。原因也是 vim 将所有中文字符一视同仁,没有考虑普通字符和标点符号的不同。这 个 Patch 会处理这种情况,避免在中文标点或符号与英文字符之间插入空格,但是仍然保留 普通中文字符和英文字符之间的空格。

例子:
---------------
令重排文本的时候,也会发生这种情况。
Vim 对中文的行禁则支持的不好,在写
---------------
原来的 vim:
---------------
令重排文本的时候,也会发生这种情况。 Vim 对中文的行禁则支持的不好,在写
---------------
打了 Patch 之后:
---------------
令重排文本的时候,也会发生这种情况。Vim 对中文的行禁则支持的不好,在写
---------------
欢迎大家试用,多提宝贵意见!有 Bug 或改进意见的话发邮件给我: yswzing at gmail.com
附件
fix_line_break3.txt
(8.54 KiB) 已下载 332 次
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: 处理 vim 中文行禁则的一个 Patch

#2

帖子 Strange » 2010-10-29 14:30

中文行禁则 到底是什么?
谁能贴一下详细规则?

关于patch,还不如把功能做成option试着提交到vim_dev上去
ニンニク入れますか?
x60 with gentoo
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

Re: 处理 vim 中文行禁则的一个 Patch

#3

帖子 yswzing. » 2010-10-29 22:00

所谓的行禁则就是有些标点符号不能放在行首,比如[,。]之类;有些不能放在行尾,比如 [(“]之类。

希望中文用户能够先测试一下,如果没有问题的话再提交官方。
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 处理 vim 中文行禁则的一个 Patch

#4

帖子 lilydjwg » 2010-10-29 23:55

打上了,貌似非常不错!
风间星魂
帖子: 490
注册时间: 2009-06-20 23:53

Re: 处理 vim 中文行禁则的一个 Patch

#5

帖子 风间星魂 » 2010-10-31 17:23

lz干的很好!不知道能否把补丁提交给Bram :em06 也好让更多人收益
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: 处理 vim 中文行禁则的一个 Patch

#6

帖子 Strange » 2010-10-31 18:58

这个一定要做成option或者能够用resource文件配置才可以,patch里对标点符号也是硬编码的
ニンニク入れますか?
x60 with gentoo
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

Re: 处理 vim 中文行禁则的一个 Patch

#7

帖子 yswzing. » 2010-10-31 23:17

1. 在 formatoptions 选项中增加了一个标志 `]',如果设置的话表示严格遵守 textwidth,没有设置的话可以将标点符号悬挂在一行的结尾;默认是不设置的;
2. Refactoring 代码。

至于添加一个选项用来设置哪些是行尾标点,哪些是行首标点,至少我现在觉得是没有必要有这种灵活性的,或许有人可以举出一个有说服力的例子来。
附件
fix_line_break5.txt
(8.7 KiB) 已下载 218 次
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: 处理 vim 中文行禁则的一个 Patch

#8

帖子 Strange » 2010-11-01 11:07

因为vim是通用编辑器,只对部分中文用户有用的功能,适合放到source tree里吗?
我觉得不但要添加这个选项,而且还要添加编译选项,毕竟这个小众选项对于大多数不用这个功能的用户来说,编译进程序就是一个奇怪的事情了。
ニンニク入れますか?
x60 with gentoo
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 处理 vim 中文行禁则的一个 Patch

#9

帖子 lilydjwg » 2010-11-01 13:09

Strange 写了:因为vim是通用编辑器,只对部分中文用户有用的功能,适合放到source tree里吗?
我觉得不但要添加这个选项,而且还要添加编译选项,毕竟这个小众选项对于大多数不用这个功能的用户来说,编译进程序就是一个奇怪的事情了。
+1。 就像 +multi_byte 那样需要编译时开启的
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 处理 vim 中文行禁则的一个 Patch

#10

帖子 lilydjwg » 2010-11-01 22:06

呃,没有更新文档?
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

Re: 处理 vim 中文行禁则的一个 Patch

#11

帖子 yswzing. » 2010-11-02 10:57

Strange 写了:因为vim是通用编辑器,只对部分中文用户有用的功能,适合放到source tree里吗?
我觉得不但要添加这个选项,而且还要添加编译选项,毕竟这个小众选项对于大多数不用这个功能的用户来说,编译进程序就是一个奇怪的事情了。
这个 patch 处于 FEAT_MBYTE 编译选项的控制之下,因为修改的那一段代码原来就已经处于 FEAT_MBYTE 控制之下,所以从 patch 文件中可能看不出来。不过你确实提醒了我,又检查一遍,发现一个变量声明没有被控制,已经改了。

另,文档也已经更新了。

至于增加标点符号选项的问题,我的想法是这样的:
1. 首先只有多字节语言是需要这个选项的,英文等单字节编码的语言不需要;
2. 多字节语言为数不多,主要是东亚语言 CJK,这些语言中的标点符号很多是相同的,总数也不多;
3. 如果增加一个选项,而所有用户的设置完全相同的话,这个选项就是没有必要的,反而增加了用户的负担。

试想一下,如果增加了这个选项,你会为其设置什么值呢?日文用户、韩文用户又会设置什么值呢?你的设置和日韩用户的设置会不会冲突呢?如果不冲突的话,会什么不设置一个超集直接内建在 vim 中,这样大家不都更方便了吗?
附件
fix_line_break6.txt
(9.16 KiB) 已下载 227 次
头像
Strange
帖子: 1824
注册时间: 2006-05-19 9:54
来自: Shanghai

Re: 处理 vim 中文行禁则的一个 Patch

#12

帖子 Strange » 2010-11-02 12:22

这个 patch 处于 FEAT_MBYTE 编译选项的控制之下,因为修改的那一段代码原来就已经处于 FEAT_MBYTE 控制之下,所以从 patch 文件中可能看不出来。
使用MBYTE的人又未必需要这个功能。feature=big时MBYTE已经是默认选项了。外国人虽然看不懂不会整理MBYTE文档,但是也不想看到乱码呀。
试想一下,如果增加了这个选项,你会为其设置什么值呢?日文用户、韩文用户又会设置什么值呢?你的设置和日韩用户的设置会不会冲突呢?如果不冲突的话,会什么不设置一个超集直接内建在 vim 中,这样大家不都更方便了吗?
有一个原则是 提供机制而不是限制。

试想万一有人排版不想用禁则怎么办。有人除了"。",还想把";"留在行末怎么办。

再说日文韩文和中文标点符号差异还是有的。
拿日文来说,",“”"这些都是没有的,取而代之的是"、「」",你准备把这些字符也硬编码吗?
就是因为不知道设置是否和日韩用户冲突,所以更要提供选项。

不管怎么样说,像硬编码这样的做法,是不符合 Vim is a highly configurable text editor 的风格的。
ニンニク入れますか?
x60 with gentoo
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 处理 vim 中文行禁则的一个 Patch

#13

帖子 lilydjwg » 2010-11-02 14:14

我想到一些不用禁则的特殊情况:排版符号表/字符艺术。比如我拿一些标点,列成 10×10 的方阵。或者使用多字节字符来排字符艺术。再者,示例中可能不用禁则(比如对比禁则前后排版差异)。
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

Re: 处理 vim 中文行禁则的一个 Patch

#14

帖子 yswzing. » 2010-11-02 16:41

Strange 写了: 使用MBYTE的人又未必需要这个功能。feature=big时MBYTE已经是默认选项了。外国人虽然看不懂不会整理MBYTE文档,但是也不想看到乱码呀。
这里没有看明白是什么意思,难道行禁则不是期望的一个功能吗?会有人故意关闭?能举出一个例子吗,不是纯粹假设意义上的?再有不管怎么说,这个 patch 也不会引入乱码,不知道乱码之说从何而来。
有一个原则是 提供机制而不是限制。
提供机制而不是提供策略。那是设计 infrastructure 或 architecture 时的理念。
试想万一有人排版不想用禁则怎么办。有人除了"。",还想把";"留在行末怎么办。

再说日文韩文和中文标点符号差异还是有的。
拿日文来说,",“”"这些都是没有的,取而代之的是"、「」",你准备把这些字符也硬编码吗?
Patch 中已经按照 Unicode 规范将大部分(不敢保证所有,但是如果有人发现少了的话,可以加进去)的 CJK 标点符号纳入了考虑。像你所说的 `;' 已经在 patch 里了。`、「」' 也是中文标点,已经在 Patch 中考虑了。

日韩文和中文的标点符号差异没有关系,只要不冲突就行。设置一个超集就可以了。我想,Unicode 规范设计的时候也不会让 CJK 标点符号相互冲突的。一个比较自然的推测是它们是不冲突的,当然我对日韩文一窍不通,如果有了解的人举出真正的例子来,我可能会重新考虑。
就是因为不知道设置是否和日韩用户冲突,所以更要提供选项。

不管怎么样说,像硬编码这样的做法,是不符合 Vim is a highly configurable text editor 的风格的。
不敢苟同这种说法,如果不明白的话,就搞明白,根据事实来设计,而不是在不明白的情况下根据假设来设计。对于变化的或不确定的需求,设置可配置的选项是正常的,如果是固定的需求,再设置选项就是多余了。好比对英文设置行禁则选项,不是多此一举吗?
上次由 yswzing. 在 2010-11-02 16:51,总共编辑 1 次。
yswzing.
帖子: 8
注册时间: 2010-10-29 13:49

Re: 处理 vim 中文行禁则的一个 Patch

#15

帖子 yswzing. » 2010-11-02 16:44

lilydjwg 写了:我想到一些不用禁则的特殊情况:排版符号表/字符艺术。比如我拿一些标点,列成 10×10 的方阵。或者使用多字节字符来排字符艺术。再者,示例中可能不用禁则(比如对比禁则前后排版差异)。
请考虑一下如果你是在排版一个英文的类似需求,你会怎么做?英文也有行禁则,并且你没法关掉。

如果你不想让 vim 自动断行,设置 textwidth=0 即可。
回复