当光标处于换行符并且我已关闭(move-to-column pos t)
时,我遇到问题indent-tabs-mode
正常工作,即:(setq-default indent-tabs-mode nil)
。
在这种情况下,如果例如该点位于第0列,并且此时有一个换行符(使用(whitespace-mode)
查看换行符很有帮助)并发出命令{{ 1}}该点不会移动到第10列。而是将该点移动到第9列。
更新
要说明问题,请首先考虑以下Emacs缓冲区
(颜色归因于(move-to-column 10 t)
)。光标位于缓冲区第二行的第0列。光标前面有一个换行符。我现在发出命令(whitespace-mode)
,我得到了以下屏幕
请注意,光标位于第9列(不是第10列,应该如此)。如果光标未定位到换行符,并且在接下来的10个缓冲区中没有换行符,则(move-to-column 10 t)
按预期工作。例如,请考虑以下情况
请注意,现在没有换行符(位于缓冲区第三行的开头),并且在以下10个缓冲区位置中没有换行符。如果我现在发出{{1}我得到了
我们看到这一点已经转移到第10列,因为它应该......
答案 0 :(得分:2)
现在至少部分回答:
我在Ubuntu 13.04下使用emacs 24.3.1。
在那里,效果只能用whitespace-mode
重现。因此,indent-tabs-mode
以及dos或unix的缓冲区编码并不重要。
whitespace-mode
摆弄了buffer-display-table
。
修改后的buffer-display-table
很容易导致move-to-column
的意外结果。
如果执行以下代码(例如,使用 M - :),move-to-column
与whitespace-mode
的效果可以在没有whitespace-mode
的情况下重现:
(setq buffer-display-table (make-display-table))
(aset buffer-display-table ?\n [?$ ?\n])
您可以通过以下方式恢复此效果:
(aset buffer-display-table ?\n nil)
如果更改任何其他文本字符的显示字符数,您将获得move-to-column
的类似意外效果。 E.g:
使用
(aset buffer-display-table ?\§ [?\§ ?\$])
和缓冲区内容
§
你得到了显示
§$
如果您呼叫(move-to-column 1 t)
点移动到此显示字符串的末尾,即使这会显示两个字符。
您可以通过以下方式恢复此设置:
(aset buffer-display-table ?\§ nil)
另一个相当有趣的设置是:
(aset buffer-display-table ?\n [?1 ?2 ?3 ?\n])
使用此设置,换行符长度为三个显示字符(仅限换行符)。 一个换行符显示为:
123
如果当前点位于该行的开头,则命令(move-to-column 3 t)
不会移动点但返回3.
请注意,此行为与正常设置的情况一致
(aset buffer-display-table ?\n nil)
如果有两个连续的换行符并且点位于介于两者之间,那么即使第0列上没有字符,(move-to-column 0 t)
也会在换行符之前放置点。
也许,这与点位置在字符之间的解释有关。对于空缓冲区,其中(point)
== (point-min)
== (point-max)
。这种解释也赋予(point-max)
== (1+ (buffer-size))
其含义。
我在此引用信息节点following-char
中(elisp) Near Point
的说明:
“请记住,点始终在字符和光标之间 通常出现在角色跟随点之上。因此, `following-char'返回的字符是字符 光标结束了。“
move-to-column
(注意,以下仅仅是我的解释。如果真正了解move-to-column
功能意图的人能够承认,否认或纠正这些内容,那将是很好的。)
以下讨论说明move-to-column
的字符之间的点位置的后果。
我们用pos0,pos1,...表示点位置,用char1,char2,......表示字符。
如果buffer-display-table
中的字符char1的条目是长度为>的向量[char1a char1b ...]
,我们使用标记char1a,char1b,.... 1.在下文中,我们将此字符命名为 复合字符 。
正常情况(无复合字符):
pos0 char1 pos1 char2 pos2 nl
(move-to-column 2 t)
表示将点放在nlchar之前。
buffer-display-table
中复合字符char1 = [char1a char1b]的情况:
pos0 char1a pos1 char1b pos2 nl
move-to-column
尊重复合字符的显示大小,但不能将点放在中间。
Point只能放在复合字符的边界上。
在这种情况下,(move-to-column 1 t)
移动指向位置pos2。
现在,让新行字符为组合字符nl = [nla nlb]。
pos0 char1 pos1 char2 pos2 nla pos3 nlb
此处,(move-to-column 3 t)
到达组合换行符的中间。
点还在这一行。因此将点放在nlb之后是没有意义的。 Emacs不能在pos3处放置点,因为它位于组合字符的中间。因此,定位点的唯一合理方法是pos2。