๐ชถ smug โ ์์กด์ฑ ์๋ ๋ฏธ๋๋ฉ tmux ์ธ์ ๋งค๋์ (ํ๋ฆฌ์ ์ ์๋ ๋ ์ด์์๊น์ง)
smug๋ Go ๋จ์ผ ๋ฐ์ด๋๋ฆฌ tmux ์ธ์ ๋งค๋์ ๋ค. ์ค์นยท๊ธฐ๋ณธ config๋ถํฐ, tmux ํ์ค ํ๋ฆฌ์ ์ ์๋ ์ปค์คํ ๋ ์ด์์์ layout ๋ฌธ์์ด๋ก ๊ณ ์ ํ๋ ๋ฒ, smug๊ฐ ํ๋ ์ผ๊ณผ ์ ํ๋ ์ผ(freeze๋ tmuxp)๊น์ง ์ค์ ์ ๋ฆฌ.
์ธ์ ๋งค๋์ ๋ฅผ ์ฌ๋ฌ ๊ฐ ๋น๊ตํ ๋์ smug๋ฅผ ๊ณจ๋๋ค๋ฉด, ์ด ๊ธ์ ๊ทธ๋ค์ ์ค์ ์ด๋ค. smug์ ์๋ฆฌ๋ ํ๋ง๋๋ก โ๋ฌด์์กดยท๋ฏธ๋๋ฉโ โ Ruby(tmuxinator)๋ Python(tmuxp) ๋ฐํ์ ์์ด ๋๋ Go ๋จ์ผ ๋ฐ์ด๋๋ฆฌ๋ค. YAML๋ก ์ธ์ ยท์๋์ฐยทํจ๋์ ์ ์ธํ๋ฉด ๊ทธ๋๋ก ๋์ ์ค๋ค.
์ธ์ ๋งค๋์ 3์ข (smugยทtmuxpยทtmuxinator)์ ๋น๊ตยท์ ํ๊ณผ, ์ด ๋๊ตฌ๋ค์ด ๋ด๋ถ์์ ๋ถ๋ฅด๋ tmux ๋ช ๋ น์ ์ ธ ํด๋ถ๋ tmux ์ธ์ ๋ถํธ์คํธ๋ฉ ๊ธ์ ์๋ค. ์ด ๊ธ์ ๊ทธ์ค smug๋ฅผ ๊ณจ๋๋ค๋ ์ ์ ์์ ์ถ๋ฐํ๋ค. ์ ์ฒด ํ์ต ์์๋ tmux ๋ก๋๋งต 3๋จ๊ณ.
์ค์น
Homebrew ํ ์ค์ด๋ฉด ๋๋๋ค. ๋ฐํ์ ์์กด์ด ์์ด ์๋ฒยท์ปจํ ์ด๋์ ๋ฐ์ด๋๋ฆฌ ํ๋๋ง ๋ณต์ฌํด๋ ๋๋ค.
1
2
brew install smug
# ๋๋: go install github.com/ivaaaan/smug@latest
๊ธฐ๋ณธ โ ์ธ์ ์ YAML๋ก ์ ์ธ
config๋ ~/.config/smug/<์ด๋ฆ>.yml์ ๋๋ค. ํ์ผ ํ๋ = ์ธ์
ํ๋๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
# ~/.config/smug/dev.yml
session: dev
root: ~/projects/app # ๋ชจ๋ ์๋์ฐยทํจ๋์ ์์ ๋๋ ํ ๋ฆฌ
windows:
- name: editor
commands:
- nvim # ์ด ์๋์ฐ์ ์ฒซ ํจ๋์์ ์คํ
- name: server
layout: main-vertical # ์ข 1 + ์ฐ 2 ๋ถํ
panes: # ์๋ฌต์ base ํจ๋ 1๊ฐ + ์๋ 2๊ฐ = ์ด 3ํจ๋
- commands: [npm run dev]
- commands: [npm run test:watch]
1
smug start dev # ์ด ์ธ์
์ ๋์ฐ๊ณ attach. `smug dev`๋ก ์ค์ฌ๋ ๋จ(๊ธฐ๋ณธ ๋ช
๋ น์ด start)
ํต์ฌ ํค๋ง ์ง์ผ๋ฉด:
sessionโ ์ธ์ ์ด๋ฆ.rootโ ์์ ๋๋ ํ ๋ฆฌ(์ธ์ ยท์๋์ฐยทํจ๋๋ณ๋ก ๊ฐ๊ฐ ์ง์ ๊ฐ๋ฅํ๊ณ , ์์ผ๋ฉด ์์ ๊ฒ์ ์์).windowsโ ๊ฐ ์๋์ฐ๋nameยทlayoutยทcommandsยทpanes๋ฅผ ๊ฐ์ง๋ค.panesโ ์ฌ๊ธฐ์ ๊ฐ์ ๊ฐ๊ฐ์ด ์ค์ํ๋ค. ์๋์ฐ๋ ์๋ฌต์ ์ผ๋ก ํจ๋ 1๊ฐ๋ก ์์ํ๊ณ ,panesํญ๋ชฉ ํ๋๋ง๋ค ๋ถํ ์ด ํ๋ ์ถ๊ฐ๋๋ค. ์ฆ ํญ๋ชฉ 2๊ฐ = ์ด 3ํจ๋์ด๋ค.commandsโ ํด๋น ์๋์ฐ/ํจ๋์์ ์์ ์ ์คํํ ๋ช ๋ น.nvimยท๊ฐ๋ฐ ์๋ฒ๋ฅผ ์๋ ๊ธฐ๋ํ๋ ๋ถ๋ถ์ด๋ค.
์ด๋ฏธ ๋ ์๋ ์ธ์
์ด๋ฉด ์๋ก ๋ง๋ค์ง ์๊ณ ๊ทธ๋๋ก attachํ๋ค(์์์ ์คํํ๋ฉด switch-client). ์
ธ ์คํฌ๋ฆฝํธ๋ก ์ง์ ์งค ๋ ์์ผ๋ก ๋ฃ๋ has-session ๋ถ๊ธฐ๊ฐ ๊ธฐ๋ณธ ๋์์ผ๋ก ๋ค์ด ์๋ ์
์ด๋ค.
ํ๋ฆฌ์ ์ ์๋ ๋ ์ด์์ โ layout ๋ฌธ์์ด๋ก ๊ณ ์
layout์๋ tmux ํ์ค ํ๋ฆฌ์
๋ช
(main-verticalยทmain-horizontalยทtiledยทeven-horizontalยทeven-vertical)์ ์ด๋ค. ๊ทธ๋ฐ๋ฐ ์ํ๋ ๋ฐฐ์น๊ฐ ํ๋ฆฌ์
์ ์์ ๋๊ฐ ์๋ค. ์๋ฅผ ๋ค์ด ์๋ ์ข/์ฐ 2๋ถํ , ์๋๋ ์ ์ฒดํญ 1๊ฐ ๊ฐ์ ๋ฐฐ์น:
1
2
3
4
5
โโโโโโโโโฌโโโโโโโโ
โ pane0 โ pane1 โ
โโโโโโโโโดโโโโโโโโค
โ pane2 โ
โโโโโโโโโโโโโโโโโ
์ด๊ฑด main-horizontal(์ 1 + ์๋ N)์ ์ํ ๋ฐ๋๋ผ ์ด๋ค ํ๋ฆฌ์
์ผ๋ก๋ ์ ๋์จ๋ค. ํด๋ฒ์ tmux ๋ ์ด์์ ๋ฌธ์์ด์ layout์ ์ง์ ๋ฃ๋ ๊ฒ์ด๋ค โ smug๋ ์ด ๊ฐ์ tmux select-layout์ ๊ทธ๋๋ก ๋๊ธฐ๋ฏ๋ก, ํ๋ฆฌ์
๋ช
์ด๋ raw ๋ฌธ์์ด์ด๋ ๋ค ๋ฐ๋๋ค.
๋ฌธ์์ด์ ์ํ๋ ๋ฐฐ์น๋ฅผ tmux์์ ํ ๋ฒ ์์ผ๋ก ๋ง๋ ๋ค ๋ฝ์๋ธ๋ค:
1
2
3
4
5
6
7
8
9
10
11
# 1) ์์ tmux์์ ์ํ๋ ๋ฐฐ์น๋ฅผ ๋ง๋ ๋ค (์ค์ ๊ฐ์ญ ์์ด -f /dev/null)
tmux -L cap -f /dev/null new-session -d -x 220 -y 50
tmux -L cap split-window -v # ์/์๋
tmux -L cap select-pane -t 0 # ์ ์ ํ
tmux -L cap split-window -h -t 0 # ์๋ฅผ ์ข/์ฐ๋ก
# 2) ๊ทธ ๋ฐฐ์น์ ๋ ์ด์์ ๋ฌธ์์ด์ ์บก์ฒ
tmux -L cap list-windows -F '#{window_layout}'
# โ 60d1,220x50,0,0[220x25,0,0{110x25,0,0,0,109x25,111,0,2},220x24,0,26,1]
tmux -L cap kill-server # ์์ ์๋ฒ ์ ๋ฆฌ
๋ฝ์ ๋ฌธ์์ด์ ๊ทธ๋๋ก layout์ ๋ฐ๋๋ค:
1
2
3
4
5
6
- name: server
# ์ ์ข/์ฐ 2 + ์๋ ์ ์ฒดํญ 1 (ํ๋ฆฌ์
์ ์์ด ๋ ์ด์์ ๋ฌธ์์ด๋ก ๊ณ ์ )
layout: 60d1,220x50,0,0[220x25,0,0{110x25,0,0,0,109x25,111,0,2},220x24,0,26,1]
panes: # ๋น ํญ๋ชฉ 2๊ฐ = ์ด 3ํจ๋ (๋ฐฐ์น๋ ์ ๋ฌธ์์ด์ด ํ์ )
-
-
๋ ๊ฐ์ง๋ง ์๋ฉด ๋๋ค:
- ๋ฌธ์์ด ์์
220x50์ ์บก์ฒ ๋น์ ํฌ๊ธฐ์ง๋ง,select-layout์ด ์ค์ ํฐ๋ฏธ๋ ํฌ๊ธฐ์ ๋น์จ๋ก ๋ฆฌ์ค์ผ์ผํ๋ฏ๋ก ์ฐฝ ํฌ๊ธฐ๊ฐ ๋ฌ๋ผ๋ ๋ฐฐ์น๋ ์ ์ง๋๋ค. ์ 4์๋ฆฌ(60d1)๋ tmux๊ฐ ๊ณ์ฐํ๋ ์ฒดํฌ์ฌ์ด๋ผ, ์ง์ ํ์ดํํ์ง ๋ง๊ณ ๋ฐ๋์ ์บก์ฒํ ๋ฌธ์์ด์ ํต์งธ๋ก ์จ์ผ ํ๋ค. - ํจ๋ ๊ฐ์๋ง ๋ง์ผ๋ฉด ๋๋ค. ๋ฌธ์์ด์ด 3ํจ๋์ด๋
panes๋น ํญ๋ชฉ 2๊ฐ(= base 1 + 2)๋ก 3ํจ๋์ ๋ง๋ค์ด ๋๋ฉด, ๋ง์ง๋ง์ ๋ฌธ์์ด์ด ๋ฐฐ์น๋ฅผ ํ์ ํ๋ค.
์ด ํธ๋ฆญ์ smug๋ฟ ์๋๋ผ tmuxinatorยทtmuxp์์๋ ๊ทธ๋๋ก ํตํ๋ค โ ์
๋ค layout์ tmux select-layout์ ๋๊ธฐ๊ธฐ ๋๋ฌธ์ด๋ค.
smug๊ฐ ํ๋ ๊ฒ / ์ ํ๋ ๊ฒ
smug์ ๋ฒ์๋ โ์ธ์ ํ๋๋ฅผ ํต์งธ๋ก ์ ์ธ โ ๊ทธ๋๋ก ๋์ฐ๊ธฐโ์ ์๊ฒฐ๋ผ ์๋ค.
ํ๋ค:
- ์ธ์
ยท์๋์ฐยทํจ๋ ์ ์ธ๊ณผ ์์ฑ,
layout(ํ๋ฆฌ์ + ๋ฌธ์์ด) - ํจ๋๋ณ ์์ ๋๋ ํ ๋ฆฌ(
root)์ ์์ ๋ช ๋ น(commands) - ํ
โ
before_start(์ธ์ ์์ฑ ์ ),stop(๋ด๋ฆด ๋) - ํ๊ฒฝ๋ณ์(
env), ์ด๋ฏธ ์์ผ๋ฉด attach, ์ ํ ์คํ(smug start dev -w server๋ก ํน์ ์๋์ฐ๋ง)
์ ํ๋ค (๊ฒฝ๊ณ ๋ฐ):
- freeze โ ์ง๊ธ ๋ ์๋ ์ธ์ ์ ๊ฑฐ๊พธ๋ก config๋ก ์ญ์ถ์ถํ๋ ๊ธฐ๋ฅ์ ์๋ค. smug๋ ์ ์ธํ ๊ฑธ ์คํํ ๋ฟ์ด๋ค.
- ํ๋ก๊ทธ๋๋จธ๋ธ ์ ์ด โ libtmux ๊ฐ์ API๋ ํ์ด์ฌ ์ฝ์์ ์๋ค.
- ๋ค๋ฅธ ๋๊ตฌ config import, ํ๋ฌ๊ทธ์ธ ์์คํ ๋ ์๋ค.
์ด ๊ฒฝ๊ณ ๋ฐ โ ํนํ freeze(์์ผ๋ก ์ง ์ธ์ ์ ํ์ผ๋ก ์ ์ฅ)๋ tmux๋ฅผ ํ์ด์ฌ์ผ๋ก ์คํฌ๋ฆฝํ ํ๊ณ ์ถ์ด์ง๋ฉด โ ๊ทธ๋ tmuxp๋ก ๋์ด๊ฐ๋ฉด ๋๋ค. ๊ธฐ๋ณธ ๋ ์ด์์ YAML์ด ์๋ก ๊ฑฐ์ 1:1์ด๋ผ ์ ํ ๋น์ฉ์ด ์๋ค. ๋ฐ๋๋ก โ์ ํด์ง ๋ ์ด์์์ ๋ฐ๋ณต ๋ก๋โ๊ฐ ์ ๋ถ๋ผ๋ฉด smug์ ์ด ๋ฒ์๊ฐ ์ ํํ ํ์ํ ๋งํผ์ด๋ค โ ๋ชจ์๋ผ์ง๋, ์ ์ฐ๋ ๊ธฐ๋ฅ์ผ๋ก ๋ฌด๊ฒ์ง๋ ์๋ค.
์์ฃผ ์ฐ๋ ๋ช ๋ น
1
2
3
4
5
6
smug start dev # ์ธ์
์์(+attach). `smug dev`๋ก ์ถ์ฝ ๊ฐ๋ฅ
smug start dev -w server # ํน์ ์๋์ฐ๋ง
smug stop dev # ์ธ์
์ข
๋ฃ (stop ํ
์คํ)
smug new dev # ์ config ํ์ผ ์์ฑ ํ ํธ์ง๊ธฐ๋ก ์ด๊ธฐ
smug edit dev # ๊ธฐ์กด config ํธ์ง
smug list # config ๋ชฉ๋ก
์ ๋ฆฌ
smug๋ โ์ธ์ ์ ์ ์ธํ๊ณ ๋์ด๋คโ ํ ๊ฐ์ง๋ฅผ ์์กด์ฑ ์์ด ๊น๋ํ๊ฒ ํ๋ ๋๊ตฌ๋ค. ๋ ์ด์์์ ํ๋ฆฌ์ ์ผ๋ก ๋๋ถ๋ถ ๋๊ณ , ์ ๋๋ ๋ฐฐ์น๋ tmux ๋ ์ด์์ ๋ฌธ์์ด์ ์บก์ฒํด ๋ฐ์ผ๋ฉด ๊ทธ๋ง์ด๋ค. ๋ฑ ๊ทธ ์ฉ๋๋ผ๋ฉด ์ต์ ์ด๊ณ , freeze๋ ํ์ด์ฌ ์ ์ด๊ฐ ํ์ํด์ง๋ ๋ tmuxp๋ก ์ฎ๊ฒจ๋ ๋ฆ์ง ์๋ค.