2011-02-23 22 views
13

Aquí está mi problema: Uso Emacs y obtengo muchos búferes que son bastante inútiles todo el tiempo, como * Messages * o * Completions *.Killing buffers cuyos nombres comienzan con una cadena en particular

Quiero enlazar \ C-y para cerrar todos los búferes que comienzan con * a excepción de * shell * (y * shell * < k>) búferes.

Para hacer eso, me gustaría añadir un poco de Emacs-Lisp en mi archivo .emacs:

(defun string-prefix s1 s2 
    (if (> (string-length s1) (string-length s2)) nil 
    (string=? s1 (substring s2 0 (string-length s1))))) 

(defun curry2 
    (lambda (f) 
    (lambda (x) 
     (lambda (y) 
    (f x y))))) 

(defun filter 
    (lambda (f l) 
    (if (null? l) '() 
     (let ((rest (cdr l))) 
    (if (f (car l)) (cons (car l) rest) 
     rest))))) 


(defun kill-useless (arg) 
    (interactive "p") 
    (map 'kill-buffer 
     (filter 
    (not ((curry2 string-prefix) "*shell*")) 
    (list-buffers) 
    ))) 

(global-set-key "\C-y" 'kill-useless) 

ya he probado string-prefix y curry2 usando Scheme y filter parece bastante sencillo. Lamentablemente, no puedo hacer que kill-useless funcione correctamente.

Dice filter: Invalid function: (curry2 string-prefix).

Ahora, la cosa es que tipo de malo en Emacs-Lisp, yo realmente no uso ninguna Lisp, excepto Esquema, y ​​en el Esquema (MIT), esto funciona:

(filter ((curry2 string-prefix?) "*shell") '("*shell*" "*sh22" "eel")) 
;Value 5: ("*shell*") 

me gustaría :

  1. una manera de arreglar mi código
  2. sugerencias sobre cómo hacer esto de una manera diferente

Gracias!

+1

El '* Mensaje *' buffer es un interés uno: cada vez que Emacs le diga algo , lo dejó allí, por lo que puede, por ejemplo, copiarlo y pegarlo en google para encontrar una solución en google. Tenga en cuenta también que cuando probablemente utilizará algún modo (como el mago) que utilizará dicho buffer de una manera útil. –

+0

Sí, terminé manteniendo ese buffer también. ¡Gracias por el consejo! –

Respuesta

11

Un enfoque alternativo:

(require 'cl) 

(defun is-useless-buffer (buffer) 
    (let ((name (buffer-name buffer))) 
    (and (= ?* (aref name 0)) 
     (not (string-match "^\\*shell\\*" name))))) 

(defun kill-useless-buffers() 
    (interactive) 
    (loop for buffer being the buffers 
     do (and (is-useless-buffer buffer) (kill-buffer buffer)))) 
+0

+1 para el bucle sobre la construcción de búferes. ¡Bonito! – ataylor

+0

Me gusta más este enfoque. También agregué un cheque para mantener el buffer \ * Messages *. Felicitaciones Sean! Usted gana :) Además, ¿qué hace '(require 'cl)' hacer exactamente? –

+0

Presenta el paquete Common Lisp de Emacs, que es donde vive la macro ("extremadamente útil") "bucle". El paquete completo es muy útil; la primera línea en mi archivo .emacs es (requiere 'cl). Ver http://www.gnu.org/software/emacs/manual/html_mono/cl.html – Sean

5

Tenga en cuenta que elisp no es el esquema, ni siquiera el ceceo común. La sintaxis y la semántica son diferentes. Por ejemplo, defun requiere una lista de parámetros rodeada de paréntesis. Además, currying no es realmente posible en elisp.

Afortunadamente, elisp tiene edificaciones integradas para la mayoría de lo que desea hacer. Para string-prefix puede usar el string-prefix-p incorporado. Para filter, puede usar remove-if-not, o remove-if para el inverso.

Para el currying puede utilizar la función integrada apply-partially. Para obtener una función que detecta cadenas con el prefijo "*shell*", intentar algo como esto:

(apply-partially 'string-prefix-p "*shell*") 

Usted puede utilizar de esta manera:

(mapcar 
(apply-partially 'string-prefix-p "*shell*") 
'("*shell*" "foo" "*shell*<2>")) 

; results in 
(t nil t) 

(require 'cl) ; for remove-if 
(remove-if 
(apply-partially 'string-prefix-p "*shell*") 
'("*shell*" "foo" "*shell*<2>")) 

; results in 
("foo") 
+0

Gracias por el aviso, pero le di la respuesta a la persona que me dio una solución de trabajo. ¡Intentar juguetear para conseguir este trabajo no habría sido demasiado divertido! –

25

Chfkill-matching-buffersRET

kill-matching-buffers es un inte compilación de la función Lisp compilada en `files.el '.

(kill-coincidentes-buffers REGEXP & interna opcional-TOO)

tampones Kill cuyo nombre coincide con la expresión regular especificada. El segundo argumento opcional indica si también se eliminarán los búferes internos.

+2

+1 para la función incorporada, aunque un ejemplo real de cómo usarlo hubiera sido mucho más útil. –

+2

Me sigue preguntando si quiero cerrar todos los búfers (incluso si no se han modificado) - ¿hay alguna manera de evitar eso? – Zitrax

+0

Zitrax: http: // stackoverflow.com/a/10931190/324105 – phils

0

Puede ser una buena idea para ver lo que va a eliminar antes de eliminarlo, ir a lo seguro.

En carámbanos, por defecto C-x k es un multi-comandos que puede utilizar para matar a cualquier número de memorias intermedias que responden a su entrada minibuffer. En este caso, escribiría * TAB para ver todos los nombres de los buffers comenzando con * como candidatos de finalización.

A continuación, puede reducir las coincidencias de varias maneras. Cuando todas las coincidencias restantes sean lo que desea, presione C-! para eliminar todos esos búferes.

En el caso que ha presentado, no desea eliminar los búferes llamados *shell.... Entonces, después de * TAB, debe presionar S-SPC y luego ingresar otro patrón para que coincida con: shell, luego S-TAB. Eso se reduce a solo los buffers *shell... que usted hace no quiere matar. Luego, toca C-~ para restar esas coincidencias (complemento). Eso deja todos los búferes excepto los búferes de shell. Hit C-! y todos son asesinados.

También puede eliminar almacenamientos intermedios individuales simplemente haciendo clic con el botón secundario en sus nombres en *Completions*: C-mouse-2.

De manera más general, en carámbanoscada múltiples comandos que lee un nombre de búfer le permite utilizar S-delete (la tecla Supr Mayús +) para matar a los candidatos de amortiguamiento.

http://www.emacswiki.org/emacs/Icicles_-_Multi-Commands

http://www.emacswiki.org/emacs/Icicles_-_More_About_Multi-Commands

0

encontré kill-matching-functions me impulsó para los búferes no modificados, que no es lo que quería. La función siguiente eliminará los búferes que coincidan con un prefijo (como en el título de la pregunta). No es exactamente lo que querías, pero tal vez la gente como yo que venga aquí desde Google lo encontrará útil.

(require 'cl) 
(defun kill-buffers-with-prefix (prefix) 
    "Kill buffers whose names start with the given prefix" 
    (interactive "sPrefix to kill: ") 
    (loop for buffer in (buffer-list) 
     do (if (string-prefix-p prefix (buffer-name buffer)) 
       (kill-buffer buffer)))) 
0

matar a todos los otros tampones

(defun px-kill-other-buffers() 
    "Kill all other buffers." 
    (interactive) 
    (mapc 'kill-buffer (delq (current-buffer) (buffer-list)))) 

Para buscar el principio de una cadena

(defun string-starts-with-p (string prefix) 
    "Return t if STRING starts with prefix." 
    (and 
    (string-match (rx-to-string `(: bos ,prefix) t) string) 
    t)) 
Cuestiones relacionadas