La To-Do List del IDE, rellenada desde fuera: cada entrada apunta a un objeto y a una línea concretos.
Durante las vacaciones me he puesto a trastear con una ventana que uso desde hace años y que, a la vez, casi nunca he rellenado yo: Tools > To-Do List. Suena contradictorio, pero me juego algo a que a más de uno le pasa lo mismo.
La explicación tiene nombre: PBSearch, la herramienta de búsqueda de Roland Smith (Topwiz Software), que llevo usando una década larga. Tiene un botón «To Do List» que vuelca ahí los resultados de una búsqueda: te pone el nombre del objeto en cada entrada y, al abrirla, te lleva a ese objeto en su painter. No te deja en la línea concreta, y es normal: para eso PBSearch ya tiene su propio editor. Así que mi To-Do List siempre ha sido, en la práctica, algo que me rellena otro.
A mano también se puede, ojo. Lo que pasa es que tuve que mirarlo en la ayuda, porque a simple vista no me pareció nada intuitivo. Es todo por menú contextual dentro de la ventana:
- Add — una tarea suelta, sin enlazar a nada.
- Add Linked — la tarea enlazada a un objeto… pero al painter que tengas abierto en ese momento. Es decir: para poder apuntar algo, tienes que haberlo abierto antes.
- Luego, Go To Link (o doble clic) para ir, arrastrar para reordenar, la casilla del margen izquierdo para marcar, y Delete / Delete All para limpiar. Incluso hay Export e Import a fichero de texto, para pasarle la lista a otro compañero.
Y ahí está el detalle que lo explica todo: solo puedes apuntar lo que ya tienes delante. Justo lo contrario de lo que uno quiere hacer, que es dejarse anotado lo que todavía no ha abierto.
Con eso en la cabeza me dio una idea. Porque llevo meses trabajando con Claude Code sobre fuentes de PowerBuilder y siempre acabo en el mismo sitio: le pido «busca dónde se usa esto» y me devuelve una lista estupenda de rutas y números de línea… que luego tengo que ir abriendo a mano, uno por uno. Si PBSearch puede dejarme sus resultados ahí dentro, ¿por qué no va a poder Claude?
Solo hacía falta averiguar cómo lo hace. Así que gracias, Roland: tú me enseñaste que la puerta existía; lo que cuento aquí es lo que encontré al tirar del hilo.
El primer intento: abrir un objeto desde la línea de comandos
Lo primero que probé fue lo más obvio y, además, documentado: PowerBuilder acepta parámetros para arrancar ya plantado en un objeto.
PB250.exe /w mi.pbsln /t mi.pbproj /l ruta\mi.pbl /p window /o w_main
Funciona. Pero se me escapó un detalle de la documentación que estaba escrito y yo había leído por encima:
«Except for the /W, /T, and /L switches, other switches must follow /P paintername»
O sea: sin /p, el IDE abre pelado y el /o no hace nada. El nombre del painter además se abrevia (dataw por DataWindow, q por Query…).
Ahora bien, tiene sus limitaciones:
- No hay
/line. Existe en la cabeza de mucha gente, pero se ignora. Te abre el painter y ahí te quedas, en la línea 1. - No hay Edit Source por comando.
- Abre una segunda instancia del IDE aunque ya tengas una funcionando. No hay forma de decirle nada a la que ya está abierta.
- Y sobre todo: abre UN objeto. Una búsqueda tiene catorce resultados, no uno.
Y ahí es donde la To-Do List se pone interesante.
¿Dónde vive la To-Do List? En el registro
Aquí es donde tuve que explorar un poco. La documentación de Appeon explica qué es la To-Do List y cómo se usa desde el IDE, que es para lo que está pensada, pero no entra en dónde se guarda — no hace falta para usarla. Y ORCA, el API oficial de librerías, tampoco expone nada de To-Do (lo comprobé: ni una coincidencia en el pborca.h del SDK).
Así que toca mirar dónde lo deja el IDE. Y lo deja a la vista, en un sitio de lo más razonable.
No es un fichero. Es el registro de Windows:
HKCU\Software\Sybase\PowerBuilder\<versión>\Target\<fichero_target>\ToDo HKCU\Software\Sybase\PowerBuilder\<versión>\Workspace\<fichero_wsp>\ToDo
Con dos detalles en el nombre de la clave que conviene saber de antemano:
- La rama sigue siendo Sybase, no Appeon, incluso en PowerBuilder 2025. Herencia de toda la vida, y se agradece: significa que esto lleva ahí, igual, desde hace muchísimas versiones.
- Las
\de la ruta van codificadas como$, porque una clave del registro no puede llevar barras:C:$proyectos$mi.pbproj.
El contenido es texto plano (REG_SZ): un valor por entrada, numerados 0, 1, 2… más un Count y un Selection. Y ojo con Count, que manda él: si no cuadra con el número de valores, el IDE sencillamente no lee la lista.
Cada entrada son cuatro campos separados por tabulador:
n → Usos de of_set_celda - w_main:159 → window:///C|/.../pypbexample.pbl?action=opensource&entry=w_main&line=159 → C:\...\pypbexample.pbproj
La n es la casilla de «hecho» (y no hace nada más que marcar, lo he comprobado). Luego el texto que se ve, el link, y el target. En el link, C: se escribe C|, las barras se dan la vuelta y los espacios van como %20. Y lo más elegante: el esquema del link es el nombre del tipo de objeto — window:, userobject:, datawindow:…
El link admite más de lo que yo pensaba
Aquí es donde tirar del hilo tuvo premio. Resulta que el link no solo dice qué objeto abrir: también dice en qué ventana del IDE abrirlo y en qué punto exacto dejarte. Eso explica lo que os contaba al principio: las entradas que deja PBSearch usan action=open, que es el painter, y sin línea ni columna. Pero el formato da para más:
| action | Qué abre | Y la línea cuenta… |
|---|---|---|
open |
el painter de siempre (admite column=) |
líneas del script |
opensource |
el Edit Source, el fuente en crudo | líneas del fichero .sr* |
Y aquí hay un detalle que conviene tener presente, porque si no se te puede ir un buen rato: la misma line=3 cae en dos sitios distintos según lo que abras. No es un fallo: cada ventana cuenta las líneas de lo que enseña. Un ejemplo real de mi propio ejemplo, la función f_locksession:
- En el fichero
.srf, la línea 3 está en blanco — porque delante van elglobal type, elforward prototypesy compañía. - En el painter, la línea 3 es
lnv = Create n_cst_pypbcontextwrapper, que en el fichero es la línea 10.
Moraleja práctica: si el número de línea lo has sacado leyendo el fichero, abre el Edit Source. Si lo mandas al painter, caerá en otro sitio y encima parecerá que la herramienta va mal.
El caso práctico: que sea Claude Code quien rellene la lista
Con todo eso medido, monté lo que quería desde el principio: un skill de Claude Code. Un skill no es más que una carpeta con instrucciones y unos scripts; la copias en tu carpeta de skills y a partir de ahí se lo pides con palabras normales.
Y la conversación es literalmente esta:
— Busca dónde se usa of_set_celda y déjame los sitios apuntados en el To-Do.
Claude rastrea los fuentes (que en modo solución son ficheros sueltos, así que buscar es trivial y rapidísimo), te enseña en seco lo que va a apuntar, y con tu OK lo escribe:
python pbtodo.py add w_main:159 w_main:160 n_cst_pyton_excel:100 ^
--texto "Usos de of_set_celda" --fuente --escribir
Entradas: 0 -> 3
Apuntadas: Usos de of_set_celda - w_main:159, ... - w_main:160, ... - n_cst_pyton_excel:100
Backup: C:\Users\...\AppData\Local\pbtodo\backups\todo_pypbexample_20260809_164200.reg
Abres PowerBuilder, Tools > To-Do List, y ahí están los tres. Doble clic y estás dentro, en la línea. Vas tachando y a otra cosa.
El skill trae siete comandos, todos con la misma filosofía:
| Comando | Qué hace |
|---|---|
info | qué proyecto PB hay aquí, qué versiones tienes, si el IDE está abierto |
find | buscar objetos por nombre (admite comodines) |
list | ver la To-Do List sin abrir el IDE |
add | apuntar entradas (objeto:línea) |
done / rm | marcar la casilla y borrar (reindexando, que si no el IDE no lee la lista) |
open | la otra vía: arrancar el IDE plantado en un objeto |
Todo lo que escribe es dry-run por defecto: sin --escribir te cuenta lo que haría y no toca nada. Y antes de cada escritura exporta la clave a un .reg. Sin frameworks, sin dependencias: Python de la biblioteca estándar y punto.
Lo que he aprendido por el camino (o sea, los peros)
1. El IDE tiene que estar CERRADO. Este es el importante y me pasó de verdad: con PowerBuilder abierto, él tiene la lista en memoria, no ve lo que metas por fuera y al cerrar escribe su copia encima. Me dejó cuatro entradas recién escritas en nada y un Count=0. Por eso el script se niega solo si detecta el IDE corriendo. Leer sí te deja; escribir no.
Lo cual, bien mirado, define para qué sirve esto: para preparar el trabajo antes de sentarte, no para pilotar el IDE en caliente. Y la buena noticia es que escribiendo con el IDE cerrado conviven perfectamente: abrí, marqué un par de tareas como hechas, cerré, y mis entradas seguían ahí con sus casillas actualizadas.
2. Esto no es una API pública. La To-Do List está pensada para usarse desde el IDE; que se pueda rellenar desde fuera es una posibilidad que da el formato, no una función soportada. Lo digo claro porque toca ser honesto: Appeon no se ha comprometido a mantener esto y podría cambiar en cualquier versión. Por eso el script hace copia de la clave antes de tocar nada y no escribe si no se lo pides expresamente. Si algún día hubiera una vía oficial para esto, encantado de tirarla a la basura y usar la buena.
3. Ninguna de las dos vías habla con un IDE ya abierto. Ni la To-Do List ni la línea de comandos. Es la limitación de fondo, y conviene tenerla clara desde el principio.
El repo: esta vez no hay nada que compilar
Aviso para los que ya me conocéis: este repo no es una solución que abráis desde el IDE, como los ejemplos que suelo publicar. Aquí no hay .pbsln ni una línea de PowerScript: es un skill de Claude Code, o sea, cuatro módulos de Python (el registro, el disco, el IDE y la CLI que los junta) más el SKILL.md que le explica a Claude cuándo y cómo usarlos. Python de la biblioteca estándar, sin instalar nada más.
Y la instalación tiene su gracia, porque se la podéis encargar al propio Claude. Le decís algo así:
— Clonagithub.com/rasanfe/PbTodoListen mi carpeta de skills, comopb-todo.
Y lo hace él: es un git clone normal y corriente, os pedirá permiso para ejecutarlo y listo. Si lo preferís a mano, es exactamente esto:
git clone https://github.com/rasanfe/PbTodoList.git ^
"%USERPROFILE%\.claude\skills\pb-todo"
Un apunte que os ahorrará dudas: poned la carpeta con el mismo nombre que el skill (pb-todo), y no con el del repo. Así es como lo tengo probado y funcionando. Y si en vez de en global lo queréis solo para un proyecto, la misma carpeta vale dentro de su .claude\skills.
Y para terminar, una pista: mientras andaba con todo esto descubrí que la To-Do List no es el único link que el IDE entiende. Hay toda una familia, y algunos apuntan a cosas bastante más ambiciosas que abrir una ventana. Todavía estoy dándole vueltas y no prometo nada, pero da para otro artículo.
¡Nos vemos en el próximo artículo! Y recuerda: en PowerBuilder y con Claude Code, los límites solo están en nuestra imaginación. 🚀
Comentarios
Publicar un comentario