Plugin UI architecture - minsuk-jang/teamproject GitHub Wiki
๊ตฌํ Vim์ ๊ฑฐ๋ํ ์ฝ๋๋ฒ ์ด์ค์ ๊ธฐ์ฌํ๋ ์์๋ GUI ์ธํฐํ์ด์ค๋ฅผ ์ํ ์์ญ ๊ฐ์ widget toolkit์ ๋ถ๋ช ํ๊ฒ ์ง์ํ๋ค๋ ๊ฒ์ ๋๋ค. Neovim์ ์ธ๋ถ ํด๋ผ์ด์ธํธ์ GUI ๊ตฌํ์ ์์ํจ์ผ๋ก์จ ์ด๋ฅผ ๋ฐฉ์งํฉ๋๋ค. ํด๋ผ์ด์ธํธ๋ Neovim`nvim '์ ์ ์ดํฉ๋๋ค. ํ๋ก์ธ์ค๋ msgpack-rpc API๋ฅผ ํตํด ๋ค์๊ณผ ๊ฐ์ด ํ ์ ์์ต๋๋ค.
- Vim ๋ช ๋ น ์คํ
- Vimscript ํํ์ ํ๊ฐ
- ๋ฒํผ, ์๋์ฐ ๋ฐ ํญ ์กฐ์
- ํธ์ง๊ธฐ ์ด๋ฒคํธ ์์ / ์ฒ๋ฆฌ
๊ฒ๋ค๊ฐ ์๊ฒฉ API๋ ์ฝ๊ฒ ํ์ฅ ํ ์ ์๋๋ก ์ค๊ณ ๋์์ผ๋ฏ๋ก ํญ์ ์๋ก์ด ๊ฐ๋ฅ์ฑ์ด ์กด์ฌํฉ๋๋ค.
**Neovim * remote plugin * (rplugin
)์ nvim
๊ณผ ๋ํํ๋ ํ๋ก๊ทธ๋จ์
๋๋ค.
์๊ฒฉ API ** (์์์ ์ ์ก ๋ฉ์ปค๋์ฆ์ ํตํด ๋๋ฌ ํ ์ ์์ต๋๋ค : TCP ์ฃผ์, ๋ช
๋ช
๋ ํ์ดํ, stdin / stdout ...).
ํ์ด์ฌ REPL๊ณผ client library๋ฅผ ์ฌ์ฉํ์ฌ ๋ํ์์ผ๋ก ํ์ฌ API๋ฅผ ํ ์คํธ ํ ์๋ ์์ง๋ง ํธ์ง๊ธฐ๋ฅผ ํ์ฅํ๋ ๋ฐ๋ ๊ทธ๋ฆฌ ์ ์ฉํ์ง ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ Neovim ํ๋ฌ๊ทธ์ธ์ ๋ค์์ ์์ฌ ์ฝ๋๋ฅผ ์คํํฉ๋๋ค :
while true
handle(next_vim_event())
์๊ฐํด ๋ณด๋ฉด legacy Vim ํ๋ฌ๊ทธ์ธ์ด ํ์ฌ ์ด๋ป๊ฒ ์๋ํ๋๋ ๊ฝค ๋ง์ด ์์ต๋๋ค. ํฅ๋ฏธ์๋ ์ผ์ด ๋ฐ์ํ ๋๋ง๋ค ์๋ ๋ช ๋ น์ ๋ฑ๋กํ์ฌ ์คํํฉ๋๋ค. ์ฐจ์ด์ ์ Neovim์ด ์ด๋ฒคํธ๋ฅผ ๋ค๋ฅธ ํ๋ก์ธ์ค๋ก ์ ํํ๊ณ ๋น๋๊ธฐ ์ ์ผ๋ก ๋ช ๋ น์ ์์ ํ ์ ์๋ค๋ ์ ์ ๋๋ค. ๊ทธ๋ฌ๋ฉด ํ๋ฌ๊ทธ์ธ์ ๋ํ ํฅ๋ฏธ๋ก์ด ๊ฐ๋ฅ์ฑ์ด ์ด๋ฆฝ๋๋ค.
- ๊ทธ๋ค์ ์ด๋ค ํ๋ก๊ทธ๋๋ฐ ์ธ์ด๋ก๋ ์์ฑ ๋ ์ ์์ต๋๋ค.
- ์ด์ ์ฒด์ ์ ๋ ์ ํตํฉ๋๋ ๊ณ ๊ธ ์ธ์ด๋ก ์์ฑ๋ ์ต์ GUI (์ : Windows์ C # / WPF ๋๋ OS X์ Ruby / Cocoa).
- ๋ฒ๊ทธ๊ฐ ์์ด ํธ์ง๊ธฐ(์๋ฒ)๊ฐ ์ถฉ๋ ํ ๊ฐ๋ฅ์ฑ์ด ์ ์ด ๋ณด์ ์ฒ๋ฆฌ๋ฉ๋๋ค.
- ํธ์ง๊ธฐ๋ฅผ ์ฐจ๋จํ์ง ์๊ณ ๋ฐฐ๊ฒฝ ์์ ์ ์ํ ํ ์ ์์ต๋๋ค.
- GUI๋ก ์ง์ ์ฒ๋ฆฌ ํ ์์๋ ** ๋ง์ถค ์ด๋ฒคํธ **๋ฅผ ๋ด๋ณด๋ผ ์ ์์ต๋๋ค. (Sublime์ minimap๊ณผ ๊ฐ์ ๊ณ ๊ธ ๊ธฐ๋ฅ ๊ตฌํ ๊ฐ๋ฅ)
- ์ฌ๋ฌ ์๊ฒฉ GUI๋ฅผ ์ฐ๊ฒฐ / ๋ถ๋ฆฌํ์ฌ ํธ์ง ์ธ์ ์ ๊ณต์ ํ ์ ์์ต๋๋ค.
- headless ํ ์คํธ ๊ฐ์ํ.
- ํธ์ง๊ธฐ๋ฅผ ๋ค๋ฅธ ํ๋ก๊ทธ๋จ์ ํฌํจํ๊ธฐ. ์ฌ์ค, GUI๋ ๋ค๋น๊ฒ์ด์ ์ ๋ด์ฅํ ํ๋ก๊ทธ๋จ์ผ๋ก ๋ณผ ์ ์์ต๋๋ค.
UI ํ๋ก๊ทธ๋จ
UI๋ ์ฌ์ฉ์์ ํธ์ง๊ธฐ ์ฌ์ด์ ๋ค๋ฆฌ ์ญํ ์ ํ๋ ํ๋ฌ๊ทธ์ธ์ ๋๋ค. ๋ค์์ UI ํ๋ก๊ทธ๋จ์ ์์ฌ ์ฝ๋์ ๋๋ค.
while true
handle(next_vim_or_user_event())
์ฌ์ฉ์ ์ด๋ฒคํธ (ํค ๋๋ฆ, ๋ง์ฐ์ค ํด๋ฆญ ๋ฑ)๋ฅผ ์ฒญ์ทจํ๊ณ , ์ด๋ฅผ ์ฐ๊ฒฐ๋ Neovim ์ฅ์น๋ก ๋ณํ ํ ๋ค์ ์ฌ์ฉ์์๊ฒ * ๋ค์ ๊ทธ๋ฆฌ๊ธฐ * ์ด๋ฒคํธ๋ฅผ ๋ฐํํด์ผ ํ๋ค๋ ์ ์ ์ ์ธํ๊ณ ๋ UI๊ฐ ์๋ ํ๋ฌ๊ทธ์ธ๊ณผ ๊ฑฐ์ ๋์ผํฉ๋๋ค.
๋ค์์ ์ํ process tree์ ๋๋ค.
Neovim ------> GUI 1 (attach/detach to running instance)
| |
| `------> GUI 2 (communicating on a different socket or transport
| mechanism, but sharing the same session with GUI 1)
`--> Plugin 1
|
`--> Plugin 2
|
`--> Plugin 3
๋ค์์ nvim
์์ ํ๋ก์ธ์ค์ ๊ฐ์์
๋๋ค :
- ์์ผ ๋๋ TCP ์ฃผ์์์ ์์ ๋๊ธฐ (๋ฌด์ํ์ง ์๋ ํ ๋ฌด์์)
- UI๋
nvim
์ ๋ํ ๋ช ๋ น ํ ์ธ์๋ก ์ง์ ๋ ์ ์์ต๋๋ค.
- UI๋
~ / .config / nvim / init.vim
์ ์ฝ์ผ์ญ์์ค.- ํ๋ฌ๊ทธ์ธ ๋ฐ๊ฒฌ (UI ํฌํจ)
- ์ฒญ์ทจ ์ฃผ์๋ฅผ ์ ๋ฌํ์ฌ UI ํ๋ก๊ทธ๋จ์ ์์ํ์ญ์์ค.
- ๋ชจ๋ ํ๋ฌ๊ทธ์ธ์ผ๋ก ์๋ฐฉํฅ ์์ฌ ์ํต ์ฑ๋์ ์ฝ๋๋ค.
๋ค์์ ๊ฐ์ GUI ๋ถ๋ถ์ ๋๋ค.
gui -> vim: {"id": 1, "method": "initClient",
"params": {"size": {"rows": 20, "columns": 25}}}
vim -> gui: {"id": 1, "result": {"clientId": 1}}
vim -> gui: {"method": "redraw",
"params": {"clientId": 1, "lines": {"5": "Welcome to neovim!"}}}
gui -> vim: {"id": 2, "method": "keyPress",
"params": {"keys": ["H", "e", "l", "l", "o"]}}
vim -> gui: {"method": "redraw",
"params": {"clientId": 1, "lines": {"1": "Hello", "5": ""}}}