Skip to main content
Lordrhavin
Inspiring
April 8, 2024
Answered

Skripting, undo: I gt an Error i dont understand

  • April 8, 2024
  • 5 replies
  • 2927 views

In the following simplified code I get the error that "the last command could not be undone".

Anyone knows WHY I get this error?

 

 

 

QGlobalSemaphores = [];

// ECMAScript 3 has no classes
function WaitForIt(callback, object) {
	this.object = object;
	this.answer = null;
	this.index  = -1;
	this.callback = callback;
}

function doSubscript(index) {
	mySemaphore = QGlobalSemaphores[index];
	mySemaphore.callback(mySemaphore.object);
	alert("executed");
}

function executeSubscript(callback, object) {
	var w = new WaitForIt(callback, object);
	w.index = QGlobalSemaphores.push(w) - 1;
	app.doScript(doSubscript,ScriptLanguage.JAVASCRIPT,[w.index],UndoModes.FAST_ENTIRE_SCRIPT,'FE-Test');
}

function deleteLayers(obj) {
	var doc = app.activeDocument;
	var i = doc.layers.length;
	while (i-->1) {
		doc.layers[i].remove();
	}
}

function test() {
	executeSubscript(deleteLayers, null);
	app.undo(); // <-- I get the error here.
}

app.doScript(test,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'Callback-Test');

 

 

 

This topic has been closed for replies.
Correct answer leo.r

Thee >  next time please describe your workflow / what you want to achieve - you'll get the solution quicker
I didnt get a solution, I got some workarounds.

Me > Anyone knows WHY I get this error?
That is still not answered. I filed a bug report, as I think this a false-negative error .
https://indesign.uservoice.com/forums/601180-adobe-indesign-bugs/suggestions/48231980-undo-does-work-but-spawns-pointless-error


quote

I didnt get a solution, I got some workarounds.

 

By @Lordrhavin

 

well. workarounds are solutions for situations where there are no other solutions.

5 replies

rob day
Community Expert
Community Expert
April 9, 2024

I think you need app.activeDoucument.undo() rather than app.undo(). This works for me:

 

var doc = app.activeDocument;

function deleteLayers() {
	doc.layers[0].remove();
}

app.doScript(deleteLayers,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'DeleteLayer');

alert("Restoring Layer")

//app.undo();//throws Unable to undo the last command. error
doc.undo()
Lordrhavin
Inspiring
April 9, 2024

I still get the same error. Did you call the subscript?

rob day
Community Expert
Community Expert
April 9, 2024

I’m not sure what’s going on with your code, my example just shows that app.undo() always throws an error with doScript()—it has to be app.activeDocument.undo().

 

I think you should watch out for the difference between collections and arrays—layers is a collection not an array of layers. A collection is similar to an array but they do not share the same methods. @Robert at ID-Tasker while loop could also be written like this where I’m explicity using the collection’s firstItem() and lastItem() methods to remove all the items above or below.

 


var doc = app.activeDocument;

function deleteLayers() {
	var i = app.activeDocument.layers.count();
	while (i-->1) {
		//doc.layers.firstItem().remove();//removes all layers except for the bottom layer
		doc.layers.lastItem().remove();//removes all layers except for the top layer
	}
}

app.doScript(deleteLayers,ScriptLanguage.JAVASCRIPT,[],UndoModes.ENTIRE_SCRIPT,'DeleteLayer');

alert("Restoring Layers")

//app.undo();//throws Unable to undo the last command. error
doc.undo()
rob day
Community Expert
Community Expert
April 9, 2024

Hi @Lordrhavin , Have you run your deleteLayers(obj) function by itself to check if it is doing what you expect?

 

A document has to have at least one layer, so the function would throw an error on a single layer document, and on a multi layer doc it only removes half the layers. Something like this, which loops an array rather than a collection, would remove all the layers (and their contents) except for the bottom layer:

 

deleteLayers("hi")

function deleteLayers(obj) {
	var lyr = app.activeDocument.layers.everyItem().getElements();
	for (var i = lyr.length-2; i > -1; i--) {
		lyr[i].remove();
	}
    $.writeln(obj)//returns hi
}

 

 

Lordrhavin
Inspiring
April 9, 2024

Yes, I know that it i not deleting the last layer. But as it does this without any error and I also get this error if I just start with i=1, I dont saw the difference in posting that code.

 

rob day
Community Expert
Community Expert
April 9, 2024

I dont saw the difference in posting that code.

 

With your function I get this:

 

Before:

After

 

 

With the reverse array loop I get this

 

m1b
Community Expert
Community Expert
April 9, 2024

You have probably tried this already but if not, try UndoModes.ENTIRE_SCRIPT rather than UndoModes.FAST_ENTIRE_SCRIPT because I recall that users have reported issues related to Undo with FAST_ENTIRE_SCRIPT.  There is an old article that discusses.

 

I would be tempted to test the various UndoModes in your inner and outer doScripts. Does any combination of them give you the desired result with no error?  Maybe it's just that using FAST_ENTIRE_SCRIPT *and then undo-ing it* is not going to work?

- Mark

Lordrhavin
Inspiring
April 9, 2024

I tested all 16 combinations.

- All combinations throw the error.
- If the outher script is set to SCRIPT_REQUEST, it does not undo automatically. Further, the inner script has *then* the following results:
ENTIRE_SCRIPT or FAST_ENTIRE_SCRIPT: I can manually undo everything in one step.
SCRIPT_REQUEST:  I can manually undo everything stepwise.


The combination SCRIPT_REQUEST on mainscript and AUTO_UNDO on subscript didnt undo and I couldnt even undo manually; I had to reload the doc.

I also tested doing undo in a try-clause. It ommited the error but didnt undo at all 😄

leo.r
Community Expert
Community Expert
April 8, 2024

just a shot in the dark but will the default undo mode 'script request' make a difference?

Legend
April 8, 2024

I suspect it is the nested doScripts. Try the undo after the app.doScript(test....

 

P.

Lordrhavin
Inspiring
April 8, 2024

Yeah, thats sadly not what i need -.-
I need to undo the subscript, not the entire script.