[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Sesquicolon -- Note: Not a Bug

From: John H Swaby
Subject: Sesquicolon -- Note: Not a Bug
Date: Fri, 23 Aug 2002 00:10:55 -0600 (MDT)

Dear Emacs Maintainers:

I teach a Unix scripting and commands class where I present scripting
in Emacs Lisp along with Perl, Python, and Tcl scripting.

For the languages other than Emacs Lisp, we use the shebang, "#!", as
the first two characters of our scripts; but since Emacs requires more
than two arguments to load and run a script in batch mode, I use the
sesquicolon, ":;", for Emacs.  I have not seen anything written about
this, so I thought (if it is new) you may find it of interest.

To illustrate, here are two example scripts (I say a little more after
the listing of the scripts):

:;exec emacs -batch -l $0 -f : $* # -*- Emacs-Lisp -*-
;;; Anagram (permute the characters of) the command line arguments
(defun : ()
  (random t) (print-string-list (mapcar 'anagram command-line-args-left)))

(defun print-string-list (ls)
  (cond (ls (princ (format (if (cdr ls) "%s " "%s\n") (car ls)))
            (print-string-list (cdr ls)))))

(defun anagram (str)
  (if (zerop (length str)) str
    (let ((n (random (length str))))
      (concat (substring str n (1+ n))
              (anagram (concat (substring str 0 n) (substring str (1+ n))))))))
;;; end of anagram

:;exec emacs -batch -l $0 -f : $* # -*- Emacs-Lisp -*-
;;; Determine the kinship relationship between two files (need absolute paths)
(defun : ()
  (let ((args command-line-args-left))
    (cond ((< (length args) 2)
           (princ (format "Usage: %s path1 path2\n"
                          (file-name-nondirectory (nth 2 command-line-args))))
           (kill-emacs 1)))
    (set 'r (relate (split-string (nth 0 args) "/")
                    (split-string (nth 1 args) "/")))
    (if (= (set 'rel (car r)) 1) (princ "siblings")
      (if (> rel 1) (princ (format "order %d cousins" (1- rel)))))
    (if (> (set 'rem (cdr r)) 0)
        (princ (concat (if (> rel 0) " ") (format "removed by %d\n" rem)))
      (if (> rel 0) (terpri)))))

(defun relate (r1 r2)
  (if (and r1 r2 (equal (car r1) (car r2))) (relate (cdr r1) (cdr r2))
    (cons (min (length r1) (length r2)) (abs (- (length r1) (length r2))))))
;;; end of kinship

If the Bourne shell or Bash is running the above scripts and Emacs is
of a recent vintage, then the above scripts are fine.  If, however,
the Korn shell ends up initially executing the above scripts, then $0
should be changed to $_.  To cover your (portable) bases, do this for
the first two lines:

:;f=$0;if [ $_ ];then f=$_;fi
:;exec emacs -batch -l $f -f : $* # -*- Emacs-Lisp -*-

Current versions of Emacs define the colon, ":", as a constant equal
to a colon; however, older emacsen, do not (for example version
19.30).  So for an older Emacs, change the sesquicolon-exec line in
the script to include "-eval '(setq : t)'".  Something like this:

:;exec emacs -batch -eval '(setq : t)' -l $0 -f : $*

I want to thank all of the maintainers for their work on the

 E xtensible
 M odifiable
 A lgorithmic
 C omputer
 S ystem

You've made Lisp readily available to the world!


John H. Swaby


reply via email to

[Prev in Thread] Current Thread [Next in Thread]