2009-02-26 18 views
32

En Vim, la tecla * en modo normal busca la palabra debajo del cursor. En GNU Emacs el equivalente nativo más cercano sería:¿Cómo puedo emular la búsqueda de Vim * en GNU Emacs?

C-s C-w 

Pero eso no es exactamente lo mismo. Abre el mini búfer de búsqueda incremental y copia desde el cursor en el búfer actual hasta el final de la palabra. En Vim buscarías la palabra completa, incluso si estás en medio de la palabra cuando presionas *.

he cocinado un poco de elisp hacer algo similar:

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

que trota hacia atrás para el comienzo de la palabra antes de disparar hasta isearch. Lo he vinculado a C- +, que es fácil de escribir en mi teclado y similar a *, así que cuando escribo C-+ C-w, copia desde el comienzo de la palabra al miniintervalo de búsqueda.

Sin embargo, esto todavía no es perfecto. Lo ideal sería regexp buscar "\<" word "\>" para no mostrar coincidencias parciales (la búsqueda de la palabra "barra" no debería coincidir con "foobar", solo "barra" en sí misma). Intenté usar search-forward-regexp y concat'ing \ <> pero esto no se ajusta al archivo, no resalta las coincidencias y generalmente es bastante cojo. Una función isearch- * parece ser la mejor opción, pero no se comportan bien cuando se escriben.

¿Alguna idea? ¿Alguien puede ofrecer alguna mejora en el bit de elisp? ¿O hay alguna otra forma que he pasado por alto?

+0

Sí, Emacs le permite enganchar en isearch para hacer esto, pero el paquete de símbolos de resaltado es incluso mejor. Me parece muy útil mantener los símbolos centrales de mi actual proceso de pensamiento. Además, obtienes una búsqueda de clave y tu punto permanece constante en relación con el comienzo del símbolo. –

+0

http://stackoverflow.com/questions/1775005/super-star-or-find-the-word-under-the-cursor-equivalent-in-emacs – Neil

Respuesta

15

Sobre la base de sus comentarios a mi primera respuesta, ¿qué tal esto:

(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) 
+0

Muere en mí si no hay coincidencias más adelante en el archivo que el actual. Instrucciones de Backtrace y repro [aquí] (https://gist.github.com/mgalgs/5392566). – mgalgs

+0

Esto falla cuando se ejecuta en . –

+0

Funciona bien la primera vez, pero da errores en el uso repetido: 'Argumento de tipo incorrecto: arrayp, nil' – Dfr

1

No lo he intentado, pero hay algún código here llamado Grep-O-Matic.

0

Con esto usted debería poder hacer C- * mientras está en modo de búsqueda.

 
(define-key isearch-mode-map [?\C-*] 'kmk-isearch-yank-thing) 

(defun kmk-isearch-yank-thing() 
    "Pull next thing from buffer into search string." 
    (interactive) 
    (let ((string (regexp-quote (thing-at-point 'word)))) 
    (setq isearch-string 
     (concat isearch-string "\\") 
     isearch-message 
     (concat isearch-message 
      (mapconcat 'isearch-text-char-description 
       string "")) 
     ;; Don't move cursor in reverse search. 
     isearch-yank-flag t)) 
    (setq isearch-regexp t isearch-word nil isearch-success t isearch-adjusted t) 
    (isearch-search-and-update)) 
+0

Esto es bastante similar (en función, si no forma) a Lo que tuve en un momento: el problema es que los usos múltiples no funcionan bien con isearch. No hay forma de "limpiar" la búsqueda antes de volver a ejecutar C- *. Terminas con search1search2search3 todos concatonated misteriosamente. – richq

5

Hay un montón de maneras de hacer esto:

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

+0

La solución de JimBlandy es tan cercana, pero en realidad no "busca", piratea en la interfaz de búsqueda. No puede saltar a anterior/siguiente y no almacena la palabra en el búfer. Argh! – richq

3

respuesta de scottfrazer funciona bien para yo, a excepción de las palabras que terminan en '_' (¿o quizás otros caracteres que no son palabras?). Descubrí que el código para el modo símbolo de luz usaba una expresión regular diferente para el límite de palabras, según la versión de emacs, y eso me lo solucionó. Aquí está el código modificado:

(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) 
0
;Here is my version: Emulates Visual Studio/Windows key bindings 
; C-F3 - Start searching the word at the point 
; F3 searches forward and Shift F3 goes reverse 

(setq my-search-wrap nil) 

(defun my-search-func (dir) 
    (interactive) 
    (let* ((text (car search-ring)) newpoint) 
     (when my-search-wrap 
      (goto-char (if (= dir 1) (point-min) (point-max))) 
      (setq my-search-wrap nil)) 
     (setq newpoint (search-forward text nil t dir)) 
     (if newpoint 
      (set-mark (if (= dir 1) (- newpoint (length text)) 
         (+ newpoint (length text)))) 
      (message "Search Failed: %s" text) (ding) 
      (setq my-search-wrap text)))) 

(defun my-search-fwd() (interactive) (my-search-func 1)) 
(defun my-search-bwd() (interactive) (my-search-func -1)) 

(defun yank-thing-into-search() 
    (interactive) 
    (let ((text (if mark-active 
      (buffer-substring-no-properties (region-beginning)(region-end)) 
       (or (current-word) "")))) 
    (when (> (length text) 0) (isearch-update-ring text) (setq my-search-wrap nil) 
      (my-search-fwd)))) 
(global-set-key (kbd "") 'my-search-fwd)   ; Visual Studio like search keys 
(global-set-key (kbd "") 'my-search-bwd) 
(global-set-key (kbd "") 'yank-thing-into-search) 

2

¿Qué hay de comandos integrados M-b C-s C-w (comienzo de la palabra, búsqueda, búsqueda de palabras)

+1

No es tan bueno como una sola pulsación de tecla, ¿verdad? :-) – richq

7

El emacs extensión highlight symbol proporciona esta funcionalidad. En particular, el recomendar .emacsrc configuración:

(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) 

Permite saltar a la siguiente símbolo en el punto actual (F3), saltando al símbolo anterior (Shift + F3) o destacando símbolos iguales la una bajo el cursor (Ctrl + F3). Los comandos continúan haciendo lo correcto si el cursor es de la mitad de la palabra.

A diferencia de la super estrella de vim, los símbolos de resaltado y los saltos entre símbolos están vinculados a dos comandos diferentes. Personalmente, no me importa la separación, pero podrías unir los dos comandos con la misma pulsación de tecla si quisieras hacer coincidir exactamente el comportamiento de vim.

2

Mickey de Mastering Emacs el blog reintrodujo un lugar fresco "Smart Scan" lib que da fijaciones globales de M-n y M-p símbolos para navegar bajo el cursor en el buffer. No afecta el registro de búsqueda, por lo que no es un reemplazo de *, sino una alternativa inteligente y utilizable al problema de navegación.

Cuestiones relacionadas