@@ -5,6 +5,7 @@ pub use action::Action;
55
66pub mod modifier;
77
8+ use action:: Direction ;
89pub use modifier:: { Modifier , Modifiers , ModifiersDef } ;
910
1011mod binding;
@@ -14,10 +15,13 @@ pub mod sym;
1415
1516use cosmic_config:: cosmic_config_derive:: CosmicConfigEntry ;
1617use cosmic_config:: { ConfigGet , CosmicConfigEntry } ;
18+ use serde:: de:: Unexpected ;
19+ use serde:: ser:: SerializeMap ;
1720use serde:: { Deserialize , Serialize } ;
1821use std:: collections:: BTreeMap ;
1922use std:: collections:: HashMap ;
20- use xkbcommon:: xkb;
23+ use sym:: NO_SYMBOL ;
24+ use xkbcommon:: xkb:: { self , Keysym } ;
2125
2226pub const ID : & str = "com.system76.CosmicSettings.Shortcuts" ;
2327
@@ -74,6 +78,31 @@ pub fn system_actions(context: &cosmic_config::Config) -> SystemActions {
7478 config
7579}
7680
81+ /// Get a map of vim symbols and their configured directions
82+ pub fn vim_symbols ( context : & cosmic_config:: Config ) -> VimSymbols {
83+ let mut config = VimSymbols :: default ( ) ;
84+
85+ // Get the system config first
86+ if let Ok ( context) = cosmic_config:: Config :: system ( ID , Config :: VERSION ) {
87+ match context. get :: < VimSymbolsImpl > ( "vim_symbols" ) {
88+ Ok ( vim_symbols) => config = vim_symbols. 0 ,
89+ Err ( why) => {
90+ tracing:: error!( "failed to read system shortcuts config 'vim_symbols': {why:?}" )
91+ }
92+ }
93+ }
94+
95+ // Then override it with the user's config
96+ match context. get :: < VimSymbolsImpl > ( "vim_symbols" ) {
97+ Ok ( user_config) => config. extend ( user_config. 0 ) ,
98+ Err ( why) => {
99+ tracing:: error!( "failed to read local shortcuts config 'vim_symbols': {why:?}" )
100+ }
101+ }
102+
103+ config
104+ }
105+
77106/// cosmic-config configuration state for `com.system76.CosmicSettings.Shortcuts`
78107#[ derive( Clone , Debug , Default , PartialEq , CosmicConfigEntry ) ]
79108#[ version = 1 ]
@@ -99,6 +128,79 @@ impl Config {
99128 }
100129}
101130
131+ pub type VimSymbols = BTreeMap < Keysym , Direction > ;
132+
133+ struct VimSymbolsImpl ( VimSymbols ) ;
134+
135+ impl Serialize for VimSymbolsImpl {
136+ fn serialize < S > ( & self , serializer : S ) -> Result < S :: Ok , S :: Error >
137+ where
138+ S : serde:: Serializer ,
139+ {
140+ let mut map = serializer. serialize_map ( Some ( self . 0 . len ( ) ) ) ?;
141+ for ( k, v) in self . 0 . iter ( ) {
142+ map. serialize_entry ( & xkb:: keysym_get_name ( k. clone ( ) ) , & v) ?;
143+ }
144+ map. end ( )
145+ }
146+ }
147+
148+ struct VimSymbolsVisitor ;
149+
150+ impl < ' de > serde:: de:: Visitor < ' de > for VimSymbolsVisitor {
151+ type Value = VimSymbolsImpl ;
152+
153+ fn expecting ( & self , formatter : & mut std:: fmt:: Formatter ) -> std:: fmt:: Result {
154+ formatter. write_str ( "VimSymbols Map" )
155+ }
156+
157+ fn visit_map < A > ( self , mut access : A ) -> Result < Self :: Value , A :: Error >
158+ where
159+ A : serde:: de:: MapAccess < ' de > ,
160+ {
161+ let mut map = VimSymbols :: new ( ) ;
162+
163+ while let Some ( ( keystring, dir) ) =
164+ access. next_entry :: < & ron:: value:: RawValue , Direction > ( ) ?
165+ {
166+ match keystring. into_rust :: < & str > ( ) {
167+ Ok ( val) => {
168+ let key = match xkb:: keysym_from_name ( val, xkb:: KEYSYM_NO_FLAGS ) {
169+ x if x. raw ( ) == NO_SYMBOL => {
170+ match xkb:: keysym_from_name ( val, xkb:: KEYSYM_CASE_INSENSITIVE ) {
171+ x if x. raw ( ) == NO_SYMBOL => Err ( <A :: Error as serde:: de:: Error >:: invalid_value ( Unexpected :: Str ( val) , & "One of the keysym names of xkbcommon.h without the 'KEY_' prefix" ) ) ,
172+ x => Ok ( Some ( x) )
173+ }
174+ }
175+ x => Ok ( Some ( x) ) ,
176+ } ?;
177+ if let Some ( key) = key {
178+ map. insert ( key, dir) ;
179+ }
180+ }
181+ Err ( err) => {
182+ tracing:: warn!(
183+ "Skipping over invalid Keysym ({}): {}" ,
184+ keystring. get_ron( ) ,
185+ err
186+ ) ;
187+ }
188+ }
189+ }
190+
191+ Ok ( VimSymbolsImpl ( map) )
192+ }
193+ }
194+
195+ impl < ' de > Deserialize < ' de > for VimSymbolsImpl {
196+ fn deserialize < D > ( deserializer : D ) -> Result < Self , D :: Error >
197+ where
198+ D : serde:: Deserializer < ' de > ,
199+ {
200+ deserializer. deserialize_map ( VimSymbolsVisitor )
201+ }
202+ }
203+
102204/// A map of defined key [Binding]s and their triggerable [Action]s
103205#[ derive( Clone , Debug , Default , PartialEq , Serialize ) ]
104206#[ serde( transparent) ]
0 commit comments