Claude Code Plugins

Community-maintained marketplace

Feedback

Best practices AutoHotkey v2. Use when writing AHK v2 scripts - covers global variable declarations, SetTimer usage, event handlers, and GUI positioning.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name julien-ref-ahk-v2
description Best practices AutoHotkey v2. Use when writing AHK v2 scripts - covers global variable declarations, SetTimer usage, event handlers, and GUI positioning.
triggers raccourci clavier windows, automatiser une tâche windows, mon script ahk ne marche pas, aide pour mon script ahk, help with my ahk script, create a hotkey, autohotkey v2, ahk v2, ahk2, autohotkey tutorial

AutoHotkey v2 - Best Practices pour LLM

RÈGLE CRITIQUE - VARIABLES GLOBALES

DÉCLARATION OBLIGATOIRE DANS CHAQUE FONCTION

; INCORRECT - Cause erreur "variable not assigned"
SomeFunction() {
    g_MyGlobalVar := "value"  ; ERREUR!
}

; CORRECT - Déclaration explicite requise
SomeFunction() {
    global g_MyGlobalVar      ; OBLIGATOIRE
    g_MyGlobalVar := "value"  ; OK
}

LISTE COMPLÈTE DES VARIABLES À DÉCLARER

FunctionUsingGlobals() {
    ; Déclarer TOUTES les variables globales utilisées
    global g_AppVersion, g_IsInitialized, g_ConfigFile
    global g_CachedPhrases, g_SavedSelections, g_CurrentProject

    ; Maintenant on peut les utiliser
    g_IsInitialized := true
    return g_AppVersion
}

STRUCTURE MODULAIRE AUTOHOTKEY V2

En-tête Standard

; Module.ahv2 - Description du module
; Encodage : UTF-8 avec BOM
; AutoHotkey v2

; Variables globales du module (si nécessaire)
global g_ModuleVar := ""

Ordre d'Inclusion Critique

; 1. Configuration TOUJOURS EN PREMIER
#Include "Config\Settings.ah2"
#Include "Config\Paths.ah2"

; 2. Modules Core
#Include "Core\Logger.ah2"
#Include "Core\FileManager.ah2"

; 3. Modules Features (qui dépendent de Core)
#Include "Features\PhraseManager.ah2"

; 4. GUI en dernier
#Include "GUI\MainInterface.ah2"

TIMERS ET ÉVÉNEMENTS - NOUVELLES ERREURS CRITIQUES

SetTimer vs Timer() - ERREUR CRITIQUE

; INCORRECT - Timer() n'existe pas en AHK v2
g_TooltipTimer := Timer(GUI_TooltipCheckMouse, 100)
g_TooltipTimer.Start()

; CORRECT - Utiliser SetTimer
SetTimer(GUI_TooltipCheckMouse, 100)

; CORRECT - Arrêter timer
SetTimer(GUI_TooltipCheckMouse, 0)  ; 0 = arrêter

; CORRECT - Timer périodique avec variable de contrôle
g_TimerActive := true
SetTimer(MyFunction, 100)

StopMyTimer() {
    global g_TimerActive
    g_TimerActive := false
    SetTimer(MyFunction, 0)
}

Event Handlers GUI - Signatures Correctes

; INCORRECT - Signature trop spécifique peut échouer
GUI_HandleResize(GuiObj, MinMax, Width, Height) {
    ; Cette signature peut ne pas correspondre à l'événement réel
}

; CORRECT - Signature flexible avec paramètres variables
GUI_HandleResize(*) {
    ; Récupérer dimensions via la GUI elle-même
    global g_MainGui
    g_MainGui.GetPos(, , &Width, &Height)
    ; ... traitement
}

; CORRECT - Event handlers standards
g_MainGui.OnEvent("Close", (*) => GUI_Hide())
g_MainGui.OnEvent("Size", GUI_HandleResize)  ; Fonction sans parenthèses
g_MainGui.OnEvent("Escape", (*) => GUI_Hide())

ListView Event Handlers

; CORRECT - Signatures standard ListView
ListView_OnItemCheck(ListViewObj, Item, Checked) {
    ; Item = numéro ligne, Checked = true/false
}

ListView_OnItemFocus(ListViewObj, Item) {
    ; Item = numéro ligne qui a le focus
}

; CORRECT - Assignment
g_ListView.OnEvent("ItemCheck", ListView_OnItemCheck)
g_ListView.OnEvent("ItemFocus", ListView_OnItemFocus)

INTERFACE UTILISATEUR - POSITIONNEMENT CRITIQUE

Calculs de Positionnement d'Interface

; PROBLÈME COURANT - Interface mal dimensionnée
CreateGUI() {
    ; Boutons positionnés trop bas, pas visibles
    g_Button1 := g_Gui.Add("Button", "x10 y450 w80 h30", "OK")
    g_ListView := g_Gui.Add("ListView", "x10 y70 w620 h400", cols)
    ; Total height = 70 + 400 + 30 = 500px mais fenêtre fait 480px
}

; SOLUTION - Calculs cohérents
CreateGUI() {
    ; Définir dimensions fenêtre d'abord
    windowHeight := 450
    headerHeight := 70
    footerHeight := 80  ; boutons + marge

    ; ListView adaptatif
    listViewHeight := windowHeight - headerHeight - footerHeight
    g_ListView := g_Gui.Add("ListView", "x10 y" . headerHeight . " w620 h" . listViewHeight, cols)

    ; Boutons dans footer calculé
    buttonY := headerHeight + listViewHeight + 10
    g_Button1 := g_Gui.Add("Button", "x10 y" . buttonY . " w80 h30", "OK")
}

GESTION DONNÉES STRUCTURÉES ET NUMÉROTATION

Objets avec Propriétés Multiples

; STRUCTURE ENRICHIE POUR CACHE
Cache_LoadData() {
    global g_CachedPhrases

    currentTitleNumber := 0
    currentPhraseNumber := 0

    ; Créer objets avec métadonnées complètes
    for lineNum, currentLine in lines {
        if (InStr(currentLine, ";;#") = 1) {
            currentTitleNumber++
            currentPhraseNumber := 0
            titleText := Trim(SubStr(currentLine, 4))

            g_CachedPhrases.Push({
                Type: "Title",
                Text: "[" . currentTitleNumber . "] === " . titleText . " ===",
                OriginalText: titleText,
                TitleNumber: currentTitleNumber
            })
        } else {
            currentPhraseNumber++
            g_CachedPhrases.Push({
                Type: "Phrase",
                Text: "[" . currentTitleNumber . "." . currentPhraseNumber . "] " . currentLine,
                OriginalText: currentLine,
                TitleNumber: currentTitleNumber,
                PhraseNumber: currentPhraseNumber
            })
        }
    }
}

Accès Propriétés Sécurisé

GUI_ProcessPhrases() {
    global g_CachedPhrases

    for phraseObj in g_CachedPhrases {
        ; Vérification existence propriété
        originalText := phraseObj.HasProp("OriginalText") ? phraseObj.OriginalText : phraseObj.Text

        ; Traitement conditionnel par type
        if (phraseObj.Type = "Title") {
            ; Traitement spécial titres
        } else if (phraseObj.Type = "Phrase") {
            ; Traitement phrases normales
        }
    }
}

ERREURS CRITIQUES À ÉVITER

  1. Variables globales sans déclaration - Cause systématiquement des erreurs
  2. Timer() au lieu de SetTimer - Timer() n'existe pas en AutoHotkey v2
  3. Event handlers avec signatures incorrectes - Utiliser (*) pour flexibilité
  4. Calculs interface incohérents - Boutons hors limites fenêtre
  5. Chemins relatifs incorrects dans les tests
  6. Ordre d'inclusion - Settings.ah2 TOUJOURS en premier
  7. Initialisation dans le désordre - Logger avant Cache
  8. Variables non initialisées - Toujours initialiser avant usage

CONVENTIONS DE NOMMAGE

; Variables globales
global g_AppVersion := "1.0.0"
global g_IsInitialized := false
global g_ConfigFile := ""

; Fonctions - Module_Action
Logger_Write()
Cache_Initialize()
PhraseManager_LoadData()

; Constantes en majuscules
global MAX_CACHE_SIZE := 1000
global DEFAULT_TIMEOUT := 5000

CHECKLIST VALIDATION

Avant de déployer un script AutoHotkey v2 :

  • Toutes les fonctions ont des déclarations global appropriées
  • SetTimer utilisé correctement (pas Timer())
  • Event handlers avec signatures flexibles (*)
  • Calculs interface cohérents (boutons dans limites fenêtre)
  • Ordre d'inclusion respecté (Config → Core → Features → GUI)
  • Chemins relatifs corrects dans les tests (..\..\)
  • Variables globales initialisées avant usage
  • Tests de compilation passent sans erreur
  • Gestion d'erreurs implémentée
  • Logging configuré pour debug