Ouvrir récursivement les fichiers correspondant à l'expression rationnelle dans les répertoires marqués

9

D'une manière générale, j'aimerais pouvoir ouvrir tous les fichiers dans un ensemble donné de répertoires (et leurs sous-répertoires) où le nom de fichier correspond à une expression rationnelle donnée.

Par exemple

  /home/nispio/project:
  total used in directory 1612 available 1000000000
  drwxrwxr-x 13 nispio group    4096 Sep 19 14:06 .
  drwxrwxr-x  7 nispio group    4096 Sep 22 16:41 ..
  drwxrwxr-x  2 nispio group    4096 Sep 19 12:46 cfg
  drwxrwxr-x  2 nispio group    4096 Sep 19 12:46 hlp
* drwxrwxr-x  2 nispio group    4096 Sep 23 16:52 hst
* drwxrwxr-x  2 nispio group    4096 Sep 29 14:52 inc
* drwxrwxr-x  2 nispio group    4096 Oct  1 12:53 lib
  drwxrwxr-x  2 nispio group    4096 Sep 19 12:46 mcr
  drwxrwxr-x  2 nispio group    4096 Sep 24 10:50 pyl
  drwxrwxr-x  2 nispio group    4096 Sep 19 12:46 snr
  drwxrwxr-x  2 nispio group    4096 Sep 19 12:46 unix

J'ai marqué les répertoires hst, incet lib, et maintenant je veux visiter tous les fichiers avec des extensions .c, .ccet .hdans ces trois répertoires et leurs sous - répertoires.

Ce serait encore mieux si je pouvais voir tout ce que j'ouvre avant de l'ouvrir. Si le tampon dired a été mis à jour pour me montrer tous les fichiers qui correspondent à ma recherche, et tous ceux-ci ont été mis en évidence, je pourrais faire une vérification de santé mentale pour m'assurer que ma recherche a retourné ce que j'attendais.

Je suis ouvert aux suggestions pour faire la même chose en utilisant helmou dired+ou toute autre extension qui me permettra de naviguer plus facilement dans mon système de fichiers.

nispio
la source
Mathias ou Drew ont-ils répondu à votre quête? Ou recherchiez-vous quelque chose de différent?
Malabarba

Réponses:

14

Essaye ça:

C-u C-x d

Cela vous permet d'entrer des arguments sur la façon dont Dired doit répertorier les fichiers. Par défaut, il est dit -alà l'invite. Ajoutez Rà cela, pour finir -alR. Tapez RET.

Sélectionnez / saisissez un répertoire, puis appuyez sur RET.

Cela ouvrira récursivement tous les répertoires de celui que vous sélectionnez et ci-dessous.

De là, tapez % mpour marquer tous les fichiers correspondant à un certain modèle de nom de fichier. Je souvent puis tapez tpuis ktuer (cacher) tous les fichiers que je ne suis pas intéressé. Saisissez à tnouveau pour marquer tous les fichiers.

En ce qui concerne réellement l'ouverture des fichiers, je ne pense pas qu'il existe une façon standard de le faire, mais vous pouvez facilement définir une nouvelle commande pour le faire (placez-la dans votre .emacsfichier):

(defun dired-find-marked-files ()
 (interactive)
 (dolist (f (dired-get-marked-files)) 
  (find-file f)))

Très probablement, quelqu'un a déjà inclus cela dans un joli package d'amélioration de Dired, mais c'est aussi amusant de le faire vous-même;)

Prendre plaisir!

Mathias Dahl
la source
7

Vous pouvez le faire facilement avec helm-projectile-find-file . Puisque Projectile garde une trace de chaque fichier avec son chemin d'accès relatif, vous pouvez facilement vous limiter à n'importe quoi. Prenons votre exemple. Dans votre cas, vous voulez ouvrir des fichiers dans hst, incet lib. Vous pouvez récupérer tous les fichiers appartenant à ce répertoire de deux manières:

  • Dans l'invite Helm de helm-projectile-find-file, entrez chaque répertoire et les fichiers marqués restreints à ce répertoire. Par exemple, j'entre d'abord ^hst/(qui se limite à tous les fichiers qui contiennent hst/au début de chaque candidat). Marquez tous les fichiers avecM-a , faites quelque chose de similaire pour les fichiers des deux autres répertoires.

  • Ou bien , vous pouvez récupérer des fichiers dans tous les répertoires en utilisant ce modèle : ^hst/\|^inc\|^lib. Helm accepte les regex après tout. Le regex \|signifie or. Faites-le si vous souhaitez tout sélectionner en une seule fois.

Avec l'un ou l'autre, vous aurez marqué tous les fichiers que vous souhaitez ouvrir. Appuyez ensuite sur RETpour les ouvrir tous.

Veuillez noter que si vous avez beaucoup de fichiers dans ces répertoires, vous devez augmenter helm-candidate-number-limit. Sinon, une fois que le nombre de candidats atteint la limite, aucun autre candidat n'est affiché et vous ne pouvez pas sélectionner de candidats invisibles. Réglez-le sur un nombre supérieur ou définissez-le sur nilsi vous ne voulez pas de cette limite.

La bonne chose avec Helm est que vous pouvez sélectionner des fichiers de manière interactive.

Tu Do
la source
Je pense qu'il veut tous les ouvrir simultanément, pas en sélectionner un.
Malabarba
1
@Malabarba Vous pouvez sélectionner plusieurs fichiers à l' M-aaide de helm-projectile-find-fileet appuyer une fois sur RET pour les ouvrir tous en utilisant la méthode que j'ai indiquée.
Tu Do
Bien sûr! Désolé, j'ai raté cette phrase. J'ai édité pour le rendre un peu plus évident pour des idiots comme moi. N'hésitez pas à revenir en arrière si vous n'aimez pas ou si j'ai fait quelque chose de mal.
Malabarba
@Malabarba Merci. C'est plus clair maintenant.
Tu Do
4

Voici deux possibilités (alternatives):

  1. Dans Dired, vous pouvez inclure tous les sous-répertoires contenant les fichiers sur lesquels vous souhaitez agir, en utilisant des lscommutateurs qui incluent -Rou en utilisant ipour inclure des sous-répertoires spécifiques. Si vous utilisez la bibliothèque Dired +, vous pouvez utiliser * .(lié à diredp-mark/unmark-extension, pour marquer tous les fichiers répertoriés qui ont une extension donnée (comme .h). Ensuite, vous pouvez utiliser F(lié à dired-do-find-marked-files) pour ouvrir tous les fichiers marqués.

  2. Avec la bibliothèque Dired +, vous pouvez agir sur tous les fichiers marqués et tous les fichiers marqués dans des sous-répertoires marqués, définis récursivement, IOW, sous-répertoires de sous-répertoires, leurs sous-répertoires, etc.

    Pour tout répertoire marqué, si aucun fichier n'est marqué dans ce répertoire (c'est-à-dire marqué dans une liste Dired pour ce sous-répertoire), alors l'action est sur tous ses fichiers.

    Il existe un bon nombre de commandes pour agir sur ces fichiers de différentes manières (ouverture, recherche, etc.). Mais les fichiers sur lesquels agir ne sont déterminés que de cette façon; il n'y a pas non plus la possibilité, par exemple, de saisir un motif global ou une expression rationnelle pour filtrer l'ensemble.

    Cependant, si vous utilisez la bibliothèque Icicles avec Dired +, vous pouvez utiliser M-+ C-F, c'est-à-dire M-+ C-S-f(qui est lié à icicle-visit-marked-file-of-content-recursive), pour ouvrir tout ou partie des fichiers qui viennent d'être décrits (c'est-à-dire ceux marqués ou dans des sous-répertoires marqués, définis récursivement).

    Vous pouvez utiliser des expressions régulières, à la volée, pour filtrer les noms de fichier (et / ou le contenu du fichier). Par exemple, vous pouvez, comme vous le demandez, ouvrez tous les fichiers qui ont des extensions .c, .ccet .hdans les sous - répertoires marqués (avec subdirs marqués étant traités de la même manière, récursive).

A dessiné
la source
3

eshell gère l' **/*expansion glob de style zsh , donc une approche consiste à lancer eshell dans le bon répertoire et à exécuterfor f in **/*cc **/*h { find-file $f}

Alternativement, la fonction find-fileprend en charge les caractères génériques lorsqu'elle est appelée depuis elisp. Voici un extrait utile de la documentation pour cela find-file:

(find-file FILENAME &optional WILDCARDS)
Interactively, or if WILDCARDS is non-nil in a call from Lisp, expand wildcards (if any) and visit multiple files.

Je ne pouvais pas comprendre comment faire fonctionner cela avec la globalisation de style zsh, mais cela pourrait être une bonne option.

Si tous ces fichiers sont dans un projet contrôlé par une seule source, le projectile pourrait être une approche différente et meilleure.

PS. Si vous optez pour eshell, je vous suggère de vous lier eshell-toggle-cdà une clé afin que vous puissiez facilement faire apparaître une invite eshell dans le répertoire du tampon que vous modifiez.

shapr
la source
Je ne pense pas que cela find-filefonctionnera récursivement, ce qui est la principale caractéristique que je recherche. Ouvrir un shell et taper une commande semble être trop de travail, car (je suppose) ma commande devrait être quelque chose comme for d in inc src hst { for f in $d/**/*cc $d/**/*c $d/**/*h { find-file $f } }Ou est-ce plus simple que ça?
nispio