Remind use case 1

From Roaring Penguin
Jump to: navigation, search
Main article: Remind

Wiki Moved

Please note that the Wiki has moved! This copy is archived and will not be updated.

The new wiki is here; please update your bookmarks.

How I (Pelzlpj) Use Remind

Remind follows the design philosophy of many great Unix utilities: it interacts well with other programs. I generally use Remind not as a standalone application, but in conjunction with other tools available on my GNU/Linux system.

At the beginning of the day I like to see a list of the day's events, along with warnings about important events that will occur in days to come. Remind can produce such a list all by itself, but I combine Remind with cron and gxmessage to pop up a graphical list of reminders on my X Window desktop every morning.

I also want to get an alarm message when timed reminders are triggered, so I don't miss any appointments. So I run a background Remind process in "daemon mode," and it pops up gxmessage windows on my desktop whenever a timed reminder goes off.

Aside from those popups, I interact with Remind primarily through Wyrd, the console-based frontend I wrote. I use Wyrd to scan through my daily schedule, and most of the changes I make to ~/.reminders are handled through Wyrd.

Generating the Message Windows

To get a list of the day's events, I just pipe the output of the remind command to gxmessage. I configured cron to bring up that window every day at 8:00am, by adding the following line to my cron table:

# Pop up daily reminders
00 08 * * * export DISPLAY=:0.0 && \
            /usr/local/bin/remind -q -g ~/.reminders | gxmessage -title "today's reminders" -file -

The DISPLAY environment variable is set so that the gxmessage window gets sent to the primary X Window display.

To pop up windows for triggered reminders, I added the following command to ~/.xinitrc :

remind -z -k'gxmessage -title "reminder" %s &' ~/.reminders &

This command is run only once, when the X server launches. It causes Remind to run in daemon mode. When a timed reminder is triggered, the MSG text for each reminder is passed to gxmessage as the %s parameter.

Using Remind with Wyrd

Wyrd provides a traditional timetable view of my daily schedule, and provides hotkeys for very quickly entering new reminders or editing existing reminders. I have configured Wyrd to invoke Vim for editing the reminder files.

When I run Remind to get a list of the day's reminders, I want to be able to differentiate between events that will occur today, tomorrow, or some number of days in the future. So I could use Remind's %b code like so:

REM Jan 17 +2 MSG Go grocery shopping %b

This will cause Remind to print out "Go grocery shopping in 2 days' time" on Jan 15, "Go grocery shopping tomorrow" on Jan 16, and "Go grocery shopping today" on Jan 17.

Now let's tweak that a bit. If I use that code, then Wyrd will print out "Go grocery shopping today" on the Jan 17 timeslot in the calendar, even though the current date may be Jun 23. In other words, it doesn't really make sense to print "today" inside Wyrd; it's a bit misleading. Fortunately there is an easy solution. Wyrd invokes Remind in calendar mode, and Remind provides a way to output somewhat different text for calendars:

REM Jan 17 +2 MSG %"Go grocery shopping%" %b

With this change, only the text between the %" symbols will be inserted into Wyrd's timetable, but the entire message gets printed when using Remind in its default mode.

For timed reminders, the situation is a bit more complicated. Here, I want events to be printed out in three different ways:

  1. In Remind's default mode, I want reminders to appear in the form "Go grocery shopping tomorrow at 3:30pm". Then at any point in the day, I can run rem -q and get something that makes sense as a to-do list.
  2. In calendar mode, I just want a short description of the reminder. I don't want any sort of timestamp or message about what day the reminder occurs on, because that information is already conveyed through Wyrd's timetable interface.
  3. In daemon mode, I'd like my Remind popups to contain text like "Go grocery shopping 30 minutes from now" or "Go grocery shopping now". I don't want a timestamp like "at 3:30pm", because I don't want to have to look at a clock just to interpret the alarm message.

Remind's scripting language is powerful enough to handle all of these cases. I start by setting up a user-defined function in ~/.reminders:

FSET t() iif($Daemon > 0, "%1", "%b %2")

I can use this function in a REM statement, with Remind's "expression pasting" syntax:

REM Jan 17 +2 AT 15:30 +30 MSG %"Go grocery shopping%" [t()]

In calendar mode, I will see only the text enclosed in %" symbols: "Go grocery shopping". In Remind's default mode, t() evaluates to %b %2, so I will see something like "Go grocery shopping tomorrow at 3:30pm". In daemon mode, t() evalutes to %1, so I will see "Go grocery shopping 30 minutes from now".

There's only one real downside to entering reminders in this fashion: it's a bit of a pain to type. This is where Wyrd's extensive configurability comes in handy. I've created a custom ~/.wyrdrc configuration file which includes the following commands:

set timed_template="REM %monname% %mday% %year% AT %hour%:%min% DURATION 1:00 MSG %\"%\" [t()]"
set untimed_template="REM %monname% %mday% %year% MSG %\"%\" %b"

Now when I hit the timed reminder hotkey in Wyrd, my editor pops open with a new reminder template like this:

REM Jan 17 2006 AT 15:00 DURATION 1:00 MSG %"%" [t()]

All I have to do is put my cursor between the %" symbols and start typing the reminder body.

Even this is too much work for me. Inevitably I want to modify my REM statements to include a Remind delta parameter, adjust the starting time, or change the duration. That means moving around within the REM statement a fair amount. I've addressed this by installing the Vim-Latex Suite, which comes with a special "placeholder" feature. I changed my templates to look like this:

set timed_template="REM %monname% %mday% %year% <++>AT %hour%:%min%<++> DURATION 1:00<++> MSG %\"<++>%\" [t()]"
set untimed_template="REM %monname% %mday% %year% <++>MSG %\"<++>%\" %b"

Now when I jump into insert mode in Vim, I can hit Ctrl-J and my cursor jumps immediately to the <++> markers. I can enter Remind delta and message parameters without wasting time manually moving the cursor around.

Other Tricks

I have a reminder which pops up every night when I should be thinking about heading to bed, lest I accidentally stay up all night writing code. But I don't really want this reminder to show up in the to-do list or on the calendar--that's just needless clutter. Again, Remind's scripting language comes to the rescue:

IF $Daemon > 0
   REM AT 01:00 MSG Go to bed!