1 minute read

Doom Emacs macos 모듈이 지원하는 macOS 파인더(finder)로 열기를 편하게 쓰고 있다. Windows에서 탐색기로 열어주는 함수가 없어서 macos 모듈을 참고해서 간단히 만들었다.

탐색기로 파일을 열기

현재 파일을 탐색기로 여는 +windows/reveal-in-explorer 함수와 프로젝트 루트를 탐색기로 여는 +windows/reveal-project-in-explorer 함수를 추가했다.

(defun +windows-explorer-with (&optional path)
  (interactive)
  (let* ((path (expand-file-name
                (replace-regexp-in-string
                 "'" "\\'"
                 (or path (if (derived-mode-p 'dired-mode)
                              (dired-get-file-for-visit)
                            (buffer-file-name)))
                 nil t)))
         (path (+windows--remove-trailing-backslash (replace-regexp-in-string "/" "\\\\" path)))
         (select-arg (format "/select,%s" path)))
    (message "Running: explorer.exe %s" select-arg)
    (w32-shell-execute "open" "explorer.exe" select-arg)))

explorer.exe 프로그램을 호출할 때, /select,[path] 인자를 사용했다. 해당 파일을 선택한 상태로 탐색기를 열 수 있다. explorer.exe /select,C:\Windows\System32\D3D12.dll 이런 식으로 호출하면 된다.

공백을 포함하는 경로가 있을 때, " 문자로도 감싸 보고 공백 앞에 \ 문자를 사용해도 제대로 인식하지 않는다. start-process 함수 대신 w32-shell-execute 함수를 사용해서 해결했다.

아래와 같이 +windows 로 시작하는 두 가지 버전의 탐색기로 열기 함수를 추가한다.

(defmacro +windows--explorer-with (id &optional dir)
  `(defun ,(intern (format "+windows/%s" id)) ()
     (interactive)
     (+windows-explorer-with ,dir)))

;;;###autoload (autoload '+windows/reveal-in-explorer "autoload/windows" nil t)
(+windows--explorer-with reveal-in-explorer (buffer-file-name))

;;;###autoload (autoload '+windows/reveal-project-in-explorer "autoload/windows" nil t)
(+windows--explorer-with reveal-project-in-explorer
                         (or (doom-project-root) default-directory))

Windows일 때만 키바인딩을 추가해서 마무리한다.

(when IS-WINDOWS
  (map! :leader
        (:prefix-map ("o" . "open")
         :desc "Reveal in Explorer"           "o" #'+windows/reveal-in-explorer
         :desc "Reveal project in Explorer"   "O" #'+windows/reveal-project-in-explorer)))

SPC o o, SPC o O 로 동작한다. macos 모듈과 같은 키바인딩을 사용한다.

만드는 김에 추가한 cmd, git bash로 열기

하는 김에 cmd와 git bash로도 현재 디렉터리를 여는 함수를 추가해 본다.

(defun +windows-open-with-cmd (&optional dir)
  (interactive)
  (let* ((dir (expand-file-name
               (replace-regexp-in-string
                "'" "\\'"
                (or dir (if (derived-mode-p 'dired-mode)
                            (dired-get-subdir)
                          default-directory))
                nil t))))
    (message "Running: cmd.exe /K cd /d %s" dir)
    (w32-shell-execute "open" "cmd.exe" (concat "/K cd /d" dir))))

(defun +windows-open-with-bash (&optional dir)
  (interactive)
  (let* ((dir (expand-file-name
               (replace-regexp-in-string
                "'" "\\'"
                (or dir (if (derived-mode-p 'dired-mode)
                            (dired-get-subdir)
                          default-directory))
                nil t))))
    (message "Running: git-bash.exe --cd=%s" dir)
    (w32-shell-execute "open" "git-bash.exe" (format "--cd=%s" dir))))

호출하는 프로그램 이름과 인자만 달라질 뿐 비슷하다. 단축키도 할당한다.

(when IS-WINDOWS
  (map! :leader
        (:prefix-map ("o" . "open")
         :desc "Open in git bash"             "i" #'+windows/open-in-bash
         :desc "Open in cmd"                  "I" #'+windows/open-in-cmd)))

macOS와 같은 키에 매핑했다. 그래서 iTerm 프로그램을 사용하지 않지만 SPC o i, SPC o I 키바인딩을 사용한다.

마치며

Windows Explorer에서 Emacs로 열기cmd와 bash에서 Emacs로 열기처럼 Emacs로 여는 건 만들어서 사용하고 있다. 이제 반대로도 가능하게 기능을 추가했다. 많이 사용할 것 같지는 않다. 많이 사용 안 하면 어때? 양쪽으로 전환이 가능하게 만들어 놓으니 뿌듯하다. 이걸로 됐다.

C-x C-s C-x C-c