emacs kill yank

Emacs: ¿Cómo tirar el último texto tirado independientemente de los asesinatos posteriores?



kill yank (8)

Una mejor implementación Yank-Pop

Esto define una mejor implementación de yank-pop que intenta solucionar el creciente problema del yank-pop.

Sólo anula la función "current-kill". Debido al diseño modular de las variables y funciones de yank, yank-pop y kill ring en Emacs, resulta que anular "kill-current" es todo lo que se necesita para obtener el comportamiento que queremos.

El comportamiento deseado es que (1) matar algo todavía lo pone al frente del anillo de matanza, pero ahora (2) tirar o tirar algo de algo también lo pone al frente del anillo de matar (3) preservamos la habilidad de yank-pop para dar la apariencia de moverse a través del anillo de interrupción al incrementar una variable global y usar esto para reemplazar el último elemento de yank-pop''ped donde estaba. Esto también significa que (4) los elementos que se eliminan temporalmente (es decir, los que se colocan con los comandos yank o yank-pop, donde el siguiente comando es un yank-pop) finalmente se quedan donde están en el anillo de eliminación.

;; Example: ;; (setq kill-ring ''("a" "b" "c" "d" "e")) ;; ;; keystroke kill ring contents value of kill-ring-yank-index ;; C-y ("a" "b" "c" "d" "e") 0 ;; M-y ("b" "a" "c" "d" "e") 1 ;; M-y ("c" "a" "b" "d" "e") 2 ;; M-y ("d" "a" "b" "c" "e") 3 ;; C-y ("d" "a" "b" "c" "e") 0 ;; M-y ("a" "d" "b" "c" "e") 1 ;; M-d ("x" "a" "d" "b" "c" "e") ;; etc.

el código:

;; ---------------------------------------------------------------- ;; helper functions (defun list-insert-before (l n x) (if (<= n 0) (cons x l) (cons (car l) (list-insert-before (cdr l) (- n 1) x)))) (defun list-prepend-nth (l n) (if (<= n 0) l (let* ((lx (list-prepend-nth (cdr l) (- n 1)))) (cons (car lx) (cons (car l) (cdr lx)))))) (defun list-insert-car-at (l n) (list-insert-before (cdr l) n (car l))) ;; ---------------------------------------------------------------- ;; overriding current-kill (defvar kill-ring-yank-index 0 "Index into kill-ring of last yank-pop. The item yank-popped will be at the head of the kill ring, but if the next command is also yank-pop, it will be returned here first before this variable is incremented.") (defun current-kill (n) "Replaces standard ''current-kill'' function. This version tries to fix the increasing yank-pop problem. TODO: - respect second argument of original function - deal with ''interprogram-{cut,paste}-function'' " (if (eq 0 n) ;; looks like we''re doing a yank; reset ;; kill-ring-yank-index to 0 to indicate that the ;; current head of the list is useful to the user (progn (setq kill-ring-yank-index 0) (car kill-ring)) ;; otherwise put the head of kill-ring back where we had ;; previously found it, and fetch the next element (setq kill-ring (list-insert-car-at kill-ring kill-ring-yank-index)) (setq kill-ring-yank-index (+ kill-ring-yank-index n)) (when (>= kill-ring-yank-index (- (length kill-ring) 1)) (setq kill-ring-yank-index (- (length kill-ring) 1)) (message "Reached end of kill-ring")) (when (< kill-ring-yank-index 0) (setq kill-ring-yank-index 0) (message "Reached beginning of kill-ring")) (setq kill-ring (list-prepend-nth kill-ring kill-ring-yank-index)) (car kill-ring))) ;; ---------------------------------------------------------------- ;; new key binding ;; Here''s an auxiliary function and key binding that makes it easy to ;; go back and forth in the kill-ring while we''re yank-popping (defun yank-pop-back () "" (interactive "*") (yank-pop -1)) (global-set-key "/C-/M-y" ''yank-pop-back)

A menudo me encuentro tirando de algo repetidamente después de hacer algunas muertes y se convierte en un proceso como:

  1. Cy
  2. Cy My
  3. Cy My My
  4. Cy My My My

Cada vez que mato un texto, empuja la primera muerte de nuevo en el anillo de muerte, de modo que necesito recorrer todas las muertes para volver al texto que quiero tirar. Lo que quiero hacer es tirar repetidamente el mismo texto mientras se mata el texto entre tirones. es posible?


  1. Si desea tirar repetidamente el mismo texto, use la selección secundaria en lugar de la región o el texto eliminado.

    Lo que falta en Vanilla Emacs es un enlace clave para eliminar la selección secundaria. Yo uso CMy para eso (ver biblioteca second-sel.el ).

  2. Para obtener acceso directo a cualquier muerte en el anillo de muerte, use My con Examinar Matar anillo o con Icicles . En ambos casos, My nivel superior le da acceso a todas las entradas en el anillo de eliminación.

    Y si usa la biblioteca second-sel.el , además del anillo de eliminación, tendrá acceso a un anillo de sus selecciones secundarias anteriores.

    Y si usa la biblioteca second-sel.el y Icicles, entonces My yankea una entrada del anillo del que sacó por última vez (kill ring o anillo de selección secundaria).

    Y si usa la biblioteca browse-kill-ring+.el , el buscador kill-ring también le da acceso a un anillo alternativo (que, de forma predeterminada, es el anillo de selecciones secundarias si utiliza la biblioteca second-sel.el ).


Este es un hack extraño, pero puede ayudar.

La primera vez que usa My , normalmente obtiene un error (sin tirón anterior). Entonces, la idea es que esta primera vez que obtenga el último tirón en lugar del último asesinato.

Para almacenar ese último tirón, utilizo el registro ''Y'' en este ejemplo.

Estas 2 funciones envolverían el yank y el yank-pop. Esperas errores, espero sugerencias.

(defun jp/yank (&optional arg) "Yank and save text to register Y" (interactive) (set-register ?Y (current-kill 0 t)) (yank arg)) (defun jp/yank-pop (&optional arg) "If yank-pop fails, then insert register Y" (interactive) (condition-case nil (yank-pop arg) (error (insert (get-register ?Y))))) (global-set-key (kbd "M-y") (quote jp/yank-pop)) (global-set-key (kbd "C-y") (quote jp/yank))


Estoy tratando de hackear a lo largo de la línea de usar un modo menor. Llamemos a este delete-mode . Una vez que ingrese al modo de eliminación, los comandos de eliminación ( kill-line kill-paragraph kill-word , ...) cambiarán su comportamiento para que la parte de delete-region de sus comandos sea reemplazada por la delete-region , y la nueva El material no se añadirá al anillo de muerte. Mientras esté en este modo, el anillo de muerte permanecerá constante. Cuando vuelve a salir de este modo, el comportamiento vuelve a la normalidad.

El siguiente es un código incompleto que intenta implementar lo que escribí anteriormente. Funciona correctamente al cambiar al modo de eliminación, pero tiene problemas para volver a activar (desactivar el modo secundario). Cualquier ayuda para arreglar esto sería apreciada.

(defvar delete-mode nil) (defun delete-mode () "delete minor-mode" (interactive) (setq delete-mode (not delete-mode)) (if delete-mode (defalias ''kill-region ''delete-region) (defalias ''kill-region ''original-kill-region) ) ) (if (not (assq ''delete-mode minor-mode-alist)) (setq minor-mode-alist (cons ''(delete-mode "Delete mode on") minor-mode-alist) ) (defalias ''original-kill-region ''kill-region) )


No uses el anillo de matar; poner el texto en un registro en su lugar. Cx rsa para almacenar el texto de la región en (diga) el registro "a"; A continuación, Cx ria para insertarlo en otro lugar.


Podría usar Mx delete-region lugar para eliminar el texto, posiblemente vinculándolo a una clave si desea usarlo mucho.


Trataré de usar delete-region más, pero conozco mejor los comandos kill. Un truco que no requiere programación o planificación anticipada es usar Mw después de una cadena particularmente molesta de My. Esto pone una copia más accesible del tirón final en el anillo de muerte.