using System.Windows; using AxCopilot.SDK; using AxCopilot.Services; using AxCopilot.Themes; namespace AxCopilot.Handlers; /// /// L21-4: 키보드 단축키 참조 사전 핸들러. "key" 프리픽스로 사용합니다. /// /// 예: key → 앱 카테고리 목록 /// key win → Windows 단축키 /// key vscode → VS Code 단축키 /// key chrome → Chrome/Edge 단축키 /// key vim → Vim 명령 /// key excel → Excel 단축키 /// key terminal → Windows Terminal 단축키 /// key <키워드> → 전체 단축키에서 키워드 검색 (예: key 찾기, key find) /// Enter → 단축키 복사. /// public class KeyHandler : IActionHandler { public string? Prefix => "key"; public PluginMetadata Metadata => new( "Key", "키보드 단축키 참조 사전 — Windows·VS Code·Chrome·Vim·Excel", "1.0", "AX"); private record Shortcut(string Keys, string Description, string App); private static readonly Shortcut[] All = [ // Windows new("Win + D", "바탕화면 보기/복원", "win"), new("Win + E", "파일 탐색기 열기", "win"), new("Win + L", "PC 잠금", "win"), new("Win + R", "실행 대화상자", "win"), new("Win + S", "Windows 검색", "win"), new("Win + V", "클립보드 히스토리", "win"), new("Win + X", "빠른 링크 메뉴 (전원 메뉴)", "win"), new("Win + Tab", "작업 보기(가상 데스크톱)", "win"), new("Win + Ctrl + D", "새 가상 데스크톱 추가", "win"), new("Win + Ctrl + →/←", "가상 데스크톱 전환", "win"), new("Win + ↑", "창 최대화", "win"), new("Win + ↓", "창 최소화/복원", "win"), new("Win + ←/→", "창 좌/우 절반 스냅", "win"), new("Win + Shift + S", "화면 부분 캡처 (Snipping Tool)", "win"), new("Alt + Tab", "실행 중인 앱 전환", "win"), new("Alt + F4", "현재 창 닫기", "win"), new("Ctrl + Shift + Esc", "작업 관리자 직접 열기", "win"), new("Ctrl + Alt + Del", "보안 옵션 화면", "win"), new("F2", "선택 항목 이름 변경", "win"), new("F5", "새로고침", "win"), new("F11", "전체화면 토글", "win"), new("Win + . (점)", "이모지 피커", "win"), new("Win + P", "프로젝션 모드 선택 (다중 모니터)", "win"), new("Win + I", "Windows 설정", "win"), new("PrtSc", "전체 화면 캡처 → 클립보드", "win"), new("Alt + PrtSc", "현재 창 캡처 → 클립보드", "win"), // VS Code new("Ctrl + P", "파일 빠른 열기", "vscode"), new("Ctrl + Shift + P", "명령 팔레트", "vscode"), new("Ctrl + `", "통합 터미널 열기/닫기", "vscode"), new("Ctrl + B", "사이드바 토글", "vscode"), new("Ctrl + J", "패널 토글(터미널·출력)", "vscode"), new("Ctrl + F", "파일 내 찾기", "vscode"), new("Ctrl + H", "파일 내 찾아 바꾸기", "vscode"), new("Ctrl + Shift + F", "전체 검색", "vscode"), new("Ctrl + Shift + H", "전체 찾아 바꾸기", "vscode"), new("Ctrl + G", "줄 이동", "vscode"), new("Ctrl + /", "줄 주석 토글", "vscode"), new("Alt + ↑/↓", "현재 줄 위/아래 이동", "vscode"), new("Alt + Shift + ↑/↓","현재 줄 위/아래 복사", "vscode"), new("Ctrl + D", "다음 동일 단어 선택", "vscode"), new("Ctrl + Shift + L", "동일 단어 모두 선택", "vscode"), new("Ctrl + Shift + K", "현재 줄 삭제", "vscode"), new("Ctrl + Enter", "아래에 새 줄 추가", "vscode"), new("Ctrl + Shift + Enter", "위에 새 줄 추가", "vscode"), new("F12", "정의로 이동", "vscode"), new("Alt + F12", "정의 미리보기", "vscode"), new("Shift + F12", "모든 참조 찾기", "vscode"), new("F2", "기호 이름 변경(리팩터링)", "vscode"), new("Ctrl + .", "빠른 수정 (Quick Fix)", "vscode"), new("Ctrl + K Ctrl + F","선택 영역 포맷", "vscode"), new("Shift + Alt + F", "전체 파일 포맷", "vscode"), new("Ctrl + Z / Y", "실행 취소 / 다시 실행", "vscode"), new("Ctrl + W", "현재 탭 닫기", "vscode"), new("Ctrl + Tab", "에디터 탭 전환", "vscode"), new("Ctrl + \\", "에디터 분할", "vscode"), new("Ctrl + 1/2/3", "에디터 그룹 포커스", "vscode"), // Chrome / Edge new("Ctrl + T", "새 탭 열기", "chrome"), new("Ctrl + W", "현재 탭 닫기", "chrome"), new("Ctrl + Shift + T", "닫은 탭 다시 열기", "chrome"), new("Ctrl + Tab", "다음 탭으로 이동", "chrome"), new("Ctrl + Shift + Tab","이전 탭으로 이동", "chrome"), new("Ctrl + 1~8", "번호로 탭 이동", "chrome"), new("Ctrl + L", "주소창 포커스", "chrome"), new("Ctrl + D", "현재 페이지 북마크", "chrome"), new("Ctrl + F", "페이지 내 찾기", "chrome"), new("Ctrl + H", "방문 기록", "chrome"), new("Ctrl + J", "다운로드 목록", "chrome"), new("Ctrl + Shift + J", "개발자 도구 콘솔", "chrome"), new("F12", "개발자 도구 토글", "chrome"), new("F5 / Ctrl + R", "페이지 새로고침", "chrome"), new("Ctrl + Shift + R", "캐시 무시 새로고침", "chrome"), new("Ctrl + +/-", "페이지 확대/축소", "chrome"), new("Ctrl + 0", "확대/축소 기본값 복원", "chrome"), new("Alt + ← / →", "뒤로/앞으로", "chrome"), new("Ctrl + N", "새 창 열기", "chrome"), new("Ctrl + Shift + N", "시크릿 창", "chrome"), new("Ctrl + Shift + B", "북마크 바 토글", "chrome"), new("Ctrl + U", "페이지 소스 보기", "chrome"), // Vim new("i", "삽입 모드 진입", "vim"), new("Esc", "노멀 모드로 복귀", "vim"), new(":w", "저장", "vim"), new(":q", "종료", "vim"), new(":wq / :x", "저장 후 종료", "vim"), new(":q!", "저장 없이 강제 종료", "vim"), new("h/j/k/l", "좌/하/상/우 이동", "vim"), new("w / b", "단어 앞/뒤로 이동", "vim"), new("gg / G", "파일 처음 / 끝으로 이동", "vim"), new("0 / $", "줄 처음 / 끝으로 이동", "vim"), new("dd", "현재 줄 삭제", "vim"), new("yy", "현재 줄 복사(yank)", "vim"), new("p / P", "붙여넣기 (다음/현재 위치)", "vim"), new("u / Ctrl + R", "실행 취소 / 다시 실행", "vim"), new("/keyword", "앞으로 검색", "vim"), new("n / N", "다음/이전 검색 결과", "vim"), new(":%s/old/new/g", "전체 치환", "vim"), new("v / V", "비주얼 모드 (문자/줄)", "vim"), new("Ctrl + V", "비주얼 블록 모드", "vim"), new(":split / :vsplit", "수평/수직 창 분할", "vim"), new("Ctrl + W + W", "다음 창으로 포커스 이동", "vim"), new(":noh", "검색 하이라이트 제거", "vim"), new(">> / <<", "들여쓰기 추가/제거", "vim"), // Excel new("Ctrl + Arrow", "데이터 끝으로 이동", "excel"), new("Ctrl + Shift + Arrow","데이터 끝까지 선택", "excel"), new("Ctrl + Home / End","셀 A1 / 마지막 셀로 이동", "excel"), new("Ctrl + Space", "열 전체 선택", "excel"), new("Shift + Space", "행 전체 선택", "excel"), new("Ctrl + Shift + +", "행/열 삽입", "excel"), new("Ctrl + -", "행/열 삭제", "excel"), new("Ctrl + D", "아래로 채우기", "excel"), new("Ctrl + R", "오른쪽으로 채우기", "excel"), new("Alt + =", "SUM 자동 합계", "excel"), new("F4", "참조 절대/상대 전환 ($)", "excel"), new("Ctrl + 1", "셀 서식 창", "excel"), new("Ctrl + ;", "현재 날짜 입력", "excel"), new("Ctrl + Shift + ;", "현재 시간 입력", "excel"), new("F2", "셀 편집 모드", "excel"), new("Alt + Enter", "셀 내 줄바꿈", "excel"), new("Ctrl + Z / Y", "실행 취소 / 다시 실행", "excel"), new("Ctrl + F", "찾기", "excel"), new("Ctrl + H", "찾아 바꾸기", "excel"), new("Ctrl + Shift + L", "필터 자동 설정 토글", "excel"), // Windows Terminal new("Ctrl + Shift + T", "새 탭 열기", "terminal"), new("Ctrl + Shift + W", "탭 닫기", "terminal"), new("Ctrl + Tab", "다음 탭 이동", "terminal"), new("Ctrl + Shift + 1~9","번호 탭으로 이동", "terminal"), new("Ctrl + Shift + D", "창 복제", "terminal"), new("Alt + Shift + D", "창 분할 (자동 방향)", "terminal"), new("Alt + Shift + +", "수평 분할", "terminal"), new("Alt + Shift + -", "수직 분할", "terminal"), new("Alt + Arrow", "분할된 창 간 포커스 이동", "terminal"), new("Ctrl + +/-", "폰트 크기 변경", "terminal"), new("Ctrl + F", "터미널 내 텍스트 검색", "terminal"), new("Ctrl + Shift + P", "명령 팔레트", "terminal"), new("Ctrl + Shift + F", "전체 화면 토글", "terminal"), ]; public Task> GetItemsAsync(string query, CancellationToken ct) { var q = query.Trim(); var items = new List(); if (string.IsNullOrWhiteSpace(q)) { items.Add(new LauncherItem("키보드 단축키 참조 사전", "key win / vscode / chrome / vim / excel / terminal / key <키워드 검색>", null, null, Symbol: "\uE92E")); AddAppOverview(items); return Task.FromResult>(items); } var parts = q.Split(' ', StringSplitOptions.RemoveEmptyEntries); var sub = parts[0].ToLowerInvariant(); // 앱 카테고리 조회 var catKeys = new Dictionary { ["win"] = ["win", "windows"], ["vscode"] = ["vscode", "code", "vs"], ["chrome"] = ["chrome", "edge", "browser"], ["vim"] = ["vim", "vi", "neovim"], ["excel"] = ["excel", "spreadsheet"], ["terminal"] = ["terminal", "wt"], }; foreach (var (cat, aliases) in catKeys) { if (aliases.Contains(sub)) { var catItems = All.Where(s => s.App == cat).ToList(); var catName = cat switch { "win" => "Windows", "vscode" => "VS Code", "chrome" => "Chrome / Edge", "vim" => "Vim", "excel" => "Excel", "terminal" => "Windows Terminal", _ => cat }; items.Add(new LauncherItem($"{catName} 단축키 {catItems.Count}개", "", null, null, Symbol: "\uE92E")); foreach (var s in catItems) items.Add(new LauncherItem(s.Keys, s.Description, null, ("copy", s.Keys), Symbol: "\uE92E")); return Task.FromResult>(items); } } // 키워드 검색 (전체) var keyword = string.Join(" ", parts); var found = All.Where(s => s.Keys.Contains(keyword, StringComparison.OrdinalIgnoreCase) || s.Description.Contains(keyword, StringComparison.OrdinalIgnoreCase)).ToList(); if (found.Count > 0) { items.Add(new LauncherItem($"'{keyword}' 검색 결과: {found.Count}개", "", null, null, Symbol: "\uE92E")); foreach (var s in found) { var appLabel = s.App.ToUpperInvariant(); items.Add(new LauncherItem(s.Keys, $"[{appLabel}] {s.Description}", null, ("copy", s.Keys), Symbol: "\uE92E")); } } else { items.Add(new LauncherItem($"'{keyword}' 결과 없음", "key win / vscode / chrome / vim / excel / terminal", null, null, Symbol: "\uE783")); AddAppOverview(items); } return Task.FromResult>(items); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { if (item.Data is ("copy", string text)) { try { System.Windows.Application.Current.Dispatcher.Invoke( () => Clipboard.SetText(text)); NotificationService.Notify("Key", "클립보드에 복사했습니다."); } catch { } } return Task.CompletedTask; } private static void AddAppOverview(List items) { var apps = new (string Key, string Label, int Count)[] { ("win", "Windows 단축키", All.Count(s => s.App == "win")), ("vscode", "VS Code 단축키", All.Count(s => s.App == "vscode")), ("chrome", "Chrome / Edge 단축키", All.Count(s => s.App == "chrome")), ("vim", "Vim 명령", All.Count(s => s.App == "vim")), ("excel", "Excel 단축키", All.Count(s => s.App == "excel")), ("terminal", "Windows Terminal 단축키", All.Count(s => s.App == "terminal")), }; foreach (var (key, label, count) in apps) items.Add(new LauncherItem($"key {key}", $"{label} ({count}개)", null, null, Symbol: "\uE92E")); } }