Nos buffers direcionados, coloque point no arquivo mais importante desse diretório

14

90% do tempo em que visito um diretório no Emacs, a primeira coisa que faço é mover o ponto para um arquivo específico e abri-lo. Muitas vezes, o arquivo que preciso abrir é muito previsível. Por exemplo:

  • Se houver .texarquivos neste diretório, eu normalmente vou direto para master.tex.
  • Na raiz dos projetos Android, é comum AndroidManifest.xml.
  • Em um diretório em que desenvolvo um pacote emacs, quase sempre é o principal arquivo de origem do pacote. Esse é geralmente, mas nem sempre, o único .elarquivo nesse diretório.

Existe uma maneira de eu ter direcionado automaticamente o ponto desses arquivos quando abro esses diretórios?

Isso ofereceria muita conveniência (como eu poderia abri-los apenas pressionando RET), mas ainda daria a flexibilidade de visitar outros arquivos.

Malabarba
fonte

Respostas:

16

Escreva uma função personalizada para dired-initial-position-hook. Nesta função, você pode usar várias funções direcionadas para procurar arquivos e, eventualmente, chamar dired-goto-filepara mover o ponto para o "melhor" arquivo:

(defun my-dired-goto-important-file ()
  "Go to an important file in the current dired buffer."
  (unless (bound-and-true-p save-place)
    (let ((candidates '("master.tex" "AndroidManifest.xml"))
          candidate)
      (while (and candidates
                  (not (dired-goto-file (expand-file-name (pop candidates)))))
        nil))))

(add-hook 'dired-initial-position-hook #'my-dired-goto-important-file)

A seguir, explicarei aspectos específicos dessa função e destacarei as possíveis extensões.

Saltando para arquivos

dired-goto-fileretorna nilse o arquivo não existir no buffer direcionado atual; portanto, é seguro chamar sem verificação prévia. No entanto, dired-goto-filerequer um nome de arquivo absoluto (erros em nomes relativos), portanto expand-file-name.

Procurando por Arquivos

Dired não fornece uma API direta para procurar arquivos. Geralmente, você pode iterar sobre todos os arquivos da mesma forma que iterava sobre todas as linhas em um buffer:

(let (files)
  (goto-char (point-min))
  (while (not (eobp))
    (let ((filename (dired-get-filename nil 'no-error)))
      (when filename
        (push filename files)))
    (forward-line 1))
  ;; Now `files' is a list of files, which you can search for patterns
  ;; …
  )

No entanto, é mais conveniente usar as funções de marcação. Apenas tome cuidado para usar caracteres marcadores "incomuns", para não perder as marcas interativas existentes:

(unwind-protect
    (when (dired-mark-files-regexp (rx ".tex" string-end) ?t)
      (dired-goto-file (expand-file-name "master.tex")))
  (dired-unmark-all-files ?t))

Modo Salvar local

Você também precisa ter cuidado com o Modo Salvar local, caso o tenha ativado. Nos buffers Dired, o Modo Salvar local não lembra o valor do ponto como em outros modos, mas o último ponto do nome do arquivo estava ativado. Ele restaura esse nome de arquivo, da mesma forma que fazemos: Ele se conecta dired-initial-position-hooke chama dired-goto-file(de fato, foi daí que roubei esse código :).

Se nosso gancho vier antes de salvar o local, o Modo Salvar Local substituirá incondicionalmente nossa posição. No entanto, se vier antes do nosso gancho (como é o caso quando o Save Place é ativado após a configuração deste gancho), nossa função substituirá o Save Place, o que não é desejável. No entanto, como em qualquer buffer, o Save Place define a variável local save-placecomo um valor não nulo; portanto, podemos simplesmente verificar isso e apenas agir como o Save Place não restaurou um nome de arquivo.

Se você preferir que o Save Place seja “solto”, remova a verificação save-placee certifique-se de que nosso gancho seja executado após o Save Place, ativando o Modo Save Place primeiro e depois chamando add-hookcom um valor não nulo para o APPENDargumento.

lunaryorn
fonte
Ótima resposta. Você pode querer definir bound-and-true-p. :-)
Malabarba
@Malabarba bound-and-true-pé uma macro interna da bindings.el.
lunaryorn 24/09
Meu Deus, eu não sei o que me faz sentir pior, o fato de eu não saber disso ou o fato de nem mesmo verificar.
Malabarba 24/09
@ Malabarba Não importa, levei um ano (literalmente) para descobrir a existência dessa função.
lunaryorn 24/09
Sim, é uma função maravilhosa da qual eu também nunca tinha ouvido falar até agora!
sanityinc 24/09