이맥스에서 미니버퍼를 편하게 열고 닫는 매크로
March 17, 2020
내가 커맨드를 잘못 입력했다고?
find-file
, swipe
, counsel-M-x
. 이맥스를 사용하면서 가장 많이 사용하는 커맨드들이다. 이들의 공통점은 미니버퍼가 열린다는 것인데 정신없이 커맨드를 입력하다보면 미니버퍼를 여는 커맨드가 여러번 눌릴 때가 있다. 이 때 이맥스는 짜증섞인 비프음과 함께 한 줄 짜리 에러 메시지를 띄운다.
우리가 할 수 있는 건 에러 메시지가 자동으로 사라질 때 까지 1초를 기다리거나 눈썹을 찡그린 채 C-g를 눌러 미니버퍼를 닫고 다시 한번 커맨드를 입력하는 것 뿐이다. 즉각적으로 실수를 교정하지 못한다는 것은 상당히 고약한 UX라고 하지 않을 수 없는데, 이맥스를 사용하는 사람에게 1초간 기다리라고 하는 것은 찬장에서 커피를 꺼내 그라인더로 곱게 갈아 커피를 끓이고 다시 자리에 앉을 수 있는 시간 동안 아무 것도 하지 말란 얘기이기 때문이다.
커맨드는 잘못한 게 없다.
그리고 나도 잘못한 게 없다. 잘못이 있다면 두번 눌린 키보드의 제조회사 혹은 내가 모르게 카페인을 많이 넣은 에너지 드링크 회사에게 있을 것이다. 그러나 인류애 적인 마인드를 가지고 상황을 바라본다면 이 실수를 방지하는 것 보다는 실수가 아닌 상황으로 만드는 것이 더 나은 해결책임이 분명하다.
미니버퍼가 열려있을 때 미니버퍼를 여는 커맨드의 동작을 고쳐 오히려 닫히게 해주면 되는 것이다. state는 이미 이맥스가 들고있다. 간단한 매크로를 만들어 보자.
(defun with-safe (command)
"Check whether minibuffer opened, running COMMAND, close seamlessly."
`(lambda (&rest args)
(interactive)
(if (minibuffer-window-active-p (active-minibuffer-window))
(minibuffer-keyboard-quit)
(apply #',command args))))
이 짧은 매크로는 미니 버퍼를 여는 임의의 커맨드를 감싸는 방식으로 사용할 수 있다.
(global-set-key (kbd "C-e") (with-safe 'counsel-M-x))
(global-set-key (kbd "s-F") (with-safe 'counsel-rg))
(global-set-key (kbd "C-b") (with-safe 'counsel-ibuffer))
(global-set-key (kbd "C-n") (with-safe 'counsel-find-file))
(global-set-key (kbd "s-p") (with-safe 'find-file-in-project))
이제 저 사악한 메시지
Command attempted to use minibuffer while in minibuffer
는 우리의 이맥스에서 영원히 사라졌다. 더불어 커피를 끓일 수 있는 시간도 확보했다. 모두가 해피해킹하길 바라며.