본문으로 건너뛰기

"distro" 태그로 연결된 1개 게시물개의 게시물이 있습니다.

모든 태그 보기

LazyVim 전환기

· 약 9분

이 글은 Neovim 시리즈의 다섯 번째 글입니다.

  1. Neovim 입문: Vim을 넘어서는 첫걸음
  2. Neovim 중급: 생산성을 높이는 기능들
  3. Neovim 고급: 플러그인과 LSP로 IDE처럼 쓰기
  4. 나의 Neovim 설정 전체 공개
  5. LazyVim distro로 갈아타기 ← 현재 글

함께 읽기: LazyVim 키맵 치트시트

들어가며​

플러그인 23개를 직접 큐레이션해서 1년 가까이 굴렸지만, 결국 LazyVim distro로 갈아탔어요. 플러그인 수는 23개에서 42개로 늘었지만 제가 직접 관리해야 하는 파일은 15개에서 5개로 줄었고, 이 비대칭이 distro의 핵심이에요.

수동 Neovim 셋업과 LazyVim의 관리 범위 비교

직전 셋업 공개 글에서 정리했던 lazy.nvim 수동 구성은 잘 동작했습니다. 다만 새 언어 LSP 하나를 붙일 때마다 mason 설정, conform 포매터, nvim-cmp 소스를 손으로 동기화해야 했고, 새 머신에 그대로 옮길 때마다 의존성이 한두 개씩 빠졌습니다. distro는 그 동기화를 일괄로 위임하고, 제 영역은 "취향 차이가 나는 부분"에만 남기는 구조입니다.

이 글은 LazyVim이라는 distro가 무엇이고, 수동 셋업에서 어떤 흐름으로 옮겼고, 어디에 백업을 두고 어떻게 롤백할 수 있는지를 정리합니다.

distro란 무엇인가​

Neovim distro는 lazy.nvim, LSP, treesitter, 자동완성, UI 같은 표준 기반을 한 묶음으로 깔아주고, 사용자는 그 위에 얇게 커스텀만 얹는 셋업 패턴입니다. 직접 lua 파일을 한 줄 한 줄 짜는 대신, 프레임워크가 정해 둔 슬롯에 옵션이나 추가 spec만 끼워 넣으면 됩니다.

distro분위기
LazyVim가장 표준적/미니멀. lazy.nvim 작성자가 직접 운영. 본 글 대상
LunarVim자체 CLI(lvim)를 가진 비교적 무거운 셋업
NvChadUI/테마 중심, 화려한 시작 화면이 특징
AstroNvim대시보드, 아이콘, 통계 정보가 많은 풍성한 셋업

LazyVim을 고른 이유는 단순합니다. 이미 쓰던 lazy.nvim 위에 그대로 얹히고, 빠지더라도 ~/.config/nvim을 통째로 갈아엎지 않아도 되는 구조이기 때문입니다. distro 자체가 lazy 플러그인 하나처럼 동작합니다.

직전 상태​

수동 lazy.nvim으로 플러그인 23개를 구성한 상태였습니다.

자세한 구성은 나의 Neovim 설정 전체 공개 글에 있습니다. 요약하면:

  • init.lua 1줄 → lua/config/에서 globals/options/keymaps 분리 로드
  • lua/plugins/ 아래 플러그인별 파일 15개 (telescope, neo-tree, lsp, cmp, treesitter, conform, kanagawa 등)
  • 자체 작성한 keyMapper 유틸로 noremap=true silent=true 일괄 적용
  • 테마는 Kanagawa Dragon (저채도 다크)

문제는 없었습니다. 단지 새 언어 추가가 매번 작은 의식이었습니다. Go를 붙이려면 mason.nvim에 gopls를 추가하고, conform.nvim에 gofmt를 등록하고, nvim-lspconfig 호출 라인을 늘리고, treesitter parser 목록도 손봐야 했습니다. 그렇게 해 둔 구성을 새 노트북에 옮기면 :checkhealth에 빨간 줄이 한두 개 떴습니다.

LazyVim이 자동으로 가져오는 것​

LazyVim 15.x를 깔면 다음이 한 번에 따라옵니다.

영역들어오는 것
플러그인 매니저lazy.nvim
파일 탐색/검색snacks.picker, snacks.dashboard, snacks.explorer (neo-tree는 editor.neo-tree extra)
키 안내which-key
LSP, 포매터, 린터nvim-lspconfig + mason 자동 설치
자동완성blink.cmp (또는 nvim-cmp 옵션)
구문 파싱nvim-treesitter
Gitgitsigns, lazygit 연동
UIbufferline, lualine, noice, mini.icons
포매팅conform.nvim + format-on-save

여기에 제가 켠 LazyExtras 6종(go, typescript, markdown, json, yaml, python)이 마저 붙습니다. 합치면 42개입니다. 직접 관리할 필요는 없고, 동작을 바꾸고 싶으면 같은 spec을 opts만 덮어씌우는 식으로 가볍게 끼어듭니다.

제가 짠 파일은 5개만 남았습니다. 나머지는 distro 본체가 가져간 책임입니다.

백업과 롤백 안전망​

distro 전환은 비가역 작업이 아니어야 합니다. Neovim의 상태는 네 군데에 흩어져 있어서, 그걸 다 같이 빼두지 않으면 깔끔한 롤백이 어렵습니다.

기존 nvim 상태 4종을 .backup-2026-05-07 suffix로 옮긴 뒤 새 LazyVim을 깔았습니다.

원본백업
~/.config/nvim~/.config/nvim.backup-2026-05-07
~/.local/share/nvim (164MB, 컴파일된 플러그인)~/.local/share/nvim.backup-2026-05-07
~/.local/state/nvim~/.local/state/nvim.backup-2026-05-07
~/.cache/nvim~/.cache/nvim.backup-2026-05-07

문제 생겼을 때 롤백은 4쌍을 역순으로 mv하면 됩니다. 새 LazyVim을 같은 suffix로 옮긴 뒤 백업을 원래 자리로:

DATE=2026-05-07
mv ~/.config/nvim ~/.config/nvim.lazyvim-$DATE
mv ~/.local/share/nvim ~/.local/share/nvim.lazyvim-$DATE
mv ~/.local/state/nvim ~/.local/state/nvim.lazyvim-$DATE
mv ~/.cache/nvim ~/.cache/nvim.lazyvim-$DATE

mv ~/.config/nvim.backup-$DATE ~/.config/nvim
mv ~/.local/share/nvim.backup-$DATE ~/.local/share/nvim
mv ~/.local/state/nvim.backup-$DATE ~/.local/state/nvim
mv ~/.cache/nvim.backup-$DATE ~/.cache/nvim

LazyVim 전환 전 백업과 문제 발생 시 롤백 흐름

이 안전망이 있어야 distro 전환을 부담 없이 시도해볼 수 있습니다.

새 디렉토리 구조​

~/.config/nvim/
├── init.lua # LazyVim 부트스트랩 (starter 그대로)
├── lua/
│ ├── config/
│ │ ├── options.lua # 사용자 추가: scrolloff=10
│ │ ├── keymaps.lua # 사용자 추가: <leader>h, <C-;>
│ │ ├── autocmds.lua # 사용자 추가: 마크다운 wrap/linebreak/spell=false 등
│ │ └── lazy.lua # LazyVim 부트스트랩 (수정 X)
│ └── plugins/
│ ├── colorscheme.lua # 신규: Solarized + Everforest + Gruvbox Material
│ ├── markdown.lua # 신규: render-markdown.nvim 옵션 강화
│ ├── ufo.lua # 신규: nvim-ufo (LSP 폴딩)
│ ├── floaterm.lua # 신규: vim-floaterm + <C-;>
│ ├── lang-extras.lua # 신규: LazyExtras 6종 일괄 import
│ └── example.lua # starter 동봉 예제 (`if true then return {} end`로 비활성)
├── lazyvim.json # LazyVim 자동 생성
├── lazy-lock.json # lazy.nvim이 잠금 관리
└── stylua.toml # starter 동봉 (lua 포매터 설정)

config/는 LazyVim의 starter 템플릿이 깔아준 그대로입니다. 사용자 영역은 plugins/ 아래 5개 파일과 config/의 keymaps/options/autocmds 추가분이며, 그게 전부입니다.

커스텀 5개 플러그인 파일​

distro가 가져가지 않은 "제 취향"은 다섯 갈래로 정리됐습니다.

lua/plugins/colorscheme.lua​

테마 후보 3종을 동시에 등록했습니다.

직전엔 Kanagawa Dragon 단일 테마였는데, 마크다운 작성 비중이 늘면서 헤딩 위계와 코드블록 배경이 더 또렷한 테마가 필요해졌습니다. 즉시 비교를 위해 셋을 같이 등록했습니다.

  • maxmx03/solarized.nvim (variant=winter) — 기본
  • neanias/everforest-nvim (background=soft)
  • sainnhe/gruvbox-material (background=medium)

런타임에 :colorscheme everforest처럼 즉시 갈아끼울 수 있고, 영구화는 LazyVim 기본 colorscheme 라인을 바꾸면 됩니다. UI에서 라이브 프리뷰로 고르고 싶으면 <Space>uC.

lua/plugins/markdown.lua​

render-markdown.nvim 옵션을 강화했습니다.

LazyExtras lang.markdown이 이미 render-markdown.nvim의 spec을 등록합니다. 거기에 opts만 덮어씌워 가독성 옵션을 강화했습니다.

return {
{
"MeanderingProgrammer/render-markdown.nvim",
opts = {
heading = {
sign = false,
icons = { "◉ ", "○ ", "✸ ", "✿ ", "✤ ", "✜ " },
backgrounds = {
"RenderMarkdownH1Bg", "RenderMarkdownH2Bg",
"RenderMarkdownH3Bg", "RenderMarkdownH4Bg",
"RenderMarkdownH5Bg", "RenderMarkdownH6Bg",
},
},
code = {
style = "full",
position = "left",
width = "block",
left_pad = 2,
},
quote = { icon = "┃" },
bullet = { icons = { "●", "○", "◆", "◇" } },
checkbox = {
unchecked = { icon = "󰄱 " },
checked = { icon = "󰱒 " },
},
pipe_table = { style = "full", alignment_indicator = "━" },
link = { image = "󰥶 ", hyperlink = "󰌹 " },
},
},
}
옵션효과
heading.iconsH1~H6 아이콘으로 위계 구분
heading.backgrounds헤딩 줄 전체 배경 틴트 (테마의 RenderMarkdownH* highlight 그룹 위임)
code.style = "full"코드블록 전체 배경 + 좌측 언어 라벨
code.width = "block"코드블록 너비를 본문보다 좁게 (들여쓰기 효과)
quote.icon인용문 좌측 세로바
bullet.icons리스트 깊이별 글리프 (● ○ ◆ ◇)
checkbox[ ]/[x]를 Nerd Font 글리프로
pipe_table.style = "full"표 경계 전체 표시

색상은 테마의 highlight 그룹에 위임했기 때문에 colorscheme를 바꿔도 헤딩 틴트가 자동으로 따라옵니다.

lua/plugins/ufo.lua​

LSP 인지 폴딩을 설정했습니다.

nvim-ufo를 사용합니다. foldcolumn=0, foldlevel=99로 기본은 모두 펼친 상태로 두고, 필요할 때만 zc/zo로 접고 폅니다.

lua/plugins/floaterm.lua​

<C-;>로 토글하도록 설정했습니다.

LazyVim 기본 <C-/> snacks.terminal과 별개로, 손에 익은 floaterm을 같이 붙였습니다. <C-;>로 토글하며 둘은 충돌하지 않고 병존합니다.

lua/plugins/lang-extras.lua​

LazyExtras를 일괄 활성화했습니다.

return {
{ import = "lazyvim.plugins.extras.lang.go" },
{ import = "lazyvim.plugins.extras.lang.typescript" },
{ import = "lazyvim.plugins.extras.lang.markdown" },
{ import = "lazyvim.plugins.extras.lang.json" },
{ import = "lazyvim.plugins.extras.lang.yaml" },
{ import = "lazyvim.plugins.extras.lang.python" },
}

이 한 파일이 mason에게 marksman, gopls, ts_ls, pyright, ruff, jsonls, yamlls를 자동 설치하도록 위임합니다. 직전 셋업에서 손으로 동기화하던 그 영역입니다.

사용자 영역 추가​

keymaps (config/keymaps.lua)​

LazyVim 기본 키맵으로 이미 커버되는 건 이식하지 않았습니다. 기존에 손에 익은 두 개만 살렸습니다.

키동작
<leader>hsearch highlight 끄기
<C-;>floaterm 토글

이미 LazyVim이 잡아주는 것: <leader>e 파일 탐색기(새로 설치하면 snacks.explorer), <C-h/j/k/l> 패인 이동, < > visual indent stay, <leader>ff 파일 찾기 등. 전체는 LazyVim 키맵 치트시트 참고합니다.

마크다운 filetype 동작 (config/autocmds.lua)​

vim.api.nvim_create_autocmd("FileType", {
pattern = "markdown",
callback = function()
vim.opt_local.wrap = true
vim.opt_local.linebreak = true
vim.opt_local.conceallevel = 2
vim.opt_local.spell = false
vim.opt_local.cursorline = true
vim.opt_local.signcolumn = "no"
end,
})
옵션효과
wrap = true한글 긴 줄 자동 래핑
linebreak = true단어 경계에서만 래핑 (어절 중간 잘림 방지)
conceallevel = 2마크업 문자(**, # 등) 숨김 (실제로는 render-markdown이 3으로 덮어씀 — 더 강한 숨김. 의도된 동작)
spell = false한글 문서에서 영어 spell 체크 끔
cursorline = true현재 줄 강조 (긴 문서 위치 추적)
signcolumn = "no"좌측 여백 줄여 본문 폭 확보

클립보드는 별도 설정 없음​

macOS 로컬에서는 비주얼 모드에서 y만 눌러도 시스템 클립보드로 복사됩니다. LazyVim 15.x가 clipboard=unnamedplus를 기본값으로 잡아주기 때문입니다.

직전 수동 셋업에서는 제 setup 글에 적었듯 opt.clipboard = "unnamedplus" 한 줄을 직접 넣어야 했는데, distro 전환 후에는 이 줄도 지웠습니다. + 레지스터(시스템 클립보드)와 무명 레지스터(")가 자동 연결돼서 y/p가 양방향 동기화됩니다.

확인:

:set clipboard?

→ clipboard=unnamedplus 출력되면 OK.

provider 레벨 진단:

:checkhealth provider

또는 직접:

:let @+ = 'test'

→ 다른 앱에서 Cmd+V 했을 때 test가 붙으면 provider 정상.

tmux 안에서만 안 될 때는 ~/.tmux.conf에 OSC 52 전달 설정이 필요할 수 있습니다.

set -g set-clipboard on

macOS 로컬 tmux + pbcopy 조합은 보통 이 설정 없이도 동작합니다. SSH 원격 nvim에서는 LazyVim이 SSH 세션을 감지해 이미 clipboard를 빈 값으로 두므로, 따로 끌 필요가 없습니다.

의존성 (brew 설치)​

LazyVim 본체와 무관하게 PATH에 있어야 하는 외부 도구입니다.

도구용도
ripgrep빠른 grep (snacks.picker <leader>sg)
fd빠른 파일 찾기 (snacks.picker <leader>ff)
lazygit<leader>gg git TUI
node, npmLSP 서버들 (ts_ls, yamlls 등)
python3pynvim, mason 도구

mason이 자동 설치하는 도구는 처음 해당 언어 파일을 열 때 받아옵니다: marksman, gopls, ts_ls, pyright, ruff, jsonls, yamlls, lua_ls, markdownlint-cli2, prettier, stylua, gofumpt, goimports, golangci-lint, shfmt 등입니다.

검증 결과​

항목결과
Lazy sync통과 (42개 플러그인 설치)
세 colorscheme 로드통과 (solarized, everforest, gruvbox-material)
마크다운 autocmd 적용통과 (ft=markdown wrap=true cole=3 spell=false)
nvim startup 에러없음

전부 첫 실행에 떨어졌습니다. 백업해 둔 .backup-2026-05-07은 한 달 정도 묵혀 두고, 회귀가 없으면 정리할 예정입니다.

사용 팁​

  • <Space> 누르고 1초 대기 → which-key가 카테고리별 메뉴를 띄웁니다. 가장 빠른 키맵 학습 방법
  • :LazyExtras → 추가 언어팩 ON/OFF UI
  • :Mason → LSP/포매터/린터 설치 상태
  • :LazyHealth, :checkhealth → 의존성/문제 진단
  • :colorscheme <name>으로 테마 즉시 전환. 영구화는 lua/plugins/colorscheme.lua 마지막 블록의 colorscheme = "..." 변경
  • :RenderMarkdown toggle — 렌더링을 잠깐 끄고 원본 마크다운(**bold**, # H1)을 보고 싶을 때

정리​

수동 lazy.nvim 셋업은 잘 동작했고, 그 자체로 충분히 좋았어요. 다만 "제가 직접 관리해야 하는 것"의 표면적이 넓을수록 새 머신/새 언어를 붙일 때마다 작은 의식이 늘어났습니다. distro는 그 표면적을 줄여줍니다. 자동으로 처리될 수 있는 영역(LSP 자동완성, 포매팅, 치트시트, Git UI)을 일괄로 위임하고, 사용자는 "취향 차이가 나는 부분"에만 집중합니다.

LazyVim의 좋은 점은 lazy.nvim 위에 그대로 얹혀 있다는 점입니다. 빠지더라도 ~/.config/nvim을 통째로 갈아엎지 않아도 되고, 위 백업 절차로 언제든 직전 상태로 돌아올 수 있습니다. 그 안전망 위에서 가볍게 시도해볼 만한 전환이었어요.

키맵은 별도 글로 분리했어요: LazyVim 키맵 치트시트.

참고​