Didier Verna's scientific blog: Lisp, Emacs, LaTeX and random stuff.

## Tag - hack

Thursday, February 25 2010

## Translucent XEmacs coming in hot !!

I'm uploading a set of changes to the XEmacs 21.5 Mercurial repository right now. These changes implement a new face property named "background-placement" which makes an XEmacs frame "slide" over a face's background pixmap when the property is set to 'absolute.

If you do this on the default face, then you can achieve some sort of pseudo-translucency, for example by using the same (or a darkened version of) the root window's background pixmap.

Here are a couple of screenshots that illustrate this.

Tuesday, July 1 2008

## CCL Objective C bridge code indentation

A whole bunch of CCL Cocoa coding involves calls to ObjC methods. For instance, the following ObjC code:
[cell drawWithFrame: frame inView: view];
will translate into this in CLL:
(#/drawWithFrame:inView: cell frame view)
. Indeed, Objective C is designed around the record-based model (methods belong to classes), so the cell object receives the drawWithFrame:inView: message via the funny bracket syntax. On the other hand, the Lisp translation involves a generic function call with the usual funcall syntax. The dispatch occurs on the first argument (the cell), and the rest is actual arguments to the message.

This layout is obviously not optimal for readability. One could define a bracket reader-macro to simulate ObjC's message passing syntax in Lisp, but I prefer to stick to the "Lisp Way". The first argument should still be considered "special" though.

For readability (especially when the method name is long), I like to put the arguments to the message (not the receiver!) on subsequent lines. However, XEmacs's cl-indent-function will indent this as an ordinary function call, like this:
(#/drawWithFrame:inView: cell                         frame view
which is awfull. What I want is the following indentation:
(#/drawWithFrame:inView: cell  frame view
This kind of indentation is normally achieved by putting a common-lisp-indent-function property of 1 on the function symbol. However, you don't want to do that on all possible ObjC message by hand (and you don't know them all in advance anyway). The following advice on common-lisp-indent-function (from the cl-indent package does the trick. It dynamically puts the property on each relevant symbol every time it is subject to indentation. A bit brute force, but it works smoothly.
(defadvice common-lisp-indent-function (before ccl-objc-bridge activate)  "Improve indentation scheme of the CCL Objective-C bridge.Currently, this does the following:- All (#/doThis:withThat: ...) forms are indented as per alisp-indent-function property of 1. This effectively treats the first argument(an object or a class) as special. The indentation you get is:  (#/function arg1        instead of:        (#/function arg1    arg2 ...)						 arg2 ...)"  (let ((containing-form-start (elt state 1)))    (save-excursion      (goto-char containing-form-start)      (forward-char 1)      (cond ((looking-at "#/\$$\\w\\|:\$$*:")	     ;; We're looking at a (#/doThis:withThat: ...) form. In its holy	     ;; brokenness, common-lisp-indent-function with the help of	     ;; parse-partial-sexp will consider that the function name in	     ;; this form is "/functioncall:". Our trick here is to	     ;; dynamically put a lisp-indent-function property of 1 on this	     ;; symbol, so that the subsequent (original) indenting function	     ;; will handle it.	     (let* ((beg (progn (forward-char 1) (point)))		    (sym (progn			   (forward-sexp 1)			   (intern (downcase (buffer-substring beg							       (point)))))))	       (put sym 'common-lisp-indent-function 1)))))))

One last thing and I'll be happy: I want to indent CCL's slet and slet* constructs just as let:
(put 'slet 'common-lisp-indent-function      '((&whole 4 &rest (&whole 1 1 2)) &body))(put 'slet* 'common-lisp-indent-function     '((&whole 4 &rest (&whole 1 1 2)) &body))

Et voilà !

Wednesday, June 4 2008

## Beamer blocks and the Listings package

For many of my lectures, I use the Listings package for typesetting code excerpts, and include them in Beamer blocks. Providing nice shortcuts for doing that is not trivial if you want to preserve control over Listings options, and add a new one for the block's title. Here is a way to nicely wrap a call to \lstinputlisting inside a Beamer block.

First, let's use the xkeyval package to create a "title" option:
\define@cmdkey[dvl]{lst}[@dvl@lst@]{title}{}

Next, a low-level listing input command. This macro takes 4 arguments: an overlay specification, a title for the block, a list of options passed to Listings, and a file name for input:
%% \dvlinputlisting{overlay}{title}{lstoption=,...}{file}\newcommand\dvlinputlisting[4]{%  \begin{block}#1{#2}    %% #### WARNING: I need this hack because keyval-style options    %% mess up the parsing.    \expandafter\lstinputlisting\expandafter[#3]{#4}  \end{block}}

And now, you can define all sorts of specialized versions for different languages. For example, here is one for Common Lisp code. The block title is "Lisp" by default, and a "lisp" extension is automatically added to the file name:
%% Language-specific shortcuts:%% The title option is used for the beamer block's title.%% All other options are passed to listings.%% \XXXinputlisting<overlay>[title=,lstoption=,...]{file}\newcommand<>\clinputlisting[2][]{%  \def\@dvl@lst@title{Lisp}%  \setkeys*[dvl]{lst}{#1}%  \edef\@dvl@lst@options{language=lisp,\XKV@rm}%  \dvlinputlisting{#3}{\@dvl@lst@title}{\@dvl@lst@options}{#2.lisp}}

Which you could call like this:
\clinputlisting<2->[title={Example 1}, gobble=2]{ex1}

As you can see, "title" is an option for the Beamer block, and all the others are dispatched to Listings. Cool.

Now, things are getting more complicated when you want nice shortcuts for inline environments, because nesting Beamer blocks with listings doesn't work. Fortunately, I figured out a trick based on the Verbatim package to simulate that. The idea is to store the contents of the listing environment in a temporary file, and use \lstinputlisting as before to include it. Clever right ?
:-)
Here is a generic environment for doing that. In the opening, we read the environment's contents and store it in the file \jobname.dvl. In the ending, we call our previous macro \dvlinputlisting on that file (actually, on a dynamically created argument list called \@dvl@args:
\usepackage{verbatim}\newwrite\lstvrb@out\def\@dvllisting{%  \begingroup  \@bsphack  \immediate\openout\lstvrb@out\jobname.dvl  \let\do\@makeother\dospecials\catcode\^^M\active  \def\verbatim@processline{%    \immediate\write\lstvrb@out{\the\verbatim@line}}%  \verbatim@start}\def\@enddvllisting{%  \immediate\closeout\lstvrb@out  \@esphack  \endgroup  \expandafter\dvlinputlisting\@dvl@args}

And now, we can define all sorts of specialized versions for every language we're insterested in. Again, here is one for Common Lisp.
\newenvironment<>{cllisting}[1][]{%  \def\@dvl@lst@title{Lisp}%  \setkeys*[dvl]{lst}{#1}%  \edef\@dvl@lst@options{language=lisp,\XKV@rm}%  \xdef\@dvl@args{{#2}{\@dvl@lst@title}{\@dvl@lst@options}{%    \jobname.dvl}}  \@dvllisting}{%  \@enddvllisting}

Which you can use like this:
\begin{cllinsting}<2->[title={Example 1},gobble=2]  (defun foo (x) (* 2 x))\end{cllisting}`

Don't forget that frames containing code excerpts like this are fragile!
Copyright (C) 2008 -- 2018 Didier Verna didier@lrde.epita.fr