33 votes

Comment puis-je émuler la recherche de Vim * dans GNU Emacs?

Dans Vim sur la touche * en mode normal, les recherches pour le mot sous le curseur. Dans GNU Emacs, le plus proche équivalent natif serait:

C-s C-w

Mais ce n'est pas tout à fait la même. Il ouvre la recherche incrémentale mini tampon et copies du curseur dans le tampon courant à la fin du mot. Dans Vim, vous seriez de recherche pour le mot en entier, même si vous êtes dans le milieu de la parole lorsque vous appuyez sur *.

J'ai cuit un peu de elisp pour faire quelque chose de similaire:

(defun find-word-under-cursor (arg)
  (interactive "p")
  (if (looking-at "\\<") () (re-search-backward "\\<" (point-min)))
  (isearch-forward))

Qui trotte vers l'arrière pour le début de la parole, avant de tirer jusqu'isearch. J'ai tenu à C+, qui est facile à taper sur mon clavier et semblable à *, donc quand je tape C-+ C-w il copie à partir du début du mot à la recherche d'un mini-tampon.

Cependant, ce n'est toujours pas parfait. Idéalement, il serait regexp recherche d' "\<" word "\>" de ne pas montrer les correspondances partielles (a la recherche du mot "bar" ne correspond pas à "foobar", juste "bar" sur son propre). J'ai essayé d'utiliser la recherche de l'avant-regexp et concat qui pratiquent \ mais ce n'est pas envelopper dans le fichier, ne met pas en évidence les matchs et est généralement assez boiteux. Un isearch-* fonction semble le meilleur choix, mais ces derniers ne se comportent bien lors de script.

Des idées? Quelqu'un peut-il proposer des améliorations pour le peu de elisp? Ou est-il un autre moyen que j'ai négligé?

15voto

scottfrazer Points 11035

Sur la base de vos commentaires sur ma première réponse, qu'en est-il:

 (defun my-isearch-word-at-point ()
  (interactive)
  (call-interactively 'isearch-forward-regexp))

(defun my-isearch-yank-word-hook ()
  (when (equal this-command 'my-isearch-word-at-point)
    (let ((string (concat "\\<"
                          (buffer-substring-no-properties
                           (progn (skip-syntax-backward "w_") (point))
                           (progn (skip-syntax-forward "w_") (point)))
                          "\\>")))
      (if (and isearch-case-fold-search
               (eq 'not-yanks search-upper-case))
          (setq string (downcase string)))
      (setq isearch-string string
            isearch-message
            (concat isearch-message
                    (mapconcat 'isearch-text-char-description
                               string ""))
            isearch-yank-flag t)
      (isearch-search-and-update))))

(add-hook 'isearch-mode-hook 'my-isearch-yank-word-hook)
 

7voto

davidg Points 2994

Le mettre en surbrillance le symbole emacs extension fournit cette fonctionnalité. En particulier, le recommander .emacsrc d'installation:

(require 'highlight-symbol)

(global-set-key [(control f3)] 'highlight-symbol-at-point)
(global-set-key [f3] 'highlight-symbol-next)
(global-set-key [(shift f3)] 'highlight-symbol-prev)

Permet de sauter à la prochaine symbole au point courant (F3), sautant à la précédente symbole (Maj+F3) ou en mettant en évidence les symboles correspondant à un sous le curseur (Ctrl+F3). Les commandes continuent à faire la bonne chose si votre curseur est au milieu d'un mot.

Contrairement à vim de la super star, en mettant en évidence les symboles et le saut entre les symboles sont liés à deux commandes différentes. Je n'ai personnellement pas l'esprit de la séparation, mais vous pouvez lier les deux commandes sous la même séquence de touches si vous voulais correspondre précisément à vim de comportement.

5voto

scottfrazer Points 11035

Il y a plusieurs manières de faire ça:

http://www.emacswiki.org/emacs/SearchAtPoint

3voto

Evan Points 196

La réponse de scottfrazer me convient bien, sauf pour les mots qui se terminent par «_» (ou peut-être d'autres caractères non verbaux?). J'ai trouvé que le code pour le mode symbole de lumière utilisait une regex différente pour la limite de mot en fonction de la version d'emacs, et cela l'a corrigé pour moi. Voici le code modifié:

 (defconst my-isearch-rx-start
  (if (< emacs-major-version 22)
      "\\<"
    "\\_<")
  "Start-of-symbol regular expression marker.")

(defconst my-isearch-rx-end
  (if (< emacs-major-version 22)
      "\\>"
    "\\_>")
  "End-of-symbol regular expression marker.")

(defun my-isearch-word-at-point ()
  (interactive)
  (call-interactively 'isearch-forward-regexp))

(defun my-isearch-yank-word-hook ()
  (when (equal this-command 'my-isearch-word-at-point)
    (let ((string (concat my-isearch-rx-start
                          (buffer-substring-no-properties
                           (progn (skip-syntax-backward "w_") (point))
                           (progn (skip-syntax-forward "w_") (point)))
                          my-isearch-rx-end)))
      (if (and isearch-case-fold-search
               (eq 'not-yanks search-upper-case))
          (setq string (downcase string)))
      (setq isearch-string string
            isearch-message
            (concat isearch-message
                    (mapconcat 'isearch-text-char-description
                               string ""))
            isearch-yank-flag t)
      (isearch-search-and-update))))

(add-hook 'isearch-mode-hook 'my-isearch-yank-word-hook)
 

2voto

user326116 Points 21

Que diriez-vous des commandes intégrées Mb Cs Cw (début de mot, recherche, recherche de mot)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X