Changes between Initial Version and Version 1 of HemlockProgrammer/AuxiliarySystems

11/05/07 15:49:21 (9 years ago)



  • HemlockProgrammer/AuxiliarySystems

    v1 v1  
     3= 18. Auxiliary Systems = 
     5This chapter describes utilities that some implementations 
     6of Hemlock may leave unprovided or unsupported. 
     8== 18.1. Key-events == 
     10These routines are defined in the "EXTENSIONS" package since other 
     11projects have often used Hemlock's input translations for interfacing 
     12to CLX. 
     14=== 18.1.1. Introduction === 
     16The canonical representation of editor input is a key-event 
     17structure. Users can bind commands to keys (see section 1.3.1), which 
     18are non-zero length sequences of key-events. A key-event consists of 
     19an identifying token known as a keysym and a field of bits 
     20representing modifiers. Users define keysyms, integers between 0 and 
     2165535 inclusively, by supplying names that reflect the legends on 
     22their keyboard's keys. Users define modifier names similarly, but the 
     23system chooses the bit and mask for recognizing the modifier. You can 
     24use keysym and modifier names to textually specify key-events and 
     25Hemlock keys in a #k syntax. The following are some examples: 
     30#k"control-x meta-d" 
     36This is convenient for use within code and in init files containing 
     37bind-key calls. 
     39The #k syntax is delimited by double quotes, but the system parses the 
     40contents rather than reading it as a Common Lisp string. Within the 
     41double quotes, spaces separate multiple key-events. A single key-event 
     42optionally starts with modifier names terminated by hyphens. Modifier 
     43names are alphabetic sequences of characters which the system uses 
     44case-insensitively. Following modifiers is a keysym name, which is 
     45case-insensitive if it consists of multiple characters, but if the 
     46name consists of only a single character, then it is case-sensitive. 
     48You can escape special characters---hyphen, double quote, open angle 
     49bracket, close angle bracket, and space---with a backslash, and you 
     50can specify a backslash by using two contiguously. You can use angle 
     51brackets to enclose a keysym name with many special characters in 
     52it. Between angle brackets appearing in a keysym name position, there 
     53are only two special characters, the closing angle bracket and 
     56=== 18.1.2. Interface === 
     58All of the following routines and variables are exported from the 
     59"EXTENSIONS" ("EXT") package. 
     61define-keysym   keysym preferred-name &rest other-names  [Function] 
     63This function establishes a mapping from preferred-name to keysym for 
     64purposes of #k syntax. Other-names also map to keysym, but the system 
     65uses preferred-name when printing key-events. The names are 
     66case-insensitive simple-strings; however, if the string contains a 
     67single character, then it is used case-sensitively. Redefining a 
     68keysym or re-using names has undefined effects. 
     70You can use this to define unused keysyms, but primarily this defines 
     71keysyms defined in the X Window System Protocol, MIT X Consortium 
     72Standard, X Version 11, Release 4. translate-key-event uses this 
     73knowledge to determine what keysyms are modifier keysyms and what 
     74keysym stand for alphabetic key-events. 
     78define-mouse-keysym     button keysym name shifted-bit event-key         [Function] 
     80This function defines keysym named name for key-events representing 
     81the X button cross the X event-key (:button-press or 
     82:button-release). Shifted-bit is a defined modifier name that 
     83translate-mouse-key-event sets in the key-event it returns whenever 
     84the X shift bit is set in an incoming event. 
     86Note, by default, there are distinct keysyms for each button 
     87distinguishing whether the user pressed or released the button. 
     89Keysym should be an one unspecified in X Window System Protocol, MIT X 
     90Consortium Standard, X Version 11, Release 4. 
     94name-keysym     name     [Function] 
     96This function returns the keysym named name. If name is unknown, this 
     97returns nil. 
     101keysym-names    keysym   [Function] 
     103This function returns the list of all names for keysym. If keysym is 
     104undefined, this returns nil. 
     108keysym-preferred-name   keysym   [Function] 
     110This returns the preferred name for keysym, how it is typically 
     111printed. If keysym is undefined, this returns nil. 
     115define-key-event-modifier       long-name short-name     [Function] 
     117This establishes long-name and short-name as modifier names for 
     118purposes of specifying key-events in #k syntax. The names are 
     119case-insensitive simple-strings. If either name is already defined, 
     120this signals an error. 
     122The system defines the following default modifiers (first the long 
     123name, then the short name): 
     125 * "Hyper", "H" 
     126 * "Super", "S" 
     127 * "Meta", "M" 
     128 * "Control", "C" 
     129 * "Shift", "Shift" 
     130 * "Lock", "Lock" 
     133all-modifier-names               [Variable] 
     135This variable holds all the defined modifier names. 
     139define-clx-modifier     clx-mask modifier-name   [Function] 
     141This function establishes a mapping from clx-mask to a defined 
     142key-event modifier-name. translate-key-event and 
     143translate-mouse-key-event can only return key-events with bits defined 
     144by this routine. 
     146The system defines the following default mappings between CLX 
     147modifiers and key-event modifiers: 
     149 * (xlib:make-state-mask :mod-1) --> "Meta" 
     150 * (xlib:make-state-mask :control) --> "Control" 
     151 * (xlib:make-state-mask :lock) --> "Lock" 
     152 * (xlib:make-state-mask :shift) --> "Shift" 
     155make-key-event-bits     &rest modifier-names     [Function] 
     157This function returns bits suitable for make-key-event from the 
     158supplied modifier-names. If any name is undefined, this signals an 
     163key-event-modifier-mask         modifier-name    [Function] 
     165This function returns a mask for modifier-name. This mask is suitable 
     166for use with key-event-bits. If modifier-name is undefined, this 
     167signals an error. 
     171key-event-bits-modifiers        bits     [Function] 
     173This returns a list of key-event modifier names, one for each modifier 
     174set in bits. 
     178translate-key-event     display scan-code bits   [Function] 
     180This function translates the X scan-code and X bits to a 
     181key-event. First this maps scan-code to an X keysym using 
     182xlib:keycode->keysym looking at bits and supplying index as 1 if the X 
     183shift bit is on, 0 otherwise. 
     185If the resulting keysym is undefined, and it is not a modifier keysym, 
     186then this signals an error. If the keysym is a modifier key, then this 
     187returns nil. 
     189If these conditions are satisfied 
     191 * The keysym is defined. 
     192 * The X shift bit is off. 
     193 * The X lock bit is on. 
     194 * The X keysym represents a lowercase letter. 
     196then this maps the scan-code again supplying index as 1 this time, 
     197treating the X lock bit as a caps-lock bit. If this results in an 
     198undefined keysym, this signals an error. Otherwise, this makes a 
     199key-event with the keysym and bits formed by mapping the X bits to 
     200key-event bits. 
     202Otherwise, this makes a key-event with the keysym and bits formed by 
     203mapping the X bits to key-event bits. 
     207translate-mouse-key-event       scan-code bits event-key         [Function] 
     209This function translates the X button code, scan-code, and modifier 
     210bits, bits, for the X event-key into a key-event. See 
     215make-key-event          object bits      [Function] 
     217This function returns a key-event described by object with 
     218bits. Object is one of keysym, string, or key-event. When object is a 
     219key-event, this uses key-event-keysym. You can form bits with 
     220make-key-event-bits or key-event-modifier-mask. 
     224key-event-p     object   [Function] 
     226This function returns whether object is a key-event. 
     230key-event-bits          key-event        [Function] 
     232This function returns the bits field of a key-event. 
     236key-event-keysym        key-event        [Function] 
     238This function returns the keysym field of a key-event. 
     242char-key-event          character        [Function] 
     244This function returns the key-event associated with character. You can 
     245associate a key-event with a character by setf-ing this form. 
     249key-event-char          key-event        [Function] 
     251This function returns the character associated with key-event. You can 
     252associate a character with a key-event by setf'ing this form. The 
     253system defaultly translates key-events in some implementation 
     254dependent way for text insertion; for example, under an ASCII system, 
     255the key-event #k"C-h", as well as #k"backspace" would map to the 
     256Common Lisp character that causes a backspace. 
     260key-event-bit-p         key-event bit-name       [Function] 
     262This function returns whether key-event has the bit set named by 
     263bit-name. This signals an error if bit-name is undefined. 
     267do-alpha-key-events     (var kind &optional result) form         [Macro] 
     269This macro evaluates each form with var bound to a key-event 
     270representing an alphabetic character. Kind is one of :lower, :upper, 
     271or :both, and this binds var to each key-event in order as specified 
     272in X Window System Protocol, MIT X Consortium Standard, X Version 11, 
     273Release 4. When :both is specified, this processes lowercase letters 
     278print-pretty-key        key &optional stream long-names-p        [Function] 
     280This prints key, a key-event or vector of key-events, in a 
     281user-expected fashion to stream. Long-names-p indicates whether 
     282modifiers should print with their long or short name. Stream defaults 
     283to standard-output. 
     287print-pretty-key-event          key-event &optional stream long-names-p  [Function] 
     289This prints key-event to stream in a user-expected 
     290fashion. Long-names-p indicates whether modifier names should appear 
     291using the long name or short name. Stream defaults to standard-output. 
     295== 18.2. CLX Interface == 
     297=== 18.2.1. Graphics Window Hooks === 
     299This section describes a few hooks used by Hemlock's internals to 
     300handle graphics windows that manifest Hemlock windows. Some heavy 
     301users of Hemlock as a tool have needed these in the past, but 
     302typically functions that replace the default values of these hooks 
     303must be written in the "HEMLOCK-INTERNALS" package. All of these 
     304symbols are internal to this package. 
     306If you need this level of control for your application, consult the 
     307current implementation for code fragments that will be useful in 
     308correctly writing your own window hook functions. 
     310create-window-hook               [Variable] 
     312This holds a function that Hemlock calls when make-window executes 
     313under CLX. Hemlock passes the CLX display and the following arguments 
     314from make-window: starting mark, ask-user, x, y, width, height, and 
     315modelinep. The function returns a CLX window or nil indicating one 
     316could not be made. 
     320delete-window-hook               [Variable] 
     322This holds a function that Hemlock calls when delete-window executes 
     323under CLX. Hemlock passes the CLX window and the Hemlock window to 
     324this function. 
     328random-typeout-hook              [Variable] 
     330This holds a function that Hemlock calls when random typeout occurs 
     331under CLX. Hemlock passes it a Hemlock device, a pre-existing CLX 
     332window or nil, and the number of pixels needed to display the number 
     333of lines requested in the with-pop-up-display form. It should return a 
     334window, and if a new window is created, then a CLX gcontext must be 
     335the second value. 
     339create-initial-windows-hook              [Variable] 
     341This holds a function that Hemlock calls when it initializes the 
     342screen manager and makes the first windows, typically windows for the 
     343Main and Echo Area buffers. Hemlock passes the function a Hemlock 
     348=== 18.2.2. Entering and Leaving Windows === 
     350Enter Window Hook       (initial value )         [Variable] 
     352When the mouse enters an editor window, Hemlock invokes the functions 
     353in this hook. These functions take a Hemlock window as an argument. 
     357Exit Window Hook        (initial value )         [Variable] 
     359When the mouse exits an editor window, Hemlock invokes the functions 
     360in this hook. These functions take a Hemlock window as an argument. 
     364=== 18.2.3 How to Lose Up-Events === 
     366Often the only useful activity user's design for the mouse is to click 
     367on something. Hemlock sees a character representing the down event, 
     368but what do you do with the up event character that you know must 
     369follow? Having the command eat it would be tasteless, and would 
     370inhibit later customizations that make use of it, possibly adding on 
     371to the down click command's functionality. Bind the corresponding up 
     372character to the command described here. 
     374Do Nothing               [Command] 
     376This does nothing as many times as you tell it. 
     380== 18.3 Slave Lisps == 
     382Some implementations of Hemlock feature the ability to manage multiple 
     383slave Lisps, each connected to one editor Lisp. The routines discussed 
     384here spawn slaves, send evaluation and compilation requests, return 
     385the current server, etc. This is very powerful because without it you 
     386can lose your editing state when code you are developing causes a 
     387fatal error in Lisp. 
     389The routines described in this section are best suited for creating 
     390editor commands that interact with slave Lisps, but in the past users 
     391implemented several independent Lisps as nodes communicating via these 
     392functions. There is a better level on which to write such code that 
     393avoids the extra effort these routines take for the editor's sake. See 
     394the CMU Common Lisp User's Manual for the remote and wire packages. 
     396=== 18.3.1 The Current Slave === 
     398There is a slave-information structure that these return which is 
     399suitable for passing to the routines described in the following 
     402create-slave    &optional name   [Function] 
     404This creates a slave that tries to connect to the editor. When the 
     405slave connects to the editor, this returns a slave-information 
     406structure, and the interactive buffer is the buffer named name. This 
     407generates a name if name is nil. In case the slave never connects, 
     408this will eventually timeout and signal an editor-error. 
     412get-current-eval-server         &optional errorp         [Function] 
     414Current Eval Server     (initial value )         [Variable] 
     416This returns the server-information for the Current Eval Server after 
     417making sure it is valid. Of course, a slave Lisp can die at 
     418anytime. If this variable is nil, and errorp is non-nil, then this 
     419signals an editor-error; otherwise, it tries to make a new slave. If 
     420there is no current eval server, then this tries to make a new slave, 
     421prompting the user based on a few variables (see the Hemlock User's 
     425get-current-compile-server               [Function] 
     427Current Compile Server          (initial value )         [Variable] 
     429This returns the server-information for the Current Compile Server 
     430after making sure it is valid. This may return nil. Since multiple 
     431slaves may exist, it is convenient to use one for developing code and 
     432one for compiling files. The compilation commands that use slave Lisps 
     433prefer to use the current compile server but will fall back on the 
     434current eval server when necessary. Typically, users only have 
     435separate compile servers when the slave Lisp can live on a separate 
     436workstation to save cycles on the editor machine, and the Hemlock 
     437commands only use this for compiling files. 
     441=== 18.3.2 Asynchronous Operation Queuing === 
     443The routines in this section queue requests with an eval 
     444server. Requests are always satisfied in order, but these do not wait 
     445for notification that the operation actually happened. Because of 
     446this, the user can continue editing while his evaluation or 
     447compilation occurs. Note, these usually execute in the slave 
     448immediately, but if the interactive buffer connected to the slave is 
     449waiting for a form to return a value, the operation requested must 
     450wait until the slave is free again. 
     452string-eval     string   [Function] 
     454region-eval     region   [Function] 
     456region-compile          region   [Function] 
     458string-eval queues the evaluation of the form read from string on eval 
     459server server. Server defaults to the result of get-current-server, 
     460and string is a simple-string. The evaluation occurs with package 
     461bound in the slave to the package named by package, which defaults to 
     462Current Package or the empty string; the empty string indicates that 
     463the slave should evaluate the form in its current package. The slave 
     464reads the form in string within this context as well. Context is a 
     465string to use when reporting start and end notifications in the Echo 
     466Area buffer; it defaults to the concatenation of "evaluation of " and 
     469region-eval is the same as string-eval, but context defaults 
     470differently. If the user leaves this unsupplied, then it becomes a 
     471string involving part of the first line of region. 
     473region-compile is the same as the above. Server defaults the same; it 
     474does not default to get-current-compile-server since this compiles the 
     475region into the slave Lisp's environment, to affect what you are 
     476currently working on. 
     480file-compile    file     [Function] 
     482Remote Compile File     (initial value nil)      [Variable] 
     484This compiles file in a slave Lisp. When output-file is t, this uses a 
     485temporary output file that is publicly writable in case the client is 
     486on another machine, which allows for file systems that do not permit 
     487remote write access. This renames the temporary file to the 
     488appropriate binary name or deletes it after compilation. Setting 
     489Remote Compile File to nil, inhibits this. If output-file is non-nil 
     490and not t, then it is the name of the binary file to write. The 
     491compilation occurs with package bound in the slave to the package 
     492named by package, which defaults to Current Package or the empty 
     493string; the empty string indicates that the slave should evaluate the 
     494form in its current package. Error-file is the file in which to record 
     495compiler output, and a nil value inhibits this file's creation. Load 
     496indicates whether to load the resulting binary file, defaults to 
     497nil. Server defaults to get-current-compile-server, but if this 
     498returns nil, then server defaults to get-current-server. 
     502=== 18.3.3. Synchronous Operation Queuing === 
     504The routines in this section queue requests with an eval server and 
     505wait for confirmation that the evaluation actually occurred. Because 
     506of this, the user cannot continue editing while the slave executes the 
     507request. Note, these usually execute in the slave immediately, but if 
     508the interactive buffer connected to the slave is waiting for a form to 
     509return a value, the operation requested must wait until the slave is 
     510free again. 
     512eval-form-in-server     server-info string &optional package     [Function] 
     514This function queues the evaluation of a form in the server associated 
     515with server-info and waits for the results. The server read's the form 
     516from string with package bound to the package named by package. This 
     517returns the results from the slave Lisp in a list of string 
     518values. You can read from the strings or simply display them depending 
     519on the print'ing of the evaluation results. 
     521Package defaults to Current Package. If this is nil, the server uses 
     522the value of package in the server. 
     524While the slave executes the form, it binds terminal-io to a stream 
     525that signals errors when read from and dumps output to a 
     526bit-bucket. This prevents the editor and slave from dead locking by 
     527waiting for each other to reply. 
     531eval-form-in-server-1   server-info string &optional package     [Function] 
     533This function calls eval-form-in-server and read's the result in the 
     534first string it returns. This result must be read'able in the editor's 
     539== 18.4. Spelling== 
     541Hemlock supports spelling checking and correcting commands based on 
     542the ITS Ispell dictionary. These commands use the following routines 
     543which include adding and deleting entries, reading the Ispell 
     544dictionary in a compiled binary format, reading user dictionary files 
     545in a text format, and checking and correcting possible spellings. 
     547spell:maybe-read-spell-dictionary                [Function] 
     549This reads the default binary Ispell dictionary. Users must call this 
     550before the following routines will work. 
     554spell:spell-read-dictionary     filename         [Function] 
     556This adds entries to the dictionary from the lines in the file 
     557filename. Dictionary files contain line oriented records like the 
     565The flags are the Ispell flags indicating which endings are 
     566appropriate for the given entry root, but these are unnecessary for 
     567user dictionary files. You can consult Ispell documentation if you 
     568want to know more about them. 
     572spell:spell-add-entry   line &optional word-end  [Function] 
     574This takes a line from a dictionary file, and adds the entry described 
     575by line to the dictionary. Word-end defaults to the position of the 
     576first slash character or the length of the line. Line is destructively 
     581spell-remove-entry      entry    [Function] 
     583This removes entry, a simple-string, from the dictionary, so it will 
     584be an unknown word. This destructively modifies entry. If it is a root 
     585word, then all words derived with entry and its flags will also be 
     586deleted. If entry is a word derived from some root word, then the root 
     587and any words derived from it remain known words. 
     591spell:correct-spelling          word     [Function] 
     593This checks the spelling of word and outputs the results. If this 
     594finds word is correctly spelled due to some appropriate suffix on a 
     595root, it generates output indicating this. If this finds word as a 
     596root entry, it simply outputs that it found word. If this cannot find 
     597word at all, then it outputs possibly correct close spellings. This 
     598writes to standard-output, and it calls maybe-read-spell-dictionary 
     599before attempting any lookups. 
     603spell:spell-try-word    word word-len    [Function] 
     605max-entry-length                 [Constant] 
     607This returns an index into the dictionary if it finds word or an 
     608appropriate root. Word-len must be inclusively in the range 2 through 
     609max-entry-length, and it is the length of word. Word must be 
     610uppercase. This returns a second value indicating whether it found 
     611word due to a suffix flag, nil if word is a root entry. 
     615spell:spell-root-word   index    [Function] 
     617This returns a copy of the root word at dictionary entry index. This 
     618index is the same as returned by spell-try-word. 
     622spell:spell-collect-close-words         word     [Function] 
     624This returns a list of words correctly spelled that are close to 
     625word. Word must be uppercase, and its length must be inclusively in 
     626the range 2 through max-entry-length. Close words are determined by 
     627the Ispell rules: 
     629 1. Two adjacent letters can be transposed to form a correct spelling. 
     630 2. One letter can be changed to form a correct spelling. 
     631 3. One letter can be added to form a correct spelling. 
     632 4. One letter can be removed to form a correct spelling. 
     635spell:spell-root-flags          index    [Function] 
     637This returns a list of suffix flags as capital letters that apply to 
     638the dictionary root entry at index. This index is the same as returned 
     639by spell-try-word. 
     642== 18.5. File Utilities == 
     644Some implementations of Hemlock provide extensive directory editing 
     645commands, Dired, including a single wildcard feature. An asterisk 
     646denotes a wildcard. 
     648dired:copy-file         spec1 spec2 &key :update :clobber :directory     [Function] 
     650This function copies spec1 to spec2. It accepts a single wildcard in 
     651the filename portion of the specification, and it accepts 
     652directories. This copies files maintaining the source's write date. 
     654If spec1 and spec2 are both directories, this recursively copies the 
     655files and subdirectory structure of spec1; if spec2 is in the 
     656subdirectory structure of spec1, the recursion will not descend into 
     657it. Use "/spec1/*" to copy only the files from spec1 to directory 
     660If spec2 is a directory, and spec1 is a file, then this copies spec1 
     661into spec2 with the same pathname-name. 
     663When :update is non-nil, then the copying process only copies files if 
     664the source is newer than the destination. 
     666When :update and :clobber are nil, and the destination exists, the 
     667copying process stops and asks the user whether the destination should 
     668be overwritten. 
     670When the user supplies :directory, it is a list of pathnames, 
     671directories excluded, and spec1 is a pattern containing one 
     672wildcard. This then copies each of the pathnames whose pathname-name 
     673matches the pattern. Spec2 is either a directory or a pathname whose 
     674pathname-name contains a wildcard. 
     678dired:rename-file       spec1 spec2 &key :clobber :directory     [Function] 
     680This function renames spec1 to spec2. It accepts a single wildcard in 
     681the filename portion of the specification, and spec2 may be a 
     682directory with the destination specification resulting in the merging 
     683of spec2 with spec1. If :clobber is nil, and spec2 exists, then this 
     684asks the user to confirm the renaming. When renaming a directory, end 
     685the specification without the trailing slash. 
     687When the user supplies :directory, it is a list of pathnames, 
     688directories excluded, and spec1 is a pattern containing one 
     689wildcard. This then copies each of the pathnames whose pathname-name 
     690matches the pattern. Spec2 is either a directory or a pathname whose 
     691pathname-name contains a wildcard. 
     695dired:delete-file       spec &key :recursive :clobber    [Function] 
     697This function deletes spec. It accepts a single wildcard in the 
     698filename portion of the specification, and it asks for confirmation on 
     699each file if :clobber is nil. If :recursive is non-nil, then spec may 
     700be a directory to recursively delete the entirety of the directory and 
     701its subdirectory structure. An empty directory may be specified 
     702without :recursive being non-nil. Specify directories with the 
     703trailing slash. 
     707dired:find-file         name &optional directory find-all        [Function] 
     709This function finds the file with file-namestring name, recursively 
     710looking in directory. If find-all is non-nil, then this continues 
     711searching even after finding a first occurrence of file. Name may 
     712contain a single wildcard, which causes find-all to default to t 
     713instead of nil. 
     717dired:make-directory    name     [Function] 
     719This function creates the directory with name. If it already exists, 
     720this signals an error. 
     724dired:pathnames-from-pattern    pattern files    [Function] 
     726This function returns a list of pathnames from the list files whose 
     727file-namestring's match pattern. Pattern must be a non-empty string 
     728and contain only one asterisk. Files contains no directories. 
     732dired:*update-default*                   [Variable] 
     734dired:*clobber-default*                  [Variable] 
     736dired:*recursive-default*                [Variable] 
     738These are the default values for the keyword arguments above with 
     739corresponding names. These default to nil, t, and nil respectively. 
     743dired:*report-function*                  [Variable] 
     744dired:*error-function*                   [Variable] 
     745dired:*yesp-function*            [Variable] 
     747These are the function the above routines call to report progress, 
     748signal errors, and prompt for yes or no. These all take format strings 
     749and arguments. 
     753merge-relative-pathnames        pathname default-directory       [Function] 
     755This function merges pathname with default-directory. If pathname is 
     756not absolute, this assumes it is relative to default-directory. The 
     757result is always a directory pathname. 
     761directoryp      pathname         [Function] 
     763This function returns whether pathname names a directory: it has no 
     764name and no type fields. 
     767== 18.6. Beeping == 
     769hemlock-beep             [Function] 
     771Hemlock binds system:*beep-function* to this function to beep the 
     772device. It is different for different devices. 
     776Bell Style      (initial value :border-flash)    [Variable] 
     778Beep Border Width       (initial value 20)       [Variable] 
     780Bell Style determines what hemlock-beep does in Hemlock under 
     781CLX. Acceptable values are :border-flash, :feep, 
     782:border-flash-and-feep, :flash, :flash-and-feep, and nil. 
     784Beep Border Width is the width in pixels of the border flashed by 
     785border flash beep styles.