# Encargo: un portapapeles de 9 ranuras en Windows con AutoHotkey v2

Eres especialista en AutoHotkey **v2** sobre Windows. Vamos a construir un
script en **cuatro fases**. No adelantes fases: cada una termina esperando mi
respuesta.

## Qué quiero que haga el script

Nueve ranuras donde guardar textos que uso todo el día, y que **sobrevivan al
reinicio**. Funciona con dos modos, y en cada uno elijo la ranura con un dígito:

- **Modo PEGAR**: pulso el líder, aparece la lista, pulso `1`–`9`, y pega el
  texto de esa ranura donde tenga el cursor.
- **Modo COPIAR**: selecciono un texto, pulso el otro líder, pulso `1`–`9`, y
  ese texto queda guardado en esa ranura.

Detalles que importan:

- Al entrar en cualquiera de los dos modos, **muéstrame en pantalla las nueve
  ranuras con su contenido actual**, recortado. Quiero elegir viendo lo que hay,
  no recordando.
- **Beep de confirmación** cuando la acción sale bien, y un beep distinto y más
  grave cuando falla (ranura vacía, nada seleccionado).
- `Esc` cancela el modo, y el modo **caduca solo** a los 5 segundos si no elijo.
- El dígito debe valer **con el líder aún pulsado o ya soltado**. Las dos formas.

Los nueve textos viven en un archivo `ranuras.txt` **junto al script**, que el
propio script crea la primera vez. Formato: una línea por ranura, `numero:valor`.
Quiero poder abrirlo con el Bloc de notas, escribir dentro y que surta efecto
**sin recargar nada**.

---

## FASE 1 — Propón combinaciones y espera mi elección

**No escribas código todavía.** Necesito **dos** líderes, uno para pegar y otro
para copiar. Ofréceme **tres** parejas posibles, cada una con su coste
explícito: qué deja de funcionar en mi equipo si la elijo. Luego pregúntame cuál
prefiero y **detente**.

Para que las propongas bien, esto es lo que hay que saber:

**AltGr es `Ctrl` + `Alt` derecho.** En teclados español, latinoamericano o
US-Internacional, un atajo `Ctrl+Alt+tecla` se dispara al escribir `@`, `~`, `|`
o `€`. Si propones esa familia, exige los modificadores **izquierdos** (`<^<!`),
que AltGr no puede producir.

**Familias de teclas, por ocupación:**

| Familia | Estado |
|---|---|
| `Ctrl+Alt+letra` | minada: las suites de oficina reservan `C R T` (símbolos ©®™), `V` (pegado especial), `D F M` (notas y comentarios), `N O P I S` (vistas y ventanas), `K L Y Z`, y `1 2 3` (estilos de título) |
| `Ctrl+Shift+letra` | minada: selección por palabras, pegado sin formato, herramientas de desarrollo del navegador |
| `Win+letra` | casi toda reservada por el sistema |
| **`Win+Alt+letra`** | **libre**, salvo `R G B D` (grabadora de pantalla del sistema). Las suites de oficina no usan la tecla Windows |
| **`CapsLock` como prefijo** | **libre en absoluto**: ninguna aplicación lo usa como modificador. Coste: su función nativa |

Ten en cuenta que las letras con memoria son `V` de pegar y `C` de copiar, las
mismas de `Ctrl+V` y `Ctrl+C`, y que la familia decide si puedo conservarlas.

Propón, no impongas. La combinación es lo único del script que yo teclearé cien
veces.

---

## FASE 2 — Entrega el script como archivo descargable

Cuando yo haya elegido:

**Entrégame un archivo `.ahk` para descargar. No me pegues el código en un
bloque para que yo lo copie.** Escríbelo y dame el enlace de descarga. En cada
iteración posterior, entrega un **archivo nuevo completo**, no un parche ni un
fragmento. Es un solo archivo: el `ranuras.txt` lo crea el script.

Detalles obligatorios del archivo:

- Guárdalo en **UTF-8 con BOM**. Sin BOM, los acentos y la `ñ` se corrompen al
  cargarlo.

Además del archivo, dime en el mensaje: qué hace cada parte.

### El diseño que quiero

**El archivo de ranuras.** Ruta derivada de dónde está el script (`A_ScriptDir`),
para que la carpeta se pueda mover. Cabecera de comentarios dentro del propio
archivo explicando el formato, y una línea por ranura:

```
# Una linea por ranura:  numero:valor
1:correo@ejemplo.com
2:
```

Como una ranura ocupa una línea, los saltos de línea van escapados como `\n`,
los tabuladores como `\t`, y la barra invertida literal como `\\`. Codifica al
guardar y descodifica al leer.

**Lee el archivo entero en cada uso.** Son unos pocos bytes: así lo que yo
escriba a mano surte efecto al instante y no hay caché que invalidar ni dos
fuentes de verdad.

**El modo** es una variable global (`""`, `"pegar"`, `"copiar"`) que condiciona
los dígitos con `#HotIf`. Un temporizador de disparo único la cierra sola.

**Copiar**: envía `Ctrl+C` a la ventana activa y espera el portapapeles con
`ClipWait`. Si no había nada seleccionado, usa lo que ya hubiera en el
portapapeles; si tampoco hay nada, avísame y no toques la ranura.

**Pegar**: guarda el portapapeles actual, pon el texto de la ranura, envía
`Ctrl+V`, y **devuelve el portapapeles anterior** unos 900 ms después. Que sea
una constante de cabecera para poder desactivarlo con un `0`.

**Antes de cada envío sintético, suelta los modificadores** con
`SendEvent("{Ctrl up}{Alt up}{Shift up}{LWin up}{RWin up}")`: yo todavía tengo
pulsados los del propio atajo y contaminarían la combinación. Registra lo mismo
en `OnExit`, para no dejar el teclado trabado si el script muere.

Añade al menú del icono de bandeja una entrada para **abrir `ranuras.txt`**.

### AutoHotkey v2: lo que necesitas para escribirlo

**La cabecera es obligatoria y la primera línea no se discute.** Sin
`#Requires`, un intérprete v1 intentará cargarlo y fallará de forma confusa:

```ahk
#Requires AutoHotkey v2.0
#SingleInstance Force
#UseHook True
#Warn
#MaxThreadsPerHotkey 1
```

`#UseHook True` evita que los envíos del propio script disparen sus hotkeys.
`#MaxThreadsPerHotkey 1` impide la reentrada.

**v2 no es v1.** Estos son los errores que comete un modelo escribiendo de
memoria:

| v1, inválido | v2 correcto |
|---|---|
| `MsgBox, Hola %nombre%` | `MsgBox("Hola " nombre)` |
| `var = texto` | `var := "texto"` |
| `StringReplace, out, in, a, b` | `out := StrReplace(in, "a", "b")` |
| `#If activeMode != ""` | `#HotIf modo != ""` |
| `SetTimer, Etiqueta, 1000` | `SetTimer(MiFuncion, 1000)` — la referencia, sin comillas |
| `Clipboard` | `A_Clipboard` |
| `ErrorLevel` | `try` / `catch` |
| `return` cerrando un hotkey multilínea | llaves `{ }` alrededor del cuerpo |

Todo parámetro es una expresión. El texto literal va entre comillas. `:=` es la
única asignación. La concatenación es un espacio entre operandos. El carácter de
escape es la comilla invertida.

**Ámbito.** Dentro de una función el ámbito es local por defecto. Se puede
**leer** una global sin declararla, pero para **escribirla** hay que poner
`global nombre` dentro de la función.

**Modificadores en el nombre del hotkey:** `#` Win, `!` Alt, `^` Ctrl, `+`
Shift, `<` solo el izquierdo, `>` solo el derecho, `*` comodín que dispara aunque
haya modificadores extra pulsados. Los dígitos del modo **necesitan el `*`**, que
es lo que hace que valgan con el líder pulsado o soltado:

```ahk
modo := ""

#<!v:: EntrarModo("pegar")      ; Win + Alt izquierdo + V

#HotIf modo != ""
*1::UsarRanura(1)
*2::UsarRanura(2)
; ... hasta 9
*Esc::CancelarModo()
#HotIf                          ; cerrar el bloque SIEMPRE
```

**Funciones que vas a necesitar:** `SoundBeep(frecuencia, duracion)`,
`A_Clipboard`, `ClipboardAll()`, `ClipWait(segundos, 0)`, `SendInput("^c")`,
`SendEvent(...)`, `ToolTip(texto, x, y)`, `CoordMode("ToolTip", "Screen")`,
`MonitorGetWorkArea(indice, &izq, &arr, &der, &aba)`, `MonitorGetPrimary()`,
`SetTimer(Funcion, -1000)` para disparo único y `SetTimer(Funcion, 0)` para
cancelar, `FileExist`, `FileRead(ruta, "UTF-8")`,
`FileOpen(ruta, "w", "UTF-8")` con `.Write()` y `.Close()`, `A_ScriptDir`,
`StrSplit`, `StrReplace`, `SubStr`, `InStr`, `Trim`, `IsInteger`, `StrLen`,
`A_TrayMenu.Insert()`, `Run(ruta)`.

### Antes de entregarlo, repasa esta lista

Son los cuatro fallos que de verdad rompen este script:

1. **Los nombres de variable no distinguen mayúsculas.** Una constante global
   `RANURAS` y una variable local `ranuras` son **la misma**, y como basta una
   asignación para que el nombre sea local en toda la función, la lectura de la
   "global" leería una variable sin asignar. Revisa que ninguna local se llame
   como una global salvo por las mayúsculas.
2. **`global` en toda función que escriba una global.** Sin esa línea, la
   asignación crea una local y el modo nunca cambia.
3. **`#HotIf` cerrado** con un `#HotIf` a secas. Si no, todos los hotkeys
   siguientes quedan condicionados.
4. **El `*` en los dígitos.** Sin él, el dígito no dispara si yo mantengo
   pulsados los modificadores del líder.

Si al lanzarlo aparece un cuadro de diálogo de advertencia, o el script parece
no arrancar, es `#Warn` avisándome de alguno de los cuatro. Léelo, no lo quites.

---

## FASE 3 — Itera hasta que lo apruebe

Termina la fase 2 preguntándome explícitamente si el resultado me sirve. Si te
digo que no, o si te pego un error, corrige y **entrégame un archivo nuevo**.
Repite hasta que yo diga que está bien. No pases a la fase 4 por tu cuenta.

Si al probarlo un atajo no dispara, estas son las causas por orden de
probabilidad: otra aplicación o script ya tiene esa combinación registrada; la
ventana activa pertenece a un programa ejecutado como administrador y el script
no lo está; el `#HotIf` está evaluando falso; o falta el `*` en los dígitos.
Diagnostica antes de cambiar código.

---

## FASE 4 — El mapa de comandos, solo cuando yo lo apruebe

Cuando yo diga que el script está bien, **ofréceme** (no lo hagas sin
preguntar) un **mapa de comandos en HTML**, también como archivo descargable.

Requisitos:

- **Un solo archivo, autocontenido.** Nada de fuentes, hojas de estilo, imágenes
  ni scripts externos: tiene que verse igual sin conexión.
- **Escrito para quien no programa.** Sin jerga, sin rutas técnicas, sin hablar
  de código. Nada de README de desarrollador.
- **Minimalista y estético.** Las teclas dibujadas como teclas. Que se entienda
  en cinco segundos qué se pulsa y qué pasa.
- Que se vea bien en tema claro y oscuro, y que se pueda imprimir en una hoja.
- Contenido: los dos atajos con sus dos pasos (líder, luego número), qué hace
  cada uno, dónde está el archivo de las nueve ranuras y cómo editarlo a mano, y
  los dos pasos para instalarlo (instalar AutoHotkey v2 desde `autohotkey.com`, y
  doble clic en el archivo).

---

## Recordatorio final

Cuatro fases, cuatro paradas. Empieza por la **fase 1**: tres parejas de líderes
con su coste, y espera mi elección. No escribas código en tu primer mensaje.
