Comment lier une expression régulière à une combinaison de touches dans emacs ?

StackOverflow https://stackoverflow.com/questions/10149

  •  08-06-2019
  •  | 
  •  

Question

Pour le contexte, je suis en quelque sorte un débutant en Emacs.Je ne l'utilise pas depuis très longtemps, mais je l'utilise de plus en plus (je l'aime beaucoup).De plus, je suis à l'aise avec Lisp, mais pas très familier avec Elisp.

Ce que je dois faire, c'est lier une expression régulière à une combinaison de touches car j'utilise très souvent cette expression rationnelle particulière.

Ce que j'ai fait :

M-C-s ^.*Table\(\(.*\n\)*?GO\)

Notez que j'ai utilisé une nouvelle ligne ci-dessus, mais j'ai trouvé cela pour isearch-forward-regexp, il faut vraiment remplacer le \n dans l'expression régulière avec le résultat de C-q Q-j.Cela insère une nouvelle ligne littérale (sans terminer la commande), ce qui me permet de mettre une nouvelle ligne dans l'expression et de faire correspondre les lignes.

Comment puis-je lier cela à une combinaison de touches ?

Je comprends vaguement que je dois créer une fonction elisp qui exécute isearch-forward-regexp avec l'expression, mais je suis flou sur les détails.J'ai cherché sur Google et j'ai trouvé que la plupart des documents étaient un peu déroutants.

Comment puis-je lier une expression régulière à une combinaison de touches dans emacs ?


Mike Stone a eu la meilleure réponse jusqu'à présent -- non exactement ce que je cherchais mais cela a fonctionné pour ce dont j'avais besoin

Modifier - cela a fonctionné, mais après avoir stocké la macro, lorsque je suis revenu pour l'utiliser plus tard, je ne pouvais pas l'utiliser avec C-xe.(c'est-à-dire si je redémarre Emacs et que je tape ensuite Nom de la macro M-x, et puis C-xe, je reçois un message dans le mini-tampon du type "pas de dernière macro kbd" ou quelque chose de similaire)


@Mike Stone - Merci pour l'information.J'ai essayé de créer une macro comme ceci :

C-x( M-C-s ^.*Table\(\(.*C-q C-J\)*?GO\) C-x)

Cela a créé ma macro, mais lorsque j'ai exécuté ma macro, je n'ai pas obtenu la même mise en évidence que celle que j'obtiens habituellement lorsque j'utilise isearch-forward-regexp.Au lieu de cela, il est simplement passé à la fin de la correspondance suivante de l'expression.Cela ne correspond donc pas vraiment à ce dont j'ai besoin.Des idées?

Modifier:On dirait que je peut utiliser des macros pour faire ce que je veux, je dois juste sortir des sentiers battus isearch-forward-regexp.Je vais essayer ce que vous avez suggéré.

Était-ce utile?

La solution

Vous pouvez utiliser des macros, faites-le simplement C-x ( puis fais tout pour la macro, puis C-x) pour terminer la macro, alors C-xe exécutera la dernière macro définie.Ensuite, vous pouvez le nommer en utilisant M-x nom-dernier-kbd-macro qui vous permet de lui attribuer un nom, que vous pourrez ensuite invoquer avec M-x TESTIT, puis stockez la définition en utilisant Mx insert-kbd-macro qui placera la macro dans votre tampon actuel, puis vous pourrez la stocker dans votre .emacs déposer.

Exemple:

C-x( abc *return* C-x)

Définira une macro pour taper "abc" et appuyer sur Entrée.

C-xeee

Exécute la macro ci-dessus immédiatement, 3 fois (d'abord e l'exécute, puis les 2 e suivants l'exécuteront deux fois de plus).

M-x name-last-kbd-macro testit

Nomme la macro "testit"

M-x testit

Exécute la macro qui vient d'être nommée (imprime "abc" puis retourne).

M-x insert-kbd-macro

Place les éléments suivants dans votre tampon actuel :

(fset 'testit
   [?a ?b ?c return])

Qui peut ensuite être enregistré dans votre .emacs fichier pour utiliser la macro nommée encore et encore après le redémarrage d'emacs.

Autres conseils

J'ai commencé par résoudre votre problème littéralement,

(defun search-maker (s)
  `(lambda ()
     (interactive)
     (let ((regexp-search-ring (cons ,s regexp-search-ring)) ;add regexp to history
           (isearch-mode-map (copy-keymap isearch-mode-map)))
       (define-key isearch-mode-map (vector last-command-event) 'isearch-repeat-forward) ;make last key repeat
       (isearch-forward-regexp)))) ;`

(global-set-key (kbd "C-. t") (search-maker "^.*Table\\(\\(.*\\n\\)*?GO\\)"))
(global-set-key (kbd "<f6>") (search-maker "HELLO WORLD"))

La séquence de clavier de (kbd ...) démarre une nouvelle recherche vide.Pour rechercher réellement votre chaîne, vous appuyez sur dernière clé encore une fois autant de fois que nécessaire.Donc C-. t t t ou <f6> <f6> <f6>.La solution est essentiellement un hack, mais je la laisse ici si vous souhaitez l'expérimenter.

Ce qui suit est probablement le plus proche de ce dont vous avez besoin,

(defmacro define-isearch-yank (key string)
  `(define-key isearch-mode-map ,key 
     (lambda ()
       (interactive) 
       (isearch-yank-string ,string)))) ;`

(define-isearch-yank (kbd "C-. t") "^.*Table\\(\\(.*\\n\\)*?GO\\)")
(define-isearch-yank (kbd "<f6>") "HELLO WORLD")

Les combinaisons de touches ne fonctionnent désormais qu'en mode isearch.Vous démarrez la recherche normalement, puis appuyez sur des combinaisons de touches pour insérer votre chaîne prédéfinie.

@Justin:

Lors de l'exécution d'une macro, c'est un peu différent...les recherches incrémentielles n'auront lieu qu'une seule fois et vous devrez réexécuter la macro si vous souhaitez effectuer une nouvelle recherche.Vous pouvez cependant faire des choses plus puissantes et complexes, comme rechercher un mot-clé, sauter au début de la ligne, marquer, aller à la fin de la ligne, M-w (pour copier), puis passer à un autre tampon, puis C-y (coller ), puis revenez à l'autre tampon et terminez votre macro.Ensuite, chaque fois que vous exécuterez la macro, vous copierez une ligne dans le tampon suivant.

Ce qui est vraiment cool avec les macros Emacs, c'est qu'elles s'arrêteront lorsqu'elles verront la cloche...ce qui se produit lorsque vous ne parvenez pas à faire correspondre une recherche incrémentielle (entre autres choses).Donc la macro ci-dessus, vous pouvez faire C-u 1000 C-x e qui exécutera la macro 1000 fois...mais puisque vous avez fait une recherche, elle ne copiera que 1000 lignes, OU JUSQU'À L'ÉCHEC DE LA RECHERCHE !Ce qui signifie que s’il y a 100 correspondances, la macro n’exécutera que 100 fois.

MODIFIER:Découvrez C-hf highlight-lines-matching-regexp qui affichera l'aide d'une commande qui met en évidence tout ce qui correspond à une regex...Par contre, je ne sais pas comment annuler la mise en surbrillance...de toute façon, vous pouvez utiliser une macro stockée pour mettre en évidence toutes celles correspondant à l'expression régulière, puis une autre macro pour trouver la suivante... ?

PLUS DE MODIFICATION :M-x unhighlight-regexp annulera la mise en surbrillance, vous devez cependant entrer la dernière regex (mais elle est par défaut la regex que vous avez utilisée pour mettre en surbrillance)

En général, pour définir une combinaison de touches personnalisée dans Emacs, vous écririez

(define-key global-map (kbd "C-c C-f") 'function-name)

define-key est, sans surprise, la fonction permettant de définir une nouvelle clé. global-map est le mappage de touches global, par opposition aux mappages individuels pour chaque mode. (kbd "C-c C-f") renvoie une chaîne représentant la séquence de touches C-c C-f.Il existe d'autres façons de procéder, notamment en saisissant directement la chaîne, mais celle-ci est généralement la plus simple car elle utilise la représentation écrite normale. 'function-name est un symbole qui est le nom de la fonction.

Maintenant, à moins que votre fonction ne soit déjà définie, vous souhaiterez la définir avant de l'utiliser.Pour ce faire, écrivez

(defun function-name (args)
  (interactive)
  stuff
  ...)

defun définit une fonction - utiliser C-h f defun pour des informations plus précises.Le (interactive) il n'y a pas vraiment d'appel de fonction ;il indique au compilateur que la fonction peut être appelée par l'utilisateur en utilisant M-x function-name et via des raccourcis clavier.

Or, pour la recherche interactive en particulier, c'est délicat ;le isearch le module ne semble pas vraiment être configuré pour ce que vous essayez de faire.Mais vous pouvez l'utiliser pour faire quelque chose de similaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top