Save prompter

I used to have a small app that prompted me to save every 10m or so. I found it very useful but it was discontinued years ago. Today, after about 10 years away from Applescript, I attempted to write a replacement:

display dialog “save prompter on?”
repeat

delay 600
try
	set theAction to button returned of (display dialog "Save now?" with icon caution buttons {"Leave me alone", "No", "Yes"} default button {"Yes"} giving up after 30)
	if theAction = "Yes" then tell application "System Events" to keystroke "s" using {command down}
	if theAction = "Leave me alone" then delay 6000
end try

end repeat

Very crude, I apologise. Of course it doesn’t work because the application I’m working on at the time become inactive when the dialog pops up, so the command s has no effect. Any thoughts?

Hi.

You can actually tell the frontmost application to display the dialog:

tell application (path to frontmost application as text)
	set theAction to button returned of (display dialog "Save now?" with icon caution buttons {"Leave me alone", "No", "Yes"} default button {"Yes"} giving up after 30)
end tell

I presume you have the script itself running as an application. It’s normally better for a constantly running script to be a stay-open applet with an ‘idle’ handler rather than to keep looping itself all the time. Something like this:

property firstIdle : true

on run
	try
		tell application (path to frontmost application as text) to display dialog "save prompter on?"
	on error number -128
		-- Quit if the Cancel button's clicked. This has to be done explicitly with a stay-open applet.
		quit
	end try
	set firstIdle to true
end run

on idle -- Called by the system after the interval returned at the bottom.
	if (firstIdle) then
		-- On the first idle, just cancel the firstIdle flag.
		set firstIdle to false
	else
		-- On subsequent idles, tell the frontmost application at the time to display the dialog.
		tell application (path to frontmost application as text)
			set theAction to button returned of (display dialog "Save now?" with icon caution buttons {"Leave me alone", "No", "Yes"} default button {"Yes"} giving up after 30)
		end tell
		if (theAction = "Yes") then
			tell application "System Events" to keystroke "s" using {command down}
		else if (theAction = "Leave me alone") then
			return 6000 + 600 -- Request another call in 6000 + 600 seconds' time (the combined delay in the original script).
		end if
	end if
	
	return 600 -- Request another call in 600 seconds' time.
end idle

Save as an application, checking the “Stay open after run handler” option in the Save dialog.

No need creating property firstIdle, and checking its state every time. It is better to put the first return 600 into the on run handler:


on run {}
	tell application (path to frontmost application as text) to ¬
		display dialog "Save Prompter.app is started" buttons "OK" giving up after 2
	delay 600
end run

on idle {}
	tell application (path to frontmost application as text) to set theAction to ¬
		button returned of (display dialog "Save now?" with icon caution ¬
		buttons {"Leave me alone", "No", "Yes"} default button {"Yes"} giving up after 30)
	if theAction is "Yes" then
		tell application "System Events" to keystroke "s" using command down
	else if theAction is "Leave me alone" then
		return 6000 + 600
	end if
	return 600
end idle