@@ -4,42 +4,171 @@ import (
44 "fmt"
55 "strings"
66
7+ "github.com/charmbracelet/lipgloss"
78 "github.com/xinnjie/onekeymap-cli/internal/mappings"
9+ "github.com/xinnjie/onekeymap-cli/pkg/pluginapi"
810)
911
1012type ActionDetailsViewModel struct {
11- actionID string
12- description string
13- category string
13+ actionID string
14+ description string
15+ category string
16+ editorSupport map [pluginapi.EditorType ]editorSupportInfo
17+ mappingConfig * mappings.ActionMappingConfig
1418}
1519
16- func newActionDetailsViewModel (actionID string , mc * mappings.MappingConfig ) ActionDetailsViewModel {
17- d := ActionDetailsViewModel {actionID : actionID }
20+ type editorSupportInfo struct {
21+ supported bool
22+ notSupportedReason string
23+ }
24+
25+ func newActionDetailsViewModel (actionID string , mc * mappings.MappingConfig ) * ActionDetailsViewModel {
26+ d := & ActionDetailsViewModel {
27+ actionID : actionID ,
28+ editorSupport : make (map [pluginapi.EditorType ]editorSupportInfo ),
29+ }
1830 if mc == nil {
1931 return d
2032 }
21- if mapping := mc .Get (actionID ); mapping != nil {
22- if mapping .Name != "" {
23- d .description = mapping .Name
24- } else if mapping .Description != "" {
25- d .description = mapping .Description
33+ mapping := mc .Get (actionID )
34+ if mapping == nil {
35+ return d
36+ }
37+
38+ d .mappingConfig = mapping
39+
40+ if mapping .Name != "" {
41+ d .description = mapping .Name
42+ } else if mapping .Description != "" {
43+ d .description = mapping .Description
44+ }
45+ if mapping .Category != "" {
46+ d .category = mapping .Category
47+ }
48+
49+ // Collect editor support information
50+ d .collectEditorSupport (mapping )
51+
52+ return d
53+ }
54+
55+ func (d * ActionDetailsViewModel ) collectEditorSupport (mapping * mappings.ActionMappingConfig ) {
56+ // Define all main editor types to check
57+ editorTypes := []pluginapi.EditorType {
58+ pluginapi .EditorTypeVSCode ,
59+ pluginapi .EditorTypeIntelliJ ,
60+ pluginapi .EditorTypeZed ,
61+ pluginapi .EditorTypeVim ,
62+ pluginapi .EditorTypeHelix ,
63+ }
64+
65+ for _ , editorType := range editorTypes {
66+ info := editorSupportInfo {
67+ supported : mapping .IsSupported (editorType ),
2668 }
27- if mapping .Category != "" {
28- d .category = mapping .Category
69+
70+ // Get not supported reason if applicable
71+ switch editorType {
72+ case pluginapi .EditorTypeVSCode :
73+ for _ , vc := range mapping .VSCode {
74+ if vc .NotSupported && vc .NotSupportedReason != "" {
75+ info .notSupportedReason = vc .NotSupportedReason
76+ break
77+ }
78+ }
79+ case pluginapi .EditorTypeIntelliJ :
80+ if mapping .IntelliJ .NotSupported {
81+ info .notSupportedReason = mapping .IntelliJ .NotSupportedReason
82+ }
83+ case pluginapi .EditorTypeZed :
84+ for _ , zc := range mapping .Zed {
85+ if zc .NotSupported && zc .NotSupportedReason != "" {
86+ info .notSupportedReason = zc .NotSupportedReason
87+ break
88+ }
89+ }
90+ case pluginapi .EditorTypeVim :
91+ if mapping .Vim .NotSupported {
92+ info .notSupportedReason = mapping .Vim .NotSupportedReason
93+ }
94+ case pluginapi .EditorTypeHelix :
95+ for _ , hc := range mapping .Helix {
96+ if hc .NotSupported && hc .NotSupportedReason != "" {
97+ info .notSupportedReason = hc .NotSupportedReason
98+ break
99+ }
100+ }
29101 }
102+
103+ d .editorSupport [editorType ] = info
30104 }
31- return d
32105}
33106
34- func (d ActionDetailsViewModel ) View () string {
107+ func (d * ActionDetailsViewModel ) View () string {
35108 var b strings.Builder
109+
110+ labelStyle := lipgloss .NewStyle ().Bold (true )
111+
36112 b .WriteString ("\n " )
37- fmt .Fprintf (& b , "Action: %s\n " , d .actionID )
113+ fmt .Fprintf (& b , "%s %s\n " , labelStyle . Render ( "Action:" ) , d .actionID )
38114 if d .description != "" {
39- fmt .Fprintf (& b , "Description: %s\n " , d .description )
115+ fmt .Fprintf (& b , "%s %s\n " , labelStyle . Render ( "Description:" ) , d .description )
40116 }
41117 if d .category != "" {
42- fmt .Fprintf (& b , "Category: %s\n " , d .category )
118+ fmt .Fprintf (& b , "%s %s\n " , labelStyle . Render ( "Category:" ) , d .category )
43119 }
120+
121+ // Display editor support
122+ if len (d .editorSupport ) > 0 {
123+ b .WriteString ("\n " )
124+ b .WriteString (d .renderEditorSupport (labelStyle ))
125+ }
126+
44127 return b .String ()
45128}
129+
130+ func (d * ActionDetailsViewModel ) renderEditorSupport (labelStyle lipgloss.Style ) string {
131+ var b strings.Builder
132+
133+ supportedStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("10" )) // Green
134+ notSupportedStyle := lipgloss .NewStyle ().Foreground (lipgloss .Color ("9" )) // Red
135+
136+ b .WriteString (labelStyle .Render ("Editor Support:" ) + "\n " )
137+
138+ // Define display order
139+ editorOrder := []pluginapi.EditorType {
140+ pluginapi .EditorTypeVSCode ,
141+ pluginapi .EditorTypeIntelliJ ,
142+ pluginapi .EditorTypeZed ,
143+ pluginapi .EditorTypeVim ,
144+ pluginapi .EditorTypeHelix ,
145+ }
146+
147+ for _ , editorType := range editorOrder {
148+ info , exists := d .editorSupport [editorType ]
149+ if ! exists {
150+ continue
151+ }
152+
153+ editorName := editorType .AppName ()
154+ status := d .formatEditorStatus (info , supportedStyle , notSupportedStyle )
155+ fmt .Fprintf (& b , " %-20s %s\n " , editorName + ":" , status )
156+ }
157+
158+ return b .String ()
159+ }
160+
161+ func (d * ActionDetailsViewModel ) formatEditorStatus (
162+ info editorSupportInfo ,
163+ supportedStyle , notSupportedStyle lipgloss.Style ,
164+ ) string {
165+ if info .supported {
166+ return supportedStyle .Render ("✓ Supported" )
167+ }
168+
169+ status := notSupportedStyle .Render ("✗ Not Supported" )
170+ if info .notSupportedReason != "" {
171+ status += fmt .Sprintf (" (%s)" , info .notSupportedReason )
172+ }
173+ return status
174+ }
0 commit comments