-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(shortcuts): generate shortcut actions from source
- Add generator for shortcut-actions.json from COSMIC source code - Add rustToNixType utility function for type conversion - Refactor shortcuts module to use generated actions - Remove hardcoded shortcut actions list
- Loading branch information
1 parent
fcd1ba9
commit 4ec258d
Showing
6 changed files
with
521 additions
and
194 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,260 @@ | ||
{ | ||
"Actions": [ | ||
{ | ||
"name": "Close" | ||
}, | ||
{ | ||
"name": "Debug" | ||
}, | ||
{ | ||
"name": "Disable" | ||
}, | ||
{ | ||
"name": "Focus", | ||
"type": "FocusDirection" | ||
}, | ||
{ | ||
"name": "LastWorkspace" | ||
}, | ||
{ | ||
"name": "Maximize" | ||
}, | ||
{ | ||
"name": "MigrateWorkspaceToNextOutput" | ||
}, | ||
{ | ||
"name": "MigrateWorkspaceToOutput", | ||
"type": "Direction" | ||
}, | ||
{ | ||
"name": "MigrateWorkspaceToPreviousOutput" | ||
}, | ||
{ | ||
"name": "Minimize" | ||
}, | ||
{ | ||
"name": "Move", | ||
"type": "Direction" | ||
}, | ||
{ | ||
"name": "MoveToLastWorkspace" | ||
}, | ||
{ | ||
"name": "MoveToNextOutput" | ||
}, | ||
{ | ||
"name": "MoveToNextWorkspace" | ||
}, | ||
{ | ||
"name": "MoveToOutput", | ||
"type": "Direction" | ||
}, | ||
{ | ||
"name": "MoveToPreviousOutput" | ||
}, | ||
{ | ||
"name": "MoveToPreviousWorkspace" | ||
}, | ||
{ | ||
"name": "MoveToWorkspace", | ||
"type": "u8" | ||
}, | ||
{ | ||
"name": "NextOutput" | ||
}, | ||
{ | ||
"name": "NextWorkspace" | ||
}, | ||
{ | ||
"name": "Orientation", | ||
"type": "Orientation" | ||
}, | ||
{ | ||
"name": "PreviousOutput" | ||
}, | ||
{ | ||
"name": "PreviousWorkspace" | ||
}, | ||
{ | ||
"name": "Resizing", | ||
"type": "ResizeDirection" | ||
}, | ||
{ | ||
"name": "SendToLastWorkspace" | ||
}, | ||
{ | ||
"name": "SendToNextOutput" | ||
}, | ||
{ | ||
"name": "SendToNextWorkspace" | ||
}, | ||
{ | ||
"name": "SendToOutput", | ||
"type": "Direction" | ||
}, | ||
{ | ||
"name": "SendToPreviousOutput" | ||
}, | ||
{ | ||
"name": "SendToPreviousWorkspace" | ||
}, | ||
{ | ||
"name": "SendToWorkspace", | ||
"type": "u8" | ||
}, | ||
{ | ||
"name": "SwapWindow" | ||
}, | ||
{ | ||
"name": "SwitchOutput", | ||
"type": "Direction" | ||
}, | ||
{ | ||
"name": "System", | ||
"type": "System" | ||
}, | ||
{ | ||
"name": "Spawn", | ||
"type": "String" | ||
}, | ||
{ | ||
"name": "Terminate" | ||
}, | ||
{ | ||
"name": "ToggleOrientation" | ||
}, | ||
{ | ||
"name": "ToggleStacking" | ||
}, | ||
{ | ||
"name": "ToggleSticky" | ||
}, | ||
{ | ||
"name": "ToggleTiling" | ||
}, | ||
{ | ||
"name": "ToggleWindowFloating" | ||
}, | ||
{ | ||
"name": "Workspace", | ||
"type": "u8" | ||
} | ||
], | ||
"Dependencies": { | ||
"Direction": [ | ||
{ | ||
"name": "Left" | ||
}, | ||
{ | ||
"name": "Right" | ||
}, | ||
{ | ||
"name": "Up" | ||
}, | ||
{ | ||
"name": "Down" | ||
} | ||
], | ||
"Orientation": [ | ||
{ | ||
"name": "Horizontal" | ||
}, | ||
{ | ||
"name": "Vertical" | ||
} | ||
], | ||
"System": [ | ||
{ | ||
"name": "AppLibrary" | ||
}, | ||
{ | ||
"name": "BrightnessDown" | ||
}, | ||
{ | ||
"name": "BrightnessUp" | ||
}, | ||
{ | ||
"name": "HomeFolder" | ||
}, | ||
{ | ||
"name": "KeyboardBrightnessDown" | ||
}, | ||
{ | ||
"name": "KeyboardBrightnessUp" | ||
}, | ||
{ | ||
"name": "Launcher" | ||
}, | ||
{ | ||
"name": "LockScreen" | ||
}, | ||
{ | ||
"name": "Mute" | ||
}, | ||
{ | ||
"name": "MuteMic" | ||
}, | ||
{ | ||
"name": "PlayPause" | ||
}, | ||
{ | ||
"name": "PlayNext" | ||
}, | ||
{ | ||
"name": "PlayPrev" | ||
}, | ||
{ | ||
"name": "Screenshot" | ||
}, | ||
{ | ||
"name": "Terminal" | ||
}, | ||
{ | ||
"name": "VolumeLower" | ||
}, | ||
{ | ||
"name": "VolumeRaise" | ||
}, | ||
{ | ||
"name": "WebBrowser" | ||
}, | ||
{ | ||
"name": "WindowSwitcher" | ||
}, | ||
{ | ||
"name": "WindowSwitcherPrevious" | ||
}, | ||
{ | ||
"name": "WorkspaceOverview" | ||
} | ||
], | ||
"FocusDirection": [ | ||
{ | ||
"name": "Left" | ||
}, | ||
{ | ||
"name": "Right" | ||
}, | ||
{ | ||
"name": "Up" | ||
}, | ||
{ | ||
"name": "Down" | ||
}, | ||
{ | ||
"name": "In" | ||
}, | ||
{ | ||
"name": "Out" | ||
} | ||
], | ||
"ResizeDirection": [ | ||
{ | ||
"name": "Inwards" | ||
}, | ||
{ | ||
"name": "Outwards" | ||
} | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
{ | ||
fetchurl, | ||
runCommand, | ||
python3, | ||
}: | ||
let | ||
actionRs = fetchurl { | ||
url = "https://github.com/pop-os/cosmic-settings-daemon/blob/61c76a9d060827402eeb9fe92cae73ce159d66e5/config/src/shortcuts/action.rs"; | ||
hash = "sha256-Qv2ACmoAm98GD2nhIXJpERSJdGhl/BxumfQH3EJzh+4="; | ||
}; | ||
in | ||
runCommand "shortcut-actions" { buildInputs = [ python3 ]; } '' | ||
cp ${actionRs} action.rs | ||
cp ${./main.py} main.py | ||
python3 main.py | ||
mkdir -p $out | ||
cp shortcut-actions.json $out | ||
'' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
import json | ||
import re | ||
from typing import Any, Dict, List, Set | ||
|
||
|
||
class EnumParser: | ||
def __init__(self, content: str): | ||
self.content = content | ||
self.parsed_enums: Dict[str, List[Dict[str, Any]]] = {} | ||
self.enum_dependencies: Set[str] = set() | ||
|
||
def find_enum_definition(self, enum_name: str) -> str: | ||
""" | ||
Find the full definition of an enum in the content. | ||
""" | ||
enum_pattern = rf"pub enum {enum_name} \{{([\s\S]*?)\}}" | ||
enum_match = re.search(enum_pattern, self.content) | ||
|
||
return enum_match.group(1) if enum_match else "" | ||
|
||
def clean_enum_content(self, content: str) -> str: | ||
""" | ||
Remove comments from enum content. | ||
""" | ||
# Remove multi-line comments | ||
content = re.sub(r"/\*[\s\S]*?\*/", "", content) | ||
# Remove single-line comments | ||
content = re.sub(r"//[^\n]*\n", "\n", content) | ||
|
||
return content | ||
|
||
def parse_enum_variants(self, enum_name: str) -> List[Dict[str, Any]]: | ||
""" | ||
Parse an enum's variants and detect dependencies. | ||
""" | ||
if enum_name in self.parsed_enums: | ||
return self.parsed_enums[enum_name] | ||
|
||
enum_content = self.find_enum_definition(enum_name) | ||
if not enum_content: | ||
return [] | ||
|
||
enum_content = self.clean_enum_content(enum_content) | ||
variants = [] | ||
|
||
variant_pattern = r"([A-Za-z]+)(?:\((.*?)\))?," | ||
matches = re.finditer(variant_pattern, enum_content) | ||
|
||
for match in matches: | ||
variant_name = match.group(1) | ||
variant_type = match.group(2) | ||
|
||
variant_info = {"name": variant_name} | ||
|
||
if variant_type: | ||
variant_info["type"] = variant_type.strip() | ||
|
||
# Check if the variant type is another enum | ||
enum_types = re.findall(r"([A-Z][a-zA-Z]+)", variant_type) | ||
for enum_type in enum_types: | ||
if self.find_enum_definition(enum_type): | ||
self.enum_dependencies.add(enum_type) | ||
|
||
variants.append(variant_info) | ||
|
||
self.parsed_enums[enum_name] = variants | ||
return variants | ||
|
||
def parse_all_actions(self) -> Dict[str, Any]: | ||
""" | ||
Parse all actions in the Action enum and all dependent enums recursively. | ||
""" | ||
self.parse_enum_variants("Action") | ||
|
||
processed_deps = set() | ||
while self.enum_dependencies - processed_deps: | ||
new_dep = (self.enum_dependencies - processed_deps).pop() | ||
self.parse_enum_variants(new_dep) | ||
processed_deps.add(new_dep) | ||
|
||
result = { | ||
"Actions": self.parsed_enums["Action"], | ||
"Dependencies": { | ||
enum_name: self.parsed_enums[enum_name] | ||
for enum_name in self.enum_dependencies | ||
}, | ||
} | ||
|
||
return result | ||
|
||
|
||
def main(): | ||
with open("action.rs", "r") as file: | ||
content = file.read() | ||
|
||
parser = EnumParser(content) | ||
result = parser.parse_all_actions() | ||
|
||
with open("shortcut-actions.json", "w") as f: | ||
json.dump(result, f, indent=2) | ||
|
||
|
||
if __name__ == "__main__": | ||
main() |
Oops, something went wrong.