web-dev-qa-db-fra.com

Comment puis-je vérifier si un fichier existe en utilisant Emacs Lisp?

Je voudrais qu'emacs marque les fichiers générés en lecture seule lorsqu'ils sont ouverts. La partie du puzzle qui me manque est de savoir comment vérifier si un fichier "existe". J'ai actuellement les éléments suivants:

;;
;; get file extension
;;
(defun get-ext (file-name)
  (car (cdr (split-string file-name "\\."))))

;; 
;; get the base name of the file
;;
(defun base-name (file-name)
  (car (split-string file-name "\\.")))

;;
;; if an 'lzz' file exists for this header, mark it as read only
;;
(defun mark-read-only ()
  (if (string= (get-ext (cur-file)) "h")
      (if ( ??file-exists??? (concat (base-name (cur-file)) ".lzz") )
          (toggle-read-only))))

Que puis-je utiliser pour "??? file-exists ???"?

Une fois que j'ai trouvé cela, j'ajouterai "mark-read-only" au hook approprié (qui je pense est le hook find-file-hook).

[~ # ~] arrière-plan [~ # ~]

Nous utilisons lzz comme générateur de code pour simplifier notre processus de développement C/C++. En bref, lzz prend un seul fichier d'entrée (qui ressemble beaucoup à C/C++) et génère des fichiers d'en-tête et source comme il convient.

Par défaut, lzz inclut des directives #line afin que le débogueur pointe vers la source d'origine et non vers la source générée, cependant, pour réduire les dépendances de compilation, nous désactivons normalement ces directives dans les fichiers d'en-tête. Le résultat est que lors du débogage de modèles ou de fonctions en ligne, le débogueur pointe normalement vers le fichier d'en-tête généré et non vers le fichier source d'origine.

Ce n'est pas un gros problème, cependant, récemment, j'ai découvert que lors du débogage, je modifierai rapidement le fichier affiché, puis je reconstruirai. Bien sûr, cela signifie normalement que le changement que j'ai effectué disparaît parce que le fichier que j'ai édité est généré et que les modifications sont donc "soufflées" lors de la reconstruction de la bibliothèque.

[~ # ~] solution [~ # ~]

Merci à tous pour leur aide et leurs commentaires. Un merci spécial à cobbal pour avoir indiqué la bonne fonction à utiliser.

Voici le code résultant (avec des mises à jour basées sur les autres commentaires ici aussi):

(defun cur-file ()
  "Return the filename (without directory) of the current buffer"
  (file-name-nondirectory (buffer-file-name (current-buffer)))
  )

(defun mark-generated-as-read-only ()
  "Mark generated source files as read only.
Mark generated files (lzz or gz) read only to avoid accidental updates."
  (if
      (or (string= (file-name-extension (cur-file)) "h")
          (string= (file-name-extension (cur-file)) "cpp"))
      (cond
       (
        (file-exists-p (concat (file-name-sans-extension (cur-file)) ".lzz"))
        (toggle-read-only))
       (
        (file-exists-p (concat (file-name-sans-extension (cur-file)) ".gz") )
        (toggle-read-only))
       )
    )
  )
64
Richard Corden

essayez file-exists-p

"Renvoie t si le nom du fichier existe (que vous puissiez le lire ou non.)"

89
cobbal
  • En fonction de vos besoins, vous voudrez peut-être file-readable-p au lieu de file-exists-p.

  • Apropos ne vous mènera pas loin. Icicles fournit à propos de l'achèvement et complétion progressive qui vous permet de trouver facilement de l'aide pour les noms de commande, de fonction, de variable, etc. qui correspondent aux sous-parties dans un ordre arbitraire (est-ce file-exists-p ou exists-file-p?).

17
Drew

Utilisation f.el , bibliothèque moderne pour la manipulation de fichiers et de répertoires. Vous pouvez utiliser f-exists? , f-file?, f-directory? et de nombreux autres prédicats. La bibliothèque est meilleure que les fonctions standard, car il s'agit de toutes les fonctions liées aux fichiers dont vous aurez besoin sous un seul espace de noms.

8
Mirzhan Irkegulov