I want to copy text from one buffer to another. With point in the source buffer, I want to insert text in the target buffer. In the target, the text should insert at point, a new line be opened, and the point should move to the beginning of the new line. When I later switch to the target buffer, the point should be at the start of the new line.
I'm able to do all that except the last bit; when I eventually switch to the target buffer, the point is still on the first line, rather than on the newline.
Here's a reduced example. Open two buffers, a *scratch*
buffer (target) and something else (source). When I run the following in the source buffer,
(with-current-buffer "*scratch*"
(insert "first")
(end-of-line)
(newline-and-indent))
(with-current-buffer "*scratch*"
(insert "second")
(end-of-line)
(newline-and-indent))
(with-current-buffer "*scratch*"
(insert "third")
(end-of-line)
(newline-and-indent))
I expect point to be here when I switch to *scratch*
(target),
first
second
third
| <-- point
Instead, I get,
|first
second
third
When I execute insert
, end-of-line
and newline-and-indent
with M-:
, the behavior is as expected. Why does it work as expected with eval-expression
but not when run programmatically?
Because there is (legitimate) concern of an X-Y problem, here's everything I'm working with. The problem, so far as I can tell, is in the with-current-buffer
section, as demonstrated above. Maybe there's another way to insert text and step?
(defvar my-on-demand-window nil
"Target on-demand window.
An on-demand window is one which you wish to return to within the
current Emacs session but whose importance doesn't warrant a
permanent binding.")
(defun my-set-on-demand-window ()
"Set the value of the on-demand window to current window."
(interactive)
(setq my-on-demand-window (selected-window))
(message "Set on-demand window to: %s" my-on-demand-window))
(defun my-send-line-or-region (&optional beg end buff)
"Send region defined by BEG and END to BUFF.
Use current region if BEG and END not provided. If no region
provided, send entire line. Default BUFF is the buffer displayed
in `my-on-demand-window'."
(interactive (if (use-region-p)
(list (region-beginning) (region-end) nil)
(list nil nil nil)))
(let* ((beg (or beg (if (use-region-p) (region-beginning)) nil))
(end (or end (if (use-region-p) (region-end)) nil))
(substr (or (and beg end (buffer-substring-no-properties beg end))
(buffer-substring-no-properties (line-beginning-position) (line-end-position))))
(buff (or buff (window-buffer my-on-demand-window))))
(if substr
(with-current-buffer buff
(insert substr)
(end-of-line)
(newline-and-indent))
(error "Invalid selection"))))
I am using GNU Emacs 27.1 (build 1, x86_64-w64-mingw32) of 2020-08-21
.