🤖

본 콘텐츠의 이미지 및 내용은 AI로 생성되었습니다.

⚠️

본 콘텐츠의 이미지 및 내용을 무단으로 복제, 배포, 수정하여 사용할 경우 저작권법에 의해 법적 제재를 받을 수 있습니다.

이미지 로딩 중...

Vim 최신 기능 완벽 가이드 - 슬라이드 1/11
A

AI Generated

2025. 11. 1. · 9 Views

Vim 최신 기능 완벽 가이드

Vim 9.0 이후 도입된 최신 기능들을 초급 개발자를 위해 쉽고 친근하게 설명합니다. Vim9 script, 팝업 윈도우, 터미널 통합 등 실무에서 바로 활용할 수 있는 강력한 기능들을 실전 예제와 함께 제공합니다.


목차

  1. Vim9 Script - 현대적이고 빠른 스크립트 언어
  2. 팝업 윈도우 - 현대적인 UI 요소
  3. 터미널 통합 - Vim 내부에서 쉘 사용하기
  4. 텍스트 속성 (Text Properties) - 고급 하이라이팅
  5. 비동기 작업 (Jobs & Channels) - 논블로킹 실행
  6. 가상 텍스트 (Virtual Text) - 코드에 주석 표시
  7. 플로팅 윈도우 개선 - 더욱 유연한 UI
  8. Vim9 클래스 - 객체지향 프로그래밍
  9. 향상된 정규표현식 엔진 - 더 빠르고 강력한 검색
  10. 모던 자동완성 시스템 - 컨텍스트 인식 완성
  11. 세션 관리 개선 - 프로젝트 상태 저장
  12. 내장 LSP 클라이언트 - 언어 서버 프로토콜 지원

1. Vim9 Script - 현대적이고 빠른 스크립트 언어

시작하며

여러분이 Vim 플러그인을 만들거나 vimrc를 작성할 때, 왜 이렇게 느리고 복잡한지 의문을 가져본 적 있나요? 특히 자동완성이나 문법 검사 같은 플러그인을 사용할 때 딜레이가 발생하는 경우가 많습니다.

이런 문제는 기존 Vim script의 성능 한계 때문입니다. 레거시 Vim script는 인터프리터 방식으로 동작하며, 타입 체크도 런타임에 이루어져 속도가 느렸습니다.

대규모 설정 파일이나 복잡한 플러그인을 사용하면 Vim의 시작 시간이 몇 초씩 걸리기도 했죠. 바로 이럴 때 필요한 것이 Vim9 Script입니다.

컴파일 시점에 최적화되고, 타입 체크가 가능하며, 기존 스크립트보다 최대 100배 빠른 성능을 제공합니다.

개요

간단히 말해서, Vim9 Script는 Vim의 차세대 스크립트 언어로, 성능과 가독성을 대폭 향상시킨 현대적인 프로그래밍 언어입니다. 왜 Vim9 Script가 필요한지 실무 관점에서 설명하자면, 개발자들은 점점 더 많은 플러그인과 복잡한 설정을 사용합니다.

LSP(Language Server Protocol) 통합, 자동완성, 린터, 포맷터 등을 모두 사용하면 Vim이 무거워집니다. Vim9 Script는 이러한 기능들을 훨씬 빠르게 실행할 수 있게 해줍니다.

기존에는 타입 없이 변수를 선언하고 런타임에 오류를 발견했다면, 이제는 타입을 명시하고 컴파일 시점에 오류를 찾을 수 있습니다. 이는 Python에서 TypeScript로 이동하는 것과 비슷한 경험입니다.

Vim9 Script의 핵심 특징은 타입 선언 지원, 컴파일 타임 최적화, 그리고 명확한 스코프 규칙입니다. 이러한 특징들이 코드의 안정성과 유지보수성을 크게 향상시킵니다.

코드 예제

vim9script

# 타입을 명시한 변수 선언
var name: string = "Developer"
var count: number = 0
const MAX_ITEMS: number = 100

# 타입이 명시된 함수
def Greet(user: string): string
  return $"Hello, {user}!"
enddef

# 리스트와 딕셔너리도 타입 지정 가능
var items: list<string> = ['vim', 'neovim', 'editor']
var config: dict<any> = {
  theme: 'dark',
  fontSize: 14
}

# 함수 호출
echo Greet(name)

설명

이것이 하는 일: Vim9 Script는 정적 타입 체크와 컴파일 최적화를 통해 안정적이고 빠른 Vim 설정 및 플러그인을 작성할 수 있게 해줍니다. 첫 번째로, vim9script 선언으로 시작합니다.

이는 이 파일이 Vim9 Script로 작성되었음을 명시하며, 컴파일러가 최적화를 수행할 수 있게 합니다. 기존 Vim script와 달리 변수 선언에 var, const, final을 사용하여 스코프를 명확히 합니다.

타입 주석(: string, : number)을 통해 컴파일 시점에 타입 오류를 발견할 수 있습니다. 그 다음으로, def 키워드로 함수를 정의합니다.

기존의 function과 달리 def는 컴파일되어 훨씬 빠르게 실행됩니다. 함수 매개변수와 반환 타입을 명시하면 코드의 의도가 명확해지고, 잘못된 타입의 인자를 전달하는 실수를 방지할 수 있습니다.

문자열 보간($"Hello, {user}!")도 지원하여 가독성이 향상되었습니다. 마지막으로, 리스트와 딕셔너리에도 타입을 지정할 수 있습니다.

list<string>은 문자열만 담는 리스트를, dict<any>는 어떤 타입이든 값으로 가질 수 있는 딕셔너리를 의미합니다. 이러한 타입 시스템 덕분에 런타임 오류를 크게 줄일 수 있습니다.

여러분이 이 코드를 사용하면 더 빠르고 안정적인 Vim 환경을 구축할 수 있습니다. 특히 복잡한 플러그인을 작성하거나, 대규모 vimrc를 관리할 때 타입 안정성과 성능 향상을 모두 누릴 수 있습니다.

또한 코드의 자동완성과 리팩토링도 더 쉬워집니다.

실전 팁

💡 기존 Vim script 파일을 Vim9 Script로 변환할 때는 점진적으로 마이그레이션하세요. :scriptversion 4를 사용하면 부분적으로 Vim9 기능을 사용할 수 있습니다.

💡 타입 주석을 생략하면 Vim이 자동으로 타입을 추론하지만, 명시적으로 작성하는 것이 코드 가독성과 유지보수에 좋습니다.

💡 성능이 중요한 함수는 반드시 def로 정의하세요. function보다 10배 이상 빠릅니다.

💡 :vim9cmd를 사용하면 명령줄에서도 Vim9 Script 문법을 사용할 수 있습니다. 디버깅할 때 유용합니다.

💡 레거시 플러그인과의 호환성을 위해 exportimport를 활용하여 모듈 시스템을 구축하세요.


2. 팝업 윈도우 - 현대적인 UI 요소

시작하며

여러분이 코드를 작성하다가 함수의 도움말을 보고 싶거나, 간단한 선택 메뉴를 띄우고 싶을 때 어떻게 하시나요? 전통적인 Vim에서는 새 버퍼를 열거나 명령줄 영역을 사용해야 했고, 이는 작업 흐름을 방해했습니다.

이런 불편함은 Vim의 UI 한계 때문입니다. 모던 에디터들은 코드 위에 떠 있는 팝업으로 정보를 표시하는데, Vim은 이런 기능이 없어 사용자 경험이 떨어졌습니다.

VSCode나 IntelliJ처럼 매끄러운 UI를 구현하기 어려웠죠. 바로 이럴 때 필요한 것이 팝업 윈도우입니다.

코드 편집을 방해하지 않으면서 정보를 표시하고, 사용자 입력을 받을 수 있는 현대적인 UI 요소를 제공합니다.

개요

간단히 말해서, 팝업 윈도우는 Vim 화면 위에 떠 있는 독립적인 윈도우로, 정보 표시, 메뉴, 알림 등 다양한 UI를 구현할 수 있는 기능입니다. 왜 팝업 윈도우가 필요한지 실무 관점에서 설명하자면, 현대적인 개발 환경에서는 LSP 자동완성, 함수 시그니처 힌트, 진단 메시지 등을 코드 위에 표시해야 합니다.

예를 들어, 함수를 호출할 때 매개변수 정보를 팝업으로 보여주거나, 에러가 발생한 줄에 마우스를 올리면 상세 정보를 표시하는 경우에 매우 유용합니다. 기존에는 분할 윈도우를 만들어서 정보를 표시했다면, 이제는 팝업 윈도우로 화면 레이아웃을 건드리지 않고 정보를 표시할 수 있습니다.

사용자는 작업에 집중하면서도 필요한 정보를 바로 확인할 수 있습니다. 팝업 윈도우의 핵심 특징은 위치와 크기를 자유롭게 설정할 수 있고, 테두리와 스타일을 커스터마이징할 수 있으며, 사용자 입력에 반응하는 콜백을 등록할 수 있다는 것입니다.

이러한 특징들이 VSCode와 같은 모던 에디터의 UX를 Vim에서도 구현 가능하게 만듭니다.

코드 예제

" 간단한 정보 팝업
let info_text = ['Function: calculateSum()',
  \ 'Parameters: num1, num2',
  \ 'Returns: number',
  \ '',
  \ 'Calculates the sum of two numbers.']

let popup_id = popup_create(info_text, #{
  \ line: 'cursor+1',
  \ col: 'cursor',
  \ border: [1, 1, 1, 1],
  \ borderchars: ['─', '│', '─', '│', '┌', '┐', '┘', '└'],
  \ padding: [0, 1, 0, 1],
  \ highlight: 'Normal',
  \ borderhighlight: ['Comment'],
  \ close: 'click',
  \ })

설명

이것이 하는 일: 팝업 윈도우는 사용자의 작업 흐름을 방해하지 않으면서 정보를 표시하거나 입력을 받을 수 있는 플로팅 UI를 생성합니다. 첫 번째로, 팝업에 표시할 내용을 리스트로 준비합니다.

각 요소는 한 줄을 의미하며, 여러 줄의 텍스트를 표시할 수 있습니다. 함수 시그니처 정보나 도움말처럼 구조화된 정보를 보여주기에 적합합니다.

빈 문자열을 넣으면 빈 줄을 추가할 수 있어 가독성을 높일 수 있습니다. 그 다음으로, popup_create() 함수로 팝업을 생성합니다.

linecol 옵션으로 위치를 지정하는데, 'cursor+1'은 커서 바로 아래를, 'cursor'는 커서 위치를 의미합니다. 절대 좌표나 상대 좌표를 모두 사용할 수 있어 유연합니다.

border 옵션으로 테두리를 그리고, borderchars로 테두리 문자를 커스터마이징할 수 있습니다. 마지막으로, 스타일과 동작을 설정합니다.

padding으로 내부 여백을 조정하고, highlight로 색상 테마를 지정합니다. close 옵션을 'click'으로 설정하면 사용자가 팝업을 클릭할 때 자동으로 닫히게 할 수 있습니다.

반환된 popup_id를 사용하면 나중에 popup_close(popup_id)로 프로그래밍 방식으로 팝업을 닫을 수도 있습니다. 여러분이 이 코드를 사용하면 LSP 통합, 자동완성 플러그인, 인터랙티브 메뉴 등을 구현할 수 있습니다.

특히 플러그인 개발자라면 사용자에게 훨씬 나은 UX를 제공할 수 있습니다. 팝업은 자동으로 화면 경계를 넘지 않도록 위치를 조정하므로 안정적입니다.

실전 팁

💡 popup_menu()를 사용하면 선택 가능한 메뉴 팝업을 쉽게 만들 수 있습니다. 사용자가 항목을 선택하면 콜백이 호출됩니다.

💡 popup_notification()은 일정 시간 후 자동으로 사라지는 알림 팝업을 만들 때 사용하세요. 저장 완료 같은 피드백에 적합합니다.

💡 팝업이 너무 많이 열리면 성능이 저하될 수 있으니 popup_list()로 현재 팝업을 확인하고 관리하세요.

💡 popup_filter_menu()popup_filter_yesno()로 사용자 입력을 받는 인터랙티브 팝업을 만들 수 있습니다.

💡 팝업 내용을 동적으로 업데이트하려면 popup_settext()를 사용하세요. 실시간 검색 결과나 로딩 상태를 표시할 때 유용합니다.


3. 터미널 통합 - Vim 내부에서 쉘 사용하기

시작하며

여러분이 코드를 작성하다가 빌드를 실행하거나 테스트를 돌려야 할 때, Vim을 종료하고 터미널로 가서 명령어를 실행한 적 있나요? 또는 :!command로 외부 명령을 실행하지만 출력을 제대로 보지 못해 답답했던 경험이 있을 겁니다.

이런 문제는 Vim과 쉘 사이의 단절 때문입니다. 전통적으로 Vim은 텍스트 편집에만 집중했고, 쉘 작업은 별도로 해야 했습니다.

이는 개발 워크플로우를 방해하고, 컨텍스트 스위칭 비용을 발생시켰습니다. tmux나 screen을 사용해 우회하기도 했지만, 복잡한 설정이 필요했죠.

바로 이럴 때 필요한 것이 터미널 통합 기능입니다. Vim 윈도우 안에서 완전한 터미널을 실행하고, 코드 편집과 쉘 작업을 매끄럽게 전환할 수 있습니다.

개요

간단히 말해서, 터미널 통합은 Vim 내부에 완전히 기능하는 터미널 에뮬레이터를 제공하여, 에디터를 떠나지 않고도 모든 쉘 작업을 수행할 수 있게 하는 기능입니다. 왜 터미널 통합이 필요한지 실무 관점에서 설명하자면, 현대 개발은 빌드 도구, 테스트 러너, 린터, 포맷터 등 다양한 CLI 도구를 사용합니다.

예를 들어, Node.js 개발을 할 때 npm run dev로 개발 서버를 띄우고, 다른 터미널에서 npm test를 실행하며, 또 다른 터미널에서 코드를 편집하는 경우가 많습니다. Vim 터미널을 사용하면 이 모든 작업을 하나의 Vim 세션에서 처리할 수 있습니다.

기존에는 Vim에서 빠져나와 별도의 터미널 창을 사용했다면, 이제는 Vim 분할 윈도우로 터미널을 열고 즉시 명령을 실행할 수 있습니다. 출력을 바로 확인하고, 필요하면 출력을 복사해서 코드에 붙여넣을 수도 있습니다.

터미널 통합의 핵심 특징은 완전한 ANSI 색상 지원, 인터랙티브 프로그램 실행 가능, 그리고 Vim 버퍼와의 원활한 통합입니다. 이러한 특징들이 IDE처럼 통합된 개발 환경을 Vim에서도 가능하게 만듭니다.

코드 예제

" 수평 분할로 터미널 열기
:terminal

" 수직 분할로 터미널 열기
:vertical terminal

" 특정 크기로 터미널 열기 (10줄 높이)
:10split | terminal

" 특정 쉘 명령어를 실행하는 터미널
:terminal python3 script.py

" 터미널 버퍼에서 노멀 모드로 전환: Ctrl-W N
" 다시 터미널 모드로: i 또는 a

" vimrc에서 터미널 단축키 설정
nnoremap <leader>t :below terminal<CR>
nnoremap <leader>vt :vertical terminal<CR>

설명

이것이 하는 일: 터미널 통합은 Vim 윈도우 내에 완전히 기능하는 터미널 에뮬레이터를 생성하여, 개발자가 에디터와 쉘 사이를 자유롭게 오갈 수 있게 합니다. 첫 번째로, :terminal 명령으로 터미널을 엽니다.

기본적으로 현재 윈도우를 수평 분할하여 아래쪽에 터미널이 나타납니다. 여기서 모든 쉘 명령을 실행할 수 있고, 색상과 커서 위치도 정확히 표시됩니다.

:vertical terminal을 사용하면 세로로 분할되어 코드와 터미널을 나란히 볼 수 있습니다. 이는 로그를 모니터링하면서 코드를 수정할 때 특히 유용합니다.

그 다음으로, 크기를 조정하거나 특정 명령을 실행하는 터미널을 열 수 있습니다. :10split | terminal은 10줄 높이의 터미널을 만들고, :terminal python3 script.py는 터미널을 열자마자 Python 스크립트를 실행합니다.

장시간 실행되는 프로세스(개발 서버, 빌드 워처 등)를 백그라운드에서 돌리면서 코드를 편집할 수 있습니다. 마지막으로, 터미널 모드와 노멀 모드를 전환하는 방법을 이해해야 합니다.

터미널에서 Ctrl-W N을 누르면 노멀 모드로 전환되어 터미널 출력을 Vim 명령으로 검색하거나 복사할 수 있습니다. 다시 ia를 누르면 터미널 모드로 돌아가 명령을 입력할 수 있습니다.

이 기능 덕분에 에러 메시지를 복사해서 검색하거나, 출력 결과를 코드에 붙여넣기가 쉬워집니다. 여러분이 이 코드를 사용하면 워크플로우가 크게 개선됩니다.

테스트 주도 개발(TDD)을 할 때 한쪽에는 코드, 다른 쪽에는 테스트 결과를 띄워놓고 작업할 수 있습니다. Git 명령도 Vim 안에서 실행하고, diff를 바로 확인할 수 있습니다.

무엇보다 마우스를 사용하지 않고 키보드만으로 모든 것을 제어할 수 있어 생산성이 향상됩니다.

실전 팁

💡 set termwinsize=10x0을 vimrc에 추가하면 새 터미널 윈도우의 기본 크기를 설정할 수 있습니다. (높이x너비)

💡 터미널 버퍼는 일반 버퍼처럼 :bdelete로 닫을 수 있습니다. 프로세스가 실행 중이면 종료 확인을 요청합니다.

💡 ++close 옵션을 사용하면 명령이 끝나면 자동으로 터미널이 닫힙니다. 예: :terminal ++close pytest

💡 터미널에서 Ctrl-W :를 누르면 Vim 명령줄 모드로 바로 전환되어 빠르게 Vim 명령을 실행할 수 있습니다.

💡 term_sendkeys()함수로 스크립트에서 터미널에 키를 전송할 수 있습니다. 자동화된 워크플로우 구축에 유용합니다.


4. 텍스트 속성 (Text Properties) - 고급 하이라이팅

시작하며

여러분이 코드에서 특정 변수의 모든 사용처를 강조 표시하거나, LSP에서 받은 진단 정보를 시각적으로 표시하고 싶을 때 어떻게 하시나요? 기존의 matchmatchadd()는 정규식 기반이라 성능이 떨어지고, 정확한 위치를 지정하기 어려웠습니다.

이런 문제는 Vim의 전통적인 하이라이팅 시스템의 한계 때문입니다. 정규식 매칭은 파일이 클수록 느려지고, 특정 바이트 위치를 정확히 강조하기 어렵습니다.

LSP 같은 외부 도구에서 받은 위치 정보를 효율적으로 표시할 방법이 없었죠. 또한 하이라이팅이 텍스트 편집에 영향을 받아 위치가 틀어지는 문제도 있었습니다.

바로 이럴 때 필요한 것이 텍스트 속성입니다. 정확한 위치에 메타데이터를 부착하고, 효율적으로 하이라이팅하며, 텍스트 편집 시 자동으로 위치가 업데이트됩니다.

개요

간단히 말해서, 텍스트 속성은 버퍼의 특정 텍스트 범위에 메타데이터(타입, ID, 하이라이팅 등)를 부착하는 기능으로, LSP 진단, 시맨틱 하이라이팅, 리팩토링 등에 활용됩니다. 왜 텍스트 속성이 필요한지 실무 관점에서 설명하자면, 현대적인 언어 서버는 코드의 의미를 분석하여 심볼의 종류(변수, 함수, 타입 등)를 알려줍니다.

예를 들어, TypeScript LSP는 같은 변수라도 지역 변수, 매개변수, 전역 변수를 다르게 구분해서 알려주는데, 이를 다른 색으로 표시하려면 텍스트 속성이 필요합니다. 또한 에러나 경고 위치에 물결선을 그어 표시하거나, 사용되지 않는 코드를 회색으로 표시하는 등의 기능도 구현할 수 있습니다.

기존에는 matchadd()로 패턴을 등록했다면, 이제는 정확한 줄과 컬럼 위치를 지정하여 속성을 추가할 수 있습니다. 텍스트를 편집해도 속성이 자동으로 따라 움직이거나, 설정에 따라 사라지거나 확장됩니다.

텍스트 속성의 핵심 특징은 정확한 위치 지정, 텍스트 편집 시 자동 업데이트, 그리고 임의의 메타데이터 저장 가능입니다. 이러한 특징들이 VSCode 수준의 시맨틱 하이라이팅을 Vim에서도 가능하게 만듭니다.

코드 예제

" 텍스트 속성 타입 정의
call prop_type_add('error', #{
  \ highlight: 'ErrorMsg',
  \ priority: 100
  \ })

call prop_type_add('warning', #{
  \ highlight: 'WarningMsg',
  \ priority: 50
  \ })

" 특정 위치에 속성 추가 (3번 줄, 5번 컬럼부터 10글자)
call prop_add(3, 5, #{
  \ length: 10,
  \ type: 'error',
  \ id: 1
  \ })

" 여러 줄에 걸친 속성
call prop_add(5, 1, #{
  \ end_lnum: 7,
  \ end_col: 20,
  \ type: 'warning'
  \ })

" 모든 속성 제거
call prop_clear(1, line('$'))

설명

이것이 하는 일: 텍스트 속성은 버퍼의 특정 텍스트 범위를 표시하고 메타데이터를 연결하여, 외부 도구의 분석 결과를 시각적으로 표현합니다. 첫 번째로, prop_type_add()로 속성 타입을 정의합니다.

타입은 하이라이팅 그룹과 우선순위를 지정하는 템플릿입니다. 예를 들어 'error' 타입은 ErrorMsg 하이라이팅을 사용하고 우선순위 100을 가집니다.

같은 위치에 여러 속성이 있을 때 우선순위가 높은 것이 표시됩니다. 이렇게 타입을 미리 정의하면 나중에 속성을 추가할 때 간단하게 타입 이름만 참조하면 됩니다.

그 다음으로, prop_add()로 실제 속성을 추가합니다. 줄 번호와 컬럼 번호를 지정하고, length로 몇 글자를 강조할지 정합니다.

id를 부여하면 나중에 이 속성을 찾거나 제거할 때 사용할 수 있습니다. LSP에서 받은 진단 정보를 표시할 때, 각 진단마다 고유 ID를 부여하면 업데이트가 쉬워집니다.

마지막으로, 여러 줄에 걸친 범위도 지정할 수 있습니다. end_lnumend_col로 종료 위치를 명시하면 그 사이의 모든 텍스트에 속성이 적용됩니다.

함수나 클래스 전체를 접거나 강조할 때 유용합니다. prop_clear()로 범위 내의 모든 속성을 제거할 수 있어, 파일을 다시 분석한 후 속성을 새로 고칠 수 있습니다.

여러분이 이 코드를 사용하면 에디터의 시각적 피드백이 크게 향상됩니다. LSP 통합 플러그인을 만들 때 에러와 경고를 정확한 위치에 표시하고, 코드를 수정해도 표시가 자동으로 따라갑니다.

시맨틱 하이라이팅으로 변수, 함수, 타입을 다르게 색칠하여 코드 가독성을 높일 수 있습니다. 무엇보다 정규식 기반 매칭보다 훨씬 빠르고 정확합니다.

실전 팁

💡 prop_list()로 특정 줄의 모든 속성을 조회할 수 있습니다. 디버깅이나 상태 확인에 유용합니다.

💡 속성 타입에 combine: v:true를 설정하면 기존 하이라이팅과 결합됩니다. 시맨틱 하이라이팅과 문법 하이라이팅을 동시에 적용할 때 사용하세요.

💡 prop_remove()로 특정 ID나 타입의 속성만 선택적으로 제거할 수 있습니다. 전체를 지우지 않고 일부만 업데이트할 때 유용합니다.

💡 가상 텍스트 기능(text 옵션)을 사용하면 실제 파일에는 없는 텍스트를 화면에만 표시할 수 있습니다. 인라인 타입 힌트나 Git blame 정보 표시에 활용하세요.

💡 성능을 위해 큰 파일에서는 보이는 영역만 속성을 추가하고, 스크롤 시 동적으로 업데이트하는 전략을 사용하세요.


5. 비동기 작업 (Jobs & Channels) - 논블로킹 실행

시작하며

여러분이 Vim에서 린터를 실행하거나 외부 도구를 호출할 때, Vim이 멈춰서 아무것도 할 수 없었던 경험이 있나요? :!command로 명령을 실행하면 완료될 때까지 기다려야 하고, 그동안 편집할 수 없어 답답했을 겁니다.

이런 문제는 Vim의 동기적 실행 모델 때문입니다. 외부 명령이 실행되는 동안 Vim은 완전히 블로킹되어 사용자 입력을 받지 못합니다.

큰 프로젝트에서 린터나 테스트를 실행하면 몇 초에서 몇 분까지 걸릴 수 있는데, 그동안 아무것도 못하는 것은 큰 생산성 저하입니다. 비동기 처리 없이는 자동완성, 실시간 린팅, 백그라운드 빌드 같은 기능을 구현할 수 없었죠.

바로 이럴 때 필요한 것이 비동기 작업입니다. 외부 프로세스를 백그라운드에서 실행하고, 결과를 콜백으로 받아 처리하여, Vim이 멈추지 않고 계속 작업할 수 있게 합니다.

개요

간단히 말해서, Jobs와 Channels는 외부 프로세스를 비동기적으로 실행하고 통신하는 기능으로, 논블로킹 방식으로 린터, 빌드 도구, LSP 등과 상호작용할 수 있게 합니다. 왜 비동기 작업이 필요한지 실무 관점에서 설명하자면, 현대 개발 환경은 실시간 피드백이 필수입니다.

예를 들어, 코드를 저장할 때마다 ESLint를 실행하여 에러를 표시하거나, 타입 체크를 백그라운드에서 수행하거나, 파일 변경 시 자동으로 테스트를 돌리는 등의 작업이 필요합니다. 이 모든 것을 동기적으로 처리하면 Vim이 계속 멈췄다 돌아가기를 반복하게 됩니다.

기존에는 외부 명령이 끝날 때까지 기다려야 했다면, 이제는 명령을 시작하고 바로 다른 작업을 계속할 수 있습니다. 명령이 끝나면 콜백 함수가 호출되어 결과를 처리합니다.

사용자는 Vim이 항상 반응한다고 느끼게 됩니다. 비동기 작업의 핵심 특징은 논블로킹 실행, 실시간 출력 스트리밍, 그리고 양방향 통신 지원입니다.

이러한 특징들이 LSP나 DAP 같은 복잡한 프로토콜을 구현하는 기반이 됩니다.

코드 예제

" 비동기로 외부 명령 실행
function! OnOutput(channel, msg)
  " 출력을 받을 때마다 호출됨
  echo 'Output: ' . a:msg
endfunction

function! OnExit(job, exit_status)
  " 프로세스가 종료되면 호출됨
  if a:exit_status == 0
    echo 'Success!'
  else
    echo 'Failed with status: ' . a:exit_status
  endif
endfunction

let job = job_start(['python3', 'script.py'], #{
  \ out_cb: 'OnOutput',
  \ err_cb: 'OnOutput',
  \ exit_cb: 'OnExit'
  \ })

" 작업 상태 확인
echo job_status(job)

" 작업 중지
call job_stop(job)

설명

이것이 하는 일: Jobs는 외부 프로세스를 백그라운드에서 실행하고, Channels는 그 프로세스와 양방향으로 데이터를 주고받아, 논블로킹 방식의 통합을 가능하게 합니다. 첫 번째로, 콜백 함수들을 정의합니다.

OnOutput()은 프로세스가 stdout이나 stderr에 한 줄을 출력할 때마다 호출됩니다. 실시간으로 로그를 표시하거나, 점진적으로 결과를 처리할 수 있습니다.

OnExit()는 프로세스가 종료되면 호출되어 최종 처리를 담당합니다. 종료 코드를 확인하여 성공 여부를 판단하고, 필요한 후처리를 수행합니다.

이 콜백들은 Vim의 메인 이벤트 루프에서 실행되므로 안전하게 Vim 기능을 사용할 수 있습니다. 그 다음으로, job_start()로 프로세스를 시작합니다.

첫 번째 인자는 명령어와 인자들의 리스트입니다. 딕셔너리로 옵션을 전달하는데, out_cb는 표준 출력 콜백, err_cb는 표준 에러 콜백, exit_cb는 종료 콜백입니다.

함수 이름을 문자열로 전달하거나, 람다를 사용할 수도 있습니다. 명령은 즉시 백그라운드에서 시작되고, job_start()는 바로 반환되어 Vim이 멈추지 않습니다.

마지막으로, 작업을 제어할 수 있습니다. job_status()로 현재 상태를 확인할 수 있고('run', 'fail', 'dead' 등), job_stop()으로 실행 중인 작업을 중단시킬 수 있습니다.

사용자가 작업을 취소하거나, 타임아웃을 구현할 때 유용합니다. Channel을 통해 실행 중인 프로세스에 입력을 보낼 수도 있어, 인터랙티브한 프로세스와 통신할 수 있습니다.

여러분이 이 코드를 사용하면 반응성이 뛰어난 Vim 환경을 만들 수 있습니다. 파일을 저장하면 자동으로 린터를 실행하고, 에러를 QuickFix 리스트에 표시하되, Vim은 계속 반응합니다.

빌드를 실행하면서 동시에 코드를 편집할 수 있고, 진행 상황을 실시간으로 볼 수 있습니다. LSP 클라이언트를 구현하면 자동완성, 정의로 이동, 리팩토링 등 모든 기능을 비동기로 처리하여 VSCode와 유사한 경험을 제공할 수 있습니다.

실전 팁

💡 ch_sendraw()로 Channel을 통해 프로세스에 데이터를 보낼 수 있습니다. JSON-RPC 기반 LSP 통신에 필수적입니다.

💡 pty: v:true 옵션을 사용하면 가상 터미널을 할당하여 색상 출력이나 인터랙티브 프로그램을 제대로 처리할 수 있습니다.

💡 여러 작업을 동시에 실행할 수 있지만, 너무 많으면 시스템 리소스를 소모하니 적절히 제한하세요.

💡 job_info()로 작업의 상세 정보를 얻을 수 있습니다. 프로세스 ID, 시작 시간, 종료 상태 등을 확인하세요.

💡 에러 처리를 철저히 하세요. 프로세스가 비정상 종료하거나, 예상치 못한 출력을 내보낼 수 있습니다.


6. 가상 텍스트 (Virtual Text) - 코드에 주석 표시

시작하며

여러분이 코드를 읽을 때 변수의 타입이나 함수의 반환 타입을 바로 확인하고 싶다거나, Git blame 정보를 줄 끝에 보고 싶은 적이 있나요? 또는 ESLint 에러 메시지를 해당 줄에 인라인으로 표시하고 싶었을 겁니다.

이런 요구사항은 VSCode의 인라인 힌트나 GitLens 같은 기능을 사용해본 개발자라면 익숙할 겁니다. 하지만 전통적인 Vim에서는 실제 파일 내용을 수정하지 않고 추가 정보를 표시할 방법이 없었습니다.

주석을 직접 작성하면 파일이 더러워지고, 상태 라인이나 팝업은 한 번에 하나만 볼 수 있어 불편했죠. 바로 이럴 때 필요한 것이 가상 텍스트입니다.

파일 내용을 변경하지 않고 화면에만 추가 정보를 표시하여, 타입 힌트, 에러 메시지, Git 정보 등을 인라인으로 보여줄 수 있습니다.

개요

간단히 말해서, 가상 텍스트는 실제 버퍼 내용에는 포함되지 않지만 화면에는 표시되는 텍스트로, 타입 힌트, 진단 메시지, 메타데이터 등을 시각적으로 제공하는 기능입니다. 왜 가상 텍스트가 필요한지 실무 관점에서 설명하자면, 현대적인 IDE는 코드에 대한 풍부한 메타데이터를 제공합니다.

예를 들어, TypeScript 코드를 작성할 때 함수의 반환 타입이 추론되면 함수 선언 옆에 회색으로 타입을 표시해줍니다. Rust의 경우 변수의 타입을 명시하지 않아도 컴파일러가 추론한 타입을 보여줍니다.

이런 정보는 코드 이해를 돕지만, 실제 파일에는 포함되어서는 안 됩니다. 기존에는 이런 정보를 보려면 커서를 해당 위치로 이동하여 hover를 띄워야 했다면, 이제는 가상 텍스트로 모든 정보를 동시에 볼 수 있습니다.

스크롤하면서 코드를 읽을 때 추가 동작 없이 모든 메타데이터를 확인할 수 있습니다. 가상 텍스트의 핵심 특징은 파일 내용과 독립적, 임의의 위치에 표시 가능, 그리고 하이라이팅 커스터마이징 가능입니다.

이러한 특징들이 VSCode IntelliSense 같은 풍부한 시각적 피드백을 Vim에서도 구현 가능하게 만듭니다.

코드 예제

" 텍스트 속성 타입 정의 (가상 텍스트 포함)
call prop_type_add('type_hint', #{
  \ highlight: 'Comment'
  \ })

" 줄 끝에 가상 텍스트 추가
call prop_add(10, 0, #{
  \ type: 'type_hint',
  \ text: ' : Promise<User>',
  \ text_align: 'after'
  \ })

" 줄 아래에 가상 텍스트 추가
call prop_add(15, 0, #{
  \ type: 'type_hint',
  \ text: 'Error: Variable not used',
  \ text_align: 'below',
  \ text_padding_left: 2
  \ })

" 줄 위에 가상 텍스트 추가
call prop_add(20, 0, #{
  \ type: 'type_hint',
  \ text: 'Last modified by: John Doe (2 days ago)',
  \ text_align: 'above'
  \ })

설명

이것이 하는 일: 가상 텍스트는 버퍼의 실제 내용을 변경하지 않으면서 화면에 추가 정보를 렌더링하여, 코드 이해를 돕는 시각적 힌트를 제공합니다. 첫 번째로, 가상 텍스트를 위한 속성 타입을 정의합니다.

일반 텍스트 속성과 동일하게 prop_type_add()를 사용하지만, 실제 사용할 때 text 옵션을 추가합니다. 하이라이팅은 보통 Comment 그룹을 사용하여 실제 코드보다 덜 눈에 띄게 만듭니다.

커스텀 하이라이팅 그룹을 만들어 색상을 세밀하게 조정할 수도 있습니다. 그 다음으로, text_align 옵션으로 가상 텍스트의 위치를 지정합니다.

'after'는 줄 끝에 추가하여 타입 힌트나 간단한 주석을 표시하는 데 적합합니다. 예를 들어 함수 선언 뒤에 반환 타입을 표시하거나, 변수 선언 뒤에 추론된 타입을 보여줄 수 있습니다.

'below'는 줄 아래에 새 줄을 만들어 긴 에러 메시지나 경고를 표시할 때 유용합니다. LSP에서 받은 진단 메시지를 해당 줄 바로 아래에 표시하면 컨텍스트를 잃지 않고 정보를 확인할 수 있습니다.

마지막으로, 'above' 정렬을 사용하면 줄 위에 정보를 표시할 수 있습니다. Git blame 정보나 문서 주석을 표시할 때 유용합니다.

text_padding_left로 들여쓰기를 조정하여 코드와 구분되게 만들 수 있습니다. 가상 텍스트는 저장할 때 파일에 포함되지 않으므로, 원하는 만큼 추가해도 실제 코드는 깨끗하게 유지됩니다.

여러분이 이 코드를 사용하면 코드 리딩 경험이 크게 향상됩니다. TypeScript나 Rust처럼 타입 추론이 강력한 언어를 사용할 때, 명시적으로 타입을 작성하지 않아도 추론된 타입을 바로 볼 수 있습니다.

ESLint나 Pylint 같은 린터의 메시지를 인라인으로 표시하여, QuickFix 리스트를 열지 않고도 문제를 파악할 수 있습니다. Git blame 정보를 각 줄에 표시하여 누가 언제 수정했는지 바로 확인할 수 있습니다.

실전 팁

💡 가상 텍스트가 너무 많으면 화면이 어수선해질 수 있으니, 토글 기능을 만들어 필요할 때만 표시하세요.

💡 text_wrap: 'truncate' 옵션을 사용하면 긴 텍스트가 화면을 넘어가지 않고 잘립니다.

💡 성능을 위해 보이는 영역만 가상 텍스트를 추가하고, 스크롤 이벤트에서 업데이트하세요.

💡 색상을 조정할 때는 밝기를 낮춰 실제 코드와 구분되게 하세요. 너무 눈에 띄면 오히려 방해가 됩니다.

💡 가상 텍스트는 복사할 때 포함되지 않으므로, 사용자가 코드를 복사-붙여넣기 해도 문제없습니다.


7. 플로팅 윈도우 개선 - 더욱 유연한 UI

시작하며

여러분이 Vim에서 자동완성 메뉴를 띄우거나, 파일 탐색기를 열거나, 도움말을 볼 때 화면 레이아웃이 망가진 경험이 있나요? 전통적인 분할 윈도우는 편집 영역을 침범하여 작업 흐름을 방해했습니다.

이런 문제는 Vim의 타일 기반 윈도우 시스템의 한계 때문입니다. 모든 윈도우가 화면 공간을 나눠 가져야 하므로, 새 윈도우를 열면 기존 윈도우가 작아집니다.

잠깐 정보를 확인하려고 분할하면 레이아웃이 바뀌어 불편했죠. 팝업 윈도우가 도입되었지만 초기에는 기능이 제한적이었습니다.

바로 이럴 때 필요한 것이 개선된 플로팅 윈도우입니다. 화면 어디든 배치할 수 있고, 투명도와 블렌딩을 지원하며, 마우스와 키보드 이벤트를 자유롭게 처리할 수 있습니다.

개요

간단히 말해서, 개선된 플로팅 윈도우는 화면의 임의 위치에 배치 가능하고, 다양한 시각 효과와 인터랙션을 지원하는 윈도우로, 현대적인 UI/UX를 구현할 수 있게 합니다. 왜 플로팅 윈도우 개선이 필요한지 실무 관점에서 설명하자면, 플러그인 개발자들은 파일 탐색기, 퍼지 파인더, 터미널 런처 등 다양한 인터페이스를 만들고 싶어 합니다.

예를 들어, 화면 중앙에 검색 입력창을 띄우고, 그 아래에 결과 목록을 표시하는 UI를 만들려면 플로팅 윈도우가 필수입니다. 또한 코드 위에 반투명 배경으로 정보를 표시하여 컨텍스트를 유지하면서 추가 정보를 볼 수도 있습니다.

기존 팝업 윈도우는 간단한 정보 표시만 가능했다면, 이제는 완전히 인터랙티브한 윈도우를 만들 수 있습니다. 사용자가 키를 입력하거나 마우스를 클릭하면 커스텀 핸들러가 호출되어 원하는 동작을 구현할 수 있습니다.

플로팅 윈도우의 핵심 특징은 절대 위치 지정, 투명도와 블렌딩 지원, 그리고 완전한 이벤트 핸들링입니다. 이러한 특징들이 Telescope, NvimTree 같은 현대적인 플러그인의 기반이 됩니다.

코드 예제

" 중앙에 플로팅 윈도우 생성
let width = 80
let height = 20
let row = (&lines - height) / 2
let col = (&columns - width) / 2

let buf = nvim_create_buf(v:false, v:true)
call nvim_buf_set_lines(buf, 0, -1, v:true,
  \ ['Select an option:', '', '1. Create file', '2. Open file', '3. Delete file'])

let opts = #{
  \ relative: 'editor',
  \ width: width,
  \ height: height,
  \ row: row,
  \ col: col,
  \ style: 'minimal',
  \ border: 'rounded',
  \ }

let win = nvim_open_win(buf, v:true, opts)

" 윈도우 옵션 설정
call nvim_win_set_option(win, 'winblend', 20)
call nvim_win_set_option(win, 'cursorline', v:true)

설명

이것이 하는 일: 플로팅 윈도우는 기존 윈도우 레이아웃과 독립적으로 화면의 임의 위치에 윈도우를 생성하여, 팝업 메뉴, 다이얼로그, 파일 탐색기 등을 구현합니다. 첫 번째로, 윈도우의 크기와 위치를 계산합니다.

화면 중앙에 배치하려면 터미널의 전체 크기(&lines, &columns)에서 윈도우 크기를 빼고 2로 나눕니다. 절대 좌표를 사용할 수도 있고, 'cursor' 기준으로 상대 위치를 지정할 수도 있습니다.

버퍼를 먼저 생성하고(nvim_create_buf) 내용을 설정합니다. 두 번째 인자를 v:true로 하면 scratch 버퍼가 되어 저장되지 않습니다.

그 다음으로, nvim_open_win()으로 플로팅 윈도우를 엽니다. relative: 'editor'는 에디터 전체를 기준으로 위치를 지정하고, 'win'이나 'cursor'를 사용할 수도 있습니다.

style: 'minimal'은 번호 표시나 상태줄 같은 UI 요소를 숨겨 깔끔한 윈도우를 만듭니다. border: 'rounded'는 둥근 테두리를 그리는데, 'single', 'double', 'shadow' 등 다양한 스타일을 선택할 수 있습니다.

마지막으로, 윈도우 옵션을 설정합니다. winblend는 투명도를 조정하는데, 0은 불투명, 100은 완전 투명입니다.

20 정도로 설정하면 뒤의 코드가 살짝 비쳐 보여 컨텍스트를 유지할 수 있습니다. cursorline을 활성화하면 현재 선택된 항목을 강조 표시할 수 있습니다.

키 매핑을 추가하여 위아래 화살표로 항목을 선택하고, Enter로 실행하는 인터랙티브 메뉴를 만들 수 있습니다. 여러분이 이 코드를 사용하면 전문적인 플러그인을 만들 수 있습니다.

파일 검색기를 화면 중앙에 띄우고, 실시간으로 검색 결과를 업데이트하며, 선택하면 파일을 엽니다. Git diff를 플로팅 윈도우로 표시하여 코드를 가리지 않고 변경 사항을 확인할 수 있습니다.

터미널을 플로팅 윈도우로 열어 빠르게 명령을 실행하고 닫을 수 있습니다. VSCode처럼 Command Palette를 구현할 수도 있습니다.

실전 팁

💡 zindex 옵션으로 여러 플로팅 윈도우의 표시 순서를 제어할 수 있습니다. 드롭다운 메뉴가 다른 팝업 위에 나타나야 할 때 유용합니다.

💡 focusable: v:false로 설정하면 포커스를 받지 않는 윈도우를 만들 수 있습니다. 정보 표시용 팝업에 적합합니다.

💡 anchor 옵션으로 위치의 기준점을 바꿀 수 있습니다. 'NW'(북서)가 기본이지만, 'SE'(남동)로 하면 오른쪽 아래를 기준으로 배치합니다.

💡 버퍼에 자동완성 플러그인이나 LSP를 연결하여 플로팅 윈도우에서도 모든 편집 기능을 사용할 수 있습니다.

💡 성능을 위해 플로팅 윈도우를 재사용하세요. 매번 새로 만들지 말고, 내용만 업데이트하는 것이 효율적입니다.


8. Vim9 클래스 - 객체지향 프로그래밍

시작하며

여러분이 복잡한 Vim 플러그인을 작성할 때, 코드가 점점 길어지고 함수들이 서로 얽혀서 관리하기 어려워진 경험이 있나요? 전역 변수와 함수가 난무하여 네임스페이스 충돌이 발생하거나, 코드 재사용이 어려웠을 겁니다.

이런 문제는 Vim script의 절차적 프로그래밍 패러다임의 한계 때문입니다. 데이터와 동작을 함께 캡슐화할 방법이 없었고, 상속이나 인터페이스 같은 객체지향 개념을 구현하기 어려웠습니다.

대규모 플러그인을 작성할 때 구조화가 힘들어 유지보수성이 떨어졌죠. 바로 이럴 때 필요한 것이 Vim9 클래스입니다.

데이터와 메서드를 클래스로 캡슐화하고, 상속과 인터페이스를 지원하여, 현대적인 객체지향 프로그래밍을 Vim에서도 할 수 있습니다.

개요

간단히 말해서, Vim9 클래스는 데이터와 메서드를 하나로 묶은 객체지향 프로그래밍 구조로, 코드의 재사용성과 유지보수성을 크게 향상시키는 기능입니다. 왜 Vim9 클래스가 필요한지 실무 관점에서 설명하자면, 플러그인이 복잡해질수록 구조화가 중요합니다.

예를 들어, LSP 클라이언트를 구현한다면 서버 연결, 메시지 파싱, 요청 관리 등 여러 관심사를 분리해야 합니다. 클래스를 사용하면 LSPClient, MessageParser, RequestManager 같은 역할별 클래스로 나누어 각각의 책임을 명확히 할 수 있습니다.

기존에는 딕셔너리에 함수를 담아 유사-객체를 만들었다면, 이제는 정식으로 클래스를 정의하고 타입 체크의 혜택을 받을 수 있습니다. 생성자, 메서드, 속성을 명확히 정의하여 API가 자명해집니다.

Vim9 클래스의 핵심 특징은 캡슐화, 상속, 그리고 인터페이스 지원입니다. 이러한 특징들이 대규모 플러그인을 체계적으로 설계하고 관리할 수 있게 만듭니다.

코드 예제

vim9script

# 기본 클래스 정의
class Buffer
  var name: string
  var lines: list<string>

  # 생성자
  def new(name: string)
    this.name = name
    this.lines = []
  enddef

  # 메서드
  def AddLine(line: string)
    this.lines->add(line)
  enddef

  def GetContent(): string
    return this.lines->join("\n")
  enddef
endclass

# 클래스 사용
var myBuffer = Buffer.new("test.txt")
myBuffer.AddLine("Hello, World!")
myBuffer.AddLine("Vim9 Classes are awesome!")
echo myBuffer.GetContent()

설명

이것이 하는 일: Vim9 클래스는 관련된 데이터와 동작을 하나의 단위로 묶어, 코드를 논리적으로 구조화하고 재사용 가능한 컴포넌트를 만듭니다. 첫 번째로, class 키워드로 클래스를 정의합니다.

클래스 내부에 var로 인스턴스 변수를 선언하는데, 타입을 명시하여 안정성을 높입니다. this 키워드로 현재 인스턴스를 참조합니다.

생성자는 new()라는 특별한 메서드로 정의하며, 인스턴스가 생성될 때 자동으로 호출됩니다. 여기서 초기화 로직을 수행합니다.

그 다음으로, 메서드를 def 키워드로 정의합니다. 메서드는 클래스의 데이터에 접근하여 동작을 수행합니다.

AddLine()은 줄을 추가하고, GetContent()는 모든 줄을 합쳐서 반환합니다. 메서드 체이닝도 가능하며, 접근 제어(public, private)를 설정할 수 있습니다.

_로 시작하는 메서드는 private으로 간주되어 클래스 외부에서 접근할 수 없습니다. 마지막으로, 클래스를 사용합니다.

Buffer.new()로 인스턴스를 생성하면 생성자가 호출됩니다. 인스턴스의 메서드를 호출하여 작업을 수행하고, 내부 상태는 캡슐화되어 보호됩니다.

여러 인스턴스를 만들 수 있으며, 각각 독립적인 상태를 유지합니다. 상속을 사용하여 기본 클래스를 확장하고, 다형성을 활용할 수도 있습니다.

여러분이 이 코드를 사용하면 플러그인 아키텍처가 크게 개선됩니다. 복잡한 플러그인을 여러 클래스로 나누어 각각의 역할을 명확히 할 수 있습니다.

테스트 가능한 코드를 작성할 수 있고, 인터페이스를 정의하여 의존성을 관리할 수 있습니다. 다른 플러그인과 협업할 때도 명확한 API를 제공할 수 있어 통합이 쉬워집니다.

실전 팁

💡 abstract class를 정의하여 인터페이스를 강제할 수 있습니다. 여러 구현체가 같은 인터페이스를 따르게 하세요.

💡 static 메서드를 사용하면 인스턴스 없이 클래스 자체에서 호출 가능한 유틸리티 함수를 만들 수 있습니다.

💡 extends 키워드로 상속을 구현할 수 있습니다. 공통 기능을 부모 클래스에 두고, 특화된 기능은 자식 클래스에서 추가하세요.

💡 생성자에서 유효성 검증을 수행하여 잘못된 상태의 객체가 만들어지지 않게 하세요.

💡 클래스가 너무 커지면 단일 책임 원칙을 위반하는 것입니다. 작은 클래스 여러 개로 나누세요.


9. 향상된 정규표현식 엔진 - 더 빠르고 강력한 검색

시작하며

여러분이 대용량 파일에서 복잡한 패턴을 검색할 때, Vim이 몇 초씩 멈춰있거나 심지어 응답하지 않는 경험을 해본 적 있나요? 특히 중첩된 그룹이나 백트래킹이 많은 정규식을 사용하면 성능이 급격히 저하됩니다.

이런 문제는 전통적인 Vim의 정규식 엔진이 백트래킹 기반으로 동작하기 때문입니다. 최악의 경우 지수 시간 복잡도를 가지며, 악의적인 패턴은 ReDoS(Regular Expression Denial of Service) 공격을 일으킬 수도 있습니다.

대규모 코드베이스에서 검색하거나, 복잡한 문법 하이라이팅을 적용하면 Vim이 느려지는 원인이 됩니다. 바로 이럴 때 필요한 것이 향상된 정규표현식 엔진입니다.

NFA(비결정적 유한 오토마타)와 DFA(결정적 유한 오토마타) 엔진을 지능적으로 선택하여, 안정적이고 빠른 검색을 제공합니다.

개요

간단히 말해서, 향상된 정규표현식 엔진은 패턴의 복잡도를 분석하여 최적의 알고리즘을 자동으로 선택하고, 성능과 안정성을 크게 향상시킨 검색 시스템입니다. 왜 향상된 정규표현식 엔진이 필요한지 실무 관점에서 설명하자면, 현대 개발은 거대한 파일과 복잡한 패턴을 다룹니다.

예를 들어, JSON 파일에서 중첩된 객체를 찾거나, 로그 파일에서 특정 패턴의 에러를 추출할 때 복잡한 정규식이 필요합니다. 기존 엔진으로는 이런 작업이 느리거나 불가능했지만, 새 엔진은 신뢰할 수 있는 성능을 보장합니다.

기존에는 정규식 성능이 예측 불가능했다면, 이제는 패턴이 아무리 복잡해도 선형 시간 내에 완료됩니다. 또한 더 풍부한 정규식 기능(lookahead, lookbehind 등)을 지원하여 표현력도 향상되었습니다.

정규표현식 엔진 개선의 핵심 특징은 자동 엔진 선택, 선형 시간 보장, 그리고 향상된 유니코드 지원입니다. 이러한 특징들이 대규모 파일에서도 안정적으로 검색하고 편집할 수 있게 만듭니다.

코드 예제

" 자동 엔진 선택 (기본값)
set regexpengine=0

" NFA 엔진 강제 사용 (복잡한 패턴에 빠름)
set regexpengine=1

" 전통적인 엔진 (간단한 패턴에 빠름)
set regexpengine=2

" Lookahead 사용 예제
/\v(function)@<=\s+\w+

" Lookbehind 사용 예제
/\v\w+\s+(const|let|var)@=

" 유니코드 문자 클래스
/\v\p{Hangul}+

" 대소문자 무시하는 스마트 검색
set ignorecase smartcase
/\vPattern

설명

이것이 하는 일: 정규표현식 엔진은 검색 패턴을 분석하여 NFA 또는 전통적인 엔진 중 더 효율적인 것을 선택하고, 복잡한 패턴도 안정적으로 처리합니다. 첫 번째로, regexpengine 옵션으로 사용할 엔진을 선택합니다.

기본값 0은 자동 선택 모드로, Vim이 패턴을 분석하여 최적의 엔진을 고릅니다. 간단한 패턴은 전통적인 엔진이 빠르지만, 복잡한 패턴(lookahead, lookbehind, 백레퍼런스 등)은 NFA 엔진이 더 안전합니다.

대부분의 경우 자동 모드를 사용하면 충분하지만, 특정 상황에서는 수동으로 조정할 수 있습니다. 그 다음으로, 향상된 정규식 기능을 활용합니다.

\v (very magic) 모드를 사용하면 특수 문자를 이스케이프할 필요가 줄어들어 가독성이 향상됩니다. Lookahead(@<=)와 lookbehind(@=)를 사용하여 더 정교한 패턴을 작성할 수 있습니다.

예를 들어, function 키워드 뒤에 오는 함수 이름만 찾거나, 특정 키워드 앞에 오는 변수 이름만 찾을 수 있습니다. 마지막으로, 유니코드를 제대로 지원합니다.

\p{Hangul}처럼 유니코드 카테고리로 검색할 수 있어, 한글, 한자, 이모지 등을 쉽게 다룰 수 있습니다. ignorecasesmartcase를 함께 사용하면, 패턴에 대문자가 없으면 대소문자를 무시하고, 대문자가 있으면 정확히 매칭합니다.

이는 대부분의 검색에서 원하는 동작입니다. 여러분이 이 코드를 사용하면 검색 경험이 크게 개선됩니다.

대용량 로그 파일에서 복잡한 패턴을 검색해도 Vim이 멈추지 않습니다. 문법 하이라이팅 플러그인을 작성할 때 복잡한 패턴을 안심하고 사용할 수 있습니다.

유니코드 텍스트를 제대로 처리하여 다국어 코드베이스에서도 정확한 검색이 가능합니다.

실전 팁

💡 :h regexp로 Vim 정규식 문법을 확인하세요. Perl이나 PCRE와는 다른 부분이 있습니다.

💡 복잡한 패턴을 작성할 때는 /\v로 very magic 모드를 사용하여 가독성을 높이세요.

💡 set hlsearch incsearch로 검색 결과를 즉시 하이라이팅하고 점진적으로 확인하세요.

💡 성능 문제가 있다면 :set regexpengine=1로 NFA 엔진을 강제해보세요. 대부분의 경우 더 안정적입니다.

💡 :h magic을 읽고 magic, nomagic, very magic, very nomagic의 차이를 이해하세요. 패턴 작성이 훨씬 쉬워집니다.


10. 모던 자동완성 시스템 - 컨텍스트 인식 완성

시작하며

여러분이 코드를 작성할 때, 자동완성이 엉뚱한 제안을 하거나, 너무 느려서 타이핑 흐름이 끊긴 경험이 있나요? 또는 함수 시그니처나 문서를 보기 위해 여러 번 키를 눌러야 했던 적이 있을 겁니다.

이런 문제는 전통적인 Vim 자동완성이 단순 문자열 매칭 기반이기 때문입니다. 코드의 의미를 이해하지 못해 부적절한 제안을 하고, 동기적으로 동작하여 느린 완성 소스(예: 태그 파일)를 사용하면 Vim이 멈춥니다.

LSP 같은 현대적인 도구와 통합하기도 어려웠죠. 바로 이럴 때 필요한 것이 모던 자동완성 시스템입니다.

여러 소스를 비동기로 조회하고, 컨텍스트를 고려한 지능적인 제안을 제공하며, 풍부한 메타데이터를 표시합니다.

개요

간단히 말해서, 모던 자동완성 시스템은 LSP, 태그, 버퍼, 파일 경로 등 여러 소스를 비동기로 통합하고, 컨텍스트를 분석하여 관련성 높은 제안을 우선순위에 따라 제공하는 기능입니다. 왜 모던 자동완성 시스템이 필요한지 실무 관점에서 설명하자면, IDE 수준의 개발 경험을 위해서는 지능적인 자동완성이 필수입니다.

예를 들어, TypeScript로 개발할 때 변수 타입을 알고 있으면 해당 타입의 메서드만 제안해야 하고, React 컴포넌트를 작성할 때는 props 타입에 맞는 속성만 보여줘야 합니다. 단순 문자열 매칭으로는 이런 것이 불가능합니다.

기존에는 Ctrl-X Ctrl-O로 옴니 완성을 수동으로 트리거했다면, 이제는 타이핑하는 동안 자동으로 관련 제안이 나타납니다. 여러 소스의 결과를 병합하고 중복을 제거하여 깔끔한 목록을 제공합니다.

모던 자동완성의 핵심 특징은 비동기 처리, 다중 소스 통합, 그리고 컨텍스트 인식입니다. 이러한 특징들이 VSCode IntelliSense와 유사한 경험을 Vim에서도 가능하게 만듭니다.

코드 예제

" 자동완성 기본 설정
set completeopt=menu,menuone,noselect,preview

" 팝업 메뉴 자동 표시
set pumheight=10

" LSP 기반 옴니 완성 활성화
autocmd FileType typescript,javascript setlocal omnifunc=v:lua.vim.lsp.omnifunc

" 자동완성 트리거 설정
inoremap <silent><expr> <C-Space> pumvisible() ? "\<C-n>" : "\<C-x>\<C-o>"

" 탭으로 다음 항목 선택
inoremap <expr> <Tab> pumvisible() ? "\<C-n>" : "\<Tab>"
inoremap <expr> <S-Tab> pumvisible() ? "\<C-p>" : "\<S-Tab>"

" 엔터로 선택 확정
inoremap <expr> <CR> pumvisible() ? "\<C-y>" : "\<CR>"

" ESC로 팝업 닫기
inoremap <expr> <Esc> pumvisible() ? "\<C-e>" : "\<Esc>"

설명

이것이 하는 일: 자동완성 시스템은 코드 컨텍스트를 분석하고 여러 소스를 병렬로 조회하여, 가장 관련성 높은 제안을 빠르게 표시합니다. 첫 번째로, completeopt를 설정하여 자동완성 동작을 조정합니다.

menu는 팝업 메뉴를 표시하고, menuone은 항목이 하나만 있어도 메뉴를 보여줍니다. noselect는 자동으로 첫 항목을 선택하지 않아 실수로 잘못된 완성을 삽입하는 것을 방지합니다.

preview는 선택한 항목의 추가 정보를 프리뷰 윈도우에 표시합니다. pumheight로 메뉴의 최대 높이를 제한하여 화면을 너무 많이 차지하지 않게 합니다.

그 다음으로, 파일 타입별로 옴니 완성 함수를 설정합니다. LSP가 활성화된 언어는 vim.lsp.omnifunc를 사용하여 언어 서버의 지능적인 제안을 받습니다.

이는 타입 정보, 문서, 함수 시그니처 등 풍부한 메타데이터를 포함합니다. LSP가 없는 언어는 태그 기반 완성이나 버퍼 단어 완성을 사용할 수 있습니다.

마지막으로, 키 매핑을 설정하여 편리하게 자동완성을 사용합니다. Ctrl-Space로 수동 트리거하고, Tab/Shift-Tab으로 항목 간 이동하며, Enter로 선택을 확정합니다.

pumvisible()로 팝업 메뉴가 열려 있는지 확인하여, 같은 키가 다른 상황에서 다르게 동작하게 합니다. 이러한 매핑은 VSCode와 유사한 키보드 경험을 제공합니다.

여러분이 이 코드를 사용하면 생산성이 크게 향상됩니다. 함수 이름을 다 타이핑할 필요 없이 몇 글자만 입력하고 Tab으로 완성할 수 있습니다.

매개변수 타입과 문서를 보면서 함수를 호출할 수 있어 API를 찾아보는 시간이 줄어듭니다. 오타를 줄이고, 사용 가능한 API를 발견하기 쉬워져 코드 품질이 향상됩니다.

실전 팁

💡 set completeopt+=noinsert를 추가하면 항목을 선택할 때까지 텍스트를 삽입하지 않습니다. 더 명시적인 제어를 원할 때 유용합니다.

💡 nvim-cmp 같은 플러그인을 사용하면 더 풍부한 자동완성 경험(아이콘, 스니펫 통합 등)을 얻을 수 있습니다.

💡 완성 소스의 우선순위를 조정하여 LSP 결과를 먼저 보이게 하고, 버퍼 단어를 나중에 보이게 할 수 있습니다.

💡 set infercase를 사용하면 입력한 대소문자를 유지하면서 완성합니다. camelCase 변수명에 유용합니다.

💡 완성 항목이 너무 많으면 성능이 저하될 수 있으니, 최소 문자 수(예: 2글자 이상)를 설정하는 것이 좋습니다.


11. 세션 관리 개선 - 프로젝트 상태 저장

시작하며

여러분이 여러 프로젝트를 오가며 작업할 때, 매번 파일을 다시 열고 윈도우를 재배치하고 설정을 조정하는 것이 번거로웠던 경험이 있나요? 전날 작업하던 상태로 정확히 돌아가고 싶지만, 무엇을 열었는지 기억하지 못해 답답했을 겁니다.

이런 문제는 Vim의 전통적인 세션 관리가 제한적이기 때문입니다. :mksession으로 세션을 저장할 수 있지만, 플러그인 상태나 터미널 버퍼는 저장되지 않았고, 세션 파일을 수동으로 관리해야 했습니다.

프로젝트별로 다른 설정을 적용하기도 어려웠죠. 바로 이럴 때 필요한 것이 개선된 세션 관리입니다.

파일, 윈도우 레이아웃, 버퍼, 마크, 레지스터 등 작업 상태를 완벽히 저장하고 복원하여, 프로젝트 간 전환을 즉각적으로 만들어줍니다.

개요

간단히 말해서, 개선된 세션 관리는 Vim의 전체 작업 상태를 프로젝트별로 저장하고 복원하는 기능으로, 컨텍스트 스위칭 비용을 최소화하고 생산성을 높입니다. 왜 세션 관리 개선이 필요한지 실무 관점에서 설명하자면, 현대 개발자는 동시에 여러 프로젝트를 다룹니다.

예를 들어, 메인 프로젝트, 사이드 프로젝트, 오픈소스 기여, 긴급 버그 수정 등을 오가며 작업합니다. 각 프로젝트마다 열어야 할 파일, 윈도우 배치, 검색 히스토리 등이 다른데, 이를 매번 수동으로 설정하면 시간 낭비입니다.

기존에는 세션을 수동으로 저장하고 불러와야 했다면, 이제는 프로젝트별로 자동 저장하고 Vim을 열 때 자동으로 복원할 수 있습니다. 마지막 작업 위치, 폴드 상태, 검색 패턴까지 정확히 재현됩니다.

세션 관리의 핵심 특징은 완전한 상태 저장, 자동 저장/복원, 그리고 프로젝트별 격리입니다. 이러한 특징들이 IDE의 워크스페이스 개념을 Vim에서도 구현 가능하게 만듭니다.

코드 예제

" 세션 옵션 설정
set sessionoptions=buffers,curdir,folds,help,tabpages,winsize,winpos,terminal

" 자동 세션 저장 디렉토리
let g:session_dir = expand('~/.vim/sessions')
if !isdirectory(g:session_dir)
  call mkdir(g:session_dir, 'p')
endif

" 세션 저장 함수
function! SaveSession()
  let l:session_name = substitute(getcwd(), '/', '_', 'g')
  let l:session_file = g:session_dir . '/' . l:session_name . '.vim'
  execute 'mksession! ' . l:session_file
  echo 'Session saved: ' . l:session_file
endfunction

" 세션 불러오기 함수
function! LoadSession()
  let l:session_name = substitute(getcwd(), '/', '_', 'g')
  let l:session_file = g:session_dir . '/' . l:session_name . '.vim'
  if filereadable(l:session_file)
    execute 'source ' . l:session_file
    echo 'Session loaded'
  endif
endfunction

" 자동 저장/불러오기
autocmd VimLeave * call SaveSession()
autocmd VimEnter * nested call LoadSession()

설명

이것이 하는 일: 세션 관리는 Vim의 현재 상태를 스냅샷으로 저장하고, 나중에 정확히 같은 상태로 복원하여, 작업 중단과 재개를 원활하게 합니다. 첫 번째로, sessionoptions를 설정하여 무엇을 저장할지 정의합니다.

buffers는 열린 버퍼 목록을, curdir은 현재 디렉토리를, folds는 폴드 상태를 저장합니다. tabpageswinsize, winpos로 윈도우 레이아웃을 정확히 재현할 수 있습니다.

terminal을 포함하면 터미널 버퍼도 저장됩니다. 필요에 따라 options를 추가하여 설정도 함께 저장할 수 있지만, 전역 vimrc와 충돌할 수 있으니 주의해야 합니다.

그 다음으로, 세션을 프로젝트별로 관리하는 함수를 작성합니다. 현재 작업 디렉토리(getcwd())를 세션 이름으로 사용하여, 프로젝트마다 별도의 세션 파일을 만듭니다.

/_로 치환하여 파일 이름으로 사용 가능하게 합니다. mksession!으로 기존 세션을 덮어쓰고, source로 세션을 불러옵니다.

이 방식으로 프로젝트를 전환할 때마다 자동으로 올바른 세션이 활성화됩니다. 마지막으로, 자동 저장과 자동 불러오기를 설정합니다.

VimLeave 이벤트에서 세션을 저장하여, Vim을 종료할 때 현재 상태를 자동으로 기록합니다. VimEnter 이벤트에서 세션을 불러와 Vim을 시작할 때 이전 상태를 복원합니다.

nested를 사용하면 세션 불러오기 후 추가 autocmd가 실행되어 플러그인이 제대로 초기화됩니다. 여러분이 이 코드를 사용하면 워크플로우가 크게 개선됩니다.

프론트엔드 프로젝트에서 작업하다가 백엔드 프로젝트로 전환하면, 각 프로젝트의 파일과 설정이 자동으로 로드됩니다. 어제 작업하던 파일이 자동으로 열리고, 커서가 정확히 마지막 위치에 있어 바로 작업을 이어갈 수 있습니다.

프로젝트별로 다른 윈도우 레이아웃을 유지할 수 있어, 각 프로젝트에 최적화된 환경을 만들 수 있습니다.

실전 팁

💡 :SessionList를 구현하여 저장된 세션 목록을 보고 선택할 수 있게 하세요. 프로젝트 간 빠른 전환이 가능합니다.

💡 세션 파일은 텍스트 파일이므로 버전 관리에 포함할 수 있습니다. 팀원과 같은 Vim 환경을 공유하세요.

💡 민감한 정보(버퍼 내용, 레지스터)가 세션에 저장될 수 있으니, 공개 저장소에 커밋하지 마세요.

💡 sessionoptions에서 options를 제거하면 전역 설정과 프로젝트별 설정이 충돌하지 않습니다.

💡 플러그인(vim-obsession, auto-session 등)을 사용하면 더 강력한 세션 관리 기능을 얻을 수 있습니다.


12. 내장 LSP 클라이언트 - 언어 서버 프로토콜 지원

시작하며

여러분이 코드를 작성할 때 정의로 이동하거나, 모든 참조를 찾거나, 리팩토링을 수행하고 싶은데, 외부 플러그인을 복잡하게 설정해야 했던 경험이 있나요? VSCode는 기본적으로 이런 기능을 제공하는데, Vim에서는 번거로웠을 겁니다.

이런 문제는 Vim이 언어별 도구와 통합하는 표준 방법이 없었기 때문입니다. 각 언어마다 다른 플러그인을 설치하고 설정해야 했고, 일관성이 없었습니다.

LSP(Language Server Protocol)가 등장하여 표준화되었지만, Vim은 기본 지원이 없어 서드파티 플러그인에 의존해야 했죠. 바로 이럴 때 필요한 것이 내장 LSP 클라이언트입니다.

Vim이 직접 LSP를 지원하여, 최소한의 설정으로 자동완성, 정의 이동, 리팩토링 등 모든 IDE 기능을 사용할 수 있습니다.

개요

간단히 말해서, 내장 LSP 클라이언트는 Vim이 언어 서버와 직접 통신하여 타입 체크, 자동완성, 정의 이동, 리팩토리 등을 제공하는 기능으로, 별도 플러그인 없이 IDE 수준의 개발 환경을 구축할 수 있게 합니다. 왜 내장 LSP 클라이언트가 필요한지 실무 관점에서 설명하자면, 현대 개발은 언어 서버를 활용한 정적 분석이 필수입니다.

예를 들어, TypeScript, Python, Rust, Go 등 대부분의 언어가 공식 언어 서버를 제공합니다. LSP를 통해 이 서버들과 통신하면 컴파일러 수준의 정확한 정보를 실시간으로 얻을 수 있습니다.

함수 시그니처, 타입 정보, 에러 진단, 리팩토링 제안 등이 모두 가능합니다. 기존에는 coc.nvim이나 ALE 같은 플러그인을 설치해야 했다면, 이제는 Vim/Neovim 자체에서 LSP를 지원합니다.

설정이 간단해지고, 성능도 향상되며, Vim의 기본 기능과 깊게 통합됩니다. 내장 LSP의 핵심 특징은 표준 프로토콜 지원, 비동기 통신, 그리고 풍부한 기능 세트입니다.

이러한 특징들이 Vim을 진정한 IDE로 변신시킵니다.

코드 예제

" Neovim LSP 설정 예제 (Lua)
lua << EOF
-- TypeScript 언어 서버 설정
require'lspconfig'.tsserver.setup{}

-- Python 언어 서버 설정
require'lspconfig'.pyright.setup{}

-- 전역 LSP 키 매핑
vim.keymap.set('n', 'gd', vim.lsp.buf.definition)
vim.keymap.set('n', 'K', vim.lsp.buf.hover)
vim.keymap.set('n', 'gi', vim.lsp.buf.implementation)
vim.keymap.set('n', 'gr', vim.lsp.buf.references)
vim.keymap.set('n', '<leader>rn', vim.lsp.buf.rename)
vim.keymap.set('n', '<leader>ca', vim.lsp.buf.code_action)
vim.keymap.set('n', '<leader>f', vim.lsp.buf.format)

-- 진단 표시 설정
vim.diagnostic.config({
  virtual_text = true,
  signs = true,
  update_in_insert = false,
})
EOF

설명

이것이 하는 일: LSP 클라이언트는 언어 서버 프로세스를 시작하고 JSON-RPC로 통신하여, 코드 분석 결과를 받아 Vim 기능으로 제공합니다. 첫 번째로, 언어 서버를 설정합니다.

lspconfig는 주요 언어 서버의 기본 설정을 제공하는 Neovim 플러그인입니다. tsserver.setup{}으로 TypeScript/JavaScript 서버를, pyright.setup{}으로 Python 서버를 활성화합니다.

각 서버는 프로젝트의 루트 디렉토리를 자동으로 감지하고, 설정 파일(tsconfig.json, pyproject.toml 등)을 읽어 정확한 분석을 수행합니다. 그 다음으로, LSP 기능에 키 매핑을 추가합니다.

gd로 정의로 이동하고, K로 hover 정보를 표시하며, gr로 모든 참조를 찾습니다. <leader>rn으로 심볼 이름을 변경하면 프로젝트 전체에서 안전하게 리팩토링됩니다.

<leader>ca로 코드 액션(import 추가, 타입 변환 등)을 실행할 수 있습니다. 이러한 기능들은 모두 언어 서버가 제공하는 정확한 정보를 기반으로 합니다.

마지막으로, 진단 표시를 설정합니다. virtual_text를 활성화하면 에러와 경고가 줄 끝에 인라인으로 표시됩니다.

signs는 라인 넘버 옆에 아이콘을 표시하여 문제가 있는 줄을 쉽게 찾을 수 있게 합니다. update_in_insert를 false로 하면 입력 모드에서는 진단이 업데이트되지 않아 방해받지 않습니다.

노멀 모드로 돌아가면 자동으로 재분석됩니다. 여러분이 이 코드를 사용하면 VSCode와 유사한 개발 경험을 얻습니다.

함수 이름을 타이핑하다가 Ctrl-Space를 누르면 자동완성 목록이 나타나고, 함수 위에서 K를 누르면 문서가 팝업으로 표시됩니다. 변수를 리팩토링하려면 커서를 올리고 <leader>rn을 눌러 새 이름을 입력하면, 모든 사용처가 안전하게 변경됩니다.

에러가 발생한 줄은 빨간색으로 강조되고, 구체적인 메시지가 표시되어 즉시 수정할 수 있습니다.

실전 팁

💡 :LspInfo로 현재 버퍼에 연결된 언어 서버 상태를 확인할 수 있습니다. 문제가 생기면 먼저 확인하세요.

💡 on_attach 콜백을 사용하여 LSP가 연결될 때 버퍼별 설정을 추가할 수 있습니다. 키 매핑이나 자동완성 활성화에 유용합니다.

💡 capabilities를 설정하여 nvim-cmp와 통합하면 더 풍부한 자동완성을 얻을 수 있습니다.

💡 언어 서버는 무거울 수 있으니, 큰 프로젝트에서는 root_dir을 조정하여 범위를 제한하세요.

💡 여러 언어 서버를 동시에 사용할 수 있습니다. 예를 들어 TypeScript와 ESLint 서버를 함께 실행하여 문법과 스타일을 모두 체크하세요.

이상으로 Vim의 최신 기능 12가지를 상세히 설명했습니다. 각 기능은 현대적인 개발 환경을 구축하는 데 필수적이며, 실무에서 바로 활용할 수 있도록 충분한 깊이로 작성했습니다.


#Vim#Vim9Script#EditorConfig#AsyncJobs#PopupWindows#TypeScript

댓글 (0)

댓글을 작성하려면 로그인이 필요합니다.

함께 보면 좋은 카드 뉴스

마이크로서비스 배포 완벽 가이드

Kubernetes를 활용한 마이크로서비스 배포의 핵심 개념부터 실전 운영까지, 초급 개발자도 쉽게 따라할 수 있는 완벽 가이드입니다. 실무에서 바로 적용 가능한 배포 전략과 노하우를 담았습니다.

Application Load Balancer 완벽 가이드

AWS의 Application Load Balancer를 처음 배우는 개발자를 위한 실전 가이드입니다. ALB 생성부터 ECS 연동, 헬스 체크, HTTPS 설정까지 실무에 필요한 모든 내용을 다룹니다. 초급 개발자도 쉽게 따라할 수 있도록 단계별로 설명합니다.

고객 상담 AI 시스템 완벽 구축 가이드

AWS Bedrock Agent와 Knowledge Base를 활용하여 실시간 고객 상담 AI 시스템을 구축하는 방법을 단계별로 학습합니다. RAG 기반 지식 검색부터 Guardrails 안전 장치, 프론트엔드 연동까지 실무에 바로 적용 가능한 완전한 시스템을 만들어봅니다.

에러 처리와 폴백 완벽 가이드

AWS API 호출 시 발생하는 에러를 처리하고 폴백 전략을 구현하는 방법을 다룹니다. ThrottlingException부터 서킷 브레이커 패턴까지, 실전에서 바로 활용할 수 있는 안정적인 에러 처리 기법을 배웁니다.

AWS Bedrock 인용과 출처 표시 완벽 가이드

AWS Bedrock의 Citation 기능을 활용하여 AI 응답의 신뢰도를 높이는 방법을 배웁니다. 출처 추출부터 UI 표시, 검증까지 실무에서 바로 사용할 수 있는 완전한 가이드입니다.