La fonction pour afficher le chemin complet du fichier actuel dans un mini tampon

98

J'ai besoin d'obtenir le chemin complet du fichier que j'édite avec emacs.

  • Y a-t-il une fonction pour ça?
  • Sinon, quelle serait la fonction elisp pour obtenir cela?
  • Comment puis-je copier le résultat (nom du chemin) dans un presse-papiers afin de pouvoir le réutiliser?

J'utilise Mac OS X et Aqumacs.

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

AJOUTÉE

(defun show-file-name ()
  "Afficher le nom du fichier de chemin complet dans le mini-tampon."
  (interactif)
  (message (nom-fichier-tampon))
  (kill-new (nom-de-fichier-vrai-tampon-nom-de-fichier))
)
(global-set-key "\ C-cz" 'show-file-name)

En combinant les deux réponses que j'ai obtenues, je pourrais obtenir ce que je veux. Merci pour les réponses. Et encore quelques questions.

  • À quoi sert (file-vrai nom)?
  • Puis-je copier le nom du chemin dans le presse-papiers du système (OS), et non dans le kill ring afin de pouvoir utiliser les informations avec les autres applications?
prosseek
la source

Réponses:

92

C'est la fonction intégrée buffer-file-namequi vous donne le chemin complet de votre fichier.

La meilleure chose à faire est que votre fenêtre emacs affiche toujours le nom de votre système et le chemin complet du tampon que vous éditez actuellement:

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

Vous pouvez également faire quelque chose comme ceci:

(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
la source
8
Dans emacs 24 buffer-file-nameest une variable
barracel
6
... mais aussi toujours une fonction
phils
17
Si c'est une fonction, pourquoi n'apparaît-elle pas M-x?
asmeurer
9
asmeurer - parce que ce n'est pas interactif
Ben Fitzgerald
2
@Talespin_Kit Oui, absolument. Elisp est un "lisp-2" par opposition à un "lisp-1", ce qui signifie qu'il y a deux espaces de noms indépendants (variables et fonctions). Chaque symbole a donc un "slot de fonction" et un "slot de valeur", et le slot auquel on accède dépend du contexte. Il existe de nombreux exemples dans la pratique (par exemple, tout nom de mode mineur sera à la fois une fonction et une variable). C'est aussi pourquoi vous devez utiliser les goûts de funcallpour appeler une fonction qui est stockée comme valeur d'une variable foo, car si vous (foo)l'utilisiez, vous utiliseriez l'emplacement de fonction de fooplutôt que l'emplacement de valeur.
phils
74

Pour emprunter à la réponse de Jérôme Radix, si vous voulez juste voir rapidement le chemin du fichier du tampon courant, vous pouvez le faire M-: buffer-file-name.

Sinon, tapez (buffer-file-name)quelque part dans le tampon et exécutez C-x C-esur la parenthèse fermante (cela fonctionnera dans n'importe quel mode, pas seulement en mode lisp).

asmeureur
la source
3
Merci, je pensais que buffer-file-namecomme une fonction, mais il ne semble pas M-x, mais apparaît en M-:tant que emacs eval, là , je peux exécuter la commande, grâce à votre réponse :)
PeterZD
6
Ouais, n'exécute M-xque des fonctions interactives, alors que M-:n'importe quelle fonction elisp.
asmeurer
41

Mon truc est de faire un C-x C-flike pour ouvrir un fichier, il préremplira le minibuff avec le chemin du fichier actuel, C-gpour quitter. Plus rapide que M-: buffer-file-namemais bien plus laid que toutes les autres méthodes.

Julien Palard
la source
Je fais ça aussi. Ce n'est pas aussi hardcore emacs-y mais si tout ce qui me préoccupe est le chemin vers le fichier actuel, cela fonctionne.
andrunix
Si vous ouvrez un fichier, disons A, puis passez à un autre fichier, disons B, par exemple en utilisant une fonctionnalité de saut vers la définition d'un plugin, cette méthode montre le chemin de A, pas B! Ainsi, cette réponse n'offre pas toujours ce que le PO demande.
Abhishek Anand
4
Cx Cv vous montrera non seulement le chemin actuel, mais également le nom du fichier actuel
kuzzooroo
@kuzzooroo c'est bien pour les utilisateurs non ido-mode (Le nom est affiché dans Cx Cf avec vous utilisez ido-mode).
Julien Palard
16

La mise en œuvre directe de ce que vous voulez est:

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

Cela dit, je trouve incroyablement utile de pouvoir obtenir le chemin complet de ce qui se trouve dans le minibuffer, et c'est ce que j'utilise:

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

Et puis si je le veux dans le presse-papiers, je tue juste la ligne ( C-a C-k). Mais nous pourrions facilement copier le vrai nom dans le presse-papiers dans la commande ci-dessus, changez simplement la dernière ligne en:

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

La nouvelle partie est l'appel 'kill-newauquel met la chaîne dans l'anneau de destruction.

Trey Jackson
la source
Pouvez-vous expliquer comment utiliser ces paramètres? Et que signifie "\ Cr"?
modéliste
Ça ne fait rien. Je l'ai compris. Je pense que c'est utile lorsque je suis en mode ido et que je pointe vers un fichier, puis j'appuie simplement sur Cr pour obtenir le chemin complet de ce fichier. En effet utile. Cependant, je ne sais toujours pas pourquoi utiliser \ C au lieu de C.
modélisateur
11

Pas besoin de fonction supplémentaire, juste

M-! pwd
thanhpk
la source
Bien que cela puisse fonctionner, cela ne fonctionnera pas sur les systèmes Windows, et cela ne tient pas compte du fait que le répertoire de travail actuel d'emacs peut être différent du répertoire du fichier du tampon actuel. Vous pouvez le constater par vous-même en visitant un fichier avec C-x C-f, en exécutant M-! pwd, puis en M-x cdsélectionnant un autre répertoire, puis en le M-! pwdrelançant.
josaphatv
3

J'ai le code suivant déjà utilisé depuis longtemps. Il copie le chemin complet du fichier vers l'anneau de destruction lorsque j'appuie sur le bouton central de la souris sur le nom du tampon dans la ligne de mode. Il copie juste le nom du tampon dans le kill-ring lorsque j'appuie sur shift-mouse-2 sur le nom du tampon dans la ligne de mode.

(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
la source
3

C-x C-d, également appelable via M-x list-directory, vous montrera le répertoire de votre fichier actuel, et il vous suffit d'appuyer sur la touche "Entrée" pour effacer le mini-tampon. Des détails supplémentaires sont disponibles ici .

MLev
la source
ma réponse préférée, simple, rapide et facile!
ticktock
2

C-x C-b affiche une liste de tampons et le chemin du fichier pour chaque tampon, le cas échéant.

David
la source
2

C-u C-x C-b répertorie les tampons qui visitent actuellement les fichiers.

memeplex
la source
1

Puis-je copier le nom du chemin dans le presse-papiers du système (OS), et non dans le kill ring afin de pouvoir utiliser les informations avec les autres applications?

Vous pouvez le faire si vous utilisez quelque chose comme xclip (Linux), pbcopy (Mac), putclip (Cygwin).

J'utilise personnellement des scripts wrapper cet ppour copier et coller respectivement, la première lecture à partir de l'entrée standard, la dernière écriture vers la sortie standard. De cette façon, cela fonctionne sur toutes mes plateformes de développement:

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

Je trouve cela plus fiable et configurable que l'utilisation du support du presse-papiers Emacs. Par exemple, ma ccommande copie l'entrée dans les 3 presse-papiers sous Linux (primaire, secondaire, presse-papiers), donc je peux coller avec Ctrl-V ou clic central.

Barry Kelly
la source
Cela devrait fonctionner, mais ce n'est pas le cas pour moi. (Ubuntu 14.04.1.) À savoir, date | xclipet les xclip filedeux fonctionnent comme annoncé (stockage de la date ou du contenu du fichier dans le fichier primaire) s'ils sont tapés dans le shell. Mais si je tape l'une de ces commandes après M-! dans emacs (et appuyez sur return) rien ne se passe; le curseur reste dans le mini-tampon comme s'il attendait plus d'entrée; et si j'interromps pour reprendre le contrôle, rien n'a été stocké en primaire.
Silvio Levy
OK, votre idée fonctionne bien avec xsel au lieu de xclip: (shell-command (format "echo '%s' | xsel -i" buffer-file-name))- et lorsqu'elle est transformée en commande interactive (comme suggéré dans la réponse la plus positive de @JeromeRadix ci-dessus), c'est un GROS GAGNANT! Merci!
Silvio Levy
0

Le moyen le plus simple et serait

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

Empruntant à Trey Jackson, j'ai trouvé ceci:

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

Vous pouvez trouver plus d'informations sur le site

DJJ
la source