Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- I had an idea and had Gemini flesh it out. The idea was to basically chain together forms and pass their outputs to each other to get the desired effect, and it's working exactly as intended:
- ## Match File `/match/eventargs.yml`
- ```yaml
- matches:
- - trigger: ":eventargs"
- # The final output comes from the last script variable
- replace: "{{code_generator}}"
- label: "Generate C# EventArgs class (Dynamic Args)"
- vars:
- # --- Step 1: Get Event Name and Number of Arguments ---
- - name: form1
- type: form
- params:
- layout: |
- EventArgs Class Generator
- Event Name (e.g., FindStation):
- [[EventName]]
- Number of arguments/variables:
- [[NumArgs]]
- fields:
- EventName:
- NumArgs:
- default: "1" # Default to 1 argument
- # --- Step 2: Generate Layout for the Second Form ---
- - name: layout_generator
- type: script
- params:
- args:
- - env
- - ESPANSO_NUM_ARGS={{form1.NumArgs}}
- - ESPANSO_EVENT_NAME={{form1.EventName}}
- - python
- - "%CONFIG%/scripts/generate_eventargs_form_layout.py"
- # --- Step 3: Show the Dynamically Generated Form ---
- - name: form2
- type: form
- params:
- # Use the layout string generated by the previous script
- layout: "{{layout_generator}}" # Espanso substitutes the stdout here
- # --- Step 4: Generate C# Code using Form 1 & Form 2 Inputs ---
- - name: code_generator
- type: script
- params:
- args:
- - env
- - ESPANSO_EVENT_NAME={{form1.EventName}}
- - ESPANSO_NUM_ARGS={{form1.NumArgs}}
- - python
- - "%CONFIG%/scripts/generate_eventargs_code_dynamic.py"matches:
- - trigger: ":eventargs"
- # The final output comes from the last script variable
- replace: "{{code_generator}}"
- label: "Generate C# EventArgs class (Dynamic Args)"
- vars:
- # --- Step 1: Get Event Name and Number of Arguments ---
- - name: form1
- type: form
- params:
- layout: |
- EventArgs Class Generator
- Event Name (e.g., FindStation):
- [[EventName]]
- Number of arguments/variables:
- [[NumArgs]]
- fields:
- EventName:
- NumArgs:
- default: "1" # Default to 1 argument
- # --- Step 2: Generate Layout for the Second Form ---
- - name: layout_generator
- type: script
- params:
- args:
- - env
- - ESPANSO_NUM_ARGS={{form1.NumArgs}}
- - ESPANSO_EVENT_NAME={{form1.EventName}}
- - python
- - "%CONFIG%/scripts/generate_eventargs_form_layout.py"
- # --- Step 3: Show the Dynamically Generated Form ---
- - name: form2
- type: form
- params:
- # Use the layout string generated by the previous script
- layout: "{{layout_generator}}" # Espanso substitutes the stdout here
- # --- Step 4: Generate C# Code using Form 1 & Form 2 Inputs ---
- - name: code_generator
- type: script
- params:
- args:
- - env
- - ESPANSO_EVENT_NAME={{form1.EventName}}
- - ESPANSO_NUM_ARGS={{form1.NumArgs}}
- - python
- - "%CONFIG%/scripts/generate_eventargs_code_dynamic.py"
- ```
- ## Python Scripts
- ### Form Layout Generator `/scripts/generate_eventargs_form_layout.py`
- ```python
- #!/usr/bin/env python
- # scripts/generate_eventargs_form_layout.py
- """
- Generates the layout string for the second Espanso form based on the
- number of arguments specified in the first form.
- Reads ESPANSO_NUM_ARGS and ESPANSO_EVENT_NAME.
- Prints the layout string to stdout.
- """
- import os
- import sys
- import logging
- # Configure logging
- logging.basicConfig(stream=sys.stderr, level=logging.WARNING, format='%(levelname)s:%(name)s:%(message)s')
- log = logging.getLogger('layout_generator')
- if __name__ == "__main__":
- layout_lines = []
- try:
- num_args_str = os.environ.get("ESPANSO_NUM_ARGS", "0")
- event_name = os.environ.get("ESPANSO_EVENT_NAME", "MyEvent") # Get name for title
- try:
- num_args = int(num_args_str)
- if num_args < 0:
- num_args = 0
- # Optional: Set a reasonable upper limit?
- # max_args = 10
- # if num_args > max_args:
- # log.warning(f"Number of args {num_args} exceeds maximum {max_args}, capping.")
- # num_args = max_args
- except ValueError:
- log.error(f"Invalid number of arguments received: '{num_args_str}'. Defaulting to 0.")
- num_args = 0
- # Start layout string - Use event name in title
- layout_lines.append(f"Define Arguments for {event_name}EventArgs")
- layout_lines.append("-" * (len(layout_lines[0]))) # Add underline
- if num_args == 0:
- layout_lines.append("\n(No arguments specified)")
- else:
- # Add fields dynamically
- for i in range(1, num_args + 1):
- layout_lines.append(f"\nArgument #{i}")
- layout_lines.append(f"Type [[type{i}]]")
- layout_lines.append(f"Name [[var{i}]]")
- # Join lines and print the final layout string
- print("\n".join(layout_lines), end='')
- except Exception as e:
- log.critical(f"Error generating form layout: {e}", exc_info=True)
- # Output a fallback layout in case of error
- print("Error generating layout\nError Message: [[error]]", end='')
- sys.exit(1)
- ```
- ### Code Builder `/scripts/generate_eventargs_code_dynamic.py`
- ```python
- #!/usr/bin/env python
- # scripts/generate_eventargs_code_dynamic.py
- """
- Generates the C# EventArgs class code based on the EventName and
- the arguments provided in the dynamically generated second form.
- Reads ESPANSO_EVENT_NAME, ESPANSO_NUM_ARGS, and ESPANSO_FORM2_TYPE/VAR pairs.
- Prints the generated C# code to stdout.
- """
- import os
- import sys
- import logging
- from typing import List, Tuple
- # Configure logging
- logging.basicConfig(stream=sys.stderr, level=logging.WARNING, format='%(levelname)s:%(name)s:%(message)s')
- log = logging.getLogger('code_generator')
- def generate_csharp_code(event_name: str, valid_args: List[Tuple[str, str]]) -> str:
- """Generates the C# EventArgs class code string."""
- if not event_name:
- event_name = "MyEvent" # Fallback name
- class_name = f"{event_name}EventArgs"
- indent = " " # 4 spaces for indentation
- # --- Build Code Parts ---
- field_lines = []
- param_list = []
- assignment_lines = []
- for arg_type, arg_name in valid_args:
- field_lines.append(f"{indent}public readonly {arg_type} {arg_name};")
- param_list.append(f"{arg_type} {arg_name}")
- assignment_lines.append(f"{indent}{indent}this.{arg_name} = {arg_name};")
- # Join parts
- fields_str = "\n".join(field_lines) if field_lines else ""
- params_str = ", ".join(param_list) if param_list else ""
- assignments_str = "\n".join(assignment_lines) if assignment_lines else ""
- # Handle constructor body indentation/newlines correctly
- constructor_body = f"\n{assignments_str}\n{indent}" if assignments_str else ""
- # Assemble final code
- code = f"""\
- public class {class_name} : EventArgs
- {{
- {fields_str}{"" if not fields_str else "\n"}
- {indent}public {class_name}({params_str})
- {indent}{{
- {constructor_body}}}
- }}""" # Using triple quotes for multi-line string
- return code
- if __name__ == "__main__":
- try:
- event_name = os.environ.get("ESPANSO_EVENT_NAME")
- num_args_str = os.environ.get("ESPANSO_NUM_ARGS", "0")
- if not event_name:
- log.error("EventName not received from environment.")
- print("// Error: EventName not provided.", file=sys.stderr)
- sys.exit(1)
- try:
- num_args = int(num_args_str)
- if num_args < 0: num_args = 0
- except ValueError:
- log.error(f"Invalid number of arguments received: {num_args_str}")
- print(f"// Error: Invalid NumArgs '{num_args_str}'", file=sys.stderr)
- sys.exit(1)
- # --- Collect valid arguments from form2 ---
- valid_args_list: List[Tuple[str, str]] = []
- log.debug(f"Expecting {num_args} argument pairs.")
- for i in range(1, num_args + 1):
- arg_type = os.environ.get(f"ESPANSO_FORM2_TYPE{i}", "").strip()
- arg_name = os.environ.get(f"ESPANSO_FORM2_VAR{i}", "").strip()
- log.debug(f"Read Arg {i}: Type='{arg_type}', Name='{arg_name}'")
- # Only include if BOTH type and name are non-empty
- if arg_type and arg_name:
- valid_args_list.append((arg_type, arg_name))
- log.debug(f"Added valid arg pair {i}: ({arg_type}, {arg_name})")
- else:
- log.debug(f"Skipping arg pair {i} because type or name was empty.")
- log.info(f"Collected {len(valid_args_list)} valid argument pairs.")
- # Generate the C# code
- csharp_code = generate_csharp_code(event_name, valid_args_list)
- # Print final code to stdout for Espanso
- print(csharp_code, end='')
- except Exception as e:
- log.critical(f"Error generating C# code: {e}", exc_info=True)
- print(f"// Error generating EventArgs code: {e}", file=sys.stderr)
- sys.exit(1)
- ```
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement