¿Es posible realizar una operación replace-string
dentro de una región rectangular en emacs? ¿Si es así, cómo?Buscar y reemplazar dentro de un rectángulo en emacs
Respuesta
Si habilita CUA modo de selección:
M-xcua-selection-mode
RET
o permanentemente en el fichero init:
(cua-selection-mode 1)
A continuación, puede utilizar sus funciones de edición rectángulo avanzadas.
(o si usted es un usuario cua-mode
, entonces usted no necesita hacer eso.)
- C-RET para marcar una esquina.
- Mueva el punto a la esquina opuesta.
- M-r hacer una expresión regular reemplazar dentro del rectángulo marcado.
- C-RET para desmarcar/salir de la edición de rectángulo.
Para la documentación, buscar el "apoyo rectángulo CUA" la partida en el comentario en Mxfind-library
RET RETcua-base
Si no desea utilizar las instalaciones para cua rectángulo alguna razón (tal vez si realmente necesita replace-string
específicamente), una función personalizada usando apply-on-rectangle
sería muy fácil de armar.
Editar: En realidad, un poco más compleja de lo que esperaba, pero la mayor parte del código es la especificación interactiva y el apoyo para el comportamiento argumento prefijo 'delimitado' (ambos basados en replace-string
).
Editar 2: decidí que valía la pena hacerlo de una manera más plenamente las funciones de:
A continuación se proporciona CxrM-% y CxrCM -%, que (con suerte) actúa de la manera esperada.
(require 'rect)
(defun my-search-replace-in-rectangle
(start end search-pattern replacement search-function literal)
"Replace all instances of SEARCH-PATTERN (as found by SEARCH-FUNCTION)
with REPLACEMENT, in each line of the rectangle established by the START
and END buffer positions.
SEARCH-FUNCTION should take the same BOUND and NOERROR arguments as
`search-forward' and `re-search-forward'.
The LITERAL argument is passed to `replace-match' during replacement.
If `case-replace' is nil, do not alter case of replacement text."
(apply-on-rectangle
(lambda (start-col end-col search-function search-pattern replacement)
(move-to-column start-col)
(let ((bound (min (+ (point) (- end-col start-col))
(line-end-position)))
(fixedcase (not case-replace)))
(while (funcall search-function search-pattern bound t)
(replace-match replacement fixedcase literal))))
start end search-function search-pattern replacement))
(defun my-replace-regexp-rectangle-read-args (regexp-flag)
"Interactively read arguments for `my-replace-regexp-rectangle'
or `my-replace-string-rectangle' (depending upon REGEXP-FLAG)."
(let ((args (query-replace-read-args
(concat "Replace"
(if current-prefix-arg " word" "")
(if regexp-flag " regexp" " string"))
regexp-flag)))
(list (region-beginning) (region-end)
(nth 0 args) (nth 1 args) (nth 2 args))))
(defun my-replace-regexp-rectangle
(start end regexp to-string &optional delimited)
"Perform a regexp search and replace on each line of a rectangle
established by START and END (interactively, the marked region),
similar to `replace-regexp'.
Optional arg DELIMITED (prefix arg if interactive), if non-nil, means
replace only matches surrounded by word boundaries.
If `case-replace' is nil, do not alter case of replacement text."
(interactive (my-replace-regexp-rectangle-read-args t))
(when delimited
(setq regexp (concat "\\b" regexp "\\b")))
(my-search-replace-in-rectangle
start end regexp to-string 're-search-forward nil))
(defun my-replace-string-rectangle
(start end from-string to-string &optional delimited)
"Perform a string search and replace on each line of a rectangle
established by START and END (interactively, the marked region),
similar to `replace-string'.
Optional arg DELIMITED (prefix arg if interactive), if non-nil, means
replace only matches surrounded by word boundaries.
If `case-replace' is nil, do not alter case of replacement text."
(interactive (my-replace-regexp-rectangle-read-args nil))
(let ((search-function 'search-forward))
(when delimited
(setq search-function 're-search-forward
from-string (concat "\\b" (regexp-quote from-string) "\\b")))
(my-search-replace-in-rectangle
start end from-string to-string search-function t)))
(global-set-key (kbd "C-x r M-%") 'my-replace-string-rectangle)
(global-set-key (kbd "C-x r C-M-%") 'my-replace-regexp-rectangle)
Si está en el modo CUA, puede utilizar cua-reemplazar-en-rectángulo con destino a 'M-r'.
Pero esto solo reemplaza la primera aparición de la cosa (comportamiento vim replace-regexp predeterminado). – Adobe
Para usuarios malvados, puede usar mi paquete evil-visual-replace para obtener query-replace
y replace-regexp
dentro de bloques visuales malvados.
En reciente de Emacs (por ejemplo Emacs 25) Esto se puede hacer fuera de la caja usando M-%
(query-replace
) o C-M-%
(query-replace-regexp
).
Use M-x rectangle-mark-mode
para crear la región rectangular. Use C-x C-x
si es necesario, para poner el punto antes de la marca. Luego solo consulta-reemplaza.
No hicieron, sin embargo, el mismo cambio en Emacs 25 para replace-string
. Puede hacerlo, si lo desea, simplemente agregando el argumento region-noncontiguous-p
de la misma manera que en query-replace
. El código es simple:
(defun replace-string (from-string to-string &optional delimited start end backward
region-noncontiguous-p)
"..."
(declare (interactive-only
"use `search-forward' and `replace-match' instead."))
(interactive
(let ((common
(query-replace-read-args
(concat "Replace"
(if current-prefix-arg
(if (eq current-prefix-arg '-) " backward" " word")
"")
" string"
(if (use-region-p) " in region" ""))
nil)))
(list (nth 0 common) (nth 1 common) (nth 2 common)
(if (use-region-p) (region-beginning))
(if (use-region-p) (region-end))
(nth 3 common)
(if (use-region-p) (region-noncontiguous-p)))))
(perform-replace
from-string to-string nil nil delimited nil nil start end backward region-noncontiguous-p))
Como alternativa, puede simplemente descargar la biblioteca replace+.el
y utilizar la versión de replace-string
desde allí. Hace lo que quieres.
Fwiw, acabo presentó Emacs bug#27897 obtener esta característica añadida a replace-string
y varios otros comandos en la misma biblioteca, replace.el
.
También hay un error anzu (que podría estar reemplazando su versión de 'query-replace') relacionado con esto: https://github.com/syohex/emacs-anzu/issues/69 –
- 1. Buscar y reemplazar palabras completas (no subcadenas) en Emacs
- 2. Buscar y reemplazar dentro de la selección en `vi`
- 3. Rectángulo funciones en emacs
- 4. emacs: Cambiar la caja de un rectángulo
- 5. Buscar y reemplazar en un archivo grande
- 6. buscar y reemplazar cadena en un archivo
- 7. Buscar y reemplazar jQuery
- 8. Nueva caja Buscar y reemplazar
- 9. Linux buscar y reemplazar
- 10. Buscar y reemplazar en nombre de variable dentro de S-Expression (ámbito léxico)?
- 11. Buscar y reemplazar en scripts de shell
- 12. Buscar y reemplazar con un comodín en Xcode 4
- 13. /in vi ¿Buscar y reemplazar?
- 14. unix tr buscar y reemplazar
- 15. Vim Buscar y reemplazar Eficiencia
- 16. vim: buscar y reemplazar por "&"
- 17. buscar y reemplazar la cadena
- 18. Buscar y reemplazar con JavaScript
- 19. Jquery: buscar y reemplazar texto
- 20. Buscar y reemplazar palabras/líneas en un archivo
- 21. Buscar y reemplazar en varios archivos
- 22. Buscar y reemplazar en archivos falla
- 23. Buscar y reemplazar expresiones regulares en línea
- 24. Buscar y reemplazar palabras en HTML
- 25. Caret buscar y reemplazar en Bash shell
- 26. Buscar y reemplazar en HTML con BeautifulSoup
- 27. Buscar y reemplazar palabras completas en vim
- 28. Buscar y reemplazar en toda la base de datos mysql
- 29. Vim: ¿Buscar y reemplazar en un proyecto grande?
- 30. expresión regular de java Buscar y reemplazar
¡Gracias! Desafortunadamente, parece que solo puedo marcar una esquina con 'C-RET' en la GUI de emacs, no en modo terminal. – user545424
Eso se debe a que su terminal no envía esa secuencia. Puede encontrar un xterm más exitoso (vea también http://stackoverflow.com/questions/4337837/send-c-to-emacs-in-vt100-xterm-terminal-mac-os-xs-terminal). También actualicé mi respuesta con un código más completo para el enfoque sin CUA. – phils
Solicitud de elemento: busca en el rectángulo. Tengo una gran columna y necesito verificar si tiene algo más que 'DPP'. Uso una expresión regular compleja, y si la columna es realmente grande, obtengo un desbordamiento de pila de regexp. – Adobe