2009-02-26 15 views
32

In Vim il tasto * in modalità normale cerca la parola sotto il cursore. In GNU Emacs l'equivalente nativo più vicino sarebbe:Come posso emulare la ricerca di Vim * in GNU Emacs?

C-s C-w 

Ma non è proprio la stessa cosa. Apre il mini buffer di ricerca incrementale e copia dal cursore nel buffer corrente fino alla fine della parola. In Vim cercheresti l'intera parola, anche se sei nel mezzo della parola quando premi *.

Ho cucinato un po 'di elisp di fare qualcosa di simile:

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

che trotta indietro all'inizio della parola prima di sparare fino isearch. L'ho associato a C- +, che è facile da digitare sulla mia tastiera e simile a *, quindi quando digito C-+ C-w viene copiato dall'inizio della parola sul mini-buffer di ricerca.

Tuttavia, questo non è ancora perfetto. Idealmente, regexp la ricerca di "\<" word "\>" per non mostrare corrispondenze parziali (la ricerca della parola "bar" non dovrebbe corrispondere a "foobar", solo "bar" a sé stante). Ho provato ad usare search-forward-regexp e concating \ <> ma questo non si avvolge nel file, non evidenzia le corrispondenze ed è generalmente piuttosto lento. Una funzione isearch- * sembra la soluzione migliore, ma questi non si comportano bene quando vengono scritti degli script.

Qualche idea? Qualcuno può offrire qualche miglioramento al bit di ELIS? O c'è un altro modo che ho trascurato?

+0

Sì, Emacs consente di eseguire il collegamento a isearch per eseguire questa operazione, ma il pacchetto di simboli di evidenziazione è ancora migliore. Trovo che mantenere i simboli centrali nel mio attuale processo di pensiero sia di grande aiuto. Inoltre, ottieni una ricerca chiave e il tuo punto rimane costante rispetto all'inizio del simbolo. –

+0

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

risposta

15

In base al feedback per la mia prima risposta, come su questo:

(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

Muore su di me se non ci sono corrispondenze successive nel file di quella corrente. Backtrace e istruzioni di ripro [qui] (https://gist.github.com/mgalgs/5392566). – mgalgs

+0

Errore durante l'esecuzione su . –

+0

Funziona bene la prima volta, ma dà errori nell'uso ripetuto: 'Argomento di tipo errato: arrayp, nil' – Dfr

1

Non l'ho provato ma c'è del codice here chiamato Grep-O-Matic.

0

Con questo si dovrebbe essere in grado di fare C- * mentre si è in modalità ricerca.

 
(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

Questo è piuttosto simile (in funzione, se non forma) a quello che ho avuto a un certo punto - il problema è che usi multipli non giocano bene con isearch. Non c'è modo di "ripulire" isearch prima di eseguire nuovamente C- *. Finisci con search1search2search3 tutto concatenato misteriosamente. – richq

5

Ci sono molti modi per farlo:

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

+0

La soluzione di JimBlandy è talmente vicina, ma in realtà non "ricerca", ma hack sull'interfaccia di ricerca. Non puoi saltare alla precedente/successiva e non memorizza la parola nel buffer. Argh! – richq

3

risposta di scottfrazer funziona bene per io, eccetto per le parole che terminano con "_" (o forse altri caratteri non verbali?). Ho scoperto che il codice per la modalità di simbolo della luce utilizzava una regex diversa per il limite della parola a seconda della versione di emacs, e questo la risolveva. Ecco il codice modificato:

(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

ne dite costruito in comandi M-b C-s C-w (inizio della parola, ricerca, ricerca di parole)

+1

Non è proprio buono come un singolo tasto, vero? :-) – richq

7

L'emacs estensione highlight symbol fornisce questa funzionalità. In particolare, il consiglio .emacsrc configurazione:

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

Consente di saltare al prossimo simbolo al punto corrente (F3), saltando al simbolo precedente (Shift + F3) o evidenziando i simboli corrispondenti quello sotto il cursore (Ctrl + F3). I comandi continuano a fare la cosa giusta se il tuo cursore è a metà parola.

A differenza della super star di vim, i simboli di evidenziazione e il salto tra i simboli sono associati a due diversi comandi. Personalmente non mi interessa la separazione, ma potresti legare i due comandi sotto la stessa sequenza di tasti se vuoi esattamente corrispondere al comportamento di vim.

2

Mickey di Mastering Emacs blog reintrodotto un luogo fresco "Smart Scan" lib che dà attacchi globali di M-n e M-p per la navigazione simboli sotto il cursore nel buffer. Non influisce sul registro di ricerca quindi non è una sostituzione * così com'è, ma un'alternativa intelligente e utilizzabile al problema di navigazione.

Problemi correlati