Switch Emacs Frames Quickly
Quick answer: Function other-frame is bound to C-x 5 o. But I'm not talking about it.
I don't like to lose focus on my keyboard when I write code. I'm not effective enough to work well while switching between keyboard and mouse.
So I try not to use mouse if possible, not because I hate mice but I can write code easier with keyboard. Someone may prefer coding without keyboard though. (But does anybody watched the video about writing perl code with voice recognition system?)
Anyway, I open about 6 emacs frames–which are windows of X– on a single GNOME workspace. And it's very hard to switch between frames with Alt-Tab skill. I'm not skillful enough with Alt-Tab. I don't know how many Tabs with Alt pressed do I need to switch to my intended frame. I saw someone opens more than 10 frames at a time.
I searched on the net and found Joseph Perla's solution. His solution was very interesting, but I'd rather not change code whenever I move window.
I thought it would be great if I can switch to the frame on some direction. I could research X Window system more, but I chose ELisp rather than that, because all of windows on the screen was Emacs and I enjoyed learning ELisp.
Well, this is ELisp code to do that. I bound super-left key to switch to the nearest frame on the left of current frame, and so on.
ELisp Code
You can copy and paste the following code and save to your ELisp place.
;; directed-switch-to-frame.el -- Switching to frames with direction.
;; Author: Jaehyun Yeom
;; Keywords: frame, direction
;; Move 4 direction to switch emacs frames.
(defun cartesian-to-polar (cartesian)
"Convert cartesian coordinate to polar coordinate."
(let ((x (float (car cartesian))) (y (float (cdr cartesian))))
(cons
(sqrt (+ (* x x) (* y y)))
(cond ((and (= x 0) (> y 0)) (* pi 0.5))
((and (= x 0) (< y 0)) (* pi 1.5))
((< x 0) (+ (atan (/ y x)) pi))
((and (> x 0) (< y 0)) (+ (atan (/ y x)) (* pi 2)))
((> x 0) (atan (/ y x)))
(t nil)))))
(defun switch-to-frame-with-direction (dir-in-deg var-in-deg next)
"Switch to frame with direction with variation."
(let ((f (sort (delq nil
(let ((list-of-frames (mapcar (lambda (each-frame)
(cons each-frame
(cons (+ (frame-parameter each-frame 'left)
(/ (frame-pixel-width each-frame) 2))
(+ (frame-parameter each-frame 'top)
(/ (frame-pixel-height each-frame) 2)))))
(cons (selected-frame)
(delete-if (lambda (item)
(or (eq (selected-frame) item)
(eq nil (frame-parameter item 'window-id))))
(visible-frame-list)))))
(dir-in-rad (degrees-to-radians (mod dir-in-deg 360)))
(var-in-rad (degrees-to-radians (mod var-in-deg 360))))
(mapcar
(lambda (each-frame)
(let ((polar (cartesian-to-polar (cons (- (cadr each-frame) (cadr (car list-of-frames)))
(- (cddr each-frame) (cddr (car list-of-frames)))))))
(when (or (not (numberp (cdr polar)))
(< (- (* 2 pi) (abs (- (cdr polar) dir-in-rad))) var-in-rad)
(< (abs (- (cdr polar) dir-in-rad)) var-in-rad))
(cons (car each-frame) polar))))
(cdr list-of-frames))))
(lambda (a b)
(or (not (numberp (cddr b)))
(and (numberp (cddr a))
(< (cadr a) (cadr b))))))))
(cond ((not f) nil)
((cddar f) (x-focus-frame (caar f)))
(t (while (not (memq (selected-frame) (mapcar 'car f)))
(other-frame next))))))
(defun switch-to-right-frame ()
(interactive)
(switch-to-frame-with-direction 0 60 -1))
(defun switch-to-down-frame ()
(interactive)
(switch-to-frame-with-direction 90 60 -1))
(defun switch-to-left-frame ()
(interactive)
(switch-to-frame-with-direction 180 60 1))
(defun switch-to-up-frame ()
(interactive)
(switch-to-frame-with-direction 270 60 1))
(provide 'directed-switch-to-frame)
Sorry, I'm not good at writing ELisp code yet.
Key binding
I put the following code to my .emacs file.
;; Moving between frames (when (load "directed-switch-to-frame") (global-set-key [s-left] 'switch-to-left-frame) (global-set-key [s-right] 'switch-to-right-frame) (global-set-key [s-up] 'switch-to-up-frame) (global-set-key [s-down] 'switch-to-down-frame))
Enjoy
Restart emacs and open multiple frames with C-x 5 2. Usually super key is bound to the Windows key. So try Win-Left, Win-Up, Win-Right, Win-Down. Does it work?
It doesn't move to windows other than Emacs. And it doesn't move to Emacs frame of other emacs instances.
If center coordinate of frames are same, focus cycles if there are no other frames on that direction. This is useful if you opened multiple full screen frames. You can switch more quickly than Alt-Tab. Opposite direction will cycle opposite direction.
0 개의 덧글:
Post a Comment