Como alternar entre dois locais em um buffer

38

Às vezes me vejo alternando com frequência entre duas funções que estou editando em conjunto. Nessas situações, é entediante e doloroso continuar fazendo um C-s <functionname>para mudar para a outra função e, em seguida, encontrar o local exato que eu estava editando anteriormente.

Como defino marcadores e depois pulo para frente e para trás entre dois locais no buffer com facilidade?

Vedaad Shakib
fonte
3
Você está fazendo isso errado. Você deve ter uma exibição dividida vertical para ver as duas funções ao mesmo tempo.
12138 CapitolCodeman
8
Não concordo que o OP esteja "fazendo errado". Embora uma janela dividida seja útil, o OP ainda precisará ir e voltar entre as janelas ao editar as duas funções. Além disso, a questão é mais geral do que o caso de uso específico: o OP quer poder saltar rapidamente para diferentes locais em um buffer. Muitas respostas abaixo fornecem várias maneiras úteis de fazer isso.
Dan
@ Dan Isso é legal, e eu concordo com você, mas minha resposta não tem a intenção de resolver o problema dele - apenas para apontar que existe uma maneira alternativa.
CaptainCodeman
4
@CaptainCodeman, tudo bem, embora a resposta de T. Vernon abaixo forneça a alternativa de janela dividida. Trate meu comentário como uma solicitação mais geral de linguagem proativa nas postagens.
Dan
1
@CaptainCodeman Você está absolutamente certo. Eu não sabia que o emacs suportava uma exibição dividida vertical. Como tal, aceitei a resposta que detalha o uso dessas visualizações divididas verticais.
Vedaad Shakib

Respostas:

20

Janelas do Emacs

C-x 2abrirá outra janela (= dividir o quadro) abaixo da atual, anexada ao mesmo buffer. Você pode mover um ponto em qualquer janela sem afetar a outra.

Você pode mover de uma janela para outra usando C-x o. A biblioteca de windmove embutida fornece algumas funções que facilitam a navegação entre janelas.

Se esse método lhe convier, convém também dar uma olhada nos buffers indiretos .

insira a descrição da imagem aqui

T. Verron
fonte
Talvez você deva adicionar mais algumas linhas sobre o uso de buffers indiretos: é realmente mais útil (e um pouco mais complexo) do que usar apenas outra janela.
Ffevotte 12/11/2014
@Francesco Entendo o que você quer dizer agora (com a outra resposta sobre buffers indiretos), na verdade também é uma opção muito fácil de usar. Esse não é o uso que eu tinha em mente: meu uso de buffers indiretos não substitui o uso de uma janela diferente, mas permite alterar a visualização com o estreitamento, por exemplo. Acrescentarei algumas palavras à resposta quando encontrar a hora.
T. Verron
56

Registros:

C-xrSPCcorre point-to-register
C-xrjcorrejump-to-register

Digite qualquer caractere para especificar um registro quando solicitado. 1 1

Favoritos:

C-xrmcorre bookmark-set
C-xrbcorrebookmark-jump

Marcar anel:

C-SPCC-SPCempurra a posição atual para o anel da marca (sem deixá-lo ativo).
C-uC-SPCaparece o anel da marca, pulando para a posição anterior. Você pode usar isso repetidamente para navegar por todo o anel.

Observe que alguns comandos (especialmente os que podem levar você a uma distância desconhecida ou arbitrária da sua localização original) serão automaticamente pressionados para o anel da marca, para que você possa usá-lo C-uC-SPCpara retornar posteriormente. Isso inclui isearch, portanto, depois de usar C-spara ir a algum lugar, você pode voltar facilmente.

Ponto e marca de troca:

E como Tu Do comenta, C-xC-xcorre exchange-point-and-markque é muito útil para saltar entre dois locais. Também ativa a marca / região, mas você pode usar C-SPCpara limpar o realce.


1 Se você está aproveitando a funcionalidade de registo no elisp, usar alguns não-conflitantes símbolo para o nome, ao invés de um char, de modo que você não pode conflito com registros de forma interativa-definidos (a menos, claro, você quer fazer aquele).

phils
fonte
2
Você deve adicionar C-x C-xtambém, pois ele pode pular para frente e para trás entre duas posições. C-u C-SPCSe tocar o anel da marca e executar novamente, o ponto será movido para outro lugar.
Tu Do
18

Além da resposta do phils, existem mais algumas opções:

  • helm-all-mark-rings : Permite visualizar o conteúdo dos anéis de marca locais e globais em uma interface amigável, para que você possa sempre voltar para onde estava. Você pode marcar com C-SPC C-SPC. Demo:

leme-todos-marca-anéis

  • helm-semântico-ou-imenu : lista todas as definições disponíveis no arquivo atual. Se o cursor estiver dentro de uma definição, ao ativar o marcador, essa definição será pré-selecionada.

  • sr-speedbar : Um navegador de arquivos que lista suas definições em cada arquivo. É semelhante ao esboço da árvore no IDE.

Tu Do
fonte
9

Além de registros e marcadores (consulte a resposta do @ phils sobre ambos e meus outros, os Sincelos respondem sobre marcadores), os marcadores , especialmente marcadores com nome automático ou temporário, podem ser úteis para isso. Você precisa da biblioteca Bookmark + para esses tipos de favoritos especiais.

  • Um marcador de nome automático é aquele que você não precisa nomear. É rápido criar e excluir: basta pressionar uma tecla. A mesma chave cria ou exclui um marcador no ponto. (Por padrão, isso está vinculado a C-x p RET, mas é claro que você pode usar qualquer tecla.)

  • Os marcadores com nome automático são, como os marcadores em geral, persistentes. Mas você pode opcionalmente excluí-los automaticamente.

  • Você também pode criar indicadores temporários ou tornar temporários os indicadores existentes. Você pode, por exemplo, optar por tornar os marcadores com nome automático temporários automaticamente.

  • Você pode alternar rapidamente entre um determinado conjunto de indicadores. Por exemplo, para alternar entre marcadores com nome automático, use comandos bmkp-next-autonamed-bookmark-repeate bmkp-previous-autonamed-bookmark-repeat(vinculando-os a chaves).

  • Você pode destacar locais marcados de maneiras diferentes, para que seja fácil identificá-los.

Desenhou
fonte
7

No que diz respeito aos buffers indiretos mencionados na resposta aceita ...

M-x clone-indirect-buffercriará um buffer indireto para o buffer atual. O nome do novo buffer terá '<2>' adicionado a ele (ou um número maior, se você já tiver nomes de buffer duplicados). O novo buffer é aberto em uma nova janela. Você pode voltar para uma única janela usando C-x 0ou C-x 1.

Com M-x winner-modevocê pode alternar facilmente entre os dois locais. C-c <left>/ M-x winner-undoe C-c <right>/ M-x winner-redoalterna entre configurações de janela. Nesse caso, as configurações serão posicionadas nos dois buffers que exibem o único arquivo.

Nota: as funções winner-undoe winner-redofuncionam em uma lista de configurações. Se a configuração for alterada, por exemplo, ponto móvel, a configuração atual se tornará o cabeçalho da lista e winner-redoserá inválida; nesse caso winner-undo, trará de volta a posição anterior.

Para a situação do OP, isso leva ao seguinte processo;

  1. Ativar o modo vencedor M-x winner-mode
  2. Arquivo de visita (nome do arquivo: File1.txt, nome do buffer: File1.txt)
  3. M-x clone-indirect-buffer (novo nome do buffer indireto: File1.txt <2>)
  4. Tornar a janela atual a única janela C-x 1
  5. Encontre o primeiro local de edição, faça as alterações.
  6. Alterne para o arquivo de visita do buffer original C-x b(o padrão será o buffer original, a menos que uma troca para outro buffer tenha ocorrido desde a etapa 3). Isso cria uma nova configuração para o vencedor retornar.
  7. Encontre um local de edição alternativo, faça alterações.

Uma mudança para o local de edição anterior (configuração da janela) depende se uma alteração é feita na configuração da janela entre as opções;

  • Se uma alteração for feita, alterne usando C-c <left>/ M-x winner-undo.
  • Se nenhuma alteração for feita, alterne usando C-c <left>/ M-x winner-undopara trás e C-c <right>/ M-x winner-redopara frente.

Uma mudança é outra coisa senão outra winner-undoou winner-redo.

user2542
fonte
3

se você usar evil-mode, a camada vim, em seguida, C-oe C-iirá funcionar da mesma.

Eles executam os comandos evil-jump-backward/ forward. C-opula para a posição mais antiga na lista de pulos, que é definida automaticamente (as marcas são definidas nos comandos de movimento). C-ivai ao contrário. Também podemos usar TABdepois de um em C-ovez de C-i. Portanto, o uso das duas funções o levará para frente e para trás no seu buffer atual.

Se você deseja que esse recurso seja um buffer cruzado, consulte evil-jumpers: http://melpa.org/#/evil-jumper

«
Evil-jumper é um complemento para o modo maligno que substitui a implementação da lista de saltos, de modo que imita mais de perto o comportamento do Vim. Especificamente, ele ultrapassará os limites do buffer e reviverá os buffers mortos, se necessário. A lista de saltos também pode ser mantida em um arquivo e restaurada entre as sessões. »

Nota: Eu aprendi neste wiki

Ehvince
fonte
Isso não fornece uma resposta para a pergunta. Para criticar ou solicitar esclarecimentos a um autor, deixe um comentário abaixo da postagem.
Dan
1
D'oh, e com esse comentário automatizado, quero dizer que a resposta parece ter a intenção de ser um comentário em outra resposta. Se você pretendia que isso seja uma resposta em seu próprio direito, você poderia expandir um pouco sobre o que C-oe C-ifazer?
Dan
Você está certo ! feito.
Ehvince
2

Se você usar Sincelos , poderá navegar rapidamente entre os marcadores no mark-ringde cada buffer ou no global-mark-ring(que possui um único marcador em cada buffer).

Você faz isso usando vários comandos C-- C-SPC (para um buffer mark-ring) ou C-- C-x C-SPC(para o global-mark-ring). Depois de pressionar a tecla uma vez, você usa as teclas usuais de ciclismo Icicles etc., para se mover entre os marcadores do anel.

(As mesmas teclas sem o prefixo arg definem a marca ( set-mark-command) e exibem a marca global ( pop-global-mark), respectivamente, da mesma forma que no Emacs de baunilha.)

O texto da linha de cada marcador é usado como candidato à conclusão. À medida que você digita, sua entrada de minibuffer restringe os candidatos àqueles que correspondem (por exemplo, correspondência de substring ou regexp). Você pode alternar rapidamente entre os marcadores correspondentes ou visitar qualquer um deles diretamente. Você pode até alterar a ordem de classificação ( C-,) para andar de bicicleta.

Desenhou
fonte
2

Uma possibilidade mínima, mas muitas vezes útil - quando você apenas deseja espiar a outra função - está definindo

(setq scroll-preserve-screen-position t)

o que leva você de volta à sua posição exata do cursor inicial ao alternar entre C-ve M-v.

Dieter.Wilhelm
fonte
1

evil-modeimplementa marcadores no estilo Vim . Você pode definir marcadores com ( m, ou seja, evil-set-marker) e pular para a marca com o backtick `( evil-goto-mark) ou para a linha da marca '( evil-goto-mark-line).

Portanto, você pode criar a marca "a" no primeiro local com ma, criar a marca "b" no segundo local com mae, em seguida, 'apular para marcar "a" e 'bpular para marcar "b".

Dan
fonte
1

use imenu e código abaixo

(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))
      )))
Chen Bin
fonte
1

Nos últimos 20 anos, mais ou menos, tenho usado essas duas gemas:

(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)))

Eu os vinculo a C-. e C-, respectivamente, e use-os constantemente sem perceber mais.

Sim, registros e marcadores são muito mais flexíveis e poderosos, mas, ainda assim, esse é um daqueles ajudantes minúsculos e rápidos que tornam impossível a mudança para outros editores.

Stefan Kamphausen
fonte
1
Uau, você está usando isso há mais tempo do que eu estou vivo.
Vedaad Shakib
Acho que isso ainda não vai acontecer no mundo do Node ou do Código do Visual Studio, mas quem sabe ... :-) Fico feliz em ver pessoas jovens e inteligentes ainda pegando o Emacs. Ah, e, eu ainda não tenho 50 anos ;-) #
234 Stefan Kamphausen
Isso é incrível. Eu tenho tentado encontrar uma maneira de alternar entre dois locais arbitrários com o modo de marca transitória ativado, e isso resolve o problema muito bem :) Obrigado.
PlagueHammer
0

Você também pode tirar proveito das macros, pois elas podem ser rapidamente vinculadas a teclas convenientes.

Por exemplo, registre um salto na posição N usando <F3> M-g g N <F4>e atribua-o à tecla F5 com C-x C-k b <F5>. Faça o mesmo com as posições M e F6. A partir de agora você pode simplesmente alternar F5 e F6 para pular entre N e M.

Ainda mais simples, já que <F4>executa a última macro gravada e <C-u> F4a penúltima, você pode pular a etapa de ligação de teclas e simplesmente alternar posições usando <F4>e <C-u> F4.


Outra possibilidade bastante radical é criar um buffer indireto em outra janela com <C-x> 4 c. Este buffer tem o mesmo conteúdo, mas pode ter uma posição de ponto diferente. Agora basta alternar entre janelas <C-x> oda maneira usual.

memeplex
fonte