Is it possible to make UndoModes.ENTIRE_SCRIPT when executing UXPScript in doScript?

When executing a UXP script from ExtendScript or AppleScript via doScript (do script), the behavior always seems to be UndoModes.SCRIPT_REQUEST even if any UndoModes are specified.

This means that the changes made by the script cannot be reverted in a single Undo, but must be repeated for each step Undo.

How to make this an ENTIRE_SCRIPT behavior, where the changes made by the script can be reverted in a single Undo?

Sample code

// ExtendScript

var uxpCode = '''
const { app } = require('indesign') ;
const sel = app.activeDocument.selection[0] ;
sel.move([0, 0]) ;
sel.move([0, 100]) ;
''' ;

try {
  app.doScript(uxpCode, ScriptLanguage.UXPSCRIPT, [], UndoModes.ENTIRE_SCRIPT) ;
} catch(e) {
  alert(e) ;
}
-- AppleScript

tell application id "com.adobe.InDesign"
	set uxp_code to "
const { app } = require('indesign') ;
const sel = app.activeDocument.selection[0] ;
sel.move([0, 0]) ;
sel.move([0, 100]) ;
"
	do script uxp_code language uxpscript with arguments {} undo mode entire script
end tell

Some ideas:

  • add an undoName string as argument after the undoMode.
  • make sure your UXP script considers global await.
  • wrap your doScript to invoke UXPSCRIPT in a function, which you invoke in another doScript that stays in ExtendScript and is responsible for the undoMode.

Thank you for your response. Tried all of them and to no success.
The following code is an example that is awkward but includes all the requirements.


(function() {
  var scriptCode = '''
const { app } = require('indesign') ;
const doSomething = async () => {
  const sel = app.activeDocument.selection[0] ;
  await sel.move([0, 0]) ;
  await sel.move([0, 100]) ;
} ;
await doSomething() ;
''' ;

  try {
    app.doScript(doUXPScript.toSource() + '("""' + scriptCode + '""");', ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, 'doJavaScript') ;
  } catch(e) {
    alert(e) ;
  }
})() ;

function doUXPScript(argv) {
  app.doScript(argv, ScriptLanguage.UXPSCRIPT, [], UndoModes.ENTIRE_SCRIPT, 'doUXPScript') ;
}

This works for me:

function main()
{
	try {
		app.doScript('''
			const { app } = require('indesign') ;
			const sel = app.activeDocument.selection[0];
			sel.move([0,0]);
			sel.move([0,100]);
		''',ScriptLanguage.UXPSCRIPT);
	} catch(e) {
		alert(e);
	}
}

app.doScript(
	main,
	ScriptLanguage.JAVASCRIPT,
	[],
	UndoModes.ENTIRE_SCRIPT,
	"Single Step"
);


The image shows the “Protokoll” panel (German locale) manual steps of

  • delete the protocol “Löschen”
  • create a new object
  • running the script - all changes merged into “Single Step”

The Undo menu also has “Rückgängig: Single Step”

Thank you, succeeded with your format. I modified the code in the UXPScript to be variables, as follows.

(function() {
  var uxpCode = '''
const { app } = require('indesign') ;
const { script } = require('uxp') ;
const sel = app.activeDocument.selection[0] ;
sel.move([0,0]) ;
sel.move([0,100]) ;
script.setResult('Result from UXPScript') ;
''' ;

  var res = app.doScript(doUXPScript, ScriptLanguage.JAVASCRIPT, [uxpCode], UndoModes.ENTIRE_SCRIPT, 'Single Step') ;
  alert(res) ;
})() ;

/**
  * Execute UXP script, must do via doScript, pass target code as arguments
  * @returns {Any} 
*/
function doUXPScript() {
  return app.doScript(arguments[0].toString(), ScriptLanguage.UXPSCRIPT) ;
}