How to open the tiddler just before the current one in the history?

I want to create a button/keyboard that would navigate to the tiddler that was focused last before the current one. I tried using the json mangler plugin to navigate $:/HistoryList, and while the filter [[$:/HistoryList]indexes[]!limit[2]first[]] does seem to return the right index for the relevant json entry, I’m stuck in figuring out how to continue from here (that is, extract the title and navigate there)

The most recent which I call the “last focused tiddler” is in $:/HistoryList!!current-tiddler

And although I love the JSON mangler it is over kill to parse titles from the History list.

See this history-sidebar.json (536 Bytes)

Now make a button that when clicked navigates to {{$:/HistoryList!!current-tiddler}}

See also this version demonstrating more history features - see the link above the button in the sidebar.
https://sandbox-by-tones.tiddlyhost.com/#

1 Like

Thanks! Your site doesn’t load BTW.

So, I created a tiddler with the below content, tagged it with $:/tags/KeyboardShortcut and added a field named ‘key’ with ‘alt-W’ as value. And nothing happens when I click alt-W


\define title-string() "title": "
\define end-title() "

<$navigator story="$:/StoryList" history="$:/HistoryList">
<$action-navigate $to={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]is[tiddler]nth[2]] }}} />

</$navigator>

Hi @Ittayd,

you can make things much easier:

<$navigator story="$:/StoryList" history="$:/HistoryList">
<$let currentTiddler={{{ [[$:/HistoryList]get[current-tiddler]] }}} beforeTiddler={{{ [list[$:/StoryList]before<currentTiddler>] ~[list[$:/StoryList]last[]] }}}>
<$action-navigate $to=<<beforeTiddler>>/>
</$let>
</$navigator>

Hope this helps,
Simon

2 Likes

I want to navigate to the tiddler visited before the current one, not the one before the current one in the story.

Can you help me figure out why the keyboard shortcut is not working?

I do not have the shortcut method but as mentioned before look in the
the History tab; In there the Last button navigates to the “last” one, ie not the recent one.

 <$list filter="[{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]is[tiddler]nth[2]]">
    <$button to=<<currentTiddler>> >Last</$button>
 </$list>

That is the following filter will retrieve the tiddler title you are after;
[{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]is[tiddler]nth[2]]

It needs these macros;

\define title-string() "title": "
\define end-title() "

Thank you.

It turned out that a plugin (modloader) was somehow blocking all keyboard shortcuts. I disabled it.

I’m facing a new issue. For some reason, if the last before current tiddler is $:/ControlPanel, then the shortcut doesn’t work. I see it in the history, and I even use $log and it shows it was found (actually, the log message appears 3 times, the last one showing the current tiddler). If I hard code it in the action-navigate widget, it works. Any tips?

Here’s the tiddler’s text:

\define title-string() "title": "
\define end-title() "

<$navigator story="$:/StoryList" history="$:/HistoryList">
	<$let target={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]is[tiddler]nth[2]] }}}>
		<$log target=<<target>> />
		<$action-navigate $to=<<target>> />
	</$let>
</$navigator>

I am using a simpler solution to display the last tiddler above the page controls in the sidebar,

last-tiddler.json (378 Bytes)

\define title-string() "title": "
\define end-title() "
<$link to={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]is[tiddler]nth[2]] }}}/>

But it has the same “Problem” you are experiencing, using the control panel settings button is not triggering an update of the history.

This has lead me to realised that this is because buttons that open tiddlers do so outside the list or navigator widget that normally happens.

I think the answer may lie in

  • using the MessageCatcherWidget to trap navigation events triggered by page controls or wrapping the page controls in $:/core/ui/PageTemplate/pagecontrols
    • A quick addition of story="$:/StoryList" history="$:/HistoryList" to that list did not work.

Further research needed but this almost deserves an issue raised in GitHub for enhancement in future versions of tiddlywiki.

  • I observe lists inside the sidebar tabs do make use of the history (unlike buttons), this is using the tabs macro ## $:/core/macros/tabs
  • I also note the use of history=<<tv-history-list>> storyview="pop" inside the side bar open tab $:/core/ui/SideBar/Open should we somehow do this with the page controls or must we do it in each button that opens a tiddler?

I think that I saw that $:/HistoryList does get updated. For me the behavior happens even if I have the control panel tiddler open and I click on the tab and then the tab of another tiddler. Then my shortcut navigates to a random tiddler instead of the control panel.
Regarding raising issues in github, I’m afraid I’ll be out of my depth if I try to explain what you just wrote…

Are you sure that your target variable is being correctly assigned? Parsing JSON with string operators is rather brittle. My guess is that the is[tiddler] filter step is excluding $:/ControlPanel since it is a shadow tiddler.

Try this:

\define title-string() "title": "
\define end-title() "

<$navigator story="$:/StoryList" history="$:/HistoryList">
	<$let target={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]nth[2]] }}}>
		<$log target=<<target>> />
		<$action-navigate $to=<<target>> />
	</$let>
</$navigator>

Also, use $action-log instead of $log inside action strings to ensure that the logging only happens when the button is clicked.

@saqimtiaz as I elucidated in my earlier post, as far as I can see the control panel button simple does not use the standard story or history list. This is the same for Tag manager and Tiddler Manager which are Navigating buttons.

That is our code is working and any tiddler opened within a SideBar tab is detected and the listory list updated. So too are new tiddlers (only once saved) and links from tiddlers in the story.

A quick way to demonstrate is to install my history tab, and keep it open in the sidebar, or return to it after following a link in another sidebar tab. history-sidebar.json (1.3 KB)

Also my last tiddler that displays the $:/HistoryList!!currentTiddler field if clicked to returns to the last focused tiddler using the link widget also gets added to the history. last-tiddler.json (378 Bytes)

So it appears that the $:/core/ui/Buttons/control-panel tiddler using the following;
<$button to="$:/ControlPanel" is just not updating the History.

Seems like an oversight or bug!

can raise an issue

@TW_Tones I am trying to assist @Ittayd in debugging his code as he has requested. I don’t see what relevance your comment about control panel buttons has here. Please post a separate thread if you believe there is some underlying issue.

The use of the is[tiddler] filter step in the code being used for that shortcut makes it impossible for that filter expression to return $:/ControlPanel or any other shadow tiddler as a result unless it has been overridden.

OK but I have detected the same fault outside his code. Debug if you wish but I am not just bullshitting or wasting my time.

Thank you. So is there a way to select either a tiddler, a system tiddler or a shadow tiddler?

Have you tried this updated code that I posted?

\define title-string() "title": "
\define end-title() "

<$navigator story="$:/StoryList" history="$:/HistoryList">
	<$let target={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>reverse[]nth[2]] }}}>
		<$log target=<<target>> />
		<$action-navigate $to=<<target>> />
	</$let>
</$navigator>

I am not sure that you need to check if the tiddler exists as a shadow or real tiddler, the only situation in which not doing so could be problematic is where the previous tiddler has been deleted.

Ahh, sorry, yes I did. I added a ‘!is[missing]’ because otherwise it would navigate to draft tiddlers if my last action was an edit. It doesn’t work. Note that I do see the $:/ControlPanel in $:/HistoryList but the log message shows it was ignored.

Try adding !is[draft] instead of !is[missing]
Also use $action-log instead of $log to only log when the actions are invoked.

\define title-string() "title": "
\define end-title() "

<$navigator story="$:/StoryList" history="$:/HistoryList">
	<$let target={{{ [{$:/HistoryList}split<title-string>splitbefore<end-title>removesuffix<end-title>!is[draft]reverse[]nth[2]] }}}>
		<$action-log target=<<target>> />
		<$action-navigate $to=<<target>> />
	</$let>
</$navigator>

Perfect! Thank you very much

To early to declare victory. If I edit a tiddler, finish and then use the shortcut, the draft tiddler is opened (because it’s now a missing tiddler). And, thinking about it, I would like to be able to navigate to a draft tiddler (e.g. editing it, want to lookup information in another, then come back to editing)