jEdit macros, vs. Emacs functions

I've been playing with customising jEdit a little bit, and decided to have a go at writing some simple date insertion macros. These perform the same work as some old elisp functions I wrote years ago in Emacs, to insert date/time stamps in various formats. In my .emacs file, I bind these functions to short-cut keys, and then use them for updating Changelogs in code and in offline journal entries.

Here are my original elisp functions, which are self describing:

(defun insert-date-iso ()
  "Inserts the current local date and time (to the minute) into the current buffer
before Point. The data are formatted per ISO 8601 specification. This is useful for

prefixing entries in a log book."
  (interactive)
  (setq now (decode-time)
        final-string (format "%04d-%02d-%02dT%02d:%02d+%d"
                             (nth 5 now)          ; yyyy
                             (nth 4 now)          ; mm
                             (nth 3 now)          ; dd
                             (nth 2 now)          ; HH
                             (nth 1 now)          ; MM
                             (/ (nth 8 now) 36))) ; UTCO
  (insert final-string))


(defun insert-date-stamp ()
  "Inserts the current local date into the current buffer before Point. The data are
formatted per ISO 8601 short specification and prefixed with my initials 'MJL'. This

is useful for inserting mod comments into code files."
  (interactive)
  (setq now (decode-time)
        final-string (format "MJL%04d%02d%02d - "
                             (nth 5 now)          ; yyyy
                             (nth 4 now)          ; mm
                             (nth 3 now)))        ; dd
  (insert final-string))


(defun insert-date-dow ()
  "Inserts the current local date and the day of the week into the current buffer
before Point. The date data are formatted per ISO 8601 specification. The DOW is

expanded to the full name. This is useful for prefixing day entries in a log book."
  (interactive)
  (setq DOWlist '(Sunday Monday Tuesday Wednesday Thursday Friday Saturday))
  (setq now (decode-time)
        final-string (format "%04d-%02d-%02d %s"
                             (nth 5 now)                 ; yyyy
                             (nth 4 now)                 ; mm
                             (nth 3 now)                 ; dd
                             (nth (nth 6 now) DOWlist))) ; day
  (insert final-string))

These are fairly simple, the only obfuscated part is the way that the output list now has been created from the (decode-time) built-in, which then has to be picked appart to get the different date elements for formatting.

Compare this with the jEdit equivalents, which are written in BeanShell. Each macro is in it's own .bsh file, rather than all together in a single file like the elisp functions, and the documentation is done in XML, rather than as a doc-comment in elisp:



/*
 * Insert_Time_ISO.bsh - a BeanShell macro script for the
 * jEdit text editor - inserts current system date in ISO 8601 format
 * Copyright © 2006 Michael Lockhart
 *
 * MJL20060603 - Created
 * MJL20060604 - Tidy code, fix meta-comments
 * MJL20060605 - Check object creation, just in case...
 * MJL20060606 - use Macros.error(), instead of Macros.message()
 *
 */


import java.text.SimpleDateFormat;


dateFmt = new SimpleDateFormat("yyyy-MM-dd");
timeFmt = new SimpleDateFormat("HH:mmZZZZ");


now = new Date();

if ((now != null) && (dateFmt != null) && (timeFmt != null))
    textArea.setSelectedText(dateFmt.format(now) + "T" +
                             timeFmt.format(now) + " ");
else
    Macros.error(view,"Could not create system Date or SimpleDateFormat "
                       + "objects!nJVM resources might be extremely low.");

/*
	Macro index data (in DocBook format)


<listitem>
    <para><filename>Insert_Time_ISO.bsh</filename></para>
    <abstract><para>
        Inserts the current local date and time (to the minute) into the
        current buffer before the cursor. The data are formatted per ISO
        8601 specification. This is useful for prefixing entries in a log
        book.
    </para></abstract>
</listitem>

*/


// end Insert_Time_ISO.bsh


/*
 * Insert_Date_ISO-MJL.bsh - a BeanShell macro script for the
 * jEdit text editor - inserts current system date in ISO 8601 condensed format
 * Copyright © 2006 Michael Lockhart
 *
 * MJL20060603 - Created
 * MJL20060604 - Tidy code, fix meta-comments
 * MJL20060605 - Check object creation, just in case...
 * MJL20060606 - use Macros.error(), instead of Macros.message()
 */


import java.text.SimpleDateFormat;

dateFmt = new SimpleDateFormat("yyyyMMdd");

now = new Date();

if ((now != null) && (dateFmt != null))
    textArea.setSelectedText("MJL" + dateFmt.format(now) + " - ");
else
    Macros.error(view,"Could not create system Date or SimpleDateFormat "
                    + "objects!nJVM resources might be extremely low.");

/*
	Macro index data (in DocBook format)

<listitem>
    <para><filename>Insert_Date_ISO-MJL.bsh</filename></para>
    <abstract><para>
        Inserts the current local date into the current buffer before the
        cursor. The data are formatted per ISO 8601 short specification and
        prefixed with my initials 'MJL'. This is useful for inserting mod
        comments into code files.
    </para></abstract>
</listitem>

*/

// end Insert_Date_ISO-MJL.bsh


/*
 * Insert_Date_DOW.bsh - a BeanShell macro script for the
 * jEdit text editor - inserts current system in ISO 8601 format, with day-of-week
 * Copyright © 2006 Michael Lockhart
 *
 * MJL20060604 - Created
 * MJL20060605 - Check object creation, just in case...
 * MJL20060606 - use Macros.error(), instead of Macros.message()
 *
 */


import java.text.SimpleDateFormat;

dateFmt = new SimpleDateFormat("yyyy-MM-dd EEEE");

now = new Date();

if ((now != null) && (dateFmt != null))
    textArea.setSelectedText(dateFmt.format(now) + " ");
else
    Macros.error(view,"Could not create system Date or SimpleDateFormat "
                    + "objects!nJVM resources might be extremely low.");

/*
	Macro index data (in DocBook format)

<listitem>
    <para><filename>Insert_Date_DOW.bsh</filename></para>
    <abstract><para>
        Inserts the current local date and the day of the week into the
        current buffer before the cursor. The date data are formatted per
        ISO 8601 specification. The DOW is expanded to the full name. This
        is useful for prefixing day entries in a log book.
    </para></abstract>
</listitem>

*/


// end Insert_Date_DOW.bsh

The comments are lot more verbose, but you can see the Insert_Date_ISO-MJL macro at work in the script comments above. Also, the Java SimpleDateFormat class makes formatting much simpler to read, I feel, but even with BeanShell's ability to use untyped variables (for example, in BeanShell you can say “dateFormatter = new SimpleDateFormat…”, instead of Java's “DateFormat dateFormatter=new SimpleDateFormat…”), the code is still not as elegant as the elisp version.

However, I think I'm starting to like jEdit over Emacs (blasphemy!). Mind you it's slow: it makes Emacs seem zippy, and traditionaly Emacs stood for “EMACS Makes A Computer Slow”!

On a side-note, there is a nice plugin for jEdit, called Code2HTML, which renders your code in HTML, with syntax highlighting to match that done by jEdit (and jEdit knows a lot of languages!). Unfortunately when I pasted the generated HTML into this WordPress post and then saved it, all the highlighting got removed… I wonder if it has something to do with the plugin's use of <SPAN>s and CSS Styles? But even if I paste the <STYLE> block into this post as well, the formatting gets eaten up by WordPress :( Something to look into.


2006-06-07T15:36+1000 - Update: I should make a point about the copyright on these scripts: they're copyleft, GNU GPL2.0. I just snipped out the boilerplate to make this post shorter. Feel free to copy/use as you like, subject to the GPL, and you should of course cite the author (me) and include the boilerplate disclamers on any copy you distribute to others. The missing boilerplate is below:
 *
 *
 * Copyright © 2006 Michael Lockhart.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the jEdit application; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *

2008-07-15T10:45+1000 - Update: I've finally re-written these functions using format-time-string as advised twice in the comments (!). Duh!


(defun mjl-insert-date-iso ()
  "Inserts the current local date and time (to the minute) into
the current buffer before Point. The date is formatted per ISO

8601 specification. This is useful for prefixing entries in a log

book."
  (interactive)
  (insert (format-time-string "%Y-%m-%dT%R%z")))


(defun mjl-insert-date-stamp ()
  "Inserts the current local date into the current buffer before
Point. The date is formatted per ISO 8601 short specification and

prefixed with my initials 'MJL'. This is useful for inserting mod

comments into code files."
  (interactive)
  (setq now (decode-time))
  (insert (format-time-string "MJL%Y%m%d")))


(defun mjl-insert-date-dow ()
  "Inserts the current local date and the day of the week into
the current buffer before Point. The date is formatted per ISO

8601 specification. The DOW is expanded to the full name. This is

useful for prefixing day entries in a log book."
  (interactive)
  (insert (format-time-string "%Y-%m-%d %A")))
… and a new one, since I've become an Org (and Remember) fan:
(defun mjl-insert-log-entry-org ()
  "Inserts the current local date and time into
the current buffer before Point. The date is formatted to suit

Org mode's agenda and highlighting functions. The date is also

formatted as a level 3 headline for inclusion in an org

file."
  (interactive)
  (insert (format-time-string "*** <%Y-%m-%d %A %R> ")))

I should add that my flirtation with jEdit is over, by the way. Back to emacs for me, and I'm repenting for my blasphemous ways…