¿Volver a abrir * scratch * buffer en Emacs?

168

Si accidentalmente cerré el buffer de scratch en Emacs, ¿cómo creo un nuevo buffer de scratch ?

Fortepianissimo
fuente

Respuestas:

199

Enlaces predeterminados de GNU Emacs:

C-xb *scratch* RET

o, más verbosamente

M-x switch-to-buffer *scratch* RET

El *scratch*búfer es el búfer seleccionado al inicio y tiene el modo principal Interacción Lisp . Nota: el modo para el *scratch*búfer está controlado por la variable initial-major-mode.

En general, puede crear tantos buffers "scratch" como desee y nombrarlos como quiera.

C-xb NAME RET

cambia a un búfer NAME, creándolo si no existe. Un nuevo búfer no está asociado con un archivo en el disco hasta que use C-xC-w(o M-x write-file RET) para elegir un archivo donde debe guardarse.

M-x text-mode RET

cambia el modo principal del búfer actual al modo Texto. Para encontrar todos los modos disponibles (es decir, sin requerir ningún paquete nuevo), puede obtener una lista escribiendo:

M-x apropos-command -mode$ RET

Trey Jackson
fuente
8
Tenga en cuenta que hay algo especial sobre scratch , al menos en GNU Emacs 21 y versiones posteriores: cambiar a un nuevo buffer de scratch lo volverá a poner en modo de interacción Lisp.
Peter S. Housel
Solo como un seguimiento rápido de esto, si .emacsdefine un modo scratch predeterminado diferente , este será el modo para el nuevo scratch , no el modo List Interaction.
ocodo
23

Agrego lo siguiente en mis .emacs:

;; bury *scratch* buffer instead of kill it
(defadvice kill-buffer (around kill-buffer-around-advice activate)
  (let ((buffer-to-kill (ad-get-arg 0)))
    (if (equal buffer-to-kill "*scratch*")
        (bury-buffer)
      ad-do-it)))

Si yo no quiero ver cero búfer presiono Cx Ck, pero no la mata, lugar justo en el final de la lista de amortiguamiento, por lo que entonces lo necesito próxima vez no tengo para crear uno nuevo.

usuario45273
fuente
Cuando pruebo este consejo de "ibuffer", el consejo se ignora. Pero lo mejor que puedo decir es que "ibuffer" está usando "kill-buffer". ¿Me puedes ayudar?
A.Ellett
Bueno, al eliminar "cerrar búfer" en la interfaz gráfica, se elimina el scratch . Esto funciona solo para Cx k,
Maurizio Loreti
15

Hay muchos consejos en esta página de EmacsWiki .

Aquí está el primero:

Una función muy simple para recrear el búfer scratch:

(defun create-scratch-buffer nil
   "create a scratch buffer"
   (interactive)
   (switch-to-buffer (get-buffer-create "*scratch*"))
   (lisp-interaction-mode))             
idbrii
fuente
9

Cx b *scratch*RET y RET con el modo iswitchb habilitado.

Solo Cx b *scratch*RET de lo contrario.

Steven Huwig
fuente
Con los enlaces predeterminados, el 'y RET' no es necesario y solo inserta una 'y' y una nueva línea en el búfer de scratch recién creado .
Trey Jackson
Vaya, tal vez sea del modo iswitchb. Lo siento por eso. Sobre otro tema, pruebe el modo iswitchb;)
Steven Huwig
Uno no debería, además, no hay nada especial en el nombre scratch . Se puede usar Cx b para crear cualquier cantidad de buffers "scratch", con nombres arbitrarios.
Chris Conway
1
No es algo especial en el nombre * scratch * (como se señala en la respuesta aceptada) - si se crea un buffer llamado cero * * el modo mayor será ajustado de acuerdo a la initial-major-modevariable (lisp-interaction-mode por defecto).
phils
4

Encontré esto hace años cuando comencé a usar emacs; No tengo idea de dónde ahora, pero siempre ha tenido un hogar en mis archivos .el personales. Aparece en las búsquedas de Google.

;;; Prevent killing the *scratch* buffer -- source forgotten
;;;----------------------------------------------------------------------
;;; Make the *scratch* buffer behave like "The thing your aunt gave you,
;;; which you don't know what is."
(save-excursion
  (set-buffer (get-buffer-create "*scratch*"))
  (make-local-variable 'kill-buffer-query-functions)
  (add-hook 'kill-buffer-query-functions 'kill-scratch-buffer))

(defun kill-scratch-buffer ()
  ;; The next line is just in case someone calls this manually
  (set-buffer (get-buffer-create "*scratch*"))

  ;; Kill the current (*scratch*) buffer
  (remove-hook 'kill-buffer-query-functions 'kill-scratch-buffer)
  (kill-buffer (current-buffer))

  ;; Make a brand new *scratch* buffer
  (set-buffer (get-buffer-create "*scratch*"))
  (lisp-interaction-mode)
  (make-local-variable 'kill-buffer-query-functions)
  (add-hook 'kill-buffer-query-functions 'kill-scratch-buffer)

  ;; Since we killed it, don't let caller do that.
  nil)
;;;----------------------------------------------------------------------
dwj
fuente
3

Solía ​​usar la solución de dwj, y estaba muy contento con eso, hasta el día en que me di cuenta de que falló cuando cambiaste el nombre del búfer de memoria virtual (por ejemplo, guardándolo).

Luego adopté esto, que me funciona bien:

  (run-with-idle-timer 1 t
    '(lambda () (get-buffer-create "*scratch*")))
Gyom
fuente
3

Tengo scratchcomo comando interactivo para abrir un nuevo buffer de scratch (me gusta tener varios):

(defun scratch ()
  "create a new scratch buffer to work in. (could be *scratch* - *scratchX*)"
  (interactive)
  (let ((n 0)
        bufname)
    (while (progn
             (setq bufname (concat "*scratch"
                                   (if (= n 0) "" (int-to-string n))
                                   "*"))
             (setq n (1+ n))
             (get-buffer bufname)))
  (switch-to-buffer (get-buffer-create bufname))
  (if (= n 1) initial-major-mode))) ; 1, because n was incremented

adoptado de: http://everything2.com/index.pl?node_id=1038451

pimenton
fuente
¿Cómo es esto superior a simplemente cambiar a un nuevo búfer (Cx b bufnameRET)?
bignose
@bignose: uso ido-modey generalmente tengo bastantes buffers abiertos. Crear un nuevo buffer usando C-x bsería realmente tedioso. Tendría que encontrar un nombre único que no coincida con ninguno de los buffers actuales.
pimentón
3
(global-set-key (kbd "C-x M-z")
                '(lambda ()
                   (interactive)
                   (switch-to-buffer "*scratch*")))

Esto no solo cambiará rápidamente al *scratch*búfer (ya que hago esto con frecuencia), sino que recreará un *scratch*búfer y lo habilitará lisp-interaction-modeautomáticamente si lo mata accidentalmente. Cambia el enlace como quieras.

CodyChan
fuente
3

Solo para tener en cuenta que el paquete emacs unkillable-scratchen MELPA hará esto. También hay scratch-persistque guardará y restaurará automáticamente el búfer entre sesiones.

nj35
fuente
2

Como dice la cadena de documentación, esta función:

Cambie al búfer de memoria virtual. Si el búfer no existe, créelo y escriba el mensaje inicial en él ".

Esto traerá un nuevo buffer de scratch que se parece al buffer de scratch inicial.

(defun switch-buffer-scratch ()
  "Switch to the scratch buffer. If the buffer doesn't exist,
create it and write the initial message into it."
  (interactive)
  (let* ((scratch-buffer-name "*scratch*")
         (scratch-buffer (get-buffer scratch-buffer-name)))
    (unless scratch-buffer
      (setq scratch-buffer (get-buffer-create scratch-buffer-name))
      (with-current-buffer scratch-buffer
        (lisp-interaction-mode)
        (insert initial-scratch-message)))
    (switch-to-buffer scratch-buffer)))

(global-set-key "\C-cbs" 'switch-buffer-scratch)
kjfletch
fuente
2

Esto es lo que uso: tengo esto vinculado a una combinación de teclas conveniente. Lo envía al *scratch*búfer, independientemente de si ya existe o no, y lo establece enlisp-interaction-mode

(defun eme-goto-scratch () 
  "this sends you to the scratch buffer"
  (interactive)
  (let ((eme-scratch-buffer (get-buffer-create "*scratch*")))
    (switch-to-buffer eme-scratch-buffer)
    (lisp-interaction-mode)))
Edric
fuente
2

Prefiero que mi memoria virtual sea un archivo real que se guarda automáticamente, y volver a abrirlo es tan simple como abrir un archivo. En el inicio, elimino el valor predeterminado y encuentro el mío así.

(add-hook 'emacs-startup-hook
  (lambda ()
    (kill-buffer "*scratch*")
    (find-file "/Users/HOME/Desktop/.scratch")))

Tengo una función personalizada kill-buffer que hace esencialmente lo mismo: reabrir mi archivo guardado scratch personal y elimina el scratch predeterminado si eliminé el último buffer visible.

Personalicé algunas de las desktop.elfunciones para cargar después (kill-buffer "*scratch*") y (find-file "/Users/HOME/Desktop/.scratch")para que el archivo visible por última vez al salir de Emacs no quede oculto por el scratch predeterminado ni por mi scratch personalizado al iniciar Emacs.

Disfruto usando auto-save-buffers-enhanced, que guarda automáticamente cualquier extensión de archivo que no esté específicamente excluida

https://github.com/kentaro/auto-save-buffers-enhanced/blob/master/auto-save-buffers-enhanced.el

(require 'auto-save-buffers-enhanced)
(auto-save-buffers-enhanced t)
(setq auto-save-buffers-enhanced-save-scratch-buffer-to-file-p 1)
(setq auto-save-buffers-enhanced-exclude-regexps '("\\.txt" "\\.el" "\\.tex"))

Utilizo una ligera variación de la función de @paprika cuando quiero crear un búfer de visitas sin archivos:

(defun lawlist-new-buffer ()
  "Create a new buffer -- \*lawlist\*"
(interactive)
  (let* (
    (n 0)
    bufname)
  (catch 'done
    (while t
      (setq bufname (concat "*lawlist"
        (if (= n 0) "" (int-to-string n))
          "*"))
      (setq n (1+ n))
      (if (not (get-buffer bufname))
        (throw 'done nil)) ))
  (switch-to-buffer (get-buffer-create bufname))
  (text-mode) ))
lista de leyes
fuente
1

He combinado las soluciones publicadas hasta ahora en una función:

(defun --scratch-buffer(&optional reset)
  "Get the *scratch* buffer object.
Make new scratch buffer unless it exists. 
If RESET is non-nil arrange it that it can't be killed."
  (let ((R (get-buffer "*scratch*")))
    (unless R
      (message "Creating new *scratch* buffer")
      (setq R (get-buffer-create "*scratch*") reset t))
        (when reset
          (save-excursion
            (set-buffer R)
            (lisp-interaction-mode)
            (make-local-variable 'kill-buffer-query-functions)
            (add-hook 'kill-buffer-query-functions '(lambda()(bury-buffer) nil)
          )))
    R))

Para aplicar esta función en su .emacs use:

(--scratch-buffer t)
(run-with-idle-timer 3 t '--scratch-buffer)

Esto hará que el búfer de memoria virtual sea indestructible en primer lugar y, si se guarda, se volverá a crear. Además, podemos usar una función de acceso directo scratchpara abrir el búfer rápidamente:

(defun scratch()
  "Switch to *scratch*.  With prefix-arg delete its contents."
  (interactive)
  (switch-to-buffer (--scratch-buffer))
  (if current-prefix-arg
      (delete-region (point-min) (point-max))
    (goto-char (point-max))))

En el pasado, ha resultado útil conocer el directorio de inicio original desde el que se inició Emacs. Este es el valor desktop-dirnameo la default-directoryvariable local del scratch-buffer:

(defvar --scratch-directory
  (save-excursion (set-buffer "*scratch*") default-directory)
  "The `default-directory' local variable of the *scratch* buffer.")

(defconst --no-desktop (member "--no-desktop" command-line-args)
  "True when no desktop file is loaded (--no-desktop command-line switch set).")

(defun --startup-directory ()
  "Return directory from which Emacs was started: `desktop-dirname' or the `--scratch-directory'.
Note also `default-minibuffer-frame'."
  (if (and (not --no-desktop) desktop-dirname) 
      desktop-dirname
    --scratch-directory))

Así --startup-directorio siempre devolverá el directorio base de su makefile, TODO-archivo, etc. En caso de que no hay escritorio ( --no-desktop de comandos-interruptor o sin desktop-file) la --scratch-directoryvariable de sostendrá directorio de Emacs fue una vez comenzó bajo.

Andreas Spindler
fuente
0

Para agregar a la respuesta aceptada, si tiene activado el modo OIT (y se completa automáticamente después C-x b, por lo que no le permite escribir *scratch*), intente:

C-xb C-b*scratch* RET

C-x b C-b *scratch* RET

petre
fuente
-3

C-xb y luego escribe *scratch* ↩︎

para crear un nuevo búfer que también esté en modo de interacción lisp.

stephanea
fuente