A função para mostrar o caminho completo do arquivo atual no mini buffer

98

Preciso obter o caminho completo do arquivo que estou editando com o emacs.

  • Existe uma função para isso?
  • Se não, qual seria a função elisp para conseguir isso?
  • Como posso copiar o resultado (nome do caminho) para uma área de transferência para poder reutilizá-lo?

Estou usando Mac OS X e Aqumacs.

(setq filepath (get-fullpath-current-file)) ???
(copy-to-clipboard 'filepath) ???

ADICIONADO

(defun show-file-name ()
  "Mostra o caminho completo do nome do arquivo no minibuffer."
  (interativo)
  (mensagem (nome do arquivo-buffer))
  (kill-new (file-truename buffer-file-name))
)
(global-set-key "\ C-cz" 'show-file-name)

Combinando as duas respostas que obtive, posso conseguir o que quero. Obrigado pelas respostas. E mais algumas perguntas.

  • Para que serve (file-truename)?
  • Posso copiar o nome do caminho para a área de transferência do sistema (SO), não para o kill ring, para que eu possa usar as informações com os outros aplicativos?
prosseek
fonte

Respostas:

91

É a função integrada buffer-file-nameque fornece o caminho completo do seu arquivo.

A melhor coisa a fazer é ter sua janela emacs para sempre mostrar o nome do seu sistema e o caminho completo do buffer que você está editando no momento:

(setq frame-title-format
      (list (format "%s %%S: %%j " (system-name))
        '(buffer-file-name "%f" (dired-directory dired-directory "%b"))))

Você também pode fazer algo assim:

(defun show-file-name ()
  "Show the full path file name in the minibuffer."
  (interactive)
  (message (buffer-file-name)))

(global-set-key [C-f1] 'show-file-name) ; Or any other key you want
Jérôme Radix
fonte
7
No emacs 24 buffer-file-nameé uma variável
barracel
5
... mas também ainda uma função
phils
16
Se for uma função, por que não aparece M-x?
asmeurer
8
asmeurer - porque não é interativo
Ben Fitzgerald
2
@Talespin_Kit Sim, absolutamente. Elisp é um "lisp-2" em oposição a um "lisp-1", o que significa que há dois espaços de nomes independentes (variáveis ​​e funções). Cada símbolo, portanto, tem um "slot de função" e um "slot de valor", e qual slot é acessado depende do contexto. Existem muitos exemplos na prática (por exemplo, qualquer nome de modo secundário será uma função e uma variável). É também por isso que você precisa usar like de funcallpara chamar uma função que é armazenada como o valor de uma variável foo, porque se você usasse, (foo)estaria usando o slot de função de fooem vez do slot de valor.
phils
73

Pegando emprestado a resposta de Jérôme Radix, se você apenas deseja ver rapidamente o caminho do arquivo do buffer atual, pode fazer M-: buffer-file-name.

Como alternativa, digite (buffer-file-name)o buffer em algum lugar e execute C-x C-eno parêntese de fechamento (isso funcionará em qualquer modo, não apenas no modo lisp).

asmeurer
fonte
3
Obrigado, achei o buffer-file-namecomo uma função, mas não aparece em M-x, mas aparece M-:como emacs eval, lá posso executar o comando, graças a sua resposta :)
PeterZD
6
Sim, M-xexecuta apenas funções interativas, enquanto M-:executa qualquer função elisp.
asmeurer de
40

Meu truque é fazer um C-x C-flike para abrir um arquivo, preenche o minibuff com o caminho do arquivo atual, C-gpara sair. Mais rápido, M-: buffer-file-namemas muito mais feio do que qualquer outro método.

Julien Palard
fonte
Eu também faço isso Não é tão hardcore emacs-y, mas se tudo que me importa é o caminho para o arquivo atual, ele funciona.
andrunix
Se você abrir um arquivo, digamos A, e então pular para outro arquivo, digamos B, por exemplo, usando alguma funcionalidade de pular para definição de um plugin, este método mostra o caminho de A, não B! Portanto, essa resposta nem sempre oferece o que o OP pede.
Abhishek Anand
4
Cx Cv mostrará não apenas o caminho atual, mas também o nome do arquivo atual
kuzzooroo
@kuzzooroo isso é certo para usuários que não usam o modo ido (o nome é exibido em Cx Cf quando você usa o modo ido).
Julien Palard de
16

A implementação direta do que você deseja é:

(defun copy-full-path-to-kill-ring ()
  "copy buffer's full path to kill ring"
  (interactive)
  (when buffer-file-name
    (kill-new (file-truename buffer-file-name))))

Dito isso, acho extremamente útil ser capaz de obter o caminho completo do que está no minibuffer, e é isso que eu uso:

(define-key minibuffer-local-completion-map "\C-r" 'resolve-sym-link)
(defun resolve-sym-link ()
  "Try to resolve symbolic links into true paths."
  (interactive)
  (beginning-of-line)
  (let* ((file (buffer-substring (point)
                                 (save-excursion (end-of-line) (point))))
         (file-dir (file-name-directory file))
         (file-true-dir (file-truename file-dir))
         (file-name (file-name-nondirectory file)))
    (delete-region (point) (save-excursion (end-of-line) (point)))
    (insert (concat file-true-dir file-name))))

E então se eu quiser na área de transferência, eu simplesmente mato a linha ( C-a C-k). Mas poderíamos facilmente copiar o nome verdadeiro para a área de transferência no comando acima, basta alterar a última linha para ser:

(insert (kill-new (concat file-true-dir file-name)))))

A nova parte é a chamada 'kill-newque coloca a corda no ringue de morte.

Trey Jackson
fonte
Você pode explicar como usar essas configurações? E o que significa "\ Cr"?
modelador de
Deixa pra lá. Eu descobri. Eu acho que é útil quando estou no modo ido e apontando para um arquivo, então eu apenas pressiono Cr para obter o caminho completo desse arquivo. Realmente útil. No entanto, ainda não sei por que usar \ C em vez de C.
modelador de
11

Não há necessidade de função extra, apenas

M-! pwd
thanhpk
fonte
Embora possa funcionar, não funcionará em sistemas Windows e não leva em consideração o fato de que o diretório de trabalho atual do emacs pode ser diferente do diretório do arquivo do buffer atual. Você pode ver isso por si mesmo visitando um arquivo com C-x C-f, executando M-! pwd, M-x cdselecionando um diretório diferente e executando M-! pwdnovamente.
josaphatv
3

Eu tenho o seguinte código já em uso há muito tempo. Ele copia o caminho completo do arquivo para o kill ring quando pressiono o botão do meio do mouse no nome do buffer na linha de modo. Ele copia apenas o nome do buffer para o kill-ring quando pressiono shift-mouse-2 no nome do buffer na linha de modo.

(defun copy-buffer-file-name (event &optional bufName)
  "Copy buffer file name to kill ring.
If no file is associated with buffer just get buffer name.
"
  (interactive "eP")
  (save-selected-window
    (message "bufName: %S" bufName)
    (select-window (posn-window (event-start event)))
    (let ((name (or (unless bufName (buffer-file-name)) (buffer-name))))
      (message "Saved file name \"%s\" in killring." name)
      (kill-new name)
      name)))

(define-key mode-line-buffer-identification-keymap [mode-line mouse-2] 'copy-buffer-file-name)
(define-key mode-line-buffer-identification-keymap [mode-line S-mouse-2] '(lambda (e) (interactive "e") (copy-buffer-file-name e 't)))
Tobias
fonte
3

C-x C-d, também chamada via M-x list-directory, mostrará o diretório do seu arquivo atual, e você só precisa pressionar a tecla "Enter" para limpar o minibuffer. Detalhes adicionais estão disponíveis aqui .

MLev
fonte
minha resposta favorita, simples, rápida e fácil!
ticktock
2

C-x C-b mostra uma lista de buffers e o caminho do arquivo para cada buffer, quando aplicável.

David
fonte
2

C-u C-x C-b lista os buffers que estão visitando os arquivos.

memeplex
fonte
1

Posso copiar o nome do caminho para a área de transferência do sistema (SO), não para o kill ring, para que eu possa usar as informações com os outros aplicativos?

Você pode se você pagar algo como xclip (Linux), pbcopy (Mac), putclip (Cygwin).

Eu pessoalmente uso scripts de wrapper ce ppara copiar e colar respectivamente, a primeira leitura da entrada padrão, a última gravando na saída padrão. Dessa forma, isso funciona em todas as minhas plataformas de desenvolvimento:

(shell-command (format "echo '%s' | c" buffer-file-name))

Acho isso mais confiável e configurável do que usar o suporte da área de transferência do Emacs. Por exemplo, meu ccomando copia a entrada para todas as 3 pranchetas no Linux (primária, secundária, área de transferência), para que eu possa colar com Ctrl-V ou clique com o botão do meio.

Barry Kelly
fonte
Isso deve funcionar, mas não para mim. (Ubuntu 14.04.1.) A saber, date | xclipe xclip fileambos funcionam conforme anunciado (armazenando a data ou o conteúdo do arquivo no primário) se digitados no shell. Mas se eu digitar qualquer um desses comandos após M-! no emacs (e pressione return) nada acontece; o cursor permanece no minibuffer como se esperasse mais entrada; e se eu interromper para recuperar o controle, nada foi armazenado no primário.
Silvio Levy
OK, sua ideia funciona bem com xsel em vez de xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- e quando transformada em um comando interativo (como sugerido na resposta mais votada por @JeromeRadix acima), esta é uma GRANDE VITÓRIA! Obrigado!
Silvio Levy
0

A maneira mais simples e seria

(buffer-name)<(C-x)(C-e)> for the file name to appear in the echo area

(buffer-name)<(C-u)(C-x)(C-e)> would print the location <here>

Pegando emprestado de Trey Jackson, eu vim com isso:

(defun buffer-kill-path ()
  "copy buffer's full path to kill ring"
  (interactive)
  (kill-new (buffer-file-name)))

Você pode encontrar mais informações no site

DJJ
fonte