165 lines
4.1 KiB
C#
165 lines
4.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Threading;
|
|
using AxCopilot.Models;
|
|
using AxCopilot.SDK;
|
|
using AxCopilot.Services;
|
|
|
|
namespace AxCopilot.Handlers;
|
|
|
|
public class SnippetHandler : IActionHandler
|
|
{
|
|
private struct INPUT
|
|
{
|
|
public uint type;
|
|
|
|
public InputUnion u;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
private struct InputUnion
|
|
{
|
|
[FieldOffset(0)]
|
|
public KEYBDINPUT ki;
|
|
}
|
|
|
|
private struct KEYBDINPUT
|
|
{
|
|
public ushort wVk;
|
|
|
|
public ushort wScan;
|
|
|
|
public uint dwFlags;
|
|
|
|
public uint time;
|
|
|
|
public nint dwExtraInfo;
|
|
}
|
|
|
|
private readonly SettingsService _settings;
|
|
|
|
public string? Prefix => ";";
|
|
|
|
public PluginMetadata Metadata => new PluginMetadata("Snippets", "텍스트 스니펫 — ; 뒤에 키워드 입력", "1.0", "AX");
|
|
|
|
public SnippetHandler(SettingsService settings)
|
|
{
|
|
_settings = settings;
|
|
}
|
|
|
|
public Task<IEnumerable<LauncherItem>> GetItemsAsync(string query, CancellationToken ct)
|
|
{
|
|
List<SnippetEntry> snippets = _settings.Settings.Snippets;
|
|
if (!snippets.Any())
|
|
{
|
|
return Task.FromResult((IEnumerable<LauncherItem>)new _003C_003Ez__ReadOnlySingleElementList<LauncherItem>(new LauncherItem("등록된 스니펫이 없습니다", "설정 → 스니펫 탭에서 추가하세요", null, null, null, "\ue70b")));
|
|
}
|
|
string q = query.Trim().ToLowerInvariant();
|
|
List<LauncherItem> list = (from s in snippets
|
|
where string.IsNullOrEmpty(q) || s.Key.ToLowerInvariant().Contains(q) || s.Name.ToLowerInvariant().Contains(q)
|
|
select new LauncherItem((s.Name.Length > 0) ? s.Name : s.Key, TruncatePreview(s.Content), null, s, null, "\ue70b")).ToList();
|
|
if (list.Count == 0)
|
|
{
|
|
list.Add(new LauncherItem("'" + query + "'에 해당하는 스니펫 없음", "설정에서 새 스니펫을 추가하세요", null, null, null, "\ue70b"));
|
|
}
|
|
return Task.FromResult((IEnumerable<LauncherItem>)list);
|
|
}
|
|
|
|
public Task ExecuteAsync(LauncherItem item, CancellationToken ct)
|
|
{
|
|
if (!(item.Data is SnippetEntry snippetEntry))
|
|
{
|
|
return Task.CompletedTask;
|
|
}
|
|
try
|
|
{
|
|
string text = ExpandVariables(snippetEntry.Content);
|
|
Clipboard.SetText(text);
|
|
Task.Delay(100, ct).ContinueWith(delegate
|
|
{
|
|
((DispatcherObject)Application.Current).Dispatcher.Invoke((Action)delegate
|
|
{
|
|
INPUT[] array = new INPUT[4]
|
|
{
|
|
new INPUT
|
|
{
|
|
type = 1u,
|
|
u = new InputUnion
|
|
{
|
|
ki = new KEYBDINPUT
|
|
{
|
|
wVk = 17
|
|
}
|
|
}
|
|
},
|
|
new INPUT
|
|
{
|
|
type = 1u,
|
|
u = new InputUnion
|
|
{
|
|
ki = new KEYBDINPUT
|
|
{
|
|
wVk = 86
|
|
}
|
|
}
|
|
},
|
|
new INPUT
|
|
{
|
|
type = 1u,
|
|
u = new InputUnion
|
|
{
|
|
ki = new KEYBDINPUT
|
|
{
|
|
wVk = 86,
|
|
dwFlags = 2u
|
|
}
|
|
}
|
|
},
|
|
new INPUT
|
|
{
|
|
type = 1u,
|
|
u = new InputUnion
|
|
{
|
|
ki = new KEYBDINPUT
|
|
{
|
|
wVk = 17,
|
|
dwFlags = 2u
|
|
}
|
|
}
|
|
}
|
|
};
|
|
SendInput((uint)array.Length, array, Marshal.SizeOf<INPUT>());
|
|
});
|
|
}, ct, TaskContinuationOptions.OnlyOnRanToCompletion, TaskScheduler.Default);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogService.Warn("스니펫 실행 실패: " + ex.Message);
|
|
}
|
|
return Task.CompletedTask;
|
|
}
|
|
|
|
private static string ExpandVariables(string content)
|
|
{
|
|
DateTime now = DateTime.Now;
|
|
return content.Replace("{date}", now.ToString("yyyy-MM-dd")).Replace("{time}", now.ToString("HH:mm:ss")).Replace("{datetime}", now.ToString("yyyy-MM-dd HH:mm:ss"))
|
|
.Replace("{year}", now.Year.ToString())
|
|
.Replace("{month}", now.Month.ToString("D2"))
|
|
.Replace("{day}", now.Day.ToString("D2"));
|
|
}
|
|
|
|
private static string TruncatePreview(string content)
|
|
{
|
|
string text = content.Replace("\r\n", " ").Replace("\n", " ").Replace("\r", " ");
|
|
return (text.Length > 60) ? (text.Substring(0, 57) + "…") : text;
|
|
}
|
|
|
|
[DllImport("user32.dll")]
|
|
private static extern uint SendInput(uint nInputs, INPUT[] pInputs, int cbSize);
|
|
}
|