Как переключаться между двумя местоположениями в буфере

38

Иногда я часто чередую две функции, которые я редактирую вместе друг с другом. В этих ситуациях утомительно и больно продолжать делать, C-s <functionname>чтобы переключиться на другую функцию, а затем найти точное место, которое я редактировал ранее.

Как установить маркеры, а затем с легкостью перемещаться между двумя точками в буфере?

Ведаад Шакиб
источник
3
Ты делаешь это неправильно. У вас должно быть вертикальное разделение, чтобы вы могли видеть обе функции одновременно.
CaptainCodeman
8
Я не согласен с тем, что ОП "делает это неправильно". В то время как разделенное окно было бы полезно, OP все еще будет нуждаться в переходе назад и вперед между окнами при редактировании обеих функций. Кроме того, этот вопрос носит более общий характер, чем конкретный вариант использования: OP хочет иметь возможность быстро перемещаться в разные места в буфере. Множество ответов ниже дают ряд полезных способов сделать это.
Дан
@ Дэн Это крутой человек, и я согласен с тобой, но мой ответ не предназначен для решения его проблемы - только указать, что есть альтернативный путь.
CaptainCodeman
4
@CaptainCodeman, это нормально, хотя ответ Т. Вернона, приведенный ниже, дает альтернативу разделенному окну. Пожалуйста, относитесь к моему комментарию как к более общему запросу на проактивный язык в постах.
Дан
1
@CaptainCodeman Вы абсолютно правы. Я не знал, что Emacs поддерживает вертикальное разделение. Таким образом, я принял ответ, который детализирует использование этих вертикальных разделенных представлений.
Ведаад Шакиб

Ответы:

20

Emacs Windows

C-x 2откроет другое окно (= разделить кадр) ниже текущего, прикрепленного к тому же буферу. Вы можете перемещать точку в любом окне, не влияя на другое.

Вы можете перемещаться из одного окна в другое, используя C-x o. Встроенная библиотека windmove предоставляет некоторую функцию, которая облегчает навигацию между окнами.

Если этот метод подходит вам, вы также можете посмотреть на косвенные буферы .

введите описание изображения здесь

Т. Веррон
источник
Возможно, вам следует добавить еще несколько строк об использовании косвенных буферов: это действительно более полезно (и просто немного сложнее), чем использование просто другого окна.
ffevotte
@Francesco Теперь я понимаю, что вы имеете в виду (с другим ответом о косвенных буферах), действительно, это очень простой в использовании вариант. Это не то использование, которое я имел в виду: мое использование косвенных буферов не заменяет использование другого окна, но позволяет, например, изменять представление сужением. Я добавлю несколько слов к ответу, когда найду время.
Т. Веррон
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, используйте неконфликтующий символ для имени, а не символ, чтобы вы не могли конфликтовать с интерактивно установленными регистрами (если, конечно, вы не хотите делать что).

Phils
источник
2
Вы должны также добавить C-x C-x, так как он может прыгать вперед и назад между двумя позициями. C-u C-SPCщелкнет кольцо метки и выполнит снова, переместит точку в другое место.
Ту До
18

В дополнение к ответу Филса, есть еще несколько вариантов:

  • helm-all-mark-rings : позволяет просматривать содержимое локальных и глобальных меток в дружественном интерфейсе, поэтому вы всегда можете вернуться туда, где вы были. Вы можете нажать кнопку с помощью C-SPC C-SPC. Демо - версия:

Хелм-все-МАРК-кольца

  • helm-semantic-or-imenu : список всех доступных определений в текущем файле. Если курсор находится внутри определения, при активации маркера предварительно выбирается это определение.

  • sr-speedbar : файловый браузер, в котором перечислены его определения в каждом файле. Это похоже на контур дерева в IDE.

Ту До
источник
9

Помимо регистров и маркеров (см. Ответ @ phils об обоих и о моем другом, Сосульки ответ о маркерах), для этого могут быть полезны закладки , в том числе как автономные, так и временные. Вам нужна библиотека Bookmark + для этих специальных типов закладок.

  • Autonamed закладка является один , что вам не нужно имя. Это быстро создавать и удалять: просто нажмите клавишу. Этот же ключ создает или удаляет закладку в точке. (По умолчанию это связано C-x p RET, но вы, конечно, можете использовать любую клавишу.)

  • Автономные закладки, как и закладки в целом, являются постоянными. Но вы также можете удалить их автоматически.

  • Вы также можете создавать временные закладки или делать любые существующие закладки временными. Например, вы можете сделать так, чтобы автоматически именованные закладки автоматически становились временными.

  • Вы можете быстро переключаться между заданным набором закладок. Например, для циклического переключения между автоматически названными закладками используйте команды bmkp-next-autonamed-bookmark-repeatи bmkp-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-undoи C-c <right>/ M-x winner-redoпереключает конфигурацию окна. В этом случае конфигурации будут позициями в двух буферах, просматривающих один файл.

Примечание: winner-undoи winner-redoфункции работают в списке конфигураций. Если конфигурация изменяется, например, перемещается точка, то текущая конфигурация становится главой списка и winner-redoявляется недействительной, в этом случае winner-undoвернется прежняя позиция.

Для ситуации ОП это приводит к следующему процессу;

  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-undoна назад и C-c <right>/ M-x winner-redoна вперед.

Изменение является ничем иным , чем другой winner-undoили winner-redo.

user2542
источник
3

если вы используете evil-modeслой vim, то C-oи C-iбудет работать так же.

Они работают команды evil-jump-backward/ forward. C-oпереходит на более раннюю позицию в списке переходов, который устанавливается автоматически (метки устанавливаются в командах движения). C-iидет в обратном направлении. Мы также можем использовать TABпосле C-oвместо C-i. Таким образом, использование обеих функций приведет вас назад и вперед в вашем текущем буфере.

Если вы хотите, чтобы эта функция была кросс-буферами, проверьте evil-jumpers: http://melpa.org/#/evil-jumper

«
Evil-jumper» - это дополнение для «evil-mode», которое заменяет реализацию списка переходов таким образом, чтобы оно более точно имитировало поведение Vim. В частности, он будет пересекать границы буфера и восстанавливать мертвые буферы, если это необходимо. Список переходов также может быть сохранен в файл и восстановлен между сеансами. »

Примечание: я узнал об этом в этой вики

Ehvince
источник
Это не дает ответа на вопрос. Чтобы критиковать или запросить разъяснения у автора, оставьте комментарий под своим постом.
Дан
1
Да, и под этим автоматическим комментарием я на самом деле имею в виду, что ответ выглядит так, как будто он предназначен для комментария к другому ответу. Если вы хотели, чтобы это было само по себе ответом, не могли бы вы немного рассказать о том, что C-oи как C-iделать?
Дан
Вы правы ! сделанный.
Ehvince
2

Если вы используете Icicles, вы можете быстро перемещаться между маркерами в mark-ringкаждом буфере или global-mark-ring(в каждом буфере которого есть один маркер).

Вы делаете это, используя мультикоманду C-- C-SPC (для буфера mark-ring) или C-- C-x C-SPC(для global-mark-ring). После однократного нажатия клавиши вы используете обычные велосипедные клавиши « Сосульки» и т. Д., Чтобы перемещаться между маркерами кольца.

(Те же ключи без префикса arg устанавливают mark ( set-mark-command) и выдают глобальную mark ( pop-global-mark) соответственно, так же, как в ванильном Emacs.)

Текст строки каждого маркера используется в качестве кандидата на завершение. По мере ввода ваш минибуферный ввод сужает кандидатов до тех, которые совпадают (например, сопоставление подстроки или регулярное выражение). Вы можете быстро переключаться между соответствующими маркерами или посетить любой из них напрямую. Вы даже можете изменить порядок сортировки ( C-,) для езды на велосипеде.

Нарисовался
источник
2

Минимальная, но часто полезная возможность - когда вы просто хотите посмотреть другую функцию - это настройка

(setq scroll-preserve-screen-position t)

что возвращает вас к вашей точной начальной позиции курсора при переключении между C-vи M-v.

Dieter.Wilhelm
источник
1

evil-modeреализует маркеры Вим-стиль . Вы можете установить маркеры с помощью ( mто есть evil-set-marker) и перейти к метке с помощью обратной черты `( evil-goto-mark) или к линии метки '( evil-goto-mark-line).

Следовательно, вы можете создать метку "a" в первом месте с помощью ma, создать метку "b" во втором месте с помощью ma, а затем 'aперейти к отметке "a" и 'bперейти к отметке "b".

Дэн
источник
1

используйте имя и код ниже

(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
Вау, ты использовал это дольше, чем я был жив.
Ведаад Шакиб
Полагаю, этого пока не произойдет в мире Node или Visual Studio Code, но кто знает ... :-) Рад, что молодые и умные люди все еще выбирают Emacs. О, и мне еще не 50 ;-)
Стефан Кампхаузен
Это довольно круто. Я пытался найти способ переключения между двумя произвольными местоположениями с включенным режимом переходных меток, и это действительно решает проблему :) Спасибо.
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обычным способом.

memeplex
источник