简体   繁体   English

当点位于换行符时,在Emacs中关闭indent-tabs模式会导致移至列的故障

[英]Turning off indent-tabs-mode in Emacs causes malfunction in move-to-column when point is at a newline character

I have problem making (move-to-column pos t) work correctly when the cursor is at newline character and I have turned off indent-tabs-mode , that is: (setq-default indent-tabs-mode nil) . 当光标位于换行符并且我关闭了indent-tabs-mode ,即: (setq-default indent-tabs-mode nil)时,我无法使(move-to-column pos t)工作正常。

In that case, if for instance the point is at column 0, and there is a newline character at that point ( it is helpful to use (whitespace-mode) to see the newline characters ) and I issue the command (move-to-column 10 t) the point does not move to column 10. Instead the point moves to column 9. 在这种情况下,例如,如果该点位于第0列,并且在该点有换行符(使用(whitespace-mode)查看换行符会很有帮助),然后发出命令(move-to-column 10 t)的点不移动到塔10代替点移动到第9栏。

Update 更新

To give an illustration of the problem, consider first the following Emacs buffer 为了说明问题,请首先考虑以下Emacs缓冲区

在此处输入图片说明

(the colors are due to (whitespace-mode) ). (颜色归因于(whitespace-mode) )。 The cursor is position at column 0 at the second line of the buffer. 光标位于缓冲区第二行的第0列。 There is a newline character just in front of the cursor. 光标前面有一个换行符。 I now issue the command (move-to-column 10 t) and I get the follwing screen 现在,我发出命令(move-to-column 10 t)然后得到以下屏幕

在此处输入图片说明

Note that the cursor is positioned at column 9 (not at column 10, as it should). 请注意,光标位于第9列(而不是应位于第10列)。 If the cursor is not positioned at a newline character and there are no newline characters at the next 10 buffer positions move-to-column works as expected. 如果光标未定位在换行符上,并且在接下来的10个缓冲区位置没有换行符,则按move-to-column将按预期进行。 For instance, consider the following case 例如,考虑以下情况

在此处输入图片说明

Notice that there now is no newline characters at the point (which is at the beginning of the third line in the buffer) and there is no newline characters in the following 10 buffer positions.. If I now issue (move-to-column 10 t) I get 请注意,现在在该点(在缓冲区第三行的开头)没有换行符,并且在以下10个缓冲区位置也没有换行符。如果我现在发出(move-to-column 10 t)我明白了

在此处输入图片说明

and we see that the point has moved to column 10 as it should.. 我们看到该点已按原样移至第10列。

At least a partial answer for now: 目前至少有部分答案:

I am using emacs 24.3.1 under Ubuntu 13.04. 我正在Ubuntu 13.04下使用emacs 24.3.1。 There, the effect is only reproducible with whitespace-mode . 在那里,该效果仅可通过whitespace-mode复制。 Thereby, indent-tabs-mode and also the buffer encoding as dos or unix do not really matter. 因此, indent-tabs-mode以及dos或unix的缓冲区编码并不重要。

whitespace-mode fiddles with the buffer-display-table . whitespace-mode小提琴与buffer-display-table

With a modified buffer-display-table one easily gets unexpected results for move-to-column . 使用修改后的buffer-display-table可以很容易地获得move-to-column意外结果。

The effect of move-to-column with whitespace-mode can already be reproduced without whitespace-mode if one executes the following code (use, eg, M-: ): 如果执行以下代码(例如,使用M-:) ,则无需whitespace-mode whitespace-mode就可以复制带有whitespace-modemove-to-column的效果:

(setq buffer-display-table (make-display-table))
(aset buffer-display-table ?\n [?$ ?\n])

You can revert this effect by: 您可以通过以下方法恢复此效果:

(aset buffer-display-table ?\n nil)

You get a similarly unexpected effect of move-to-column if you change the number of displayed characters for any other text character. 如果更改任何其他文本字符的显示字符数,则会获得类似move-to-column效果。 Eg: 例如:

With

(aset buffer-display-table ?\§ [?\§ ?\$])

and the buffer content 和缓冲区内容

§ §

you get the display 你得到显示

§$ §$

If you call (move-to-column 1 t) point moves to the end of this displayed string even if this makes two displayed characters. 如果您调用(move-to-column 1 t) ,即使这使两个显示的字符都指向该显示的字符串的末尾。

You can revert this setting by: 您可以通过以下方式还原此设置:

(aset buffer-display-table ?\§ nil)

A further rather interesting setting is: 另一个更有趣的设置是:

(aset buffer-display-table ?\n [?1 ?2 ?3 ?\n])

With this setting the newline character is three displayed characters long (exclusively the line break). 使用此设置,换行符是三个显示的字符长(换行符除外)。 One linebreak is shown as: 一个换行符显示为:

123 123

If the current point is at the beginning of that line the command (move-to-column 3 t) does not move point but returns 3. 如果当前点在该行的开头,则命令(move-to-column 3 t)不会移动点,而是返回3。

Note, that this behaviour is consistent with the case of the normal setting 请注意,此行为与正常设置的情况一致

(aset buffer-display-table ?\n nil)

If there are two consecutive linebreaks and point is positioned in between then (move-to-column 0 t) does place point before the linebreak even if there is no character on column 0. 如果有两个连续的换行符,并且点位于它们之间,则即使行0上没有字符, (move-to-column 0 t)也会在换行符之前放置点。

Maybe, this is connected to the interpretation of point positions as being between characters. 也许这与点位置在字符之间的解释有关。 For an empty buffer one has (point) == (point-min) == (point-max) . 对于空缓冲区,具有(point) == (point-min) == (point-max) This interpretation also gives (point-max) == (1+ (buffer-size)) its meaning. 这种解释还给出(point-max) == (1+ (buffer-size))的含义。

I cite here the description of following-char in the info-node (elisp) Near Point : 我在这里引用info-node (elisp) Near Pointfollowing-char的描述:

"Remember that point is always between characters, and the cursor normally appears over the character following point. Therefore, the character returned by `following-char' is the character the cursor is over." “请记住,该点始终位于字符之间,并且光标通常会出现在该字符之后的位置上。因此,'following-char'返回的字符就是光标所经过的字符。”


Point positions between characters and move-to-column 字符和move-to-column之间的点位置

(Note, the following is just my interpretation. It would be nice if someone who really knows the intentions in the features of move-to-column could acknowledge, deny, or correct this stuff.) (请注意,以下只是我的解释。如果真正了解move-to-column功能的意图的人可以确认,拒绝或纠正此问题,那将是很好的。)

The following discussion illustrates the consequences of point positions between characters for move-to-column . 下面的讨论说明了字符之间的点位置对于move-to-column的后果。 We denote the point positions by pos0, pos1,... and the characters with char1, char2,.... We use the denotation char1a, char1b, ... if the entry of a character char1 in buffer-display-table is a vector [char1a char1b ...] of length > 1. In the following we name such an character as compound character . 我们用pos0,pos1,...表示点位置,并用char1,char2,....表示字符。如果在buffer-display-table字符char1的条目是一个长度大于1的向量[char1a char1b ...] 。在下文中,我们将这样的字符命名为复合字符

Normal case (no compound characters): 正常情况(无复合字符):

pos0 char1 pos1 char2 pos2 nl pos0 char1 pos1 char2 pos2 nl

(move-to-column 2 t) means to position the point before the nlchar. (move-to-column 2 t)表示将点定位在nlchar之前。

Case with a compound character char1 = [char1a char1b] in buffer-display-table : buffer-display-table具有复合字符char1 = [char1a char1b]的情况:

pos0 char1a pos1 char1b pos2 nl pos0 char1a pos1 char1b pos2 nl

move-to-column respects the display size of the compound character but it cannot put point in the middle of it. move-to-column尊重复合字符的显示大小,但不能将指针放在中间。 Point can only be placed at the boundaries of the compound character. 点只能放置在复合字符的边界处。

In this case (move-to-column 1 t) moves point to position pos2. 在这种情况下(move-to-column 1 t)将点移动到位置pos2。

Now, let the new-line character be a composed character nl = [nla nlb]. 现在,让换行字符为组合字符nl = [nla nlb]。

pos0 char1 pos1 char2 pos2 nla pos3 nlb pos0 char1 pos1 char2 pos2 nla pos3 nlb

Here, (move-to-column 3 t) arrives in the middle of the composed newline character. 在这里, (move-to-column 3 t)到达了换行符的中间。

Point is still on this line. 点仍然在这条线上。 So it does not make sense to put point behind nlb. 因此,将点放在nlb后面是没有意义的。 Emacs cannot place point at pos3 since this is in the middle of a composed character. Emacs无法将点放在pos3上,因为它位于组合字符的中间。 Thus, the only sensible way to position point is pos2. 因此,定位点的唯一明智的方法是pos2。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM