如何在缓冲区的两个位置之间来回切换


38

有时我发现自己经常在两个要相互编辑的函数之间交替使用。在这种情况下,继续执行操作C-s <functionname>以切换到其他功能,然后找到我之前编辑的确切位置,既麻烦又痛苦。

如何设置标记,然后轻松地在缓冲区中的两个位置之间来回跳转?


3
你这样做是错的。您应该有一个垂直拆分视图,以便同时看到两个功能。
CaptainCodeman 2014年

8
我不同意OP是“做错了”。尽管拆分窗口会有所帮助,但在编辑两个功能时,OP仍需要在窗口之间来回跳转。除此之外,这个问题比特定的用例还要笼统:OP希望能够快速跳转到缓冲区中的不同位置。以下许多答案提供了许多有用的方法。

@Dan太好了,我同意你的观点,但是我的回答并不是要解决他的问题,只是要指出还有另一种方法。
CaptainCodeman 2014年

4
@CaptainCodeman,这很好,尽管T. Vernon的回答确实提供了拆分窗口的替代方法。请把我的评论视为对帖子中主动语言的更一般性要求。

1
@CaptainCodeman你是完全正确的。我不知道emacs支持垂直拆分视图。因此,我接受了详细说明这些垂直拆分视图用法的答案。
Vedaad Shakib 2014年

Answers:


20

Emacs视窗

C-x 2将在当前窗口下方打开另一个窗口(=分割框架),该窗口连接到同一缓冲区。您可以在任何一个窗口中移动点而不会影响另一个窗口。

您可以使用来从一个窗口移到另一个窗口C-x o。内置的windmove库提供了一些使在窗口之间导航更容易的功能。

如果此方法适合您,您可能还需要看一下间接缓冲区

在此处输入图片说明


也许您应该添加更多有关使用间接缓冲区的内容:与仅使用另一个窗口相比,它确实更加有用(并且稍微复杂一点)。
ffevotte 2014年

@Francesco我明白您的意思了(还有关于间接缓冲区的其他答案),确实这也是一个非常易于使用的选项。这不是我要记住的用法:间接缓冲区的使用不会用其他窗口代替,但是例如,它允许通过缩小来更改视图。找时间的时候我会在答案中加几句话。
T. Verron 2014年

56

寄存器:

C-xrSPC运行point-to-register
C-xrj运行jump-to-register

提示时键入任何字符以指定寄存器。1个

书签:

C-xrm运行bookmark-set
C-xrb运行bookmark-jump

标记环:

C-SPCC-SPC将当前位置推到标记环(不保持其活动状态)。
C-uC-SPC弹出标记环,跳到上一个位置。您可以反复使用它来浏览整个环。

请注意,某些命令(尤其是那些可能使您离开原始位置未知或任意距离的命令)将自动推入标记环,以便您以后可以使用C-uC-SPC。其中包括isearch,因此在C-s用于某处之后,您可以轻松地再次跳回。

交换点和标记:

正如Tu Do的评论所述,C-xC-x运行exchange-point-and-mark对于在两个位置之间跳转非常有用。它还可以激活标记/区域,但是您可以C-SPC用来清除突出显示。


1如果您要利用elisp中的寄存器功能,请为名称使用一些不冲突的符号,而不要使用char,以免与交互式设置的寄存器发生冲突(当然,除非您这样做那)。


2
您还应该添加C-x C-x,因为它可以在两个位置之间来回跳转。C-u C-SPC弹出标记环并再次执行将点移动到其他位置。
Tu Do

18

除了phils的答案外,还有其他一些选择:

  • helm-all-mark-rings:它允许您在友好的界面中查看本地和全局标记环的内容,因此您始终可以跳回原来的位置。您可以使用来标记C-SPC C-SPC。演示:

舵所有标记环

  • helm-semantic-or-imenu:列出当前文件中的所有可用定义。如果光标在定义内,则在激活荧光笔时会预先选择该定义。

  • sr-speedbar:一个文件浏览器,在每个文件中列出其定义。它类似于IDE中的大纲树。


9

除了寄存器和标志(见@菲尔斯的有关答案和我的其他,冰柱约标记的答案),书签,特别是无论是autonamed或临时书签,可以为这很有帮助。这些特殊的书签类型需要库Bookmark +

  • 自动命名的书签是您不需要命名的书签。创建和删除操作非常快捷:只需按下一个键即可。相同的键会在该点创建或删除书签。(默认情况下,此键绑定到C-x p RET,但是您当然可以使用任何键。)

  • 与一般的书签一样,自动命名的书签是永久性的。但是您可以选择将其自动删除。

  • 您还可以创建临时书签或将任何现有书签设置为临时书签。例如,您可以选择使自动命名的书签自动成为临时的。

  • 您可以在一组给定的书签之间快速循环。例如,要在自动命名的书签之间循环,请使用命令bmkp-next-autonamed-bookmark-repeatbmkp-previous-autonamed-bookmark-repeat(将它们绑定到键)。

  • 您可以用不同的方式突出显示加书签的位置,因此很容易发现它们。


7

关于接受的答案中提到的间接缓冲区...

M-x clone-indirect-buffer将为当前缓冲区创建一个间接缓冲区。新缓冲区的名称将添加“ <2>”(如果已经有重复的缓冲区名称,则为更大的数字)。新缓冲区将在新窗口中打开。您可以使用C-x 0或切换回单个窗口C-x 1

使用,M-x winner-mode您可以轻松地在两个位置之间切换。C-c <left>/ M-x winner-undoC-c <right>/ M-x winner-redo在窗口配置之间切换。在这种情况下,配置将位于查看一个文件的两个缓冲区中的位置。

注意:winner-undowinner-redo功能可用于配置列表。如果更改了配置(例如,移动点),则当前配置将成为列表的开头并且winner-redo无效,在这种情况下,winner-undo将恢复先前的位置。

对于OP的情况,这导致以下过程;

  1. 打开赢家模式 M-x winner-mode
  2. 访问文件(文件名:File1.txt,缓冲区名称:File1.txt)
  3. M-x clone-indirect-buffer (新的间接缓冲区名称:File1.txt <2>)
  4. 将当前窗口设为唯一窗口 C-x 1
  5. 找到第一个编辑位置,进行更改。
  6. 切换到原始缓冲区访问文件C-x b(除非从步骤3开始切换到另一个缓冲区,否则默认为原始缓冲区)。这将创建一个新的配置,供赢家切换回。
  7. 查找替代的编辑位置,进行更改。

切换到上一个编辑位置(窗口配置)取决于是否在开关之间更改了窗口配置。

  • 如果进行更改,请使用C-c <left>/ 进行切换M-x winner-undo
  • 如果未进行任何更改,请使用C-c <left>/ 向前M-x winner-undoC-c <right>/ M-x winner-redo向前切换。

更改是除winner-undo或之外的任何其他内容winner-redo


3

如果您使用evil-mode,vim层,则C-oC-i将起作用。

他们运行命令evil-jump-backward/ forwardC-o跳转到自动设置的跳转列表中的较早位置(标记在运动命令上设置)。C-i相反。我们也可以使用TABa C-o代替C-i。因此,同时使用这两个功能将带您在当前缓冲区中来回移动。

如果您希望此功能是跨缓冲区的,请查看evil-jumpershttp : //melpa.org/#/evil-jumper

«
evil-jumper是邪恶模式的附加组件,它替换了跳转列表的实现,从而使其更类似于Vim的行为。具体来说,它将跳过缓冲区边界,并在必要时恢复死缓冲区。跳转列表也可以保存到文件中,并在会话之间恢复。»

注意:我是在这个Wiki上学到的


这不能为问题提供答案。要批评或要求作者澄清,请在其帖子下方发表评论。

1
D'oh,通过自动评论,我的意思是说答案看起来像是对另一个答案的评论。如果你打算这是在自己的权利的答案,你可以扩展什么有点C-oC-i办?

你是对的 !完成。
Ehvince 2014年

2

如果您使用冰柱,则可以在mark-ring每个缓冲区的标记或每个缓冲区global-mark-ring(每个缓冲区中有一个标记)之间快速导航。

您可以使用多命令 C-- C-SPC(对于缓冲区mark-ring)或C-- C-x C-SPC(对于global-mark-ring)执行此操作。按下键一次后,您可以使用常用的“ 冰柱”循环键等在戒指的标记之间移动。

(没有前缀arg的相同键分别设置标记(set-mark-command)和弹出全局标记(pop-global-mark),就像在普通Emacs中一样。)

每个标记行的文本用作完成候选。在键入时,您的迷你缓冲区输入将候选者的范围缩小到匹配的候选者(例如,子字符串或正则表达式匹配)。您可以在匹配的标记之间快速循环或直接访问它们中的任何一个。您甚至可以更改C-,循环的排序顺序()。


2

一种最小但通常有用的可能性-当您只想查看其他功能时-正在设置

(setq scroll-preserve-screen-position t)

C-v和之间切换时,可将您带回到您的确切起始光标位置M-v


1

evil-mode实现Vim样式的标记。您可以使用(m,即evil-set-marker)设置标记,并使用反引号`(evil-goto-mark)跳至标记或标记的行'evil-goto-mark-line)。

因此,您可以在第一个位置ma创建标记“ a”,在第二个位置创建标记“ b” ma,然后'a跳转到标记“ a”和'b跳转到标记“ b”。


1

使用imenu和下面的代码

(defvar rimenu-position-pair nil "positions before and after imenu jump")
(add-hook 'imenu-after-jump-hook
          (lambda ()
            (let ((start-point (marker-position (car mark-ring)))
                  (end-point (point)))
              (setq rimenu-position-pair (list start-point end-point)))))

(defun rimenu-jump ()
  "jump to the closest before/after position of latest imenu jump"
  (interactive)
  (when rimenu-position-pair
    (let ((p1 (car rimenu-position-pair))
          (p2 (cadr rimenu-position-pair)))

      ;; jump to the far way point of the rimenu-position-pair
      (if (< (abs (- (point) p1))
             (abs (- (point) p2)))
          (goto-char p2)
          (goto-char p1))
      )))

1

在过去的20年左右的时间里,我一直在使用这两个宝石:

(defun ska-point-to-register ()
  "Store cursorposition _fast_ in a register. Use ska-jump-to-register
to jump back to the stored position."
  (interactive)
  (point-to-register 8))

(defun ska-jump-to-register ()
  "Switches between current cursorposition and position
that was stored with ska-point-to-register."
  (interactive)
  (let ((tmp (point-marker)))
    (jump-to-register 8)
    (set-register 8 tmp)))

我将它们绑定到C-。和C-分别使用,并且不断地使用它们而不再意识到。

是的,套准和标记等等更为灵活和强大,但这仍然是那些很小的快速帮助者之一,使我无法切换到其他编辑器。


1
哇,您使用这个工具的时间比我活着的更长。
Vedaad Shakib

我想这还不会在Node或Visual Studio Code世界中发生,但是谁知道... :-)很高兴看到年轻又聪明的人仍然选择Emacs。哦,我还不到50岁;-)
Stefan Kamphausen

太棒了 我一直在尝试找到一种在启用瞬态标记模式的情况下在两个任意位置之间切换的方法,这确实很好地解决了问题:)谢谢。
PlagueHammer

0

您还可以利用宏,因为它们可以快速绑定到方便的键。

例如,使用记录到位置N的跳转,<F3> M-g g N <F4>并使用将其分配给键F5 C-x C-k b <F5>。然后对位置M和F6执行相同操作。从现在开始,您可以简单地交替使用F5和F6在N和M之间跳转。

更简单的是,由于<F4>执行最后记录的宏和<C-u> F4最后一个宏,因此可以跳过键绑定步骤,而只需使用<F4>和即可替换位置<C-u> F4


另一个相当大的可能性是使用<C-x> 4 c。在另一个窗口中创建间接缓冲区。该缓冲区的内容相同,但点位置可能不同。现在,只需使用<C-x> o通常的方法在窗口之间交替即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.