using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; using System.Windows; using AxCopilot.SDK; namespace AxCopilot.Handlers; public class EnvHandler : IActionHandler { private static readonly string[] _priorityKeys = new string[22] { "PATH", "JAVA_HOME", "PYTHON_HOME", "NODE_HOME", "GOPATH", "GOROOT", "USERPROFILE", "APPDATA", "LOCALAPPDATA", "TEMP", "TMP", "COMPUTERNAME", "USERNAME", "USERDOMAIN", "OS", "PROCESSOR_ARCHITECTURE", "SYSTEMROOT", "WINDIR", "PROGRAMFILES", "PROGRAMFILES(X86)", "COMMONPROGRAMFILES", "NUMBER_OF_PROCESSORS" }; public string? Prefix => "env"; public PluginMetadata Metadata => new PluginMetadata("EnvVars", "환경변수 조회 — env 뒤에 변수명 입력", "1.0", "AX"); public Task> GetItemsAsync(string query, CancellationToken ct) { string q = query.Trim(); List<(string Key, string Value)> allVars = (from DictionaryEntry e in Environment.GetEnvironmentVariables() select (Key: e.Key?.ToString() ?? "", Value: e.Value?.ToString() ?? "") into x where !string.IsNullOrEmpty(x.Key) select x).ToList(); IEnumerable<(string, string)> source; if (string.IsNullOrWhiteSpace(q)) { HashSet prioritySet = new HashSet(_priorityKeys, StringComparer.OrdinalIgnoreCase); IEnumerable<(string, string)> first = from k in _priorityKeys where allVars.Any(((string Key, string Value) v) => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase)) select allVars.First(((string Key, string Value) v) => string.Equals(v.Key, k, StringComparison.OrdinalIgnoreCase)); IOrderedEnumerable<(string, string)> second = from v in allVars where !prioritySet.Contains(v.Key) orderby v.Key select v; source = first.Concat(second).Take(20); } else { source = (from v in allVars where v.Key.Contains(q, StringComparison.OrdinalIgnoreCase) || v.Value.Contains(q, StringComparison.OrdinalIgnoreCase) orderby (!v.Key.StartsWith(q, StringComparison.OrdinalIgnoreCase)) ? 1 : 0, v.Key select v).Take(20); } List list = source.Select<(string, string), LauncherItem>(delegate((string Key, string Value) v) { string text = ((v.Value.Length > 80) ? (v.Value.Substring(0, 77) + "…") : v.Value); if (v.Key.Equals("PATH", StringComparison.OrdinalIgnoreCase) && v.Value.Contains(';')) { text = v.Value.Split(';')[0] + $" (외 {v.Value.Split(';').Length - 1}개)"; } return new LauncherItem(v.Key, text + " · Enter로 값 복사", null, v.Value, null, "\ue8d7"); }).ToList(); if (!list.Any()) { list.Add(new LauncherItem("'" + q + "' — 환경변수 없음", "해당 이름의 환경변수를 찾을 수 없습니다", null, null, null, "\ue7ba")); } return Task.FromResult((IEnumerable)list); } public Task ExecuteAsync(LauncherItem item, CancellationToken ct) { if (item.Data is string text) { try { Clipboard.SetText(text); } catch { } } return Task.CompletedTask; } }