Emacs: ¿cómo eliminar texto sin kill ring?

81

Me gustaría eliminar un poco de texto para poder tirar de otro texto en lugar de él. ¿Cómo puedo hacer eso? Cw corta el texto seleccionado para matar el anillo y termino sin el texto que quería tirar.

Además, ¿es posible tirar de texto directamente en lugar de texto sin siquiera presionar botones para eliminarlo?

mannicken
fuente
2
consulte mi respuesta a continuación, puede usar el botón Retroceso en el teclado para la primera pregunta, marcar el texto para la segunda pregunta
Kevin Zhu
¿No es solo Cx rk después de haber definido su bloque?
yalu2015

Respuestas:

49

Escribo con M-x delete-regionbastante frecuencia, pero puedes vincularlo a una tecla.

Con el modo de eliminación de selección en las versiones más recientes de Emacs, no tiene que escribir un comando, simplemente comience a escribir:

De forma predeterminada, la inserción de texto ocurre normalmente incluso si la marca está activa; por ejemplo, al escribir a se inserta el carácter 'a' y luego se desactiva la marca. El modo Eliminar selección, un modo menor, modifica este comportamiento: si habilita ese modo, al insertar texto mientras la marca está activa, el texto de la región se eliminará primero. Además, los comandos que normalmente eliminan solo un carácter, como C-do DEL, eliminarán toda la región. Para activar o desactivar el modo Eliminar selección, escribaM-x delete-selection-mode.

Ashawley
fuente
33
Además, con la última versión de Emacs, ni siquiera necesita vincularse delete-regiona una clave porque Backspace lo hace ahora. Retroceso elimina la región seleccionada en lugar de matarla, en otras palabras, Retroceso borra el texto seleccionado sin guardarlo / empujarlo al círculo de la muerte. Esto se debe a que el valor de delete-active-regiones a tmenos que lo personalice con algún otro valor.
Jisang Yoo
21

Tuve el mismo problema. Lo más cercano que tengo hasta ahora es hacer una pequeña función que es esencialmente:

(defun ruthlessly-kill-line ()
  "Deletes a line, but does not put it in the kill-ring. (kinda)"
  (interactive)
  (move-beginning-of-line 1)
  (kill-line 1)
  (setq kill-ring (cdr kill-ring)))
Haakon Løtveit
fuente
1
¿Por qué no solo (delete-region (line-begin-position) (line-end-position))?
CodyChan
La función enumerada sonaba bien, pero no me funcionó en general. En particular, descubrí que haría que el puntero del tirón apunte al otro extremo del anillo de muerte, que en general (¿de hecho casi siempre?) ¡No es el siguiente elemento de la lista! (Todavía estoy tratando de piratear una función que funciona de manera confiable a través de la delegación a 'kill-line' ... tal vez simplemente recurra a delete-region como lo han hecho otros ...)
pnkfelix
11

Tomado del EmacsWiki :

El equivalente de ‘kill-line’( ‘C-k’) pero sin efectos secundarios de anillo de muerte:

(delete-region (point) (line-end-position))
John J. Camilleri
fuente
Mejor respuesta en mi opinión. Y enlacé ctrl-shift-W para eliminar la región: (global-set-key (kbd "CSw") 'delete-region)
Tongfa
5

Mx eval-expression (setq kill-ring (cdr kill-ring)) - elimina el último elemento de kill-ring

Evgeny
fuente
Solo hace eso para la sesión actual de manera extraña. ¡Fuera de emacs no se elimina del anillo de muerte!
PascalVKooten
4

Para su segunda pregunta, como alternativa a DeleteSelectionMode , puede habilitar el modo CUA, que además le brinda un bonito modo de selección de rectángulo habilitado por C-Return. El modo CUA es parte de emacs desde 22.1.

danielpoe
fuente
3

Encontré una respuesta a esto.

Publíquelo primero aquí .

;; Ctrl-K with no kill
(defun delete-line-no-kill ()
  (interactive)
  (delete-region
   (point)
   (save-excursion (move-end-of-line 1) (point)))
 (delete-char 1)
)
(global-set-key (kbd "C-k") 'delete-line-no-kill)
Viejo
fuente
El problema es que este comando siempre elimina la nueva línea también, mientras que kill-line solo elimina la nueva línea si el valor de la variable kill-whole-line no es nil. Sería mejor cambiar "(delete-char 1)" por "(if kill-whole-line (delete-char 1))".
Alan
3

La mayoría de las funciones de eliminación se utilizan kill-regionpara realizar el trabajo real de eliminar el texto. Utilizo una macro lisp para crear funciones de eliminación de funciones de eliminación.

(defmacro jpk/delete-instead-of-kill (&rest body)
  "Replaces `kill-region' with `delete-region' in BODY."
  `(cl-letf (((symbol-function 'kill-region)
              (lambda (beg end &optional yank-handler)
                (delete-region beg end))))
     ,@body))

(defun jpk/delete-word (arg)
  "Like `kill-word', but does not save to the `kill-ring'."
  (interactive "*p")
  (jpk/delete-instead-of-kill (kill-word arg)))
jpkotta
fuente
¿Como funciona? ¿Tienes más información sobre esto? Esto es increíble.
sinekonata
1
cl-letfpuede crear un enlace local de una función con alcance dinámico. Eso significa que solo tiene efecto para el código dentro de cl-letf, pero se aplica a todo el árbol de llamadas (por ejemplo kill-region, no aparece directamente en body, pero kill-wordllama kill-regiony se reemplaza con delete-region).
jpkotta
Incluso puede llamar a la función original desde su reemplazo si primero la vincula a un nombre diferente en el archivo cl-letf. cl-letffunciona así let*en ese sentido.
jpkotta
Entiendo la esencia, todavía es demasiado técnico para mí. Apenas tengo experiencia intermedia con Python. ¿Cuál es el nombre general para estas funciones de "sobrescritura" / reescritura / bifurcación? ¿Es una característica específica de lenguajes como lisp?
sinekonata
No estoy exactamente seguro de cuál es el nombre general de esta técnica. Creo que lo describiría como un alcance dinámico para funciones, y no es común en la mayoría de los idiomas porque puede ser muy fácil de abusar. Emacs se está moviendo lentamente hacia el ámbito léxico, que es lo que utilizan la mayoría de los lenguajes. No estoy seguro de que pueda hacerlo en Python en general, tendría que diseñar su código para permitir anular la función en un ámbito particular.
jpkotta
2

Técnicamente, las otras respuestas están equivocadas en la primera parte.

Aquí está mi implementación y motivación:

(defun delete-word (arg)
  "Delete characters backward until encountering the beginning of a word.
With argument ARG, do this that many times."
  (interactive "p")
  (delete-region (point) (progn (backward-word arg) (point))))

Adapté el código aquí de " kill-word" en simple.el. Cambié kill-regioncon delete-regionyforward-word para backward-word. De esta manera REALMENTE no afecta al kill-ring, a diferencia de otras situaciones en las que, fuera de emacs, noté que kill-ringestaba influenciado.

PascalVKooten
fuente
2
Prefiero esta respuesta porque no estropea pegar desde el portapapeles del sistema operativo (donde dejar caer lo último del anillo de la muerte no ayuda porque lo que está en el portapapeles del sistema operativo se pierde)
Brel
Consulte mi respuesta para ver una forma de hacer esto sin copiar la definición de la función de matar.
jpkotta
1
(defun copy-to-register-z (p1 p2)
  "Copy text selection to register named “z”."
  (interactive "r")
  (copy-to-register ?z p1 p2))
(defun replace-register-content-z (p1 p2)
  "Replace register named “z”'s content."
  (interactive "r")
  (delete-region p1 p2)
  (insert-register ?z))
(global-set-key (kbd "C-c c") 'copy-to-register-z)
(global-set-key (kbd "C-c v") 'replace-register-content-z)
ZBeginner
fuente
Me gusta esto, pero como no uso el modo de marca transitoria, prefiero un "insert-register-content-z" con todo menos la línea delete-region.
Joshua Goldberg
1

Agregue un equivalente de eliminación de las teclas kill-region y kill-line Cw y Ck de la siguiente manera. Vinculado a las teclas Cv y Cz.

;; Una combinación de teclas para delete-region da un buen "equivalente de Windows CUT Ctrl-x".
;; Es incómodo elegir qué combinación de teclas usar.
;; usar Cv "Windows PASTE Ctrl-v" es una opción bastante subversiva.
;; Cv = desplazarse hacia arriba en emacs que no tengo ningún uso.
(global-set-key (kbd "Cv") 'eliminar-región)

;; Para tener también una alternativa de "Windows CUT" a Ck (kill-line), esto se puede hacer:
(defun delete-line () "eliminar línea, sacarla del kill ring. vincular esta función a Cz"
 (interactivo)
 (setq último comando 'eliminar-línea)
 (línea de muerte)
 (setq kill-ring (cdr kill-ring))
 (setq kill-ring-yank-pointer kill-ring)
 (setq último comando 'eliminar-línea)
)
(global-set-key (kbd "Cz") 'eliminar-línea)
;; sin configurar el último comando 2+ C-zs estropean el kill-ring
James Coleman
fuente
1

Mi respuesta a la primera pregunta: marque el texto en emacs (usando el mouse o establezca la marca C-SPC) y presione el botón "<- Retroceso" en el teclado en lugar de C-w. De esta manera, aún puede pegar texto en el portapapeles del sistema, sin preocuparse de que el portapapeles haya sido anulado por el texto eliminado porC-w

Antecedentes de esta respuesta: a veces, cuando recibía texto fuera de emacs que quiero usar para reemplazar una región en emacs, a menudo cometía un error al copiar primero ese texto en el portapapeles del sistema (es decir, en Windows Ctrl + C) y luego hacer un C-wen emacs para " eliminar "la región de texto que quiero reemplazar, con la esperanza de que más tarde M-wpueda recuperar mi texto en el portapapeles de kill-ring. Desafortunadamente, el portapapeles simplemente se anularía con el texto eliminado por C-w, y el mensaje original en el portapapeles nunca se mostraría en kill-ring.

Para la segunda pregunta, sí, siempre puede marcar el texto en emacs primero y luego directamente C-y

Kevin Zhu
fuente
0

Aquí hay una versión de kill-regioneso que no fuerza valores en el círculo de la muerte.

(defun kill-or-delete-region (beg end prefix)
  "Delete the region, storing it in the kill-ring.
If a prefix argument is given, don't change the kill-ring."
  (interactive "r\nP")
  (if prefix
      (delete-region beg end)
    (kill-region beg end)))

(global-set-key (kbd "C-w") 'kill-or-delete-region)

Esto le permite hacer lo mismo C-wque antes, pero C-u C-wahora elimina el texto sin cambiar el anillo de muerte.

Wilfred Hughes
fuente
0

¿Cómo eliminar texto sin anillo de muerte?

la delete-regionfunción eliminará la región seleccionada sin agregarla al anillo de muerte

Además, ¿es posible tirar de texto directamente en lugar de texto sin siquiera presionar botones para eliminarlo?

Creo que está preguntando cómo reemplazar el texto en una región seleccionada con algo que ya ha puesto en el anillo de muerte.

La configuración (delete-selection-mode 1)le permitirá tirar / pegar sobre una región seleccionada. También le permite simplemente escribir y reemplazar una región seleccionada.

En la versión 25.1.1 en OS XI también tuvo que agregar (setq select-enable-primary nil)para evitar que copiara la región seleccionada al kill ring

Kevincasey
fuente
0

Como complemento a todas las respuestas. Si escribe código elisp para eliminar, puede llamar a funciones que matan siempre y cuando use un objeto de anillo de muerte local como este:

(defun delete-something()
  "Delete something without storing in kill ring."
  (let (kill-ring)
     (kill-something)))

Utilice cualquier función que elimine algo en lugar de matar algo. La función luego se eliminará y no se recordará nada en el kill-ring real.

PRouleau
fuente