Función similar a buscar / reemplazar para intercambiar texto

12

Con frecuencia me encuentro tratando de reemplazar, por ejemplo, foocon bary barcon fooen un búfer.

La forma en que lo hago generalmente es:

  • 3-consulta Reemplaza: aaa -> @@@, bbb -> aaa,@@@ -> bbb
  • renunciar a la automatización y simplemente hacer el reemplazo a mano

Supongo que es posible hacer que algo funcione usando la ,sintaxis query-replace-regexppara probar si la cadena coincidente es aaao bbb. Pero la sintaxis resultante sería demasiado engorrosa, por lo que nunca lo intenté realmente.

La cuestión es que, dada la frecuencia de la tarea, creo que debe haber una mejor manera de hacerlo en un solo paso, ya sea integrada o en un paquete existente. ¿Esta ahí?

T. Verron
fuente
Puede haber un camino de un solo paso, pero tu primer camino no es malo, en mi opinión. Y si elige la cadena de reemplazo en este momento, simplemente puede hacer un reemplazo sin consulta para el segundo paso.
Drew
@Drew Para regular query-replace, sé que generalmente es más rápido M-% str1 str2que mover el punto y hacer el cambio a mano. Es bueno, porque no tengo que perder el tiempo pensando en lo que será más rápido, incluso si solo ocurre una vez str1. Idealmente, me gustaría que la inversión de texto sea igual de rápida, de modo que pueda usarla sin pensarlo también.
T. Verron
Alguien proporcionará una respuesta simple. Sin duda, puede hacer lo que le pida, por ejemplo, utilizando una expresión Lisp para el reemplazo, haciendo referencia al texto que se va a reemplazar. Por ejemplo, usa algo similar al lenguaje de intercambio (setq a (prog1 b (setq b a))). E incluso puede haber una forma más simple.
Drew
2
No me parece \,(if \1 "b" "a")especialmente feo (en contra de una expresión regular de \(a\)\|b), pero aún así las palabras deben escribirse dos veces, si eso te molesta.
politza
2
¿Por qué no \(aaa\)\|bbb?
politza

Respuestas:

8

Aquí hay un pequeño comando que hará esto:

(defun query-swap-strings (from-string to-string &optional delimited start end)
  "Swap occurrences of FROM-STRING and TO-STRING."
  (interactive
   (let ((common
          (query-replace-read-args
           (concat "Query swap"
                   (if current-prefix-arg
                       (if (eq current-prefix-arg '-) " backward" " word")
                     "")
                   (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)))))
  (perform-replace
   (concat "\\(" (regexp-quote from-string) "\\)\\|" (regexp-quote to-string))
   `(replace-eval-replacement replace-quote (if (match-string 1) ,to-string ,from-string))
   t t delimited nil nil start end))
link0ff
fuente
¡Gracias, eso es mucho más elaborado que algo que hubiera escrito yo mismo! ¿Tal vez podría elaborar sobre las características implementadas? Veo que con el argumento prefijo retrocede, que realiza el reemplazo solo en la región si es necesario ... ¿O es solo una reescritura de query-replacela inversión, para que conserve todas sus características? No coincide con el 100% de la definición en mis emacs, pero todavía estoy con 24.5 ...
T. Verron
@ T.Verron Este es solo un cuerpo estándar de la query-replacefamilia de funciones de la última versión, por lo que conserva todas las características. Al final de la función, agregué mi forma recomendada de intercambiar cadenas mencionadas en el manual de Emacs.
link0ff
Probablemente acepté demasiado rápido. La función solo funciona aquí (emacs 24.3) si comento backwardy region-noncontiguous-pdesde la llamada a perform-replace. ¿Es un problema general o significa que la interfaz perform-replaceha cambiado entre versiones?
T. Verron
Sí, la interfaz ha cambiado con estos 2 argumentos agregados en la última versión, por lo que no existen en
versiones
2
Esta solución también parece estar bien ahora.
Nombre
9

Instalar plur

y ejecuta el comando plur-query-replace

y entrada {foo,bar}y su reemplazo{bar,foo}

Presiona ypara reemplazar las ocurrencias como desees.

También hay variantes no interactivas y similares a la búsqueda de este comando.

En el sendero de lastimas
fuente
¡Gracias! El propósito de plur también es algo que a veces he estado buscando, definitivamente lo echaré un vistazo. Mi única duda surge del comentario del autor del paquete anterior ...;)
T. Verron
1
plurrequiere emacs 24.4.
T. Verron