ESA: a CLIM Library for Writing Emacs-Style Applications
Total Page:16
File Type:pdf, Size:1020Kb
ESA: A CLIM Library for Writing Emacs-Style Applications Robert Strandh Troels Henriksen LaBRI, Université Bordeaux 1 DIKU, University of Copenhagen 351, Cours de la Libération Universitetsparken 1, Copenhagen 33405 Talence Cedex [email protected] France [email protected] David Murray Christophe Rhodes ADMurray Associates Goldsmiths, University of London 10 Rue Carrier Belleuse, 75015 Paris New Cross Road, London, SE14 6NW [email protected] [email protected] ABSTRACT style applications. The central distinguishing feature of an We describe ESA (for Emacs-Style Application), a library Emacs-style application, for our purposes, is that it uses for writing applications with an Emacs look-and-feel within short sequences of keystrokes as the default method of in- the Common Lisp Interface Manager. The ESA library voking commands, and only occasionally requires the user to takes advantage of the layered design of CLIM to provide a type the full name of the command in a minibuffer. A spe- command loop that uses Emacs-style multi-keystroke com- cial keystroke (M-x) is used to invoke commands by name. mand invocation. ESA supplies other functionality for writ- This interaction style is substantially different from the one ing such applications such as a minibuffer for invoking ex- provided by CLIM by default, and therefore required us to tended commands and for supplying command arguments, write a different CLIM top level. Fortunately, CLIM was Emacs-style keyboard macros and numeric arguments, file designed to make this not only possible but fairly straight- and buffer management, and more. ESA is currently used forward, as the implementation of a replacement top level in two major CLIM applications: the Climacs text editor can build on the protocol layers beneath, just as the default (and the Drei text gadget integrated with the McCLIM im- top level is built. plementation), and the Gsharp score editor. This paper describes the features provided by ESA, gives some detail The ESA library provides other features that are helpful in about their implementation, and suggests avenues for fur- the creation of Emacs-style applications; these features need ther work. not be used, but are available if desired. A client applica- tion may choose to use an info pane1 to display information 1. INTRODUCTION about an associated master pane, such as the name of a buffer being edited, whether application state needs saving, The Common Lisp Interface Manager (CLIM) [3] is spec- or the position of the cursor in a buffer. Other optional com- ification of a substantial library for user interaction with ponents include a protocol for file input/output with ver- Common Lisp applications. CLIM has a layered design, sioning support; a framework for reading and writing buffers and defines a fairly large collection of interacting protocols (with application-defined content) to external streams; and that together make up the full library. Thanks to this lay- support for displaying command and keystroke documenta- ered approach, it is straightforward to add functionality to tion on-demand. However, we wish to emphasize that, for CLIM by defining new classes and new methods on existing our purposes, the defining characteristic of an Emacs-style generic functions: provided that they respect the defined application is not its function (such as editing text files or protocols, such extensions will integrate seamlessly into the text buffers) but its mode of interaction. rest of CLIM. Customization of the standard behaviour of CLIM components is likewise straightforward, using stan- Two major applications already use the ESA library, namely dard CLOS means such as subclassing and auxiliary meth- Drei, the Emacs-like editor component distributed as part of ods on protocol generic functions as in [1]. For more infor- McCLIM [7] (and its extension to a standalone application, mation on CLIM, see for example [2, 4, 5]. Climacs [6]) and Gsharp, an editor for music scores. Thanks to the ESA library, the look and feel of these applications is ESA is a library for CLIM that assists in writing Emacs- similar, even though they manipulate very different objects. Other applications that use the ESA library have been writ- ten or are in the process of development, such as a directory editor, a mail client, and an info documentation browser. ESA is developed and distributed as part of McCLIM2, but 1a “mode line” in Emacs terminology. 2See http://common-lisp.net/project/mcclim/ for in- structions on obtaining McCLIM and ESA. has been run on other CLIM implementations in the past, marker, *numeric-argument-p*, a Boolean value that indi- and, to the authors’ knowledge, it should still be possible to cates whether a numeric argument was given by the user at do so. ESA is designed as a portable layer that should run on all. This extension allows ESA applications to tell the differ- top of any CLIM implementation, using only exported CLIM ence between the case where a numeric argument of 1 was symbols, though this is unfortunately not always possible. explicitly given, and the case where no numeric argument was given. The rest of this paper gives more details about each of the components making up the ESA library: section 2 intro- Finally, the ESA top level contains support for execut- duces the customized top level and command loop; section ing Emacs-style keyboard macros, whereby a sequence of 3 discusses the support for keystroke handling using CLIM keystrokes is recorded for later playback. This mechanism command tables, and describes the command tables avail- is very hard to implement unless there is support in the able for use by client applications. Sections 4 and 5 describe top level for it, because special treatment is required for the support for multiple windows and for buffer handling, keystrokes that start and end the recording. respectively, following which we demonstrate an example Emacs-style application, and conclude with a discussion of 2.1 Command Arguments the scope for further work. The custom top-level function provided by ESA is integrated into CLIM in that it uses the CLIM function accept to 2. TOP LEVEL acquire commands and arguments. The ESA library cus- A key part of CLIM is the top level which executes a com- tomizes the stream-accept generic function called by ac- mand loop that, in each iteration, acquires a command and cept so that commands and arguments are prompted for in any arguments that the command might need, and finally the ESA minibuffer. executes the command. The minibuffer’s version of stream-accept calls the stan- CLIM provides a default top level that prompts the user for dard prompt-for-accept function, but then calls accept- a command to be executed. The user can satisfy this request 1-for-minibuffer, an ESA-internal function, rather than by typing the name of a command (with completion) into an the CLIM function accept-1. We must use our own func- interactor pane; by selecting an entry in a menu; by issuing tion as we wish to turn input sensitization off, and accept-1 a gesture associated with the command; or by clicking on does not allow this. a presentation that has a presentation-to-command transla- tor associated with it. Command arguments are acquired There is additional work required to support accepting com- in a similar way. This default top level works fine when mands for the com-extended-command command (invoked gestures are mouse gestures or single keystrokes using some by M-x). ESA provides its own command-parser and partial- modifier such as control or meta, but is less well adapted command-parser to integrate well with ESA’s top level; how- when commands are to be invoked by keystrokes associated ever, there is no standard way to discover, given a command with ordinary characters and when sequences of keystrokes name, what arguments that command requires, and conse- should be used, as in Emacs. quently the implementation of these command parsers are sensitive to the internal implementation details of the CLIM When the CLIM function run-frame-top-level is invoked implementation. on an application frame, CLIM executes the top-level func- tion associated with the frame. What top-level function 3. COMMAND TABLES is associated with a particular frame is determined by CLIM command tables support both nesting and inheri- the :top-level option given to the standard CLIM macro tance. Inheritance is used for code factoring as usual. An define-application-frame. When no such initarg is given, entry in a command table can be associated with a name in CLIM uses the generic function default-frame-top-level a menu or with a single keystroke, usually with some modi- as the top-level function for the frame. ESA applications fier key such as control or meta. The value of an entry can must give the :top-level option with a value of (esa-top- be either a command to be executed, or another command level) in order to use the specific top-level function pro- table for nesting. Multiple keystrokes such as required by vided as part of the ESA library. Emacs-style applications are not supported, however. The ESA top level accumulates a sequence of keystrokes The Emacs-style interaction mode assumes that the vast until that sequence is associated with a command. To de- majority of all commands are to be invoked by sequences termine whether that is the case, the top level searches a of keystrokes that may be ordinary characters, and that on hierarchy of command tables (see section 3 for the details of the rare occasion that a command is needed that is not as- this mechanism). sociated with a sequence of keystrokes, a special keystroke (M-x) must be used as a prefix.