Emacs记住文本选择

时间:2010-07-19 01:54:20

标签: emacs

在我使用gEdit满足大部分编码需求几年之后,我决定尝试新的东西,并尝试使用Emacs学习。我知道这很难,因为我听说Emacs有多复杂,但我被它的力量所吸引。最困难的事情是习惯于在.emacs文件中编写ELisp来改变编辑器的内容。我现在无法自己做,但我在这里和那里找到了一些有用的片段来改变一些选项。

我遇到很多问题的一件事是让Emacs记住我在命令后选择的文字。例如,我通常会突出显示一段代码来批量缩进它。但是,如果我在Emacs中执行此操作,它将在取消选择所有文本之前仅移动所选文本一次。有没有人知道解决这个问题?

无论如何,我为在我看来这是一个简单的问题道歉,但经过一个小时的谷歌搜索并在这里搜索SO,我觉得值得问。我还有一些关于Emacs的问题,但我会保存它们并在我理解之后单独询问。谢谢!

更新

有些人询问我使用的是什么模式以及我输入的文字类型。虽然我对Emacs模式了解不多,但我现在正在编辑一个纯文本文件。像这样:

Hello, I am a simple text file
that is made up of three separate 
lines.

如果我突出显示所有三行并点击TAB,我会得到:

    Hello, I am a simple text file
    that is made up of three separate 
    lines.

这很好,但是,如果我像下面的一些建议那样使用C-x C-x重新选择文本并再次点击TAB,我明白了:

        Hello, I am a simple text file
            that is made up of three separate 
                lines.

我希望这有帮助!

5 个答案:

答案 0 :(得分:8)

FWIW,这是您新添加的示例的行为的原因。 (我不是在这里'解决'这个问题,但是我发布它来揭开你所看到的神秘面纱。)

这是使用emacs -q确定的,这会禁用我的自定义,因此以下是emacs 23.2的默认行为。

  1. 您处于文字模式。您应该在屏幕底部的模式行中看到(Text)或类似内容,C-h m会告诉您(在次要模式列表下)“文本模式:编辑为人类编写的文本的主要模式阅读。”如果您访问与某些扩展名匹配的文件名(例如auto-mode-alist),则Emacs会决定(通过.txt变量)它应切换到文本模式。

  2. 在文本模式下,按下突出显示区域的TAB会导致indent-according-to-mode按顺序在区域的每一行上调用。找到这个的稍微复杂的路径从C-h k TAB开始,它告诉我们TAB绑定到indent-for-tab-command,在这个实例中调用indent-region - 该函数名称未在帮助,但可以在代码中看到 - 它检查缓冲区本地indent-region-function变量,它是nil,并且:“值为nil意味着每行真正运行indent-according-to-mode。”< / p>

  3. indent-according-to-mode检查indent-line-function变量,该变量具有缓冲区本地值indent-relative

  4. 使用C-h f indent-relative RET查看此功能的帮助。 (阅读本文)。

  5. 虽然你可能还没有经验知道如何检查所有(或者甚至想要!),并完全理解它告诉你的一切,这是一个如何自我记录方面的例子Emacs使用户能够弄清楚发生了什么(这使得改变事情变得可行)。我基本上只使用C-h k(describe-key),C-h f(describe-function)和C-h v(describe-variable)来遵循文档。查看indent-for-tab-command的源代码就像单击帮助页面中显示的文件名一样简单。

    我建议您执行以下操作以帮助查看每行indent-relative运行时发生的情况:

    M-x set-variable x-stretch-cursor t
    M-x set-variable ruler-mode-show-tab-stops t
    M-x ruler-mode

    现在依次为每一行,将光标放在行的最开头,然后按Tab键。你最终将所有三条线缩进到第一个制表位(标尺中的“T”)。

    现在重复一遍 - 再次确保你在每一行的最开头,在现有的缩进之前。

    第一行(当前是制表符)的第一个字符再次缩进到第一个制表位,因为没有前一行要检查。

    接下来,第二行的第一个字符缩进以匹配前一行的第一个非空白字符的位置。因为第二行的第一个字符也是一个制表符,所以第二行的实际文本被进一步按下一个制表符。

    第三行也是如此。它的第一个制表符与第二行的第一个非空白字符对齐,具有与之前相同的相对效果,为您提供示例中的最终状态。

    要强调,请注意如果您现在在现有行上方输入“a b c”行,然后返回到下一行的开头(之前的第一行)并按TAB键会发生什么。现在,第一个制表符字符将与'b'一致缩进。如果indent-tabs-mode变量为真(意味着你有实际的制表符),那么这对单词在行中的位置没有实际影响,因为'缩进'带空格的制表符不会产生影响直到空格的数量超过标签的宽度(但这完全是另一个鱼的水壶!)

    这一切的真正含义是Emacs中的text-mode在这种情况下的行为不符合您的喜好。当然,当你按TAB时,其他主要模式可以做完全不同的事情。

    正如Emacs的情况一样,你不喜欢的东西可以用elisp改变或规避。一些搜索(特别是在Emacs Wiki上)会经常为您遇到的问题提供有用的解决方案。

答案 1 :(得分:2)

在Emacs取消选择后尝试输入C-x C-x。

然后,而不是点击tab(我从来不知道tab做了你说的话!这完全是打击了。),做M-8 C-x C-i。可惜它是如此多的钥匙,但它应该做你想要的 - 即,将所有东西都推到8列。如果你想要其他数量的列,显然可以用其他东西替换M-8

答案 2 :(得分:1)

你是如何缩进的,以及在哪种模式下?

任何编程模式下的缩进规则通常都应该正确。 (如果他们不这样做,那可能更能说明你想要以不同的方式配置该模式的规则,但我怀疑这是一个已经被问过的另一个问题。)

如果您处于文本模式或类似模式且仅使用TAB,那么我可以看到问题。

请注意,如果您使用indent-rigidlyC-x C-iC-x TAB这是相同的事情),那么您可以重复缩进同一区域通过重复命令,即使突出显示已从视图中消失。

您还可以使用indent-rigidly前缀arg使其缩进多次。例如C-u C-u C-x C-i(比它看起来更容易打字)将缩进16个空格(4 x 4,因为前缀arg默认为4,并且它在每次重复时相乘)。同样,M-8 C-x C-i缩进8个空格。在某些情况下这很好,而在其他情况下则太麻烦了。

我个人建议将(cua-selection-mode 1)放入.emacs并将其用于严格缩进。 Trey Jackson made a handy blog about it。有了这个,您可以C-RET开始选择矩形,down尽可能多的行,TAB重复缩进行,C-RET退出模式。< / p>

当矩形处于活动状态时,RET会在角落中循环。对于左手角,在前面键入插入。对于右手角,请在之后键入插入。对于单列矩形,为此目的,底部计为“左”,顶部计为“右”。

Trey的博客列出了所有可用的功能(或查看源文件:cua-base.el)

请注意,Emacs中的缩进通常为an unexpectedly complicated topic

答案 3 :(得分:1)

我通常做的只是在取消激活区域的命令后输入 C-x C-x exchange-point-and-mark)。

答案 4 :(得分:1)

您可以使用以下内容执行此操作:


(add-hook 'text-mode-hook (lambda ()
                            (set (make-local-variable 'indent-region-function)
                                 (lambda (s e)
                                   (indent-rigidly s e tab-width)))))

然后选择一个区域并点击TAB。将以标签宽度缩进该区域。然后,您可以与C-x C-x交换点和标记,然后再次点击TAB重复。

但是,我确实同意以前建议直接使用indent-rigidly的答案。