저의 윈도우 개발환경

주의 이 글은 저에 대한 내용을 담고 있으며, 별로 영양가가 없는 글입니다.

저는 데스크탑에서 개발만 하는 것이 아니라 게임도 하고 다른 온갖 작업들을 하기 때문에, 어쩔 수 없이 윈도우를 사용합니다. 하지만 개발자들 사이에서 종종 윈도우는 개발하기 어려운 플랫폼이라던가 개발자가 맥을 많이 쓰는 데에는 이유가 있다던가와 같은 말이 들려옵니다.

사실, 완전히 틀린 말은 아닌게 *nix 계열의 서버를 사용하는 것이 대부분이고 윈도우는 어떻게 보나 *nix와는 거리가 있어보입니다. 이 글에서는 제가 그러한 윈도우에서 어떻게 개발을 하고 있는지에 대해 잠시 서술해보려고 합니다.

커맨드라인 인터페이스

Cmder + clink + MSYS
Alacritty + MSYS (zsh)

명령어

우선, 윈도우는 사용하는 명령어부터가 *nix 계열과는 다릅니다. 예를 들어, 주로 사용하는 cp나 ls 같은 명령조차 윈도우에서는 실행되지 않습니다.

왜 WSL을 안 쓰시나요?

보통, 이에 대한 해결책으로 WSL을 많이 사용합니다. 그러나 저는 WSL을 주로 사용하지 않으며, 이 이유는 이는 말 그대로 WSL은 "서브시스템" 이고 윈도우와 긴밀하게 연계되어있지 않다는 느낌을 받았다는 것입니다. 예를 들어, WSL2에 들어가면서 어느정도 해결하려 하는 것으로 알지만 파일시스템은 여전히 NTFS이기 때문에 꼬이는 부분이 있고 리눅스의 파일들을 윈도우에서 수정하기도 까다롭거나 하는 등의 문제가 있습니다. 또한, 제가 WSL을 통해 실행시키지 않은 프로그램에서 보았을 때는 윈도우 그대로이기 때문에 명령어의 실행이 불가능한 점도 있습니다.

왜 MSYS를 쓰시나요?

WSL 이전에는 시그윈을 이에 대한 해결책으로 많이 사용하곤 하였으나, 저는 그냥 가장 간단한 MSYS를 사용합니다. 참고로 MSYS는 Cygwin의 포크인데, cygwin의 dll 없이도 작동하게 한다는 것 같습니다만 저도 자세한 사항은 잘 모릅니다.

아무튼 MSYS는 단순히 윈도우를 위해 미니멀(M)한 시스템(SYS)를 제공해주는 것인데, 단순히 말하자면 컴퓨터에 ls.exe, bash.exe같은 게 있어서 ls 명령을 실행했을 때 제대로 동작하는 것과 같습니다. MSYS를 사용함에 있어서의 이점은 WSL과 비교했을 때 새 시스템을 얹어서 무거워지는 것을 방지하고, 윈도우 시스템을 그대로 가져갈 수 있다는 것입니다.

MSYS가 정답인가요?

물론 단점도 있습니다. 아까 전의 설명의 정반대인, 윈도우에 적절히 리눅스 명령어를 섞어 쓰는 것이 아니라 완전한 POSIX 환경이 필요하시다면 MSYS를 사용하시면 안됩니다. 굳이 완전한 POSIX 환경까진 아니더라도, 예를 들어 같은 이름을 가진 윈도우 명령이 있을 때에는 윈도우 명령이 우선적용되어서 alias를 따로 지정해줘야하는 등의 소소한 문제 또한 있습니다.

그리고 파일이 많아질 경우에 ls 명령어는 굉장히 느려집니다. 그거 뿐만 아니라 무거워지는 것을 방지한다는 이전의 설명과는 다르게 MSYS는 꽤나 느립니다. 저도 왜 느린지에 대해 조사해본 결과, fork() 를 윈도우에서 구현하기 위해 굉장히 많은 일을 해서 느리다는 설이 있는 것 같습니다. 저도 이유에 대해서는 확실히 모르겠습니다.

하지만 저와 같은 경우 윈도우에서 적당히 리눅스 명령어를 사용할 수 있는 정도로만 필요했고, 이런 니즈를 MSYS가 잘 충족시켜 주었기에 MSYS를 사용합니다.

라인 에디팅

윈도우에서는 주요 명령어만 안 되는 것이 아니라, 제 서버에서 습관처럼 사용하는 reverse-i-search 와 같은 라인 에디팅도 당연히 지원되지 않습니다.

라인 에디팅과 같은 기능을 위해서는 저는 Clink를 사용하는데, 이것은 그저 cmder에서 기본으로 줘서 쓰다보니까 쓸만하네 하고 쓰는 것이지 다른 분들은 bash를 쓰시는게 더 좋을 수도 있을 것 같습니다. 특히, bash의 문법은 cmd의 문법과는 꽤 많이 다르기 때문에 bash가 더 나을 것 같습니다. bash를 추천드립니다.

하지만 Clink로도 많은 작업들이 되기 때문에 저는 우선 현재는 Clink를 사용하고 있습니다. lua 확장 또한 지원하기 때문에, 파워라인처럼 깔끔한 상황표시가 필요했던 저는 이를 만들어서 사용하는 것도 가능했습니다.

+ 20.12.30 추가
현재는 MSYS에 포함되어 나오는 zsh를 사용하고 있습니다. 하지만 MSYS에 포함된 bash / zsh는 clink와는 달리 *.cmd나 *.bat을 실행하기 위해 확장자가 필요하다거나, 그 외에도 윈도우와는 소소하게 다른 사항들이 많아서 하위 호환성을 중요하게 여기시는 분들에게는 아직 clink가 유효한 답안이라고 생각합니다.

+ 21.01.21 추가
주의할 점은, zsh-async 가 윈도우에서는 제대로 작동하지 않아 (Cygwin 코드나 zpty 코드 등을 찾아보면서 디버깅을 시도해봤지만 어째선지 제대로 작동하지 않았습니다.) 윈도우를 지원하면서도 비동기가 되는 테마가 별로 없었습니다. 현재 Agkozak 이라는 테마를 찾아 agkozak-nenwflavoured 로 커스터마이징을 해둔 상태입니다.

하지만, 아무리 비동기로 돌아가는 쉘 테마에 빠르기로 유명한 Zinit을 쓰고 하더라도 MSYS로 하는 zsh 실행 자체가 너무 느렸습니다. 이런 이유로 다시 Clink로 돌아간 상태입니다.

터미널

터미널과 같은 경우에는 무엇을 사용할지 굉장히 많이 고민한 부분이기도 하였습니다. 우선 가장 유명한 Hyper 터미널이나 Terminus alpha 등 여러가지를 써보고 그 중에서 차선책으로 Cmder를 사용하고 있습니다.

우선 다른 터미널을 사용하지 않은 이유는 순전히 속도와 UX 때문입니다. Hyper와 Terminus alpha, FluentTerminal과 같은 경우 시작속도가 너무 느려 사용하기 힘들었고, 깃 배시는 기능이 너무 적었습니다.

마이크로소프트의 터미널이 cmder의 대안으로 가장 적합했던 거 같았지만 아직 사용해보지 않았으며 곧 사용해보려고 합니다.

Cmder(ConEmu)의 장점은 우선 빠르고, 설정이 풍부하고, 무난히 잘 돌아간다는 점입니다. 특히 CJK 폰트 지정이나 다른 데에 있던 잔 버그들이 Cmder를 쓸 때는 없었습니다. 그리고 기능이 매우 다양해서 다른 돌아가는 프로세스에 붙인다던가 하는 기능도 지원을 합니다.

Cmder(ConEmu)의 단점은 일단 디자인이 구리고, 너무 오래되어서 Fluent한 투명같은 기능들의 구현이 힘들다고 제작자가 쐐기를 박은 점 등입니다. 그것 말고도 다른 터미널 에뮬레이터와 비교했을 때 매우 빠르고 버그도 거의 없지만, node의 자동완성이나 스크롤이 느려지는 버그 같은 건 있습니다.

+20.12.30 추가
현재에는 Alacritty 라고 하는 터미널을 실험적으로 사용해보는 중에 있습니다. 이 터미널은 러스트 기반에 OpenGL을 통해 돌아가는 물건인데 Cmder보다도 빠르게 구동되는 것이 매력적입니다. 뭐 여전히 Fluent한 투명도 같은 건 지원하지 않지만, 그래도 사용하며 버그를 굉장히 못 느꼈고 만족스럽게 사용할 만한 터미널 같습니다. 무엇보다도 멀티플랫폼 지원이라 리눅스 환경에서도 같은 터미널 에뮬레이터를 사용할 수 있습니다. 대신에 기능을 최대한 절제하는 건지 아직 미구현된 건지는 모르겠지만, 가장 중요한 Fallback Font와 같은 기능들이 없으며 탭과 같은 기능조차도 tmux 등을 대신해서 사용해야 합니다.

물론, MSYS의 tmux는 mintty 외의 터미널 에뮬레이터에서 거의 동작하지 않습니다. 이 문제는 mintty외에는 pseudo-terminal이 생성되지 않아 /dev/pty* 대신에 /dev/cons* 가 현재 터미널로 인식되는데, 해당 파일은 윈도우의 한계로 현재 콘솔 세션 프로세스가 아닌 이상 접근이 되지 않아서입니다. 해당 문제를 해결하기 위해 util-linuxscript.c 파일을 보며 alacritty가 켜질 때 새로운 pseudo-terminal을 만들어 그 위에서 쉘을 실행시키는 프로그램을 만들어보는 중입니다.

+ 21.01.21 추가
Alacritty를 최대한 써보려고 시도했지만, 우선 터미널 자체가 쓰면 쓸 수록 버그가 보였습니다. 특히 복잡한 레이아웃일 수록 레이아웃 전체가 깨지는 일도 많고 해서 어쩔 수 없이 다시 Cmder로 돌아갔습니다.

그리고 무엇보다도, 스크롤바 지원이 없습니다. (!)

Alias

Alias는 다음과 같이 설정해서 사용중입니다.

aliasedit="C:\Program Files (x86)\Notepad++\notepad++.exe" "%CMDER_ROOT%\config\user_aliases.cmd"
clear=cls
e.=explorer .
find="C:\Program Files\Git\usr\bin\find.exe" $*
gl=git log --oneline --all --graph --decorate  $*
history=less +G "%CMDER_ROOT%\config\.history"
historygrep=cat "%CMDER_ROOT%\config\.history" | grep $*
ll=ls -a -l --color $*
ls=ls --show-control-chars -F --color $*
npp="C:\Program Files (x86)\Notepad++\notepad++.exe" $1
pwd=cd $*
su=cmd /k "%ConEmuDir%\..\init.bat" -new_console:a:.
sudo=sudo cmd /c $*
vi=vim $*

다음은 서버에 접속하는 용도로 사용되는 alias 입니다.

(서버 이름)=putty.exe -new_console -load "(서버 이름)"
(서버 이름)pull=scp -i "(개인 키 경로)" $3 -P (포트) (유저명)@(주소):$1 $2
(서버 이름)push=scp -i "(개인 키 경로)" $3 -P (포트) $1 (유저명)@(주소):$2

PuTTY 를 이용해 접속하게 alias를 설정해뒀는데, 큰 이유는 없고 ssh보다 터미널 관련 버그를 적게 만날 수 있어서입니다. (ex: tmux에서 레이아웃이 깨짐)

최근에는 ssh 명령어로도 많이 사용하고 있습니다.

(서버 이름)=ssh (이름)@(주소) -o ProxyCommand="C:/Windows/system32/openssh/ssh.exe -W %h:%p (이름)@(프록시 주소) -p (프록시 포트)"

다음과 같이 프록시 서버를 통해서 접속하는 용도로 많이 사용합니다. PuTTY 자체도 지원하지만 ssh로 alias를 잡아두면 -new_console 플래그 (Cmder 예약)를 붙이지 않아도 되어 새 탭을 열리지 않아 사용합니다.

참고로 윈도우의 ssh가 PuTTY보다 버그가 많긴 합니다. 특히 vim이나 tmux 같은 TUI의 레이아웃이 깨지기 쉽상입니다. 그래도 일단은 쓸만은 하다고 생각합니다.

텍스트 에디터

Jetbrains 사의 IDE, Atom Editor, 또는 Notepad++

우선 텍스트 에디터가 필요한 상황은 그 때 그 때 다릅니다. 사소한 설정 파일 하나를 빠르게 편집하는 상황, IDE와 같은 강력한 기능이 필요한 상황, 텍스트 에디팅만 필요하지만 프로젝트에서 작업하는 상황 등이 있습니다.

뭐 서버에서야 vim을 사용하지만, 저는 GUI 편집기를 조금 더 선호하기 때문에 많은 에디터 중 하나를 선택해야만 했습니다.

우선 IDE를 고르는 건 쉬웠습니다. 옛날에는 이클립스를 주로 사용했으나 젯브레인즈의 IDE를 써본 후에 젯브레인즈 사가 IDE를 굉장히 잘 만든다는 사실을 깨닫고 주로 러스트나 C++, 자바, C# 등을 편집하는데 Clion이나 Rider, IDEA 등을 사용합니다. phpStorm 또한 예전에는 많이 사용하였지만 요즘엔 php를 주로 다루지 않기 때문에 사용하지 않고 있습니다.

사소한 설정 파일 편집과 같은 것은 폴더를 열지 않았으면 좋겠고 매우 빠르게 열리는 에디터를 원했습니다. 예전에 (중학생 시절에) 잠깐 서브라임 에디터를 사용하기도 했었는데 저장할 때 결제에 대해 물어보는 건 원치 않아서 초등학교 시절부터 꾸준히 Notepad++를 사용하고 있습니다.

그리고 그 외의 경우에는 저는 거의 대부분의 프로젝트를 하면서 아톰 에디터를 사용하고, 주변으로부터 질문도 많이 받았습니다.

왜 VSCode 대신에 아톰을 쓰시나요?

와 같은 질문을 말이죠. 이유는 간단히 한마디로 말해서 Legacy 적인 이유입니다. 저에게 누군가 에디터로 뭘 쓰냐고 묻는다면 전 과감히 VSCode를 쓰라고 할 것입니다.

우선 제가 주로 자바나 php개발을 하면서 eclipse를 사용하다가, 중학교 때 node.js 개발을 처음 시작하면서 텍스트 에디터를 하나 정해서 써야겠다고 정했습니다. 그 당시에는 한창 신뢰의 깃허브에서 Atom을 내놔서 너도 나도 사용할 시기였고 저도 Atom 외에는 선택지가 별로 없어보여 Atom을 사용하기 시작했습니다.

그리고 얼마 있다가 VSCode가 나왔는데 Atom Shell (현 일렉트론)을 가지고 개발을 시작했다고 하고 별로 좋아하지도 않는 마이크로소프트에서 만드는 거고, 아톰을 놔두고 굳이 왜 개발을 하지 싶은 생각도 많이 들었기 때문에 VSCode는 곧 망할 것이라고 생각했습니다. 물론, 제 생각은 완전히 빗나갔고 Atom은 그저 Electron을 만들었다는 의의만을 가진 채 점점 인기가 줄어가는 상황입니다.

서론이 길었네요. Atom에서 VSCode로 사람들이 넘어가기 시작한 가장 큰 이유는 느려서라고 다들 말하더라고요. 하지만 저는 VSCode로 쉽사리 넘어갈 수가 없었습니다.

가장 큰 이유는, 에디터 커스터마이징 때문입니다. 저는 아톰을 사용하면서 불편한 점이 하나 있을 때마다 전체 에디터 CSS나 이런것에 손을 대었으며, 제가 원하지만 없는 플러그인이 있을 때마다 만들어서 썼습니다. 물론, atom-discord 와 같은 플러그인은 제가 만든 후에 다른 분들로부터 VSCode용으로 따로 만들어도 되냐고 허락을 구하는 이메일이 날라오기도 했었고, 실제로 VSCode용으로도 구현이 되었습니다. atom-live2d 도 최근에 찾아보니 VSCode용이 생긴 것 같더라고요.

하지만 그 외에 제가 사용하는 수십개의 플러그인 중에 대체하기 어려운 플러그인도 많고 에디터 커마를 워낙 오랜 시간에 걸쳐서 해왔기 때문에 이걸 다시 VSCode용으로 옮기는 작업은 쉽지 않았습니다. 2번 정도 시도를 해보았지만 불편하여 버틸 수 없었습니다.

우선, 아톰이 일반적인 상황에서 그리 느린 것도 아닐 뿐더러 제가 작업하는데 필요한 대부분의 것이 이미 완벽하게 맞춰져있기 때문에 굳이 VSCode로 옮길 이유를 찾지 못했습니다.

아무튼 Atom이 느린 것도 확실하고 저무는 해인 것도 확실하기 때문에 지인이 에디터를 물어볼 때는 항상 VSCode를 추천했습니다.