--- name: save_onlyoffice_file kind: function lang: bash domain: shell purity: impure version: 1.1.0 description: "Fuerza el guardado (Ctrl+S) de un documento abierto en una instancia de OnlyOffice Desktop en Linux/X11 y confirma que llego a disco por cambio de mtime. Primer paso del flujo seguro guardar -> actualizar -> recargar; evita perder cambios no guardados cuando un build regenera el archivo leyendo del disco." signature: "save_onlyoffice_file(file_path: string, [instance: string]) -> json" error_type: error_go_core tags: [onlyoffice, desktop, x11, gui, save, persist] uses_functions: [] uses_types: [] file_path: bash/functions/shell/save_onlyoffice_file.sh params: - name: file_path desc: "ruta al documento abierto en OnlyOffice cuyo guardado se quiere forzar. Debe existir. Se normaliza a ruta absoluta y se usa su basename para localizar la ventana." - name: instance desc: "nombre del slot/instancia para etiquetar la salida JSON (default: 'demo'). Usar el MISMO valor que en open/reload/close del mismo documento por coherencia." output: "linea JSON a stdout: {\"instance\":\"\",\"file\":\"\",\"wid\":\"|null\",\"status\":\"saved\"|\"no_change\"|\"no_window\",\"dialog_confirmed\":0|1[,\"mtime_before\":N,\"mtime_after\":N]}. dialog_confirmed=1 si se envio Return para cerrar el dialogo modal de formato. Exit 0 salvo error de dependencia o archivo inexistente (exit 1)." --- Fuerza el guardado (Ctrl+S) de un documento abierto en una instancia de ONLYOFFICE Desktop Editors en Linux/X11 y confirma que el guardado llegó a disco observando el cambio de `mtime` del archivo. Existe para cerrar una ventana de pérdida de datos: OnlyOffice mantiene los cambios en memoria hasta que el usuario guarda. Cualquier proceso que regenere el archivo leyendo del disco (un build que refresca hojas, un script de sincronización) perdería el trabajo manual no guardado. Esta función vuelca ese trabajo a disco ANTES de tocar el archivo, de modo que el paso de actualización pueda preservarlo. Es el primer paso del flujo seguro de refresco: ``` save_onlyoffice_file -> (actualizar el archivo en disco) -> reload_onlyoffice_file ``` ## Ejemplo ```bash # Forzar el guardado de un xlsx abierto en la instancia "afiliados" bash bash/functions/shell/save_onlyoffice_file.sh \ /home/enmanuel/afiliados/programas_afiliados.xlsx afiliados # {"instance":"afiliados","file":"/home/enmanuel/afiliados/programas_afiliados.xlsx","wid":"0x0a20002a","status":"saved","mtime_before":1718380000,"mtime_after":1718380042} # Via fn run (tras fn index) ./fn run save_onlyoffice_file /home/enmanuel/afiliados/programas_afiliados.xlsx afiliados # Encadenado con la actualización y la recarga (flujo seguro completo) bash bash/functions/shell/save_onlyoffice_file.sh "$XLSX" afiliados python build_xlsx.py # regenera solo las hojas gestionadas ./fn run reload_onlyoffice_file "$XLSX" afiliados ``` ## Cuando usarla Llámala SIEMPRE justo antes de regenerar o modificar en disco un archivo que el usuario pueda tener abierto en OnlyOffice, para no pisar sus cambios sin guardar. Es el primer eslabón del flujo guardar -> actualizar -> recargar. Si no hay ventana abierta para ese archivo, es un no-op seguro (status `no_window`). ## Gotchas - **Orden crítico**: guarda ANTES de actualizar el archivo. Si actualizas primero y guardas OnlyOffice después, OnlyOffice sobrescribe tu actualización con su copia en memoria (vieja). El flujo correcto es save -> update -> reload. - **status `no_change`**: el `mtime` no cambió. Normalmente significa que no había cambios pendientes (no es un error). - **Auto-confirmación del diálogo de formato (v1.1.0)**: si tras Ctrl+S el guardado no se completa en ~1.2s, la función asume que OnlyOffice mostró un diálogo modal ("mantener formato") y le envía Return, que acepta la opción por defecto (mantener el formato actual). El campo `dialog_confirmed` indica si se envió. Si no había diálogo, el Return va al editor y solo mueve de celda (no altera datos). Para suprimir el diálogo de forma permanente, desmárcalo en OnlyOffice: Configuración avanzada → desactivar el aviso de formato al guardar. - **status `no_window`**: no hay ninguna ventana cuyo título contenga el basename del archivo. No hay nada que guardar; el disco ya es la única fuente de verdad. - **Detección por basename**: dos archivos con el mismo nombre en rutas distintas colisionan al localizar la ventana (igual que open/reload). - **X11 obligatorio**: depende de `xdotool` (y `stat` de coreutils). No funciona en Wayland puro sin XWayland. - **Foco**: la función activa la ventana (`windowactivate --sync`) para que Ctrl+S llegue al editor. Roba el foco un instante; es esperable. ## Capability growth log - v1.1.0 (2026-06-15) — auto-confirma el diálogo modal "mantener formato" enviando Return a la ventana activa cuando el guardado no se completa en ~1.2s; añade el campo `dialog_confirmed` a la salida JSON.