SqlHandler.cs (신규, ~280줄, prefix=sql, partial class):
- Keywords[]: 50+ SQL 키워드 + NewlineKeywords HashSet
- Format(): Tokenize() 기반 키워드·괄호·쉼표 들여쓰기 포맷
- Minify(): 공백·괄호 주변 최소화
- TransformKeywords(): 키워드 대소문자 일괄 변환
- BuildStatsItems(): DML유형·테이블·JOIN·WHERE·서브쿼리 분석
- ExtractTables(): FROM/JOIN 테이블 추출 (TableRegex)
- sql select <table>: SELECT 쿼리 템플릿 생성
- [GeneratedRegex]: Whitespace/SpaceAroundParens/Table/SelectCols
TextCaseHandler.cs (신규, ~220줄, prefix=text, partial class):
- CaseItem record: Name/Key/Func<string,string> 13가지 케이스
- Tokenize(): CamelBoundaryRegex + SeparatorRegex 단어 분리
- ToCamel/ToPascal/ToSnake/ToConst/ToKebab/ToDot 구현
- ToSlug(): NormalizationForm.FormD → ASCII 변환 + NonSlugRegex
- 인라인 입력: text camel hello world → helloWorld
- 특정 케이스 선택 시 다른 케이스도 함께 표시
AspectHandler.cs (신규, ~260줄, prefix=aspect):
- AspectPreset record: Ratio/Name/(W,H)[] 9개 프리셋
- BuildFromResolution(): GCD 약분 비율 + 배율별 해상도
- BuildFromRatio(): 프리셋 매칭 또는 기준 너비 5개 계산
- BuildFromRatioAndDim(): 너비/높이 단방향 계산
- BuildCropItems(): 크롭 방향 판별 + FFmpeg crop 파라미터
- TryParseRatio(): :·/ 구분자 + 소수 비율 지원
- Gcd(): 재귀 최대공약수
AbbrHandler.cs (신규, ~260줄, prefix=abbr):
- AbbrEntry record: Short/Full/Description/Category
- 150+개 내장 약어 (웹/개발/DB/보안/클라우드/AI/데이터형식/협업)
- 정확 일치 1개: 약어·원문·설명·카테고리 상세 표시
- 부분 일치: 목록 표시 (Short·Full·Description 검색)
- 카테고리명 직접 입력 → 해당 카테고리 전체 목록
App.xaml.cs (수정): Phase L18 핸들러 4종 RegisterHandler 추가
docs/LAUNCHER_ROADMAP.md (수정): Phase L18 섹션 추가 (✅ 완료)
빌드: 경고 0, 오류 0
304 lines
27 KiB
C#
304 lines
27 KiB
C#
using System.Windows;
|
||
using AxCopilot.SDK;
|
||
using AxCopilot.Services;
|
||
using AxCopilot.Themes;
|
||
|
||
namespace AxCopilot.Handlers;
|
||
|
||
/// <summary>
|
||
/// L18-4: IT·개발 약어 사전 핸들러. "abbr" 프리픽스로 사용합니다.
|
||
///
|
||
/// 예: abbr → 주요 약어 목록
|
||
/// abbr api → API 뜻 + 설명
|
||
/// abbr crud → CRUD 약어 풀이
|
||
/// abbr rest → REST 설명
|
||
/// abbr http → HTTP 약어 목록
|
||
/// Enter → 약어 또는 뜻을 클립보드에 복사.
|
||
/// </summary>
|
||
public class AbbrHandler : IActionHandler
|
||
{
|
||
public string? Prefix => "abbr";
|
||
|
||
public PluginMetadata Metadata => new(
|
||
"Abbr",
|
||
"IT·개발 약어 사전 — API · CRUD · REST · HTTP · SQL 등 내장",
|
||
"1.0",
|
||
"AX");
|
||
|
||
private record AbbrEntry(string Short, string Full, string Description, string Category);
|
||
|
||
// ── 내장 약어 사전 (~150개) ───────────────────────────────────────────────
|
||
private static readonly AbbrEntry[] Entries =
|
||
[
|
||
// 웹/네트워크
|
||
new("API", "Application Programming Interface", "소프트웨어 간 통신 규격", "웹/네트워크"),
|
||
new("REST", "Representational State Transfer", "HTTP 기반 아키텍처 스타일", "웹/네트워크"),
|
||
new("HTTP", "HyperText Transfer Protocol", "웹 통신 프로토콜", "웹/네트워크"),
|
||
new("HTTPS", "HTTP Secure", "TLS/SSL로 암호화된 HTTP", "웹/네트워크"),
|
||
new("HTML", "HyperText Markup Language", "웹 페이지 마크업 언어", "웹/네트워크"),
|
||
new("CSS", "Cascading Style Sheets", "웹 스타일 시트 언어", "웹/네트워크"),
|
||
new("URL", "Uniform Resource Locator", "인터넷 자원 주소", "웹/네트워크"),
|
||
new("URI", "Uniform Resource Identifier", "자원 식별자 (URL의 상위 개념)", "웹/네트워크"),
|
||
new("DNS", "Domain Name System", "도메인 ↔ IP 변환 시스템", "웹/네트워크"),
|
||
new("IP", "Internet Protocol", "인터넷 패킷 전송 프로토콜", "웹/네트워크"),
|
||
new("TCP", "Transmission Control Protocol", "신뢰성 연결형 전송 프로토콜", "웹/네트워크"),
|
||
new("UDP", "User Datagram Protocol", "비연결형 전송 프로토콜", "웹/네트워크"),
|
||
new("SSH", "Secure Shell", "원격 보안 접속 프로토콜", "웹/네트워크"),
|
||
new("FTP", "File Transfer Protocol", "파일 전송 프로토콜", "웹/네트워크"),
|
||
new("SMTP", "Simple Mail Transfer Protocol", "이메일 전송 프로토콜", "웹/네트워크"),
|
||
new("CDN", "Content Delivery Network", "콘텐츠 분산 배포 네트워크", "웹/네트워크"),
|
||
new("VPN", "Virtual Private Network", "가상 사설 네트워크", "웹/네트워크"),
|
||
new("NAT", "Network Address Translation", "사설↔공인 IP 주소 변환", "웹/네트워크"),
|
||
new("CORS", "Cross-Origin Resource Sharing", "브라우저 교차 출처 리소스 공유", "웹/네트워크"),
|
||
new("SSE", "Server-Sent Events", "서버→클라이언트 단방향 스트림", "웹/네트워크"),
|
||
new("WebSocket","WebSocket Protocol", "양방향 실시간 통신 프로토콜", "웹/네트워크"),
|
||
new("gRPC", "Google Remote Procedure Call", "프로토콜 버퍼 기반 RPC 프레임워크", "웹/네트워크"),
|
||
new("GraphQL", "Graph Query Language", "API 쿼리 언어 (Facebook 개발)", "웹/네트워크"),
|
||
new("SOAP", "Simple Object Access Protocol", "XML 기반 웹 서비스 프로토콜", "웹/네트워크"),
|
||
new("WSDL", "Web Services Description Language", "웹 서비스 인터페이스 설명 언어", "웹/네트워크"),
|
||
new("TLS", "Transport Layer Security", "암호화 통신 프로토콜 (SSL 후속)", "웹/네트워크"),
|
||
new("SSL", "Secure Sockets Layer", "암호화 통신 프로토콜 (TLS의 전신)", "웹/네트워크"),
|
||
new("OAuth", "Open Authorization", "위임 인증 표준 프로토콜", "웹/네트워크"),
|
||
new("MIME", "Multipurpose Internet Mail Extensions", "이메일·웹 콘텐츠 타입 표준", "웹/네트워크"),
|
||
|
||
// 개발/프로그래밍
|
||
new("CRUD", "Create Read Update Delete", "기본 데이터 처리 4가지 연산", "개발"),
|
||
new("OOP", "Object-Oriented Programming", "객체 지향 프로그래밍", "개발"),
|
||
new("SOLID", "Single responsibility Open/closed Liskov Interface-segregation Dependency-inversion",
|
||
"객체지향 5가지 설계 원칙", "개발"),
|
||
new("DRY", "Don't Repeat Yourself", "코드 중복 최소화 원칙", "개발"),
|
||
new("KISS", "Keep It Simple, Stupid", "단순하게 유지하라 원칙", "개발"),
|
||
new("YAGNI", "You Aren't Gonna Need It", "필요할 때만 구현하라 원칙", "개발"),
|
||
new("TDD", "Test-Driven Development", "테스트 주도 개발 방법론", "개발"),
|
||
new("BDD", "Behavior-Driven Development", "행동 주도 개발 방법론", "개발"),
|
||
new("DDD", "Domain-Driven Design", "도메인 주도 설계", "개발"),
|
||
new("MVC", "Model-View-Controller", "UI 아키텍처 패턴", "개발"),
|
||
new("MVP", "Model-View-Presenter", "MVC의 변형, Presenter가 View와 Model 중재", "개발"),
|
||
new("MVVM", "Model-View-ViewModel", "WPF·모바일 아키텍처 패턴", "개발"),
|
||
new("SRP", "Single Responsibility Principle", "단일 책임 원칙 (SOLID의 S)", "개발"),
|
||
new("OCP", "Open/Closed Principle", "개방/폐쇄 원칙 (SOLID의 O)", "개발"),
|
||
new("LSP", "Liskov Substitution Principle", "리스코프 치환 원칙 (SOLID의 L)", "개발"),
|
||
new("ISP", "Interface Segregation Principle", "인터페이스 분리 원칙 (SOLID의 I)", "개발"),
|
||
new("DIP", "Dependency Inversion Principle", "의존성 역전 원칙 (SOLID의 D)", "개발"),
|
||
new("IoC", "Inversion of Control", "제어 역전 (프레임워크 핵심 개념)", "개발"),
|
||
new("DI", "Dependency Injection", "의존성 주입 패턴", "개발"),
|
||
new("AOP", "Aspect-Oriented Programming", "관점 지향 프로그래밍", "개발"),
|
||
new("FP", "Functional Programming", "함수형 프로그래밍", "개발"),
|
||
new("DSL", "Domain-Specific Language", "특정 도메인 전용 언어", "개발"),
|
||
new("SDK", "Software Development Kit", "소프트웨어 개발 도구 모음", "개발"),
|
||
new("IDE", "Integrated Development Environment", "통합 개발 환경", "개발"),
|
||
new("CLI", "Command Line Interface", "명령줄 인터페이스", "개발"),
|
||
new("GUI", "Graphical User Interface", "그래픽 사용자 인터페이스", "개발"),
|
||
new("UI", "User Interface", "사용자 인터페이스", "개발"),
|
||
new("UX", "User Experience", "사용자 경험", "개발"),
|
||
new("SPA", "Single Page Application", "단일 페이지 애플리케이션", "개발"),
|
||
new("SSR", "Server-Side Rendering", "서버 사이드 렌더링", "개발"),
|
||
new("CSR", "Client-Side Rendering", "클라이언트 사이드 렌더링", "개발"),
|
||
new("PWA", "Progressive Web App", "프로그레시브 웹 앱", "개발"),
|
||
new("CDK", "Cloud Development Kit", "클라우드 인프라 코드 개발 도구", "개발"),
|
||
new("ORM", "Object-Relational Mapping", "객체-관계형 데이터베이스 매핑", "개발"),
|
||
new("REPL", "Read-Eval-Print Loop", "대화형 프로그래밍 환경", "개발"),
|
||
new("GC", "Garbage Collection", "자동 메모리 회수", "개발"),
|
||
new("JIT", "Just-In-Time Compilation", "실행 시점 컴파일", "개발"),
|
||
new("AOT", "Ahead-Of-Time Compilation", "사전 컴파일", "개발"),
|
||
new("WASM", "WebAssembly", "브라우저용 바이너리 형식", "개발"),
|
||
new("AST", "Abstract Syntax Tree", "추상 구문 트리", "개발"),
|
||
new("LSP", "Language Server Protocol", "언어 분석 서버 표준 프로토콜", "개발"),
|
||
|
||
// 데이터베이스
|
||
new("SQL", "Structured Query Language", "관계형 DB 쿼리 언어", "DB"),
|
||
new("NoSQL", "Not Only SQL", "비관계형 데이터베이스 총칭", "DB"),
|
||
new("ACID", "Atomicity Consistency Isolation Durability", "DB 트랜잭션 4가지 성질", "DB"),
|
||
new("CAP", "Consistency Availability Partition-tolerance","분산 DB 설계 이론 (셋 중 2개만 보장)", "DB"),
|
||
new("ETL", "Extract Transform Load", "데이터 추출·변환·적재 프로세스", "DB"),
|
||
new("OLTP", "Online Transaction Processing", "트랜잭션 처리 중심 DB", "DB"),
|
||
new("OLAP", "Online Analytical Processing", "분석 처리 중심 DB (데이터 웨어하우스)", "DB"),
|
||
new("DDL", "Data Definition Language", "DB 구조 정의 SQL (CREATE/ALTER/DROP)", "DB"),
|
||
new("DML", "Data Manipulation Language", "데이터 조작 SQL (SELECT/INSERT/UPDATE/DELETE)", "DB"),
|
||
new("DCL", "Data Control Language", "접근 권한 SQL (GRANT/REVOKE)", "DB"),
|
||
|
||
// 보안
|
||
new("JWT", "JSON Web Token", "JSON 기반 인증 토큰 표준", "보안"),
|
||
new("RBAC", "Role-Based Access Control", "역할 기반 접근 제어", "보안"),
|
||
new("ABAC", "Attribute-Based Access Control", "속성 기반 접근 제어", "보안"),
|
||
new("MFA", "Multi-Factor Authentication", "다중 인증", "보안"),
|
||
new("2FA", "Two-Factor Authentication", "이중 인증", "보안"),
|
||
new("XSS", "Cross-Site Scripting", "악성 스크립트 삽입 공격", "보안"),
|
||
new("CSRF", "Cross-Site Request Forgery", "교차 사이트 요청 위조 공격", "보안"),
|
||
new("SQL Injection", "SQL Injection Attack", "SQL 쿼리 삽입 공격", "보안"),
|
||
new("OWASP", "Open Web Application Security Project", "웹 보안 가이드라인 기관", "보안"),
|
||
new("CVE", "Common Vulnerabilities and Exposures", "공개 보안 취약점 DB", "보안"),
|
||
new("HTTPS", "HTTP Secure", "TLS로 암호화된 HTTP", "보안"),
|
||
new("AES", "Advanced Encryption Standard", "대칭키 암호화 표준 (128/192/256bit)", "보안"),
|
||
new("RSA", "Rivest–Shamir–Adleman", "공개키 비대칭 암호화 알고리즘", "보안"),
|
||
new("HMAC", "Hash-based Message Authentication Code", "해시 기반 메시지 인증 코드", "보안"),
|
||
new("PKI", "Public Key Infrastructure", "공개키 인프라", "보안"),
|
||
|
||
// 클라우드/인프라
|
||
new("AWS", "Amazon Web Services", "아마존 클라우드 서비스", "클라우드"),
|
||
new("GCP", "Google Cloud Platform", "구글 클라우드 서비스", "클라우드"),
|
||
new("SaaS", "Software as a Service", "구독형 소프트웨어 서비스", "클라우드"),
|
||
new("PaaS", "Platform as a Service", "플랫폼 서비스", "클라우드"),
|
||
new("IaaS", "Infrastructure as a Service", "인프라 서비스", "클라우드"),
|
||
new("FaaS", "Function as a Service", "서버리스 함수 서비스", "클라우드"),
|
||
new("K8s", "Kubernetes", "컨테이너 오케스트레이션 플랫폼", "클라우드"),
|
||
new("CI/CD", "Continuous Integration/Continuous Delivery","지속적 통합/배포 파이프라인", "클라우드"),
|
||
new("IaC", "Infrastructure as Code", "코드로 관리하는 인프라", "클라우드"),
|
||
new("VPC", "Virtual Private Cloud", "가상 사설 클라우드 네트워크", "클라우드"),
|
||
new("SLA", "Service Level Agreement", "서비스 수준 계약 (가용성 보장)", "클라우드"),
|
||
new("SLO", "Service Level Objective", "서비스 수준 목표", "클라우드"),
|
||
new("RTO", "Recovery Time Objective", "복구 목표 시간", "클라우드"),
|
||
new("RPO", "Recovery Point Objective", "복구 목표 지점", "클라우드"),
|
||
new("CDN", "Content Delivery Network", "콘텐츠 분산 배포 네트워크", "클라우드"),
|
||
new("ECS", "Elastic Container Service", "AWS 컨테이너 관리 서비스", "클라우드"),
|
||
new("ECR", "Elastic Container Registry", "AWS 컨테이너 이미지 저장소", "클라우드"),
|
||
new("EKS", "Elastic Kubernetes Service", "AWS 관리형 Kubernetes", "클라우드"),
|
||
|
||
// AI/ML
|
||
new("AI", "Artificial Intelligence", "인공지능", "AI/ML"),
|
||
new("ML", "Machine Learning", "머신러닝", "AI/ML"),
|
||
new("DL", "Deep Learning", "딥러닝", "AI/ML"),
|
||
new("LLM", "Large Language Model", "대규모 언어 모델", "AI/ML"),
|
||
new("NLP", "Natural Language Processing", "자연어 처리", "AI/ML"),
|
||
new("CNN", "Convolutional Neural Network", "합성곱 신경망", "AI/ML"),
|
||
new("RNN", "Recurrent Neural Network", "순환 신경망", "AI/ML"),
|
||
new("GAN", "Generative Adversarial Network", "생성적 적대 신경망", "AI/ML"),
|
||
new("RAG", "Retrieval-Augmented Generation", "검색 증강 생성 (LLM + 검색)", "AI/ML"),
|
||
new("RLHF", "Reinforcement Learning from Human Feedback","인간 피드백 강화학습", "AI/ML"),
|
||
new("GPT", "Generative Pre-trained Transformer", "생성형 사전학습 변환기 (OpenAI)", "AI/ML"),
|
||
new("BERT", "Bidirectional Encoder Representations from Transformers","양방향 트랜스포머 언어 모델", "AI/ML"),
|
||
new("SFT", "Supervised Fine-Tuning", "지도 학습 파인튜닝", "AI/ML"),
|
||
new("LoRA", "Low-Rank Adaptation", "저순위 행렬 파인튜닝 기법", "AI/ML"),
|
||
new("MCP", "Model Context Protocol", "LLM 외부 도구 연결 표준 프로토콜", "AI/ML"),
|
||
new("CoT", "Chain of Thought", "사고 단계 명시 프롬프팅", "AI/ML"),
|
||
|
||
// 데이터 형식
|
||
new("JSON", "JavaScript Object Notation", "경량 데이터 교환 형식", "데이터형식"),
|
||
new("XML", "Extensible Markup Language", "확장 가능 마크업 언어", "데이터형식"),
|
||
new("YAML", "YAML Ain't Markup Language", "사람이 읽기 쉬운 데이터 직렬화 형식", "데이터형식"),
|
||
new("TOML", "Tom's Obvious, Minimal Language", "설정 파일 전용 경량 형식", "데이터형식"),
|
||
new("CSV", "Comma-Separated Values", "쉼표 구분 데이터 형식", "데이터형식"),
|
||
new("TSV", "Tab-Separated Values", "탭 구분 데이터 형식", "데이터형식"),
|
||
new("Protobuf","Protocol Buffers", "구글 이진 직렬화 형식", "데이터형식"),
|
||
new("Avro", "Apache Avro", "Hadoop 생태계 이진 직렬화", "데이터형식"),
|
||
new("Parquet", "Apache Parquet", "열 지향 이진 데이터 형식", "데이터형식"),
|
||
new("Base64", "Base 64 encoding", "이진 데이터 텍스트 인코딩 (64진수)", "데이터형식"),
|
||
|
||
// 버전 관리/협업
|
||
new("VCS", "Version Control System", "버전 관리 시스템", "협업"),
|
||
new("SCM", "Source Code Management", "소스 코드 관리", "협업"),
|
||
new("PR", "Pull Request", "코드 병합 요청 (GitHub 용어)", "협업"),
|
||
new("MR", "Merge Request", "코드 병합 요청 (GitLab 용어)", "협업"),
|
||
new("LGTM", "Looks Good To Me", "코드 리뷰 승인 표현", "협업"),
|
||
new("WIP", "Work In Progress", "진행 중 작업", "협업"),
|
||
new("RFC", "Request for Comments", "의견 요청 문서 (표준화 프로세스)", "협업"),
|
||
new("POC", "Proof of Concept", "개념 검증", "협업"),
|
||
new("MVP", "Minimum Viable Product", "최소 기능 제품", "협업"),
|
||
new("KPI", "Key Performance Indicator", "핵심 성과 지표", "협업"),
|
||
new("OKR", "Objectives and Key Results", "목표 및 핵심 결과", "협업"),
|
||
new("SOP", "Standard Operating Procedure", "표준 운영 절차", "협업"),
|
||
];
|
||
|
||
private static readonly string[] Categories = Entries.Select(e => e.Category).Distinct().ToArray();
|
||
|
||
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
||
{
|
||
var q = query.Trim();
|
||
var items = new List<LauncherItem>();
|
||
|
||
if (string.IsNullOrWhiteSpace(q))
|
||
{
|
||
items.Add(new LauncherItem($"IT·개발 약어 사전 {Entries.Length}개",
|
||
"abbr <약어> 예: abbr api / abbr crud / abbr jwt",
|
||
null, null, Symbol: "\uE82D"));
|
||
items.Add(new LauncherItem("── 카테고리 ──", "", null, null, Symbol: "\uE82D"));
|
||
foreach (var cat in Categories)
|
||
{
|
||
var cnt = Entries.Count(e => e.Category == cat);
|
||
items.Add(new LauncherItem(cat, $"{cnt}개 · abbr {cat}로 목록 보기",
|
||
null, null, Symbol: "\uE82D"));
|
||
}
|
||
// 자주 쓰는 약어 샘플
|
||
items.Add(new LauncherItem("── 자주 쓰는 약어 ──", "", null, null, Symbol: "\uE82D"));
|
||
var popular = new[] { "API", "CRUD", "REST", "JWT", "SQL", "CI/CD", "TDD", "OOP" };
|
||
foreach (var p in popular)
|
||
{
|
||
var e = Entries.FirstOrDefault(x => x.Short.Equals(p, StringComparison.OrdinalIgnoreCase));
|
||
if (e != null)
|
||
items.Add(MakeAbbrItem(e));
|
||
}
|
||
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
||
}
|
||
|
||
// 카테고리 검색
|
||
if (Categories.Any(c => c.Equals(q, StringComparison.OrdinalIgnoreCase)))
|
||
{
|
||
var catEntries = Entries.Where(e => e.Category.Equals(q, StringComparison.OrdinalIgnoreCase)).ToList();
|
||
items.Add(new LauncherItem($"{q} {catEntries.Count}개", "", null, null, Symbol: "\uE82D"));
|
||
foreach (var e in catEntries)
|
||
items.Add(MakeAbbrItem(e));
|
||
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
||
}
|
||
|
||
// 약어 검색 (정확 일치 우선, 그 다음 부분 일치)
|
||
var exact = Entries.Where(e =>
|
||
e.Short.Equals(q, StringComparison.OrdinalIgnoreCase)).ToList();
|
||
|
||
var partial = Entries.Where(e =>
|
||
!exact.Contains(e) &&
|
||
(e.Short.Contains(q, StringComparison.OrdinalIgnoreCase) ||
|
||
e.Full.Contains(q, StringComparison.OrdinalIgnoreCase) ||
|
||
e.Description.Contains(q, StringComparison.OrdinalIgnoreCase))).ToList();
|
||
|
||
var all = exact.Concat(partial).ToList();
|
||
|
||
if (all.Count == 0)
|
||
{
|
||
items.Add(new LauncherItem($"'{q}' 약어를 찾을 수 없습니다",
|
||
"카테고리: " + string.Join(", ", Categories),
|
||
null, null, Symbol: "\uE946"));
|
||
return Task.FromResult<IEnumerable<LauncherItem>>(items);
|
||
}
|
||
|
||
if (exact.Count == 1)
|
||
{
|
||
// 정확 일치 1개 → 상세 표시
|
||
var e = exact[0];
|
||
items.Add(new LauncherItem($"{e.Short} = {e.Full}",
|
||
e.Description, null, ("copy", $"{e.Short}: {e.Full}"), Symbol: "\uE82D"));
|
||
items.Add(new LauncherItem("약어", e.Short, null, ("copy", e.Short), Symbol: "\uE82D"));
|
||
items.Add(new LauncherItem("원문", e.Full, null, ("copy", e.Full), Symbol: "\uE82D"));
|
||
items.Add(new LauncherItem("설명", e.Description, null, ("copy", e.Description), Symbol: "\uE82D"));
|
||
items.Add(new LauncherItem("카테고리",e.Category, null, null, Symbol: "\uE82D"));
|
||
}
|
||
else
|
||
{
|
||
items.Add(new LauncherItem($"'{q}' 검색 결과 {all.Count}개", "", null, null, Symbol: "\uE82D"));
|
||
foreach (var e in all.Take(30))
|
||
items.Add(MakeAbbrItem(e));
|
||
}
|
||
|
||
return Task.FromResult<IEnumerable<LauncherItem>>(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("Abbr", "클립보드에 복사했습니다.");
|
||
}
|
||
catch { }
|
||
}
|
||
return Task.CompletedTask;
|
||
}
|
||
|
||
private static LauncherItem MakeAbbrItem(AbbrEntry e) =>
|
||
new(e.Short,
|
||
$"{e.Full} · {e.Description}",
|
||
null, ("copy", $"{e.Short}: {e.Full}"), Symbol: "\uE82D");
|
||
}
|