| 1 | @comment{-*- Dictionary: /usr/lisp/scribe/hem/hem; Mode: spell; Package: Hemlock; Log: /usr/lisp/scribe/hem/hem-docs.log -*-}
|
|---|
| 2 | @chapter (Auxiliary Systems)
|
|---|
| 3 | This chapter describes utilities that some implementations of @hemlock may
|
|---|
| 4 | leave unprovided or unsupported.
|
|---|
| 5 |
|
|---|
| 6 |
|
|---|
| 7 | @section[Key-events]
|
|---|
| 8 | @index(I/O)
|
|---|
| 9 | @index[keyboard input]
|
|---|
| 10 | @index[input, keyboard]
|
|---|
| 11 | @index[mouse input]
|
|---|
| 12 | @index[input, mouse]
|
|---|
| 13 | @label[key-events]
|
|---|
| 14 |
|
|---|
| 15 | These routines are defined in the @f["EXTENSIONS"] package since other projects
|
|---|
| 16 | have often used @hemlock's input translations for interfacing to CLX.
|
|---|
| 17 |
|
|---|
| 18 |
|
|---|
| 19 | @subsection[Introduction]
|
|---|
| 20 |
|
|---|
| 21 | The canonical representation of editor input is a key-event structure. Users
|
|---|
| 22 | can bind commands to keys (see section @ref[key-bindings]), which are non-zero
|
|---|
| 23 | length sequences of key-events. A key-event consists of an identifying token
|
|---|
| 24 | known as a @i[keysym] and a field of bits representing modifiers. Users define
|
|---|
| 25 | keysyms, integers between 0 and 65535 inclusively, by supplying names that
|
|---|
| 26 | reflect the legends on their keyboard's keys. Users define modifier names
|
|---|
| 27 | similarly, but the system chooses the bit and mask for recognizing the
|
|---|
| 28 | modifier. You can use keysym and modifier names to textually specify
|
|---|
| 29 | key-events and Hemlock keys in a @f[#k] syntax. The following are some
|
|---|
| 30 | examples:
|
|---|
| 31 | @begin[programexample]
|
|---|
| 32 | #k"C-u"
|
|---|
| 33 | #k"Control-u"
|
|---|
| 34 | #k"c-m-z"
|
|---|
| 35 | #k"control-x meta-d"
|
|---|
| 36 | #k"a"
|
|---|
| 37 | #k"A"
|
|---|
| 38 | #k"Linefeed"
|
|---|
| 39 | @end[programexample]
|
|---|
| 40 | This is convenient for use within code and in init files containing
|
|---|
| 41 | @f[bind-key] calls.
|
|---|
| 42 |
|
|---|
| 43 | The @f[#k] syntax is delimited by double quotes, but the system parses the
|
|---|
| 44 | contents rather than reading it as a Common Lisp string. Within the double
|
|---|
| 45 | quotes, spaces separate multiple key-events. A single key-event optionally
|
|---|
| 46 | starts with modifier names terminated by hyphens. Modifier names are
|
|---|
| 47 | alphabetic sequences of characters which the system uses case-insensitively.
|
|---|
| 48 | Following modifiers is a keysym name, which is case-insensitive if it consists
|
|---|
| 49 | of multiple characters, but if the name consists of only a single character,
|
|---|
| 50 | then it is case-sensitive.
|
|---|
| 51 |
|
|---|
| 52 | You can escape special characters @dash hyphen, double quote, open angle
|
|---|
| 53 | bracket, close angle bracket, and space @dash with a backslash, and you can
|
|---|
| 54 | specify a backslash by using two contiguously. You can use angle brackets to
|
|---|
| 55 | enclose a keysym name with many special characters in it. Between angle
|
|---|
| 56 | brackets appearing in a keysym name position, there are only two special
|
|---|
| 57 | characters, the closing angle bracket and backslash.
|
|---|
| 58 |
|
|---|
| 59 |
|
|---|
| 60 |
|
|---|
| 61 | @subsection[Interface]
|
|---|
| 62 |
|
|---|
| 63 | All of the following routines and variables are exported from the "EXTENSIONS"
|
|---|
| 64 | ("EXT") package.
|
|---|
| 65 |
|
|---|
| 66 |
|
|---|
| 67 | @defun[fun {define-keysym}, args {@i[keysym] @i[preferred-name] @rest @i[other-names]}]
|
|---|
| 68 | This function establishes a mapping from @i[preferred-name] to @i[keysym] for
|
|---|
| 69 | purposes of @f[#k] syntax. @i[Other-names] also map to @i[keysym], but the
|
|---|
| 70 | system uses @i[preferred-name] when printing key-events. The names are
|
|---|
| 71 | case-insensitive simple-strings; however, if the string contains a single
|
|---|
| 72 | character, then it is used case-sensitively. Redefining a keysym or re-using
|
|---|
| 73 | names has undefined effects.
|
|---|
| 74 |
|
|---|
| 75 | You can use this to define unused keysyms, but primarily this defines keysyms
|
|---|
| 76 | defined in the @i[X Window System Protocol, MIT X Consortium Standard, X
|
|---|
| 77 | Version 11, Release 4]. @f[translate-key-event] uses this knowledge to
|
|---|
| 78 | determine what keysyms are modifier keysyms and what keysym stand for
|
|---|
| 79 | alphabetic key-events.
|
|---|
| 80 | @enddefun
|
|---|
| 81 |
|
|---|
| 82 |
|
|---|
| 83 | @defun[fun {define-mouse-keysym}, args {@i[button] @i[keysym] @i[name] @i[shifted-bit] @i[event-key]}]
|
|---|
| 84 | This function defines @i[keysym] named @i[name] for key-events representing the
|
|---|
| 85 | X @i[button] cross the X @i[event-key] (@kwd[button-press] or
|
|---|
| 86 | @kwd[button-release]). @i[Shifted-bit] is a defined modifier name that
|
|---|
| 87 | @f[translate-mouse-key-event] sets in the key-event it returns whenever the X
|
|---|
| 88 | shift bit is set in an incoming event.
|
|---|
| 89 |
|
|---|
| 90 | Note, by default, there are distinct keysyms for each button distinguishing
|
|---|
| 91 | whether the user pressed or released the button.
|
|---|
| 92 |
|
|---|
| 93 | @i[Keysym] should be an one unspecified in @i[X Window System Protocol, MIT X
|
|---|
| 94 | Consortium Standard, X Version 11, Release 4].
|
|---|
| 95 | @enddefun
|
|---|
| 96 |
|
|---|
| 97 |
|
|---|
| 98 | @defun[fun {name-keysym}, args {@i[name]}]
|
|---|
| 99 | This function returns the keysym named @i[name]. If @i[name] is unknown, this
|
|---|
| 100 | returns @nil.
|
|---|
| 101 | @enddefun
|
|---|
| 102 |
|
|---|
| 103 | @defun[fun {keysym-names}, args {@i[keysym]}]
|
|---|
| 104 | This function returns the list of all names for @i[keysym]. If @i[keysym] is
|
|---|
| 105 | undefined, this returns @nil.
|
|---|
| 106 | @enddefun
|
|---|
| 107 |
|
|---|
| 108 | @defun[fun {keysym-preferred-name}, args {@i[keysym]}]
|
|---|
| 109 | This returns the preferred name for @i[keysym], how it is typically printed.
|
|---|
| 110 | If @i[keysym] is undefined, this returns @nil.
|
|---|
| 111 | @enddefun
|
|---|
| 112 |
|
|---|
| 113 | @defun[fun {define-key-event-modifier}, args {@i[long-name] @i[short-name]}]
|
|---|
| 114 | This establishes @i[long-name] and @i[short-name] as modifier names for
|
|---|
| 115 | purposes of specifying key-events in @f[#k] syntax. The names are
|
|---|
| 116 | case-insensitive simple-strings. If either name is already defined, this
|
|---|
| 117 | signals an error.
|
|---|
| 118 |
|
|---|
| 119 | The system defines the following default modifiers (first the long name,
|
|---|
| 120 | then the short name):
|
|---|
| 121 | @begin[Itemize]
|
|---|
| 122 | @f["Hyper"], @f["H"]
|
|---|
| 123 |
|
|---|
| 124 | @f["Super"], @f["S"]
|
|---|
| 125 |
|
|---|
| 126 | @f["Meta"], @f["M"]
|
|---|
| 127 |
|
|---|
| 128 | @f["Control"], @f["C"]
|
|---|
| 129 |
|
|---|
| 130 | @f["Shift"], @f["Shift"]
|
|---|
| 131 |
|
|---|
| 132 | @f["Lock"], @f["Lock"]
|
|---|
| 133 | @end[Itemize]
|
|---|
| 134 | @enddefun
|
|---|
| 135 |
|
|---|
| 136 |
|
|---|
| 137 | @defvar[var {all-modifier-names}]
|
|---|
| 138 | This variable holds all the defined modifier names.
|
|---|
| 139 | @enddefvar
|
|---|
| 140 |
|
|---|
| 141 |
|
|---|
| 142 | @defun[fun {define-clx-modifier}, args {@i[clx-mask] @i[modifier-name]}]
|
|---|
| 143 | This function establishes a mapping from @i[clx-mask] to a defined key-event
|
|---|
| 144 | @i[modifier-name]. @f[translate-key-event] and @f[translate-mouse-key-event]
|
|---|
| 145 | can only return key-events with bits defined by this routine.
|
|---|
| 146 |
|
|---|
| 147 | The system defines the following default mappings between CLX modifiers and
|
|---|
| 148 | key-event modifiers:
|
|---|
| 149 | @begin[Itemize]
|
|---|
| 150 | @f[(xlib:make-state-mask :mod-1) --> "Meta"]
|
|---|
| 151 |
|
|---|
| 152 | @f[(xlib:make-state-mask :control) --> "Control"]
|
|---|
| 153 |
|
|---|
| 154 | @f[(xlib:make-state-mask :lock) --> "Lock"]
|
|---|
| 155 |
|
|---|
| 156 | @f[(xlib:make-state-mask :shift) --> "Shift"]
|
|---|
| 157 | @end[Itemize]
|
|---|
| 158 | @enddefun
|
|---|
| 159 |
|
|---|
| 160 |
|
|---|
| 161 | @defun[fun {make-key-event-bits}, args {@rest @i[modifier-names]}]
|
|---|
| 162 | This function returns bits suitable for @f[make-key-event] from the supplied
|
|---|
| 163 | @i[modifier-names]. If any name is undefined, this signals an error.
|
|---|
| 164 | @enddefun
|
|---|
| 165 |
|
|---|
| 166 | @defun[fun {key-event-modifier-mask}, args {@i[modifier-name]}]
|
|---|
| 167 | This function returns a mask for @i[modifier-name]. This mask is suitable for
|
|---|
| 168 | use with @f[key-event-bits]. If @i[modifier-name] is undefined, this signals
|
|---|
| 169 | an error.
|
|---|
| 170 | @enddefun
|
|---|
| 171 |
|
|---|
| 172 | @defun[fun {key-event-bits-modifiers}, args {@i[bits]}]
|
|---|
| 173 | This returns a list of key-event modifier names, one for each modifier
|
|---|
| 174 | set in @i[bits].
|
|---|
| 175 | @enddefun
|
|---|
| 176 |
|
|---|
| 177 |
|
|---|
| 178 | @defun[fun {translate-key-event}, args {@i[display] @i[scan-code] @i[bits]}]
|
|---|
| 179 | This function translates the X @i[scan-code] and X @i[bits] to a key-event.
|
|---|
| 180 | First this maps @i[scan-code] to an X keysym using @f[xlib:keycode->keysym]
|
|---|
| 181 | looking at @i[bits] and supplying index as @f[1] if the X shift bit is on,
|
|---|
| 182 | @f[0] otherwise.
|
|---|
| 183 |
|
|---|
| 184 | If the resulting keysym is undefined, and it is not a modifier keysym,
|
|---|
| 185 | then this signals an error. If the keysym is a modifier key, then this
|
|---|
| 186 | returns @nil.
|
|---|
| 187 |
|
|---|
| 188 | If these conditions are satisfied
|
|---|
| 189 | @begin[Itemize]
|
|---|
| 190 | The keysym is defined.
|
|---|
| 191 |
|
|---|
| 192 | The X shift bit is off.
|
|---|
| 193 |
|
|---|
| 194 | The X lock bit is on.
|
|---|
| 195 |
|
|---|
| 196 | The X keysym represents a lowercase letter.
|
|---|
| 197 | @end[Itemize]
|
|---|
| 198 | then this maps the @i[scan-code] again supplying index as @f[1] this time,
|
|---|
| 199 | treating the X lock bit as a caps-lock bit. If this results in an undefined
|
|---|
| 200 | keysym, this signals an error. Otherwise, this makes a key-event with the
|
|---|
| 201 | keysym and bits formed by mapping the X bits to key-event bits.
|
|---|
| 202 |
|
|---|
| 203 | Otherwise, this makes a key-event with the keysym and bits formed by
|
|---|
| 204 | mapping the X bits to key-event bits.
|
|---|
| 205 | @enddefun
|
|---|
| 206 |
|
|---|
| 207 |
|
|---|
| 208 | @defun[fun {translate-mouse-key-event}, args {@i[scan-code] @i[bits] @i[event-key]}]
|
|---|
| 209 | This function translates the X button code, @i[scan-code], and modifier bits,
|
|---|
| 210 | @i[bits], for the X @i[event-key] into a key-event. See
|
|---|
| 211 | @f[define-mouse-keysym].
|
|---|
| 212 | @enddefun
|
|---|
| 213 |
|
|---|
| 214 | @defun[fun {make-key-event}, args {@i[object] @i[bits]}]
|
|---|
| 215 | This function returns a key-event described by @i[object] with @i[bits].
|
|---|
| 216 | @i[Object] is one of keysym, string, or key-event. When @i[object] is a
|
|---|
| 217 | key-event, this uses @f[key-event-keysym]. You can form @i[bits] with
|
|---|
| 218 | @f[make-key-event-bits] or @f[key-event-modifier-mask].
|
|---|
| 219 | @enddefun
|
|---|
| 220 |
|
|---|
| 221 | @defun[fun {key-event-p}, args {@i[object]}]
|
|---|
| 222 | This function returns whether @i[object] is a key-event.
|
|---|
| 223 | @enddefun
|
|---|
| 224 |
|
|---|
| 225 | @defun[fun {key-event-bits}, args {@i[key-event]}]
|
|---|
| 226 | This function returns the bits field of a @i[key-event].
|
|---|
| 227 | @enddefun
|
|---|
| 228 |
|
|---|
| 229 | @defun[fun {key-event-keysym}, args {@i[key-event]}]
|
|---|
| 230 | This function returns the keysym field of a @i[key-event].
|
|---|
| 231 | @enddefun
|
|---|
| 232 |
|
|---|
| 233 | @defun[fun {char-key-event}, args {@i[character]}]
|
|---|
| 234 | This function returns the key-event associated with @i[character]. You can
|
|---|
| 235 | associate a key-event with a character by @f[setf]'ing this form.
|
|---|
| 236 | @enddefun
|
|---|
| 237 |
|
|---|
| 238 | @defun[fun {key-event-char}, args {@i[key-event]}]
|
|---|
| 239 | This function returns the character associated with @i[key-event]. You can
|
|---|
| 240 | associate a character with a key-event by @f[setf]'ing this form. The system
|
|---|
| 241 | defaultly translates key-events in some implementation dependent way for text
|
|---|
| 242 | insertion; for example, under an ASCII system, the key-event @f[#k"C-h"], as
|
|---|
| 243 | well as @f[#k"backspace"] would map to the Common Lisp character that causes a
|
|---|
| 244 | backspace.
|
|---|
| 245 | @enddefun
|
|---|
| 246 |
|
|---|
| 247 | @defun[fun {key-event-bit-p}, args {@i[key-event] @i[bit-name]}]
|
|---|
| 248 | This function returns whether @i[key-event] has the bit set named by
|
|---|
| 249 | @i[bit-name]. This signals an error if @i[bit-name] is undefined.
|
|---|
| 250 | @enddefun
|
|---|
| 251 |
|
|---|
| 252 | @defmac[fun {do-alpha-key-events}, args
|
|---|
| 253 | {(@i[var] @i[kind] @optional @i[result]) @mstar<@i[form]>}]
|
|---|
| 254 | This macro evaluates each @i[form] with @i[var] bound to a key-event
|
|---|
| 255 | representing an alphabetic character. @i[Kind] is one of @kwd[lower],
|
|---|
| 256 | @kwd[upper], or @kwd[both], and this binds @i[var] to each key-event in order
|
|---|
| 257 | as specified in @i[X Window System Protocol, MIT X Consortium Standard, X
|
|---|
| 258 | Version 11, Release 4]. When @kwd[both] is specified, this processes lowercase
|
|---|
| 259 | letters first.
|
|---|
| 260 | @enddefmac
|
|---|
| 261 |
|
|---|
| 262 | @defun[fun {print-pretty-key}, args {@i[key] @optional @i[stream] @i[long-names-p]}]
|
|---|
| 263 | This prints @i[key], a key-event or vector of key-events, in a user-expected
|
|---|
| 264 | fashion to @i[stream]. @i[Long-names-p] indicates whether modifiers should
|
|---|
| 265 | print with their long or short name. @i[Stream] defaults to
|
|---|
| 266 | @var[standard-output].
|
|---|
| 267 | @enddefun
|
|---|
| 268 |
|
|---|
| 269 | @defun[fun {print-pretty-key-event}, args {@i[key-event] @optional @i[stream] @i[long-names-p]}]
|
|---|
| 270 | This prints @i[key-event] to @i[stream] in a user-expected fashion.
|
|---|
| 271 | @i[Long-names-p] indicates whether modifier names should appear using the long
|
|---|
| 272 | name or short name. @i[Stream] defaults to @var[standard-output].
|
|---|
| 273 | @enddefun
|
|---|
| 274 |
|
|---|
| 275 |
|
|---|
| 276 |
|
|---|
| 277 | @section (CLX Interface)
|
|---|
| 278 |
|
|---|
| 279 | @subsection (Graphics Window Hooks)
|
|---|
| 280 | This section describes a few hooks used by Hemlock's internals to handle
|
|---|
| 281 | graphics windows that manifest Hemlock windows. Some heavy users of Hemlock as
|
|---|
| 282 | a tool have needed these in the past, but typically functions that replace the
|
|---|
| 283 | default values of these hooks must be written in the "@f[HEMLOCK-INTERNALS]"
|
|---|
| 284 | package. All of these symbols are internal to this package.
|
|---|
| 285 |
|
|---|
| 286 | If you need this level of control for your application, consult the current
|
|---|
| 287 | implementation for code fragments that will be useful in correctly writing your
|
|---|
| 288 | own window hook functions.
|
|---|
| 289 |
|
|---|
| 290 | @defvar[var {create-window-hook}]
|
|---|
| 291 | This holds a function that @Hemlock calls when @f[make-window] executes under
|
|---|
| 292 | CLX. @Hemlock passes the CLX display and the following arguments from
|
|---|
| 293 | @f[make-window]: starting mark, ask-user, x, y, width, height, and modelinep.
|
|---|
| 294 | The function returns a CLX window or nil indicating one could not be made.
|
|---|
| 295 | @enddefvar
|
|---|
| 296 |
|
|---|
| 297 | @defvar[var {delete-window-hook}]
|
|---|
| 298 | This holds a function that @hemlock calls when @f[delete-window] executes under
|
|---|
| 299 | CLX. @hemlock passes the CLX window and the @hemlock window to this function.
|
|---|
| 300 | @enddefvar
|
|---|
| 301 |
|
|---|
| 302 | @defvar[var {random-typeout-hook}]
|
|---|
| 303 | This holds a function that @hemlock calls when random typeout occurs under CLX.
|
|---|
| 304 | @hemlock passes it a @hemlock device, a pre-existing CLX window or @nil, and
|
|---|
| 305 | the number of pixels needed to display the number of lines requested in the
|
|---|
| 306 | @f[with-pop-up-display] form. It should return a window, and if a new window
|
|---|
| 307 | is created, then a CLX gcontext must be the second value.
|
|---|
| 308 | @enddefvar
|
|---|
| 309 |
|
|---|
| 310 | @defvar[var {create-initial-windows-hook}]
|
|---|
| 311 | This holds a function that @hemlock calls when it initializes the screen
|
|---|
| 312 | manager and makes the first windows, typically windows for the @hid[Main] and
|
|---|
| 313 | @hid[Echo Area] buffers. @hemlock passes the function a @hemlock device.
|
|---|
| 314 | @enddefvar
|
|---|
| 315 |
|
|---|
| 316 |
|
|---|
| 317 | @subsection (Entering and Leaving Windows)
|
|---|
| 318 |
|
|---|
| 319 | @defhvar[var "Enter Window Hook"]
|
|---|
| 320 | When the mouse enters an editor window, @hemlock invokes the functions in this
|
|---|
| 321 | hook. These functions take a @Hemlock window as an argument.
|
|---|
| 322 | @enddefhvar
|
|---|
| 323 |
|
|---|
| 324 | @defhvar[var "Exit Window Hook"]
|
|---|
| 325 | When the mouse exits an editor window, @hemlock invokes the functions in this
|
|---|
| 326 | hook. These functions take a @Hemlock window as an argument.
|
|---|
| 327 | @enddefhvar
|
|---|
| 328 |
|
|---|
| 329 |
|
|---|
| 330 | @subsection (How to Lose Up-Events)
|
|---|
| 331 | Often the only useful activity user's design for the mouse is to click on
|
|---|
| 332 | something. @Hemlock sees a character representing the down event, but what do
|
|---|
| 333 | you do with the up event character that you know must follow? Having the
|
|---|
| 334 | command eat it would be tasteless, and would inhibit later customizations that
|
|---|
| 335 | make use of it, possibly adding on to the down click command's functionality.
|
|---|
| 336 | Bind the corresponding up character to the command described here.
|
|---|
| 337 |
|
|---|
| 338 | @defcom[com "Do Nothing"]
|
|---|
| 339 | This does nothing as many times as you tell it.
|
|---|
| 340 | @enddefcom
|
|---|
| 341 |
|
|---|
| 342 |
|
|---|
| 343 | @section (Slave Lisps)
|
|---|
| 344 | @index (Slave lisp interface functions)
|
|---|
| 345 | Some implementations of @hemlock feature the ability to manage multiple slave
|
|---|
| 346 | Lisps, each connected to one editor Lisp. The routines discussed here spawn
|
|---|
| 347 | slaves, send evaluation and compilation requests, return the current server,
|
|---|
| 348 | etc. This is very powerful because without it you can lose your editing state
|
|---|
| 349 | when code you are developing causes a fatal error in Lisp.
|
|---|
| 350 |
|
|---|
| 351 | The routines described in this section are best suited for creating editor
|
|---|
| 352 | commands that interact with slave Lisps, but in the past users implemented
|
|---|
| 353 | several independent Lisps as nodes communicating via these functions. There is
|
|---|
| 354 | a better level on which to write such code that avoids the extra effort these
|
|---|
| 355 | routines take for the editor's sake. See the @i[CMU Common Lisp User's Manual]
|
|---|
| 356 | for the @f[remote] and @f[wire] packages.
|
|---|
| 357 |
|
|---|
| 358 |
|
|---|
| 359 | @subsection (The Current Slave)
|
|---|
| 360 | There is a slave-information structure that these return which is suitable for
|
|---|
| 361 | passing to the routines described in the following subsections.
|
|---|
| 362 |
|
|---|
| 363 | @defun[fun {create-slave}, args {@optional @i[name]}]
|
|---|
| 364 | This creates a slave that tries to connect to the editor. When the slave
|
|---|
| 365 | connects to the editor, this returns a slave-information structure, and the
|
|---|
| 366 | interactive buffer is the buffer named @i[name]. This generates a name if
|
|---|
| 367 | @i[name] is @nil. In case the slave never connects, this will eventually
|
|---|
| 368 | timeout and signal an editor-error.
|
|---|
| 369 | @enddefun
|
|---|
| 370 |
|
|---|
| 371 | @defun[fun {get-current-eval-server}, args {@optional @i[errorp]}]
|
|---|
| 372 | @defhvar1[var {Current Eval Server}]
|
|---|
| 373 | This returns the server-information for the @hid[Current Eval Server] after
|
|---|
| 374 | making sure it is valid. Of course, a slave Lisp can die at anytime. If this
|
|---|
| 375 | variable is @nil, and @i[errorp] is non-@nil, then this signals an
|
|---|
| 376 | editor-error; otherwise, it tries to make a new slave. If there is no current
|
|---|
| 377 | eval server, then this tries to make a new slave, prompting the user based on a
|
|---|
| 378 | few variables (see the @i[Hemlock User's Manual]).
|
|---|
| 379 | @enddefun
|
|---|
| 380 |
|
|---|
| 381 | @defun[fun {get-current-compile-server}]
|
|---|
| 382 | @defhvar1[var {Current Compile Server}]
|
|---|
| 383 | This returns the server-information for the @hid[Current Compile Server] after
|
|---|
| 384 | making sure it is valid. This may return nil. Since multiple slaves may
|
|---|
| 385 | exist, it is convenient to use one for developing code and one for compiling
|
|---|
| 386 | files. The compilation commands that use slave Lisps prefer to use the current
|
|---|
| 387 | compile server but will fall back on the current eval server when necessary.
|
|---|
| 388 | Typically, users only have separate compile servers when the slave Lisp can
|
|---|
| 389 | live on a separate workstation to save cycles on the editor machine, and the
|
|---|
| 390 | @hemlock commands only use this for compiling files.
|
|---|
| 391 | @enddefun
|
|---|
| 392 |
|
|---|
| 393 |
|
|---|
| 394 | @subsection (Asynchronous Operation Queuing)
|
|---|
| 395 | The routines in this section queue requests with an eval server. Requests are
|
|---|
| 396 | always satisfied in order, but these do not wait for notification that the
|
|---|
| 397 | operation actually happened. Because of this, the user can continue editing
|
|---|
| 398 | while his evaluation or compilation occurs. Note, these usually execute in the
|
|---|
| 399 | slave immediately, but if the interactive buffer connected to the slave is
|
|---|
| 400 | waiting for a form to return a value, the operation requested must wait until
|
|---|
| 401 | the slave is free again.
|
|---|
| 402 |
|
|---|
| 403 | @defun[fun {string-eval}, args {@i[string]}, keys {[server][package][context]}]
|
|---|
| 404 | @defun1[fun {region-eval}, args {@i[region]}, keys {[server][package][context]}]
|
|---|
| 405 | @defun1[fun {region-compile}, args {@i[region]}, keys {[server][package]}]
|
|---|
| 406 | @f[string-eval] queues the evaluation of the form read from @i[string] on eval
|
|---|
| 407 | server @i[server]. @i[Server] defaults to the result of
|
|---|
| 408 | @f[get-current-server], and @i[string] is a simple-string. The evaluation
|
|---|
| 409 | occurs with @var[package] bound in the slave to the package named by
|
|---|
| 410 | @i[package], which defaults to @hid[Current Package] or the empty string; the
|
|---|
| 411 | empty string indicates that the slave should evaluate the form in its current
|
|---|
| 412 | package. The slave reads the form in @i[string] within this context as well.
|
|---|
| 413 | @i[Context] is a string to use when reporting start and end notifications in
|
|---|
| 414 | the @hid[Echo Area] buffer; it defaults to the concatenation of @f["evaluation
|
|---|
| 415 | of "] and @i[string].
|
|---|
| 416 |
|
|---|
| 417 | @f[region-eval] is the same as @f[string-eval], but @i[context] defaults
|
|---|
| 418 | differently. If the user leaves this unsupplied, then it becomes a string
|
|---|
| 419 | involving part of the first line of region.
|
|---|
| 420 |
|
|---|
| 421 | @f[region-compile] is the same as the above. @i[Server] defaults the same; it
|
|---|
| 422 | does not default to @f[get-current-compile-server] since this compiles the
|
|---|
| 423 | region into the slave Lisp's environment, to affect what you are currently
|
|---|
| 424 | working on.
|
|---|
| 425 | @enddefun
|
|---|
| 426 |
|
|---|
| 427 | @defun[fun {file-compile}, args {@i[file]},
|
|---|
| 428 | keys {[output-file][error-file][load][server]},
|
|---|
| 429 | morekeys {[package]}]
|
|---|
| 430 | @defhvar1[var {Remote Compile File}, val {nil}]
|
|---|
| 431 | This compiles @i[file] in a slave Lisp. When @i[output-file] is @true (the
|
|---|
| 432 | default), this uses a temporary output file that is publicly writable in case
|
|---|
| 433 | the client is on another machine, which allows for file systems that do not
|
|---|
| 434 | permit remote write access. This renames the temporary file to the appropriate
|
|---|
| 435 | binary name or deletes it after compilation. Setting @hid[Remote Compile File]
|
|---|
| 436 | to @nil, inhibits this. If @i[output-file] is non-@nil and not @true, then it
|
|---|
| 437 | is the name of the binary file to write. The compilation occurs with
|
|---|
| 438 | @var[package] bound in the slave to the package named by @i[package], which
|
|---|
| 439 | defaults to @hid[Current Package] or the empty string; the empty string
|
|---|
| 440 | indicates that the slave should evaluate the form in its current package.
|
|---|
| 441 | @i[Error-file] is the file in which to record compiler output, and a @nil value
|
|---|
| 442 | inhibits this file's creation. @i[Load] indicates whether to load the
|
|---|
| 443 | resulting binary file, defaults to @nil. @i[Server] defaults to
|
|---|
| 444 | @f[get-current-compile-server], but if this returns nil, then @i[server]
|
|---|
| 445 | defaults to @f[get-current-server].
|
|---|
| 446 | @enddefun
|
|---|
| 447 |
|
|---|
| 448 | @subsection (Synchronous Operation Queuing)
|
|---|
| 449 | The routines in this section queue requests with an eval server and wait for
|
|---|
| 450 | confirmation that the evaluation actually occurred. Because of this, the user
|
|---|
| 451 | cannot continue editing while the slave executes the request. Note, these
|
|---|
| 452 | usually execute in the slave immediately, but if the interactive buffer
|
|---|
| 453 | connected to the slave is waiting for a form to return a value, the operation
|
|---|
| 454 | requested must wait until the slave is free again.
|
|---|
| 455 |
|
|---|
| 456 | @defun[fun {eval-form-in-server},
|
|---|
| 457 | args {@i[server-info] @i[string] @optional @i[package]}]
|
|---|
| 458 | This function queues the evaluation of a form in the server associated with
|
|---|
| 459 | @i[server-info] and waits for the results. The server @f[read]'s the form from
|
|---|
| 460 | @i[string] with @var[package] bound to the package named by @i[package]. This
|
|---|
| 461 | returns the results from the slave Lisp in a list of string values. You can
|
|---|
| 462 | @f[read] from the strings or simply display them depending on the @f[print]'ing
|
|---|
| 463 | of the evaluation results.
|
|---|
| 464 |
|
|---|
| 465 | @i[Package] defaults to @hid[Current Package]. If this is @nil, the server
|
|---|
| 466 | uses the value of @var[package] in the server.
|
|---|
| 467 |
|
|---|
| 468 | While the slave executes the form, it binds @var[terminal-io] to a stream that
|
|---|
| 469 | signals errors when read from and dumps output to a bit-bucket. This prevents
|
|---|
| 470 | the editor and slave from dead locking by waiting for each other to reply.
|
|---|
| 471 | @enddefun
|
|---|
| 472 |
|
|---|
| 473 | @defun[fun {eval-form-in-server-1},
|
|---|
| 474 | args {@i[server-info] @i[string] @optional @i[package]}]
|
|---|
| 475 | This function calls @f[eval-form-in-server] and @f[read]'s the result in the
|
|---|
| 476 | first string it returns. This result must be @f[read]'able in the editor's
|
|---|
| 477 | Lisp.
|
|---|
| 478 | @enddefun
|
|---|
| 479 |
|
|---|
| 480 |
|
|---|
| 481 | @section (Spelling)
|
|---|
| 482 | @index (Spelling checking)
|
|---|
| 483 | @hemlock supports spelling checking and correcting commands based on the ITS
|
|---|
| 484 | Ispell dictionary. These commands use the following routines which include
|
|---|
| 485 | adding and deleting entries, reading the Ispell dictionary in a compiled binary
|
|---|
| 486 | format, reading user dictionary files in a text format, and checking and
|
|---|
| 487 | correcting possible spellings.
|
|---|
| 488 |
|
|---|
| 489 | @defun[fun {maybe-read-spell-dictionary}, package {spell}]
|
|---|
| 490 | This reads the default binary Ispell dictionary. Users must call this before
|
|---|
| 491 | the following routines will work.
|
|---|
| 492 | @enddefun
|
|---|
| 493 |
|
|---|
| 494 | @defun[fun {spell-read-dictionary}, package {spell}, args {@i[filename]}]
|
|---|
| 495 | This adds entries to the dictionary from the lines in the file @i[filename].
|
|---|
| 496 | Dictionary files contain line oriented records like the following:
|
|---|
| 497 | @begin[programexample]
|
|---|
| 498 | entry1/flag1/flag2
|
|---|
| 499 | entry2
|
|---|
| 500 | entry3/flag1
|
|---|
| 501 | @end[programexample]
|
|---|
| 502 | The flags are the Ispell flags indicating which endings are appropriate for the
|
|---|
| 503 | given entry root, but these are unnecessary for user dictionary files. You can
|
|---|
| 504 | consult Ispell documentation if you want to know more about them.
|
|---|
| 505 | @enddefun
|
|---|
| 506 |
|
|---|
| 507 | @defun[fun {spell-add-entry}, package {spell},
|
|---|
| 508 | args {@i[line] @optional @i[word-end]}]
|
|---|
| 509 | This takes a line from a dictionary file, and adds the entry described by
|
|---|
| 510 | @i[line] to the dictionary. @i[Word-end] defaults to the position of the first
|
|---|
| 511 | slash character or the length of the line. @i[Line] is destructively modified.
|
|---|
| 512 | @enddefun
|
|---|
| 513 |
|
|---|
| 514 | @defun[fun {spell-remove-entry}, package {spell}, args {@i[entry]}]
|
|---|
| 515 | This removes entry, a simple-string, from the dictionary, so it will be an
|
|---|
| 516 | unknown word. This destructively modifies @i[entry]. If it is a root word,
|
|---|
| 517 | then all words derived with @i[entry] and its flags will also be deleted. If
|
|---|
| 518 | @i[entry] is a word derived from some root word, then the root and any words
|
|---|
| 519 | derived from it remain known words.
|
|---|
| 520 | @enddefun
|
|---|
| 521 |
|
|---|
| 522 | @defun[fun {correct-spelling}, package {spell}, args {@i[word]}]
|
|---|
| 523 | This checks the spelling of @i[word] and outputs the results. If this finds
|
|---|
| 524 | @i[word] is correctly spelled due to some appropriate suffix on a root, it
|
|---|
| 525 | generates output indicating this. If this finds @i[word] as a root entry, it
|
|---|
| 526 | simply outputs that it found @i[word]. If this cannot find @i[word] at all,
|
|---|
| 527 | then it outputs possibly correct close spellings. This writes to
|
|---|
| 528 | @var[standard-output], and it calls @f[maybe-read-spell-dictionary] before
|
|---|
| 529 | attempting any lookups.
|
|---|
| 530 | @enddefun
|
|---|
| 531 |
|
|---|
| 532 | @defun[fun {spell-try-word}, package {spell}, args {@i[word] @i[word-len]}]
|
|---|
| 533 | @defcon1[var {max-entry-length}, val {31}]
|
|---|
| 534 | This returns an index into the dictionary if it finds @i[word] or an
|
|---|
| 535 | appropriate root. @i[Word-len] must be inclusively in the range 2 through
|
|---|
| 536 | @f[max-entry-length], and it is the length of @i[word]. @i[Word] must be
|
|---|
| 537 | uppercase. This returns a second value indicating whether it found @i[word]
|
|---|
| 538 | due to a suffix flag, @nil if @i[word] is a root entry.
|
|---|
| 539 | @enddefun
|
|---|
| 540 |
|
|---|
| 541 | @defun[fun {spell-root-word}, package {spell}, args {@i[index]}]
|
|---|
| 542 | This returns a copy of the root word at dictionary entry @i[index]. This index
|
|---|
| 543 | is the same as returned by @f[spell-try-word].
|
|---|
| 544 | @enddefun
|
|---|
| 545 |
|
|---|
| 546 | @defun[fun {spell-collect-close-words}, package {spell}, args {@i[word]}]
|
|---|
| 547 | This returns a list of words correctly spelled that are @i[close] to @i[word].
|
|---|
| 548 | @i[Word] must be uppercase, and its length must be inclusively in the range 2
|
|---|
| 549 | through @f[max-entry-length]. Close words are determined by the Ispell rules:
|
|---|
| 550 | @begin[enumerate]
|
|---|
| 551 | Two adjacent letters can be transposed to form a correct spelling.
|
|---|
| 552 |
|
|---|
| 553 | One letter can be changed to form a correct spelling.
|
|---|
| 554 |
|
|---|
| 555 | One letter can be added to form a correct spelling.
|
|---|
| 556 |
|
|---|
| 557 | One letter can be removed to form a correct spelling.
|
|---|
| 558 | @end[enumerate]
|
|---|
| 559 | @enddefun
|
|---|
| 560 |
|
|---|
| 561 | @defun[fun {spell-root-flags}, package {spell}, args {@i[index]}]
|
|---|
| 562 | This returns a list of suffix flags as capital letters that apply to the
|
|---|
| 563 | dictionary root entry at @i[index]. This index is the same as returned by
|
|---|
| 564 | @f[spell-try-word].
|
|---|
| 565 | @enddefun
|
|---|
| 566 |
|
|---|
| 567 |
|
|---|
| 568 | @section (File Utilities)
|
|---|
| 569 | Some implementations of @hemlock provide extensive directory editing commands,
|
|---|
| 570 | @hid[Dired], including a single wildcard feature. An asterisk denotes a
|
|---|
| 571 | wildcard.
|
|---|
| 572 |
|
|---|
| 573 | @defun[fun {copy-file}, package {dired},
|
|---|
| 574 | args {@i[spec1] @i[spec2]}, keys {[update][clobber][directory]}]
|
|---|
| 575 | This function copies @i[spec1] to @i[spec2]. It accepts a single wildcard in
|
|---|
| 576 | the filename portion of the specification, and it accepts directories. This
|
|---|
| 577 | copies files maintaining the source's write date.
|
|---|
| 578 |
|
|---|
| 579 | If @i[spec1] and @i[spec2] are both directories, this recursively copies the
|
|---|
| 580 | files and subdirectory structure of @i[spec1]; if @i[spec2] is in the
|
|---|
| 581 | subdirectory structure of @i[spec1], the recursion will not descend into it.
|
|---|
| 582 | Use @f["/spec1/*"] to copy only the files from @i[spec1] to directory
|
|---|
| 583 | @i[spec2].
|
|---|
| 584 |
|
|---|
| 585 | If @i[spec2] is a directory, and @i[spec1] is a file, then this copies
|
|---|
| 586 | @i[spec1] into @i[spec2] with the same @f[pathname-name].
|
|---|
| 587 |
|
|---|
| 588 | When @kwd[update] is non-@nil, then the copying process only copies files if the
|
|---|
| 589 | source is newer than the destination.
|
|---|
| 590 |
|
|---|
| 591 | When @kwd[update] and @kwd[clobber] are @nil, and the destination exists, the
|
|---|
| 592 | copying process stops and asks the user whether the destination should be
|
|---|
| 593 | overwritten.
|
|---|
| 594 |
|
|---|
| 595 | When the user supplies @kwd[directory], it is a list of pathnames, directories
|
|---|
| 596 | excluded, and @i[spec1] is a pattern containing one wildcard. This then copies
|
|---|
| 597 | each of the pathnames whose @f[pathname-name] matches the pattern. @i[Spec2]
|
|---|
| 598 | is either a directory or a pathname whose @f[pathname-name] contains a
|
|---|
| 599 | wildcard.
|
|---|
| 600 | @enddefun
|
|---|
| 601 |
|
|---|
| 602 | @defun[fun {rename-file}, package {dired},
|
|---|
| 603 | args {@i[spec1] @i[spec2]}, keys {[clobber][directory]}]
|
|---|
| 604 | This function renames @i[spec1] to @i[spec2]. It accepts a single wildcard in
|
|---|
| 605 | the filename portion of the specification, and @i[spec2] may be a directory
|
|---|
| 606 | with the destination specification resulting in the merging of @i[spec2] with
|
|---|
| 607 | @i[spec1]. If @kwd[clobber] is @nil, and @i[spec2] exists, then this asks the
|
|---|
| 608 | user to confirm the renaming. When renaming a directory, end the specification
|
|---|
| 609 | without the trailing slash.
|
|---|
| 610 |
|
|---|
| 611 | When the user supplies @kwd[directory], it is a list of pathnames, directories
|
|---|
| 612 | excluded, and @i[spec1] is a pattern containing one wildcard. This then copies
|
|---|
| 613 | each of the pathnames whose @f[pathname-name] matches the pattern. @i[Spec2]
|
|---|
| 614 | is either a directory or a pathname whose @f[pathname-name] contains a
|
|---|
| 615 | wildcard.
|
|---|
| 616 | @enddefun
|
|---|
| 617 |
|
|---|
| 618 | @defun[fun {delete-file}, package {dired},
|
|---|
| 619 | args {@i[spec]}, keys {[recursive][clobber]}]
|
|---|
| 620 | This function deletes @i[spec]. It accepts a single wildcard in the filename
|
|---|
| 621 | portion of the specification, and it asks for confirmation on each file if
|
|---|
| 622 | @kwd[clobber] is @nil. If @kwd[recursive] is non-@nil, then @i[spec] may be a
|
|---|
| 623 | directory to recursively delete the entirety of the directory and its
|
|---|
| 624 | subdirectory structure. An empty directory may be specified without
|
|---|
| 625 | @kwd[recursive] being non-@nil. Specify directories with the trailing
|
|---|
| 626 | slash.
|
|---|
| 627 | @enddefun
|
|---|
| 628 |
|
|---|
| 629 | @defun[fun {find-file}, package {dired},
|
|---|
| 630 | args {@i[name] @optional @i[directory] @i[find-all]}]
|
|---|
| 631 | This function finds the file with @f[file-namestring] @i[name], recursively
|
|---|
| 632 | looking in @i[directory]. If @i[find-all] is non-@nil (defaults to @nil), then
|
|---|
| 633 | this continues searching even after finding a first occurrence of file.
|
|---|
| 634 | @i[Name] may contain a single wildcard, which causes @i[find-all] to default to
|
|---|
| 635 | @true instead of @nil.
|
|---|
| 636 | @enddefun
|
|---|
| 637 |
|
|---|
| 638 | @defun[fun {make-directory}, package {dired}, args {@i[name]}]
|
|---|
| 639 | This function creates the directory with @i[name]. If it already exists, this
|
|---|
| 640 | signals an error.
|
|---|
| 641 | @enddefun
|
|---|
| 642 |
|
|---|
| 643 | @defun[fun {pathnames-from-pattern}, package {dired},
|
|---|
| 644 | args {@i[pattern] @i[files]}]
|
|---|
| 645 | This function returns a list of pathnames from the list @i[files] whose
|
|---|
| 646 | @f[file-namestring]'s match @i[pattern]. @i[Pattern] must be a non-empty
|
|---|
| 647 | string and contain only one asterisk. @i[Files] contains no directories.
|
|---|
| 648 | @enddefun
|
|---|
| 649 |
|
|---|
| 650 | @defvar[var {update-default}, package {dired}]
|
|---|
| 651 | @defvar1[var {clobber-default}, package {dired}]
|
|---|
| 652 | @defvar1[var {recursive-default}, package {dired}]
|
|---|
| 653 | These are the default values for the keyword arguments above with corresponding
|
|---|
| 654 | names. These default to @nil, @true, and @nil respectively.
|
|---|
| 655 | @enddefvar
|
|---|
| 656 |
|
|---|
| 657 | @defvar[var {report-function}, package {dired}]
|
|---|
| 658 | @defvar1[var {error-function}, package {dired}]
|
|---|
| 659 | @defvar1[var {yesp-function}, package {dired}]
|
|---|
| 660 | These are the function the above routines call to report progress, signal
|
|---|
| 661 | errors, and prompt for @i[yes] or @i[no]. These all take format strings and
|
|---|
| 662 | arguments.
|
|---|
| 663 | @enddefvar
|
|---|
| 664 |
|
|---|
| 665 |
|
|---|
| 666 | @defun[fun {merge-relative-pathnames}, args {@i[pathname] @i[default-directory]}]
|
|---|
| 667 | This function merges @i[pathname] with @i[default-directory]. If @i[pathname]
|
|---|
| 668 | is not absolute, this assumes it is relative to @i[default-directory]. The
|
|---|
| 669 | result is always a directory pathname.
|
|---|
| 670 | @enddefun
|
|---|
| 671 |
|
|---|
| 672 | @defun[fun {directoryp}, args {@i[pathname]}]
|
|---|
| 673 | This function returns whether @i[pathname] names a directory: it has no name
|
|---|
| 674 | and no type fields.
|
|---|
| 675 | @enddefun
|
|---|
| 676 |
|
|---|
| 677 |
|
|---|
| 678 | @section (Beeping)
|
|---|
| 679 |
|
|---|
| 680 | @defun[fun {hemlock-beep}]
|
|---|
| 681 | @Hemlock binds @f[system:*beep-function*] to this function to beep the device.
|
|---|
| 682 | It is different for different devices.
|
|---|
| 683 | @enddefun
|
|---|
| 684 |
|
|---|
| 685 | @defhvar[var "Bell Style", val {:border-flash}]
|
|---|
| 686 | @defhvar1[var "Beep Border Width", val {20}]
|
|---|
| 687 | @hid[Bell Style] determines what @var[hemlock-beep] does in @hemlock under CLX.
|
|---|
| 688 | Acceptable values are @kwd[border-flash], @kwd[feep],
|
|---|
| 689 | @kwd[border-flash-and-feep], @kwd[flash], @kwd[flash-and-feep], and @nil (do
|
|---|
| 690 | nothing).
|
|---|
| 691 |
|
|---|
| 692 | @hid[Beep Border Width] is the width in pixels of the border flashed by border
|
|---|
| 693 | flash beep styles.
|
|---|
| 694 | @enddefhvar
|
|---|