vim emacs elisp dot-emacs

¿Cómo puedo emular la búsqueda de Vim*en GNU Emacs?



elisp dot-emacs (9)

¿Qué hay de los comandos integrados Mb Cs Cw (inicio de la palabra, búsqueda, búsqueda de palabras)

En Vim, la tecla * en el modo normal busca la palabra debajo del cursor. En GNU Emacs, el equivalente nativo más cercano sería:

C-s C-w

Pero eso no es 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 para 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 hasta el comienzo de la palabra antes de disparar la búsqueda. Lo he vinculado a C- +, que es fácil de escribir en mi teclado y es similar a *, así que cuando C-+ Cw , copia desde el principio de la palabra al mini-buffer de búsqueda.

Sin embargo, esto todavía no es perfecto. Lo ideal es que regexp busque "/<" word "/>" para no mostrar coincidencias parciales (la búsqueda de la palabra" barra "no debe 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.

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


Con esto, 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))


El blog Mickey of Mastering Emacs reintrodujo una genial lib de " Smart Scan " que proporciona enlaces globales de Mn y Mp para navegar símbolos debajo del cursor en el búfer. No afecta el registro de búsqueda, por lo que no es * un reemplazo tal cual, sino una alternativa inteligente y utilizable al problema de navegación.


En base a 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)



La extensión de símbolo de resaltado emacs proporciona esta funcionalidad. En particular, la configuración de .emacsrc recomendada:

(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 al siguiente símbolo en el punto actual (F3), saltando al símbolo anterior (Shift + F3) o resaltando símbolos que coinciden con el que está debajo del 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, resaltar símbolos y saltar 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.


La respuesta de scottfrazer funciona bien para mí, a excepción de las palabras que terminan en ''_'' (¿o tal vez 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)


No lo he intentado, pero aquí hay un código llamado Grep-O-Matic.


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