본문으로 건너뛰기

PostgreSQL 19 새 기능 총정리

· 약 6분
2026-09-28 업데이트

2026-09-24 PostgreSQL 19 Beta 4 공지에서 이 글이 소개한 기능 일부가 revert됐습니다. 파티션 MERGE/SPLIT, SQL/PGQ가 여기에 해당합니다. 공지에는 이 밖에 online data checksums, FOR PORTION OF, pg_get_role_ddl() 등 DDL 함수의 revert와 제거도 있습니다. GROUP BY ALL은 그보다 앞서 Beta 3 이전에 revert됐습니다. 공지 기준 GA 예상 시점도 10월로 바뀌었습니다. 경위와 컨테이너 비교 결과는 PG19 Beta 4 기능 철회에 정리했습니다.

PostgreSQL 19 개요​

PostgreSQL 19는 2026년 9월 출시 예정이에요. 기능 동결(Feature Freeze)은 4월 8일에 완료되었고, 5월에 첫 번째 베타가 나올 예정이에요.

PostgreSQL 18이 비동기 I/O, UUIDv7, 가상 생성 컬럼 같은 굵직한 기능을 가져왔다면, PostgreSQL 19는 기존 기능의 실질적 개선과 성능 최적화에 집중하는 릴리즈입니다. 화려하진 않지만 실무에서 체감할 수 있는 변화가 많습니다.

이 글은 2026년 4월 기준으로 작성되었으며, 정식 출시 전까지 일부 내용이 변경될 수 있습니다.

업데이트: 첫 베타(Beta 1)는 2026-06-04에 나왔습니다. 아래 GROUP BY ALL은 Beta 3에서 revert되어 최종 릴리스에서 빠졌습니다.

쿼리 플래너 & 실행​

GROUP BY ALL​

SELECT department, role, COUNT(*)
FROM employees
GROUP BY ALL;

GROUP BY ALL을 쓰면 집계 함수가 아닌 SELECT 표현식을 자동으로 GROUP BY에 포함합니다. 컬럼 5개를 일일이 나열할 필요가 없어졌습니다.

Eager Aggregation​

대용량 테이블을 조인하기 전에 먼저 집계하는 최적화입니다. enable_eager_aggregate 파라미터로 제어합니다.

-- 플래너가 자동으로 orders를 먼저 집계한 후 customers와 조인
SELECT c.name, SUM(o.amount)
FROM customers c JOIN orders o ON c.id = o.customer_id
GROUP BY c.name;

조인 대상 행 수가 줄어들기 때문에 대용량 분석 쿼리에서 성능이 크게 개선될 수 있습니다.

COUNT() 자동 최적화​

COUNT(1), COUNT(not_null_col)을 자동으로 COUNT(*)로 변환합니다. 습관적으로 COUNT(1)을 쓰던 사람들에게는 반가운 변화입니다.

병렬 TID Range Scan​

TID Range Scan이 병렬 실행을 지원합니다. 대규모 테이블에서 특정 범위의 물리적 행을 빠르게 스캔할 수 있습니다.

Incremental Sort 확장​

Append/MergeAppend 노드 내에서도 Incremental Sort가 가능해졌습니다. 파티션 테이블의 정렬 성능이 개선됩니다.

EXPLAIN ANALYZE 타이밍 오버헤드 감소​

x86-64 CPU에서 RDTSC 명령어를 활용해 시간 측정 오버헤드를 약 38% 줄였습니다. 이 주제는 별도 포스트에서 상세히 다룹니다.

윈도우 함수 개선​

IGNORE NULLS / RESPECT NULLS​

lag, lead, first_value, last_value, nth_value에서 NULL 처리 방식 지정을 지원합니다.

SELECT
ts,
value,
last_value(value) IGNORE NULLS OVER (ORDER BY ts) AS last_non_null
FROM sensor_data;

시계열 데이터에서 NULL 값을 건너뛰고 마지막 유효 값을 가져오는 패턴이 훨씬 간결해졌습니다. 이전에는 서브쿼리나 래터럴 조인이 필요했습니다.

파티셔닝​

MERGE / SPLIT PARTITIONS​

-- 파티션 병합
ALTER TABLE bookings MERGE PARTITIONS (p_2024_q1, p_2024_q2) INTO p_2024_h1;

-- 파티션 분할
ALTER TABLE bookings SPLIT PARTITION p_2024 INTO
(PARTITION p_2024_h1 FOR VALUES FROM ('2024-01-01') TO ('2024-07-01'),
PARTITION p_2024_h2 FOR VALUES FROM ('2024-07-01') TO ('2025-01-01'));

파티션을 병합하거나 분할하는 DDL이 추가되었습니다. 기존에는 새 파티션을 만들고 데이터를 이동한 뒤 기존 파티션을 삭제해야 했습니다.

COPY TO with Partitioned Tables​

파티션 테이블에서 직접 COPY TO가 가능해졌습니다. 이전에는 각 파티션을 개별적으로 복사해야 했습니다.

논리 복제 (Logical Replication)​

WAL 레벨 동적 조정​

서버 재시작 없이 WAL 레벨 변경을 지원합니다. effective_wal_level 읽기 전용 파라미터로 현재 상태를 확인합니다.

이전에는 wal_level = logical 설정 변경 후 반드시 재시작이 필요했습니다. 운영 중인 시스템에서 논리 복제를 활성화할 때 다운타임을 줄일 수 있습니다.

시퀀스 복제​

논리 복제에서 시퀀스 값 동기화를 지원합니다.

ALTER SUBSCRIPTION my_sub REFRESH SEQUENCES;

WAIT FOR LSN​

레플리카가 특정 LSN까지 동기화될 때까지 대기하는 메커니즘입니다. 읽기 일관성이 필요한 경우에 유용합니다.

동기화 모니터링​

pg_replication_slots에 slotsync_skip_reason 컬럼이 추가되어 슬롯 동기화 지연 원인을 파악하기 쉬워졌습니다.

성능 최적화​

jsonb_agg 성능 향상​

jsonb_agg 함수의 성능이 50% 이상 개선되었습니다. JSON 집계가 많은 API 백엔드에는 반가운 변화입니다.

LISTEN/NOTIFY 최적화​

채널별 해시 테이블 기반으로 처리 방식이 변경되어, 많은 채널을 사용하는 환경에서 성능이 개선됩니다.

ICU 문자 변환 최적화​

UTF-8 데이터베이스에서 ICU 문자 변환 함수의 성능이 향상되었습니다.

Buffer Cache 알고리즘 변경​

Free buffer list를 Clock-sweep 알고리즘으로 교체했습니다.

Temporary Table 트렁케이션 고속화​

임시 테이블 truncation 처리가 빨라졌습니다.

모니터링 & 관찰성​

pg_stat_statements 확장​

  • Generic/Custom 플랜별 호출 횟수 추적
  • FETCH 명령어 정규화
  • IN 절 파라미터 리스트 정규화

VACUUM / ANALYZE 진행 상황​

  • mode, started_by 컬럼 추가로 수동/자동 실행 구분 가능
  • VACUUM VERBOSE에서 메모리 사용량 표시
  • vacuumdb --dry-run 옵션 추가
  • log_autoanalyze_min_duration 신규 파라미터로 ANALYZE 로깅 분리

pg_buffercache 확장​

pg_buffercache_os_pages가 OS 페이지 분포를 보여줍니다.

WAL 모니터링​

wal_fpi_bytes로 Full Page Image 바이트를 추적합니다.

멀티트랜잭션 통계​

pg_get_multixact_stats() 함수가 멀티트랜잭션 사용 현황을 보여줍니다.

SQL & 함수​

random() 날짜/시간 생성​

SELECT random('2024-01-01'::date, '2024-12-31'::date);

지정 범위 내 랜덤 날짜/시간을 생성합니다. 테스트 데이터 생성이 간편해졌습니다.

base64url 인코딩​

encode/decode 함수에서 URL-safe한 base64url 포맷을 지원합니다.

error_on_null()​

NULL 값 검증 함수가 추가되었습니다. NULL이 들어오면 에러를 발생시킵니다.

SRF(Set-Returning Function) 인라인​

Set-returning 함수의 인라인 최적화가 지원됩니다.

관리 & 도구​

regdatabase 타입​

데이터베이스 이름과 OID를 상호 변환하는 새 객체 식별자 타입입니다.

CHECKPOINT 개선​

FLUSH_UNLOGGED, MODE 파라미터가 추가되었습니다.

pg_upgrade 대용량 객체 최적화​

대용량 객체(Large Object) 마이그레이션이 빨라졌습니다.

psql 개선​

  • %S 프롬프트 옵션으로 검색 경로 표시
  • boolean 값 표시 커스터마이징 (\pset display_true)

pgbench​

--continue-on-error 옵션으로 에러 발생 시에도 벤치마크를 계속 진행합니다.

그래프 쿼리 (SQL/PGQ)​

PostgreSQL 19는 SQL:2023 Part 16(SQL/PGQ) 을 코어에 들였습니다. 관계형 테이블 위에 프로퍼티 그래프 뷰를 얹고, GRAPH_TABLE과 MATCH 구문으로 그래프 패턴 매칭을 표준 SQL 안에서 풉니다. 별도 그래프 DB나 확장 없이 PostgreSQL만으로 일부 그래프 워크로드를 받아낼 수 있게 되었습니다.

첫 구현은 고정 깊이 패턴까지입니다. 가변 길이 경로는 다음 릴리스의 1차 후보입니다. 이 주제는 분량이 커서 별도 포스트에서 상세히 다룹니다.

호환성 주의​

standard_conforming_strings 비활성화 불가​

이제 standard_conforming_strings를 off로 설정할 수 없습니다. 비표준 문자열 리터럴(\' 등)은 에러를 발생시킵니다. escape_string_warning 파라미터도 제거되었습니다.

기존에 E'...' 없이 역슬래시 이스케이프를 쓰던 레거시 코드가 있다면 확인이 필요합니다.

log_lock_waits 기본값 변경​

log_lock_waits가 기본적으로 활성화됩니다. 잠금 대기 로그가 자동으로 남습니다.

마무리​

PostgreSQL 19는 눈에 띄는 신기능보다는 기존 기능의 완성도를 높이는 릴리즈입니다.

제가 개인적으로 주목하는 기능은 분석 쿼리 성능에 직접 영향을 주는 Eager Aggregation과 운영 중 논리 복제 활성화를 편하게 해주는 WAL 레벨 동적 조정이에요. IGNORE NULLS는 시계열 처리를 깔끔하게 해주고, 표준 그래프 쿼리를 코어에 들인 SQL/PGQ도 눈에 들어와요. EXPLAIN ANALYZE RDTSC는 다음 글에서, SQL/PGQ는 후속편에서 상세히 다룹니다.

2026년 9월 정식 출시가 기대되고, 5월 베타부터 미리 테스트해볼 수 있어요.

참고 자료​

Claude Code Routines

· 약 5분

또 나왔다​

Anthropic이 자꾸 뭔가를 내놓네요.

Claude Code 데스크톱 앱이 나왔나 싶더니, 이번엔 Routines라는 기능이 2026년 4월 14일에 리서치 프리뷰로 공개됐습니다. Claude Code에서 프롬프트를 한 번 짜두면, 정해진 시간에 혹은 특정 이벤트가 발생할 때 알아서 실행되는 자동화 기능입니다.

쉽게 말하면 "AI cron job"입니다.

주의: 이 글에서 다루는 내용은 전부 리서치 프리뷰 기준입니다. API, 실행 한도, 동작 방식 모두 정식 출시 전에 바뀔 수 있습니다. "오 좋은데?" 하고 프로덕션에 넣었다가 다음 달에 스펙이 바뀌면 본인 책임입니다.

Routines가 뭔데​

루틴은 Claude에게 시킬 작업을 담은 프롬프트, 작업 대상 코드베이스인 GitHub 저장소, Slack, Linear, Google Drive 같은 외부 서비스를 잇는 MCP 커넥터를 하나로 묶습니다.

이걸 한 번 설정하면 Anthropic 클라우드 VM에서 실행됩니다. 제 노트북이 꺼져 있어도 돌아갑니다. 퇴근하고 자는 동안에도 돌아갑니다.

어떻게 실행되나​

트리거는 세 종류입니다.

트리거설명
Schedule시간별, 일별, 주별 반복. cron 표현식 지원. 최소 간격 1시간
APIHTTP POST로 외부 시스템이 호출. Bearer 토큰 인증
GitHub 이벤트PR 열림/닫힘, 릴리즈 생성 등에 반응

하나의 루틴에 여러 트리거를 동시에 걸 수 있습니다. 예를 들면:

  • 매일 밤 11시 + PR 열릴 때 + Sentry 알림 API 호출 → 같은 루틴이 세 가지 상황에서 모두 실행

여러 트리거가 하나의 Routine을 클라우드에서 실행하는 흐름

활용 예시​

  • 매일 밤 이슈 트래커를 읽어서 라벨 붙이고 Slack에 요약 보고
  • PR 열릴 때 팀 코드 리뷰 체크리스트 자동 적용
  • 에러 알림 임계값 초과 시 수정 PR 초안 자동 생성
  • 배포 후 스모크 테스트 자동 실행
  • 주간 스캔으로 API 변경 사항을 반영한 문서 업데이트 PR 생성

꽤 그럴듯합니다. 그럴듯한데, 아직 베타입니다. 잊지 말아야 합니다.

요금은​

플랜월 비용일일 실행 횟수
Pro$205회
Max$100~20015회
Team / Enterprise별도25회
Free-불가
  • 루틴 실행은 기존 구독 사용량에 포함됩니다
  • "Extra Usage" 활성화 시 한도 초과분은 추가 과금으로 계속 실행됩니다
  • Free 플랜은 사용할 수 없습니다

하루 5회가 많아 보이지 않을 수 있지만, 잘 설계된 루틴 하나가 수동 작업 30분을 대체한다면 충분할 수도 있습니다.

ChatGPT Tasks랑 뭐가 다른데​

이런 기능이라면 ChatGPT Tasks가 먼저 떠오릅니다. 근데 성격이 꽤 다릅니다.

Claude RoutinesChatGPT Tasks
실행 방식자율 코드 실행 (커밋, PR 생성까지)알림/리마인더 전달
트리거스케줄 + API + GitHub 이벤트스케줄만
개발자 연동GitHub, Slack, Linear, MCP없음
실제 작업 수행수행미수행(사용자가 직접)

ChatGPT Tasks는 "내일 아침에 이거 확인해"라고 알려주는 알람 앱입니다. Claude Routines는 "내일 아침에 이거 확인하고 PR까지 만들어놓을게"라고 하는 자동화 에이전트입니다.

방향 자체가 다릅니다.

좋은 점​

알림만 보내는 데 그치지 않고 코드 수정, PR 생성, Slack 메시지까지 실제로 수행하는 진짜 자동화입니다. 스케줄, API, GitHub 이벤트를 하나의 루틴에 동시에 설정하는 다중 트리거도 지원합니다. 클라우드 실행이라 로컬 머신에 의존하지 않습니다. 퇴근해도 돌아갑니다. MCP 커넥터에는 Slack, Linear, Google Drive 등 외부 서비스 연동 기능이 내장되어 있습니다.

우려되는 점​

여기서부터가 진짜 중요합니다.

리서치 프리뷰라는 것​

정식 출시가 아닙니다. API 스펙, 실행 한도, 트리거 동작 방식 전부 바뀔 수 있습니다. Anthropic도 공식 문서에서 이 점을 명시하고 있습니다. 프로덕션 워크플로우에 넣기에는 이릅니다.

개인 계정에 묶인다​

루틴은 개인 claude.ai 계정에 귀속됩니다. 팀원과 공유할 수 없고, 루틴이 만든 커밋/PR은 해당 개인 이름으로 찍힙니다. 팀 단위 운영이 어렵습니다.

보안 이슈​

자율 실행 중 문서에 숨겨진 악성 지시를 따를 수 있는 프롬프트 인젝션 위험이 있습니다. Anthropic 자체 보고로 공격 성공률은 ~1%입니다. CVE 2건도 보고됐습니다. RCE 취약점(CVE-2025-59536)과 API 키 유출(CVE-2026-21852)입니다. 데이터 학습의 경우 Pro/Max 플랜은 AI 학습을 위한 데이터 사용이 기본 ON이고, Enterprise만 OFF입니다.

벤더 락인​

루틴 설정이 Anthropic 클라우드에 저장됩니다. git에 백업되지 않습니다. 나중에 다른 도구로 갈아타고 싶어도 이식할 방법이 없습니다.

사내에서 쓸 수 있을까​

솔직히 말하면, 지금 당장 프로덕션에 넣기는 이르다고 봐요.

가능한 부분​

  • Team/Enterprise 플랜에서 사용 가능
  • SOC 2 Type 2, ISO 27001 인증 있음
  • Enterprise는 클라우드 세션 감사 로그 지원
  • 네트워크 프록시로 개인 계정 차단 가능 (Enterprise)

아직 안 되는 부분​

이슈상세
리서치 프리뷰API 안정성 미보장
감사 로그 공백Cowork 모드 활동은 감사 로그에서 제외
개인 계정 귀속팀 루틴 공유 불가, 변경 추적 곤란
사용자 권한 제어세일즈 별도 문의 필요
PII/금융 데이터규제 대상 코드에 사용 부적합

현실적 접근법​

먼저 Team 플랜으로 파일럿을 진행합니다. 비규제, 비프로덕션 환경에서 테스트하는 방식입니다.

MCP 커넥터는 제한해야 합니다. 읽기 전용이면서 관리자가 승인한 것만 허용합니다.

정식 출시를 기다리는 방법도 있습니다. GA 후 Enterprise 세일즈와 감사 로그/권한 제어를 확인합니다.

규제 데이터는 금지합니다. PII, 금융, 의료 데이터에는 절대 사용하지 않습니다.

마무리​

Anthropic이 정말 쉬지 않고 무언가를 내놓고 있습니다. Subagents가 나왔나 싶더니 Agent Teams가 나오고, 이제는 Routines까지 나왔습니다. 따라가는 것만으로도 바쁩니다.

Routines의 컨셉 자체는 매력적입니다. "AI가 밤새 일한다"는 말이 과장이 아닌 시대가 정말 오고 있습니다. 하지만 지금은 리서치 프리뷰입니다. 흥미롭게 지켜보되, 프로덕션에 넣는 것은 아직 참아야 합니다.

한 가지 확실한 건, AI 도구의 변화 속도가 이전과는 차원이 다르다는 거예요. 정신 차리고 따라가야 해요. 아니면 어느 날 제 자리에서 루틴이 일하고 있을지도 모르겠어요.

이 글의 내용은 2026년 4월 16일 기준 리서치 프리뷰 상태를 바탕으로 작성되었습니다. 정식 출시 후 기능, 요금, 제한 사항이 달라질 수 있습니다.

참고 자료​

Claude Code 고급 단축키

· 약 4분

여기까지 왔다면​

1편에서 필수 단축키를, 2편에서 Vim 모드를 다뤘어요. 3편에서는 키 바인딩 커스터마이징과 특정 화면에서만 쓰는 세부 컨텍스트 단축키를 정리해요.

이 시리즈는 3편으로 구성됩니다.

키 바인딩 커스터마이징​

설정 파일 열기​

Claude Code 안에서 /keybindings를 입력하면 ~/.claude/keybindings.json 파일이 열립니다. 없으면 자동 생성됩니다. 변경 사항은 재시작 없이 즉시 적용됩니다.

설정 형식​

[
{
"key": "ctrl+enter",
"command": "chat:submit",
"when": "Chat"
},
{
"key": "ctrl+shift+k",
"command": "chat:clearInput",
"when": "Global"
}
]
  • key: 키 조합 (ctrl, alt, shift, meta + 키)
  • command: namespace:action 형식의 액션 이름
  • when: 적용 컨텍스트

바인딩 해제​

특정 단축키를 비활성화하려면 command를 null로 설정합니다.

[
{
"key": "ctrl+s",
"command": null,
"when": "Chat"
}
]

사용 가능한 컨텍스트​

컨텍스트설명
Global어디서나 동작
Chat채팅 입력 중
Autocomplete자동완성 메뉴
Confirmation확인/권한 다이얼로그
Settings설정 화면
Help도움말 화면
Transcript트랜스크립트 뷰어
HistorySearch히스토리 검색 모드
Tabs탭 내비게이션
Attachments이미지 첨부
Footer하단 바
MessageSelector메시지 선택 (되감기)
DiffDialog디프 뷰어
ModelPicker모델 선택
Scroll스크롤 모드
Plugin플러그인 관리자
Doctor/doctor 화면
ThemePicker테마 선택

바인딩 불가 키​

다음 키는 터미널 수준에서 예약되어 있어 변경할 수 없습니다.

키이유
Ctrl+C인터럽트 시그널 (하드코딩)
Ctrl+DEOF 시그널 (하드코딩)
Ctrl+MEnter와 동일 (터미널에서 둘 다 CR 전송)

설정 검증​

/doctor

키 바인딩 설정에 문제가 있으면 /doctor에서 확인합니다.

트랜스크립트 뷰어​

Ctrl+O로 트랜스크립트 뷰어를 열면, Claude가 어떤 도구를 실행했는지 상세하게 보입니다. MCP 호출 내용도 여기서 확인 가능합니다.

단축키기능
Ctrl+E전체 내용 펼치기/접기
/검색 모드 진입
n다음 검색 결과
N이전 검색 결과
q, Ctrl+C, Esc뷰어 닫기

풀스크린 모드에서 Ctrl+O를 반복하면 normal → transcript → focus view 순서로 전환됩니다.

디프 뷰어​

Claude가 파일을 수정했을 때 나오는 디프 화면에서 쓸 수 있는 키입니다.

단축키기능
Esc디프 뷰어 닫기
← / →이전/다음 디프 소스
↑ / ↓이전/다음 파일
Enter디프 상세 보기

되감기 / 요약 (메시지 선택)​

Esc × 2로 진입하는 메시지 선택 화면의 단축키입니다.

단축키기능
↑, K, Ctrl+P위로 이동
↓, J, Ctrl+N아래로 이동
Shift+K, Ctrl+↑맨 위로 점프
Shift+J, Ctrl+↓맨 아래로 점프
Enter메시지 선택

Vim 스타일의 J/K 이동도 지원하는 점이 눈에 띕니다.

스크롤 / 풀스크린 모드​

풀스크린 렌더링이 활성화된 상태에서 사용 가능합니다.

단축키기능
PageUp반 화면 위로 스크롤
PageDown반 화면 아래로 스크롤
Ctrl+Home대화 맨 처음으로
Ctrl+End최신 메시지로 (자동 따라가기 재활성화)
Ctrl+Shift+C / Cmd+C선택한 텍스트 클립보드에 복사
마우스 휠한 줄씩 스크롤

이미지 첨부 내비게이션​

이미지를 여러 장 붙여넣은 후 관리할 때 씁니다.

단축키기능
→다음 첨부
←이전 첨부
Backspace / Delete선택한 첨부 삭제
↓ 또는 Esc첨부 내비게이션 종료

PR 상태, 태스크 등이 표시되는 하단 바에서 쓸 수 있는 키입니다.

단축키기능
← / →항목 이동
↑ / ↓위/아래 탐색
Enter선택한 항목 열기
Esc선택 해제
Cmd+클릭 (Mac)PR 링크를 브라우저에서 열기

설정 화면​

/config로 진입하는 설정 화면의 단축키입니다.

단축키기능
/검색 모드
R사용량 데이터 다시 로드
Enter저장 후 닫기
Esc변경사항 버리고 닫기

모델 선택​

Option+P로 모델 선택 화면에 진입하면 다음 단축키가 동작합니다.

단축키기능
←추론 강도(effort) 낮추기
→추론 강도 높이기

플러그인 관리자​

단축키기능
Space플러그인 선택/해제
I선택한 플러그인 설치

터미널 멀티플렉서 충돌​

tmux나 screen을 쓰고 있다면 일부 단축키가 충돌할 수 있습니다.

단축키충돌 대상해결법
Ctrl+Btmux 프리픽스두 번 눌러서 Claude Code로 전달
Ctrl+AGNU screen 프리픽스두 번 눌러서 전달
Ctrl+ZUnix 프로세스 일시정지 (SIGTSTP)의도치 않게 누르지 않도록 주의

tmux 사용자는 Ctrl+B를 백그라운드 전환에 쓸 때 항상 두 번 눌러야 한다는 것만 기억하면 됩니다.

한눈에 보기: 커스터마이징 요약​

[키 바인딩]
/keybindings .... 설정 파일 열기
/doctor ......... 설정 검증
재시작 불필요 .... 변경 즉시 적용

[트랜스크립트 뷰어] (Ctrl+O)
/ ............... 검색
n / N ........... 다음/이전 결과
Ctrl+E .......... 전체 펼치기
q ............... 닫기

[디프 뷰어]
← / → .......... 디프 소스 전환
↑ / ↓ .......... 파일 전환
Esc ............. 닫기

[되감기] (Esc × 2)
J / K ........... 위/아래 이동
Enter ........... 선택

[주의: 멀티플렉서]
Ctrl+B .......... tmux와 충돌 (두 번 누르기)
Ctrl+A .......... screen과 충돌 (두 번 누르기)

시리즈를 마치며​

3편에 걸쳐 Claude Code의 단축키를 정리했습니다. 솔직히 전부 외울 필요는 없습니다. 1편의 필수 단축키만 익혀도 충분하고, 나머지는 필요할 때 이 글을 찾아보면 됩니다.

한 가지 팁을 남기자면, Claude Code 안에서 ?를 누르면 현재 환경에서 쓸 수 있는 단축키가 바로 나옵니다. 이 글보다 그게 더 빠를 수 있습니다.

이 글은 2026년 4월 기준 Claude Code v2.1.x 기준으로 작성했어요. /keybindings 커스터마이징은 v2.1.18 이상이 필요해요.

참고 자료​

Claude Code Vim 단축키

· 약 5분

Claude Code에 Vim이 있다고?​

있어요. /config에서 에디터 모드를 Vim으로 바꾸면 돼요. 그 순간부터 Claude Code의 입력창이 Vim처럼 동작해요.

Normal 모드와 Insert 모드가 분리되고, h/j/k/l로 이동하고, dd로 줄을 지우고, ciw로 단어를 바꿉니다. Vim 사용자라면 손에 익은 그대로입니다.

이 시리즈는 3편으로 구성됩니다.

  • 1편: 필수 단축키
  • 2편: Vim 모드 (이 글)
  • 3편: 커스터마이징 & 세부 컨텍스트

활성화 방법​

Claude Code 실행 후 /config를 입력하고, Editor mode를 Vim으로 변경합니다. 별도 설치나 플러그인은 필요 없습니다.

참고로 Vim 모드와 일반 키 바인딩은 독립적으로 동작합니다. Vim 모드를 켜도 Ctrl+C, Ctrl+R 같은 일반 단축키는 그대로 동작합니다.

모드 전환​

Vim의 핵심은 모드입니다. Claude Code에서도 동일하게 적용됩니다.

Insert → Normal​

키동작
EscNormal 모드 진입

Normal → Insert​

키동작커서 위치
i커서 앞에서 입력 시작현재 위치
I줄 시작에서 입력 시작줄 맨 앞
a커서 뒤에서 입력 시작한 칸 뒤
A줄 끝에서 입력 시작줄 맨 뒤
o아래에 새 줄 열기새 줄
O위에 새 줄 열기새 줄

Vim을 써본 적이 있다면 완전히 같은 동작입니다. 처음이라면 i로 입력하고 Esc로 나온다는 것만 기억하면 됩니다.

Claude Code Vim 모드 전환 상태도

내비게이션 (Normal 모드)​

기본 이동​

키동작
h왼쪽
j아래
k위
l오른쪽

화살표 키도 동작하지만, 홈 로우에서 손을 떼지 않는 게 Vim을 쓰는 이유입니다.

단어 단위 이동​

키동작
w다음 단어 시작으로
e현재 단어 끝으로
b이전 단어 시작으로

줄 단위 이동​

키동작
0줄 맨 앞
$줄 맨 뒤
^첫 번째 비공백 문자

전체 이동​

키동작
gg입력 맨 처음
G입력 맨 끝

문자 점프​

키동작
f{문자}다음 해당 문자로 이동
F{문자}이전 해당 문자로 이동
t{문자}다음 해당 문자 바로 앞으로
T{문자}이전 해당 문자 바로 뒤로
;마지막 f/F/t/T 반복
,마지막 f/F/t/T 반대 방향

예를 들어 f=을 누르면 커서가 다음 = 문자로 점프합니다. ;을 누르면 그다음 =으로 계속 이동합니다. 긴 프롬프트에서 특정 위치를 빠르게 찾을 때 유용합니다.

히스토리 탐색​

키동작
k (맨 위에서)이전 명령어로
j (맨 아래에서)다음 명령어로

커서가 더 이상 이동할 수 없는 경계에 도달하면 명령어 히스토리를 탐색합니다.

편집 (Normal 모드)​

삭제​

키동작
x커서 위 문자 삭제
dd줄 전체 삭제
D커서부터 줄 끝까지 삭제
dw다음 단어까지 삭제
de단어 끝까지 삭제
db이전 단어까지 삭제

변경 (삭제 후 Insert 모드 진입)​

키동작
cc줄 전체 변경
C커서부터 줄 끝까지 변경
cw다음 단어까지 변경
ce단어 끝까지 변경
cb이전 단어까지 변경

d는 삭제만 하고 Normal 모드에 남습니다. c는 삭제 후 바로 Insert 모드로 전환됩니다. 뭔가를 지우고 바로 다시 타이핑하려면 c 계열이 키 입력을 한 번 줄여줍니다.

복사 & 붙여넣기​

키동작
yy 또는 Y줄 전체 복사(yank)
yw다음 단어까지 복사
ye단어 끝까지 복사
yb이전 단어까지 복사
p커서 뒤에 붙여넣기
P커서 앞에 붙여넣기

기타 편집​

키동작
>>들여쓰기
<<내어쓰기
J아래 줄과 합치기
.마지막 편집 반복

.은 꽤 강력합니다. cw로 단어를 바꾼 뒤 .을 누르면 같은 동작을 반복하므로, 여러 곳에서 같은 수정을 할 때 시간을 아낍니다.

텍스트 오브젝트​

Vim의 진짜 힘은 텍스트 오브젝트에 있습니다. d, c, y 같은 오퍼레이터와 조합해 사용합니다.

단어​

키범위
iw단어 안쪽 (inner word)
aw단어 + 주변 공백 (a word)
iWWORD 안쪽 (공백 기준 단어)
aWWORD + 주변 공백

괄호 / 따옴표​

키범위
i" / a"큰따옴표 안쪽 / 포함
i' / a'작은따옴표 안쪽 / 포함
i( / a(소괄호 안쪽 / 포함
i[ / a[대괄호 안쪽 / 포함
i{ / a{중괄호 안쪽 / 포함

실전 조합 예시​

입력동작
ciw커서 위 단어를 삭제하고 입력 모드
di"큰따옴표 안의 내용 삭제
ya(소괄호 포함해서 복사
ci{중괄호 안의 내용을 바꾸기

예를 들어 프롬프트에 "이전 파일을 수정해줘"라고 적었는데 따옴표 안의 내용만 바꾸고 싶다면, 따옴표 안에 커서를 두고 ci"를 누르면 됩니다. 따옴표 안의 텍스트가 지워지면서 바로 새 내용을 입력하는 상태가 됩니다.

Normal 모드에서 도움말​

키동작
?도움말 메뉴 표시

Vim 모드에서 Normal 모드일 때 ?를 누르면 현재 환경에서 사용 가능한 단축키 목록이 표시됩니다.

한눈에 보기​

[모드 전환]
Esc ............. Normal 모드
i / a ........... Insert 모드 (앞/뒤)
I / A ........... Insert 모드 (줄 시작/끝)
o / O ........... 새 줄 열기 (아래/위)

[이동]
h/j/k/l ........ 좌/하/상/우
w / e / b ...... 단어 (시작/끝/이전)
0 / $ / ^ ...... 줄 (맨앞/맨뒤/첫글자)
gg / G ......... 전체 (처음/끝)
f{c} / t{c} .... 문자 점프

[편집]
x .............. 문자 삭제
dd / D ......... 줄 삭제 / 줄끝까지
cc / C ......... 줄 변경 / 줄끝까지
yy / p / P ..... 복사 / 붙여넣기
. .............. 마지막 편집 반복

[텍스트 오브젝트]
ciw ............ 단어 변경
di" ............ 따옴표 안 삭제
ci( ............ 괄호 안 변경
ya{ ............ 중괄호 포함 복사

다음 편 예고​

3편에서는 커스터마이징과 세부 컨텍스트 단축키를 다뤄요. keybindings.json으로 키를 재설정하는 방법, Transcript Viewer, Diff Viewer, 스크롤 모드 등 특정 상황에서만 쓰는 단축키를 정리할게요.

이 글은 2026년 4월 기준 Claude Code v2.1.x 기준으로 작성되었습니다. Vim 모드는 /config → Editor mode에서 활성화할 수 있습니다.

참고 자료​

Claude Code 필수 단축키

· 약 5분

Claude Code 단축키 도움말 화면​

Claude Code에서 ?를 누르면 볼 수 있는 단축키 요약 화면이에요.

Claude Code 단축키 도움말

이 화면에 나오는 것들을 하나씩 풀어서 정리해보겠습니다.

단축키를 왜 알아야 하나​

Claude Code를 터미널에서 쓰다 보면, 마우스 없이 모든 걸 해결해야 하는 순간이 옵니다. 긴 프롬프트를 수정하고, 실행을 취소하고, 모델을 바꾸고, 히스토리를 뒤지는 일이 전부 키보드로 가능합니다.

문제는 단축키가 꽤 많다는 점입니다. 전부 외울 필요는 없습니다. 이 글에서는 매일 쓰게 되는 것만 추렸습니다.

이 시리즈는 3편으로 구성됩니다.

macOS 터미널 설정부터​

시작하기 전에 하나 짚고 가겠습니다. macOS에서 Option(Alt) 키 조합이 안 먹히는 경우가 많습니다. 터미널 설정을 먼저 바꿔야 합니다.

터미널설정 방법
iTerm2Settings → Profiles → Keys → Left/Right Option key → "Esc+"
Terminal.appSettings → Profiles → Keyboard → "Use Option as Meta Key" 체크
VS Code설정에서 "terminal.integrated.macOptionIsMeta": true 추가

이걸 안 하면 Option+P, Option+T 같은 단축키가 특수문자만 입력됩니다. 꼭 먼저 설정해야 합니다.

일반 제어​

가장 자주 쓰는 기본 조작입니다.

단축키기능비고
Ctrl+C현재 입력 또는 실행 취소가장 많이 누르게 됨
Ctrl+DClaude Code 종료EOF 시그널
Ctrl+L입력창 내용 지우기대화 기록은 유지
Ctrl+R히스토리 역방향 검색이전 프롬프트를 찾을 때
Ctrl+O트랜스크립트 뷰어 토글도구 실행 상세 내용 확인
Ctrl+B실행 중인 작업 백그라운드로tmux 사용자는 두 번 눌러야 함
Ctrl+T태스크 목록 토글진행 상황 확인
Esc × 2되감기(Rewind) / 요약이전 상태로 복원

히스토리 검색 모드 (Ctrl+R 이후)​

히스토리 검색에 진입하면 쓸 수 있는 키가 따로 있습니다.

단축키기능
Ctrl+R다음(이전) 매칭 결과로 이동
Tab 또는 Esc현재 결과 선택 후 편집 계속
Enter현재 결과 선택 후 바로 실행
Ctrl+C검색 취소, 원래 입력 복원

텍스트 편집​

프롬프트가 길어질수록 이 단축키들이 빛을 발합니다.

단축키기능비고
Ctrl+K커서부터 줄 끝까지 삭제삭제된 텍스트 저장됨
Ctrl+U커서부터 줄 시작까지 삭제줄 전체 지울 때 유용
Ctrl+Y삭제한 텍스트 붙여넣기Ctrl+K/Ctrl+U로 지운 것
Alt+B한 단어 뒤로 이동macOS: Option 설정 필요
Alt+F한 단어 앞으로 이동macOS: Option 설정 필요
Ctrl+_실행 취소(Undo)Ctrl+Shift+-도 동일
Ctrl+S현재 프롬프트 임시 저장(Stash)나중에 다시 불러올 수 있음

Ctrl+K로 지우고 Ctrl+Y로 붙여넣는 조합은 터미널의 킬 링(kill ring)과 같은 원리입니다. 익숙해지면 마우스 드래그보다 빠릅니다.

멀티라인 입력​

Claude Code에서 한 줄짜리 프롬프트만 쓰지는 않습니다. 여러 줄 입력하는 방법을 알아두어야 합니다.

방법단축키비고
이스케이프\ + Enter모든 터미널에서 동작
macOS 기본Option+EntermacOS 기본값
Shift+EnterShift+EnteriTerm2, WezTerm, Ghostty, Kitty
줄바꿈 문자Ctrl+J라인 피드
붙여넣기코드 블록 직접 붙여넣기코드, 로그 등

VS Code, Alacritty, Zed, Warp 터미널에서 Shift+Enter를 쓰려면 /terminal-setup을 실행해서 바인딩을 설치해야 합니다.

또 하나 유용한 단축키가 있습니다.

단축키기능
Ctrl+G 또는 Ctrl+X Ctrl+E외부 에디터에서 프롬프트 편집

프롬프트가 정말 길어지면 터미널에서 편집하는 게 고역입니다. 이 단축키를 누르면 기본 에디터(보통 vim이나 nano)가 열리고, 거기서 편하게 작성할 수 있습니다. 저장하고 나오면 바로 입력됩니다.

모드와 모델 전환​

Claude Code를 쓰다가 모델을 바꾸거나 모드를 전환하고 싶을 때는 명령어를 입력할 필요가 없습니다.

단축키기능비고
Shift+Tab권한 모드 순환default → acceptEdits → plan → auto → bypassPermissions
Option+P모델 전환프롬프트 유지한 채로 변경
Option+T확장 사고(Extended Thinking) 토글
Option+OFast 모드 토글

Windows/Linux에서는 Option 대신 Alt를 사용합니다.

Shift+Tab은 특히 자주 씁니다. 코드 수정이 맘에 안 들면 plan 모드로 바꿔서 계획을 먼저 세우게 하고, 빠르게 진행하고 싶으면 auto로 전환하는 식입니다.

입력 프리픽스​

프롬프트 첫 글자에 따라 동작이 달라집니다.

프리픽스기능예시
/명령/스킬 메뉴 열기/help, /config, /doctor
!셸 명령 직접 실행!git status, !npm test
@파일 경로 자동완성@src/index.ts

!은 Claude에게 시키지 않고 직접 셸 명령을 실행할 때 씁니다. git status 같은 단순 확인을 AI한테 시키면 아깝습니다.

프롬프트 제안​

Claude Code가 회색 텍스트로 다음 입력을 제안할 때가 있습니다.

키기능
Tab 또는 →제안 수락
Enter제안 수락 + 바로 전송
아무 키나 타이핑제안 무시

이미지 붙여넣기​

스크린샷이나 이미지를 Claude에게 보여줘야 할 때도 있습니다.

단축키기능
Ctrl+V클립보드 이미지 붙여넣기
Cmd+ViTerm2에서 이미지 붙여넣기

붙여넣으면 [Image #N] 형태로 입력창에 표시됩니다.

확인/권한 다이얼로그​

Claude가 파일을 수정하거나 명령을 실행하려 할 때 나오는 확인 창에서 쓸 수 있는 키입니다.

단축키기능
Y 또는 Enter승인
N 또는 Escape거부
↑ / ↓옵션 이동
Ctrl+E권한 설명 토글

한눈에 보기​

마지막으로 매일 쓰는 것만 골라서 한 장에 정리했습니다.

[일반]
Ctrl+C .......... 취소
Ctrl+D .......... 종료
Ctrl+L .......... 입력 지우기
Ctrl+R .......... 히스토리 검색
Esc × 2 ........ 되감기

[편집]
Ctrl+K .......... 줄 끝까지 삭제
Ctrl+U .......... 줄 시작까지 삭제
Ctrl+Y .......... 붙여넣기 (킬 링)
Alt+B / Alt+F ... 단어 단위 이동
Ctrl+J .......... 줄바꿈

[전환]
Shift+Tab ....... 권한 모드 순환
Option+P ........ 모델 전환
Option+T ........ 사고 모드 토글
Option+O ........ Fast 모드 토글

[입력]
/ ............... 명령 메뉴
! ............... 셸 실행
@ ............... 파일 자동완성

다음 편 예고​

2편에서는 Claude Code의 Vim 모드를 다뤄요. /config에서 활성화하면 Normal/Insert 모드 전환, h/j/k/l 내비게이션, 텍스트 오브젝트까지 전부 쓸 수 있어요. Vim 사용자라면 기대해도 좋아요.

이 글은 2026년 4월 기준 Claude Code v2.1.x 기준으로 작성되었습니다. 버전에 따라 단축키가 다를 수 있습니다. ?를 눌러 현재 환경의 단축키를 확인할 수 있습니다.

참고 자료​

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 수준의 코드 내비게이션이 가능해집니다.

아래 표의 키 중 K, Ctrl-]처럼 Neovim이 기본 제공하는 것도 있지만, gd, gi, <leader>rn, <leader>ca, Insert 모드 Ctrl-k 같은 키는 LSP 설정에서 직접 매핑하는 대표적인 사용자 설정 예시입니다. Neovim 0.11부터는 grn(rename), gra(코드 액션), grr(참조), gri(구현), gO(문서 심볼), Insert 모드 Ctrl-s(시그니처)가 기본 매핑으로 들어 있습니다. 버전별 기본값은 :help lsp-defaults로 확인합니다.

코드 내비게이션​

키동작
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-v → I → // 방식보다 훨씬 간편합니다. 언어별 주석 형식도 자동 감지합니다.

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 모드에서 Space는 l과 같은 동작(쓸모 없음)
  • 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의 동사와 명사를 조합해 편집 명령을 만드는 문법

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

모드​

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 단위 (공백 기준으로만 구분)

w와 W의 차이: 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는 선택을 시작한 후 반대 방향으로도 확장하고 싶을 때 씁니다.

모드 전환​

선택을 유지한 채 모드를 바꿉니다. v → V로 문자에서 줄로, V → Ctrl-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-v → jj → lll → d.

예: 주석 일괄 제거

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

// 위에 Ctrl-v → jj → ll → d.

컬럼 치환​

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

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. > → 한 레벨 더

또는 V → jjj → 3>로 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-v → jjj (0들을 선택) → g Ctrl-a.

실전 예제 모음​

상황방법
여러 줄 앞에 // 주석Ctrl-v → jjj → I → // → Esc
여러 줄 // 주석 제거Ctrl-v → jjj → ll → d
여러 줄 끝에 ; 추가Ctrl-v → jjj → $ → A → ; → Esc
CSV 특정 컬럼 삭제해당 열에 Ctrl-v → G → d
변수명 일괄 교체해당 열에 Ctrl-v → jjj → e → c → 새 이름 → Esc
여러 줄 들여쓰기Ctrl-v → jjj → > (또는 V → jjj → >)
0부터 순차 번호0을 입력 → 복사해서 여러 줄 → Ctrl-v로 선택 → g Ctrl-a
HTML 속성 일괄 추가태그 뒤에 Ctrl-v → jjj → A → 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-v → jjj → I → // → Esc
여러 줄 주석 제거Ctrl-v → jjj → ll → d
괄호 안 내용만 교체ci(
따옴표 안 내용 복사yi"
태그 안 내용 삭제dit
현재 줄 복제yyp
두 줄 순서 바꾸기ddp
여러 줄 들여쓰기V → jjj → > (반복: .)
여러 줄 내어쓰기V → jjj → <
선택 영역 정렬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//

마치며​

이 글에서 다룬 것은 모두 Vim과 Neovim에서 공통으로 동작하는 단축키예요.

기억할 것은 세 가지예요.

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

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

Claude HUD 상태 표시줄

· 약 3분

Claude Code를 쓸 때 궁금한 것들​

Claude Code로 작업하다 보면 이런 생각이 들어요:

  • 컨텍스트를 얼마나 썼지? 곧 한계에 도달하나?
  • 지금 무슨 도구를 실행 중이지? 파일을 읽고 있나, 편집 중인가?
  • 서브에이전트가 돌고 있는데 얼마나 걸리고 있지?
  • 할 일 목록에서 몇 번째까지 끝났지?

이 정보들을 터미널 하단에 항상 보여주는 플러그인이 Claude HUD예요. 2026년 4월 기준 GitHub Stars 18.7k로, 인기 있는 Claude Code 플러그인 중 하나예요.

뭘 보여주는가​

Claude HUD는 터미널 입력창 바로 아래에 상태 표시줄을 추가합니다.

[Opus] │ my-project git:(main*)
Context █████░░░░░ 45% │ Usage ██░░░░░░░░ 25% (1h 30m / 5h)

기본 표시 항목​

항목설명
모델명현재 사용 중인 모델 (Opus, Sonnet 등)
프로젝트 경로작업 디렉토리 (depth 조절 가능)
Git 브랜치현재 브랜치 + dirty 상태(*), ahead/behind 표시
Context 바컨텍스트 윈도우 사용률 (현재 모델의 컨텍스트 윈도우 기준)
Usage 바구독 사용량 (5시간 또는 주간 한도 대비)

선택 표시 항목​

설정으로 다음 정보를 추가합니다.

도구 활동

◐ Edit: auth.ts | ✓ Read ×3 | ✓ Grep ×2

지금 Claude가 어떤 파일을 편집 중인지, 몇 번 읽기/검색을 했는지 실시간으로 보입니다.

에이전트 상태

◐ explore [haiku]: Finding auth code (2m 15s)

서브에이전트가 돌고 있을 때 어떤 에이전트가 뭘 하고 있는지, 얼마나 걸렸는지 표시합니다.

할 일 진행률

▸ Fix authentication bug (2/5)

TaskCreate로 만든 할 일 목록의 진행 상황을 보여줍니다.

왜 유용한가​

1. 컨텍스트 관리​

Claude Code는 대화가 길어지면 컨텍스트 윈도우가 차오릅니다. 가득 차면 이전 내용이 압축되면서 맥락을 잃을 수 있습니다. Context 바를 보면서 적절한 시점에 새 대화를 시작하면 됩니다.

2. 대기 시간 활용​

Claude가 뭘 하고 있는지 보이면, 기다릴지 다른 일을 할지 판단할 수 있습니다. "에이전트가 탐색 중이니 2분은 걸리겠군" 같은 판단이 가능해집니다.

3. 사용량 추적​

구독 사용자라면 주간 사용량 한도가 있습니다. Usage 바를 보면서 속도를 조절합니다. 80% 이상이면 경고 표시도 됩니다.

설치​

Claude Code 안에서 3줄이면 됩니다.

/plugin marketplace add jarrodwatts/claude-hud
/plugin install claude-hud
/claude-hud:setup

setup에서 프리셋을 선택합니다.

프리셋표시 내용
Full도구, 에이전트, 할 일, Git, 사용량 전부 표시
Essential활동 상태 + Git, 적당한 밀도
Minimal모델명 + 컨텍스트 바만

설치 후 Claude Code를 재시작하면 적용됩니다.

설정 커스터마이징​

~/.claude/plugins/claude-hud/config.json에서 세부 설정을 조정할 수 있습니다.

{
"language": "en",
"lineLayout": "expanded",
"pathLevels": 1,
"gitStatus": { "enabled": true },
"display": {
"showTools": true,
"showAgents": true,
"showTodos": true,
"showDuration": false,
"showMemoryUsage": false,
"showCost": false
}
}

레이아웃​

  • expanded: 여러 줄로 펼쳐서 표시 (정보 밀도 높음)
  • compact: 한 줄로 압축 (화면 절약)

경로 깊이​

pathLevels: 1 → my-project
pathLevels: 2 → apps/my-project
pathLevels: 3 → dev/apps/my-project

색상​

named color(dim, red, green 등), 256-color 번호(0-255), hex 값(#rrggbb) 모두 지원합니다.

동작 원리​

Claude HUD는 Claude Code의 statusline API를 사용합니다.

  • Claude Code가 약 300ms 간격으로 세션 데이터를 JSON으로 전달
  • HUD가 이를 파싱해서 컨텍스트 사용량, 토큰 속도 등을 계산
  • transcript JSONL 파일을 읽어 도구 사용, 에이전트, 할 일 상태를 추출
  • 포맷팅된 텍스트를 터미널 하단에 출력

Claude HUD의 데이터 흐름

별도 창이나 tmux 없이, Claude Code 터미널 자체에 통합됩니다.

요구사항​

  • Claude Code v1.0.80 이상
  • Node.js 18+ 또는 Bun

마치며​

Claude Code를 많이 쓸수록 "지금 뭘 하고 있는지"가 중요해집니다. 특히 서브에이전트를 여러 개 띄우거나, 긴 작업을 시킬 때 HUD가 있으면 체감이 크게 다릅니다.

설치에 1분, 설정에 1분이면 되니까 한번 써보는 걸 추천해요.

GitHub: jarrodwatts/claude-hud

Obsidian CLI 자동화

· 약 6분

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

  1. Obsidian CLI 입문: 터미널에서 노트를 다루는 새로운 방법
  2. Obsidian CLI 비교: 공식 CLI vs URI vs 직접 파일 조작
  3. Obsidian CLI 자동화: 스크립트와 워크플로우 실전 가이드 ← 현재 글

왜 자동화하는가​

노트를 꾸준히 쓰기는 어렵습니다. 데일리 노트를 열고, 양식을 채우고, 태스크를 옮기는 작업은 반복적이고 귀찮습니다. 귀찮으면 안 하게 되고, 안 하면 쌓이고, 쌓이면 포기합니다.

자동화의 핵심은 반복적인 부분을 제거해서 본질(기록)에만 집중하게 만드는 것입니다.

Obsidian CLI 덕분에 이 반복 작업을 셸 스크립트로 만들 수 있습니다.

셸·cron·tmux·Git 훅에서 Obsidian 노트로 이어지는 자동화 흐름

셸 별칭과 함수​

~/.zshrc에 추가해두면 매일 쓰게 되는 것들:

기본 별칭​

# 데일리 노트 단축키
alias dn="obsidian daily"
alias dna="obsidian daily:append"

# 빠른 검색
alias qs="obsidian search"

# 태그 현황
alias tags="obsidian tags counts"

memo() 빠른 메모​

타임스탬프와 함께 데일리 노트에 한 줄 메모를 추가합니다.

memo() {
local timestamp=$(date +%H:%M)
obsidian daily:append content="- **${timestamp}** $*"
}
# 사용
memo "내일 블로그 배포 일정 확인할 것"
memo "obsidian CLI 포스트 초안 완성"

# 데일리 노트에 이렇게 추가된다:
# - **14:23** 내일 블로그 배포 일정 확인할 것
# - **15:10** obsidian CLI 포스트 초안 완성

til() TIL 노트 자동 생성​

오늘 배운 것(Today I Learned)을 빠르게 기록합니다.

til() {
local today=$(date +%Y-%m-%d)
local slug=$(echo "$1" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
obsidian create name="TIL/${today}-${slug}" content="---
tags: [til]
date: ${today}
---
# $1

$2"
}
# 사용
til "Obsidian CLI" "터미널에서 데일리 노트를 관리할 수 있다"

cron으로 정기 작업​

반복 스케줄이 정해진 작업은 cron에 맡깁니다.

매일 아침 데일리 노트 자동 생성​

# crontab -e
0 9 * * * obsidian daily

매일 오전 9시에 데일리 노트가 자동 생성됩니다. Obsidian을 열면 이미 오늘 노트가 준비되어 있습니다.

주간 리뷰 노트​

# 매주 금요일 오후 5시에 주간 리뷰 노트 생성
0 17 * * 5 obsidian create name="Review/$(date +\%Y-W\%V)" template="Templates/weekly-review"

전일 태스크 알림​

# 매일 오전 9시 30분에 어제 미완료 태스크 확인
30 9 * * * obsidian tasks daily --offset=-1

주의: cron에서 Obsidian CLI가 동작하려면, Obsidian 데스크톱 앱이 이미 실행 중이어야 합니다. macOS라면 로그인 시 Obsidian이 자동 실행되도록 설정해두면 됩니다.

macOS sleep 함정: 노트북이 sleep 상태일 때는 cron 자체가 발사되지 않습니다. 데스크톱이라면 무관하지만 노트북에서 매일 9시 데일리 노트가 안 만들어지면 이 때문입니다. caffeinate -s로 일시 차단하거나, 아예 launchd (launchctl)의 StartCalendarInterval로 옮기면 sleep 후 깨어났을 때 한 번 따라잡습니다.

vault 지정: 공식 CLI는 현재 디렉터리가 볼트 폴더면 그 볼트를, 아니면 실행 중인 앱의 활성 볼트를 사용합니다. cron 환경은 셸 환경변수와 PATH를 자동 상속하지 않고 작업 디렉터리도 볼트 폴더가 아닐 수 있으므로, 여러 볼트를 쓴다면 obsidian vault="MyVault" daily처럼 명령 앞에 vault=를 붙이고 crontab에 PATH를 명시해 두는 편이 안전합니다.

tmux 연동​

tmux를 쓰고 있다면, Obsidian CLI와의 조합이 강력합니다.

작업용 레이아웃​

tmux 패널 하나를 Obsidian 전용으로 쓰면, 코드를 쓰면서 노트를 바로 확인할 수 있습니다.

┌──────────────────┬──────────────────┐
│ Neovim │ obsidian read │
│ │ │
├──────────────────┼──────────────────┤
│ Shell │ obsidian search │
│ │ │
└──────────────────┴──────────────────┘

좌상: 코드 편집, 우상: 노트 확인, 좌하: 빌드/테스트, 우하: 검색

자동화 스크립트​

프로젝트 시작 시 tmux 워크스페이스를 한 번에 구성하는 스크립트입니다.

#!/bin/bash
# obsidian-workspace.sh

SESSION="obsidian-work"

tmux new-session -d -s $SESSION

# 왼쪽: 에디터
tmux send-keys -t $SESSION "nvim" C-m

# 오른쪽: Obsidian 노트
tmux split-window -h -t $SESSION
tmux send-keys -t $SESSION "obsidian read path='Projects/current.md'" C-m

# 하단: 터미널
tmux split-window -v -t $SESSION:0.0
tmux send-keys -t $SESSION "obsidian daily" C-m

tmux attach -t $SESSION

tmux에서 빠른 메모​

tmux의 아무 패널에서 memo 함수를 실행하면 작업 흐름을 끊지 않고 메모를 남길 수 있습니다. 에디터를 떠나지 않아도 됩니다.

Git 연동​

커밋 로그를 데일리 노트에 자동 기록​

git의 post-commit hook을 활용합니다.

#!/bin/bash
# .git/hooks/post-commit

COMMIT_MSG=$(git log -1 --pretty=format:"%s")
REPO_NAME=$(basename $(git rev-parse --show-toplevel))

obsidian daily:append content="- **commit** \`${REPO_NAME}\`: ${COMMIT_MSG}"

hook에 실행 권한을 부여합니다.

chmod +x .git/hooks/post-commit

이제 커밋할 때마다 데일리 노트에 자동으로 기록됩니다.

- **commit** `blog-repo`: Obsidian CLI 시리즈 포스트 추가
- **commit** `blog-repo`: 오타 수정

하루가 끝나면 데일리 노트에 오늘의 작업 이력이 쌓여 있습니다.

프로젝트 노트 자동 생성​

새 프로젝트를 시작할 때 git repo와 Obsidian 노트를 동시에 만드는 함수입니다.

new-project() {
local name=$1
mkdir -p ~/Projects/$name && cd ~/Projects/$name
git init
obsidian create name="Projects/$name" template="Templates/project"
echo "프로젝트 '$name' 생성 완료 — git repo + Obsidian 노트"
}

실전 워크플로우 예제​

아침 루틴 스크립트​

매일 아침 실행하는 스크립트 하나로 하루를 시작합니다.

#!/bin/bash
# morning.sh — 아침 루틴

echo "☀️ 아침 루틴 시작"

# 1. 오늘 데일리 노트 생성
obsidian daily
echo "✓ 데일리 노트 생성"

# 2. 어제 미완료 태스크 확인
echo ""
echo "📋 어제 미완료 태스크:"
obsidian tasks daily --offset=-1

# 3. 태그 현황
echo ""
echo "🏷️ 태그 현황:"
obsidian tags counts
# 실행
chmod +x morning.sh
./morning.sh

프로젝트 대시보드 생성​

볼트의 현재 상태를 요약하는 대시보드 노트를 자동 생성합니다.

#!/bin/bash
# dashboard.sh — 프로젝트 대시보드 갱신

VAULT=~/Documents/MyVault
TODAY=$(date +%Y-%m-%d)

# 통계 수집
TOTAL_NOTES=$(find $VAULT -name "*.md" | wc -l | tr -d ' ')
TODO_COUNT=$(grep -rc "\- \[ \]" $VAULT --include="*.md" | awk -F: '{sum+=$2} END{print sum}')
DONE_COUNT=$(grep -rc "\- \[x\]" $VAULT --include="*.md" | awk -F: '{sum+=$2} END{print sum}')

# 최근 수정된 노트 (상위 5개)
RECENT=$(find $VAULT -name "*.md" -mtime -1 -exec basename {} .md \; | head -5 | sed 's/^/- /')

# 대시보드 노트 갱신
obsidian create name="Dashboard" content="---
tags: [dashboard]
---
# 프로젝트 대시보드
> 마지막 갱신: ${TODAY}

## 통계
| 항목 | 수 |
|------|-----|
| 전체 노트 | ${TOTAL_NOTES} |
| 미완료 태스크 | ${TODO_COUNT} |
| 완료 태스크 | ${DONE_COUNT} |

## 최근 수정된 노트
${RECENT}
"

cron으로 매일 실행하면 항상 최신 상태의 대시보드를 유지할 수 있습니다.

마치며​

Obsidian CLI의 진짜 가치는 명령어 자체보다 자동화 가능성에 있습니다.

셸 별칭으로 매일 쓰는 명령을 줄이고, cron으로 반복 작업을 없애고, tmux와 결합해 워크플로우에 녹여넣고, git hook으로 기록을 자동화합니다. 이 모든 것이 CLI가 있기 때문에 가능해졌습니다.

터미널에서 Neovim으로 코드를 쓰고, tmux로 세션을 관리하고, Obsidian CLI로 노트까지 다뤄요. GUI로 전환할 이유가 하나 줄었어요.

참고 자료​

Obsidian CLI 비교

· 약 5분

이 글은 Obsidian CLI 시리즈의 두 번째 글입니다.

  1. Obsidian CLI 입문: 터미널에서 노트를 다루는 새로운 방법
  2. Obsidian CLI 비교: 공식 CLI vs URI vs 직접 파일 조작 ← 현재 글
  3. Obsidian CLI 자동화: 스크립트와 워크플로우 실전 가이드

세 가지 접근법​

Obsidian을 터미널에서 제어하는 방법은 크게 세 가지입니다.

  1. 공식 CLI: Obsidian v1.12부터 내장된 커맨드라인 도구
  2. URI scheme: obsidian:// 프로토콜로 앱에 명령을 전달
  3. 직접 파일 조작: 볼트가 마크다운 디렉토리라는 점을 이용

각각 동작 방식이 다르고, 잘하는 것과 못하는 것이 다릅니다.

Obsidian 공식 CLI와 URI 및 직접 파일 조작 경로 비교

공식 CLI​

1편에서 자세히 다뤘습니다. 핵심만 정리하면 다음과 같습니다.

동작 방식​

obsidian 명령어 → 로컬 소켓 → Obsidian 프로세스 → 볼트 조작

Obsidian 내부 API를 직접 호출합니다. 파일을 이동하면 위키링크가 자동 업데이트되고, 속성 변경은 인덱스에 즉시 반영됩니다.

강점은 기능이 온전하다는 데 있습니다. 데일리 노트, 태스크, 검색, 태그, 템플릿 등 Obsidian 기능을 그대로 쓸 수 있고, 변경이 캐시와 그래프에 즉시 반영되며, 파일을 옮기거나 이름을 바꿔도 위키링크가 자동으로 따라 업데이트됩니다. Templater나 Dataview 같은 플러그인과도 호환됩니다.

대신 앱에 묶입니다. Obsidian 데스크톱 앱이 켜져 있어야 하고, 그래서 SSH로 접속한 원격 서버에서는 쓸 수 없습니다. 기능 자체가 v1.12 이상에서만 제공되므로 이전 버전 사용자는 업데이트가 필요합니다.

대표 명령어​

obsidian daily:append content="메모 내용"
obsidian search query="키워드"
obsidian create name="노트명" template="템플릿"
obsidian tags counts

Obsidian URI Scheme​

obsidian://로 시작하는 URL을 통해 Obsidian에 명령을 전달하는 방법입니다.

동작 방식​

open "obsidian://..." → OS URL 핸들러 → Obsidian 앱 → 동작 실행

macOS에서는 open 명령어, Linux에서는 xdg-open을 사용합니다.

기본 URI​

# 특정 노트 열기
open "obsidian://open?vault=MyVault&file=Projects/blog"

# 새 노트 생성
open "obsidian://new?vault=MyVault&name=Meeting/standup&content=회의%20메모"

# 검색
open "obsidian://search?vault=MyVault&query=TODO"

URL이므로 특수문자는 퍼센트 인코딩이 필요합니다. 한글도 마찬가지:

# 한글 포함 시
open "obsidian://open?vault=MyVault&file=$(python3 -c 'import urllib.parse; print(urllib.parse.quote("프로젝트/일정"))')"

Advanced URI 플러그인​

obsidian-advanced-uri 플러그인을 설치하면 URI의 기능이 크게 확장됩니다.

# 데일리 노트에 클립보드 내용 추가
open "obsidian://adv-uri?vault=MyVault&daily=true&clipboard=true&mode=append"

# 특정 헤딩 아래에 내용 추가
open "obsidian://adv-uri?vault=MyVault&filepath=Projects/blog.md&heading=TODO&data=새%20항목&mode=append"

# Obsidian 커맨드 실행
open "obsidian://adv-uri?vault=MyVault&commandid=editor:toggle-bold"

URI 방식의 매력은 진입 장벽이 낮다는 데 있습니다. CLI를 따로 활성화하지 않아도 앱만 설치돼 있으면 동작하고, 브라우저나 Alfred, Raycast, Shortcuts 같은 외부 앱에서 호출할 수 있으며, macOS, Windows, Linux를 모두 지원합니다.

한계도 뚜렷합니다. 기본 URI로는 열기, 생성, 검색 정도만 가능하고, 한글이나 특수문자가 들어가면 URL 인코딩이 번거로워집니다. 무엇보다 명령을 보내기만 할 뿐 결과를 터미널로 받아올 수 없고, 고급 기능은 Advanced URI 플러그인에 의존합니다.

직접 파일 조작 (Vault as Code)​

Obsidian 볼트의 본질은 마크다운 파일이 들어 있는 디렉토리입니다. 따라서 표준 유닉스 도구로 직접 조작할 수 있습니다.

사용 예시​

# 볼트 구조 확인
ls ~/Documents/MyVault/

# 키워드 검색
grep -r "TODO" ~/Documents/MyVault/ --include="*.md"

# 특정 태그가 달린 파일 찾기
grep -rl "#project" ~/Documents/MyVault/ --include="*.md"

# 노트 생성
cat << 'EOF' > ~/Documents/MyVault/TIL/obsidian-cli.md
---
tags: [til, obsidian]
---
# Obsidian CLI
오늘 배운 것
EOF

# 일괄 태그 변경
find ~/Documents/MyVault -name "*.md" -exec sed -i '' 's/#old-tag/#new-tag/g' {} +

fzf와 조합​

# fzf로 노트 선택해서 Neovim으로 열기
find ~/Documents/MyVault -name "*.md" | fzf --preview 'head -20 {}' | xargs nvim

이 방식의 장점은 앱에서 완전히 자유롭다는 것입니다. Obsidian이 설치돼 있지 않아도, SSH로 접속한 원격 서버에서도 동작합니다. grep, sed, awk, find 같은 유닉스 도구를 전부 끌어다 쓸 수 있어 유연성이 가장 크고, 수백 개 파일을 일괄 수정하는 대량 처리도 간편합니다.

문제는 Obsidian을 거치지 않는다는 데서 그대로 나옵니다. 변경 사항은 앱을 다시 열거나 리로드해야 인덱스에 반영되고, 파일을 옮기거나 이름을 바꾸면 위키링크가 자동으로 따라오지 않습니다. Templater나 Dataview 같은 플러그인 기능도 적용되지 않으며, 프론트매터 YAML 포맷은 직접 맞춰야 합니다.

종합 비교​

기능공식 CLIURI Scheme직접 파일 조작
앱 실행 필요필수필수불필요
원격 서버 사용——지원
검색 결과 반환터미널 출력—grep 등
위키링크 자동 업데이트지원——
인덱스 즉시 반영지원지원지연
플러그인 연동지원일부—
템플릿 지원지원Advanced URI수동
대량 일괄 처리루프 필요—지원
외부 앱 연동—지원—
설정 난이도낮음낮음없음

이럴 때는 이것을​

  • 터미널에서 빠르게 노트를 쓰고 싶다 → 공식 CLI
  • 브라우저나 Alfred에서 Obsidian을 열고 싶다 → URI scheme
  • 수백 개 파일의 태그를 일괄 수정하고 싶다 → 직접 파일 조작
  • 서버에서 마크다운 파일을 관리하고 싶다 → 직접 파일 조작
  • 데일리 노트를 자동으로 만들고 싶다 → 공식 CLI
  • Shortcuts/Raycast에서 Obsidian 연동 → URI scheme

조합해서 쓰기​

실제로는 하나만 쓰기보다 상황에 따라 조합하는 편이 낫습니다.

예시 워크플로우는 다음과 같습니다.

# 1. 공식 CLI로 데일리 노트 작성 (인덱스 반영 + 템플릿 적용)
obsidian daily:append content="## 작업 로그"

# 2. grep으로 볼트 전체에서 미완료 태스크 카운트 (대량 검색에 강함)
grep -rc "\- \[ \]" ~/Documents/MyVault/ --include="*.md" | sort -t: -k2 -rn | head -5

# 3. URI로 특정 노트를 Obsidian GUI에서 열기 (그래프 뷰 등 GUI 기능 활용)
open "obsidian://open?vault=MyVault&file=Projects/dashboard"

각 방법의 강점을 살려서 쓰면 됩니다. CLI로 안 되는 대량 처리는 직접 파일 조작으로, 터미널에서 안 되는 GUI 기능은 URI로 보완합니다.

마치며​

세 방법은 맞고 틀리고의 문제가 아니라 각각 잘하는 것이 다르고, 상황에 따라 최적의 도구가 달라집니다.

일상적인 노트 작성에는 공식 CLI가 가장 편하고, 대량 처리에는 직접 파일 조작이, 외부 앱 연동에는 URI scheme이 낫습니다.

다음 글에서는 이 도구들을 활용한 실전 자동화 워크플로우를 정리해요. 셸 별칭, cron, tmux 연동, git hook까지 다룰게요.

참고 자료​