As I’ve mentioned before, I remain using Snownews in lieu of more modern maintained options because it actually works for me where the others don’t; I do however check every now and again that is still the case.
One thing I don’t like about Snownews is how easy it is for me to accidentally mark EVERYTHING as read and have no way to undo this. So for awhile I’ve had a “someday” action on my todo list to look at adding an undo functionality - it was “someday” because I presumed it would be difficult for me to do and would face me with the uncomfortable realisation that I’m not actually very good at programming whereas if I ignored it I could continue along in my happy ignorance.
As it turned out, it was remarkably easy to do and I even managed to get all the required changes right first time: Not even a compilation error! So now not only can I carry on in my ignorance - I’ve actually managed to reinforce it! Admittedly I’ve gone for a very simplistic “works ok for me” solution, but afterall that is all I need.
There are two relevant bits of code, depending on where in the UI you are. There’s markread
for within individual feeds:
if (uiinput == keybindings.markread) {
/* Mark everything read. */
for (markasread = current_feed->items; markasread != NULL; markasread = markasread->next_ptr) {
markasread->data->readstatus = 1;
}
}
And markallread
for within the main index of all feeds:
if (uiinput == keybindings.markallread) {
/* This function is safe for using in filter mode, because it only
changes int values. It automatically marks the correct ones read
if a filter is applied since we are using a copy of the main data. */
for (cur_ptr = first_ptr; cur_ptr != NULL; cur_ptr = cur_ptr->next_ptr) {
for (markasread = cur_ptr->items; markasread != NULL; markasread = markasread->next_ptr) {
markasread->data->readstatus = 1;
}
}
}
So my cunning simple plan was to add another variable to the newsdata
structure and backup the previous value in there. Shown here for the markread
section, but applies similarly for markallread
:
if (uiinput == keybindings.markread) {
/* Mark everything read. */
for (markasread = current_feed->items; markasread != NULL; markasread = markasread->next_ptr) {
/* backup previous value */
markasread->data->prevreadstatus = markasread->data->readstatus;
markasread->data->readstatus = 1;
}
}
Then restoring is as easy as adding a keybinding and reading the previous value:
if (uiinput == keybindings.undoread) {
for (markasread = current_feed->items; markasread != NULL; markasread = markasread->next_ptr) {
/* markasread is a bit of a naff name for the pointer here, but see no need to create new one */
markasread->data->readstatus = markasread->data->prevreadstatus;
}
}
The only downside is if I, for some idiotic reason, accidentally mark all as read twice in succession, but I happy with the compromise. I’ve put the patches in a gist on Github (with some unrelated minor keybinding changes muddled in - sorry).