1

I have two frames opened in emacs (one in each monitor, but this is irrelevant). I would like to have a lisp function to switch the buffer in the other frame (in the other monitor), whose focus is in an arbitrary buffer. The buffer I want to switch to in the other frame has a process (say Python) that is already running. When doing this, I want to keep the final focus in the current frame and buffer I ran the lisp function. Only now the other frame will show the buffer with the process. How could I have a lisp function to do that?

Edited: I ended up doing this, but maybe there is a better way

(defun go-to-python-buffer () "Create or visit a Python buffer." (interactive) (if (null (process-live-p (get-process "Python"))) ; (note that this line is different for python b/c get-process return different types in that case) (progn (split-window-sensibly (selected-window)) (other-window 1) (run-python)) (progn (split-window-sensibly (selected-window)) (switch-to-buffer (process-buffer (get-process "Python"))) (other-window -1)) ) ) (defun go-to-python-frame () "Create or visit a Python buffer in another frame." (interactive) ;; check if there is a python process already open, if not, start one (if (not (stringp (get-process "Python"))) ; (note that this line is different for R b/c get-process return different types in that case) (run-python)) (if (= (list-length (frame-list)) 1) ;; if there is just one frame, create another, put the focus, and show the buffer with the python process (progn (switch-to-buffer-other-frame (process-buffer (get-process "Python"))) (other-window-or-frame -1)) (progn ;; if there is another frame already open, show the python buffer, and keep the focus (select-frame (next-frame)) (switch-to-buffer (process-buffer (get-process "Python")) ) (other-window-or-frame -1)))) 
2
  • Does your frames have dedicated names to help us target the right one? E.g., a frame for processes, a frame for code, a frame for email, a frame for calendar, etc. -- (let ((a (make-frame '((name . "TODAY")))) (b (make-frame '((name . "TOMORROW"))))) (message "a: %s | b: %s" a b )) Commented Dec 28, 2016 at 22:11
  • They don't, but we can give them arbitrary names when they are created, as you did. Commented Dec 28, 2016 at 23:36

1 Answer 1

1

Start from emacs -q, switch to the *scratch* buffer, copy and paste the example below to the *scratch* buffer, place the cursor immediately following the last closing parenthesis, and press: C-x C-e (aka eval-last-sexp). Then type M-x my-example

STEP BY STEP:

  • Step #1:  Create or retrieve the process buffer (in this example we use run-python).

[The default behavior when run-python is executed is to display the process buffer in another window on the existing frame. This example does not seek to alter the default behavior -- e.g., we are not deleting windows; we are not seeking to prevent windows from being split.]

  • Step #2:  Make a new frame named MISCELLANEOUS.

  • Step #3:  Make a new frame named PROCESSES.

  • Step #4:  Cycle through all existing frames looking for the frame named PROCESSES.

  • Step #5:  Display the process buffer in the largest window on the frame named PROCESSES.

  • Step #6:  Select the original frame where the user was just before starting this example.

  • Step #7:  Sit for just three (3) seconds and quickly observe what happened.

  • Step #8:  Clean up the example by deleting the frame named MISCELLANEOUS.

  • Step #9:  Clean up the example by deleting the frame named PROCESSES.

  • Step #10:  Display a message thanking the user for trying out this example.

(defun my-example () "Example for @Diogo." (interactive) (let ((python-buffer (progn (require 'python) (or (python-shell-get-buffer) (process-buffer (run-python))))) (original-frame (selected-frame)) (a (make-frame '((name . "MISCELLANEOUS") (height . 20) (width . 80) (top . 0) (left . 625)))) (b (make-frame '((name . "PROCESSES") (height . 20) (width . 80) (top . 400) (left . 625)))) (frame-list (frame-list))) (catch 'break (mapc (lambda (frame) (let ((frame-name (cdr (assq 'name (frame-parameters frame))))) (when (and python-buffer (equal frame-name "PROCESSES")) (throw 'break (progn (with-selected-frame frame (unless (get-buffer-window python-buffer) (set-window-buffer (get-largest-window) python-buffer)))))))) frame-list) ;; Just in case there was an error above, throw a break. (throw 'break nil)) (select-frame original-frame 'norecord) (raise-frame original-frame) (sit-for 3) (delete-frame a) (delete-frame b) (message "Thank you for testing this example."))) 
2
  • it works, but the other frame closes, and if there is a second frame already open, it does not use it. I ended up doing something in those lines that I posted in the edited question. Commented Dec 29, 2016 at 23:17
  • I've added a 10-step analysis to explain what this example does. If you need additional assistance, please let me know. Commented Dec 29, 2016 at 23:56

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.