Auto-updating list where updated lines pop to top of the list
August 10, 2021 12:05 AM   Subscribe

Reading the Making a list, checking it twice thread, I wondered if it's possible to have a live list where changing a line down the list (and editing that line's content) results in that line popping to the top of the list, i.e. live auto-sorting.

1 - So, a sample list:
20210808 17:24 Things1 Notes_About_things
20210707 11:17 Things2 Notes_About_things
20210810 03:40 Things3 Notes_About_things

2 - Status of Thing2 changed:
20210808 17:24 Things1 Notes_About_things
20210810 17:44 Things2 Some Thing changed
20210810 03:40 Things3 Notes_About_things
[Changes would be self edited date change, and any notes]

3 - Updated line automatically pops to the top:
20210810 17:44 Things2 Some Thing changed
20210808 17:24 Things1 Notes_About_things
20210810 03:40 Things3 Notes_About_things

I imagine it would live in vscode or some kind of locally hosted webpage but I wouldn't really have a clue as not a coder. I spend a lot of time writing and hand updating lists but this would be amazing, if it exists, or if it could exist.

Simple lists seem to me the best getting things done solution, but I'm not aware of anyone doing one an auto-updating one like this. Has anyone seen anything like this? If not would it be very hard to implement?

I can do this manually in vscode using its auto date:time insertion and then sorting by lines, but full automation seems the way to go if possible.
posted by unearthed to Computers & Internet (15 answers total) 1 user marked this as a favorite
You can do this in Javascript if you have the date in a separate field or it is easily extracted from the main field. Just generate the table "live" (i.e. display order is not the same as actual file order). Basically, load all the content into an array, extract the datetime, and sort by that datetime, and generate the display table with it. I know, sounds easier than it is. If you know a bit of Javascript, and you can generate the tables easy enough with something like Bootstrap 4 or 5, depending how many entries you're dealing with.

Then the question is... is this multi-user, or single-user only? How many people would be reading/writing?
posted by kschang at 5:08 AM on August 10, 2021 [1 favorite]

Response by poster: Thanks, I'd be the only one. On my desktop, not on a network. Yes, the date would be in it's own field.

I'm interested in this as it would be like a live handwritten list like I write (and rewrite) each day. Having it digital would also make it searchable.

New day lines would be added manually, and old items down list would pop to the top if I changed their date. Would probably create a new list monthly to stop it becoming slow.

I normally handwrite fifteen or so lines a day, and probably rewrite 3 to 5 of those lines the next day.
posted by unearthed at 1:11 PM on August 10, 2021

Not sure how much interest you have in learning some coding, but I think my old project here has some relevance to your needs. It runs in your local browser, and stores in your browser's "localStorage" only.
posted by kschang at 1:42 PM on August 10, 2021

How would you feel about setting up a word processor hotkey that inserts a timestamp at the start of the current paragraph if it doesn't already have one, or modifies an existing timestamp if it does, then flicks the whole paragraph to the top of the document? Because that should be quite doable with LibreOffice Writer and a fairly short macro.
posted by flabdablet at 1:57 PM on August 10, 2021


$ ls
$ ls -a
.  ..  .timelist
$ cat .timelist 
function tasks { ls -1t --full-time | tail +2 | cut -d' ' -f6-; }
function poke { touch "$1"; }
function purge { rm "$1"; }
function mod { purge "$1"; poke "$2"; }
$ source .timelist 
$ poke "add first thing"
$ poke "add second thing"
$ poke "add third thing"
$ poke "add final thing"
$ tasks
2021-08-10 19:41:01.566300340 -0700 add final thing
2021-08-10 19:40:55.982372283 -0700 add third thing
2021-08-10 19:40:48.734465634 -0700 add second thing
2021-08-10 19:40:41.182562881 -0700 add first thing
$ mod add\ fi
add final thing  add first thing  
$ mod add\ first\ thing "make this first"
$ tasks
2021-08-10 19:41:27.281968771 -0700 make this first
2021-08-10 19:41:01.566300340 -0700 add final thing
2021-08-10 19:40:55.982372283 -0700 add third thing
2021-08-10 19:40:48.734465634 -0700 add second thing
$ mod add\ third\ thing "new first"
$ tasks
2021-08-10 19:41:41.857780688 -0700 new first
2021-08-10 19:41:27.281968771 -0700 make this first
2021-08-10 19:41:01.566300340 -0700 add final thing
2021-08-10 19:40:48.734465634 -0700 add second thing
$ purge add\ final\ thing 
$ tasks
2021-08-10 19:41:41.857780688 -0700 new first
2021-08-10 19:41:27.281968771 -0700 make this first
2021-08-10 19:40:48.734465634 -0700 add second thing
$ poke "yet another thing"
$ tasks
2021-08-10 19:42:03.949495364 -0700 yet another thing
2021-08-10 19:41:41.857780688 -0700 new first
2021-08-10 19:41:27.281968771 -0700 make this first
2021-08-10 19:40:48.734465634 -0700 add second thing
You can basically make this from *any* language or framework just starting with the basic "build your first web app with database" tutorial. It's just Create Read Update Delete (CRUD) with a sort thrown in the mix. Doing this in a browser using some sort of local storage is a bit beyond me.

You might want to give your OS. (doesn't vscode run on many things?)

Like flabdablet mentioned, it could be done in a document with a macro. There's probably some todo list app that does this already and hopefully somebody knows about it.
posted by zengargoyle at 7:51 PM on August 10, 2021

Response by poster: via Libre would be a good solution flabdablet. I also have Word (office365 now - yuk) but Libre Office much preferable. That sounds elegant!

Yes that is how I'd be thinking of using this; the most recent edited line/para would get pushed to the top, and when I'd completed them I'd tag them as COMPLETE or some such and they'd slowly get overtaken by subsequent newer items.

zengargoyle Windows 10 Home 64. Yes VScode runs perfectly fine on it.

I'm having a look at that kschang - looks very clean. Right now my head is too full of very complicated jobs to learn code.
posted by unearthed at 9:23 PM on August 10, 2021

Best answer: Okay, I made a small script. I've only tested it under Debian but it should work in a Windows instance of LibreOffice as well. I believe Mac and Windows installations of LibreOffice come with Python scripting support installed by default, but on Linux it's sometimes packaged separately; my Debian box needed the "libreoffice-script-provider-python" package installed to make this work.

Paste the following script into a new Notepad window and save it as "". Make sure to change the "Save as type" option inside Notepad's "Save as" dialog from "Text files" to "All files", otherwise it will add a (possibly hidden) ".txt" extension to the end of the filename and break things.
import re
from datetime import datetime

def LiftTimeStampedPara():

    # Get the current document via the scripting context global
    doc = XSCRIPTCONTEXT.getDocument()

    # Make a new internal cursor from the current view cursor
    cursor = doc.Text.createTextCursorByRange(doc.CurrentController.ViewCursor)

    # Get paragraph content with updated or new timestamp
    content = re.sub("^[0-9]{8} [0-9]{2}:[0-9]{2}\t", "", cursor.String, 1)
    content ="%Y%m%d %H:%M\t") + content + "\r"

    # Delete paragraph from current position
    cursor.goRight(1, True)
    cursor.String = ""

    # Insert content at start of document
    cursor.String = content

    return None
Next step is to move the script to a folder where LibreOffice will find and use it. On Windows, the folder to use is "%APPDATA%\LibreOffice\4\user\Scripts\python". On Mac or Linux, it's "$HOME/.config/libreoffice/4/user/Scripts/python". You might need to make the "Scripts" and "python" subfolders by hand if they're not already there.

At this point you should be able to run the macro against any LibreOffice Writer document by selecting it from the menu. Tools -> Macros -> Run Macro... will bring up the Macro Selector. In the Library pane, navigate to My Macros -> LiftTimeStampedPara and click on it; this will bring up LiftTimeStampedPara as the sole entry in the "Macro Name" pane. Double-clicking that will make the script do its thing. In your document, you should see whichever paragraph the cursor was in get moved to the top of the document with the current date and time prepended.

Having verified that all is well so far, the next step is to assign a hotkey so you don't need to click around in menus all day. Choosing Tools -> Customize will bring up the Customize dialog. Click the Keyboard tab, then click the Writer radio button. In the "Shortcut Keys" pane, click on the row for some key that doesn't currently have anything associated with it (I used F4). In the Category pane, navigate to LibreOffice Macros -> My Macros -> LiftTimeStampedPara and click on it. This will make LiftTimeStampedPara the sole entry in the Function pane; click on that. Click the Modify button, and you should see your selected shortcut key appear in the Keys pane. Finally, click OK.

At this point you should be able to timestamp any paragraph and lift it to the top of the document just by putting the cursor in it and hitting your selected shortcut key. Bonus nice thing: Undo works if you do this by accident :-)

The OpenOffice/LibreOffice UI for working with macros is hideous and it's easy to get lost, so post back if you get stuck.
posted by flabdablet at 7:12 AM on August 11, 2021

Thoughts on tweaks: as it stands, the script leaves the insertion cursor at the beginning of the paragraph following the one that just got lifted. That's probably reasonable behaviour if what you're doing is working through some kind of to-do list but if you'd rather put it somewhere else (perhaps after any existing timestamp?) I'm sure that would be relatively easy to accomplish.

Also, the timestamp format is as you have it in the question, but separated from the paragraph content with a tab rather than a space. I thought that was tidier, but if you'd rather have the space instead, just change both instances of "\t" in the script to spaces.

If you want a different timestamp format altogether, you will need to modify both the formatting argument to "strftime()" and the regex that matches existing timestamps for deletion. I can easily help with that if you give me some examples of timestamps in the format you prefer. Note that because the only sorting this script does is implicit, there's no particular need for your timestamps to be in a format that sorts cleanly when run through an alphabetic sort although obviously the ISO-derived formats will always be preferable on religious grounds.

Personally the only change I'd make is using extended format for both date and time, like 2021-08-08 17:24 instead of 20210808 17:24. If you want to use that, change the strftime() format from "%Y%m%d %H:%M\t" to "%Y-%m-%d %H:%M\t" and the regex from "^[0-9]{8} [0-9]{2}:[0-9]{2}\t" to "^[0-9]{4}-?[0-9]{2}-?[0-9]{2} [0-9]{2}:[0-9]{2}\t" (note that this regex will match timestamps both with and without - separators in the date field, so you can cut over to it for existing documents and not end up with doubled-up timestamps).
posted by flabdablet at 7:39 AM on August 11, 2021

Further thought: as it stands, this script destroys any formatting in paragraphs that it timestamps and lifts, because it processes their content as plain text. If that's annoying, let me know and I'll research less destructive ways to script the shifting around of document content.
posted by flabdablet at 7:53 AM on August 11, 2021

Response by poster: Hi flabdablet

Hey, that's neat how that works! And I can just select a date time string anywhere in the list, punch F4 and it overwrites it and resorts it to the top.

20210812 09:03 notes, update
20210812 09:02 items B, update
20210812 09:02 items
20210812 09:01

List before: notes, update
20210812 09:02 items B, update
20210812 09:02 items
20210812 09:01
20210812 08:29 notes,

It runs but with an error about 'Non' undefined.

Not too terrible setting up. Libre itself put up a warning about {Warning 1946. Property 'System.AppUserModel.ID' for shortcut 'LibreOffice.lnk' could not be set.} Who knows, I haven't used had libre on here for 5 years.
posted by unearthed at 2:04 PM on August 11, 2021

Looks like you've missed the final "e" on "return None". Just correcting that in place with Notepad or any other text editor should fix it. Shouldn't even need a restart of LibreOffice.

You shouldn't need to select the timestamp per se; just having the current selection or text cursor anywhere inside the paragraph you want to lift should be enough.
posted by flabdablet at 5:30 PM on August 11, 2021

Also, the Warning 1946 thing looks like a minor annoyance that can safely be ignored.

I haven't seen it before; when I install LibreOffice on Windows boxes I generally do that via Ninite (usually combined with other packages) rather than using the official installer. Ninite rocks.
posted by flabdablet at 5:48 PM on August 11, 2021 [1 favorite]

Another potentially nice thing: LibreOffice Writer is just as happy to edit plain text files as OpenDocument Text formatted text files, which could be handy if you're preparing these lists in order to have them consumed by some other tool. And because this script is saved inside your local LibreOffice user profile rather than attached to a particular ODT file, it and its associated keyboard shortcut will remain available to you regardless of which file you're using Writer to edit.

In the Windows file browser, you should be able to right-click on any plain text file (in Windows, that's any file whose name ends with ".txt") and select Open with -> LibreOffice Writer. As long as you avoid applying formatting like bold or underline or font size or whatever as you edit the text, Writer should save the file after editing without giving you any static about it being in a non-native format.
posted by flabdablet at 6:07 PM on August 11, 2021

Response by poster: Hi, yep, just realised that, changed it and now it's fine.

It's a very, very nice script, thank you flabdablet; I've looked at loads of timekeeping applications (desktop and online), but they never fit with a very fluid day, this along with nagme.cmd will make my time a lot more manageable.

Yes, I was just wondering about how this could interwork with other software, that's more to ponder on thanks.
posted by unearthed at 6:16 PM on August 11, 2021

You can also do this in Airtable. Just add a "last modified" column, and whatever other columns you like, and set it to sort by last modified. Example:
posted by Nothing at 7:56 AM on August 12, 2021

« Older ADHD at Work - Management Edition   |   Tips for a manly spa day Newer »

You are not logged in, either login or create an account to post comments