이맥스 프레임 빨리 바꾸기
빠른 답변: 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를 눌러서 프레임을 여러 개 만듭니다. 보통 슈퍼키는 윈도키로 바인딩 되어 있으므로 윈도키를 누른 상태에서 방향키를 눌러보세요. 잘 되나요?
이맥스 창으로만 움직일 수 있습니다. 그리고 다른 이맥스 인스턴스의 프레임으로는 이동할 수 없습니다.
만약에 프레임의 중심 좌표가 정확하게 겹친 상태에서 프레임이 없는 방향으로 이동하라고 한다면 겹쳐진 창을 순환시킬 수 있습니다. 전체 화면 프레임들을 여러 개 겹쳐 놓고 작업하는 상황에서 유용하게 쓸 수 있습니다. 알트 탭을 누르는 것보다 더 빨리 움직일 수 있습니다. 반대쪽 방향을 누르면 반대로 순환합니다.