How to automatically kill buffer on terminal process exit in Emacs - emacs

How can I automatically kill the terminal buffer when the process associated with it ends.

I found much simpler method, define an advice on term-handle-exit
(defadvice term-handle-exit
(after term-kill-buffer-on-exit activate)
(kill-buffer))

I found that I can use process sentinels for that and set it using term-exec-hook
(add-hook 'term-exec-hook (lambda ()
(let* ((buff (current-buffer))
(proc (get-buffer-process buff)))
(lexical-let ((buff buff))
(set-process-sentinel proc (lambda (process event)
(if (string= event "finished\n")
(kill-buffer buff))))))))

Related

emacs function after asynchonous command

I currently use emacs for making and editing LaTeX documents. When compiling, I use an external program to compile into pdf. Right now, with the following code in my .emacs file, emacs will start compiling the document into a pdf whenever I save the file.
(defun auto-compile-latex ()
(save-window-excursion
(async-shell-command (format "cd %s; scons -u" default-directory))))
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-hook 'after-save-hook 'auto-compile-latex nil 'make-it-local)))
I prefer this over M-x compile, because I am more in the habit of saving, and it launches in the background, allowing me to continue working. However, I do not get a prominent notification when the compilation process finishes.
Ideally, I would want to run the following function whenever a compilation process finishes.
(defun latex-compilation-status (exit-code)
(if (/= exit-code 0)
(setq mode-name (propertize mode-name 'face 'font-lock-warning-face))
(setq mode-name (propertize mode-name 'face 'mode-line-highlight))))
That way, I can have the color in the mode line automatically change depending on whether the compilation was successful or not. However, looking through the emacs documentation, I have not found any mention of a hook that gets run after async-shell-command completes. I know that there is the message in the minibuffer stating the exit status of the subprocess, but if I am typing at the time, it is often hard to notice.
Alternatively, I could wait for the shell command to complete, then change the color immediately. However, this then makes the entirety of emacs freeze while compiling, which is not desired.
How would I go about having this indication applied at the end of the compilation, without having emacs freeze during the process?
You should try the command async-start from https://github.com/jwiegley/emacs-async
Thank you.
I ended up getting it using a modified version of lawlist's code.
This now has changes the color when starting to compile,
then changes it again to indicate success or failure.
;Automatically compile any latex documents when saved.
(defun auto-compile-latex ()
(setq mode-name (propertize mode-name 'face 'font-lock-string-face))
(set-process-sentinel
(start-process-shell-command "latex-compile" "latex-compile"
(format "cd %s; scons -u" default-directory))
'latex-compile-sentinel))
;Change the color after compilation. Still need to find the right hook to add it to.
(defun latex-compile-sentinel (process event)
(if (string-equal event "finished\n")
(setq mode-name (propertize mode-name 'face 'mode-line-highlight))
(setq mode-name (propertize mode-name 'face 'font-lock-warning-face))))
;Hooks for latex-mode
(add-hook 'LaTeX-mode-hook '(lambda ()
(add-hook 'after-save-hook 'auto-compile-latex nil 'make-it-local)))
As an aside, the emacs-async package did not work for this use.
I assume that this is because emacs-async starts the secondary functions in a separate process,
with some of the variables not propagated back to the parent process.
Here is another option using set-process-sentinel based upon a prior helpful answer by Francesco. Please do be careful, however, about using a let binding to define a start-process (which [in my lay opinion] is a definite "no no") because that would cause the process to begin immediately before its time. [FYI: Nicolas has gotten me out of quite a few jams in the past, so please be sure to take a good hard look at his solution also.]
Emacs: if latexmk finishes okay, then show pdf, else display errors
You would just add your function to the last part of the function dealing with success -- i.e., (when (= 0 (process-exit-status p)) . . .:
(defun latexmk ()
".latexmkrc contains the following entries (WITHOUT the four backslashes):
$pdflatex = 'pdflatex -file-line-error -synctex=1 %O %S && (cp \"%D\" \"%R.pdf\")';
$pdf_mode = 1;
$out_dir = '/tmp';"
(interactive)
(setq tex-file buffer-file-name)
(setq pdf-file (concat "/tmp/" (car (split-string
(file-name-nondirectory buffer-file-name) "\\.")) ".pdf"))
(setq line (format "%d" (line-number-at-pos)))
(setq skim "/Applications/Skim.app/Contents/SharedSupport/displayline")
(setq tex-output (concat "*" (file-name-nondirectory buffer-file-name) "*") )
(setq latexmk "/usr/local/texlive/2012/texmf-dist/scripts/latexmk/latexmk.pl")
(setq latexmkrc "/Users/HOME/.0.data/.0.emacs/.latexmkrc")
(if (buffer-modified-p)
(save-buffer))
(delete-other-windows)
(set-window-buffer (split-window-horizontally) (get-buffer-create tex-output))
(with-current-buffer tex-output (erase-buffer))
(set-process-sentinel
(start-process "compile" tex-output latexmk "-r" latexmkrc tex-file)
(lambda (p e) (when (= 0 (process-exit-status p))
(start-process "displayline" nil skim "-b" line pdf-file tex-file)
(switch-to-buffer (get-file-buffer tex-file))
(if (get-buffer-process (get-buffer tex-output))
(process-kill-without-query (get-buffer-process (get-buffer tex-output))))
(kill-buffer tex-output)
(delete-other-windows)))))
You could also arrange for your auto-compile-latex to run compile.

Elisp sentinel on process waiting for input

I made a function, compiling the current latex file:
;close the *async pdflatex* window, when pdflatex finishes
(defun latex-sentinel (process event)
(message event)
(cond ((string-match-p "finished" event)
(progn
(kill-buffer "*async pdflatex*")
(message "pdflatex done")
(delete-other-windows)))))
(defun latex-compile ()
"Runs pdflatex on current file"
(interactive)
(let* ((file-name (shell-quote-argument (buffer-file-name)))
(process (start-process-shell-command
"pdflatex"
"*async pdflatex*"
(concat "pdflatex " file-name))))
(set-process-sentinel process 'latex-sentinel)
(setq new-window (split-window-below 40))
(set-window-buffer new-window "*async pdflatex*")
(other-window 1)))
(add-hook 'LaTeX-mode-hook (lambda ()
(define-key LaTeX-mode-map (kbd "<f2>") 'latex-compile)))
When there is an error, while compiling, pdflatex freezes, and I see this:
My current workflow:
Scroll up to see the error
kill-this-buffer - to kill pdflatex process
delete-window - to close *async pdflatex* window and get back to editing.
Is it possible to track, that the process has stopped and is waiting for user input? My current sentinel activates only on "finished" event. So I could automate my current workflow.
[ #Thomas: you don't need AUCTeX for that. The builtin latex-mode also provides a C-c C-c binding for that task. ]
In general, detecting that a process is "waiting for me" is difficult/impossible (at best you might monitor the process's CPU usage and if it's been 0% for a while you can decide that it's probably waiting for you, but even doing that is tricky since you need to find the proper OS-process to monitor and then use system-dependent operations to get the CPU usage). latex-modes usually "solve" this by passing \nonstopmode\input on pdflatex's command line.
I had the same difficulty. The following seems to be OK.
(defun latex-compile()
(interactive)
(save-buffer)
(set 'tex-to-pdf "pdflatex -interaction=nonstopmode")
(set 'file-name (shell-quote-argument (buffer-file-name)))
(set 'comm1 (concat tex-to-pdf " " file-name ))
(set-process-sentinel
(start-process-shell-command "latex-compile"
"*async latex-compile*"
comm1)
'tex-to-pdf-sentinel))
;;;
(defun tex-to-pdf-sentinel (process event)
(cond
( (string-match-p "finished" event)
(message "latex-compile complete"))
( (string-match-p "\\(exited\\|dumped\\)" event)
(message "error in latex-compile"))
))
I realize use of global variables with set is not advisable; this is just a minimal example.
You can set up a second sentilel when the first completes, e.g. so that a viewer opens to display the the .pdf output, or you want to ensure bibtex runs each time. This may save on repeated calls to C-c C-c in latex mode.

Emacs Shell mode: how to send region to shell?

Is there some module or command that'll let me send the current region to shell?
I want to have something like Python-mode's python-send-region which sends the selected region to the currently running Python shell.
Ok, wrote an easy bit. Will probably spend some time to write a complete minor mode.
For time being the following function will send current line (or region if the mark is active). Does quite a good job for me:
(defun sh-send-line-or-region (&optional step)
(interactive ())
(let ((proc (get-process "shell"))
pbuf min max command)
(unless proc
(let ((currbuff (current-buffer)))
(shell)
(switch-to-buffer currbuff)
(setq proc (get-process "shell"))
))
(setq pbuff (process-buffer proc))
(if (use-region-p)
(setq min (region-beginning)
max (region-end))
(setq min (point-at-bol)
max (point-at-eol)))
(setq command (concat (buffer-substring min max) "\n"))
(with-current-buffer pbuff
(goto-char (process-mark proc))
(insert command)
(move-marker (process-mark proc) (point))
) ;;pop-to-buffer does not work with save-current-buffer -- bug?
(process-send-string proc command)
(display-buffer (process-buffer proc) t)
(when step
(goto-char max)
(next-line))
))
(defun sh-send-line-or-region-and-step ()
(interactive)
(sh-send-line-or-region t))
(defun sh-switch-to-process-buffer ()
(interactive)
(pop-to-buffer (process-buffer (get-process "shell")) t))
(define-key sh-mode-map [(control ?j)] 'sh-send-line-or-region-and-step)
(define-key sh-mode-map [(control ?c) (control ?z)] 'sh-switch-to-process-buffer)
Enjoy.
(defun shell-region (start end)
"execute region in an inferior shell"
(interactive "r")
(shell-command (buffer-substring-no-properties start end)))
I wrote a package that sends/pipes lines or regions of code to shell processes, basically something similar that ESS is for R. It also allows for multiple shell processes to exist, and lets you choose which one to send the region to.
Have a look here: http://www.emacswiki.org/emacs/essh
M-x append-to-buffer RET
M-x shell-command-on-region
aka.
M-|
Modifying Jurgens answer above to operate on a specific buffer gives the following function, which will send the region and then switch to the buffer, displaying it in another window, the buffer named PYTHON is used for illustration. The target buffer should already be running a shell.
(defun p-send(start end)
(interactive "r") ;;Make the custom function interactive and operative on a region
(append-to-buffer (get-buffer "*PYTHON*") start end) ;;append to the buffer named *PYTHON*
(switch-to-buffer-other-window (get-buffer "*PYTHON*")) ;;switches to the buffer
(execute-kbd-macro "\C-m")) ;;sends the enter keystroke to the shell
Do you want the command to be executed automatically, or just entered into the command line in preparation?
M-x append-to-buffer RET will enter the selected text into the specified buffer at point, but the command would not be executed by the shell.
A wrapper function for that could automatically choose *shell* for the buffer (or more smartly select/prompt based on current buffers in shell-mode), and then call append-to-buffer.
You could trivially record a keyboard macro to copy the region, switch to *shell*, yank, and enter (if required).
F3M-wC-xb*shell*RETC-yRETF4
C-xC-knmy-execute-region-in-shellRET
M-xinsert-kbd-macroRETmy-execute-region-in-shellRET
(global-set-key (kbd "C-c e") 'my-execute-region-in-shell)
Update
The above (brilliant and useful) answers look a bit incomplete as of mid-2020: sh-mode has a function for sending shell region to non-interactive shell with output in the minibuffer called sh-send-line-or-region-and-step.
Alternatively: click Shell-script in the mode bar at the bottom of the window, then Mouse-1, then Execute region. The output is sent to the minibuffer and #<*Messages*>.
If minibuffer output is not enough, there are referenced techniques to redirect output to other buffers (not only the shell one, see for example "How to redirect message/echo output to a buffer in Emacs?").
You can also execute all the script with C-c C-x. Voilà.
Here is another solution from this post.
Just copying it for convenience. The print statement is key here.
(add-hook 'python-mode-hook
'my-python-send-statement)
(defun my-python-send-statement ()
(interactive)
(local-set-key [C-return] 'my-python-send-statement)
(end-of-line)
(set-mark (line-beginning-position))
(call-interactively 'python-shell-send-region)
(python-shell-send-string "; print()"))
I adapted the accepted answer for ansi-term / sane-term.
Changes:
change "shell" to "ansi-term" everywhere
The (with-current-buffer pbuff ...) form doesn't work, because of the way that line and char modes work in terminal mode. It'll give you a read-only buffer error. Wrapping the insert in mode commands to toggle toggle line on before inserting fixes that, but is not needed because...
You can just use the process-send-string form by itself evidently, and the term output and cursor location reflect the change.
(defun ansi-term-send-line-or-region (&optional step)
(interactive ())
(let ((proc (get-process "*ansi-term*"))
pbuf
min
max
command)
(unless proc
(let ((currbuff (current-buffer)))
(sane-term)
(switch-to-buffer currbuff)
(setq proc (get-process "*ansi-term*"))))
(setq pbuff (process-buffer proc))
(if (use-region-p)
(setq min (region-beginning)
max (region-end))
(setq min (point-at-bol)
max (point-at-eol)))
(setq command (concat (buffer-substring min max) "\n"))
(process-send-string proc command)
(display-buffer (process-buffer proc) t)
(when step
(goto-char max)
(next-line))))
(defun sh-send-line-or-region-and-step ()
(interactive)
(sh-send-line-or-region t))
(defun sh-switch-to-process-buffer ()
(interactive)
(pop-to-buffer (process-buffer (get-process "*ansi-term*")) t))
(define-key sh-mode-map [(control ?j)] 'sh-send-line-or-region-and-step)
(define-key sh-mode-map [(control ?c) (control ?z)] 'sh-switch-to-process-buffer)

Emacs - Can't get buffer-offer-save working

I would like to have Emacs ask me whether I want to save a modified buffer, when that buffer is not associated with a file. To open a new buffer (not visiting a file) I have the following function in my .emacs file:
;; Creates a new empty buffer
(defun new-empty-buffer ()
"Opens a new empty buffer."
(interactive)
(let ((buf (generate-new-buffer "untitled")))
(switch-to-buffer buf)
(funcall (and default-major-mode))
(setq buffer-offer-save t)))
I thought setting "buffer-offer-save" to something not nil would made the trick. But whenever I kill the buffer with "kill-this-buffer", it gets instantly killed without asking anything.
This happens on GNU Emacs 23.1.1
Any ideas?
Thanks,
W
Edited to add use of buffers-offer-save. Note: the variable buffer-offer-save is only used upon exiting Emacs.
You can start with this code and customize it to what you want:
(add-to-list 'kill-buffer-query-functions 'ask-me-first)
(defun ask-me-first ()
"prompt when killing a buffer"
(if (or buffer-offer-save
(eq this-command 'kill-this-buffer)
(and (buffer-modified-p) (not (buffer-file-name))))
(y-or-n-p (format "Do you want to kill %s without saving? " (buffer-name)))
t))
Upon further reflection, that is a bit heavy-handed because you get prompted for all buffers that get killed, and there are often lots of temporary buffers that Emacs uses. If you just want to be prompted when you try to interactively kill a buffer (that isn't associated with a file).
You can use this advice which only prompts you when you're interactively trying to kill a buffer:
(defadvice kill-buffer (around kill-buffer-ask-first activate)
"if called interactively, prompt before killing"
(if (and (or buffer-offer-save (interactive-p))
(buffer-modified-p)
(not (buffer-file-name)))
(let ((answ (completing-read
(format "Buffer '%s' modified and not associated with a file, what do you want to do? (k)ill (s)ave (a)bort? " (buffer-name))
'("k" "s" "a")
nil
t)))
(when (cond ((string-match answ "k")
;; kill
t)
((string-match answ "s")
;; write then kill
(call-interactively 'write-file)
t)
(nil))
ad-do-it)
t)
;; not prompting, just do it
ad-do-it))
Modifying 'new-empty-buffer seems to make it work as I intended with Trey's defadvice.
;; Creates a new empty buffer
(defun new-empty-buffer ()
"Opens a new empty buffer."
(interactive)
(let ((buf (generate-new-buffer "untitled")))
(switch-to-buffer buf)
(funcall (and default-major-mode))
(put 'buffer-offer-save 'permanent-local t)
(setq buffer-offer-save t)))
This makes buffer-offer-save permanent local in our new buffer, so it won't get killed with the rest of the local variables when switching major modes.
buffer-offer-save asking on exiting Emacs but not on closing a buffer manually doesn't make sense, so why not “enlarge” its responsibilities?
(defadvice kill-buffer (around kill-buffer-ask activate)
"If `buffer-offer-save' is non-nil and a buffer is modified,
prompt before closing."
(if (and buffer-offer-save (buffer-modified-p))
(when (yes-or-no-p "The document isn't saved. Quit? ")
ad-do-it)
ad-do-it))
It will not prompt if untitled buffer is newly created. It will not prompt if you use kill-buffer from Elisp. It will not prompt on Emacs system buffers like *Messages*. But it will prompt if you created an empty buffer and wrote something in it.
See also my answer on creating an empty buffer.

Re-open *scratch* buffer in Emacs?

If I accidentally closed the scratch buffer in Emacs, how do I create a new scratch buffer?
GNU Emacs default bindings:
C-xb *scratch* RET
or, more verbosely
M-x switch-to-buffer *scratch* RET
The *scratch* buffer is the buffer selected upon startup, and has the major mode Lisp Interaction. Note: the mode for the *scratch* buffer is controlled by the variable initial-major-mode.
In general you can create as many "scratch" buffers as you want, and name them however you choose.
C-xb NAME RET
switches to a buffer NAME, creating it if it doesn't exist. A new buffer is not associated with a file on disk until you use C-xC-w (or M-x write-file RET) to choose a file where it should be saved.
M-x text-mode RET
changes the current buffer's major mode to Text mode. To find all the modes available (that is, without requiring any new packages), you can get a list by typing:
M-x apropos-command -mode$ RET
I add following in my .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)))
If I don't want to see scratch buffer I press C-x C-k , but it doesn't kill it, just place in the end of buffer list, so then I need it next time I don't have to create new one.
There are a whole bunch of tips on this EmacsWiki page.
Here's the first one:
A very simple function to recreate the scratch buffer:
(defun create-scratch-buffer nil
"create a scratch buffer"
(interactive)
(switch-to-buffer (get-buffer-create "*scratch*"))
(lisp-interaction-mode))
C-x b *scratch* RET y RET with iswitchb-mode enabled.
Just C-x b *scratch* RET otherwise.
I found this years ago when I first started using emacs; I have no idea where now but it has always had a home in my personal .el files. It does pop up in google searches.
;;; 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)
;;;----------------------------------------------------------------------
Like the docstring says, this function will:
Switch to the scratch buffer. If the buffer doesn't exist create it and write the initial message into it."
This will bring a new scratch buffer up which looks like the initial scratch buffer.
(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)
I used to use dwj's solution, and I was quite happy about it, until the day I realized that it failed when you actually rename the scratch buffer (for example by saving it).
Then I adopted this, which works well for me :
(run-with-idle-timer 1 t
'(lambda () (get-buffer-create "*scratch*")))
I have scratch as an interactive command for opening a new scratch buffer (I like to have several):
(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
adopted from: http://everything2.com/index.pl?node_id=1038451
(global-set-key (kbd "C-x M-z")
'(lambda ()
(interactive)
(switch-to-buffer "*scratch*")))
This will not only quickly switch to *scratch* buffer(since I do this frequently), but recreate a *scratch* buffer and enable lisp-interaction-mode automatically if you kill it accidentally. Change the binding as you like.
Just to note emacs package unkillable-scratch in MELPA will do this. There is also scratch-persist that will automatically save and restore the buffer between sessions.
This is what I use - I have this bound to a convenient keystroke. It sends you to the *scratch* buffer, regardless of whether or not it already exists, and sets it to be in lisp-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)))
I prefer to have my scratch buffer be an actual file that is automatically saved, and reopening it is as simple as opening a file. On startup, I kill the default and find my own like this.
(add-hook 'emacs-startup-hook
(lambda ()
(kill-buffer "*scratch*")
(find-file "/Users/HOME/Desktop/.scratch")))
I have a custom kill-buffer function that does essentially the same thing -- reopens my personal scratch saved file and kills the default scratch if I killed the last visible buffer.
I customized a few of the desktop.el functions to load after (kill-buffer "*scratch*") and (find-file "/Users/HOME/Desktop/.scratch") so that the file last visible on exiting Emacs doesn't get buried by the default scratch or buried by my custom scratch when launching Emacs.
I enjoy using auto-save-buffers-enhanced, which automatically saves any file extension that is not specifically excluded:
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"))
I use a slight variation of the function by #paprika when I want to create a no-file visiting buffer:
(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) ))
I have combined the solutions posted so far into one function:
(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))
To apply this function in your .emacs use:
(--scratch-buffer t)
(run-with-idle-timer 3 t '--scratch-buffer)
This will make the scratch buffer indestructible in the first place, and if saved it will be recreated. Additionally we can use a shortcut function scratch to bring up the buffer quickly:
(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))))
In the past it has proven useful to know the original startup-directory from which Emacs was started. This is either the value of desktop-dirname or the default-directory local variable of the 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))
So --startup-directory will always return the base directory of your makefile, TODO-file etc. In case there is no desktop (--no-desktop commandline-switch or no desktop-file) the --scratch-directory variable will hold directory Emacs was once started under.
find answer in EmacsWiki: http://www.emacswiki.org/emacs/RecreateScratchBuffer
(defun create-scratch-buffer nil
"create a scratch buffer"
(interactive)
(switch-to-buffer (get-buffer-create "*scratch*"))
(lisp-interaction-mode))
To add to the accepted answer, if you have ILO mode on (and it is autocompleting after C-x b, thus not letting you write *scratch*), then try:
C-xb C-b*scratch* RET
C-x b C-b *scratch* RET
C-xb and then type *scratch* ↩︎
to create a new buffer which is in lisp interaction mode also.