Back to the Future is my favorite movie of all time and I resisted the urge to name the new API method flux_capacitor (opting instead for the much more boring navigate_help_history), so I’m indulging myself with a little “witticism” and using that as the title for today’s devlog entry about the new ability of hyperhelp to allow you to skip backwards and forwards through your help history.
I’m getting ahead of myself, though.
I think one of the key features of a system that lets you navigate around through help is the ability to go back to where you came from. For example you’re reading help and there is a link to teach you about something you need to know before you continue, and the most natural way to work in that situation would be to follow the link, read what you need to know, then go back to where you came from and continue.
A less satisfying version of the same thing is trying to manually find the location you were previously at, but that could be minutes, hours or days ago, which is not overly helpful. Instead, why not have the help system store that information for you the way your web browser does?
Thanks to tonight’s changes, this is now possible which brings a big missing feature to the project so far. This all hangs together in a few parts, but it’s not overly complex and (in my biased opinion) somewhat elegant in it’s approach.
The first thing is that there is a new data type for storing help history information. In particular we need to store the package and help file that are currently on display, so that we can navigate back to that file later. The structure also needs to store the current cursor location and viewport position (where in the file you’re currently looking), so that when it takes you back to that point in history, it can make the window appear how it looked then.
There also need to be a couple of new hidden settings attached to the view to track the history for us. This uses the same mechanism as storing the current package and help file being displayed, which saves us from having to persist it ourselves because Sublime will happily do the work for us. The first of these settings is an array of the new HelpData data structures and the second is the position in the list of help data that is currently being visualized in the help window.
Whenever a help view is initially created, we need to set these new settings into the view to initialize history, with a history list that contains a single entry that references the top of the current help file. Whenever you follow a link, the entry at the current history position is updated to save the current view state in case it was different than it was when the history entry was first created, and then we follow the link and add a new history entry for the new file.
Navigating through history is also fairly simple. First we again update the view state in the current history entry, then move the history position forward or backward as needed and use the information from the history to restore the file and view state to what it was the last time that state was left.
When you follow a link when you’re not at the end of the history list, the system will discard all of the history entries that follow the current one and start a new history, which I refer to as Biff stealing the almanac.
The core of this work is in two main places. The first is a new dedicated method for updating the history, which is responsible for saving the state at the current position and then adding a new one, and the second is the existing method for displaying a help topic. This method now takes a parameter that tells it whether it should update history or not while it is displaying the topic.
The reason for this is that when navigating the history you need to be able to display the new help topic, which is what that method is for. However you don’t want it to treat displaying that link like any other topic and update the history, because doing so will cause Biff to kill George McFly and marry Marty’s mom.
Due to the lateness of the hour and my desire to work on some video editing before shuffling off to bed, I’ve left things off for this evening with the new functionality in place and bound to some default navigation keys. There is still a bit more to do with this, such as menu entries to allow you to navigate and possibly some way to visualize the history and jump directly to some location within it all in one shot.
Those are things to work on tomorrow, along with thoughts of starting to clean up the organization of everything a little better. In general I’m thinking that it’s time to split the code from the two parts into their own separate folders inside of the top level folder, so that logically I can refer to them as two separate packages while physically they’re still a part of the same repository.