본문으로 건너뛰기

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

모든 태그 보기

LazyVim 키맵 치트시트

· 약 5분

이 글은 Vim/Neovim 단축키 시리즈의 세 번째 글입니다.

  1. Vi/Vim 단축키 종합 가이드: 기본부터 실전까지
  2. Neovim 단축키 가이드: Vim을 넘어서는 기능들
  3. LazyVim 키맵 치트시트 ← 현재 글

함께 읽기: LazyVim distro로 갈아타기

들어가며

LazyVim에서 키 외울 일은 사실 거의 없어요. <Space>를 누르고 잠깐 기다리면 which-key가 카테고리별 메뉴를 띄워 주고, <Space>sk로 키맵을 검색할 수도 있어요. 그래도 매일 자주 누르는 키는 손이 기억하는 편이 빨라요. 이 글은 그 "매일 누르는 키"만 모아 둔 치트시트예요.

Leader 키는 Space입니다. 아래 표의 <Space>가 모두 leader라고 보면 됩니다.

직전 수동 셋업의 키맵과는 다른 기본값이 많습니다. 새로 외우거나 같은 키에 다른 의미를 매핑하지 말고, LazyVim 기본을 그대로 쓰는 편을 권장합니다. 이미 합의된 컨벤션을 그대로 쓰는 편이 손이 덜 갑니다.

파일 트리 (neo-tree)

동작
<Space>e트리 토글 (열기/닫기 + 포커스)
<Space>Ecwd 기준 트리 (root와 다를 때)

트리 안에서:

동작
<CR>파일 열기
a추가
d삭제
r이름 변경
q닫기
H숨김파일 토글

<Space>e는 가장 자주 누르는 키 중 하나입니다. 토글이라 한 번 더 누르면 닫힙니다.

창 이동 (트리 ↔ 에디터)

동작
<C-h> / <C-l>왼/오 창 이동 (트리 ↔ 에디터 복귀에 가장 자주)
<C-j> / <C-k>아래/위 창
<C-w>=창 크기 균등화
<C-w>q현재 창 닫기

<C-w> 접두사를 누르고 다음 키를 눌러도 같은 동작이지만, <C-h/j/k/l> 직접 매핑이 손가락에 더 빠릅니다. LazyVim이 이미 잡아 준 키입니다.

파일/검색 (snacks.picker)

동작
<Space><Space>파일 찾기 (가장 빠른 진입)
<Space>ff / <Space>fF파일 찾기 (root / cwd)
<Space>sg내용 grep (live grep)
<Space>fr최근 파일

직전 셋업에서 Telescope의 <leader>ff/<leader>fg 조합을 썼다면 의미가 거의 그대로 옮겨 옵니다. 차이는 두 가지입니다. leader는 동일하게 Space이고, grep 키는 <Space>fg 대신 <Space>sg로 옮겨졌습니다(s = search 카테고리).

가장 짧은 진입은 **<Space><Space>**입니다. 두 번 두드리면 바로 파일 picker가 뜹니다.

버퍼/탭

동작
<S-h> / <S-l>이전/다음 버퍼
<Space>,버퍼 목록에서 선택
<Space>bd현재 버퍼 닫기

<S-h>/<S-l>은 Shift + h/l. 이게 LazyVim에서 버퍼 전환의 표준입니다. 바로 옆 버퍼로 점프할 일이 압도적으로 많아서 두 키만 외워도 대부분 커버됩니다.

코드 (LSP)

동작
gd정의로 점프
gr참조 찾기
gI구현으로 점프
K호버 문서
<Space>ca코드 액션
<Space>crrename
<Space>cf포맷
]d / [d다음/이전 진단

gd로 점프한 뒤 <C-o>로 직전 위치로 돌아옵니다. 이건 Vim 자체의 점프 리스트라 LazyVim과 무관하게 동작합니다.

<Space>c 접두사는 Code 그룹이라 외우기 쉽습니다. ca = code action, cr = code rename, cf = code format.

Git

동작
<Space>gglazygit 실행
]h / [h다음/이전 hunk
<Space>gbline blame

<Space>gg를 가장 자주 누릅니다. lazygit TUI 안에서 stage, commit, push까지 다 처리합니다. nvim 본체로 돌아오면 gitsigns가 변경된 줄에 사이드 마커를 자동으로 표시해 주고, ]h/[h로 hunk 사이를 점프합니다.

기타

동작
<C-/>터미널 토글 (snacks.terminal, <Esc> 두 번 또는 <C-\><C-n>으로 빠져나옵니다)
<C-;>floaterm 토글 (사용자 추가)
<Space>lLazy 플러그인 매니저
<Space>cmMason (LSP/포매터 매니저)
<Space>w저장
<Space>qq전체 종료
<Space>uC컬러스킴 변경 (UI에서 라이브 프리뷰)
<Space>hsearch highlight 끄기 (사용자 추가)

<C-/><C-;>는 둘 다 터미널 토글이지만 띄우는 플러그인이 다릅니다(snacks.terminal vs vim-floaterm).

<Space>uC는 테마를 라이브 프리뷰로 바꿔 본 뒤 마음에 드는 것을 영구화할 때 편리합니다. 자세한 컬러스킴 셋업은 distro 갈아타기 글을 참고합니다.

자주 쓰는 명령

치트시트는 키 위주로 정리했지만, : 명령으로 자주 들어가는 곳도 같이 외워 두면 좋습니다.

명령동작
:LazyExtras추가 언어팩 ON/OFF UI
:MasonLSP/포매터/린터 설치 상태
:LazyHealth, :checkhealth의존성/문제 진단
:RenderMarkdown toggle마크다운 렌더링 잠시 끄기
:colorscheme <name>테마 즉시 전환

학습 팁

키를 외우려고 할 필요 없습니다. 다음 두 가지만 습관화하면 자동으로 박힙니다.

  1. <Space> 누르고 잠시 기다리기. f(파일)/b(버퍼)/c(코드)/g(git)/s(검색)/u(UI 토글) 메뉴가 뜨면 첫 글자 한 번 보고 다음 키를 누릅니다. 한 번에 다 외우려 하지 말고 매일 한 카테고리씩 훑어보면 됩니다.
  2. <Space>sk로 키맵 검색. "버퍼 닫는 키가 뭐였더라?" 싶을 때 <Space>sk → "buffer close"를 입력하면 매핑이 바로 뜹니다.

:verbose map <key>도 디버깅 단계에선 유용합니다. 어떤 플러그인이 해당 키를 가져갔는지 표시해 줍니다.

마치며

LazyVim의 키맵은 이미 합의된 컨벤션입니다. Telescope 시절의 <leader>ff/fg, neo-tree의 <leader>e, gitsigns의 ]h/[h 같은 묶음이 그대로 살아 있고, 거기에 snacks 계열 picker, dashboard, terminal이 같은 카테고리에 얹혀 있습니다. 손이 헷갈릴 일이 거의 없습니다.

새 머신에 LazyVim을 깔고 가장 먼저 손에 익히면 좋은 6개:

<Space><Space> — 파일 찾기
<Space>sg — 내용 grep
<Space>e — 트리 토글
<S-h> / <S-l> — 버퍼 이전/다음
gd — 정의 점프
<Space>gg — lazygit

이 여섯 개만 손에 박히면 매일 쓰는 키는 거의 다 커버됩니다. 나머지는 <Space> 누르고 기다리면 which-key가 알려줍니다.

전체 셋업 맥락은 LazyVim distro로 갈아타기 글에 정리해 두었어요.

참고

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의 핵심이에요.

직전 셋업 공개 글에서 정리했던 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, neo-tree
키 안내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

이 안전망이 있어야 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 neo-tree, <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"좌측 여백 줄여 본문 폭 확보

클립보드는 별도 설정 없음

비주얼 모드에서 y만 눌러도 macOS 시스템 클립보드로 복사됩니다. 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에서 OSC 52 핸들링이 깨지는 환경이라면 LazyVim 기본값을 의도적으로 끄고 싶을 수 있습니다 — options.luavim.opt.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 키맵 치트시트.

참고

Claude Code 외부 에디터

· 약 5분

터미널에서 긴 프롬프트는 힘들다

Claude Code를 쓰다 보면 몇 줄 넘는 프롬프트를 치고 싶을 때가 종종 있어요. 들여쓰기가 있거나, 코드를 붙이거나, 한글 IME 상태에서 복잡한 편집이 필요한 순간이에요. 터미널의 한 줄 편집기는 이런 상황에 약해요.

이럴 때 Claude Code 프롬프트를 외부 에디터로 열어서 쓸 수 있습니다. 방법 자체는 간단한데, 운용하다 보면 사소한 함정이 하나 있어 같이 정리합니다.

$EDITORCtrl+X Ctrl+E를 쓰는 기본 방법

Claude Code는 프롬프트 입력 중 Ctrl+X 뒤이어 Ctrl+E 를 누르면 $EDITOR 환경변수에 지정된 에디터를 띄웁니다. 내부적으로는 claude-prompt-<uuid>.md 같은 임시 파일을 만들고 그걸 에디터에 넘깁니다. 편집 후 저장하고 닫으면 그 내용이 그대로 프롬프트에 입력됩니다.

가장 단순한 세팅:

# ~/.zshrc
export EDITOR='nvim'

이러면 Ctrl+X Ctrl+E로 nvim이 뜨고, :wq로 닫으면 내용이 Claude Code 프롬프트로 들어옵니다.

참고로 최근 Claude Code 버전은 Ctrl+G도 같은 동작으로 바인딩돼 있습니다. 둘 다 테스트해 보고 손에 맞는 것을 쓰면 됩니다.

전역 EDITOR는 nvim, Claude만 Cursor로

그런데 EDITOR 환경변수는 git, crontab, less 등 여러 곳에서 참조합니다. 저는 이걸 nvim으로 둔 상태가 편해서 바꾸고 싶지 않아요. Claude Code 프롬프트만 GUI 에디터(Cursor, VSCode)로 띄우고 싶을 때는 함수로 감싸서 EDITOR를 이 프로세스 범위에서만 오버라이드하면 됩니다.

~/.zshrc에 들어 있는 것은 이것입니다.

cc() {
# VSCode 쓸 때
# EDITOR="code -w" command claude "$@"

# Cursor 쓸 때
EDITOR="/Applications/Cursor.app/Contents/Resources/app/bin/cursor -w" command claude "$@"
}

중요한 점은 두 가지입니다.

  • command claude: alias나 동명 함수가 걸려 있어도 실제 claude 바이너리를 실행하도록 우회합니다.
  • -w 플래그: Cursor/VSCode는 기본적으로 연 뒤 바로 셸로 제어를 반환합니다. -w(또는 --wait)를 붙여야 에디터 창이 닫힐 때까지 대기합니다. 없으면 Claude Code가 빈 파일을 바로 읽어 갑니다.

이제 터미널에서 cc만 실행하면 Claude Code가 뜨고, 프롬프트 편집 시 Cursor로 열립니다. 다른 툴들은 EDITOR=nvim을 그대로 봅니다.

실제 동작

1. 프롬프트에서 Ctrl+X Ctrl+E

Claude Code 프롬프트에서 Ctrl+X Ctrl+E 입력

2. Cursor에 임시 파일이 열립니다

Cursor에 claude-prompt 임시 파일이 열린 모습

파일명은 claude-prompt-<uuid>.md 형식입니다. 마크다운이라 코드 블록이나 리스트도 편하게 쓸 수 있습니다.

3. 저장하고 닫으면 프롬프트로 들어옵니다

여기서 한 가지 이상한 게 생겼습니다.

![복귀 후 프롬프트에 ^[[O^[I 이상 문자가 끼어든 상태

프롬프트 앞부분의 기존 텍스트와 Cursor에서 쓴 내용 사이에 ^[[O^[[I^[[O^[[I^[[O가 끼어 있습니다. 정체가 무엇일까요?

^[[O, ^[[I의 정체

이 문자들은 Focus Reporting에서 나옵니다.

터미널에는 포커스 리포팅(Focus Reporting) 이라는 기능이 있습니다. ANSI/xterm 스펙의 DEC Private Mode 1004. 이게 켜져 있으면 터미널 창의 포커스가 들어오고 나갈 때 아래 두 이스케이프 시퀀스가 터미널에 주입됩니다.

이벤트시퀀스
포커스 들어옴 (focus-in)ESC [ I (표기상 ^[[I)
포커스 나감 (focus-out)ESC [ O (표기상 ^[[O)

이걸 왜 쓰느냐면, vim/tmux 같은 TUI 앱이 유휴 상태일 때 렌더링을 멈추거나 커서 스타일을 바꾸기 위해 필요합니다. 터미널이 보내주는 이 이벤트로 현재 창이 활성인지 아닌지를 알 수 있습니다.

문제는 이 지점입니다.

  1. Claude Code가 Cursor를 띄웁니다. 이 순간 터미널 포커스가 제 터미널에서 Cursor 윈도우로 이동하고, 터미널이 ^[[O (focus-out)을 내보냅니다.
  2. Cursor에서 저장/종료하면 포커스가 다시 터미널로 돌아옵니다. ^[[I (focus-in)이 내보내집니다.
  3. 창 전환을 두세 번 하다 보면 여러 번의 in/out이 생깁니다.
  4. 이 이스케이프 시퀀스들은 stdin 버퍼에 쌓입니다. Claude Code가 에디터 종료 후 다시 입력 읽기를 시작할 때, 앞서 쌓인 것들을 프롬프트 텍스트로 흡수합니다.

정리하면 Cursor/VSCode 같은 별도 윈도우 GUI 에디터를 띄울 때만 이 현상이 생깁니다. 터미널에서 포커스가 실제로 왔다갔다 하기 때문입니다.

해결 방법

1순위: nvim / vim / helix / micro

같은 터미널 세션 안에서 도는 TUI 에디터는 포커스가 창 단위로 움직이지 않습니다. 창은 하나, 안에서 그냥 화면이 바뀔 뿐입니다. focus-in/out 이벤트 자체가 생기지 않습니다.

export EDITOR='nvim'

제 경험상 이게 제일 안정적이에요. nvim이 충분히 좋은 마크다운 편집기이기도 하고요.

2순위: 그래도 Cursor/VSCode를 쓰고 싶다면

몇 가지 부분 해결책이 있지만 완벽한 건 없습니다.

  • 복귀 후 섞인 ^[[ 시퀀스를 backspace로 수동 제거한 뒤 Enter를 누릅니다.
  • 터미널 앱 설정에서 focus reporting을 비활성화합니다(Ghostty, iTerm2 등에 옵션이 있습니다). 단 vim/tmux 쪽 기능도 같이 잃습니다.
  • Cursor/VSCode를 쓰되 cc 함수 내에서 임시로 focus reporting을 꺼 주는 래퍼를 끼웁니다. 번거로운 방법입니다.

깔끔한 길은 첫 번째예요. 긴 프롬프트 편집에 IDE급 기능이 꼭 필요한 게 아니라면 TUI 에디터 쪽이 나아요.

요약

  • Claude Code 프롬프트는 Ctrl+X Ctrl+E (또는 Ctrl+G)로 $EDITOR를 호출합니다.
  • 전역 EDITOR를 건드리지 않고 싶다면 cc() 함수 패턴으로 Claude에 한정해 오버라이드합니다. -w 플래그를 꼭 붙여야 합니다.
  • Cursor/VSCode를 쓰면 포커스 리포팅 시퀀스가 프롬프트에 섞이는 부작용이 있습니다.
  • 제일 안정적인 조합은 TUI 에디터(nvim 등) + EDITOR=nvim입니다.

참고 링크

Neovim 단축키 가이드

· 약 9분

이 글은 Vim 단축키 시리즈의 두 번째 글이에요.

  1. Vi/Vim 단축키 종합 가이드: 기본부터 실전까지
  2. Neovim 단축키 가이드: Vim을 넘어서는 기능들 ← 현재 글

Vi와 뭐가 다른가

1편에서 다룬 단축키는 Vi/Vim 어디서든 동작하는 보편적인 키입니다. 이 글에서는 Neovim에서만 쓸 수 있는 기능들을 다룹니다.

Neovim이 Vim 위에 추가하는 것:

Neovim에는 플러그인 없이 코드 분석, 정의 이동, 자동완성을 지원하는 내장 LSP가 있습니다. 내장 터미널에서는 에디터 안에서 셸을 실행합니다. Lua 설정으로 Vimscript 대신 Lua를 사용해 설정과 플러그인을 구성하며, 플러그인 생태계에는 Telescope, Treesitter, LSP 기반 플러그인 등이 있습니다.

아래 단축키 중 <leader> 키가 나오면, 대부분의 Neovim 설정에서 Space로 매핑되어 있습니다.

내장 LSP 단축키

LSP(Language Server Protocol)를 설정하면 IDE 수준의 코드 내비게이션이 가능해집니다.

코드 내비게이션

동작
gd정의로 이동 (Go to Definition)
gD선언으로 이동 (Go to Declaration)
gr참조 목록 (Go to References)
gi구현으로 이동 (Go to Implementation)
K커서 아래 심볼 정보 표시 (hover)
Ctrl-]정의로 이동 (태그 스택 방식)

gd로 이동한 후 Ctrl-o를 누르면 이전 위치로 돌아옵니다.

코드 액션

동작
<leader>ca코드 액션 (자동 수정, import 추가 등)
<leader>rn심볼 이름 변경 (rename)
<leader>f포맷팅

진단 (Diagnostics)

동작
[d이전 진단(에러/경고)으로 이동
]d다음 진단으로 이동
<leader>e현재 줄 진단 메시지 표시
<leader>q진단 목록 열기 (quickfix)

자동완성

동작
Ctrl-Space자동완성 메뉴 열기
Tab / Shift-Tab다음 / 이전 항목
Enter선택 확정
Ctrl-e자동완성 취소
Ctrl-n / Ctrl-p다음 / 이전 (내장 완성)

시그니처 도움말

동작
Ctrl-k함수 시그니처 표시 (Insert 모드)

함수 호출 시 인자를 입력하는 중에 Ctrl-k를 누르면 파라미터 정보가 표시됩니다.

내장 터미널

Neovim 안에서 셸을 실행합니다.

기본 사용

명령동작
:terminal현재 윈도우에서 터미널 열기
:split | terminal가로 분할 후 터미널
:vsplit | terminal세로 분할 후 터미널

터미널 모드 키

동작
i / a터미널 입력 모드 진입
Ctrl-\ Ctrl-nNormal 모드로 복귀

터미널에서 Normal 모드로 돌아오면 출력 내용을 Vim 명령으로 검색하거나 복사할 수 있게 됩니다.

분할 터미널 워크플로우

+------------------+------------------+
| Code (Neovim) | Terminal (shell) |
| | |
+------------------+------------------+

코드를 편집하면서 옆 터미널에서 빌드/테스트를 실행합니다. Ctrl-w l로 터미널로 이동하고, Ctrl-w h로 코드로 복귀합니다.

플로팅 터미널: 많은 설정에서 Ctrl-; 또는 <leader>t로 플로팅 터미널을 토글합니다. 화면을 많이 가리지 않으면서 빠르게 명령을 실행하는 데 유용합니다.

마우스 활용

Neovim에서 mouse=a 설정을 켜면 마우스를 활용할 수 있게 됩니다.

기본 동작

동작결과
클릭커서 이동
드래그Visual 모드로 텍스트 선택
더블클릭단어 선택 (Visual)
트리플클릭줄 전체 선택 (Visual Line)
Shift + 클릭현재 커서부터 클릭 위치까지 선택
스크롤 휠페이지 스크롤

마우스 + 키보드 하이브리드

마우스로 선택한 후 키보드로 조작:

1. 마우스 드래그로 영역 선택 (Visual 모드 진입)
2. d, c, y 등 키보드 명령 실행

예: 마우스로 코드 블록을 드래그 선택 → > (들여쓰기), y (복사), d (삭제)

언제 마우스를 쓰는가

키보드가 더 빠른 경우는 다음과 같습니다.

  • 같은 줄 내 이동 (f, w, 0, $)
  • 구조적 선택 (ci", vi{, vap)
  • 반복 작업 (., 매크로)

마우스는 화면에 보이는 임의의 위치로 먼 거리 점프를 하거나, 여기저기 클릭하며 코드 리뷰를 하거나, 단어나 괄호 경계와 무관하게 비구조적 선택을 할 때 더 빠릅니다.

키보드 순수주의에 집착할 필요는 없습니다. 상황에 따라 둘 다 사용하면 됩니다.

필수 플러그인 단축키

Neovim 생태계의 핵심 플러그인들과 주요 단축키를 정리합니다.

Telescope

퍼지 파인더로 파일과 텍스트, 버퍼, 도움말 태그를 검색합니다.

동작
<leader>ff파일 찾기
<leader>fg텍스트 검색 (live grep)
<leader>fb열린 버퍼 목록
<leader>fh도움말 태그 검색

Telescope 창 안에서:

동작
Ctrl-j / Ctrl-k위아래 이동
Enter선택 항목 열기
Ctrl-x가로 분할로 열기
Ctrl-v세로 분할로 열기
Ctrl-t새 탭으로 열기
Esc닫기

Neo-tree

파일 트리를 제공하는 탐색기입니다.

동작
<leader>e파일 트리 토글

Neo-tree 안에서:

동작
Enter / o파일 열기 / 폴더 토글
a새 파일/폴더 생성
d삭제
r이름 변경
c / m복사 / 이동
y경로 복사
/필터 검색

Comment.nvim

언어에 맞는 주석을 간편하게 적용합니다.

동작
gcc현재 줄 주석 토글
gc{motion}범위 주석 토글 (예: gcap 문단)
gc (Visual)선택 영역 주석 토글
gbc현재 줄 블록 주석 토글

Vim의 Ctrl-vI// 방식보다 훨씬 간편합니다. 언어별 주석 형식도 자동 감지합니다.

nvim-surround

텍스트를 원하는 문자로 감싸거나 기존 감싸기를 변경하고 삭제합니다.

동작예시
ys{motion}{char}감싸기 추가ysiw" → word를 "word"로
cs{old}{new}감싸기 변경cs"' → "text"를 'text'로
ds{char}감싸기 삭제ds" → "text"를 text로
S{char} (Visual)선택 영역 감싸기선택 후 S( → (선택 영역)으로

Surround 문법:

ys + iw + " → 단어를 "로 감싸기
ys + ap + { → 문단을 {로 감싸기
cs + " + ' → "를 '로 변경
ds + ( → (를 삭제

이것도 동사(ys/cs/ds) + 명사(motion/text object) + 감싸기 문자의 문법입니다.

Flash / Hop

현재 화면 안에서 원하는 위치로 빠르게 이동합니다.

동작
s{char}{char}2글자 입력 후 레이블로 점프

화면에 보이는 위치로 2-3번의 키 입력만으로 이동합니다. f/t는 같은 줄로 제한되지만, Flash는 화면 전체에서 동작합니다.

Gitsigns

Git 변경 사항을 표시하고 hunk 단위 작업을 지원합니다.

동작
]c / [c다음 / 이전 변경 사항으로 이동
<leader>hshunk 스테이지
<leader>hrhunk 리셋
<leader>hphunk 미리보기 (diff)
<leader>hb줄 blame 표시

Which-key

사용할 수 있는 키를 팝업으로 안내합니다.

동작설명
<leader> 누르고 잠시 대기사용 가능한 키 목록이 표시됨

단축키가 기억나지 않을 때 <leader>만 누르고 기다리면 됩니다. 어떤 키가 어떤 기능인지 팝업으로 보여줍니다.

Leader 키와 커스텀 매핑 전략

Space를 Leader로 쓰는 이유

vim.g.mapleader = " "
  • 양손 어디서든 누르기 쉬운 위치
  • 기본적으로 Normal 모드에서 Spacel과 같은 동작(쓸모 없음)
  • Neovim 커뮤니티의 사실상 표준

네이밍 규칙

잘 만들어진 설정에서는 Leader 뒤의 키가 일관된 체계를 따릅니다.

접두사의미예시
<leader>fFindff(파일), fg(grep), fb(버퍼)
<leader>bBufferbn(다음), bp(이전), bd(닫기)
<leader>gGitgs(status), gc(commit), gp(push)
<leader>lLSPld(정의), lr(참조), ln(rename)
<leader>tTerminal/Tabtt(토글), tn(새 탭)
<leader>wWindowwv(세로분할), ws(가로분할)

자주 쓰는 커스텀 매핑

-- 저장
vim.keymap.set("n", "<leader>w", ":w<CR>")

-- 창 이동 (Ctrl-h/j/k/l)
vim.keymap.set("n", "<C-h>", "<C-w>h")
vim.keymap.set("n", "<C-j>", "<C-w>j")
vim.keymap.set("n", "<C-k>", "<C-w>k")
vim.keymap.set("n", "<C-l>", "<C-w>l")

-- Visual 모드에서 들여쓰기 후 선택 유지
vim.keymap.set("v", "<", "<gv")
vim.keymap.set("v", ">", ">gv")

-- 줄 이동
vim.keymap.set("v", "J", ":m '>+1<CR>gv=gv")
vim.keymap.set("v", "K", ":m '<-2<CR>gv=gv")

-- 검색 하이라이트 제거
vim.keymap.set("n", "<leader>h", ":nohlsearch<CR>")

-- 시스템 클립보드 복사
vim.keymap.set({"n", "v"}, "<leader>y", '"+y')

마지막 <gv / >gv 매핑은 특히 유용합니다. 기본 Vim에서는 >로 들여쓰기하면 Visual 선택이 해제되지만, 이 매핑을 쓰면 선택이 유지되어 연속으로 > >를 누를 수 있습니다.

클립보드 연동

기본 사용

"+y → 시스템 클립보드에 복사
"+p → 시스템 클립보드에서 붙여넣기

매번 "+를 치기 귀찮다면 설정에서:

vim.opt.clipboard = "unnamedplus"

이렇게 하면 y/p가 바로 시스템 클립보드를 사용합니다.

SSH 원격에서 클립보드

SSH로 접속한 서버의 Neovim에서 복사한 텍스트를 로컬 클립보드로 보내려면 OSC 52를 지원하는 터미널이 필요합니다.

지원 터미널: iTerm2, WezTerm, Alacritty, kitty, Windows Terminal

Neovim 0.10+에서는 OSC 52가 기본 지원됩니다. 별도 설정 없이 "+y로 SSH 환경에서도 로컬 클립보드에 복사합니다.

Neovim 전용 편의 기능

명령/검색 히스토리 윈도우

동작
q:명령 히스토리를 편집 가능한 창으로
q/검색 히스토리를 편집 가능한 창으로

일반 : 프롬프트와 달리, Vim 명령(검색, 편집, 이동)으로 이전 명령을 수정해 실행합니다. 긴 치환 명령을 재사용할 때 유용합니다.

q:를 실수로 눌렀다면 :q로 닫습니다.

inccommand

치환 결과를 실시간으로 미리 보여주는 기능입니다.

vim.opt.inccommand = "split"

:s/old/new/g를 입력하는 동안 실시간으로 변경 결과를 미리 보여줍니다. 정규식이 맞는지 실행 전에 확인할 수 있습니다.

"split"으로 설정하면 화면 하단에 변경될 줄 목록이 표시됩니다. "nosplit"이면 본문에서 직접 하이라이트합니다.

:lua 직접 실행

:lua print(vim.fn.expand("%")) " 현재 파일 경로
:lua print(vim.opt.tabstop:get()) " 탭 크기
:lua vim.lsp.buf.format() " LSP 포맷팅

설정을 바꾸거나 디버깅할 때 Lua 코드를 즉시 실행할 수 있다는 점도 유용합니다.

내장 diff 모드

nvim -d file1.txt file2.txt

또는 이미 열린 상태에서:

:diffthis " 현재 윈도우를 diff에 포함
:diffoff " diff 모드 해제
]c / [c " 다음/이전 변경으로 이동
do " diff obtain — 반대쪽 변경 가져오기
dp " diff put — 이쪽 변경 보내기

단축키 디버깅

단축키가 안 먹히거나 예상과 다르게 동작할 때:

매핑 확인

:map <leader>f " <leader>f에 뭐가 매핑되어 있는지
:nmap " Normal 모드 매핑 전체 목록
:imap " Insert 모드 매핑 전체
:vmap " Visual 모드 매핑 전체
:verbose map <leader>f " 어떤 파일에서 매핑했는지까지 표시

:verbose가 특히 중요합니다. 키 충돌이 생겼을 때 어떤 플러그인이 해당 키를 가져갔는지 바로 확인합니다.

Which-key 활용

Which-key 플러그인이 설치되어 있다면 <leader>를 누르고 기다리면 모든 매핑이 시각화됩니다. 키 충돌이 있으면 같은 접두사에 두 개 이상의 매핑이 보입니다.

키가 안 먹힐 때 체크리스트

  1. :verbose map <key>로 다른 플러그인이 덮어쓰지 않았는지 확인
  2. 올바른 모드인지 확인 (nmap vs imap vs vmap)
  3. Leader 키가 제대로 설정되었는지: :echo mapleader
  4. 플러그인이 로드되었는지: :Lazy check (lazy.nvim 사용 시)

마치며

Neovim은 Vim의 편집 철학 위에 현대적인 기능을 더해요. LSP는 IDE 수준의 코드 내비게이션을 제공하고, 내장 터미널은 에디터 밖을 나가지 않는 워크플로우를 만들며, 플러그인은 기능을 폭넓게 확장해요.

다음 순서로 익히기를 권합니다.

  1. 1편의 Vim 기본을 먼저 익힙니다
  2. LSP 단축키(gd, K, gr)를 자주 쓰면서 습관을 만듭니다
  3. Telescope(<leader>ff/fg)를 파일 탐색의 기본으로 삼습니다
  4. Comment(gcc), Surround(ys/cs/ds)를 익힙니다
  5. 나머지는 필요할 때 하나씩 추가합니다

한 번에 다 외우려 하지 말고, 매일 하나씩 새로운 키를 시도해보세요.

참고 자료

Vi/Vim 단축키 가이드

· 약 15분

이 글은 Vim 단축키 시리즈의 첫 번째 글이에요.

  1. Vi/Vim 단축키 종합 가이드: 기본부터 실전까지 ← 현재 글
  2. Neovim 단축키 가이드: Vim을 넘어서는 기능들

Vim의 언어: 동사 + 명사

Vim 단축키는 외워야 하는 목록보다 문법에 가깝습니다.

동사(operator)는 "무엇을 할 것인가":

동사의미
d삭제 (delete)
c변경 (change) — 삭제 후 Insert
y복사 (yank)
>들여쓰기
<내어쓰기
gU대문자로
gu소문자로
=자동 정렬

명사(motion/text object)는 "어디까지":

명사의미
w다음 단어까지
$줄 끝까지
gg파일 처음까지
%매칭 괄호까지
iw단어 안쪽 (inner word)
i"따옴표 안쪽
a(괄호 포함 전체

동사와 명사는 다음처럼 조합합니다.

d + iw = diw → 단어 삭제
c + i" = ci" → 따옴표 안 내용 변경
y + $ = y$ → 줄 끝까지 복사
> + ap = >ap → 문단 들여쓰기
gU + iw = gUiw → 단어 대문자로

이 문법을 이해하면 수백 개의 조합을 일일이 외우지 않고 만들어낼 수 있습니다.

모드

Vim은 모드 기반 에디터입니다. 같은 키도 모드에 따라 다르게 동작합니다.

모드진입역할
NormalEsc이동, 편집 명령 실행
Inserti, a, o텍스트 입력
Visualv, V, Ctrl-v영역 선택
Command-line:, /, ?명령 실행, 검색
ReplaceR덮어쓰기 입력

Insert 모드 내 단축키

Insert 모드에서도 몇 가지 유용한 키가 있습니다.

동작
Ctrl-w커서 앞 단어 삭제
Ctrl-u커서 앞 줄 전체 삭제
Ctrl-r "레지스터 내용 붙여넣기
Ctrl-oNormal 모드 명령 1회 실행 후 Insert 복귀
Ctrl-t들여쓰기
Ctrl-d내어쓰기

기본 이동

k

h ← → l

j

숫자를 앞에 붙이면 반복합니다. 5j는 5줄 아래, 10k는 10줄 위로 이동합니다.

단어 단위 이동

동작
w다음 단어 시작
b이전 단어 시작
e현재/다음 단어 끝
ge이전 단어 끝
W/B/EWORD 단위 (공백 기준으로만 구분)

wW의 차이: hello-world에서 w-에서 멈추지만, W는 공백까지 건너뜁니다.

줄 안에서 이동

위치
0줄 맨 처음 (0번째 열)
^줄 첫 번째 글자 (공백 제외)
$줄 끝
g_줄 마지막 글자 (공백 제외)
+다음 줄 첫 글자
-이전 줄 첫 글자

문자 찾기로 이동

줄 안에서 특정 문자로 이동하는 기능입니다. 이동뿐 아니라 동사와 조합하면 강력해집니다.

동작
f{char}오른쪽으로 {char} 위치로 이동
F{char}왼쪽으로 {char} 위치로 이동
t{char}오른쪽으로 {char} 앞까지 이동
T{char}왼쪽으로 {char} 뒤까지 이동
;같은 방향으로 반복
,반대 방향으로 반복

실전에서 자주 쓰는 조합:

dt) → 닫는 괄호 앞까지 삭제
cf, → 쉼표까지 변경 (쉼표 포함)
yt; → 세미콜론 앞까지 복사
vf" → 따옴표까지 선택

괄호와 블록 사이 이동

동작
%매칭 괄호로 점프 — (↔), {↔}, [↔]
[{현재 블록의 여는 {
]}현재 블록의 닫는 }
[(현재 블록의 여는 (
])현재 블록의 닫는 )

%는 코드 읽을 때 특히 유용합니다. 긴 함수의 시작 {에서 %를 누르면 닫는 }로 바로 이동합니다.

화면과 파일 안에서 이동

스크롤

동작
Ctrl-d반 페이지 아래
Ctrl-u반 페이지 위
Ctrl-f한 페이지 아래
Ctrl-b한 페이지 위

화면 내 이동

동작
H화면 상단 (High)
M화면 중단 (Middle)
L화면 하단 (Low)

화면 정렬

동작
zz현재 줄을 화면 가운데로
zt현재 줄을 화면 상단으로
zb현재 줄을 화면 하단으로

파일 내 이동

동작
gg파일 처음
G파일 끝
{n}Gn번째 줄로 (:42와 동일)

검색으로 이동

동작
/pattern아래로 검색
?pattern위로 검색
n다음 결과
N이전 결과
*커서 아래 단어를 아래로 검색
#커서 아래 단어를 위로 검색
gn다음 검색 결과를 Visual 선택
gd현재 파일에서 변수 선언으로

*#은 변수명 위에서 누르면 같은 이름을 바로 찾아줍니다. 검색어를 타이핑할 필요가 없습니다.

텍스트 삽입

위치
i커서 앞
a커서 뒤
I줄 첫 글자 앞
A줄 끝
o아래에 새 줄
O위에 새 줄
gi마지막 Insert 위치로 돌아가서 입력

gi는 편집 중 Normal로 돌아가서 다른 작업을 하다가, 다시 이전 편집 위치로 돌아갈 때 씁니다.

텍스트 삭제

삭제(d)는 동사입니다. 명사와 조합합니다.

동작
x커서 아래 문자
X커서 앞 문자
dw다음 단어까지
de단어 끝까지
db이전 단어까지
dd줄 전체
D = d$줄 끝까지
d0줄 처음까지
d^첫 글자까지
dG파일 끝까지
dgg파일 처음까지
diw단어 (inner)
daw단어 + 주변 공백 (around)
di"따옴표 안
di(괄호 안

텍스트 변경

변경(c)은 삭제 후 Insert 모드로 진입합니다. d와 같은 문법을 따르며 곧바로 입력할 수 있습니다.

동작
cw단어 끝까지 변경
ciw단어 전체 변경
ci"따옴표 안 변경
ci(괄호 안 변경
cc줄 전체 변경
C = c$줄 끝까지 변경
s문자 하나 변경 (= cl)
S줄 전체 변경 (= cc)
r{char}커서 문자를 {char}로 교체 (Normal 유지)
RReplace 모드 진입 (타이핑이 기존 텍스트를 덮어씀)

ci"는 아마 Vim에서 가장 많이 쓰는 조합 중 하나입니다. 따옴표 안에 커서를 놓고 ci"를 누르면 안의 내용이 지워지고 바로 새 내용을 입력하게 됩니다.

복사와 붙여넣기

동작
yy줄 복사
yw단어 복사
y$줄 끝까지 복사
yi"따옴표 안 복사
ya(괄호 포함 전체 복사
p커서 뒤에 붙여넣기
P커서 앞에 붙여넣기
]p들여쓰기 맞춰서 붙여넣기
[p위에 들여쓰기 맞춰서 붙여넣기

자주 쓰는 조합:

조합결과
yyp현재 줄 복제
ddp현재 줄과 아래 줄 교환
xp커서 아래 두 문자 교환

줄 조작

동작
J현재 줄과 아래 줄 합치기 (공백 추가)
gJ줄 합치기 (공백 없이)
>>현재 줄 들여쓰기
<<현재 줄 내어쓰기
5>>5줄 들여쓰기
==현재 줄 자동 정렬
=G현재 줄부터 파일 끝까지 자동 정렬
:m+1현재 줄을 한 줄 아래로 이동
:m-2현재 줄을 한 줄 위로 이동

>> 후에 .을 누르면 한 단계씩 더 들여씁니다. 들여쓰기 레벨을 조절할 때 편리합니다.

대소문자와 숫자 편집

동작
~커서 아래 문자 대소문자 토글
gUiw단어 대문자로
guiw단어 소문자로
gU$줄 끝까지 대문자로
gUU줄 전체 대문자로
guu줄 전체 소문자로
Ctrl-a커서 아래(또는 뒤) 숫자 +1
Ctrl-x커서 아래(또는 뒤) 숫자 -1
5Ctrl-a숫자 +5

Ctrl-a/Ctrl-x는 코드에서 인덱스나 포트 번호를 바꿀 때 유용합니다. 커서가 숫자 위에 없어도, 같은 줄의 다음 숫자를 찾아서 변경합니다.

반복의 힘: . 명령어

.마지막 편집 동작을 반복합니다. Vim에서 가장 강력한 키 중 하나입니다.

패턴 1: 검색 + 반복 치환

1. * → 커서 아래 단어 검색
2. ciw → 단어 변경
3. 새 단어 → 입력
4. Esc → Normal 복귀
5. n → 다음 결과
6. . → 같은 변경 반복

n.n.를 반복하면 원하는 것만 골라서 치환할 수 있습니다. :%s와 달리 하나씩 확인하면서 바꿀 수 있습니다.

패턴 2: 여러 줄에 같은 편집

1. A; → 줄 끝에 세미콜론 추가
2. Esc
3. j → 다음 줄
4. . → 같은 동작 반복

패턴 3: 점진적 들여쓰기

1. >> → 들여쓰기
2. . → 한 레벨 더
3. . → 한 레벨 더

.과 잘 어울리는 명령어

명령어.으로 반복하면
ciw + 입력다른 단어를 같은 내용으로 변경
A;줄 끝에 세미콜론 추가
I// 줄 앞에 주석 추가
dd줄 삭제
>>들여쓰기
r{char}문자 교체

텍스트 오브젝트

i(inner)는 안쪽만, a(around)는 주변 공백이나 구분자를 포함합니다.

오브젝트inner (i)around (a)대상
단어iwawword
WORDiWaWWORD (공백 구분)
문장isassentence
문단ipapparagraph
"i"a""큰따옴표"
'i'a''작은따옴표'
`i`a``백틱`
( / )i(a((소괄호)
{ / }i{a{{중괄호}
[ / ]i[a[[대괄호]
< / >i<a<<꺾쇠>
태그itatHTML 태그

실전 조합:

ciw → 단어 내용 변경
da" → 따옴표 포함 삭제
vi( → 괄호 안 Visual 선택
yat → HTML 태그 전체 복사
>ip → 현재 문단 들여쓰기
gUiw → 단어 대문자로

Visual 모드 기본

세 가지 Visual 모드

모드선택 단위
vVisual문자 단위
VVisual Line줄 단위
Ctrl-vVisual Block사각형 블록

선택 확장

동작
o선택 영역의 양 끝을 토글 (시작↔끝 커서 이동)
OVisual Block에서 같은 줄의 반대쪽 모서리로

o는 선택을 시작한 후 반대 방향으로도 확장하고 싶을 때 씁니다.

모드 전환

선택을 유지한 채 모드를 바꿀 수 있습니다. vV로 문자에서 줄로, VCtrl-v로 줄에서 블록으로 바꿀 수 있습니다.

재선택

동작
gv마지막 Visual 선택 영역을 다시 선택

>로 들여쓰기 후 gv로 재선택하면 한 번 더 들여쓸 수 있습니다. gv>gv> 순서입니다.

선택 + 모션

조합결과
v2w2단어 선택
vit태그 안 선택
vi{중괄호 안 선택
vap문단 선택
v$줄 끝까지 선택

Visual 모드에서 선택 영역 조작

영역을 선택한 후 다음 명령을 사용합니다.

기본 조작

동작
d삭제
c변경 (삭제 후 Insert)
y복사

들여쓰기

동작
>한 레벨 들여쓰기
<한 레벨 내어쓰기
3>3레벨 들여쓰기

V로 여러 줄을 선택하고 >를 누르면 한꺼번에 들여쓸 수 있습니다. .으로 반복할 수 있습니다.

대소문자

동작
~대소문자 토글
U전부 대문자
u전부 소문자

정렬과 외부 명령

동작
=자동 정렬 (indentation)
J선택한 줄 합치기
!sort선택 영역을 알파벳 정렬
!sort -n숫자 정렬
!column -t컬럼 정렬 (표 형태)

ex 명령

선택 후 :를 누르면 :'<,'>가 자동 입력됩니다. 선택 범위에 ex 명령을 적용할 수 있습니다.

:'<,'>s/old/new/g " 선택 영역에서 치환
:'<,'>normal A; " 선택한 모든 줄 끝에 ; 추가
:'<,'>normal I// " 선택한 모든 줄 앞에 // 추가

컬럼 편집 심화 (Visual Block)

Ctrl-v로 진입하는 Visual Block 모드는 사각형 영역을 선택합니다. 일반 에디터의 "멀티 커서"와 비슷한 결과를 만들 수 있습니다.

컬럼 선택

Ctrl-v → Visual Block 진입
j/k → 위아래 행 확장
l/h → 좌우 열 확장
$ → 각 줄 끝까지 (줄 길이 달라도 OK)

다중 행 앞에 삽입

여러 줄 앞에 동시에 텍스트를 넣습니다.

1. Ctrl-v → Visual Block 진입
2. jjj → 4줄 선택
3. I → 맨 앞에 Insert
4. // (스페이스) → 입력
5. Esc → 모든 줄에 적용

예: 주석 추가

실행 전: 실행 후:
let a = 1 // let a = 1
let b = 2 // let b = 2
let c = 3 // let c = 3
let d = 4 // let d = 4

다중 행 끝에 추가

1. Ctrl-v → Visual Block 진입
2. jjj → 4줄 선택
3. $ → 각 줄 끝까지 (길이 달라도 OK)
4. A → 끝에 Append
5. ; → 입력
6. Esc → 모든 줄에 적용

컬럼 삭제

선택한 사각형 영역을 통째로 삭제합니다.

1. Ctrl-v → Visual Block 진입
2. jjj → 행 선택
3. ll → 열 확장
4. d → 삭제

예: 들여쓰기 일괄 제거

실행 전: 실행 후:
line 1 line 1
line 2 line 2
line 3 line 3

4칸 공백 위치에 Ctrl-vjjllld.

예: 주석 일괄 제거

실행 전: 실행 후:
// let a = 1 let a = 1
// let b = 2 let b = 2
// let c = 3 let c = 3

// 위에 Ctrl-vjjlld.

컬럼 치환

선택한 사각형 영역을 새로운 텍스트로 교체합니다.

1. Ctrl-v → Visual Block 진입
2. jjj → 행 선택
3. e → 단어 끝까지 열 확장
4. c → 변경
5. newText → 새 텍스트 입력
6. Esc → 모든 줄에 적용

컬럼 문자 교체

선택 영역의 모든 문자를 같은 문자로 바꿉니다.

1. Ctrl-v → 블록 선택
2. r- → 모든 문자를 -로 교체

구분선을 만들거나, 공백을 특정 문자로 채울 때 유용합니다.

컬럼 들여쓰기

1. Ctrl-v → Visual Block 진입
2. jjj → 행 선택
3. > → 들여쓰기
4. gv → 재선택
5. > → 한 레벨 더

또는 Vjjj3>로 3레벨 한 번에 들여쓰기.

컬럼 대소문자

Ctrl-v → 영역 선택 → ~ (토글)
Ctrl-v → 영역 선택 → U (대문자)
Ctrl-v → 영역 선택 → u (소문자)

순차 번호 매기기

g Ctrl-a는 Visual Block으로 선택한 숫자들을 순차적으로 증가시킵니다.

실행 전 (모두 0): 실행 후:
0. item 1. item
0. item 2. item
0. item 3. item
0. item 4. item

방법: Ctrl-vjjj (0들을 선택) → g Ctrl-a.

실전 예제 모음

상황방법
여러 줄 앞에 // 주석Ctrl-vjjjI// Esc
여러 줄 // 주석 제거Ctrl-vjjjlld
여러 줄 끝에 ; 추가Ctrl-vjjj$A;Esc
CSV 특정 컬럼 삭제해당 열에 Ctrl-vGd
변수명 일괄 교체해당 열에 Ctrl-vjjjec → 새 이름 → Esc
여러 줄 들여쓰기Ctrl-vjjj> (또는 Vjjj>)
0부터 순차 번호0을 입력 → 복사해서 여러 줄 → Ctrl-v로 선택 → g Ctrl-a
HTML 속성 일괄 추가태그 뒤에 Ctrl-vjjjA class="new"Esc

검색과 치환

검색

동작
/pattern아래 방향 검색
?pattern위 방향 검색
n다음 결과
N이전 결과
*커서 아래 단어 검색 (아래로)
#커서 아래 단어 검색 (위로)

치환

:s/old/new/ " 현재 줄, 첫 번째만
:s/old/new/g " 현재 줄, 전체
:%s/old/new/g " 파일 전체
:%s/old/new/gc " 파일 전체, 하나씩 확인
:'<,'>s/old/new/g " Visual 선택 영역
:5,20s/old/new/g " 5~20번째 줄

정규식 기초

패턴의미
.아무 문자 1개
.*아무 문자 0개 이상
\d숫자
\w영문/숫자/밑줄
\s공백
^줄 시작
$줄 끝
\(\)캡처 그룹
\1첫 번째 캡처 역참조

예: 순서 뒤집기

:%s/\(\w\+\), \(\w\+\)/\2, \1/g
" "Kim, John" → "John, Kim"

다중 줄 일괄 편집 (ex 명령)

특정 줄 범위나 패턴에 매칭되는 줄에 일괄 명령을 적용합니다.

줄 범위 조작

명령동작
:5,20d5~20줄 삭제
:5,20y5~20줄 복사
:10,20m3010~20줄을 30줄 뒤로 이동
:10,20co3010~20줄을 30줄 뒤에 복사

:g (global)로 패턴 매칭 일괄 실행

:g/pattern/d " pattern 포함 줄 전부 삭제
:v/pattern/d " pattern 미포함 줄 전부 삭제 (v = inverse)
:g/TODO/normal A; " TODO 포함 줄 끝에 ; 추가
:g/^$/d " 빈 줄 전부 삭제
:g/console.log/d " console.log 줄 전부 삭제

:normal로 줄 범위에 Normal 명령 적용

:5,20normal >> " 5~20줄 들여쓰기
:5,20normal I// " 5~20줄 앞에 // 추가
:5,20normal A; " 5~20줄 끝에 ; 추가
:5,20normal dd " 5~20줄 삭제

:g:normal을 조합하면 Vim 안에서 거의 모든 일괄 편집이 가능합니다.

매크로

매크로는 키 입력을 녹화하고 재생하는 기능입니다.

기본 사용법

1. qa → a 레지스터에 녹화 시작
2. (편집 동작) → 원하는 작업 수행
3. q → 녹화 종료
4. @a → 매크로 실행
5. @@ → 마지막 매크로 반복
6. 10@a → 10회 반복 실행

실전 예제: CSV를 SQL INSERT로 변환

원본:

John,30,Seoul
Jane,25,Busan

변환 결과:

INSERT INTO users VALUES ('John', 30, 'Seoul');
INSERT INTO users VALUES ('Jane', 25, 'Busan');

첫 줄에서 매크로를 녹화하고, 나머지 줄에 @a로 적용하면 됩니다.

재귀 매크로

매크로 안에서 자기 자신을 호출할 수도 있습니다.

qaq → a 레지스터 초기화
qa → 녹화 시작
(편집 동작)
j → 다음 줄
@a → 자기 자신 호출
q → 녹화 종료
@a → 실행 (파일 끝까지 반복)

파일 끝에 도달하면 j가 실패해서 자동으로 멈춥니다.

레지스터

Vim은 삭제하거나 복사한 텍스트를 여러 레지스터에 저장합니다.

레지스터이름용도
""무명마지막 d/c/y 결과
"0yank마지막 y 결과만 (d/c 제외)
"1~"9숫자최근 삭제 이력
"+시스템 클립보드OS 복사/붙여넣기
"a~"z이름 지정사용자 지정 저장
"A~"Z이름 추가기존 레지스터에 추가(append)
"_블랙홀삭제해도 어디에도 저장 안 됨
"/검색마지막 검색 패턴
":명령마지막 ex 명령
".입력마지막 Insert 입력

사용법

"ay → a 레지스터에 복사
"ap → a 레지스터에서 붙여넣기
"+y → 시스템 클립보드에 복사
"+p → 시스템 클립보드에서 붙여넣기
"_dd → 줄 삭제하되 레지스터 건드리지 않기
:reg → 모든 레지스터 확인

"0이 유용한 상황: yy로 복사한 후 dd로 다른 줄을 삭제하면, p는 삭제한 줄을 붙여넣습니다. 원래 복사한 줄을 붙여넣으려면 "0p.

마크

파일 내 위치를 북마크처럼 저장합니다.

동작
m{a-z}현재 위치를 로컬 마크로 저장
m{A-Z}현재 위치를 글로벌 마크로 저장 (파일 간 이동 가능)
`a마크 a의 정확한 위치로 이동
'a마크 a가 있는 줄의 처음으로 이동
:marks마크 목록 보기

자동 마크

Vim이 자동으로 설정하는 마크:

마크위치
`.마지막 편집 위치
`"마지막으로 파일을 닫았던 위치
`[마지막 변경/붙여넣기 시작
`]마지막 변경/붙여넣기 끝
''마지막 점프 이전 위치

''(작은따옴표 두 번)는 "아까 있던 곳으로 돌아가기"입니다. 검색이나 G로 이동한 후 원래 위치로 돌아갈 때 씁니다.

윈도우/버퍼/탭

버퍼

열려 있는 파일 목록입니다.

명령동작
:e file파일 열기
:ls열린 버퍼 목록
:bn / :bp다음 / 이전 버퍼
:bd현재 버퍼 닫기
:b{n}n번 버퍼로 이동
:b name이름으로 버퍼 이동 (탭 자동완성)

윈도우

화면을 분할해서 여러 파일을 동시에 봅니다.

명령동작
:split / :sp가로 분할
:vsplit / :vs세로 분할
Ctrl-w h/j/k/l윈도우 간 이동
Ctrl-w =크기 동일하게
Ctrl-w o현재 윈도우만 남기고 닫기
Ctrl-w > / <너비 조절
Ctrl-w + / -높이 조절
Ctrl-w r윈도우 위치 회전

명령동작
:tabnew새 탭
gt / gT다음 / 이전 탭
:tabclose탭 닫기
{n}gtn번 탭으로 이동

접기 (Folding)

코드의 일부를 접어서 숨길 수 있습니다.

동작
zf{motion}접기 생성 (예: zfap 문단 접기)
za접기 토글
zo접기 열기
zc접기 닫기
zR전체 열기
zM전체 닫기
zj다음 접기로 이동
zk이전 접기로 이동

실전 편집 레시피

"이걸 하고 싶은데 어떻게 하지?"라는 상황에 맞춘 단축키 조합입니다.

하고 싶은 것방법
이 단어를 전부 바꾸고 싶다*ciw → 새 단어 → Esc → n. 반복
여러 줄 앞에 주석 추가Ctrl-vjjjI// → Esc
여러 줄 주석 제거Ctrl-vjjjlld
괄호 안 내용만 교체ci(
따옴표 안 내용 복사yi"
태그 안 내용 삭제dit
현재 줄 복제yyp
두 줄 순서 바꾸기ddp
여러 줄 들여쓰기Vjjj> (반복: .)
여러 줄 내어쓰기Vjjj<
선택 영역 정렬V → 선택 → !sort
단어를 대문자로gUiw
줄 전체 대문자로gUU
0~N 순차 번호 매기기0 여러 줄 → Ctrl-v로 선택 → g Ctrl-a
함수 블록 전체 복사여는 {에서 V%y
빈 줄 전부 삭제:g/^$/d
TODO 줄만 남기기:v/TODO/d
console.log 전부 삭제:g/console.log/d
5~20줄에 주석 추가:5,20normal I//

마치며

이 글에서 다룬 것은 모두 Vi/Vim에서 동작하는 보편적인 단축키라서 Neovim, Vim, Vi 어디서든 쓸 수 있어요.

기억할 것은 세 가지예요.

  1. 문법 이해 — 동사 + 명사 조합으로 암기량 줄이기
  2. . 습관화 — 반복 가능한 편집으로 생산성 높이기
  3. Visual Block 익히기 — 멀티 커서 없이 다중 행 편집하기

다음 글에서는 LSP, 터미널, 플러그인, 마우스 활용까지 Neovim만의 단축키를 다뤄요.

나의 Neovim 설정 전체 공개

· 약 5분

이 글은 Neovim 시리즈의 마지막 글이에요.

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

설정 철학

설정은 Lua 기반으로 VimScript 대신 Lua로 모두 작성하고, 모듈화를 위해 기능별로 파일을 분리해서 관리합니다. 최소주의에 따라 꼭 필요한 플러그인만 23개로 유지하며, 일관된 키매핑을 위해 커스텀 keyMapper 유틸리티로 통일했습니다.

디렉토리 구조

~/.config/nvim/
├── init.lua # 진입점 (1줄)
├── lazy-lock.json # 플러그인 버전 고정
└── lua/
├── config/
│ ├── init.lua # config 모듈 진입점
│ ├── globals.lua # 전역 변수 (leader 키 등)
│ ├── options.lua # Neovim 옵션
│ └── keymaps.lua # 글로벌 키매핑
├── plugins/
│ ├── alpha.lua # 시작 화면
│ ├── comment.lua # 주석 토글
│ ├── conform.lua # 코드 포매팅
│ ├── indent-blankline.lua # 들여쓰기 가이드
│ ├── kanagawa.lua # 컬러스킴
│ ├── lsp.lua # LSP 설정
│ ├── lualine.lua # 상태줄
│ ├── neo-tree.lua # 파일 탐색기
│ ├── nvim-autopairs.lua # 자동 괄호
│ ├── nvim-cmp.lua # 자동완성
│ ├── nvim-treesitter.lua # 구문 하이라이팅
│ ├── nvim-ufo.lua # 코드 폴딩
│ ├── render-markdown.lua # 마크다운 렌더링
│ ├── telescope.lua # 퍼지 파인더
│ └── vim-floaterm.lua # 플로팅 터미널
└── utils/
└── keyMapper.lua # 키매핑 헬퍼

핵심은 init.lua가 단 1줄이라는 점입니다.

require("config")

config/init.lua에서 globals, options, keymaps, lazy.nvim 순서로 로드합니다.

핵심 옵션

-- lua/config/options.lua
opt = vim.opt

-- 2칸 탭
opt.tabstop = 2
opt.shiftwidth = 2
opt.softtabstop = 2
opt.expandtab = true
opt.smartindent = true
opt.wrap = false

-- 검색
opt.incsearch = true
opt.ignorecase = true
opt.smartcase = true -- 대문자가 포함되면 대소문자 구분

-- 줄 번호
opt.number = true
opt.relativenumber = true -- 상대 줄 번호 (이동에 유용)

-- 기타
opt.termguicolors = true
opt.signcolumn = "yes"
opt.scrolloff = 10 -- 커서 위아래 10줄 여유
opt.mouse:append("a")

-- 클립보드
opt.clipboard = "unnamedplus" -- y/p가 시스템 클립보드와 자동 동기화

-- 마크다운 전용 설정
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 -- 문법 마커 숨기기
end,
})

relativenumber는 처음에는 어색하지만, 5j, 12k 같은 상대 이동을 할 때 줄 수를 바로 알 수 있어서 매우 편합니다.

시스템 클립보드 연동

기본 Neovim에서 y는 내부 무명 레지스터에만 저장되고 macOS 시스템 클립보드와는 분리돼 있습니다. 시스템 클립보드로 복사하려면 매번 "+y처럼 접두사를 붙여야 하는데, 한글 IME 상태나 tmux 안에서 "(Shift+') 입력이 종종 씹혀서 번거롭습니다.

opt.clipboard = "unnamedplus" 한 줄로 해결됩니다. 비주얼 모드에서 y만 눌러도 macOS 클립보드에 바로 들어가고, 다른 앱에서 Cmd+C 한 내용도 p로 바로 붙여넣어집니다.

LazyVim 배포판에서는 기본값이지만, lazy.nvim만 직접 쓰는 수동 구성에서는 이 한 줄을 빼먹기 쉽습니다.

값 선택

의미
unnamed* 레지스터 (Linux X11의 primary selection)
unnamedplus+ 레지스터 (시스템 클립보드) — 권장

macOS에서는 *+가 실질적으로 같지만, 크로스 플랫폼 호환성 측면에서 unnamedplus가 표준입니다. LazyVim 기본값도 이것.

확인

:set clipboard?

clipboard=unnamedplus가 출력되면 OK.

:checkhealth provider

→ clipboard provider 섹션에 에러가 없어야 합니다.

안 될 때

  • which pbcopy/usr/bin/pbcopy 확인 (macOS 기본 탑재).
  • Neovim 빌드에 클립보드 지원이 있는지: :echo has('clipboard')1.
  • tmux 안에서만 안 되는 경우, ~/.tmux.confset -g set-clipboard on. 다만 macOS 로컬 tmux + pbcopy 조합은 대부분 이 설정 없이도 동작합니다.

keyMapper 유틸리티

모든 키매핑에 일관되게 noremapsilent를 적용하기 위해 만든 헬퍼입니다.

-- lua/utils/keyMapper.lua
local keyMapper = function(from, to, mode, opts)
local options = { noremap = true, silent = true }
mode = mode or "n"

if opts then
options = vim.tbl_extend("force", options, opts)
end

vim.keymap.set(mode, from, to, options)
end

return { mapKey = keyMapper }

사용법:

local mapKey = require("utils.keyMapper").mapKey

mapKey("<leader>e", ":Neotree toggle<cr>") -- Normal 모드 (기본)
mapKey("<", "<gv", "v") -- Visual 모드 지정

전체 키매핑

글로벌 키매핑

동작모드
SpaceLeader 키-
<leader>eNeo-tree 파일 탐색기 토글N
<leader>h검색 하이라이트 제거N
Ctrl-h/j/k/l분할 창 이동N
< / >들여쓰기 유지하며 인덴트V
Ctrl-;플로팅 터미널 토글N

Telescope 키매핑

동작
<leader>ff파일 이름 검색
<leader>fg파일 내용 검색 (grep)
<leader>fb버퍼 목록
<leader>fh도움말 검색

LSP 키매핑

동작
K호버 문서
gd정의로 이동
<leader>ca코드 액션

플러그인 전체 목록 (23개)

핵심

플러그인역할
lazy.nvim플러그인 매니저
telescope.nvim퍼지 파인더 (파일/텍스트/버퍼 검색)
neo-tree.nvim사이드바 파일 탐색기
nvim-cmp자동완성 엔진
nvim-lspconfigLSP 클라이언트 설정
mason.nvim언어 서버/포매터 설치 관리
nvim-treesitter구문 파싱 & 하이라이팅
conform.nvim저장 시 자동 포매팅

자동완성 소스

플러그인소스
cmp-nvim-lspLSP 자동완성
cmp-buffer버퍼 텍스트
cmp-path파일 경로
cmp_luasnip스니펫
LuaSnip스니펫 엔진
friendly-snippetsVS Code 스니펫 모음

UI & 외관

플러그인역할
kanagawa.nvim컬러스킴 (dragon 테마)
lualine.nvim하단 상태줄
alpha-nvim시작 화면 대시보드
nvim-web-devicons파일 아이콘
indent-blankline.nvim들여쓰기 시각 가이드

편집 보조

플러그인역할
Comment.nvimgcc로 주석 토글
nvim-autopairs괄호/따옴표 자동 닫기
nvim-ufoLSP 기반 코드 폴딩
vim-floaterm플로팅 터미널
render-markdown.nvim마크다운 실시간 렌더링

테마: Kanagawa Dragon

Kanagawa의 Dragon 변형을 사용합니다. 일본 전통 색상에서 영감을 받은 다크 테마로, 눈의 피로가 적습니다.

커스터마이징 포인트:

overrides = function(colors)
local theme = colors.theme
return {
-- 플로팅 윈도우 배경 투명화
NormalFloat = { bg = "none" },
FloatBorder = { bg = "none" },
FloatTitle = { bg = "none" },

-- Telescope UI 커스터마이징
TelescopePromptNormal = { bg = theme.ui.bg_p1 },
TelescopeResultsNormal = { fg = theme.ui.fg_dim, bg = theme.ui.bg_m1 },
TelescopePreviewNormal = { bg = theme.ui.bg_dim },

-- 자동완성 팝업
Pmenu = { fg = theme.ui.shade0, bg = theme.ui.bg_p1 },
PmenuSel = { fg = "NONE", bg = theme.ui.bg_p2 },
}
end,
theme = "dragon",

상태줄(lualine)은 Gruvbox 테마를 사용해서 본문과 미묘하게 다른 톤을 줍니다.

마크다운 작성 환경

블로그를 Neovim으로 작성하기 때문에 마크다운 환경을 신경 썼습니다.

마크다운 환경에서는 render-markdown.nvim으로 헤딩, 코드 블록, 테이블, 체크박스를 시각적으로 렌더링하고, 줄 바꿈 활성화를 위해 마크다운 파일에서만 wrap = true로 설정합니다. conceallevel 2**bold** 같은 마커를 숨기고 bold 형태로 표시합니다.

LSP 구성

Mason으로 3개 언어 서버를 관리합니다.

서버언어포매터
lua_lsLuastylua
ts_lsTypeScript/JavaScriptprettierd
goplsGogofmt (내장)

새 언어를 추가하려면:

  1. :Mason에서 언어 서버 설치
  2. lsp.luaensure_installed에 추가
  3. conform.lua에 포매터 추가 (필요 시)

정리

이 설정은 계속 발전 중이에요. Neovim의 장점은 제 워크플로우에 맞게 모든 것을 조정할 수 있다는 점이에요. 처음에는 남의 설정을 복사하더라도, 하나씩 이해하면서 자기 것으로 만들어가는 과정이 중요해요.

가장 좋은 Neovim 설정은 제가 이해하고 있는 설정입니다.

Neovim 고급 활용

· 약 5분

이 글은 Neovim 시리즈의 세 번째 글이에요.

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

플러그인 매니저: lazy.nvim

Neovim 플러그인 매니저 중 가장 인기 있는 것이 lazy.nvim입니다. 지연 로딩(lazy loading)을 기본으로 지원해서 시작 속도가 빠릅니다.

설치 (부트스트랩)

~/.config/nvim/init.lua에 아래 내용을 추가하면 lazy.nvim이 없을 때 자동으로 설치됩니다.

local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not vim.loop.fs_stat(lazypath) then
vim.fn.system({
"git", "clone", "--filter=blob:none",
"https://github.com/folke/lazy.nvim.git",
"--branch=stable", lazypath,
})
end
vim.opt.rtp:prepend(lazypath)

require("lazy").setup("plugins")

마지막 줄의 "plugins"~/.config/nvim/lua/plugins/ 디렉토리를 의미합니다. 이 디렉토리에 파일을 추가하면 자동으로 플러그인이 로드됩니다.

플러그인 추가 방법

lua/plugins/ 안에 파일을 만들고 테이블을 반환하면 됩니다.

-- lua/plugins/example.lua
return {
"작성자/플러그인이름",
config = function()
require("플러그인").setup({
-- 옵션
})
end
}

플러그인 관리: :Lazy

LSP (Language Server Protocol)

LSP는 에디터와 언어 서버 사이의 표준 프로토콜입니다. 코드 자동완성, 정의로 이동, 에러 표시, 리팩토링 등 IDE 기능의 핵심입니다.

구조

Neovim ←→ nvim-lspconfig ←→ Language Server
(lua_ls, gopls, ts_ls, ...)

Mason으로 언어 서버 설치

Mason은 언어 서버, 포매터, 린터를 Neovim 안에서 설치/관리하는 도구입니다.

-- lua/plugins/lsp.lua
return {
{
"williamboman/mason.nvim",
config = function()
require("mason").setup()
end
},
{
"williamboman/mason-lspconfig.nvim",
config = function()
require("mason-lspconfig").setup({
ensure_installed = { "lua_ls", "ts_ls", "gopls" }
})
end
},
{
"neovim/nvim-lspconfig",
config = function()
vim.lsp.enable({ "lua_ls", "ts_ls", "gopls" })

-- LSP 키매핑
vim.keymap.set("n", "K", vim.lsp.buf.hover)
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action)
end
}
}
동작
K커서 위 심볼의 문서 표시
gd정의로 이동
<leader>ca코드 액션 (자동 수정 등)

Mason UI: :Mason (설치된 서버 확인/추가/삭제)

자동완성: nvim-cmp

nvim-cmp는 Neovim의 자동완성 엔진입니다. 여러 소스(LSP, 버퍼, 파일 경로, 스니펫)에서 후보를 가져옵니다.

-- lua/plugins/nvim-cmp.lua
return {
"hrsh7th/nvim-cmp",
dependencies = {
"hrsh7th/cmp-nvim-lsp", -- LSP 소스
"hrsh7th/cmp-buffer", -- 버퍼 텍스트 소스
"hrsh7th/cmp-path", -- 파일 경로 소스
"L3MON4D3/LuaSnip", -- 스니펫 엔진
"saadparwaiz1/cmp_luasnip", -- 스니펫 소스
"rafamadriz/friendly-snippets", -- 스니펫 모음
},
config = function()
local cmp = require("cmp")
local luasnip = require("luasnip")

require("luasnip.loaders.from_vscode").lazy_load()

cmp.setup({
snippet = {
expand = function(args)
luasnip.lsp_expand(args.body)
end,
},
mapping = cmp.mapping.preset.insert({
["<C-Space>"] = cmp.mapping.complete(),
["<CR>"] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping.select_next_item(),
["<S-Tab>"] = cmp.mapping.select_prev_item(),
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "luasnip" },
{ name = "buffer" },
{ name = "path" },
}),
})
end
}

자동완성 키:

동작
Ctrl-Space수동으로 완성 목록 열기
Tab다음 후보
Shift-Tab이전 후보
Enter선택 확정

Treesitter: 구문 하이라이팅

Treesitter는 코드를 파싱해서 정확한 구문 하이라이팅을 제공합니다. 정규식 기반의 기존 하이라이팅보다 훨씬 정확합니다.

-- lua/plugins/nvim-treesitter.lua
return {
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
config = function()
require("nvim-treesitter.configs").setup({
ensure_installed = {
"lua", "go", "javascript", "html",
"markdown", "markdown_inline",
},
highlight = { enable = true },
indent = { enable = true },
})
end
}

새 언어 추가: :TSInstall python

Telescope: 퍼지 파인더

Telescope는 파일, 텍스트, 버퍼, Git 등 모든 것을 검색할 수 있는 퍼지 파인더입니다.

-- lua/plugins/telescope.lua
return {
"nvim-telescope/telescope.nvim",
tag = "0.1.5",
dependencies = { "nvim-lua/plenary.nvim" },
config = function()
local builtin = require("telescope.builtin")
vim.keymap.set("n", "<leader>ff", builtin.find_files)
vim.keymap.set("n", "<leader>fg", builtin.live_grep)
vim.keymap.set("n", "<leader>fb", builtin.buffers)
vim.keymap.set("n", "<leader>fh", builtin.help_tags)
end
}
동작
<leader>ff파일 이름 검색
<leader>fg파일 내용 검색 (grep)
<leader>fb열린 버퍼 목록
<leader>fh도움말 검색

live_grep를 사용하려면 ripgrep이 설치되어 있어야 합니다: brew install ripgrep

파일 탐색기: Neo-tree

-- lua/plugins/neo-tree.lua
return {
"nvim-neo-tree/neo-tree.nvim",
branch = "v3.x",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-tree/nvim-web-devicons",
"MunifTanjim/nui.nvim",
},
}

<leader>e로 사이드바 파일 탐색기를 토글할 수 있습니다. VS Code의 Explorer와 비슷한 역할입니다.

코드 포매팅: conform.nvim

-- lua/plugins/conform.lua
return {
"stevearc/conform.nvim",
config = function()
require("conform").setup({
formatters_by_ft = {
lua = { "stylua" },
javascript = { "prettierd", "prettier", stop_after_first = true },
typescript = { "prettierd", "prettier", stop_after_first = true },
},
format_on_save = {
timeout_ms = 500,
lsp_format = "fallback",
},
})
end
}

파일 저장 시 자동으로 포매팅됩니다. 포매터는 Mason으로 설치할 수 있습니다: :Mason에서 stylua, prettierd를 검색합니다.

추천 플러그인 조합

최소한의 IDE 환경을 위한 추천 조합:

카테고리플러그인역할
플러그인 관리lazy.nvim플러그인 매니저
LSPmason + lspconfig언어 서버
자동완성nvim-cmp코드 완성
구문treesitter하이라이팅
검색telescope퍼지 파인더
파일 탐색neo-tree파일 트리
포매팅conform.nvim자동 포매팅
테마kanagawa / tokyonight / catppuccin컬러스킴

다음 글

이 플러그인들을 실제로 어떻게 조합하고 커스터마이징하는지, 저의 전체 Neovim 설정을 공개할게요.

저의 Neovim 설정 전체 공개

참고 자료

Neovim 중급 활용

· 약 4분

이 글은 Neovim 시리즈의 두 번째 글이에요.

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

텍스트 오브젝트

Vim의 진짜 힘은 동사 + 대상 조합입니다. 텍스트 오브젝트는 "대상"에 해당합니다.

문법

{동사}{범위}{대상}

동사는 d(삭제), c(변경), y(복사), v(선택)이며, 범위는 i(inner, 안쪽), a(around, 바깥 포함)입니다. 대상은 w(단어), ", ', ), }, ], t(태그) 등입니다.

실전 예시

커서가 단어 중간에 있을 때:

명령동작
ciw단어를 지우고 입력 모드 (Change Inner Word)
diw단어 삭제
yiw단어 복사

따옴표 안에 커서가 있을 때:

명령동작
ci"따옴표 안의 내용을 지우고 입력
di"따옴표 안의 내용 삭제
da"따옴표까지 포함해서 삭제

괄호 안에 커서가 있을 때:

명령동작
ci(괄호 안 내용을 변경
da{중괄호를 포함해서 삭제
vi[대괄호 안 내용을 선택

i vs a의 차이

print("hello world")

커서가 hello 위에 있을 때:

  • di"print("") (따옴표 안 내용만 삭제)
  • da"print() (따옴표까지 삭제)

텍스트 오브젝트를 익히면 편집 속도가 비약적으로 올라갑니다.

버퍼, 윈도우, 탭

버퍼

파일을 열면 버퍼에 로드됩니다. 여러 파일을 동시에 열어둘 수 있습니다.

:e file1.lua 파일 열기 (새 버퍼)
:ls 열린 버퍼 목록
:bn 다음 버퍼
:bp 이전 버퍼
:bd 버퍼 닫기
:b {숫자} 해당 번호 버퍼로 이동

윈도우 (분할)

화면을 분할해서 여러 버퍼를 동시에 볼 수 있습니다.

:split 가로 분할 (또는 Ctrl-w s)
:vsplit 세로 분할 (또는 Ctrl-w v)
Ctrl-w h/j/k/l 분할 창 간 이동
Ctrl-w = 분할 창 크기 균등화
:close 현재 창 닫기

여러 윈도우 레이아웃을 탭으로 관리할 수 있습니다.

:tabnew 새 탭
:tabn 다음 탭 (또는 gt)
:tabp 이전 탭 (또는 gT)
:tabclose 탭 닫기

실무 팁: 버퍼 + 윈도우 분할을 주로 쓰고, 탭은 맥락이 완전히 다른 작업을 분리할 때 쓰면 좋습니다.

매크로

반복 작업을 녹화해서 재생하는 기능입니다.

기본 사용법

  1. q{레지스터}: 녹화 시작 (예: qa)
  2. 원하는 작업 수행
  3. q: 녹화 중지
  4. @{레지스터}: 재생 (예: @a)
  5. @@: 마지막 매크로 재생
  6. {숫자}@a: N번 반복 재생

실전 예시

모든 줄 끝에 세미콜론을 추가하고 싶다면:

qa q 레지스터에 녹화 시작
A; 줄 끝에 ; 추가
Esc Normal 모드로
j 다음 줄로
q 녹화 중지
99@a 99번 반복

레지스터

Vim의 복사/붙여넣기는 레지스터라는 저장소를 사용합니다. 클립보드가 여러 개 있는 것과 같습니다.

주요 레지스터

레지스터설명
""기본 레지스터 (마지막 yank/delete)
"0yank 전용 레지스터
"+시스템 클립보드
"a ~ "z이름 지정 레지스터
"_블랙홀 레지스터 (버리기)

사용법

"ay a 레지스터에 복사
"ap a 레지스터에서 붙여넣기
"+y 시스템 클립보드에 복사
"+p 시스템 클립보드에서 붙여넣기
"_dd 줄을 삭제하되 레지스터에 저장하지 않음

레지스터 확인: :reg

: dd로 줄을 지우면 기본 레지스터가 덮어씌워집니다. 복사한 내용을 유지하려면 "0p(yank 레지스터)를 쓰거나, 삭제 시 "_dd(블랙홀)를 쓰면 됩니다.

Marks

특정 위치를 북마크해두고 바로 이동할 수 있습니다.

ma 현재 위치를 a 마크로 저장
'a a 마크의 줄로 이동
`a a 마크의 정확한 위치로 이동
:marks 모든 마크 목록
  • 소문자(a-z): 파일 내 마크
  • 대문자(A-Z): 파일 간 글로벌 마크

비주얼 블록 모드

Ctrl-v로 사각형 영역을 선택할 수 있습니다. 여러 줄을 동시에 편집할 때 유용합니다.

여러 줄 앞에 텍스트 추가

1. Ctrl-v 블록 선택 시작
2. j/k로 줄 선택
3. I 줄 앞에 입력 모드
4. 텍스트 입력
5. Esc 모든 선택된 줄에 적용

여러 줄 뒤에 텍스트 추가

1. Ctrl-v 블록 선택 시작
2. j/k로 줄 선택
3. $ 줄 끝까지 선택 확장
4. A 줄 뒤에 입력 모드
5. 텍스트 입력
6. Esc 적용

내장 터미널

Neovim 안에서 터미널을 열 수 있습니다.

:terminal 터미널 열기

터미널에서 Normal 모드로 전환: Ctrl-\ Ctrl-n

저는 내장 터미널 대신 vim-floaterm 플러그인을 사용해요. Ctrl-;로 플로팅 터미널을 토글할 수 있어서 더 편해요.

기본 설정 시작하기

Neovim 설정 파일은 ~/.config/nvim/init.lua입니다. 간단한 설정부터 시작합니다.

-- 줄 번호 표시
vim.opt.number = true
vim.opt.relativenumber = true

-- 탭 설정 (2칸)
vim.opt.tabstop = 2
vim.opt.shiftwidth = 2
vim.opt.expandtab = true

-- 검색 설정
vim.opt.ignorecase = true
vim.opt.smartcase = true
vim.opt.incsearch = true

-- 스크롤 여유
vim.opt.scrolloff = 10

-- 마우스 지원
vim.opt.mouse:append("a")

이 정도만 설정해도 기본 Neovim보다 훨씬 쾌적해집니다.

다음 글

기본기가 탄탄해졌다면, 플러그인과 LSP를 설정해서 Neovim을 IDE처럼 사용하는 방법을 알아봐요.

Neovim 고급: 플러그인과 LSP로 IDE처럼 쓰기

참고 자료

Neovim 입문

· 약 4분

이 글은 Neovim 시리즈의 첫 번째 글이에요.

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

Neovim이란?

Neovim은 Vim의 모던 포크(fork)입니다. Vim의 철학(모달 편집, 키보드 중심)을 유지하면서 내부를 현대적으로 재구성했습니다.

Vim과 뭐가 다른가?

VimNeovim
설정 언어VimScriptLua (VimScript도 지원)
비동기 처리제한적내장
내장 LSP없음있음
내장 터미널기본적완전한 터미널 에뮬레이터
플러그인 생태계성숙빠르게 성장 중
설정 파일~/.vimrc~/.config/nvim/init.lua

한 줄로 요약하면 Vim의 편집 철학 + 현대적인 확장성입니다.

설치

macOS

brew install neovim

Rocky Linux / CentOS

# EPEL에서 설치
dnf install -y epel-release
dnf install -y neovim

Ubuntu / Debian

apt install -y neovim

설치 확인:

nvim --version

4가지 모드

Neovim(Vim)이 다른 에디터와 결정적으로 다른 점은 모드가 있다는 것입니다.

Normal 모드

Neovim을 열면 이 모드입니다. 글을 쓰는 게 아니라 글을 조작하는 모드입니다.

  • 커서 이동, 삭제, 복사, 붙여넣기 등
  • 다른 모드에서 Esc를 누르면 항상 Normal로 돌아옵니다

Insert 모드

실제로 글을 타이핑하는 모드입니다.

동작
i커서 앞에 입력
a커서 뒤에 입력
I줄 맨 앞에 입력
A줄 맨 뒤에 입력
o아래에 새 줄 만들고 입력
O위에 새 줄 만들고 입력

Visual 모드

텍스트를 선택하는 모드입니다.

동작
v문자 단위 선택
V줄 단위 선택
Ctrl-v블록(사각형) 선택

Command 모드

:를 누르면 하단에 명령줄이 나타납니다.

:w 저장
:q 종료
:wq 저장 후 종료
:q! 저장하지 않고 종료

커서 이동

Normal 모드에서의 이동이 Vim의 핵심입니다. 처음에는 어색하지만 손에 익으면 마우스보다 빠릅니다.

기본 이동

k
h l
j
방향
h← 왼쪽
j↓ 아래
k↑ 위
l→ 오른쪽

: j의 아래쪽 꼬리를 생각하면 기억하기 쉽습니다.

단어 단위 이동

동작
w다음 단어 시작
b이전 단어 시작
e단어 끝

줄 이동

동작
0줄 맨 앞
$줄 맨 끝
^줄의 첫 글자 (공백 제외)

화면/파일 이동

동작
gg파일 맨 위
G파일 맨 아래
Ctrl-d반 페이지 아래
Ctrl-u반 페이지 위
{숫자}G해당 줄로 이동 (예: 42G)

기본 편집

삭제

동작
x커서 위 문자 삭제
dd줄 삭제
dw단어 삭제
d$ 또는 D커서부터 줄 끝까지 삭제

복사 & 붙여넣기

동작
yy줄 복사 (yank)
yw단어 복사
p커서 뒤에 붙여넣기
P커서 앞에 붙여넣기

실행 취소 & 다시 실행

동작
u실행 취소 (Undo)
Ctrl-r다시 실행 (Redo)

검색과 치환

검색

/검색어 아래 방향으로 검색
?검색어 위 방향으로 검색
n 다음 결과
N 이전 결과

치환

:s/old/new/ 현재 줄에서 첫 번째만
:s/old/new/g 현재 줄에서 모두
:%s/old/new/g 파일 전체에서 모두
:%s/old/new/gc 파일 전체, 하나씩 확인하며

파일 열기

# 터미널에서
nvim filename.txt

# Neovim 안에서
:e filename.txt
:e . 현재 디렉토리 탐색

숫자 + 명령 조합

Vim의 강력한 문법: 숫자 + 동작으로 반복할 수 있습니다.

5j 5줄 아래로
3dd 3줄 삭제
4w 4단어 앞으로
10G 10번째 줄로
2yy 2줄 복사

vimtutor로 연습하기

Neovim에는 대화형 튜토리얼이 내장되어 있습니다.

nvim +Tutor

30분 정도 따라 하면 기본 조작이 손에 익습니다. 처음 Neovim을 설치했다면 반드시 한 번은 해보세요.

다음 글

기본 조작이 익숙해졌다면 텍스트 오브젝트, 매크로, 레지스터 등 생산성을 끌어올리는 기능을 알아봐요.

Neovim 중급: 생산성을 높이는 기능들

참고 자료