Added key binding service

This commit is contained in:
2025-06-20 13:37:48 +08:00
parent 13072a00a1
commit 85544ba1e4
18 changed files with 1968 additions and 349 deletions

View File

@@ -40,50 +40,45 @@ const (
// GeneralConfig 通用设置配置
type GeneralConfig struct {
AlwaysOnTop bool `json:"alwaysOnTop" yaml:"always_on_top" mapstructure:"always_on_top"` // 窗口是否置顶
DataPath string `json:"dataPath" yaml:"data_path" mapstructure:"data_path"` // 数据存储路径
EnableSystemTray bool `json:"enableSystemTray" yaml:"enable_system_tray" mapstructure:"enable_system_tray"` // 是否启用系统托盘
AlwaysOnTop bool `json:"alwaysOnTop"` // 窗口是否置顶
DataPath string `json:"dataPath"` // 数据存储路径
EnableSystemTray bool `json:"enableSystemTray"` // 是否启用系统托盘
// 全局热键设置
EnableGlobalHotkey bool `json:"enableGlobalHotkey" yaml:"enable_global_hotkey" mapstructure:"enable_global_hotkey"` // 是否启用全局热键
GlobalHotkey HotkeyCombo `json:"globalHotkey" yaml:"global_hotkey" mapstructure:"global_hotkey"` // 全局热键组合
EnableGlobalHotkey bool `json:"enableGlobalHotkey"` // 是否启用全局热键
GlobalHotkey HotkeyCombo `json:"globalHotkey"` // 全局热键组合
}
// HotkeyCombo 热键组合定义
type HotkeyCombo struct {
Ctrl bool `json:"ctrl" yaml:"ctrl" mapstructure:"ctrl"` // Ctrl键
Shift bool `json:"shift" yaml:"shift" mapstructure:"shift"` // Shift键
Alt bool `json:"alt" yaml:"alt" mapstructure:"alt"` // Alt键
Win bool `json:"win" yaml:"win" mapstructure:"win"` // Win键
Key string `json:"key" yaml:"key" mapstructure:"key"` // 主键(如 'X', 'F1' 等)
Ctrl bool `json:"ctrl"` // Ctrl键
Shift bool `json:"shift"` // Shift键
Alt bool `json:"alt"` // Alt键
Win bool `json:"win"` // Win键
Key string `json:"key"` // 主键(如 'X', 'F1' 等)
}
// EditingConfig 编辑设置配置
type EditingConfig struct {
// 字体设置
FontSize int `json:"fontSize" yaml:"font_size" mapstructure:"font_size"` // 字体大小
FontFamily string `json:"fontFamily" yaml:"font_family" mapstructure:"font_family"` // 字体族
FontWeight string `json:"fontWeight" yaml:"font_weight" mapstructure:"font_weight"` // 字体粗细
LineHeight float64 `json:"lineHeight" yaml:"line_height" mapstructure:"line_height"` // 行高
FontSize int `json:"fontSize"` // 字体大小
FontFamily string `json:"fontFamily"` // 字体族
FontWeight string `json:"fontWeight"` // 字体粗细
LineHeight float64 `json:"lineHeight"` // 行高
// Tab设置
EnableTabIndent bool `json:"enableTabIndent" yaml:"enable_tab_indent" mapstructure:"enable_tab_indent"` // 是否启用Tab缩进
TabSize int `json:"tabSize" yaml:"tab_size" mapstructure:"tab_size"` // Tab大小
TabType TabType `json:"tabType" yaml:"tab_type" mapstructure:"tab_type"` // Tab类型空格或Tab
EnableTabIndent bool `json:"enableTabIndent"` // 是否启用Tab缩进
TabSize int `json:"tabSize"` // Tab大小
TabType TabType `json:"tabType"` // Tab类型空格或Tab
// 保存选项
AutoSaveDelay int `json:"autoSaveDelay" yaml:"auto_save_delay" mapstructure:"auto_save_delay"` // 自动保存延迟(毫秒)
AutoSaveDelay int `json:"autoSaveDelay"` // 自动保存延迟(毫秒)
}
// AppearanceConfig 外观设置配置
type AppearanceConfig struct {
Language LanguageType `json:"language" yaml:"language" mapstructure:"language"` // 界面语言
SystemTheme SystemThemeType `json:"systemTheme" yaml:"system_theme" mapstructure:"system_theme"` // 系统界面主题
}
// KeyBindingsConfig 快捷键设置配置
type KeyBindingsConfig struct {
// 预留给未来的快捷键配置
Language LanguageType `json:"language"` // 界面语言
SystemTheme SystemThemeType `json:"systemTheme"` // 系统界面主题
}
// UpdatesConfig 更新设置配置
@@ -93,18 +88,16 @@ type UpdatesConfig struct {
// AppConfig 应用配置 - 按照前端设置页面分类组织
type AppConfig struct {
General GeneralConfig `json:"general" yaml:"general" mapstructure:"general"` // 通用设置
Editing EditingConfig `json:"editing" yaml:"editing" mapstructure:"editing"` // 编辑设置
Appearance AppearanceConfig `json:"appearance" yaml:"appearance" mapstructure:"appearance"` // 外观设置
KeyBindings KeyBindingsConfig `json:"keyBindings" yaml:"key_bindings" mapstructure:"key_bindings"` // 快捷键设置
Updates UpdatesConfig `json:"updates" yaml:"updates" mapstructure:"updates"` // 更新设置
Metadata ConfigMetadata `json:"metadata" yaml:"metadata" mapstructure:"metadata"` // 配置元数据
General GeneralConfig `json:"general"` // 通用设置
Editing EditingConfig `json:"editing"` // 编辑设置
Appearance AppearanceConfig `json:"appearance"` // 外观设置
Updates UpdatesConfig `json:"updates"` // 更新设置
Metadata ConfigMetadata `json:"metadata"` // 配置元数据
}
// ConfigMetadata 配置元数据
type ConfigMetadata struct {
Version string `json:"version" yaml:"version" mapstructure:"version"` // 配置版本
LastUpdated time.Time `json:"lastUpdated" yaml:"last_updated" mapstructure:"last_updated"` // 最后更新时间
LastUpdated string `json:"lastUpdated"` // 最后更新时间
}
// NewDefaultAppConfig 创建默认应用配置
@@ -149,15 +142,9 @@ func NewDefaultAppConfig() *AppConfig {
Language: LangZhCN,
SystemTheme: SystemThemeDark, // 默认使用深色系统主题
},
KeyBindings: KeyBindingsConfig{
// 预留给未来的快捷键配置
},
Updates: UpdatesConfig{
// 预留给未来的更新配置
},
Updates: UpdatesConfig{},
Metadata: ConfigMetadata{
Version: "1.0.0",
LastUpdated: time.Now(),
LastUpdated: time.Now().Format(time.RFC3339),
},
}
}

View File

@@ -0,0 +1,462 @@
package models
import "time"
// KeyBinding 单个快捷键绑定
type KeyBinding struct {
ID string `json:"id"` // 快捷键唯一标识
Action KeyBindingAction `json:"action"` // 快捷键动作
Category KeyBindingCategory `json:"category"` // 快捷键分类
Scope KeyBindingScope `json:"scope"` // 快捷键作用域
Key string `json:"key"` // 快捷键组合(如 "Mod-f", "Ctrl-Shift-p"
Enabled bool `json:"enabled"` // 是否启用
IsDefault bool `json:"isDefault"` // 是否为默认快捷键
}
// KeyBindingCategory 快捷键分类
type KeyBindingCategory string
const (
CategorySearch KeyBindingCategory = "search" // 搜索相关
CategoryEdit KeyBindingCategory = "edit" // 编辑相关
CategoryCodeBlock KeyBindingCategory = "codeblock" // 代码块相关
CategoryNavigation KeyBindingCategory = "navigation" // 导航相关
CategoryView KeyBindingCategory = "view" // 视图相关
CategoryFile KeyBindingCategory = "file" // 文件相关
CategoryApp KeyBindingCategory = "app" // 应用相关
)
// KeyBindingScope 快捷键作用域
type KeyBindingScope string
const (
ScopeGlobal KeyBindingScope = "global" // 全局作用域
ScopeEditor KeyBindingScope = "editor" // 编辑器作用域
ScopeSearch KeyBindingScope = "search" // 搜索面板作用域
)
// KeyBindingAction 快捷键动作类型
type KeyBindingAction string
const (
// 搜索相关
ActionShowSearch KeyBindingAction = "showSearch" // 显示搜索
ActionHideSearch KeyBindingAction = "hideSearch" // 隐藏搜索
ActionFindNext KeyBindingAction = "findNext" // 查找下一个
ActionFindPrevious KeyBindingAction = "findPrevious" // 查找上一个
ActionShowReplace KeyBindingAction = "showReplace" // 显示替换
ActionReplaceNext KeyBindingAction = "replaceNext" // 替换下一个
ActionReplaceAll KeyBindingAction = "replaceAll" // 替换全部
ActionToggleCase KeyBindingAction = "toggleCase" // 切换大小写匹配
ActionToggleWholeWord KeyBindingAction = "toggleWholeWord" // 切换全词匹配
ActionToggleRegex KeyBindingAction = "toggleRegex" // 切换正则表达式
// 编辑相关
ActionSelectAll KeyBindingAction = "selectAll" // 全选
ActionCopy KeyBindingAction = "copy" // 复制
ActionCut KeyBindingAction = "cut" // 剪切
ActionPaste KeyBindingAction = "paste" // 粘贴
ActionUndo KeyBindingAction = "undo" // 撤销
ActionRedo KeyBindingAction = "redo" // 重做
ActionDuplicateLine KeyBindingAction = "duplicateLine" // 复制行
ActionDeleteLine KeyBindingAction = "deleteLine" // 删除行
ActionMoveLineUp KeyBindingAction = "moveLineUp" // 上移行
ActionMoveLineDown KeyBindingAction = "moveLineDown" // 下移行
ActionToggleComment KeyBindingAction = "toggleComment" // 切换注释
ActionIndent KeyBindingAction = "indent" // 缩进
ActionOutdent KeyBindingAction = "outdent" // 取消缩进
// 代码块相关
ActionNewCodeBlock KeyBindingAction = "newCodeBlock" // 新建代码块
ActionDeleteCodeBlock KeyBindingAction = "deleteCodeBlock" // 删除代码块
ActionSelectCodeBlock KeyBindingAction = "selectCodeBlock" // 选择代码块
ActionFormatCode KeyBindingAction = "formatCode" // 格式化代码
ActionChangeLanguage KeyBindingAction = "changeLanguage" // 更改语言
// 导航相关
ActionGoToLine KeyBindingAction = "goToLine" // 跳转到行
ActionFoldAll KeyBindingAction = "foldAll" // 折叠所有
ActionUnfoldAll KeyBindingAction = "unfoldAll" // 展开所有
ActionToggleFold KeyBindingAction = "toggleFold" // 切换折叠
// 视图相关
ActionZoomIn KeyBindingAction = "zoomIn" // 放大
ActionZoomOut KeyBindingAction = "zoomOut" // 缩小
ActionResetZoom KeyBindingAction = "resetZoom" // 重置缩放
ActionToggleMinimap KeyBindingAction = "toggleMinimap" // 切换小地图
ActionToggleLineNumbers KeyBindingAction = "toggleLineNumbers" // 切换行号
// 文件相关
ActionSave KeyBindingAction = "save" // 保存
)
// KeyBindingMetadata 快捷键配置元数据
type KeyBindingMetadata struct {
LastUpdated string `json:"lastUpdated"` // 最后更新时间
}
// KeyBindingConfig 快捷键配置
type KeyBindingConfig struct {
KeyBindings []KeyBinding `json:"keyBindings"` // 快捷键列表
Metadata KeyBindingMetadata `json:"metadata"` // 配置元数据
}
// NewDefaultKeyBindingConfig 创建默认快捷键配置
func NewDefaultKeyBindingConfig() *KeyBindingConfig {
return &KeyBindingConfig{
KeyBindings: NewDefaultKeyBindings(),
Metadata: KeyBindingMetadata{
LastUpdated: time.Now().Format(time.RFC3339),
},
}
}
// NewDefaultKeyBindings 创建默认快捷键配置
func NewDefaultKeyBindings() []KeyBinding {
return []KeyBinding{
// 搜索相关快捷键
{
ID: "search.show",
Action: ActionShowSearch,
Category: CategorySearch,
Scope: ScopeGlobal,
Key: "Mod-f",
Enabled: true,
IsDefault: true,
},
{
ID: "search.hide",
Action: ActionHideSearch,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Escape",
Enabled: true,
IsDefault: true,
},
{
ID: "search.findNext",
Action: ActionFindNext,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Enter",
Enabled: true,
IsDefault: true,
},
{
ID: "search.findPrevious",
Action: ActionFindPrevious,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Shift-Enter",
Enabled: true,
IsDefault: true,
},
{
ID: "search.showReplace",
Action: ActionShowReplace,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Mod-h",
Enabled: true,
IsDefault: true,
},
{
ID: "search.replaceAll",
Action: ActionReplaceAll,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Mod-Alt-Enter",
Enabled: true,
IsDefault: true,
},
{
ID: "search.toggleCase",
Action: ActionToggleCase,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Alt-c",
Enabled: true,
IsDefault: true,
},
{
ID: "search.toggleWholeWord",
Action: ActionToggleWholeWord,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Alt-w",
Enabled: true,
IsDefault: true,
},
{
ID: "search.toggleRegex",
Action: ActionToggleRegex,
Category: CategorySearch,
Scope: ScopeSearch,
Key: "Alt-r",
Enabled: true,
IsDefault: true,
},
// 编辑相关快捷键
{
ID: "edit.selectAll",
Action: ActionSelectAll,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-a",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.copy",
Action: ActionCopy,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-c",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.cut",
Action: ActionCut,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-x",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.paste",
Action: ActionPaste,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-v",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.undo",
Action: ActionUndo,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-z",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.redo",
Action: ActionRedo,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-y",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.duplicateLine",
Action: ActionDuplicateLine,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-d",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.deleteLine",
Action: ActionDeleteLine,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-Shift-k",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.moveLineUp",
Action: ActionMoveLineUp,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Alt-ArrowUp",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.moveLineDown",
Action: ActionMoveLineDown,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Alt-ArrowDown",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.toggleComment",
Action: ActionToggleComment,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Mod-/",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.indent",
Action: ActionIndent,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Tab",
Enabled: true,
IsDefault: true,
},
{
ID: "edit.outdent",
Action: ActionOutdent,
Category: CategoryEdit,
Scope: ScopeEditor,
Key: "Shift-Tab",
Enabled: true,
IsDefault: true,
},
// 代码块相关快捷键
{
ID: "codeblock.new",
Action: ActionNewCodeBlock,
Category: CategoryCodeBlock,
Scope: ScopeEditor,
Key: "Mod-Alt-n",
Enabled: true,
IsDefault: true,
},
{
ID: "codeblock.delete",
Action: ActionDeleteCodeBlock,
Category: CategoryCodeBlock,
Scope: ScopeEditor,
Key: "Mod-Alt-d",
Enabled: true,
IsDefault: true,
},
{
ID: "codeblock.select",
Action: ActionSelectCodeBlock,
Category: CategoryCodeBlock,
Scope: ScopeEditor,
Key: "Mod-Alt-a",
Enabled: true,
IsDefault: true,
},
{
ID: "codeblock.format",
Action: ActionFormatCode,
Category: CategoryCodeBlock,
Scope: ScopeEditor,
Key: "Mod-Alt-f",
Enabled: true,
IsDefault: true,
},
{
ID: "codeblock.changeLanguage",
Action: ActionChangeLanguage,
Category: CategoryCodeBlock,
Scope: ScopeEditor,
Key: "Mod-Alt-l",
Enabled: true,
IsDefault: true,
},
// 导航相关快捷键
{
ID: "navigation.goToLine",
Action: ActionGoToLine,
Category: CategoryNavigation,
Scope: ScopeEditor,
Key: "Mod-g",
Enabled: true,
IsDefault: true,
},
{
ID: "navigation.foldAll",
Action: ActionFoldAll,
Category: CategoryNavigation,
Scope: ScopeEditor,
Key: "Mod-k Mod-0",
Enabled: true,
IsDefault: true,
},
{
ID: "navigation.unfoldAll",
Action: ActionUnfoldAll,
Category: CategoryNavigation,
Scope: ScopeEditor,
Key: "Mod-k Mod-j",
Enabled: true,
IsDefault: true,
},
{
ID: "navigation.toggleFold",
Action: ActionToggleFold,
Category: CategoryNavigation,
Scope: ScopeEditor,
Key: "Mod-k Mod-l",
Enabled: true,
IsDefault: true,
},
// 视图相关快捷键
{
ID: "view.zoomIn",
Action: ActionZoomIn,
Category: CategoryView,
Scope: ScopeGlobal,
Key: "Mod-=",
Enabled: true,
IsDefault: true,
},
{
ID: "view.zoomOut",
Action: ActionZoomOut,
Category: CategoryView,
Scope: ScopeGlobal,
Key: "Mod--",
Enabled: true,
IsDefault: true,
},
{
ID: "view.resetZoom",
Action: ActionResetZoom,
Category: CategoryView,
Scope: ScopeGlobal,
Key: "Mod-0",
Enabled: true,
IsDefault: true,
},
{
ID: "view.toggleMinimap",
Action: ActionToggleMinimap,
Category: CategoryView,
Scope: ScopeGlobal,
Key: "Mod-m",
Enabled: true,
IsDefault: true,
},
{
ID: "view.toggleLineNumbers",
Action: ActionToggleLineNumbers,
Category: CategoryView,
Scope: ScopeGlobal,
Key: "Mod-l",
Enabled: true,
IsDefault: true,
},
// 文件相关快捷键
{
ID: "file.save",
Action: ActionSave,
Category: CategoryFile,
Scope: ScopeGlobal,
Key: "Mod-s",
Enabled: true,
IsDefault: true,
},
}
}

View File

@@ -1,6 +1,7 @@
package services
import (
"encoding/json"
"errors"
"fmt"
"os"
@@ -62,14 +63,14 @@ func NewConfigService(logger *log.LoggerService) *ConfigService {
// 固定配置路径和文件名
configPath := filepath.Join(currentDir, "config")
configName := "config"
configName := "settings"
// 创建 Viper 实例
v := viper.New()
// 配置 Viper
v.SetConfigName(configName)
v.SetConfigType("yaml")
v.SetConfigType("json")
v.AddConfigPath(configPath)
// 设置环境变量前缀
@@ -104,33 +105,32 @@ func setDefaults(v *viper.Viper) {
defaultConfig := models.NewDefaultAppConfig()
// 通用设置默认值
v.SetDefault("general.always_on_top", defaultConfig.General.AlwaysOnTop)
v.SetDefault("general.data_path", defaultConfig.General.DataPath)
v.SetDefault("general.enable_system_tray", defaultConfig.General.EnableSystemTray)
v.SetDefault("general.enable_global_hotkey", defaultConfig.General.EnableGlobalHotkey)
v.SetDefault("general.global_hotkey.ctrl", defaultConfig.General.GlobalHotkey.Ctrl)
v.SetDefault("general.global_hotkey.shift", defaultConfig.General.GlobalHotkey.Shift)
v.SetDefault("general.global_hotkey.alt", defaultConfig.General.GlobalHotkey.Alt)
v.SetDefault("general.global_hotkey.win", defaultConfig.General.GlobalHotkey.Win)
v.SetDefault("general.global_hotkey.key", defaultConfig.General.GlobalHotkey.Key)
v.SetDefault("general.alwaysOnTop", defaultConfig.General.AlwaysOnTop)
v.SetDefault("general.dataPath", defaultConfig.General.DataPath)
v.SetDefault("general.enableSystemTray", defaultConfig.General.EnableSystemTray)
v.SetDefault("general.enableGlobalHotkey", defaultConfig.General.EnableGlobalHotkey)
v.SetDefault("general.globalHotkey.ctrl", defaultConfig.General.GlobalHotkey.Ctrl)
v.SetDefault("general.globalHotkey.shift", defaultConfig.General.GlobalHotkey.Shift)
v.SetDefault("general.globalHotkey.alt", defaultConfig.General.GlobalHotkey.Alt)
v.SetDefault("general.globalHotkey.win", defaultConfig.General.GlobalHotkey.Win)
v.SetDefault("general.globalHotkey.key", defaultConfig.General.GlobalHotkey.Key)
// 编辑设置默认值
v.SetDefault("editing.font_size", defaultConfig.Editing.FontSize)
v.SetDefault("editing.font_family", defaultConfig.Editing.FontFamily)
v.SetDefault("editing.font_weight", defaultConfig.Editing.FontWeight)
v.SetDefault("editing.line_height", defaultConfig.Editing.LineHeight)
v.SetDefault("editing.enable_tab_indent", defaultConfig.Editing.EnableTabIndent)
v.SetDefault("editing.tab_size", defaultConfig.Editing.TabSize)
v.SetDefault("editing.tab_type", defaultConfig.Editing.TabType)
v.SetDefault("editing.auto_save_delay", defaultConfig.Editing.AutoSaveDelay)
v.SetDefault("editing.fontSize", defaultConfig.Editing.FontSize)
v.SetDefault("editing.fontFamily", defaultConfig.Editing.FontFamily)
v.SetDefault("editing.fontWeight", defaultConfig.Editing.FontWeight)
v.SetDefault("editing.lineHeight", defaultConfig.Editing.LineHeight)
v.SetDefault("editing.enableTabIndent", defaultConfig.Editing.EnableTabIndent)
v.SetDefault("editing.tabSize", defaultConfig.Editing.TabSize)
v.SetDefault("editing.tabType", defaultConfig.Editing.TabType)
v.SetDefault("editing.autoSaveDelay", defaultConfig.Editing.AutoSaveDelay)
// 外观设置默认值
v.SetDefault("appearance.language", defaultConfig.Appearance.Language)
v.SetDefault("appearance.system_theme", defaultConfig.Appearance.SystemTheme)
v.SetDefault("appearance.systemTheme", defaultConfig.Appearance.SystemTheme)
// 元数据默认值
v.SetDefault("metadata.version", defaultConfig.Metadata.Version)
v.SetDefault("metadata.last_updated", defaultConfig.Metadata.LastUpdated)
v.SetDefault("metadata.lastUpdated", defaultConfig.Metadata.LastUpdated)
}
// initConfig 初始化配置
@@ -162,21 +162,32 @@ func (cs *ConfigService) createDefaultConfig() error {
currentDir = "."
}
configDir := filepath.Join(currentDir, "config")
configPath := filepath.Join(configDir, "config.yaml")
configPath := filepath.Join(configDir, "settings.json")
// 确保配置目录存在
if err := os.MkdirAll(configDir, 0755); err != nil {
return &ConfigError{Operation: "create_config_dir", Err: err}
}
// 设置当前时间为最后更新时间
cs.viper.Set("metadata.last_updated", time.Now())
// 获取默认配置
defaultConfig := models.NewDefaultAppConfig()
// 使用 SafeWriteConfigAs 写入配置文件(如果文件不存在则创建)
if err := cs.viper.SafeWriteConfigAs(configPath); err != nil {
// 使用 JSON marshal 方式设置完整的默认配置
configBytes, err := json.MarshalIndent(defaultConfig, "", " ")
if err != nil {
return &ConfigError{Operation: "marshal_default_config", Err: err}
}
// 写入配置文件
if err := os.WriteFile(configPath, configBytes, 0644); err != nil {
return &ConfigError{Operation: "write_default_config", Err: err}
}
// 重新读取配置文件到viper
if err := cs.viper.ReadInConfig(); err != nil {
return &ConfigError{Operation: "read_created_config", Err: err}
}
cs.logger.Info("Config: Created default config file", "path", configPath)
return nil
}
@@ -213,11 +224,21 @@ func (cs *ConfigService) GetConfig() (*models.AppConfig, error) {
func (cs *ConfigService) Set(key string, value interface{}) error {
cs.mu.Lock()
defer cs.mu.Unlock()
// 设置验证后的值
// 设置值到viper
cs.viper.Set(key, value)
// 使用 WriteConfig 写入配置文件(会触发文件监听)
if err := cs.viper.WriteConfig(); err != nil {
// 直接从viper获取配置并构建AppConfig结构
var config models.AppConfig
if err := cs.viper.Unmarshal(&config); err != nil {
return &ConfigError{Operation: "unmarshal_config_for_set", Err: err}
}
// 更新时间戳
config.Metadata.LastUpdated = time.Now().Format(time.RFC3339)
// 直接写入JSON文件
if err := cs.writeConfigToFile(&config); err != nil {
return &ConfigError{Operation: "set_config", Err: err}
}
@@ -238,43 +259,49 @@ func (cs *ConfigService) ResetConfig() {
defaultConfig := models.NewDefaultAppConfig()
// 通用设置 - 批量设置到viper中
cs.viper.Set("general.always_on_top", defaultConfig.General.AlwaysOnTop)
cs.viper.Set("general.data_path", defaultConfig.General.DataPath)
cs.viper.Set("general.enable_system_tray", defaultConfig.General.EnableSystemTray)
cs.viper.Set("general.enable_global_hotkey", defaultConfig.General.EnableGlobalHotkey)
cs.viper.Set("general.global_hotkey.ctrl", defaultConfig.General.GlobalHotkey.Ctrl)
cs.viper.Set("general.global_hotkey.shift", defaultConfig.General.GlobalHotkey.Shift)
cs.viper.Set("general.global_hotkey.alt", defaultConfig.General.GlobalHotkey.Alt)
cs.viper.Set("general.global_hotkey.win", defaultConfig.General.GlobalHotkey.Win)
cs.viper.Set("general.global_hotkey.key", defaultConfig.General.GlobalHotkey.Key)
// 编辑设置 - 批量设置到viper中
cs.viper.Set("editing.font_size", defaultConfig.Editing.FontSize)
cs.viper.Set("editing.font_family", defaultConfig.Editing.FontFamily)
cs.viper.Set("editing.font_weight", defaultConfig.Editing.FontWeight)
cs.viper.Set("editing.line_height", defaultConfig.Editing.LineHeight)
cs.viper.Set("editing.enable_tab_indent", defaultConfig.Editing.EnableTabIndent)
cs.viper.Set("editing.tab_size", defaultConfig.Editing.TabSize)
cs.viper.Set("editing.tab_type", defaultConfig.Editing.TabType)
cs.viper.Set("editing.auto_save_delay", defaultConfig.Editing.AutoSaveDelay)
// 外观设置 - 批量设置到viper中
cs.viper.Set("appearance.language", defaultConfig.Appearance.Language)
cs.viper.Set("appearance.system_theme", defaultConfig.Appearance.SystemTheme)
// 元数据 - 批量设置到viper中
cs.viper.Set("metadata.version", defaultConfig.Metadata.Version)
cs.viper.Set("metadata.last_updated", time.Now())
// 一次性写入配置文件,触发配置变更通知
if err := cs.viper.WriteConfig(); err != nil {
// 直接写入JSON文件
if err := cs.writeConfigToFile(defaultConfig); err != nil {
cs.logger.Error("Config: Failed to write config during reset", "error", err)
} else {
cs.logger.Info("Config: All settings have been reset to defaults")
// 手动触发配置变更检查,确保通知系统能感知到变更
cs.notificationService.CheckConfigChanges()
return
}
// 重新读取配置文件到viper
if err := cs.viper.ReadInConfig(); err != nil {
cs.logger.Error("Config: Failed to reload config after reset", "error", err)
return
}
cs.logger.Info("Config: All settings have been reset to defaults")
// 手动触发配置变更检查,确保通知系统能感知到变更
cs.notificationService.CheckConfigChanges()
}
// writeConfigToFile 直接写入配置到JSON文件
func (cs *ConfigService) writeConfigToFile(config *models.AppConfig) error {
// 获取配置文件路径
currentDir, err := os.Getwd()
if err != nil {
currentDir = "."
}
configPath := filepath.Join(currentDir, "config", "settings.json")
// 序列化为JSON
configBytes, err := json.MarshalIndent(config, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal config: %v", err)
}
// 写入文件
if err := os.WriteFile(configPath, configBytes, 0644); err != nil {
return fmt.Errorf("failed to write config file: %v", err)
}
// 重新读取到viper中
if err := cs.viper.ReadInConfig(); err != nil {
return fmt.Errorf("failed to reload config: %v", err)
}
return nil
}
// SetHotkeyChangeCallback 设置热键配置变更回调

View File

@@ -0,0 +1,631 @@
package services
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
"strings"
"sync"
"time"
"voidraft/internal/models"
"github.com/fsnotify/fsnotify"
"github.com/spf13/viper"
"github.com/wailsapp/wails/v3/pkg/services/log"
)
// KeyBindingService 快捷键管理服务
type KeyBindingService struct {
viper *viper.Viper // Viper 实例
logger *log.LoggerService // 日志服务
mu sync.RWMutex // 读写锁
}
// KeyBindingError 快捷键错误
type KeyBindingError struct {
Operation string // 操作名称
KeyID string // 快捷键ID
Err error // 原始错误
}
// Error 实现error接口
func (e *KeyBindingError) Error() string {
if e.KeyID != "" {
return fmt.Sprintf("keybinding error during %s for key %s: %v", e.Operation, e.KeyID, e.Err)
}
return fmt.Sprintf("keybinding error during %s: %v", e.Operation, e.Err)
}
// Unwrap 获取原始错误
func (e *KeyBindingError) Unwrap() error {
return e.Err
}
// Is 实现错误匹配
func (e *KeyBindingError) Is(target error) bool {
var keyBindingError *KeyBindingError
ok := errors.As(target, &keyBindingError)
return ok
}
// NewKeyBindingService 创建新的快捷键服务实例
func NewKeyBindingService(logger *log.LoggerService) *KeyBindingService {
// 设置日志服务
if logger == nil {
logger = log.New()
}
// 获取当前工作目录
currentDir, err := os.Getwd()
if err != nil {
currentDir = "."
}
// 固定配置路径和文件名
configPath := filepath.Join(currentDir, "config")
configName := "keybindings"
// 创建 Viper 实例
v := viper.New()
// 配置 Viper
v.SetConfigName(configName)
v.SetConfigType("json")
v.AddConfigPath(configPath)
// 设置环境变量前缀
v.SetEnvPrefix("VOIDRAFT_KEYBINDING")
v.AutomaticEnv()
// 设置默认值
setKeyBindingDefaults(v)
// 构造快捷键服务实例
service := &KeyBindingService{
viper: v,
logger: logger,
}
// 初始化配置
if err := service.initConfig(); err != nil {
service.logger.Error("KeyBinding: Failed to initialize keybinding config", "error", err)
}
// 启动配置文件监听
service.startWatching()
return service
}
// setKeyBindingDefaults 设置默认快捷键配置值
func setKeyBindingDefaults(v *viper.Viper) {
defaultConfig := models.NewDefaultKeyBindingConfig()
// 快捷键列表默认值
v.SetDefault("keyBindings", defaultConfig.KeyBindings)
// 元数据默认值
v.SetDefault("metadata.lastUpdated", defaultConfig.Metadata.LastUpdated)
}
// initConfig 初始化配置
func (kbs *KeyBindingService) initConfig() error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 尝试读取配置文件
if err := kbs.viper.ReadInConfig(); err != nil {
var configFileNotFoundError viper.ConfigFileNotFoundError
if errors.As(err, &configFileNotFoundError) {
// 配置文件不存在,创建默认配置文件
kbs.logger.Info("KeyBinding: Config file not found, creating default keybinding config")
return kbs.createDefaultConfig()
}
// 配置文件存在但读取失败
return &KeyBindingError{Operation: "read_keybinding_config", Err: err}
}
kbs.logger.Info("KeyBinding: Successfully loaded keybinding config file", "file", kbs.viper.ConfigFileUsed())
return nil
}
// createDefaultConfig 创建默认配置文件
func (kbs *KeyBindingService) createDefaultConfig() error {
// 获取配置目录路径
currentDir, err := os.Getwd()
if err != nil {
currentDir = "."
}
configDir := filepath.Join(currentDir, "config")
configPath := filepath.Join(configDir, "keybindings.json")
// 确保配置目录存在
if err := os.MkdirAll(configDir, 0755); err != nil {
return &KeyBindingError{Operation: "create_keybinding_config_dir", Err: err}
}
// 获取默认配置
defaultConfig := models.NewDefaultKeyBindingConfig()
configBytes, err := json.MarshalIndent(defaultConfig, "", " ")
if err != nil {
return &KeyBindingError{Operation: "marshal_default_keybinding_config", Err: err}
}
// 写入配置文件
if err := os.WriteFile(configPath, configBytes, 0644); err != nil {
return &KeyBindingError{Operation: "write_default_keybinding_config", Err: err}
}
// 重新读取配置文件到viper
if err := kbs.viper.ReadInConfig(); err != nil {
return &KeyBindingError{Operation: "read_created_keybinding_config", Err: err}
}
kbs.logger.Info("KeyBinding: Created default keybinding config file", "path", configPath)
return nil
}
// startWatching 启动配置文件监听
func (kbs *KeyBindingService) startWatching() {
// 设置配置变化回调
kbs.viper.OnConfigChange(func(e fsnotify.Event) {
kbs.logger.Info("KeyBinding: Config file changed", "file", e.Name, "operation", e.Op.String())
})
// 启动配置文件监听
kbs.viper.WatchConfig()
kbs.logger.Info("KeyBinding: Started watching keybinding config file for changes")
}
// GetKeyBindingConfig 获取完整快捷键配置
func (kbs *KeyBindingService) GetKeyBindingConfig() (*models.KeyBindingConfig, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
var config models.KeyBindingConfig
if err := kbs.viper.Unmarshal(&config); err != nil {
return nil, &KeyBindingError{Operation: "unmarshal_keybinding_config", Err: err}
}
return &config, nil
}
// GetAllKeyBindings 获取所有快捷键配置
func (kbs *KeyBindingService) GetAllKeyBindings() ([]models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
config, err := kbs.GetKeyBindingConfig()
if err != nil {
return nil, &KeyBindingError{Operation: "get_all_keybindings", Err: err}
}
return config.KeyBindings, nil
}
// GetKeyBindingsByCategory 根据分类获取快捷键
func (kbs *KeyBindingService) GetKeyBindingsByCategory(category models.KeyBindingCategory) ([]models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
allKeyBindings, err := kbs.GetAllKeyBindings()
if err != nil {
return nil, err
}
var result []models.KeyBinding
for _, kb := range allKeyBindings {
if kb.Category == category {
result = append(result, kb)
}
}
return result, nil
}
// GetKeyBindingsByScope 根据作用域获取快捷键
func (kbs *KeyBindingService) GetKeyBindingsByScope(scope models.KeyBindingScope) ([]models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
allKeyBindings, err := kbs.GetAllKeyBindings()
if err != nil {
return nil, err
}
var result []models.KeyBinding
for _, kb := range allKeyBindings {
if kb.Scope == scope && kb.Enabled {
result = append(result, kb)
}
}
return result, nil
}
// GetKeyBindingByID 根据ID获取快捷键
func (kbs *KeyBindingService) GetKeyBindingByID(id string) (*models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
allKeyBindings, err := kbs.GetAllKeyBindings()
if err != nil {
return nil, err
}
for _, kb := range allKeyBindings {
if kb.ID == id {
return &kb, nil
}
}
return nil, &KeyBindingError{
Operation: "get_keybinding_by_id",
KeyID: id,
Err: errors.New("keybinding not found"),
}
}
// GetKeyBindingByAction 根据动作获取快捷键
func (kbs *KeyBindingService) GetKeyBindingByAction(action models.KeyBindingAction) (*models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
allKeyBindings, err := kbs.GetAllKeyBindings()
if err != nil {
return nil, err
}
for _, kb := range allKeyBindings {
if kb.Action == action && kb.Enabled {
return &kb, nil
}
}
return nil, &KeyBindingError{
Operation: "get_keybinding_by_action",
Err: fmt.Errorf("keybinding for action %s not found", action),
}
}
// UpdateKeyBinding 更新快捷键
func (kbs *KeyBindingService) UpdateKeyBinding(id string, newKey string) error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 验证新的快捷键格式
if err := kbs.validateKeyFormat(newKey); err != nil {
return &KeyBindingError{
Operation: "update_keybinding",
KeyID: id,
Err: fmt.Errorf("invalid key format: %v", err),
}
}
// 检查快捷键冲突
if err := kbs.checkKeyConflict(id, newKey); err != nil {
return &KeyBindingError{
Operation: "update_keybinding",
KeyID: id,
Err: fmt.Errorf("key conflict: %v", err),
}
}
// 获取当前配置
config, err := kbs.GetKeyBindingConfig()
if err != nil {
return &KeyBindingError{Operation: "update_keybinding", KeyID: id, Err: err}
}
// 查找并更新快捷键
found := false
for i, kb := range config.KeyBindings {
if kb.ID == id {
config.KeyBindings[i].Key = newKey
config.KeyBindings[i].IsDefault = false // 标记为非默认
found = true
break
}
}
if !found {
return &KeyBindingError{
Operation: "update_keybinding",
KeyID: id,
Err: errors.New("keybinding not found"),
}
}
// 更新时间戳
config.Metadata.LastUpdated = time.Now().Format(time.RFC3339)
// 保存配置
if err := kbs.saveConfig(config); err != nil {
return &KeyBindingError{Operation: "update_keybinding", KeyID: id, Err: err}
}
kbs.logger.Info("KeyBinding: Updated keybinding", "id", id, "newKey", newKey)
return nil
}
// EnableKeyBinding 启用快捷键
func (kbs *KeyBindingService) EnableKeyBinding(id string) error {
return kbs.setKeyBindingEnabled(id, true)
}
// DisableKeyBinding 禁用快捷键
func (kbs *KeyBindingService) DisableKeyBinding(id string) error {
return kbs.setKeyBindingEnabled(id, false)
}
// setKeyBindingEnabled 设置快捷键启用状态
func (kbs *KeyBindingService) setKeyBindingEnabled(id string, enabled bool) error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 获取当前配置
config, err := kbs.GetKeyBindingConfig()
if err != nil {
return &KeyBindingError{Operation: "set_keybinding_enabled", KeyID: id, Err: err}
}
// 查找并更新快捷键
found := false
for i, kb := range config.KeyBindings {
if kb.ID == id {
config.KeyBindings[i].Enabled = enabled
found = true
break
}
}
if !found {
return &KeyBindingError{
Operation: "set_keybinding_enabled",
KeyID: id,
Err: errors.New("keybinding not found"),
}
}
// 更新时间戳
config.Metadata.LastUpdated = time.Now().Format(time.RFC3339)
// 保存配置
if err := kbs.saveConfig(config); err != nil {
return &KeyBindingError{Operation: "set_keybinding_enabled", KeyID: id, Err: err}
}
action := "enabled"
if !enabled {
action = "disabled"
}
kbs.logger.Info("KeyBinding: "+action+" keybinding", "id", id)
return nil
}
// ResetKeyBinding 重置快捷键到默认值
func (kbs *KeyBindingService) ResetKeyBinding(id string) error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 获取默认配置
defaultKeyBindings := models.NewDefaultKeyBindings()
var defaultKeyBinding *models.KeyBinding
for _, kb := range defaultKeyBindings {
if kb.ID == id {
defaultKeyBinding = &kb
break
}
}
if defaultKeyBinding == nil {
return &KeyBindingError{
Operation: "reset_keybinding",
KeyID: id,
Err: errors.New("default keybinding not found"),
}
}
// 获取当前配置
config, err := kbs.GetKeyBindingConfig()
if err != nil {
return &KeyBindingError{Operation: "reset_keybinding", KeyID: id, Err: err}
}
// 查找并重置快捷键
found := false
for i, kb := range config.KeyBindings {
if kb.ID == id {
config.KeyBindings[i].Key = defaultKeyBinding.Key
config.KeyBindings[i].Enabled = defaultKeyBinding.Enabled
config.KeyBindings[i].IsDefault = true
found = true
break
}
}
if !found {
return &KeyBindingError{
Operation: "reset_keybinding",
KeyID: id,
Err: errors.New("keybinding not found"),
}
}
// 更新时间戳
config.Metadata.LastUpdated = time.Now().Format(time.RFC3339)
// 保存配置
if err := kbs.saveConfig(config); err != nil {
return &KeyBindingError{Operation: "reset_keybinding", KeyID: id, Err: err}
}
kbs.logger.Info("KeyBinding: Reset keybinding to default", "id", id, "key", defaultKeyBinding.Key)
return nil
}
// ResetAllKeyBindings 重置所有快捷键到默认值
func (kbs *KeyBindingService) ResetAllKeyBindings() error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 获取默认配置
defaultConfig := models.NewDefaultKeyBindingConfig()
// 保存配置
if err := kbs.saveConfig(defaultConfig); err != nil {
return &KeyBindingError{Operation: "reset_all_keybindings", Err: err}
}
kbs.logger.Info("KeyBinding: Reset all keybindings to default")
return nil
}
// saveConfig 保存配置到文件
func (kbs *KeyBindingService) saveConfig(config *models.KeyBindingConfig) error {
// 设置快捷键列表到viper
kbs.viper.Set("keyBindings", config.KeyBindings)
kbs.viper.Set("metadata.lastUpdated", config.Metadata.LastUpdated)
// 写入配置文件
if err := kbs.viper.WriteConfig(); err != nil {
return fmt.Errorf("failed to write keybinding config: %v", err)
}
return nil
}
// validateKeyFormat 验证快捷键格式
func (kbs *KeyBindingService) validateKeyFormat(key string) error {
if key == "" {
return errors.New("key cannot be empty")
}
// 基本格式验证
// 支持的修饰符: Mod, Ctrl, Shift, Alt, Win
// 支持的组合: Mod-f, Ctrl-Shift-p, Alt-ArrowUp 等
validModifiers := []string{"Mod", "Ctrl", "Shift", "Alt", "Win"}
parts := strings.Split(key, "-")
if len(parts) == 0 {
return errors.New("invalid key format")
}
// 检查修饰符
for i := 0; i < len(parts)-1; i++ {
modifier := parts[i]
valid := false
for _, validMod := range validModifiers {
if modifier == validMod {
valid = true
break
}
}
if !valid {
return fmt.Errorf("invalid modifier: %s", modifier)
}
}
// 最后一部分应该是主键
mainKey := parts[len(parts)-1]
if mainKey == "" {
return errors.New("main key cannot be empty")
}
return nil
}
// checkKeyConflict 检查快捷键冲突
func (kbs *KeyBindingService) checkKeyConflict(excludeID, key string) error {
allKeyBindings, err := kbs.GetAllKeyBindings()
if err != nil {
return err
}
for _, kb := range allKeyBindings {
if kb.ID != excludeID && kb.Key == key && kb.Enabled {
return fmt.Errorf("key %s is already used by %s", key, kb.ID)
}
}
return nil
}
// GetKeyBindingCategories 获取所有快捷键分类
func (kbs *KeyBindingService) GetKeyBindingCategories() []models.KeyBindingCategory {
return []models.KeyBindingCategory{
models.CategorySearch,
models.CategoryEdit,
models.CategoryCodeBlock,
models.CategoryNavigation,
models.CategoryView,
models.CategoryFile,
models.CategoryApp,
}
}
// GetKeyBindingScopes 获取所有快捷键作用域
func (kbs *KeyBindingService) GetKeyBindingScopes() []models.KeyBindingScope {
return []models.KeyBindingScope{
models.ScopeGlobal,
models.ScopeEditor,
models.ScopeSearch,
}
}
// ExportKeyBindings 导出快捷键配置
func (kbs *KeyBindingService) ExportKeyBindings() ([]models.KeyBinding, error) {
kbs.mu.RLock()
defer kbs.mu.RUnlock()
return kbs.GetAllKeyBindings()
}
// ImportKeyBindings 导入快捷键配置
func (kbs *KeyBindingService) ImportKeyBindings(keyBindings []models.KeyBinding) error {
kbs.mu.Lock()
defer kbs.mu.Unlock()
// 验证导入的快捷键
for _, kb := range keyBindings {
if err := kbs.validateKeyFormat(kb.Key); err != nil {
return &KeyBindingError{
Operation: "import_keybindings",
KeyID: kb.ID,
Err: fmt.Errorf("invalid key format for %s: %v", kb.ID, err),
}
}
}
// 检查重复的快捷键
keyMap := make(map[string]string)
for _, kb := range keyBindings {
if kb.Enabled {
if existingID, exists := keyMap[kb.Key]; exists {
return &KeyBindingError{
Operation: "import_keybindings",
Err: fmt.Errorf("duplicate key %s found in %s and %s", kb.Key, existingID, kb.ID),
}
}
keyMap[kb.Key] = kb.ID
}
}
// 创建新的配置
config := &models.KeyBindingConfig{
KeyBindings: keyBindings,
Metadata: models.KeyBindingMetadata{
LastUpdated: time.Now().Format(time.RFC3339),
},
}
// 保存配置
if err := kbs.saveConfig(config); err != nil {
return &KeyBindingError{Operation: "import_keybindings", Err: err}
}
kbs.logger.Info("KeyBinding: Imported keybindings", "count", len(keyBindings))
return nil
}

View File

@@ -9,14 +9,15 @@ import (
// ServiceManager 服务管理器,负责协调各个服务
type ServiceManager struct {
configService *ConfigService
documentService *DocumentService
migrationService *MigrationService
systemService *SystemService
hotkeyService *HotkeyService
dialogService *DialogService
trayService *TrayService
logger *log.LoggerService
configService *ConfigService
documentService *DocumentService
migrationService *MigrationService
systemService *SystemService
hotkeyService *HotkeyService
dialogService *DialogService
trayService *TrayService
keyBindingService *KeyBindingService
logger *log.LoggerService
}
// NewServiceManager 创建新的服务管理器实例
@@ -45,6 +46,9 @@ func NewServiceManager() *ServiceManager {
// 初始化托盘服务
trayService := NewTrayService(logger, configService)
// 初始化快捷键服务
keyBindingService := NewKeyBindingService(logger)
// 使用新的配置通知系统设置热键配置变更监听
err := configService.SetHotkeyChangeCallback(func(enable bool, hotkey *models.HotkeyCombo) error {
return hotkeyService.UpdateHotkey(enable, hotkey)
@@ -71,14 +75,15 @@ func NewServiceManager() *ServiceManager {
}
return &ServiceManager{
configService: configService,
documentService: documentService,
migrationService: migrationService,
systemService: systemService,
hotkeyService: hotkeyService,
dialogService: dialogService,
trayService: trayService,
logger: logger,
configService: configService,
documentService: documentService,
migrationService: migrationService,
systemService: systemService,
hotkeyService: hotkeyService,
dialogService: dialogService,
trayService: trayService,
keyBindingService: keyBindingService,
logger: logger,
}
}
@@ -92,6 +97,7 @@ func (sm *ServiceManager) GetServices() []application.Service {
application.NewService(sm.hotkeyService),
application.NewService(sm.dialogService),
application.NewService(sm.trayService),
application.NewService(sm.keyBindingService),
}
}
@@ -119,3 +125,8 @@ func (sm *ServiceManager) GetConfigService() *ConfigService {
func (sm *ServiceManager) GetTrayService() *TrayService {
return sm.trayService
}
// GetKeyBindingService 获取快捷键服务实例
func (sm *ServiceManager) GetKeyBindingService() *KeyBindingService {
return sm.keyBindingService
}