이맥스 프레임 빨리 바꾸기
빠른 답변: other-frame 함수가 C-x 5 o로 바인딩되어 있습니다만, 그것에 대하여 얘기하고자 하는 것은 아닙니다.
저는 코드 작성할 때 키보드에서 다른 곳으로 집중을 빼앗기는 것을 싫어합니다. 전, 키보드와 마우스를 넘나들면서도 남들보다 빨리 코딩할 자신이 없습니다.
그래서 될 수 있으면 마우스를 안 쓰려고 하는데, 그건 쥐들이 싫어서 그런 것이 아니라 키보드로 코드 쓰는 것이 제일 편하기 때문입니다. 키보드 없이 코딩하는 것을 좋아하시는 분이 있을지도 모르겠습니다. (그치만, 음성 인식 시스템으로 펄 코딩하는 비디오 보셨나요?)
어쨌든 저는 그놈 작업 공간 하나에 이맥스 프레임을 6개 올려 놓고 사용합니다. 이맥스 프레임이라는 것이 X 상에서는 창이지요. 그리고 알트 탭 신공으로는 창 바꾸기가 너무 힘듭니다. 전 알트 탭 신공에 능하지 않아서 알트를 누르고 있으면서 탭을 몇 번 눌러야 제가 원하는 창으로 갈 수 있는지를 모릅니다. 어떤 분은 한번에 10개 이상 창을 띄워 놓고 작업하시더라구요.
웹에 찾아보니까 Joseph Perla라는 분의 방법을 이용할 수 있겠더라구요. 아주 재미있는 방법인데, 제가 창을 옮길 때마다 코드를 수정하고 싶지는 않더라구요.
특정 방향에 있는 프레임으로 옮기면 정말 좋을 것 같다고 생각했죠. X 윈도 시스템을 좀 더 파 볼까 생각했지만, 어차피 화면에 놓여 있는 창들은 모두 이맥스 프레임인데, ELisp으로 짜는 것이 더 낫고, 더 재미있겠다고 생각했습니다.
그걸 하기 위한 이맥스 코드를 작성했습니다. 슈퍼키+왼쪽 화살표로 왼쪽에 있는 가장 가까운 이맥스 프레임(창)으로 이동합니다. 다른 화살표도 마찬가지.
ELisp 코드
아래 코드를 복사해서 붙인 다음 ELisp 코드를 두는 곳에 저장하세요.
;; directed-switch-to-frame.el -- Switching to frames with direction.
;; 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)
죄송합니다만, 아직 ELisp 코드를 잘 짜는 것은 아닙니다.
키 바인딩
다음 코드를 이맥스 설정 파일인 .emacs에 넣습니다.
;; 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))
되는지 해 볼까요?
이맥스를 새로 시작하고 C-x 5 2를 눌러서 프레임을 여러 개 만듭니다. 보통 슈퍼키는 윈도키로 바인딩 되어 있으므로 윈도키를 누른 상태에서 방향키를 눌러보세요. 잘 되나요?
이맥스 창으로만 움직일 수 있습니다. 그리고 다른 이맥스 인스턴스의 프레임으로는 이동할 수 없습니다.
만약에 프레임의 중심 좌표가 정확하게 겹친 상태에서 프레임이 없는 방향으로 이동하라고 한다면 겹쳐진 창을 순환시킬 수 있습니다. 전체 화면 프레임들을 여러 개 겹쳐 놓고 작업하는 상황에서 유용하게 쓸 수 있습니다. 알트 탭을 누르는 것보다 더 빨리 움직일 수 있습니다. 반대쪽 방향을 누르면 반대로 순환합니다.
댓글 없음:
댓글 쓰기