Skip to content

Step 3-A — 명령어 입력 기반 (history · InputRules · keymap)

상태: ✅ 완료 (2026-04-14) 목표: 슬래시 명령 메뉴(3-B) 를 구현하기 전에, 파워유저가 타이핑과 단축키만으로 모든 편집을 수행할 수 있는 기반을 마련한다.


목차

  1. 설치된 의존성
  2. 추가된 파일
  3. 플러그인 구성
  4. 제공되는 입력 수단
  5. 검증 결과
  6. 알려진 제한 / 3-B 에서 해결할 것

설치된 의존성

prosemirror-history      ^1.4.x  — undo/redo 스택 관리
prosemirror-inputrules   ^1.4.x  — 타이핑 중 자동 변환 규칙 엔진
prosemirror-schema-list  ^1.5.x  — splitListItem / liftListItem / sinkListItem

추가된 파일

src/plugins/input-rules.ts (신규)

prosemirror-inputrules 의 헬퍼(wrappingInputRule, textblockTypeInputRule, smartQuotes, emDash, ellipsis) 를 조합하여 Markdown 스타일 자동 변환 규칙을 정의. 스키마 존재 여부를 체크하여 조건부로 규칙을 추가한다.

적용 규칙:

패턴변환 결과
> (공백 포함)blockquote 래핑
- / * / + bullet list 래핑
숫자. ordered list 래핑 (시작 번호 인식)
```code block 변환
# ~ ###### heading 1~6 변환 (# 개수로 레벨 결정)
"..." / '...'스마트 인용 부호
--em-dash (—)
...ellipsis (…)

src/plugins/keymap.ts (신규)

prosemirror-keymap + prosemirror-commands + prosemirror-history + prosemirror-schema-list 를 조합한 확장 키맵.

동작
Mod-zundo
Mod-y, Shift-Mod-zredo
Mod-btoggle strong
Mod-itoggle em
Mod-`toggle inline code
Enter(리스트 안) splitListItem
Tab(리스트 안) sinkListItem — 중첩 들여쓰기
Shift-Tab(리스트 안) liftListItem — 내어쓰기

Mod = macOS Cmd, Windows/Linux Ctrl

src/index.ts (수정)

플러그인 배열 확장. 순서 중요:

ts
plugins: [
  history(),                 // 1. 히스토리 트래킹 (가장 먼저)
  buildInputRules(schema),   // 2. 타이핑 자동 변환
  buildKeymap(schema),       // 3. 확장 키맵 (마크, 리스트, undo)
  keymap(baseKeymap),        // 4. 기본 키맵 (fallback)
]

ProseMirror는 플러그인을 앞에서부터 순차 처리 하며, 먼저 handleKeyDown 을 처리한 플러그인이 이기면 뒤 플러그인은 호출되지 않는다. 따라서:

  • 리스트 안에서 EnterbuildKeymapsplitListItem 으로 처리
  • 리스트 밖에서 EnterbaseKeymapcreateParagraphNear 등으로 처리

index.html (수정)

노란색 힌트 박스 추가 — 사용자가 열자마자 주요 입력 방식을 안내.


플러그인 구성

┌──────────────────────────────────────────┐
│  NewtilEditor Web Component               │
│                                           │
│  EditorView                               │
│    ├─ history()            ← undo/redo    │
│    ├─ buildInputRules()    ← 타이핑 변환  │
│    ├─ buildKeymap()        ← 확장 키      │
│    └─ keymap(baseKeymap)   ← 기본 키      │
│                                           │
│  Schema: prosemirror-markdown 기본        │
└──────────────────────────────────────────┘

제공되는 입력 수단

Step 3-A 시점에서 슬래시 메뉴 없이도 가능해진 것들:

블록 만들기 (Markdown 타이핑)

  • # 제목 → H1 제목
  • ## 제목 → H2 제목
  • ### 제목 → H3 제목
  • - 항목 → 불릿 리스트
  • 1. 항목 → 번호 리스트
  • > 인용 → blockquote
  • ``` + Enter → 코드 블럭

인라인 서식 (단축키)

  • Mod-B → 굵게 (선택 영역 토글)
  • Mod-I → 기울임
  • Mod-` → 인라인 코드

구조 조작

  • Mod-Z → 되돌리기
  • Mod-Shift-Z / Mod-Y → 다시 실행
  • 리스트 안에서 Tab → 중첩 들여쓰기
  • 리스트 안에서 Shift-Tab → 내어쓰기
  • 리스트 안에서 Enter → 새 리스트 항목
  • 리스트 안에서 Enter (빈 항목) → 리스트 탈출 (baseKeymap 연계)

검증 결과

명령결과
npm run typecheck✅ 오류 0건
npm run build✅ ESM 7.70KB + CJS 8.33KB + DTS
npm run dev✅ HMR 정상, 3개 신규 의존성 자동 최적화

브라우저 수동 확인 (http://localhost:5174):

  • # + 스페이스 → heading 생성
  • - + 스페이스 → 불릿 리스트 생성
  • 리스트 안에서 Enter → 새 항목 생성
  • Cmd+B + 타이핑 → 굵게 입력 모드
  • 편집 후 Cmd+Z → 이전 상태로 되돌리기
  • 리스트 항목에서 Tab → 들여쓰기
  • 하단 Markdown 패널에 올바른 #, -, ** 형태로 직렬화 확인

알려진 제한 / 3-B 에서 해결할 것

제한해결 예정
단축키·Markdown 문법을 몰라도 명령 접근할 방법 없음Step 3-B (슬래시 메뉴)
링크 삽입 UI 없음Step 3-B (Link 명령 + URL 모달)
이미지 삽입 UI 없음Step 3-B (Image 명령 + URL 모달)
H4~H6 는 Markdown 타이핑으로만 가능Step 3-B (Heading 4-6 드롭다운)
선택 영역 기반 툴바 없음Step 4
현재 mark 활성화 상태 시각 표시 없음Step 4 (floating toolbar)
placeholder, readonly 속성 없음Step 4

설계 변경 이력

2026-04-14 — Step 3 재정의

원래 Step 3 는 "툴바 / 단축키 / InputRules" 였으나, 슬래시 명령 메뉴가 주 UX 여야 한다는 사용자 결정에 따라 재구성:

  • Step 3: 명령어 입력 시스템 (3-A 기반 + 3-B 슬래시 메뉴)
  • Step 4 (신규): 툴바 + 속성 + 이벤트
  • Step 5: CSS 격리 + 테마 (기존 Step 4)
  • Step 6: React/Vue 래퍼 (기존 Step 5)
  • Step 7: npm 배포 (기존 Step 6)