Overview of fvwm2 parsing as of 16-Aug-2014
===========================================

Sources of input to parse
-------------------------

 * Configuration files and files read with the Read command
   - May be preprocessed by FvwmCpp or FvwmM4

 * Input from the PipeRead command

 * Input from modules to fvwm through the module pipes

   - Fixed or generated strings from modules (e.g. FvwmPager,
     FvwmButtons etc.)

   - User input, e.g. from FvwmConsole or FvwmCommand.

 * Module input from fvwm through the module pipes is parsed by
   the receiving module.

   - Binary input in predefined packets is only partially parsed
     (packet type).  The format and meaning of the packets is a
     property of the module protocol.

   - The payload of some string packets (e.g. generated by the
     SendToModule command) is a free form string that is
     interpreted by the receiving module.  The module does any
     necessary parsing.  Example:

       `SendToModule FvwmButtons changebutton 0 title foo, activetitle bar`

 * Commands generated internally by fvwm as the result of an
   external event, for example, an Ewmh message.  This is used
   quite often; instead of calling the function to maximize a
   window directly, one may generate a command string that is
   passed to `execute_function()`.  Examples are
   `virtual.c:CMD_EdgeResistance()` or
   `ewmh_events.c:ewmh_DesktopGeometry()`.

Various properties of parser input and the communication channels
-----------------------------------------------------------------

 * Maximum length of of lines read from a file is hard coded ro
   1024 bytes in `read.c:run_command_stream()`.  This is applicable
   to configuration files and the Read and Piperead commands.

 * The maximum depth of nested files opened through the Read
   command is hard coded to 40 (read.c).

 * Input from files or the `PipeRead` command may have an unlimited
   number of lines.

 * The maximum length of packets that can be sent in one chunk
   from fvwm to the modules or back is hard coded to 256 including
   the packet header (`FvwmPacketMaxSize` in `libs/Module.h`).  This is an
   artifact of module communication through pipes.  256 bytes is
   the size that all systems guarantee to be sent through the pipe
   in an atomic block.

   Anything larger than that may be split into multiple write
   calls, leading to mutilated messages in either direction.
   Packets from fvwm to the modules are simply truncated to 256
   bytes (`module_interface.c:make_vpacket()`).  Packets from the
   modules to fvwm are possibly sent in multiple pieces (write
   call in `Module.c:SendText()`).  Fvwm can theoretically handle
   any size of module input (`module_list.c:module_receive()`).

 * Input from modules to fvwm is pre-parsed in
   `module_interface.c:module_input_execute()`, i.e. fvwm checks
   whether the command name of the packet is "popup" and does some
   special processing if that is the case (this command name is
   not to be confused with the command from the text to be
   executed by fvwm; its a fixed field in the packet).  This is
   done before any regular processing of the input.

 * Input from the modules is not executed right away but stored in
   a queue and executed when fvwm can process it (this is
   important because otherwise module input might interfere with
   function execution) (`module_interface.c:ExecuteCommandQueue()`).

Fvwm's central parsing function: execute_function()
---------------------------------------------------

 * All input to the parser is passed through
   `functions.c:__execute_command_line()`.

   NOTE:  This function is called `__execute_function()` in fvwm.

 * `__execute_command_line` is called from two places:

   - `execute_function()` is just a wrapper exported rom
     functions.c.  There are two more wrappers,
     `execute_function_override_wcontext()` and
     `execute_function_override_window()` which change the execution
     context of the command (see below) and then call
     `execute_function()`.

   - `__run_complex_function_items()` calls `__execute_command_line()` to
     process the individual commands of a complex function.  In
     other words: The items of a complex function are passed twice
     through the parser.  First when the complex function is
     defined, and a second time when they are executed (they are
     treated differently in both passes, see further down).

 * The call to `__execute_command_line()` is passed various pieces of
   information:

   ```

      void __execute_command_line(
	cond_rc_t *cond_rc,
        const exec_context_t *exc,
        char *action,
	FUNC_FLAGS_TYPE exec_flags,
        char *args[],
        Bool has_ref_window_moved)
    ```

    - `cond_rc` is a pointer to memory where the return code of
      command line execution is to be stored.  This can be used in
      scripting through complex functions
      (`__run_complex_function_items()`) and by the internal caller
      of execute_function.  It is also one of the parameters of
      the `CMD_...` functions, and it's important that cond_rc is
      passed around and not set to a NULL pointer except by the
      first call triggering command line processing.

    - exc is the execution context of the command line
      (`execcontext.h`).  This is a vital data structure for command
      line processing and execution.  It contains information
      about the originator of the command and the assiciated
      application (type (module, event, scheduler, ...), the
      actual X event, the module, the window).  This data is used
      during command execution, e.g. to identify the window on
      which a command is executed or to determine the pointer
      position; some commands work differently when input comes
      from the mouse or the keyboard.  It is also used during
      variable expansion (e.g. to expand window related extended
      parameters like `$[w.id]`).

      It is important to properly set the execution context
      whenever a command line is generated.  Currently, some of
      the Ewmh code fails to do so for historical reasons which I
      won't explain here.  This needs to be fixed eventually.

    - action is the command line to parse and execute.

    - `exec_flags` are flags that affect command parsing and
      execution that may become necessary in some contexts not
      related to the originator of the command.  The flags are
      defined in the structure execute_flags_t in functions.h.

      - `FUNC_NEEDS_WINDOW` commands that need a context window are
        not executed if it's missing.
      - `FUNC_DONT_REPEAT` the command line is not repeatable (see
        `CMD_Repeat`).
      - `FUNC_ADD_TO` signals that the command is the addtofunc or
        `+` command.
      - `FUNC_DECOR` signals that the command is a decor related
        command.
      - `FUNC_ALLOW_UNMANAGED` allows running a command with an
        overrideredirect window.
      - `FUNC_IS_UNMANAGED` signals that the context window is an
        overrideredirect window.
      - `FUNC_DONT_EXPAND_COMMAND` suppresses expansion of variables
        on the command line.
      - `FUNC_DONT_DEFER` suppresses deferring execution of commands
        that need a target window (normally these are put into the
        queue and processed later).

    - args is the array of the positional arguments during complex
      function execution.  For calls from `execute_function()` it's
      a NULL pointer.

    - `has_ref_window_moved` is a separate flag (hack) that triggers
      some special treatment of the execution of the command Move,
      Resize and AnimatedMove (but forgets the ResizeMove and
      ResizeMoveMaximize commands).  This should ratehr be stored
      in exec_flags.

Command line parsing
--------------------

The command independent parsing of any command line is done by the
`__execute_command_line()` call.  The parsing procedure is as follows.
Remember that `action` is the command line to be parsed.  The
pointer and the memory it points to are updated during the parsing
process.

* Step 1
  Handle NULL pointer, whitespace and comments

   1. Stop parsing and execute nothing if action is a NULL
       pointer.
       *DONE*
   2. Strip all whitespace from the beginning of the command
       line.
   3. Stop parsing and execute nothing if action is a NULL
       pointer or an empty string.  (Note that some of the
       functions in libs/Parse.c never return an empty string but
       rather a NULL pointer.  Parsing in the individual commands
       often relies on that.)
       *DONE*
   4. If the first character is '#', is a comment.  Stop parsing
       and execute nothing.
       *DONE*

* Step 2
   1. Increment the nested function depth.
   2. If the function depth is too high, print an error message
       and stop.
       *DONE*
   3. Determine the context window.

* Step 3
  Handle prefixes

   1. If action begins with `-`, set the `FUNC_DONT_EXPAND_COMMAND`
       flag and skip the `-` character.
   2. Peek the first token of action.
   3. If the token is `silent`, set the global
       `Scr.flags.are_functions_silent` if not already set, strip
       the token from action and go back to (b).
   4. If the token is `keeprc`, set the internal `do_keep_rc` flag,
       strip the token from action and go back to (b).  (A dummy
       return code variable is used in the command execution.)

* Step 4
  Finish if there is no remaining action to execute.

* Step 5
  Parse the command token

   1. Get (but not strip) the command token from the action.
   2. Expand variables in the token (expand.c:expand_vars()).
   3. If the token does not start with a '*':
       * strip all characters from and including the first
         whitespace from the command token.

         [Bug: Complex function names cannot have embedded
         whitespace because of this, see comment in the code.]

         [Note: If a command line begins with

           `*foo`

         (including the double quotes), the double quotes are
         removed by GetNextToken, and the remaining token does
         begin with `*`.]

       * find the internal command matching this token from the
         builtin function table.  Note that any token _beginning_
         with `+` or ` +` is treated as the `+` command.

        [What the heck is this good for?]

* Step 6

  If a we're currently adding to a decor, and the command token
  designates a builtin function that does not have the `FUNC_DECOR`
  flag set, generate a warning that the command cannot be added to
  the decor.

* Step 7

  If the `FUNC_DONT_EXPAND_COMMAND` flag is not set, expand
  variables in the action, including the part from which the
  command token was extracted above.  (The ismod flag of the call
  to expand_vars() flag is set if the action begins with '*').

  [Note: The command token was parsed before expansion in step 5.
  Now the whole line including the token is expanded before
  further processing.  This may or may not cause subtle bugs with
  quoting and expansion.]

* Step 8

  If the expanded action begins with '*' treat it as a module
  configuration line.
  *GOTO step 10*

  [BUG: Contrary to step 5 (c), a line beginning with

    `*foo`

  is not recognized as a module configuration line because it
  begins with double quotes, not `*`.]

* Step 9

  Execute the action

  1. Prepare the execution context.
  2. If it's a builtin function other than `Function`, strip the
      first token from the expanded action and defer or execute
      the CMD_<command>() function as necessary with the proper
      execution context.
      *GOTO step 10*
  3. If it's the builtin command `Function`, strip the first
      token from the expanded action.

      [Note: this may again be a different substring than in step
      5 (c) or step 8.]
  4. Call
      `execute_complex_function` with the remaining expanded action.
  5. If no complex function with that name can be found and it
      was not the builtin command `Function`, assume that the
      builtin command was `Module` and try to execute `CMD_Module`
      with the remaining expanded action as its arguments.

* Step 10
  Cleanup

   1. Clear the `Scr.flags.are_functions_silent` flag if set in
       step 3 (c).
   2. Store the number of pending breaks from the functions
       return code structure in the original cond_rc (which may be
       a different one in case the command was prefixed with
       keeprc).
   3. Decrement the nested function depth.

Tokenization
------------

The token parsing code is in `libs/Parse.c:DoPeekToken()` and
CopyToken() (called by the former).  `DoPeekToken` takes the input
string, a pointer to memory where it stores the pointer to the
resulting token, a pointer to memory to store the output string
(buffer with hardcoded length `MAX_TOKEN_LENGTH = 1023` bytes
(`libs/Parse.h`), and may be provided a string of additional characters
to be treated as spaces, a string of input token delimiter
characters, and a pointer where the character that ended the token
is stored (output delimiter).  By default, the set of space
characters contains the character class determined by isspace(),
and the set of input delimiter characters is empty

* Step 1 (DoPeekToken)
  1. Strip all space characters (see above) from the beginning of
      the input string.
  2. Call `CopyToken()` with the remaining string.

* Step 2 (CopyToken)

  1. Set the src pointer to the beginning of the input string.
      The dest pointer is passed in as a function argument.
  2. If src is at the end of the string,
      *GOTO stp 3*
  3. If *src is a space character or an input delimiter,
      *GOTO stp 3*
  4. If *src is a quote character (either a double quote
      chararcter, a single quote or a backtick),
      *GOTO step 2A*
  5. Otherwise,
      *GOTO step 2B*

* Step 2A
  1. `c := *src`
  2. Skip over the src quote character (`src++`)
  3. If `*src` is `c` or the end of string,
      *GOTO (f)*
  4. If `*src` is a backslash and the next character is not the end
      of the input string (null byte), skip over the backslash in
      the input (src++).
  5. If there's still room in the output string, copy `*src` to
      `*dest` and increment both pointers, otherwise just skip over
      the input character (`src++`).
      *GOTO (c)*
  6. If `*src` is `c`, skip over it (`src++`).
      *GOTO step 2 (b)*

* Step 2B
  1. If `*src` is a backslash and the next character is not the end
      of the input string (null byte), skip over the backslash in
      the input (`src++`).
  2. If there's still room in the output string, copy `*src` to
      `*dest` and increment both pointers, otherwise just skip over
      the input character (`src++`).
      *GOTO step 2 (b)*

* Step 3
  1. Set the output delimiter to the character pointer to by src
      (i.e. the first character after the token).
  2. Terminate the destination string with a null byte.
  3. If src points to a string of zero or more spaces followed by
      an input delimiter, store the delimiter as the output
      delimiter and return a pointer to the character after that.
  4. Otherwise, if src is not at the end of the string, return
      the character after src.
  5. Otherwise src points to the end of the string; return src.

Step 4 (DoPeekToken)
  1. If the remaining string has the length zero, set the token
      pointer to NULL.
  2. Return a pointer to the beginning of the next token in the
      input string.
      *DONE*

Variable expansion
------------------

Variable expansion is done `expand.c:expand_vars()`.  The function
takes an input string, the execution context, `cond_rc` and an array
of positional parameters and returns the string with the variables
expanded.  It also takes the flags addto (never set) and ismod
(set in step 7 of the parsing algorithm if the command begins with
`*`).

[BUG: The addto flag is actually never set when the function is
called but instead used as a bogus local variable.]

* Step 1
  1. l := length of input
  2. If the input begins with '*', set the addto flag.
  3. Calculate the length of the expanded string and allocate
      memory for it.

* Step 2 (Scan for variables)
  1. Begin at the start of the input and output strings.
  2. Copy all character up to but excluding the next '$'
      character to the output string (stop at the end of string).
  3. If we're at the end of the string, stop.
      *DONE*
  4. Otherwise we're now at a `$` character.  If the ismod flag
      set and the next character is a letter, copy both to the
      output string.
      *GOTO (b)*

      [Note: In module configuration lines, variable in the form
      `$<letter>` are not expanded.  There are probably several
      bugs because of this logic.]

* Step 3 (Expand a variable)
  1. If the next character is a `$`, copy one `$` to the output,
      skip over two `$` in the input and
      *GOTO step 2 (b)*
  2. If the next character is '[',
      *GOTO step 4*
  3. If the `$<character>` sequence does not designate a valid
      one character variable, copy it to the output and
      *GOTO step 2 (b)*
  4. Otherwise, skip over the `$` and the next character in the
      input and copy the value of the one character variable to
      the output.
      *GOTO step 2 (b)*

* Step 4 (Expand an extended variable)
  1. If addto is set, copy the `$[` to the output and
      *GOTO step 2 (b)*
  2. Determine the name of the extended variable.  The name
      starts after the initial `[` character and ends before the
      final `]` character.  The final `]` character is the first
      occurence of the character `]` after the `$`, where the
      number of `[` minus the number of `]` is zero (i.e., square
      brackets can be nested).  If the end of string is
      encountered, just copy everything to the output and
      *GOTO step 2 (b)*
  3. Otherwise, if the variable name contains at least one `$`,
      call expand vars with the name to expand nested variable
      references.  The result of this expansion is taken as the
      new variable name.
  4. If an extended variable with that name exists, copy its
      value into the output, skip the `$[...]` in the input and
      *GOTO step 2 (b)*
  5. Otherwise copy the "$[...]" to the output and
      *GOTO step 2 (b)*

The second level of parsing
---------------------------

When `__execute_command_line()` has finished its work it either tries to
execute a module, a builtin command or a complex function (or
nothing at all and just returns).  Module execution is treated
like a call of `CMD_Module()`, so there are two different ways how
parsing continues.  A third context of parsing is, when a module
receives a packet from fvwm.

* Parsing of builtin commands is done individually by the
  `CMD_<builtin>()` functions.

* Parsing and of a complex function call and its items is handled
   by the function `functions.c:execute_complex_function()`.

* Parsing of module configuration lines is done by the modules
   with help from libs/Modules.c.  There is also an optional step
   of module variable expansion that is implemented in
   `Modules.c:module_expand_action()`.  It replaces some module
   variables in the string that is going to be sent to fvwm,
   e.g. `$width` or `$x`.  FvwmButtons, FvwmIconMan and
   FvwmTaskBar and use this mechanism.

Parsing of complex function calls
---------------------------------

Implemented in `functions.c:execute_complex_function()`.

* Step 1
  1. Peek the first token of the action.
  2. Look it up in the list of complex functions.
  3. If no such function exists, return an error.
      *DONE*
  4. Split the action into tokens using GetNextToken.  Store the
      original action (without the function name) followed by the
      first ten tokens in the positional arguments array.
  5. Set up an execution context for the function items.
  6. Call `__run_complex_function_items()`.

* Step 2 (`__run_complex_function_items()`)
  1. For each complex function item, call `__execute_command_line()`
      with the `FUNC_DONT_DEFER` flag and the list of positional
      arguments.  This causes the function item command text to be
      passed through the parser again.
  *DONE*

Parsing needs of the builtin commands
-------------------------------------

Note: Let's attempt to formulate the existing syntax in ABNF
(rfc5234).

Definitions that need defining for the below
--------------------------------------------

* FLAG = !!!;
* DECOR = !!!;
* FONTNAME = !!!;
* IMAGEFILE = !!!;
* GRADIENT = !!!;
* MOVEARGS = !!!;
* MODULECONFIG = !!!;
* CONDITION = !!!;
* COLOUR_FG = !!!;
* COLOUR_BG = !!!;
* COMMAND = !!!; (builtin; can also be one of FUNCNAME)
* FUNCNAME = !!!; (StartFunction | ExitFunction | etc, plus user-defined)
* SHELL = !!!;
* KEYNAME = !!!;
* STYLEOPTION = !!!; (massive list of style options!!!)
* TOKEN = !!! ; Same as string?
* STRING = !!! ; Sequence of characters?
* RESTOFLINE = !!! ; STRING?
* RESTOFLINE_COMMAND = !!! ; COMMAND

Types
-----

```
WSC = %x20 / %x09
WS = *WSC
DIGIT = "0" / "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9"
SIGNPOS = "+"
SIGNNEG = "-"
SIGN = SIGNPOS / SIGNNEG
POSINT = [SIGNPOS] 1*DIGIT
INT = [SIGN] 1*DIGIT
INTPERCENTAGE = 1DIGIT | 2DIGIT | ("0" / "1") 2DIGIT
TRUE = "yes" / "y" / "1" / "t" / "true"
FALSE = "no" / "n" / "0" / "f" / "false"
BOOL = TRUE / FALSE
TOGGLE = "toggle"
BOOL_OR_TOGGLE = BOOL / TOGGLE
MODIFIERS = "s" / "c" / "l" / "m" / "1" / "2" / "3" / "4" / "5" / "a"
BINDINGMODIFIERS = "n" / 1*MODIFIERS
PATH = ["/"] *(STRING "/") [STRING]
VISIBLE_NAME = !!!
CLASS = !!!
RESOURCE = !!!
NAME = !!!
WINDOW_ID = !!!
WINDOWSELECTOR = VISIBLE_NAME / CLASS / RESOURCE / NAME / WINDOW_ID
BINDINGCONTEXT = "R" / "W" / "D" / "T" / "F" / "A" / "S" / "M" / "I"
BINDINGCONTEXT = "[" / "]" / "-" / "_"
BINDINGCONTEXT = "<" / "^" / ">" / "v"
BINDINGCONTEXT = DIGIT
MODULENAME = "MvwmAnimate" / "MvwmButtons" / ; etc...
MODULALIAS = TOKEN
TOKEN_DECORNAME = TOKEN
FUNCNAME = TOKEN
MENUNAME = TOKEN
MENUSTYLENAME = TOKEN
STYLENAME = TOKEN / "*"
DIRS_MAIN = "North" / "N"
DIRS_MAIN =/ "East" / "E"
DIRS_MAIN =/ "South" / "S"
DIRS_MAIN =/ "West" / "W"
DIRS_DIAG = DIRS_MAIN
DIRS_DIAG =/ "NorthEast" / "NW"
DIRS_DIAG =/ "SouthEast" / "SE"
DIRS_DIAG =/ "SouthWest" / "SW"
DIRS_DIAG =/ "NorthWest" / "NW"
DIRS_CENTER = DIRS_DIAG / "Center" / "C"
COLORSET_NUM = POSINT
BUTTON = 1*DIGIT
VERSION = POSINT "." POSINT "." POSINT
```

Commands
--------

```
CMD_ADDBUTTONSTYLE = "AddButtonStyle"
	ADDBUTTONSTYLEBUTTON [ADDBUTTONSTYLESTATE]
	[ADDBUTTONSTYLESTYLE] [ADDBUTTONSTYLEFLAG]
ADDBUTTONSTYLEBUTTON = POSINT ("All" / "Left" / "Right")
ADDBUTTONSTYLESTATE = "ActiveUp"
ADDBUTTONSTYLESTATE =/ "ActiveDown"
ADDBUTTONSTYLESTATE =/ "InactiveUp"
ADDBUTTONSTYLESTATE =/ "InactiveDown"
ADDBUTTONSTYLESTATE =/ ADDBUTTONSTYLEACTIVE
ADDBUTTONSTYLESTATE =/ "Inactive"
ADDBUTTONSTYLESTATE =/ TOGGLE
ADDBUTTONSTYLESTATE =/ "AllActive"
ADDBUTTONSTYLESTATE =/ "AllInactive"
ADDBUTTONSTYLESTATE =/ "AllNormal"
ADDBUTTONSTYLESTATE =/ "AllToggled"
ADDBUTTONSTYLESTATE =/ "AllUp"
ADDBUTTONSTYLESTATE =/ "AllDown"
ADDBUTTONSTYLESTATE =/ "AllActiveUp"
ADDBUTTONSTYLESTATE =/ "AllActiveDown"
ADDBUTTONSTYLESTATE =/ "AllInactiveUp"
ADDBUTTONSTYLESTATE =/ "AllInactiveDown"
ADDBUTTONSTYLEACTIVE = "Active" - implies FOCUSED_WINDOW
ADDBUTTONSTYLEFLAG = ["!"]ADDBUTTONSTYLEKEYWORD *("," ["!"]ADDBUTTONSTYLEKEYWORD)
ADDBUTTONSTYLEKEYWORD = 1*("UseTitleStyle" / "UseBorderStyle") *("Raised" / "Sunk" / "Flat")

CMD_ADDTITLESTYLE = "AddTitleStyle" [ADDTITLESTYLESTATE]
	[ADDTITLESTYLESTYLE] [ADDTITLESTYLEFLAG]
ADDTITLESTYLESTATE = "ActiveUp"
ADDTITLESTYLESTATE =/ "ActiveDown"
ADDTITLESTYLESTATE =/ "InactiveUp"
ADDTITLESTYLESTATE =/ "InactiveDown"
ADDTITLESTYLESTATE =/ ADDTITLESTYLEACTIVE
ADDTITLESTYLESTATE =/ "Inactive"
ADDTITLESTYLESTATE =/ "toggled"
ADDTITLESTYLESTATE =/ "AllActive"
ADDTITLESTYLESTATE =/ "AllInactive"
ADDTITLESTYLEFLAG = ["!"] ADDTITLESTYLEFLAGKEYWORD *("," ["!"] ADDTITLESTYLEFLAGKEYWORD)
ADDTITLESTYLEACTIVE = "Active" ; - implies FOCUSED_WINDOW
; (XXX = TitleStyle/ButtonStyle relationships here...)
```
```
CMD_ADDTOFUNC = "AddToFunc" FUNCNAME ADDTOFUNCFUNCDEFS RESTOFLINE_COMMAND
ADDTOFUNCFUNCDEFS = "I"
ADDTOFUNCFUNCDEFS =/ "M"
ADDTOFUNCFUNCDEFS =/ "C"
ADDTOFUNCFUNCDEFS =/ "H"
ADDTOFUNCFUNCDEFS =/ "D"
```
```
CMD_ADDTOMENU = "AddToMenu" MENUNAME [ADDTOMENULABEL RESTOFLINE_COMMAND]
ADDTOMENULABEL = STRING
```
```
CMD_ANIMATEDMOVE = "AnimatedMove" ANIMATEMOVEARGS ANIMATEMOVEARGS
	[ANIMATEDMOVEKEYWORD]
ANIMATEMOVEARGS = !!!
ANIMATEDMOVEKEYWORD = "Warp"
```
```
CMD_ASTERISK = "Asterisk" [MODULE_LINE]
```
```
CMD_BEEP = "Beep"
```
```
CMD_BORDERSTYLE = "BorderStyle" BORDERSTYLESTATE
	[BORDERSTYLESTYLE] [BORDERSTYLEFLAG]
BORDERSTYLESTATE = "Active" / "Inactive"
BORDERSTYLESTYLE = "TiledPixmap" / "Colorset"
BORDERSTYLEFLAG = ["!"] BORDERSTYLEKEYWORD ("," ["!"] BORDERSTYLEKEYWORD)
BORDERSTYLEKEYWORD = "HiddenHandles"
BORDERSTYLEKEYWORD =/ "NoInset"
BORDERSTYLEKEYWORD =/ "Raised"
BORDERSTYLEKEYWORD =/ "Sunk"
BORDERSTYLEKEYWORD =/ "Flat"
BORDERSTYLEKEYWORD =/ "Simple"
```
```
CMD_BUGOPTS = "BugOpts" BUGOPTSOPTION
BUGOPTSOPTION = 1*(BUGOPTSKEYWORD [BOOL_OR_TOGGLE])
BUGOPTSKEYWORD = "FlickingMoveWorkaround"
BUGOPTSKEYWORD =/ "MixedVisualWorkaround"
BUGOPTSKEYWORD =/ "ModalityIsEvil"
BUGOPTSKEYWORD =/ "RaiseOverNativeWindows"
BUGOPTSKEYWORD =/ "RaiseOverUnmanaged"
BUGOPTSKEYWORD =/ "FlickingQtDialogsWorkaround"
BUGOPTSKEYWORD =/ "QtDragnDropWorkaround"
BUGOPTSKEYWORD =/ "EWMHIconicStateWorkaround"
BUGOPTSKEYWORD =/ "DisplayNewWindowNames"
BUGOPTSKEYWORD =/ "ExplainWindowPlacement"
BUGOPTSKEYWORD =/ "DebugCRMotionMethod"
BUGOPTSKEYWORD =/ "TransliterateUtf8"
```
```
CMD_BUSYCURSOR = "BusyCursor" BUSYCURSOROPTION *("," BUSYCURSOROPTION)
BUSYCURSOROPTION = 1*(BUSYCURSORKEYWORD BOOL)
BUSYCURSORKEYWORD = "DynamicMenu"
BUSYCURSORKEYWORD =/ "ModuleSynchronous"
BUSYCURSORKEYWORD =/ "Read"
BUSYCURSORKEYWORD =/ "Wait"
BUSYCURSORKEYWORD =/ "*"
```
```
CMD_BUTTONSTATE = "ButtonState" BUTTONSTATEOPTION *("," BUTTONSTATEOPTION)
BUTTONSTATEOPTION = BUTTONSTATEKEYWORD [BOOL]
BUTTONSTATEKEYWORD = "ActiveUp"
BUTTONSTATEKEYWORD =/ "ActiveDown"
BUTTONSTATEKEYWORD =/ "InactiveUp"
BUTTONSTATEKEYWORD =/ "InactiveDown"
```
```
CMD_BUTTONSTYLE = "ButtonStyle" BUTTONSTYLEBUTTON
	[BUTTONSTYLESTATE] [BUTTONSTYLESTYLE] [FLAGS]
BUTTONSTYLEBUTTON = 0-9
BUTTONSTYLEBUTTON =/ "All"
BUTTONSTYLEBUTTON =/ "Left"
BUTTONSTYLEBUTTON =/ "Right"
BUTTONSTYLEBUTTON =/ "Reset"
BUTTONSTYLEBUTTONSTATE = "ActiveUp"
BUTTONSTYLEBUTTONSTATE =/ "ActiveDown"
BUTTONSTYLEBUTTONSTATE =/ "InactiveUp"
BUTTONSTYLEBUTTONSTATE =/ "InactiveDown"
BUTTONSTYLEBUTTONSTATE =/ BUTTONSTYLEACTIVE
BUTTONSTYLEBUTTONSTATE =/ "Inactive"
BUTTONSTYLEBUTTONSTATE =/ TOGGLE
BUTTONSTYLEBUTTONSTATE =/ "AllActive"
BUTTONSTYLEBUTTONSTATE =/ "AllInactive"
BUTTONSTYLEBUTTONSTATE =/ "AllNormal"
BUTTONSTYLEBUTTONSTATE =/ "AllToggled"
BUTTONSTYLEBUTTONSTATE =/ "AllUp"
BUTTONSTYLEBUTTONSTATE =/ "AllDown"
BUTTONSTYLEBUTTONSTATE =/ "AllActiveUp"
BUTTONSTYLEBUTTONSTATE =/ "AllActiveDown"
BUTTONSTYLEBUTTONSTATE =/ "AllInactiveUp"
BUTTONSTYLEBUTTONSTATE =/ "AllInactiveDown"
BUTTONSTYLEACTIVE = "Active" ; - implies FOCUSED_WINDOW
BUTTONSTYLESTYLE = "Simple"
BUTTONSTYLESTYLE =/ "Default"
BUTTONSTYLESTYLE =/ "Solid"
BUTTONSTYLESTYLE =/ "Colorset"
BUTTONSTYLESTYLE =/ "Vector"
BUTTONSTYLESTYLE =/ BUTTONSTYLEGRADIENT
BUTTONSTYLESTYLE =/ "Pixmap"
BUTTONSTYLESTYLE =/ AdjustedPixmap"
BUTTONSTYLESTYLE =/ "ShrunkPixmap"
BUTTONSTYLESTYLE =/ "StretchedPixmap"
BUTTONSTYLESTYLE =/ "TiledPixmap"
BUTTONSTYLESTYLE =/ "MiniIcon"
BUTTONSTYLEGRADIENT = TYPE START-COLOUR END-COLOUR
BUTTONSTYLESTYLEFLAG =
	["!"] BUTTONSTYLESTYLEKEYWORD *("," ["!"] BUTTONSTYLESTYLEKEYWORD)
BUTTONSTYLESTYLEKEYWORD = "Raised"
BUTTONSTYLESTYLEKEYWORD =/ "Sunk"
BUTTONSTYLESTYLEKEYWORD =/ "Flat"
BUTTONSTYLESTYLEKEYWORD =/ "UseBorderStyle"
BUTTONSTYLESTYLEKEYWORD =/ "UseTitleStyle"
; (XXX = "Raised, Sunk, and Flat" can only be used initially!!!")
```
```
CMD_CHANGEMENUSTYLE = "ChangeMenuStyle" MENUSTYLENAME MENUNAME
```
```
CMD_CLEANUPCOLORSETS = "CleanupColorsets"
```
```
CMD_CLICKTIME = "ClickTime" POSINT
; (stores the negative value during startup>
```
```
CMD_CMD_CLASS_CLOSE = "Close" / "Delete" / "Destroy"
; work on context window
```
```
CMD_COLORMAPFOCUS = "ColormapFocus" ("FollowsMouse" / "FollowsFocus")
```
```
CMD_COLORSET = "Colorset" COLORSET_NUM COLORSETOPTION *("," COLORSETOPTION)
COLORSETOPTION = COLORSETKEYWORD [COLORSETVALUE]
COLORSETKEYWORD = "fg"
COLORSETKEYWORD =/ "Fore"
COLORSETKEYWORD =/ "Foreground"
COLORSETKEYWORD =/ "bg"
COLORSETKEYWORD =/ "Back"
COLORSETKEYWORD =/ "Background"
COLORSETKEYWORD =/ "hi"
COLORSETKEYWORD =/ "Hilite"
COLORSETKEYWORD =/ "Hilight"
COLORSETKEYWORD =/ "sh"
COLORSETKEYWORD =/ "Shade"
COLORSETKEYWORD =/ "Shadow"
COLORSETKEYWORD =/ "fgsh"
COLORSETKEYWORD =/ "Pixmap"
COLORSETKEYWORD =/ "TiledPixmap"
COLORSETKEYWORD =/ "AspectPixmap"
COLORSETKEYWORD =/ "Transparent"
COLORSETKEYWORD =/ "RootTransparent"
COLORSETKEYWORD =/ "Shape"
COLORSETKEYWORD =/ "TiledShape"
COLORSETKEYWORD =/ "AspectShape"
COLORSETKEYWORD =/ "NoShape"
COLORSETKEYWORD =/ ("V" / "B" / "D" / "S" / "C" / "R" / "Y") "Gradient"
COLORSETKEYWORD =/ "Tint"
COLORSETKEYWORD =/ "fgTint"
COLORSETKEYWORD =/ "bgTint"
COLORSETKEYWORD =/ "Alpha"
COLORSETKEYWORD =/ "fgAlpha"
COLORSETKEYWORD =/ "Dither"
COLORSETKEYWORD =/ "NoDither"
COLORSETKEYWORD =/ "IconTint"
COLORSETKEYWORD =/ "IconAlpha"
COLORSETKEYWORD =/ "Plain"
COLORSETVALUE = INT
COLORSETVALUE =/ COLORNAME
COLORSETVALUE =/ IMAGEFILENAME
COLORSETVALUE =/ INTPERCENTAGE
; (memory usage depends on highest colorset number)
```
```
COPYMENUSTYLE = "CopyMenuStyle" MENUSTYLENAME MENUSTYLENAME
```
```
CMD_CURSORMOVE = "CursorMove"
	CURSORMOVEDIM[CURSORMOVESUFFIX] CURSORMOVEDIM[CURSORMOVESUFFIX]
CURSORMOVEDIM = INT
CURSORMOVESUFFIX = "p"
```
```
CMD_CURSORSTYLE = "CursorStyle" CURSORSTYLECONTEXT [CURSORSTYLEXOPTION]
CURSORSTYLECONTEXT = CURSORSTYLEKEYWORD / CURSORSTYLEX11NAME
CURSORSTYLEKEYWORD = "POSITION"
CURSORSTYLEKEYWORD =/ "TITLE"
CURSORSTYLEKEYWORD =/ "DEFAULT"
CURSORSTYLEKEYWORD =/ "SYS"
CURSORSTYLEKEYWORD =/ "MOVE"
CURSORSTYLEKEYWORD =/ "RESIZE"
CURSORSTYLEKEYWORD =/ "WAIT"
CURSORSTYLEKEYWORD =/ "MENU"
CURSORSTYLEKEYWORD =/ "SELECT"
CURSORSTYLEKEYWORD =/ "DESTROY"
CURSORSTYLEKEYWORD =/ "TOP"
CURSORSTYLEKEYWORD =/ "RIGHT"
CURSORSTYLEKEYWORD =/ "BOTTOM"
CURSORSTYLEKEYWORD =/ "LEFT"
CURSORSTYLEKEYWORD =/ "TOP_LEFT"
CURSORSTYLEKEYWORD =/ "TOP_RIGHT"
CURSORSTYLEKEYWORD =/ "BOTTOM_LEFT"
CURSORSTYLEKEYWORD =/ "BOTTOM_RIGHT"
CURSORSTYLEKEYWORD =/ "TOP_EDGE"
CURSORSTYLEKEYWORD =/ "RIGHT_EDGE"
CURSORSTYLEKEYWORD =/ "BOTTOM_EDGE"
CURSORSTYLEKEYWORD =/ "LEFT_EDGE"
CURSORSTYLEKEYWORD =/ "ROOT"
CURSORSTYLEKEYWORD =/ "STROKE"
CURSORSTYLEKEYWORD =/ "None"
CURSORSTYLEKEYWORD =/ "Tiny"
CURSORSTYLEX11NAME = "top_left_corner"
CURSORSTYLEX11NAME =/ "top_left_arrow"
CURSORSTYLEX11NAME =/ "hand2"
CURSORSTYLEX11NAME =/ "fleur"
CURSORSTYLEX11NAME =/ "sizing"
CURSORSTYLEX11NAME =/ "watch"
CURSORSTYLEX11NAME =/ "crosshair"
CURSORSTYLEX11NAME =/ "pirate"
CURSORSTYLEX11NAME =/ "top_side"
CURSORSTYLEX11NAME =/ "bottom_side"
CURSORSTYLEX11NAME =/ "left_side"
CURSORSTYLEX11NAME =/ "top_right_corner"
CURSORSTYLEX11NAME =/ "bottom_left_corner"
CURSORSTYLEX11NAME =/ "top_side"
CURSORSTYLEX11NAME =/ "right_side"
CURSORSTYLEX11NAME =/ "left_side"
CURSORSTYLEX11NAME =/ "left_ptr"
CURSORSTYLEX11NAME =/ "plus"
CURSORSTYLEXOPTION = IMAGEFILE [INT]
CURSORSTYLEXOPTION =/ "fg"
CURSORSTYLEXOPTION =/ "bg"
```
```
CMD_DEFAULTFONT = "DefaultFont" [FONTNAME]
```
```
CMD_DEFAULTICON = "DefaultIcon" [IMAGEFILE]
```
```
CMD_DEFAULTLAYERS = "DefaultLayers" INT INT INT
```
```
CMD_DESCHEDULE = "Deschedule" [INT]
```
```
CMD_DESKTOPNAME = "DesktopName" INT DESKTOPNAME
DESKTOPNAME = 1*(ALPHA DIGIT)
```
```
CMD_DESKTOPSIZE = "DesktopSize" DESKTOPSIZDIM "x" DESKTOPSIZDIM
DESKTOPSIZEDIM = INT
```
```
CMD_DESTROYFUNC = "DestroyFunc" [FUNCNAME]
```
```
CMD_DESTROYMENU = "DestroyMenu" ["recreate"] MENUNAME
```
```
CMD_DESTROYMENUSTYLE = "DestroyMenuStyle" MENUSTYLENAME
```
```
CMD_DESTROYMODULECONFIG = "DestroyModuleConfig" MODULECONFIG
```
```
CMD_DESTROYSTYLE = "DestroyStyle" STYLENAME
```
```
CMD_DESTROYWINDOWSTYLE = "DestroyWindowStyle" ; operates on context window
```
```
CMD_ECHO = "Echo" RESTOFLINE
```
```
CMD_ECHOFUNCDEFINITION = "EchoFuncDefinition" FUNCNAME
```
```
CMD_EDGECOMMAND = "EdgeCommand" [DIRS_MAIN [RESTOFLINE_COMMAND]]
```
```
CMD_EDGELEAVECOMMAND = "EdgeLeaveCommand" [DIRS_MAIN [RESTOFLINE_COMMAND]]
```
```
CMD_EDGESCROLL = "EdgeScroll" EDGESCROLLDIM[EDGESCROLLSUFFIX]
	EDGESCROLLDIM[EDGESCROLLSUFFIX] [EDGESCROLLOPTION]
EDGESCROLLDIM = INT
EDGESCROLLSUFFIX = "p"
EDGESCROLLOPTION = "Wrap"
EDGESCROLLOPTION =/ "WrapX"
EDGESCROLLOPTION =/ "WrapY"
```
```
CMD_EDGETHICKNESS = "EdgeThickness" EDGETHICKNESSVAL
EDGETHICKNESSVAL = "0" / "1" / "2"
```
```
CMD_EMULATE = "Emulate" EMULATEVAL
EMULATEVAL = "Mvwm"
EMULATEVAL =/ "Mwm"
EMULATEVAL =/ "Win"
```
```
CMD_ESCAPEFUNC = "EscapeFunc"
```
```
CMD_EWMHBASESTRUTS = "EwmhBaseStruts" ["screen" XRANDRMONITORNAME] INT INT INT INT
```
```
CMD_EWMHNUMBEROFDESKTOPS = "EwmhNumberOfDesktops" ["screen" XRANDRMONITORNAME] INT INT
```
```
CMD_EXEC = "Exec" RESTOFLINE_COMMAND
```
```
CMD_EXECUSESHELL = "ExecUseShell" EXECUSESHELLSHELL
; Could technically be any external command; assume a value from /etc/shells
EXECUSESHELLSHELL = !!!
```
```
CMD_FAKECLICK = "FakeClick" FAKECLICKACTION *("," FAKECLICKACTION)
FAKECLICKACTION = FAKECLICKCOMMAND FAKECLICKVALUE
FAKECLICKCOMMAND = (FAKECLICKKEYWORD, FAKECLICKVALUE)
FAKECLICKKEYWORD = "press"
FAKECLICKKEYWORD =/ "release"
FAKECLICKKEYWORD =/ "modifiers"
FAKECLICKKEYWORD =/ "wait"
FAKECLICKKEYWORD =/ FAKECLICKDEPTH
FAKECLICKVALUE = "1"
FAKECLICKVALUE =/ "2"
FAKECLICKVALUE =/ "3"
FAKECLICKVALUE =/ "4"
FAKECLICKVALUE =/ "5"
FAKECLICKVALUE =/ "Mod1"
FAKECLICKVALUE =/ "Mod2"
FAKECLICKVALUE =/ "Mod3"
FAKECLICKVALUE =/ "Mod4"
FAKECLICKVALUE =/ "Mod5"
FAKECLICKVALUE =/ "6"
FAKECLICKVALUE =/ "7"
FAKECLICKVALUE =/ "8"
FAKECLICKVALUE =/ "Shift"
FAKECLICKVALUE =/ "Lock"
FAKECLICKVALUE =/ "Control"
FAKECLICKDEPTH = "depth"
FAKECLICKDEPTH =/ "0"
FAKECLICKDEPTH =/ "1"
FAKECLICKDEPTH =/ "2"
FAKECLICKDEPTH =/ "3"
FAKECLICKDEPTH =/ INT
```
```
CMD_FAKEKEYPRESS = "FakeKeypress" FAKEKEYPRESSACTION *("," FAKEKEYPRESSACTION)
FAKEKEYPRESSACTION = FAKEKEYPRESSCOMMAND FAKEKEYPRESSVALUE
FAKEKEYPRESSKEYWORD = "press"
FAKEKEYPRESSKEYWORD =/ "release"
FAKEKEYPRESSKEYWORD =/ "modifiers"
FAKEKEYPRESSKEYWORD =/ "wait"
FAKEKEYPRESSKEYWORD =/ DEPTH
FAKEKEYPRESSVALUE = KEYNAME
FAKEKEYPRESSDEPTH = "depth"
FAKEKEYPRESSDEPTH =/ "0"
FAKEKEYPRESSDEPTH =/ "1"
FAKEKEYPRESSDEPTH =/ "2"
FAKEKEYPRESSDEPTH =/ "3"
FAKEKEYPRESSDEPTH =/ INT
```
```
CMD_FLIPFOCUS = "FlipFocus" ["nowarp"]
```
```
CMD_FOCUS = "Focus" ["nowarp"]
```
```
CMD_FOCUSSTYLE = "FocusStyle" STYLEOPTIONS
```
```
CMD_FUNCTION = "Function" [FUNCNAME]
```
```
CMD_GEOMETRYWINDOW = "GeometryWindow" GEOMWIN_CMD
GEOMWIN_CMD = "Hide" [GEOMWIN_HIDEOPT]
GEOMWIN_CMD =/ "Show" [GEOMWIN_HIDEOPT]
GEOMWIN_CMD =/ "Colorset" INT
GEOMWIN_CMD =/ "Position" [+/-]INT[p] [+/-]INT[p]
GEOMWIN_CMD =/ "Screen" XRANDRMONITORNAME
GEOMWIN_HIDEOPT = "Never" / "Move" / "Resize"
```
```
CMD_GOTODESK = "GotoDesk" DESKNUMBER
DESKNUMBER = ["prev" / (INT [INT [INT [INT]]])]
```
```
CMD_GOTODESKANDPAGE = "GotoDeskAndPage" "prev" / (INT INT INT)
```
```
CMD_GOTOPAGE = "GotoPage" PAGE_ARGUMENTS
PAGE_ARGUMENTS = ["prev" / ([OPTIONS] 2(PAGECCORD[PAGESUFFIX])
OPTIONS = ["!"] ("wrapx" / "wrapy" / "nodesklimitx" / "nodesklimity")
PAGECOORD = INT
PAGESUFFIX = "p"
```
```
CMD_ICONIFY = "Iconify" BOOL_OR_TOGGLE
```
```
CMD_IGNOREMODIFIERS = "IgnoreModifiers" [ BINDINGMODIFIERS ]
```
```
CMD_IMAGEPATH = "ImagePath" [PATH]
```
```
CMD_INFOSTOREADD = "InfoStoreAdd" INFOSTOREKEY INFOSTOREVALUE
INFOSTOREKEY = STRING
INFOSTOREVALUE = STRING
```
```
CMD_INFOSTOREREMOVE = "InfoStoreRemove" [INFOSTOREREKEY]
```
```
CMD_KEEPRC = "KeepRc" [RESTOFLINE_COMMAND]
```
```
CMD_CLASS_KEY = ("Key" / "PointerKey") ["(" WINDOWSELECTOR ")"] KEYNAME
	BINDINGCONTEXT BINDINGMODIFIERS RESTOFLINE_COMMAND
```
```
CMD_KILLMODULE = "KillModule" [MODULENAME] [MODULEALIAS]
```
```
CMD_LAYER = "Layer" [INT INT] / "default"
```
```
CMD_LOCALEPATH = "LocalePath" [PATH]
```
```
CMD_CLASS_RAISELOWER = ("Lower" / "Raise" / "RaiseLower") ; operates on context window
```
```
CMD_MAXIMIZE = "Maximize" [MAXIMIZEFLAGS] [BOOL_OR_TOGGLE / "forget"]
	[[MAXIMIZEDIM[MAXIMIZESUFFIX]] MAXIMIZEDIM[MAXIMIZESUFFIX]]
MAXIMIZEGROWOPTS = "grow"
MAXIMIZEGROWOPTS =/ "growleft"
MAXIMIZEGROWOPTS =/ "growright"
MAXIMIZEGROWOPTS =/ "growup"
MAXIMIZEGROWOPTS =/ "growdown"
MAXIMIZEDIM = INT
MAXIMIZEDIM =/ MAXIMIZEGROWOPTS
MAXIMIZESUFFIX = "p"
MAXIMIZEFLAGS = "ewmhiwa"
MAXIMIZEFLAGS =/ "growonwindowlayer"
MAXIMIZEFLAGS =/ "growonlayers"
MAXIMIZEFLAGS =/ ("screen" / XINERAMASCR)
```
```
CMD_CLASS_MENU = ("Menu" / "Popup") MENUNAME [MENUPOSITION] [MENUCOMMAND]
MENUPOSITION = MENUCONTEXT_RECTANGLE INT INT [MENUOPTIONS]
MENUCONTEXT_RECTANGLE = "Root" !!!
MENUCONTEXT = "XineramaRoot"
MENUCONTEXT =/ "Mouse"
MENUCONTEXT =/ "Window"
MENUCONTEXT =/ "Interior"
MENUCONTEXT =/ "Title"
MENUCONTEXT =/ ("Button" INT) "Icon"
MENUCONTEXT =/ "Item"
MENUCONTEXT =/ "Context"
MENUCONTEXT =/ "This"
MENUCONTEXT =/ ("Rectangle" MENUCONTEXTGEOMETRY)
MENUOPTIONS = "TearoffImmediately"
MENUOPTIONS =/ "SelectInPlace"
MENUOPTIONS = !!!
MENUCONTEXTGEOMETRY = !!!
```
```
CMD_MENUSTYLE = "MenuStyle" MENUSTYLENAME *(["!"] MENUSTYLEOPTIONS)
MENUSTYLEOPTIONS = "Mvwm"
MENUSTYLEOPTIONS =/ "Mwm"
MENUSTYLEOPTIONS =/ "Win"
MENUSTYLEOPTIONS =/ "BorderWidth"
MENUSTYLEOPTIONS =/ "Foreground"
MENUSTYLEOPTIONS =/ "Background"
MENUSTYLEOPTIONS =/ "Greyed"
MENUSTYLEOPTIONS =/ "HilightBack"
MENUSTYLEOPTIONS =/ "HilightTitleBack"
MENUSTYLEOPTIONS =/ "ActiveFore"
MENUSTYLEOPTIONS =/ "MenuColorset"
MENUSTYLEOPTIONS =/ "ActiveColorset"
MENUSTYLEOPTIONS =/ "GreyedColorset"
MENUSTYLEOPTIONS =/ "TitleColorset"
MENUSTYLEOPTIONS =/ "Hilight3DThick"
MENUSTYLEOPTIONS =/ "Hilight3DThin"
MENUSTYLEOPTIONS =/ "Hilight3DOff"
MENUSTYLEOPTIONS =/ "Hilight3DThickness"
MENUSTYLEOPTIONS =/ "Animation"
MENUSTYLEOPTIONS =/ "Font"
MENUSTYLEOPTIONS =/ "TitleFont"
MENUSTYLEOPTIONS =/ "MenuFace"
MENUSTYLEOPTIONS =/ "PopupDelay"
MENUSTYLEOPTIONS =/ "PopupOffset"
MENUSTYLEOPTIONS =/ "TitleWarp"
MENUSTYLEOPTIONS =/ "TitleUnderlines0"
MENUSTYLEOPTIONS =/ "TitleUnderlines1"
MENUSTYLEOPTIONS =/ "TitleUnderlines2"
MENUSTYLEOPTIONS =/ "SeparatorsLong"
MENUSTYLEOPTIONS =/ "SeparatorsShort"
MENUSTYLEOPTIONS =/ "TrianglesSolid"
MENUSTYLEOPTIONS =/ "TrianglesRelief"
MENUSTYLEOPTIONS =/ "PopupImmediately"
MENUSTYLEOPTIONS =/ "PopupDelayed"
MENUSTYLEOPTIONS =/ "PopdownImmediately"
MENUSTYLEOPTIONS =/ "PopdownDelayed"
MENUSTYLEOPTIONS =/ "PopupActiveArea"
MENUSTYLEOPTIONS =/ "DoubleClickTime"
MENUSTYLEOPTIONS =/ "SidePic"
MENUSTYLEOPTIONS =/ "SideColor"
MENUSTYLEOPTIONS =/ "PopupAsRootMenu"
MENUSTYLEOPTIONS =/ "PopupAsSubmenu"
MENUSTYLEOPTIONS =/ "PopupIgnore"
MENUSTYLEOPTIONS =/ "PopupClose"
MENUSTYLEOPTIONS =/ "RemoveSubmenus"
MENUSTYLEOPTIONS =/ "HoldSubmenus"
MENUSTYLEOPTIONS =/ "SubmenusRight"
MENUSTYLEOPTIONS =/ "SubmenusLeft"
MENUSTYLEOPTIONS =/ "SelectOnRelease"
MENUSTYLEOPTIONS =/ "ItemFormat"
MENUSTYLEOPTIONS =/ "VerticalItemSpacing"
MENUSTYLEOPTIONS =/ "VerticalMargins"
MENUSTYLEOPTIONS =/ "VerticalTitleSpacing"
MENUSTYLEOPTIONS =/ "AutomaticHotkeys"
MENUSTYLEOPTIONS =/ "UniqueHotkeyActivatesImmediate"
MENUSTYLEOPTIONS =/ "MouseWheel"
MENUSTYLEOPTIONS =/ "ScrollOffPage"
MENUSTYLEOPTIONS =/ "TrianglesUseFore"
; add option syntax
```
```
CMD_CLASS_MODULE = ("Module" / "ModuleListenOnly") CMDMODULEARGS
CMDMODULEARGS = MODULENAME [MODULEALIAS]
```
```
CMD_MODULEPATH = "ModulePath" PATH
```
```
CMD_MODULESYNCHRONOUS = "ModuleSynchronous" ["Expect" STRING] ["Timeout" INT]
	CMDMODULEARGS
```
```
CMD_MODULETIMEOUT = "ModuleTimeout" INT
```
```
CMD_MOUSE = "Mouse" ["(" WINDOWSELECTOR ")"] BUTTON
	BINDINGCONTEXT BINDINGMODIFIERS COMMAND
```
```
CMD_MOVE = "Move" [MOVEARGS]
MOVEARGS = !!!
```
```
CMD_MOVETHRESHOLD = "MoveThreshold" [INT]
```
```
CMD_MOVETODESK = "MoveToDesk" DESKNUMBER
```
```
CMD_MOVETOPAGE = "MoveToPage" ["prev"] [MOVETOPAGEOPTIONS]
	2(MOVETOPAGECOORD[MOVETOPAGESUFFIX])
MOVETOPAGEOPTIONS = "wrapx" / "wrapy" / "nodesklimitx" / "nodesklimity"
MOVETOPAGECOORD = INT
MOVETOPAGESUFFIX = "p" / "w"
```
```
CMD_MOVETOSCREEN = "MoveToScreen" [XRANDRMONITORNAME]
XRANDRMONITORNAME = !!!
```
```
CMD_NOP = "Nop"
```
```
CMD_OPAQUEMOVESIZE = "OpaqueMoveSize" [INT]
```
```
CMD_PIPEREAD = "PipeRead" TOKEN ["quiet"]
```
```
CMD_PLACEAGAIN = "PlaceAgain" *("Anim" "Icon")
```
```
CMD_PLUS = "Plus" RESTOFLINE
```
```
CMD_PRINTINFO = "PrintInfo" PRINTINFOSUBJECT
PRINTINFOSUBJECT = (PRINTINFOKEYWORD [PRINTINFOVAL])
PRINTINFOVAL = "0"
PRINTINFOVAL =/ "1"
PRINTINFOVAL =/ "2"
PRINTINFOKEYWORD = "Colors"
PRINTINFOKEYWORD =/ "ImageCache"
PRINTINFOKEYWORD =/ "Locale"
PRINTINFOKEYWORD =/ "NLS"
PRINTINFOKEYWORD =/ "Style"
PRINTINFOKEYWORD =/ "Bindings"
PRINTINFOKEYWORD =/ "Infostore"
```
```
CMD_QUIT = "Quit"
```
```
CMD_READ = "Read" FILENAME ["quiet"]
```
```
CMD_CLASS_RECAPTURE = ("Recapture" / "RecaptureWindow")
```
```
CMD_CLASS_REFRESH = ("Refresh" / "RefreshWindow")
```
```
CMD_REPEAT = "Repeat" ["command"]
```
```
CMD_CLASS_RESIZE = ("Resize" / "ResizeMaximize") [RESIZEOPTS]
RESIZEOPTS = (RESIZEOPTS_BR / RESIZEOPTS_OTHER) [2RESIZEARG]
RESIZEOPTS_BR = ("bottomright" / "br") MOVEARGS
RESIZEOPTS_OTHER =
	("frame" / "fixeddirection" /
	("direction" (DIRS_CENTER / "automatic")) /
	("warptoborder" ["automatic"]))
RESIZEARG = "keep" / (RESIZEARG_2 [RESIZEARGSUFFIX])
RESIZEARG_2 = "w" / (["w"] RESIZEARGVAL)
RESIZEARGVAL = (SIGN INT) / POSINT
RESIZEARGSUFFIX = "p" / "c"
```
```
CMD_CLASS_RESIZEMOVE = ("ResizeMove" / "ResizeMoveMaximize")
	RESIZEOPTS MOVEARGS
```
```
CMD_RESTACKTRANSIENTS = "RestackTransients"
```
```
CMD_RESTART = "Restart" [STRING]
```
```
CMD_SCHEDULE = "Schedule" ["periodic"] INT [INT] RESTOFLINE_COMMAND
```
```
CMD_SCROLL = "Scroll"
	[(SCROLLDIM[SCROLLSUFFIX] SCROLLDIM[SCROLLSUFFIX]) / OPTION]
SCROLLDIM = INT
OPTION = "reverse"
SCROLLSUFFIX = "p"
```
```
CMD_SENDTOMODULE = "SendToModule" [MODULENAME] [STRING]
```
```
CMD_SETANIMATION = "SetAnimation" INT [INT]
```
```
CMD_SILENT = "Silent" RESTOFLINE_COMMAND
```
```
CMD_STATE = "State" STATENUM [BOOL]
```
```
CMD_CLASS_STICK = ("Stick" / "StickAcrossDesks" / "StickAcrossPages")
	[BOOL_OR_TOGGLE]
```
```
CMD_CLASS_STYLE = ("Style" / "WindowStyle") [STYLENAME] [STYLEOPTIONS]
; note: WindowStyle operates on context window
STYLEOPTIONS = STYLEOPTION ("," STYLEOPTION)
STYLEOPTION = !!!
```
```
CMD_TEARMENUOFF = "TearMenuOff"
; note: applies to menu context only
; note: ignores all arguments
; note: syntax description complete
```
```
CMD_TITLE = "Title"
; note: applies to menu context only
; note: ignores all arguments
; note: syntax description complete
```
```
CMD_TITLESTYLE = "TitleStyle"
;!!!
```
```
CMD_SETENV = "SetEnv" [TOKEN_ENVVAR [TOKEN_ENVVAL]]
TOKEN_ENVVAR = TOKEN
TOKEN_ENVVAL = TOKEN
; note: does nothing if no arguments are given
; note: uses an empty value string if the second argument is missing
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_UNSETENV = "UnsetEnv" [TOKEN_ENVVAR]
; note: does nothing if argument is missing
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_UPDATESTYLES = "UpdateStyles"
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_WAIT = "Wait" [TOKEN_WAIT_PATTERN [STRIPPED_RESTOFLINE]]
; Note: The first argument, or - if present - the rest of the line is used as
; the pattern to wait for.
; note: the syntax with more than one argument is not documented.  Comment in
; the sources call it the "old syntax".
; note: syntax description complete
```
```
CMD_WARPTOWINDOW = "WarpToWindow" [PERCENT_ARG_PAIR]
; note: arguments not used when used on an unmanaged window
; note: arguments are ignored if not valid
; note: ignores rest of line
; note: syntax description complete
```
```
;!!!todo
CMD_WINDOWLIST = "WindowList" ["(" WINDOWLISTCONDITIONS ")"]
	[WINDOWLISTPOSITION] [WINDOWLLISTOPTIONS] [COMMAND]
WINDOWLISTPOSITION = WINDOWLISTCONTEXT_RECTANGLE INT INT
	[WINDOWLISTCONTEXTOPTIONS]
WINDOWLISTCONTEXT_RECTANGLE = "Root"
WINDOWLISTCONTEXT_RECTANGLE =/ "XineramaRoot"
WINDOWLISTCONTEXT_RECTANGLE =/ "Mouse"
WINDOWLISTCONTEXT_RECTANGLE =/ "Window"
WINDOWLISTCONTEXT_RECTANGLE =/ "Interior"
WINDOWLISTCONTEXT_RECTANGLE =/ "Tiitle"
WINDOWLISTCONTEXT_RECTANGLE =/ ("Button" INT)
WINDOWLISTCONTEXT_RECTANGLE =/ "Icon"
WINDOWLISTCONTEXT_RECTANGLE =/ "Item"
WINDOWLISTCONTEXT_RECTANGLE =/ "Context"
WINDOWLISTCONTEXT_RECTANGLE =/ "This"
WINDOWLISTCONTEXT_RECTANGLE =/ ("Rectangle" GEOMETRY)
WINDOWLISTCONTEXTOPTIONS = "TearoffImmediately"
WINDOWLISTCONTEXTOPTIONS =/ "SelectInPlace"
WINDOWLISTOPTIONS = (WINDOWLISTKEYWORD [WINDOWLISTVALUE])
WINDOWLISTOPTIONS = "Geometry"
WINDOWLISTOPTIONS =/ "NoGeometry"
WINDOWLISTOPTIONS =/ "NoGeometryWithInfo"
WINDOWLISTOPTIONS =/ "NoDeskNum"
WINDOWLISTOPTIONS =/ "NoLayer"
WINDOWLISTOPTIONS =/ "NoNumInDeskTitle"
WINDOWLISTOPTIONS =/ "NoCurrentDeskTitle"
WINDOWLISTOPTIONS =/ ("MaxLabelWidth" INT)
WINDOWLISTOPTIONS =/ "TitleForAllDesks"
WINDOWLISTOPTIONS =/ ("Function" FUNCNAME)
WINDOWLISTOPTIONS =/ ("Desk" INT)
WINDOWLISTOPTIONS =/ "CurrentDesk"
WINDOWLISTOPTIONS =/ "NoIcons"
WINDOWLISTOPTIONS =/ "Icons"
WINDOWLISTOPTIONS =/ "OnlyIcons"
WINDOWLISTOPTIONS =/ "NoNormal"
WINDOWLISTOPTIONS =/ "Normal"
WINDOWLISTOPTIONS =/ "OnlyNormal"
WINDOWLISTOPTIONS =/ "NoSticky"
WINDOWLISTOPTIONS =/ "Sticky"
WINDOWLISTOPTIONS =/ "OnlySticky"
WINDOWLISTOPTIONS =/ "NoStickyAcrossPages"
WINDOWLISTOPTIONS =/ "StickyAcrossPages"
WINDOWLISTOPTIONS =/ "OnlyStickyAcrossPages"
WINDOWLISTOPTIONS =/ "NoStickyAcrossDesks"
WINDOWLISTOPTIONS =/ "StickyAcrossDesks"
WINDOWLISTOPTIONS =/ "OnlyStickyAcrossDesks"
WINDOWLISTOPTIONS =/ "NoOnTop"
WINDOWLISTOPTIONS =/ "OnTop"
WINDOWLISTOPTIONS =/ "OnlyOnTop"
WINDOWLISTOPTIONS =/ "NoOnBottom"
WINDOWLISTOPTIONS =/ "OnlyOnBottom"
WINDOWLISTOPTIONS =/ (Layer INT [INT])
WINDOWLISTOPTIONS =/ "UseSkipList"
WINDOWLISTOPTIONS =/ "OnlySkipList"
WINDOWLISTOPTIONS =/ "SortByResource"
WINDOWLISTOPTIONS =/ "SortByClass"
WINDOWLISTOPTIONS =/ "NoHotKeys"
WINDOWLISTOPTIONS =/ "SelectOnRelease"
WINDOWLISTOPTIONS =/ "ReverseOrder"
WINDOWLISTOPTIONS =/ "NoDeskSort"
WINDOWLISTOPTIONS =/ "CurrentAtEnd"
WINDOWLISTOPTIONS =/ "IconifiedAtEnd"
WINDOWLISTOPTIONS =/ "UseIconName"
WINDOWLISTOPTIONS =/ "Alphabetic"
WINDOWLISTOPTIONS =/ "NotAlphabetic"
WINDOWLISTKEYWORD = !!!
WINDOWLISTVALUE = !!!
; note: !!! to do
```
```
CMD_WINDOWSHADE = "WindowShade" ["shadeagain"]
	["last" / DIRS_MINOR] [WINDOWSHADEMODE]
WINDOWSHADEMODE = WINDOWSHADETOGGLE / WINDOWSHADEON / WINDOWSHADEOFF
WINDOWSHADETOGGLE = () / TOGGLE
WINDOWSHADEON = TRUE
WINDOWSHADEOFF = FALSE / "2"
; note: defaults to toggle
; note: if "last" or DIRS_MINOR is present and valid, ignore the
;       WINDOWSHADEMODE argument if present
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_XSYNC = "XSync"
; note: ignores all arguments
; note: syntax description complete
```
```
CMD_XSYNCHRONIZE = "XSynchronize" [BOOL_OR_TOGGLE_DEFAULT_TOGGLE]
; note: argument defaults to toggle if missing or invalid
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_XORPIXMAP = "XorPixmap" [IMAGEFILE]
; note: if argument is missing, maps to "XorValue 0"
; note: ignores rest of line
; note: syntax description complete
```
```
CMD_XORVALUE = "XorValue" [INTEGER_ARGUMENT]
; note: argument defaults to 0 if missing or malformed
; note: argument is converted to unsigned long before use
; note: argument should be parsed as unsigned long to prevent misinterpretation
; note: ignores rest of line
; note: syntax description complete
```
```
;; decor commands

CMD_ADDTODECOR = "AddToDecor" [TOKEN_DECORNAME] RESTOFLINE_COMMAND
; note: does nothing if the decor name is missing
; note: if no decor with that name exists, creates a new one
; note: adds the command to the decor
; note: syntax description complete

CMD_CHANGEDECOR = "ChangeDecor" [TOKEN_DECORNAME]
; note: does nothing if no decor name is given
; note: ignores rest of line
; note: syntax description complete
; note: operates on current window

CMD_DESTROYDECOR = "DestroyDecor" ["recreate"] [TOKEN_DECORNAME]
; note: does nothing if no decor name is given
; note: ignores rest of line
; note: syntax description complete

CMD_UPDATEDECOR = "UpdateDecor" [TOKEN_DECORNAME]
; note: updates all decors if decor name is missing
; note: ignores rest of line
; note: syntax description complete
```
```
;; conditional commands

CMD_BREAK = "Break" [BREAKLEVELS]
BREAKLEVELS = INT
; note: uses -1 if BREAKLEVELS is missing or invalid (<= 0)
; note: syntax description complete
```
```
CMD_CLASS_PICK = ("ThisWindow" / "Pick" / "PointerWIndow" )
	[SELECTCMDCONDITION] RESTOFLINE_COMMAND
; note: syntax description complete
```
```
CMD_ALL = "All" [ALLOPTIONS] [SELECTCMDCONDITION] RESTOFLINE_COMMAND
ALLOPTIONS = "Reverse"
ALLOPTIONS =/ "UseStack"
; note: syntax description complete
```
```
CMD_NOWINDOW = "NoWindow" RESTOFLINE_COMMAND
; note: executes the command without a window context
; note: syntax description complete
```
```
CMD_CLASS_CIRCULATE = ("Any" / "Current" / "Next" / "None" / "Prev")
	[SELECTCMDCONDITION] RESTOFLINE_COMMAND
; note: syntax description complete
```
```
CMD_DIRECTION = "Direction" ["FromPointer"] DIRS_CENTER
	[SELECTCMDCONDITION] RESTOFLINE_COMMAND
; note: syntax description complete
```
```
CMD_SCANFORWINDOW = "ScanForWindow" ["FromPointer"] DIRS_MAIN DIRS_MAIN
	[SELECTCMDCONDITION] RESTOFLINE_COMMAND
; note: syntax description complete
```
```
CMD_WINDOWID = "WindowId"
	[("root" [WINDOWIDSCREENNUM]) / (WINDOWID [SELECTCMDCONDITION])]
	RESTOFLINE_COMMAND
; does nothing if no argument is given of the window id is invalid
; note: syntax description complete
WINDOWIDSCREENNUM = POSINT
; note: valid range is 0 to <number of screens - 1>
; note: fvwm has replaced Xinerama with XRandr, therefore using integers to
;       refer to monitors won't work.
WINDOWID = LONGINT
; note: long value parsed by strtol without error checking
```
```
CMD_TEST = "Test" TESTCMDCONDITION RESTOFLINE_COMMAND
TESTCMDCONDITIONSTRING = [STRING_IN_BRACES / STRING_IN_PARENTHESES]
; note: the STRING_IN_... is then parsed with the TESTCMDCONDITIONS rule
TESTCMDCONDITIONS = STRING_COMMA_TERMINATED *["," STRING_COMMA_TERMINATED]
; note: the TESTCMDCONDITIONS is then parsed with the TESTCMDCONDNEG rule
TESTCMDCONDNEG = ["!"] TESTCMDCOND
TESTCMDCOND = ("version" ((TOKEN_TESTCMDOPERATOR VERSION) / TOKEN_VERSIONPATTERN))
TESTCMDCOND =/ ("EnvIsSet" TOKEN_ENVVAR)
TESTCMDCOND =/ ("EnvMatch" ENVMATCHARG)
TESTCMDCOND =/ (("EdgeHasPointer" / "EdgeIsActive") (DIRS_MAIN / "Any"))
TESTCMDCOND =/ ("Start" / "Init" / "Restart" / "Exit" / "Quit" / "ToRestart")
TESTCMDCOND =/ ("True" / "False")
TESTCMDCOND =/ (("F" / "R" / "W" / "X" / "I") "," FILENAME)
TOKEN_TESTCMDOPERATOR = ">=" / ">" / "<=" / "==" / "!="
ENVMATCHARG = ("infostore."INFOSTOREKEY) / TOKEN_ENVVAR
TESTCMDVERSIONPATTERN = TOKEN
; note: TESTCMDVERSIONPATTERN is compared to the version string (x.y.z) and may
; contain wildcards.
```
```
CMD_TESTRC = "TestRc" [STRING_IN_BRACES / STRING_IN_PARENTHESES]
	RESTOFLINE_COMMAND
TESRRCRCNEG = ["!"] TESTRCRC
TESTRCRC =  "1" / "match"
TESTRCRC =/ "0" / "nomatch"
TESTRCRC =/ "-1" / "error"
TESTRCRC =/ "-2" / "break"
; note: the STRING_IN_... is then parsed with the TESTRCRC rule
; note: does nothing if no command is given
: note: the condition inside the braces or parentheses may contain quoted
; note: syntax description complete
```
```
;; !!! more common rules

; Integer arguments as parsed by GetIntegerArguments()
INTEGER_ARGUMENT = INT

; Loaded by PictureFindImageFile
IMAGEFILE = TOKEN
; note: if file not found, try again with IMAGEFILE ".gz"
```
```
; parsed by parse_gravity_argument
DIR_N = "-" / "N" / "North" / "Top" / "t" / "Up" / "u"
DIR_E = "]" / "E" / "East" / "Right" / "r" / "Right" / "r"
DIR_S = "_" / "S" / "South" / "Bottom" / "b" / "Down" / "d"
DIR_W = "[" / "W" / "West" / "Left" / "l" / "Left" / "l"
DIR_NE = "^" / "NE" / "NorthEast" / "TopRight" / "tr" / "UpRight" / "ur"
DIR_SE = ">" / "SE" / "SouthEast" / "BottomRight" / "br" / "DownRight" / "dr"
DIR_SW = "v" / "SW" / "SouthWest" / "BottomLeft" / "bl" / "DownLeft" / "dl"
DIR_NE = "<" / "NW" / "NorthWest" / "TopLeft" / "tl" / "UpLeft" / "ul"
DIR_C = "." / "C" / "Center" / "Centre"
DIRS_MAJOR = DIR_N / DIR_E / DIR_S / DIR_W
DIRS_MINOR = DIRS_MAIN / DIR_NE / DIR_SE / DIR_SW / DIR_NW
DIRS_ALL = DIRS_MAIN / DIRS_DIAG / DIR_C
```
```
; Parsed by ParseToggleArgument
BOOL_OR_TOGGLE_DEFAULT_TOGGLE = BOOL / TOGGLE
BOOL_OR_TOGGLE_DEFAULT_TRUE = BOOL / TOGGLE
BOOL_OR_TOGGLE_DEFAULT_FALSE = BOOL / TOGGLE
BOOL_DEFAULT_TRUE = BOOL
BOOL_DEFAULT_FALSE = BOOL
```
```
; parsed by strtol
LONGINT = INT
```
```
; parsed by select_cmd()
SELECTCMDCONDITION = [STRING_IN_BRACES / STRING_IN_PARENTHESES]
; note: the STRING_IN_... is then parsed with the CONDITIONMASK rule
```
```
; parsed by CreateFlagString
CONDITIONMASK = [CM_COND_NEG *("," CM_COND_NEG)]
CM_COND_NEG = ["!"] CM_COND
CM_COND = ("AcceptsFocus")
CM_COND =/ ("Focused")
CM_COND =/ ("HasPointer")
CM_COND =/ ("Iconic")
CM_COND =/ ("Visible")
CM_COND =/ ("Overlapped")
CM_COND =/ ("PlacedByButton" [BUTTON])
CM_COND =/ ("PlacedByButton3")
CM_COND =/ ("Raised")
CM_COND =/ ("Sticky")
CM_COND =/ ("StickyAcrossPages")
CM_COND =/ ("StickyAcrossDesks")
CM_COND =/ ("StickyIcon")
CM_COND =/ ("StickyAcrossPagesIcon")
CM_COND =/ ("StickyAcrossDesksIcon")
CM_COND =/ ("Maximized")
CM_COND =/ ("FixedSize")
CM_COND =/ ("FixedPosition")
CM_COND =/ ("HasHandles")
CM_COND =/ ("Iconifiable")
CM_COND =/ ("Maximizable")
CM_COND =/ ("Closable")
CM_COND =/ ("Shaded")
CM_COND =/ ("Transient")
CM_COND =/ ("PlacedByMvwm")
CM_COND =/ ("CurrentDesk")
CM_COND =/ ("CurrentPage")
CM_COND =/ ("CurrentGlobalPage")
CM_COND =/ ("CurrentPageAnyDesk")
CM_COND =/ ("CurrentScreen")
CM_COND =/ ("AnyScreen")
CM_COND =/ ("CurrentGlobalPageAnyDesk")
CM_COND =/ ("CirculateHit")
CM_COND =/ ("CirculateHitIcon")
CM_COND =/ ("CirculateHitShaded")
CM_COND =/ ("State" STATENUM)
CM_COND =/ ("Layer" [INT])
; argument is the layer number; negative values are silently ignored
CM_COND =/ NAMELIST
CM_NAMELIST = NAME *["|" NAME]
CM_NAME = STRING
; up to and excluding next "|"
```
```
QUOTED_TOKEN = TOKEN
```
```
STATENUM = DIGIT / ("1" DIGIT) / ("2" DIGIT) / "30" / "31"
```
```
; Parsed by GetOnePercentArgument()
PERCENT_ARG = INT [PERCENT_ARG_SUFFIX]
PERCENT_ARG_SUFFIX = "p" / "P"
; Parsed by GetTwoPercentArguments()
PERCENT_ARG_PAIR = 2PERCENT_ARG / RECTANGLE_ARGS
; Parsed by GetRectangleArguments()
RECTANGLE_ARGS = INT RECT_CHARACTER INT
RECT_CHARACTER = %x01-09 / %x0b-4f / %x51-6f / %x71-ff
; note: any character except p, P and \n.
DQ_RECT_CHARACTER = %x01-09 / %x0b-4f / %x51-6f / %x71-ff
```
```
;; string rules

DQUOTE = %x22 ; "
SQUOTE = %x27 ; '
BQUOTE = %x60 ; `
CQUOTE = %x5c ; \

; any character except \, ", ', `, whitespace, newline
SCHAR_UNQ = %x01-08
SCHAR_UNQ =/ %x0b-1f
SCHAR_UNQ =/ %x21
SCHAR_UNQ =/ %x23-26
SCHAR_UNQ =/ %x28-5b
SCHAR_UNQ =/ %x5d-5f
SCHAR_UNQ =/ %x61-ff

; any character except \, ", ', `, ), whitespace, newline
SCHAR_UNQ_NO_CPAREN = %x01-08
SCHAR_UNQ_NO_CPAREN =/ %x0b-1f
SCHAR_UNQ_NO_CPAREN =/ %x21
SCHAR_UNQ_NO_CPAREN =/ %x23-26
SCHAR_UNQ_NO_CPAREN =/ %x28
SCHAR_UNQ_NO_CPAREN =/ %x2a-5b
SCHAR_UNQ_NO_CPAREN =/ %x5d-5f
SCHAR_UNQ_NO_CPAREN =/ %x61-ff

; any character except \, ", ', `, ], whitespace, newline
SCHAR_UNQ_NO_CBRACE = %x01-08
SCHAR_UNQ_NO_CBRACE =/ %x0b-1f
SCHAR_UNQ_NO_CBRACE =/ %x21
SCHAR_UNQ_NO_CBRACE =/ %x23-26
SCHAR_UNQ_NO_CBRACE =/ %x28-5b
SCHAR_UNQ_NO_CBRACE =/ %x5e-5f
SCHAR_UNQ_NO_CBRACE =/ %x61-ff

; any character except \, ", ', `, comma, whitespace, newline
SCHAR_UNQ_NO_COMMA = %x01-08
SCHAR_UNQ_NO_COMMA =/ %x0b-1f
SCHAR_UNQ_NO_COMMA =/ %x21
SCHAR_UNQ_NO_COMMA =/ %x23-26
SCHAR_UNQ_NO_COMMA =/ %x28-2b
SCHAR_UNQ_NO_COMMA =/ %x2d-5b
SCHAR_UNQ_NO_COMMA =/ %x5d-5f
SCHAR_UNQ_NO_COMMA =/ %x61-ff

; \ followed by any character except newline
SCHAR_CQ_CHAR = "\" (%x01-09 /%x0b-ff)

; any character except ", whitespace, newline (\ quotes resolved)
SCHAR_DQ = SCHAR_UNQ
SCHAR_DQ =/ SQUOTE
SCHAR_DQ =/ BQUOTE
SCHAR_DQ =/ SCHAR_CQ_CHAR
; any character except ', whitespace, newline (\ quotes resolved)
SCHAR_SQ = SCHAR_UNQ
SCHAR_SQ =/ DQUOTE
SCHAR_SQ =/ BQUOTE
SCHAR_SQ =/ SCHAR_CQ_CHAR
; any character except `, whitespace, newline (\ quotes resolved)
SCHAR_BQ = SCHAR_UNQ
SCHAR_BQ =/ DQUOTE
SCHAR_BQ =/ SQUOTE
SCHAR_BQ =/ SCHAR_CQ_CHAR
; any simple character or one quoted with \
SCHAR_CQ = SCHAR_UNQ
SCHAR_CQ =/ SCHAR_CQ_CHAR
```
```
; unquoted string
STRING_UNQ = 1*SCHAR_UNQ
STRING_UNQ_NO_CPAREN = 1*SCHAR_UNQ_NO_CPAREN
STRING_UNQ_NO_CBRACE = 1*SCHAR_UNQ_NO_CBRACE
STRING_UNQ_NO_COMMASTRING_UNQ_NO_COMMA = 1*SCHAR_UNQ_NO_COMMA
; strings quoted with ", ', `
STRING_DQ = DQUOTE 1*SCHAR_DQ DQUOTE
STRING_SQ = SQUOTE 1*SCHAR_SQ SQUOTE
STRING_BQ = BQUOTE 1*SCHAR_BQ BQUOTE
STRING_Q_PAIR = STRING_DQ / STRING_SQ / STRING_BQ

STRING = 1*(STRING_UNQ / STRING_DQ / STRING_SQ / STRING_BQ)
TOKEN = STRING

; a string with embedded whitespace enclosed in [] used in condigions
STRING_IN_BRACES = *WS
	"[" *(STRING_UNQ_NO_CBRACE / STRING_Q_PAIR / 1*WSC) "]"
; a string with embedded whitespace enclosed in () used in conditions
STRING_IN_PARENTHESES = *WS
	"[" *(STRING_UNQ_NO_CPAREN / STRING_Q_PAIR / 1*WSC) "]"
; a string with embedded whitespace terminated by an unquoted comma
STRING_COMMA_TERMINATED = *(STRING_UNQ_NO_COMMA / STRING_Q_PAIR / 1*WSC)
```
```
;; !!! obsolete commands removed in mvwm

CMD_SAVESESSION = "SaveSession"
CMD_SAVEQUITSESSION = "SaveQuitSession"
CMD_QUITSESSION = "QuitSession"

;; !!! obsolete commands in fvwm2

;; Not fully obsolete, still used for EdgeScroll resistance.
CMD_EDGERESISTANCE = "EdgeResistance" ; Style * EdgeMoveDelay, EdgeMoveResistance
```
