Skip to content

fix: Ctrl+N,M 수식 단축키 + 수식 삭제 오류 수정 (closes #767, closes #766)#786

Closed
oksure wants to merge 2 commits into
edwardkim:develfrom
oksure:contrib/chord-equation-shortcut
Closed

fix: Ctrl+N,M 수식 단축키 + 수식 삭제 오류 수정 (closes #767, closes #766)#786
oksure wants to merge 2 commits into
edwardkim:develfrom
oksure:contrib/chord-equation-shortcut

Conversation

@oksure

@oksure oksure commented May 10, 2026

Copy link
Copy Markdown
Contributor

요약

PR #739 (수식 신규 입력) 후속 버그 2건 수정:

1. Ctrl+N,M 단축키 매핑 누락 (#767)

chordMapNm/(한글 IME) → insert:equation 매핑 추가.
기존: Ctrl+N 후 M 입력 시 chordMapN['m'] 미발견 → preventDefault() 미호출 → 브라우저 기본 동작(새 창).

2. 수식 객체 Backspace/Delete 삭제 오류 (#766)

수식 객체 선택 후 Backspace 시 deleteShapeControl 호출 → Control::Equation 타입 불일치로 "Shape이 아닙니다" 오류.

수정 내용:

  • delete_equation_control_native + WASM export deleteEquationControl 신규
  • 키보드 핸들러 4개소 삭제 디스패치에 ref.type === 'equation' 분기 추가:
    • input-handler-keyboard.ts (Backspace, Ctrl+X, Ctrl+X in Ctrl handler)
    • input-handler.ts (cut handler)
    • input-handler-picture.ts (deleteObjectControl helper)
    • command/commands/insert.ts (object:delete command)
  • wasm-bridge.tsdeleteEquationControl wrapper 추가

검증

  • cargo test --release ✅ ALL GREEN
  • cargo clippy -- -D warnings ✅ 경고 없음
  • tsc --noEmit ✅ (기존 @wasm 모듈 에러 외 신규 없음)

감사합니다.

…edwardkim#766)

1. chordMapN에 'm'/'ㅡ' → 'insert:equation' 매핑 추가 (edwardkim#767)
   - Ctrl+N 후 M 키 입력 시 브라우저 새 창 대신 수식 삽입 동작

2. 수식 객체 Backspace/Delete 삭제 시 "Shape이 아닙니다" 오류 수정 (edwardkim#766)
   - deleteEquationControl WASM API 신규 추가
   - 키보드 핸들러 삭제 디스패치에 equation 분기 추가
   - input-handler, input-handler-keyboard, input-handler-picture,
     insert commands 모두 equation 분기 추가
Copilot AI review requested due to automatic review settings May 10, 2026 09:39

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

수식 입력 단축키(Ctrl+N,M) 매핑 누락을 보완하고, 수식 컨트롤이 선택된 상태에서 Backspace/Delete/Cut으로 삭제할 때 Shape 삭제 경로로 잘못 디스패치되던 오류를 수정하기 위한 PR입니다.

Changes:

  • Ctrl+N 코드 단축키(chord) 맵에 m/ㅡinsert:equation 매핑 추가
  • Rust/WASM에 deleteEquationControl API 추가 및 Studio 측 브리지 래퍼 추가
  • Studio 키보드/컷/오브젝트 삭제 경로들에 ref.type === 'equation' 분기 추가

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
src/wasm_api.rs WASM export deleteEquationControl 추가
src/document_core/commands/object_ops.rs delete_equation_control_native 구현 추가
rhwp-studio/src/core/wasm-bridge.ts deleteEquationControl() TS 래퍼 추가
rhwp-studio/src/engine/input-handler-keyboard.ts chordMapN에 수식 단축키 추가 및 키보드 삭제/컷 경로에 equation 분기 추가
rhwp-studio/src/engine/input-handler.ts cutObject 처리에서 equation 삭제 분기 추가
rhwp-studio/src/engine/input-handler-picture.ts deleteObjectControl에서 equation 삭제 분기 추가
rhwp-studio/src/command/commands/insert.ts object:delete에서 equation 삭제 분기 추가

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +3393 to +3413
/// 수식(Equation) 컨트롤을 문단에서 삭제한다.
pub fn delete_equation_control_native(
&mut self,
section_idx: usize,
parent_para_idx: usize,
control_idx: usize,
) -> Result<String, HwpError> {
if section_idx >= self.document.sections.len() {
return Err(HwpError::RenderError(format!("구역 인덱스 {} 범위 초과", section_idx)));
}
let section = &mut self.document.sections[section_idx];
if parent_para_idx >= section.paragraphs.len() {
return Err(HwpError::RenderError(format!("문단 인덱스 {} 범위 초과", parent_para_idx)));
}
let para = &mut section.paragraphs[parent_para_idx];
if control_idx >= para.controls.len() {
return Err(HwpError::RenderError(format!("컨트롤 인덱스 {} 범위 초과", control_idx)));
}
if !matches!(&para.controls[control_idx], Control::Equation(_)) {
return Err(HwpError::RenderError("지정된 컨트롤이 수식이 아닙니다".to_string()));
}
para.char_count -= 8;
}

Self::reflow_paragraph_line_segs_after_control_delete(para, &self.styles, self.dpi);
Comment thread src/wasm_api.rs
Comment on lines +2049 to +2065
/// 수식 컨트롤을 문단에서 삭제한다.
///
/// 반환: JSON `{"ok":true}`
#[wasm_bindgen(js_name = deleteEquationControl)]
pub fn delete_equation_control(
&mut self,
section_idx: u32,
parent_para_idx: u32,
control_idx: u32,
) -> Result<String, JsValue> {
self.delete_equation_control_native(
section_idx as usize,
parent_para_idx as usize,
control_idx as usize,
)
.map_err(|e| e.into())
}
Comment on lines +593 to +595
deleteEquationControl(sec: number, para: number, ci: number): { ok: boolean } {
if (!this.doc) throw new Error('문서가 로드되지 않았습니다');
return JSON.parse(this.doc.deleteEquationControl(sec, para, ci));
if (ref.type === 'image') {
wasm.deletePictureControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
if (ref.type === 'image') {
wasm.deletePictureControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
if (ref.type === 'image') {
wasm.deletePictureControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
if (ref.type === 'image') {
wasm.deletePictureControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
Comment on lines 260 to 266
export function deleteObjectControl(this: any, ref: { sec: number; ppi: number; ci: number; type: 'image' | 'shape' | 'equation' | 'group' | 'line' }): void {
if (ref.type === 'shape' || ref.type === 'group' || ref.type === 'line') {
this.wasm.deleteShapeControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
this.wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
} else {
this.wasm.deletePictureControl(ref.sec, ref.ppi, ref.ci);
if (ref.type === 'shape' || ref.type === 'line' || ref.type === 'group') {
services.wasm.deleteShapeControl(ref.sec, ref.ppi, ref.ci);
} else if (ref.type === 'equation') {
services.wasm.deleteEquationControl(ref.sec, ref.ppi, ref.ci);
Copilot 리뷰 반영: 수식 삭제 후 남은 컨트롤 높이 계산에서
Control::Equation 분기 누락 → 수식만 남은 문단의 line_segs가
0으로 리셋되는 가능성 수정.

참고: 셀 내 수식 삭제(cellIdx/cellParaIdx 전달)는 현재
deleteEquation의 스코프 밖 — 본문 수식 삭제만 지원.
@oksure

oksure commented May 10, 2026

Copy link
Copy Markdown
Contributor Author

Copilot 리뷰 피드백 반영 (b376a0d):

reflow 높이 계산 수정: reflow_paragraph_line_segs_after_control_delete의 남은 컨트롤 높이 계산에 Control::Equation 분기 추가. 수식만 남은 문단에서 line_segs 높이가 0으로 리셋되는 가능성 수정.

셀 내 수식 삭제 (cellIdx/cellParaIdx): 현재 deleteEquationControl은 본문 수준 수식만 지원. Issue #766은 본문 수식 Backspace 삭제 오류이므로 스코프 범위 내. 셀 내 수식 삭제 확장은 필요 시 후속 이슈로 분리 가능합니다.

edwardkim added a commit that referenced this pull request May 10, 2026
PR #786 영역 chordMapN['m'] / ['ㅡ'] 매핑 정정 영역 영역 chord 2번째 키 영역만 처리. 그러나 chord 1번째 키 (Ctrl+N) 영역 영역 InputHandler textarea keydown listener 영역 영역만 차단 — textarea 미포커스 상태 (메뉴 바 / button 클릭 후 등) 영역 영역 keydown 영역 document 발동 영역 setupGlobalShortcuts 영역 영역 InputHandler.active 영역 영역 return → Ctrl+N 차단 부재 → 크롬 새 창 발동.

정정: setupGlobalShortcuts 영역 영역 InputHandler 활성 시점 영역 영역도 Ctrl+N 차단 추가:
- e.preventDefault() (크롬 새 창 차단)
- inputHandler._pendingChordN = true (chord 1번째 키 활성화)
- inputHandler.focus() (textarea 포커스 복귀 — 후속 키 영역 InputHandler chord 2번째 키 처리)

작업지시자 시각 검증 영역 영역 발견:
"수식 객체 삭제 통과. Ctrl+N 누르면 크롬 웹브라우저 단축키가 먼저 발동."

PR #740 자기 정정 패턴 정합 — devel HEAD 잠재 결함 영역 영역 본 PR 의 신규 호출 영역 영역 노출 영역 자기 정정 commit.
edwardkim added a commit that referenced this pull request May 10, 2026
…cut 회피)

PR #786 영역 chordMapN['m'] / ['ㅡ'] 매핑 정정 영역 영역 chord 2번째 키 영역만 처리. 그러나 Chrome / Edge 영역 영역 Ctrl+N (새 창) 영역 영역 OS-level reserved shortcut 영역 영역 JS preventDefault() 차단 불가 영역 영역 chord 1번째 키 영역 영역 자체 발동 부재.

작업지시자 결정: chord 키 영역 영역 Ctrl+N → Ctrl+M 변경.

정정 영역:
- input-handler-keyboard.ts: chordMapN → chordMapM, _pendingChordN → _pendingChordM, chord 1번째 키 영역 영역 'm'/'M'/'ㅡ' (Ctrl+M)
- insert.ts: shortcutLabel 'Ctrl+N,M' → 'Ctrl+M,M' (수식)
- table.ts: shortcutLabel 'Ctrl+N,F' → 'Ctrl+M,F' (계산식)
- edit.ts: shortcutLabel 'Ctrl+N,K' → 'Ctrl+M,K' (누름틀 고치기)
- page.ts: shortcutLabel 'Ctrl+N,S' → 'Ctrl+M,S' (감추기)

자기 정정 commit (7bc2dc0, setupGlobalShortcuts Ctrl+N chord 시작 보강) revert 영역 영역 fb1a22c 머지 — 효과 없는 정정 영역 영역 정합성 영역 영역 보존.

작업지시자 시각 검증 영역 영역 발견 (PR #786 후속): "Ctrl+N 누르면 크롬 웹브라우저 단축키가 먼저 발동."

본질: Chrome reserved shortcut 영역 영역 JS 차단 불가 영역 영역 chord 키 변경 영역 영역 회피.

PR #740 자기 정정 패턴 정합.
edwardkim added a commit that referenced this pull request May 10, 2026
작업지시자 시각 검증 영역 영역 발견: '한글 IME 상태에서도 적용되어야 합니다.'

본질: 한국어 IME 합성 중 영역 영역 e.key === 'Process' (Chrome 영역 영역 IME 합성 중 영역 영역 일관 영역 영역) 영역 영역 line 201 영역 영역 IME 합성 중 영역 영역 즉시 return → chord 1번째/2번째 키 활성화 부재.

정정 (input-handler-keyboard.ts +18):
- chord 1번째 키 영역 영역 IME 합성 중 영역 영역 e.code === 'KeyM' 영역 영역 활성화
- chord 2번째 키 영역 영역 _pendingChordM 활성화 시 e.code 영역 영역 chordMapM lookup (KeyM/KeyN/KeyS/KeyF/KeyK → 'm'/'n'/'s'/'f'/'k')

본 환경 영역 영역 IME 합성 중 영역 영역 chord 1/2번째 키 영역 영역 모두 e.code 영역 영역 판별 영역 영역 한글 IME 상태 영역 영역 정합 동작.

PR #740 자기 정정 패턴 정합.
edwardkim added a commit that referenced this pull request May 10, 2026
… 오류 수정

PR #739 (수식 신규 입력) 후속 발견 결함 2건 정정 + 본 환경 자기 정정 4건 (Chrome reserved shortcut 회피 + IME 합성 중 chord 활성화).

본 PR cherry-pick (2 commits):
- 4a8772b: Issue #767 (Ctrl+N,M 단축키 매핑) + Issue #766 (수식 객체 삭제 오류) 정정
- a86668e: Copilot 리뷰 — reflow_paragraph_line_segs Equation 높이 반영

본 환경 자기 정정 commits (4건):
- 7bc2dc0: setupGlobalShortcuts Ctrl+N chord 시작 보강 시도 (Chrome reserved shortcut 영역 영역 효과 없음)
- fb1a22c: 7bc2dc0 revert (정합성 회복)
- 924ca0f: chord 키 Ctrl+N → Ctrl+M 변경 (작업지시자 결정 — Chrome reserved shortcut 회피)
- e906c1b: Ctrl+M chord IME 합성 중 활성화 (한글 IME e.code 판별)

본질 — Chrome / Edge 영역 영역 Ctrl+N (새 창) 영역 영역 OS-level reserved shortcut 영역 영역 JS preventDefault() 차단 불가 영역 영역 chord 키 영역 영역 Ctrl+M 영역 영역 변경. 한글 IME 합성 중 영역 영역 e.key === 'Process' 영역 영역 e.code (KeyM/KeyN/KeyS/KeyF/KeyK) 판별 영역 영역 chord 활성화.

정정 영역:
- input-handler-keyboard.ts: chordMapN → chordMapM, _pendingChordN → _pendingChordM, chord 1/2번째 키 영역 영역 Ctrl+M + IME 합성 중 e.code 판별
- shortcutLabel: Ctrl+N,? → Ctrl+M,? (insert/table/edit/page)
- delete_equation_control_native + WASM export deleteEquationControl 신규
- 키보드 핸들러 4개소 영역 'equation' 분기 추가

검증:
- cargo build/test/clippy --release ALL GREEN
- tsc --noEmit ✅
- 광범위 sweep 170/170 same
- WASM 4.68 MB 재빌드
- 작업지시자 웹 에디터 시각 검증 ✅ 통과 (수식 객체 삭제 + Ctrl+M,M 영문/한글 IME)

closes #767 + #766
@edwardkim

Copy link
Copy Markdown
Owner

@oksure 검토 완료했습니다. 감사합니다.

처리 결과

Merge commit: ea9531d0 (devel)

본 PR 본질

PR #739 (수식 신규 입력) 후속 발견 결함 2건 정정:

본 환경 자기 정정 (4 commits)

작업지시자 웹 에디터 시각 검증 영역 영역 발견된 결함 영역 영역 본 환경 자기 정정:

  1. **** setupGlobalShortcuts Ctrl+N chord 시작 보강 시도 — Chrome reserved shortcut 영역 영역 효과 없음
  2. fb1a22cb 1번 revert (정합성 회복)
  3. 924ca0f4 chord 키 Ctrl+N → Ctrl+M 변경 (작업지시자 결정) — Chrome / Edge 영역 영역 Ctrl+N (새 창) 영역 영역 OS-level reserved shortcut 영역 영역 JS preventDefault() 차단 불가 영역 영역 chord 키 변경 영역 영역 회피
  4. e906c1b8 Ctrl+M chord IME 합성 중 활성화 — 한글 IME 영역 영역 e.key === 'Process' 영역 영역 e.code (KeyM/KeyN/KeyS/KeyF/KeyK) 판별 영역 영역 chord 활성화

shortcutLabel 갱신: Ctrl+N,M → Ctrl+M,M (수식) / Ctrl+N,F → Ctrl+M,F (계산식) / Ctrl+N,K → Ctrl+M,K (누름틀 고치기) / Ctrl+N,S → Ctrl+M,S (감추기).

검증

  • cargo build/test/clippy --release ALL GREEN
  • tsc --noEmit ✅
  • 광범위 sweep 170/170 same
  • WASM 4.68 MB 재빌드
  • 작업지시자 웹 에디터 시각 검증 ✅ 통과 (수식 객체 삭제 + Ctrl+M,M 영문/한글 IME)

Issues #767 + #766 close.

5/11 사이클 1번째 PR — 수고하셨습니다.

@edwardkim

Copy link
Copy Markdown
Owner

Merged. Merge commit: ea9531d

@edwardkim edwardkim closed this May 10, 2026
edwardkim added a commit that referenced this pull request May 10, 2026
PR #786 (closes #767+#766) — PR #739 후속 발견 결함 정정 + 본 환경 자기 정정 4 commits (Chrome reserved shortcut 회피 영역 chord 키 Ctrl+N → Ctrl+M 변경 + IME 합성 중 chord 활성화).

Merge commit: ea9531d
Cherry-pick: 4a8772b + a86668e
자기 정정: 7bc2dc0 (revert 7bc2dc0fb1a22c) + 924ca0f (chord Ctrl+N→Ctrl+M) + e906c1b (IME 합성 중 chord)

5/11 사이클 시작 — orders/20260511.md 신규 등록 (5/10 사이클 27 PR 후 첫 PR).
edwardkim added a commit that referenced this pull request May 10, 2026
5/10 + 5/11 사이클 누적 — 외부 기여자 다수 PR 30+ 머지.

Cargo.toml + rhwp-vscode/package.json + npm/editor/package.json + rhwp-studio/package.json: 0.7.10 → 0.7.11
rhwp-vscode/CHANGELOG.md: [0.7.11] 항목 추가

핵심 변경:
- Skia native raster P8 (#761) + P9 (#769) — Layer IR contract hardening + text replay parity
- HWP3 native 렌더링 (#753) — hwp3-sample10 8 단계 정정 + Git LFS pdf-large/ 신규
- 페이지네이션 정정 (#778) — Task #703 다단 컬럼 분배 회귀 정정
- rhwp-studio 인터랙션 (PR #781/#786/#787/#788) — scrollbar/수식/표 셀/도구 모음 결함 정정
- rhwp-studio editor 신규 기능 (PR #728/#748/#750/#760 등) — 표 편집 Undo/Redo + 다단 설정 + 다수 단축키
@edwardkim edwardkim mentioned this pull request May 10, 2026
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants