Emacs: send output of eval to a new buffer - emacs

I want to eval a buffer and send the result to a new buffer. How do I "send" the result of the eval-buffer function to the content of a new buffer? here my attempt:
(set-buffer (get-buffer-create "test")) ; create new buffer
(let ((value (eval-buffer)) .... ; how to put this inside the new buffer?

This evaluates the contents of buffer evaluate-me and prints the value of each toplevel form to the buffer output:
(eval-buffer "evaluate-me" (get-buffer-create "output"))
Do C-h f eval-buffer to see the documentation that explains why this works. The second argument to eval-buffer is named PRINTFLAG, of which the docstring says:
PRINTFLAG controls printing of output:
A value of nil means discard it; anything else is stream for print.
The slightly confusing thing about this is Emacs's unusual concept of what counts as an "output stream". Buffers, markers (locations in buffers), and the echo area can all be treated as "streams", as can any function that takes a character argument. Look up the docstrings of the print function or standard-output variable for more info.
The more general way to make things happen inside another buffer is the macro with-current-buffer. Unlike set-buffer, it takes care of restoring the original context cleanly even if errors happen in the wrapped code.
(with-current-buffer (get-buffer-create "output")
(insert "some text"))

Your value calculation appears wrong: since set-buffer will switch to the new buffer, eval-buffer will evaluate the contents of the new empty buffer. My understanding is that you want to evaluate the contents of the previous buffer and print its value in the new buffer:
(let ((value (eval-buffer)))
(set-buffer (get-buffer-create "test"))
(print value))
If you want the new buffer to be visible to the user, replace set-buffer with switch-to-buffer.

Related

Force fontification of another buffer

Let us assume I have registered a function as fontification in a buffer named foo.
With jit-lock-mode:
(jit-lock-register #'(lambda (start end)
(message "Jit!")))
From another buffer, I would like to force that fontification function (and all registered fontification functions).
I am using the function font-lock-flush, in the following:
(with-current-buffer "foo"
(font-lock-flush))
Without any success.
That is, when I evaluate (with-current-buffer "foo"...) in a buffer different from foo, no message is printed.
I would expect that expression forces the anonymous function registered as fontification in buffer foo. Instead, the function is not invoked -- I don't see any message in the *Message* buffer.
Additional Notes
I have also tried other functions to force, such as: jit-lock-fontify-now. Still, no message is printed.
How to reproduce
Simply, open two buffer: foo and bar.
The content of foo:
(jit-lock-register #'(lambda (start end)
(message "Jit!")))
And evaluate the buffer.
Now, every time the buffer needs to be fontified a message ("Jit!" will be printed).
Instead, the content of the buffer bar:
(with-current-buffer "foo"
(font-lock-flush)) ;; or jit-lock-fontify-now
Evaluate (from the buffer bar) that expression.
You should notice no message is printed, despite the fact that expression should force the fontification inside foo.
jit-lock-refontify is a compiled Lisp function in ‘jit-lock.el’.
(jit-lock-refontify &optional BEG END)
Force refontification of the region BEG..END (default whole buffer).
Experimentally, this does what you want:
(with-current-buffer "foo"
(jit-lock-refontify))
After running jit-lock-register in foo, buffer foo is marked as fully "jit-locked" (more specifically, it's done in the redisplay cycle that immediately follows, and it's done because the buffer is presumably fully displayed). Running jit-lock-fontify-now after that will do nothing because there's nothing there that needs to be "jit-locked". Running font-lock-flush won't make a difference either because presumably foo is in fundamental-mode so font-lock-mode is not enabled so font-lock-flush sees that there's no font-lock highlighting applied yet, and hence nothing to flush.

Get the content as string of a region in a buffer by elisp program

Here is the problem that I'm solving:
Convert a region of text into a string data structure for subsequent processing by elisp program. The challenge is that
I want to execute an elisp program interactively without affecting the selection of a region
store the string value into a variable so that I can further manipulate it.
By my understanding, a region is defined by a mark and the subsequent cursor position. And I usually execute elisp program in *scratch* buffer. Furthermore, the region is also in the *scratch* buffer.
But to write the function call and execute it in the buffer, I need to move the cursor away from the end of the text selection (region) in order to write the program of
(setq grabbed (buffer-substring-no-properties (region-beginning) (region-end)))
but then the region of selection would change due to the cursor movement.
So I wonder how I could execute the elisp program while keeping the selection intact and still can access the return value.
If you want to run the function from some Elisp code but as if the user had invoked it via a keybinding, you can use call-interactively:
(setq variable-to-keep-the-value (call-interactively 'lines-to-list))
But in most cases, what you want instead is to take yourself the responsibility to choose to which part of text the function should apply:
(setq variable-to-keep-the-value
(lines-to-list (region-beginning) (region-end)))
Notice that the region's boundaries are nothing magical, regardless if they've been set by the mouse or what.
Finally, I found a desirable solution! It's using ielm buffer, the real repl of elisp.
In the ielm buffer, I can set working buffer (by C-c C-b) to be a buffer where I have the text to be manipulated, for example, *scratch*.
I can then select a region of the working buffer to be processed, and in the ielm buffer then I can type and execute elisp code to extract the text in the selected region in the working buffer, for example,
ELISP> (setq grabbed (buffer-substring-no-properties (region-beginning) (region-end)))
"One\nTwo\nThre"
ELISP> grabbed
"One\nTwo\nThre"
ELISP> (split-string grabbed)
("One" "Two" "Thre")
I can then work with the value held by the set variable, grabbed.
Here is a very helpful description of ielm:
https://www.masteringemacs.org/article/evaluating-elisp-emacs

Get result back from comint-redirect-send-command

I want to read the output of a buffer after process started by comint finishes.
(comint-redirect-send-command-to-process
command-string ;; tested to work in the commint buffer
output-buffer-name ;; random text
buffer-process ;; (get-buffer-process (current-buffer))
nil ;; don't echo input back
t) ;; don't show output buffer immediatly
This sexp is evaluated in a buffer running a comint process. I want to read all the text of output-buffer-name once the process has finished.
I have tried applying the solution posted to this question: sleep in emacs lisp by adding this below the process start command:
(defun on-status-change (process status)
(message "status done"))
(set-process-sentinel buffer-process 'on-status-change)
This message does not appear in *Messages*.
There is no prompt in the output-buffer text, but I can write a function that returns t when the output is finished based on the full output text.
How can I react to the buffer finishing/changing, or how can I force comint to run this function synchronously.
The source for comint-redirect-send-command-to-process is here on line 3717
If anyone else has a similar issue, I ended up "solving" this.
(while (not comint-redirect-completed)
(sleep-for 0.01))
comint-redirect-completed’s value is nil
Documentation:
Non-nil if redirection has completed in the current buffer.
Obviously not a great solution, but I couldn't get anything else working.

&optional BUFFER for other-buffer function does not work?

When I need to switch to another buffer I have a key binding that will create a buffer called "*Buffer List*" from which I select the new buffer.
I need a command to switch between current buffer and the previous one. Except I don't want "*Buffer List*". I looked up function definition for other-buffer:
(other-buffer &optional BUFFER VISIBLE-OK FRAME)
Return most recently selected buffer other than BUFFER...
so I tried using:
(other-buffer "*Buffer List*")
Now if in the new buffer I execute above code with C-x C-e it will echo "*Buffer List*", instead of the initial buffer that I called "*Buffer List*" from. So &optional BUFFER does not seem to work the way I do it. Can anyone explain why?
BUFFER must be a buffer object. To use the buffer name you would need to use:
(other-buffer (get-buffer "*Buffer List*"))
Notice that when you can use a buffer's name as the argument, the documentation tends to name that argument BUFFER-OR-NAME (e.g. see the docstring for get-buffer itself), and to be explicit about the fact in the text.
If you see BUFFER as an argument, it likely requires the actual buffer object (as in this instance).

How can I check if a current buffer exists in Emacs?

I would like to write a function which takes action if a give buffer name already exists. For example:
(if (buffer-exists "my-buffer-name")
; do something
)
Does elisp have a function that will check the for the existence of a buffer similar to how my made up "buffer-exists" function does?
Thanks
From the documentation:
(get-buffer name)
Return the buffer named name (a string).
If there is no live buffer named name, return nil.
name may also be a buffer; if so, the value is that buffer.
(get-buffer-create name)
Return the buffer named name, or create such a buffer and return it.
A new buffer is created if there is no live buffer named name.
If name starts with a space, the new buffer does not keep undo information.
If name is a buffer instead of a string, then it is the value returned.
The value is never nil.
This is what I did:
(when (get-buffer "*scratch*")
(kill-buffer "*scratch*"))
This checks for the buffer scratch. If there's such a thing, kill it.
If not, do nothing at all.
not sure about version this predicate appeared, but now Emacs has buffer-live-p:
buffer-live-p is a built-in function in `buffer.c'.
(buffer-live-p OBJECT)
Return non-nil if OBJECT is a buffer which has not been killed.
Value is nil if OBJECT is not a buffer or if it has been killed.
If you'd like to define your hypothetical function as above, this works:
(defun buffer-exists (bufname) (not (eq nil (get-buffer bufname))))
I use this to automatically close the *scratch* buffer on startup, so I don't have to cycle through it in my list of buffers, as follows:
(defun buffer-exists (bufname) (not (eq nil (get-buffer bufname))))
(if (buffer-exists "*scratch*") (kill-buffer "*scratch*"))