Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions .github/workflows/ahk-lint-format-compile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,20 @@ jobs:
- uses: actions/checkout@v6

- name: Install AutoHotkey v1.1 (Portable)
run: choco install autohotkey.portable --version=1.1.37.02 -y
run: choco install autohotkey.portable -y
shell: pwsh

- name: Install AutoHotkey v2
run: choco install autohotkey --version=2.0.19 -y
run: choco install autohotkey -y
shell: pwsh
Comment on lines +22 to +26
Copy link

Copilot AI Feb 4, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing the version pins from the AutoHotkey installations makes the CI/CD pipeline non-deterministic. The workflow will now install whatever the latest versions are at the time of execution, which could introduce breaking changes or unexpected behavior if new versions are released.

This is particularly risky because:

  1. AutoHotkey v2.x is still evolving and could introduce breaking syntax changes
  2. The scripts in this repository depend on specific v2 syntax and behavior
  3. CI/CD failures could occur intermittently when new versions are released

Consider either:

  • Keeping the version pins for reproducibility (recommended)
  • If flexibility is needed, pin to major versions only (e.g., --version=2.0 or use version ranges)
  • Document why version pins were removed if there's a specific reason

Copilot uses AI. Check for mistakes.
- name: Install Ahk2Exe
run: |
$url = "https://github.com/AutoHotkey/Ahk2Exe/releases/latest/download/Ahk2Exe1.zip"
$dest = "C:\Ahk2Exe"
New-Item -ItemType Directory -Force -Path $dest | Out-Null
Invoke-WebRequest -Uri $url -OutFile "$dest\Ahk2Exe.zip"
Expand-Archive "$dest\Ahk2Exe.zip" -DestinationPath $dest -Force
Remove-Item "$dest\Ahk2Exe.zip"
Write-Host "Ahk2Exe installed to $dest"
shell: pwsh

- name: Verify Installations
Expand All @@ -37,11 +46,10 @@ jobs:
Write-Host "Installed AHK v1: $((Get-Item $ahkV1).VersionInfo.FileVersion)"
Write-Host "Installed AHK v2: $(& $ahkV2 --version)"
shell: pwsh

- name: Syntax Check & Format Validation
run: |
$compilerV1 = "C:\ProgramData\chocolatey\lib\autohotkey.portable\tools\Compiler\Ahk2Exe.exe"
$compilerV2 = "$env:ProgramFiles\AutoHotkey\Compiler\Ahk2Exe.exe"
$compilerExe = "C:\Ahk2Exe\Ahk2Exe.exe"

$tempDir = New-Item -Type Directory -Force "$env:TEMP\ahk-$(Get-Random)"
$syntaxErrors = @()
$formatIssues = @()
Expand All @@ -66,7 +74,8 @@ jobs:
$isV2 = $true
}

$compiler = if ($isV2) { $compilerV2; $v2Count++ } else { $compilerV1; $v1Count++ }
if ($isV2) { $v2Count++ } else { $v1Count++ }
$compiler = $compilerExe
$version = if ($isV2) { "v2" } else { "v1" }

# Syntax check
Expand Down
44 changes: 38 additions & 6 deletions Other/AutoStartManager.ahk
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,44 @@ if (!FileExist(configFile)) {

; Read configuration
try {
exeName := IniRead(configFile, emulatorName, "exe")
key := IniRead(configFile, emulatorName, "key", "F11")
maximize := IniRead(configFile, emulatorName, "maximize", "true") = "true"
delay := Integer(IniRead(configFile, emulatorName, "delay", "0"))
activate := IniRead(configFile, emulatorName, "activate", "false") = "true"
special := IniRead(configFile, emulatorName, "special", "none")
; Optimization: Read the entire section once to reduce disk I/O
sectionContent := IniRead(configFile, emulatorName)
if (sectionContent = "") {
throw Error("Section '" . emulatorName . "' not found in config file or is empty")
}
config := Map()
config.CaseSense := "Off" ; Ensure case-insensitive lookups (INI standard)
Loop Parse, sectionContent, "`n", "`r" {
if (p := InStr(A_LoopField, "=")) {
k := Trim(SubStr(A_LoopField, 1, p-1))
v := Trim(SubStr(A_LoopField, p+1))
config[k] := v
}
}

if !config.Has("exe") {
if (config.Count = 0)
throw Error("Section '" . emulatorName . "' is empty or missing required key 'exe'")
else
throw Error("Key 'exe' not found in section '" . emulatorName . "'")
}

exeName := config["exe"]
key := config.Has("key") ? config["key"] : "F11"
maximize := (config.Has("maximize") ? config["maximize"] : "true") = "true"
if config.Has("delay") {
delayRaw := config["delay"]
if RegExMatch(delayRaw, "^[+-]?\d+$") {
delay := Integer(delayRaw)
} else {
throw Error("Invalid delay value '" . delayRaw . "' in section '" . emulatorName . "': must be an integer number of milliseconds")
}
} else {
delay := 0
}
activate := (config.Has("activate") ? config["activate"] : "false") = "true"
special := config.Has("special") ? config["special"] : "none"
Comment on lines 61 to 74

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The current approach for handling default values using config.Has("key") ? ... : ... is functional but can be simplified. AutoHotkey v2's Map object provides a Get(Key, Default) method that achieves the same result more concisely. Using Map.Get() would make the code more readable and idiomatic.

    key := config.Get("key", "F11")
    maximize := config.Get("maximize", "true") = "true"
    delay := Integer(config.Get("delay", "0"))
    activate := config.Get("activate", "false") = "true"
    special := config.Get("special", "none")


} catch Error as err {
MsgBox("Error reading config for " . emulatorName . ":`n" . err.Message)
ExitApp()
Expand Down
Loading