Where to exactly? What is the rule to follow? Is it for example the last positions of cursor that you hit “Play” (Or “Stop”)? Is it wherever you clicked?
I like the idea!
Using Midi Remote we can come up with something to do this, Martin. Here’s a snippet which monitors cursor positions, when not in play mode obviously, and sniffing the end of rewind/forward actions. What’s missing from this snippet is the handling of nudges, but it can be done. I’'ve setup 2 buttons for previous/next history cursor position, and limited the history size to 10 entries. Did some tests, it’s working almost OK. But I do see issues 
var midiremote_api=require('midiremote_api_v1')
var deviceDriver = midiremote_api.makeDeviceDriver('Test', 'Cursor History', 'Test')
var midiInput = deviceDriver.mPorts.makeMidiInput()
var midiOutput = deviceDriver.mPorts.makeMidiOutput()
deviceDriver.makeDetectionUnit().detectPortPair(midiInput, midiOutput)
.expectInputNameEquals('loopMIDI Port 1')
.expectOutputNameContains('loopMIDI Port 2')
var surface=deviceDriver.mSurface
var dummyPlayControl=surface.makeButton(0,0,0,0)
var dummyRewindControl=surface.makeButton(0,0,0,0)
var dummyForwardControl=surface.makeButton(0,0,0,0)
var dummyStopControl=surface.makeButton(0,0,0,0)
var buttonHistoryCursorPrevious=surface.makeButton(0,0,1,1)
buttonHistoryCursorPrevious.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.bindToControlChange(0,24)
var buttonHistoryCursorNext=surface.makeButton(1,0,1,1)
buttonHistoryCursorNext.mSurfaceValue.mMidiBinding
.setInputPort(midiInput)
.bindToControlChange(0,25)
var page=deviceDriver.mMapping.makePage("page")
var maxHistoryCursorSize=10
var delimiter="//"
var delimiterLength=delimiter.length
var sniffForward=true
var sniffRewind=true
var dummyHistoryCursorPrevious=page.mCustom.makeHostValueVariable("dummyHistoryCursorPrevious")
page.makeValueBinding(buttonHistoryCursorPrevious.mSurfaceValue,dummyHistoryCursorPrevious).mOnValueChange=function(activeDevice,activeMapping,value){
if(value==1){
restoreCursor(activeDevice,activeMapping,-1)
}
}
var dummyHistoryCursorNext=page.mCustom.makeHostValueVariable("dummyHistoryCursorNext")
page.makeValueBinding(buttonHistoryCursorNext.mSurfaceValue,dummyHistoryCursorNext).mOnValueChange=function(activeDevice,activeMapping,value){
if(value==1){
restoreCursor(activeDevice,activeMapping,1)
}
}
page.makeValueBinding(dummyStopControl.mSurfaceValue,page.mHostAccess.mTransport.mValue.mStop).mOnValueChange=function(activeDevice,activeMapping,stop){
console.log("stop="+stop)
activeDevice.setState("stop",""+stop)
}
page.makeValueBinding(dummyPlayControl.mSurfaceValue,page.mHostAccess.mTransport.mValue.mStart).mOnValueChange=function(activeDevice,activeMapping,play){
console.log("play="+play)
activeDevice.setState("play",""+play)
}
page.makeValueBinding(dummyRewindControl.mSurfaceValue,page.mHostAccess.mTransport.mValue.mRewind).mOnValueChange=function(activeDevice,activeMapping,rewind){
console.log("rewind="+rewind)
activeDevice.setState("rewind",""+rewind)
if(rewind==0 && sniffRewind){
setHistoryCursor(activeDevice,activeDevice.getState("temporaryCursor"))
}
}
page.makeValueBinding(dummyForwardControl.mSurfaceValue,page.mHostAccess.mTransport.mValue.mForward).mOnValueChange=function(activeDevice,activeMapping,forward){
console.log("forward="+forward)
activeDevice.setState("forward",""+forward)
if(forward==0 && sniffForward){
setHistoryCursor(activeDevice,activeDevice.getState("temporaryCursor"))
}
}
page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mTransportLocator.mOnChange=function(activeDevice,activeMapping,arg1,arg2){
if(activeDevice.getState("restoringCursor")=="1"){
activeDevice.setState("restoringCursor","0")
return
}
var cursorPosition=arg1
if((activeDevice.getState("rewind")=="1" && sniffRewind) || (activeDevice.getState("forward")=="1" && sniffForward)){
activeDevice.setState("temporaryCursor",cursorPosition)
} else if(activeDevice.getState("play")=="0" && activeDevice.getState("rewind")=="0" && activeDevice.getState("forward")=="0"){
setHistoryCursor(activeDevice,cursorPosition)
}
}
function setHistoryCursor(activeDevice,cursorPosition){
if(cursorPosition=="" || cursorPosition==undefined){
return
}
console.log("setting cursor to "+cursorPosition)
var historyCursorSizeStr=activeDevice.getState("historyCursorSize")
var historyCursors=activeDevice.getState("historyCursors")
var historyCursorSize=historyCursorSizeStr=="" ? 0 : parseInt(historyCursorSizeStr)
historyCursorSize++
if(historyCursorSize<maxHistoryCursorSize){
activeDevice.setState("historyCursorSize",""+historyCursorSize)
} else {
historyCursorSize=maxHistoryCursorSize
historyCursors=historyCursors.substring(historyCursors.indexOf(delimiter)+delimiterLength)
}
historyCursors=historyCursors+cursorPosition+delimiter
activeDevice.setState("historyCursors",historyCursors)
activeDevice.setState("historyCursorIndex",(historyCursorSize-1).toString())
console.log("historyCursors="+historyCursors)
}
function restoreCursor(activeDevice,activeMapping,step){
var historyCursorSizeStr=activeDevice.getState("historyCursorSize")
var historyCursorSize=historyCursorSizeStr=="" ? 0 : parseInt(historyCursorSizeStr)
if(historyCursorSize==0){
return
}
var historyCursorIndexStr=activeDevice.getState("historyCursorIndex")
var historyCursorIndex=historyCursorIndexStr=="" ? 0 : parseInt(historyCursorIndexStr)
historyCursorIndex+=step
if(historyCursorIndex<0){
historyCursorIndex=0
} else if (historyCursorIndex>historyCursorSize-1){
historyCursorIndex=historyCursorSize-1
}
var historyCursors=activeDevice.getState("historyCursors")
var arrHistoryCursors=historyCursors.substring(0,historyCursors.length-delimiterLength).split(delimiter)
var fromHistoryCursor=arrHistoryCursors[historyCursorIndex]
activeDevice.setState("restoringCursor","1")
activeDevice.setState("historyCursorIndex",""+historyCursorIndex)
page.mHostAccess.mTransport.mTimeDisplay.mPrimary.mTransportLocator.setTime(activeMapping,fromHistoryCursor)
}
deviceDriver.mOnActivate=function(activeDevice){
console.log("activating")
activeDevice.setState("play","0")
activeDevice.setState("rewind","0")
activeDevice.setState("forward","0")
}