8
votes

Passer des variables Emacs aux commandes de shell minibuffer

Je peux exécuter rapidement une commande shell en frappant m -! . Une chose que je voudrais faire est d'effectuer des opérations rapides Shell sur le fichier actuel. Un exemple vérifierait le fichier via Perforce:

m -! P4 Edit tampon-nom-file-nom RET

(Oui, il existe des intégrations de perforce, mais je suis plus intéressé par le problème minishell / variable plutôt qu'un flux de travail spécifique)

Bien sûr, la variable nom de fichier tampon n'est pas évaluée avant que la commande soit envoyée à la coque.

Y a-t-il une façon facile à la volée de faire cela? Ou devrai-je lancer une fonction ELISP personnalisée?


2 commentaires

Perforce devrait s'intégrer avec Emacs voir: emaccesswiki.org/emacs/perforcescm


Je modifierai la question pour indiquer clairement que je veux dire cela comme exemple uniquement. Je suis intéressé par la manière d'évaluer facilement une variable avant de la passer à la coquille de minibuffer.


6 Réponses :


1
votes

Vous ne pouvez pas faire cela avec m -! , mais vous pouvez évaluer l'élis arbitraire du minibuffer, donc écrire une fonction n'est pas strictement nécessaire:

m -: (commande shell (format "édition de% s" (shell-ciote-argument tampon-file-file))) ret

Dans ce cas cependant, je pense que eShell est ce que vous voulez utiliser:

mx eShell-commande ret p4 edit (nom tampon-tampon-name-nom) ret

edit: sauf malheureusement cela ne fonctionne pas, car le tampon * eShell cmd * est sélectionné lors de l'évaluation. Une solution serait:

mx eShell-commande ret p4 edit (nom de tampon-tampon-name-nom (autre tampon nil t)) < / Code> RET

(pas aussi aussi élégant, désolé.)


2 commentaires

Votre première suggestion fonctionne, mais le second ne le fait pas. (Eval Tampon-Nom du fichier) semble évaluer à rien.


Malédictions; Je n'ai pas testé cela correctement. Le tampon * eShell cmd * est sélectionné à ce moment-là.



1
votes

Vous pouvez utiliser Cu M -: ( eval-expression avec un argument de préfixe universel) pour évaluer toute expression LISP et insérer sa valeur au point dans le tampon actuel ( Y compris les minibuffers, aussi longtemps que vous avez activer-récursif-minibuffers défini sur une valeur non nil ).

Dans votre exemple: CU M-: tampon-file-name reta .

Notez que le résultat de l'expression est imprimé sous forme LISP: c'est cité de telle sorte qu'un appel ultérieur à lu construirait une valeur LISP. Pour les cordes, cela signifie enfiler des guillemets doubles, qui seront probablement interprétés comme vous vous attendez par la coquille inférieure. Cependant, vous pouvez rencontrer des problèmes avec des chaînes contenant des caractères spéciaux, qui ont besoin de différentes échappées par ELISP et la coquille.

plus la voie est correcte utilise shell-ciote-argument , comme dans la solution phils. Voici un défuneur rapide qui lit une expression LISP et insère sa valeur au point sous la forme d'un mot shell correctement cité: xxx

L'étape de lecture-and-évalue se produit automatiquement à l'aide d'un < Code> "x" comme argument sur interactif .

modifié pour ajouter : comme @TenPn Notes, la solution ci-dessus ne " t Travalk pour insérer des variables tampon-locales telles que nom de fichier tampon dans un minibuffer tel que celui m -! apparaît (plus précisément, il insère la valeur tampon-locale du minibuffer, qui est peu susceptible d'être utile). Voici une version révisée qui semble fonctionner. Si le minibuffer est actif, il rend le tampon de la fenêtre sélectionnée temporairement active temporairement lors de la lecture et de l'évaluation d'une expression.

final modifier : de la réponse de @ Stefan je vois que je aurait dû utiliser (fenêtre sélectionné minibuffer) pour trouver la fenêtre précédemment sélectionnée. J'ai également ajouté un (format "% s" ..) pour permettre l'insertion de valeurs non-chaînes, tout en cité des caractères spéciaux dans les chaînes. Voici la version finale: xxx


4 commentaires

Si je fais m-! P4 Edit C-U M-: TABER-FILE-NAME-NAME RET , TABER-FIGH-NAME ÉVALUE À NIL. Je suppose que c'est parce que cela prend le nom de fichier du minibuffer (qui n'existe pas logiquement), pas le tampon principal actuellement ouvert?


Et je ne suis pas tout à fait de savoir ce que votre fonction est censée faire - excuser ma note d'emacs. Pouvez-vous aller dans plus de détails?


@TENPN: HMM, vous avez absolument raison d'utiliser M-: dans le minibuffer - j'aurais dû le tester plus soigneusement. Je verrai si je peux trouver une meilleure solution.


@TENPN: J'ai posté une solution révisée (bien que le vôtre soit clairement un moyen plus simple si vous souhaitez généralement simplement utiliser le nom de fichier de fichier ). Faites-moi savoir si vous souhaitez plus de détails dessus.



3
votes

i avez fait ma propre fonction Elisp, et il ressemble à ceci: xxx

https://gist.github.com/2367513

Je l'ai liée à m -" , alors maintenant mon exemple peut être complété avec:

m - " p4 édition% s reta

j'ai gagné ' t Acceptez ceci comme réponse, car j'ai demandé des solutions qui ne nécessitent pas de fonction.


0 commentaires

4
votes

En effet, en utilisant c-u m-: est presque raison. Je ne suis pas sûr d'utiliser shell-ciote-argument dans Eval-to-shell-argument car il ne fonctionne que sur les chaînes rendant impossible l'utilisation eval -à-shell-argument pour insérer un nombre ou un symbole. Vous pouvez essayer quelque chose comme: xxx

puis liez cette fonction dans votre minibuffer avec (Minibuffer-MiniBuffer-local de la touche [? insert-val) . Bien sûr, si la seule chose que vous voulez jamais insérer est le nom de fichier tampon-file, alors votre exécuté-shell-command-on-tamper est plus simple.


2 commentaires

Pouvez-vous aller dans plus de détails? Je suis désolé mais je ne suivez tout simplement pas ce que votre fonction est censée faire. Mon inexpérience, pas votre code.


AHA, donc la fonction que je cherchais dans ma réponse modifiée est minibuffer-window-window ! Merci pour la leçon.



1
votes

Tout le monde semble rouler sa propre version, alors voici la mienne - il substituera le nom de fichier actuel ou les fichiers dirigeés ou le fichier dirigeé actuel où un % code> est dans la commande shell. Il suit les mêmes conventions que m -! Code> alors je le lie à cela.

(defun my-shell-command (command &optional output-buffer error-buffer)
  "Run a shell command with the current file (or marked dired files).
In the shell command, the file(s) will be substituted wherever a '%' is."
  (interactive (list (read-from-minibuffer "Shell command: "
                                           nil nil nil 'shell-command-history)
                     current-prefix-arg
                     shell-command-default-error-buffer))
  (cond ((buffer-file-name)
         (setq command (replace-regexp-in-string "%" (buffer-file-name) command nil t)))
        ((and (equal major-mode 'dired-mode) (save-excursion (dired-move-to-filename)))
         (setq command (replace-regexp-in-string "%" (mapconcat 'identity (dired-get-marked-files) " ") command nil t))))
  (shell-command command output-buffer error-buffer))


0 commentaires

9
votes

Il semble que les emacs actuels ont quelque chose intégré pour atteindre le résultat souhaité, après m -! ( coquille-commande ) Appuyez sur , vous obtiendrez le nom de fichier que vous visitez actuellement sur l'invite. Maintenant, vous pouvez le modifier pour ajouter la commande que vous souhaitez exécuter dessus.

dans mode dired Il vous donnera le fichier que votre curseur est actuellement activé.


0 commentaires