home *** CD-ROM | disk | FTP | other *** search
/ Media Share 9 / MEDIASHARE_09.ISO / progmisc / msh21b.zip / MSHFILES.ZIP / REFMAN.DOC < prev    next >
Text File  |  1992-08-19  |  46KB  |  855 lines

  1.  
  2.                          Mi-Shell Reference Manual
  3.                                 Jean Michel
  4.                       Version 2.10 --- 19 August 1992
  5.  
  6.  
  7. Introduction:
  8.  
  9.     MSH is a ``shell'' which provides a convenient and configurable way to
  10. browse through directories and execute commands on files and sets of files
  11. by a ``point and shoot'' interface.   In contrast to many popular  shells,
  12. MSH is designed to be particularly useful  to a ``power  user;''  there is
  13. no limit to the number of  shortcuts in  everyday work  she can  implement
  14. with it:   an arbitrary sequence of actions (which is written as an  ``MSH
  15. script'')  may  be  assigned  to  each keyboard  key,  and may  depend on  the
  16. environment (like the file currently pointed to, or its extension, etc...).
  17. Of course, MSH is also useful to the average user.
  18.  
  19.  
  20. Installation:
  21.  
  22.     Installation  of  MSH  is  simple.    You  only have  to copy  MSH.EXE  to
  23. some directory in your PATH (the directories which are scanned by  MS-DOS1
  24. to  look  for  commands),  and  copy the  script files  (with extension  .MSH)
  25. to  the  same  directory.    You  should then  modify the  file CONFIG.MSH  to
  26. indicate your display type,  the drives you  can access,  whether you  own
  27. The Berkeley Utilities or not, which directory to use for swap files, which
  28. editor and browser you want to use, etc... In the file there is a series of
  29. lines of the form:
  30.  
  31.     | in the line below, replace "c_blue.msh" by the name
  32.     | of one of the available files describing attributes:
  33.     |  c_mda.msh                  for monochrome displays
  34.     |  c_pcga.msh                 for plasma cga displays
  35.     |  c_blue.msh, c_blue1.msh,
  36.     |  c_blue2.msh, c_white.msh   various possibilities
  37.     |                             for color displays
  38.     |
  39.     "c_blue.msh"loaddefs               | load blue color
  40.                                        | set attributes
  41.  
  42. you  should  do  at  it  says,  e.g.   replace  c_blue by  c_mda  if you  have
  43. a monochrome display.   You can define your  own colors for  MSH; see  the
  44. appendix on attributes.
  45.     You now modify the following two lines to define your available drives:
  46.  
  47.     "CD" fixed_drives!     | define your fixed drives
  48.     "AB"floppy_drives!     | define your floppy drives
  49.  
  50.     Similarly, there are these 3 lines in the file:
  51.  
  52.     true delta!
  53.     true berk!
  54.     true berk_cpmvrm!
  55. ----------------------------
  56.   1  MS-DOS is a trademark of Microsoft Corporation
  57.  
  58. If  you  do  not  own  DELTA,  you  should  replace  true  by  false  on  the
  59. first  line  and  similarly  for  the  second  and third  if  you do  not  own
  60. The Berkeley Utilities.   The third line refers to whether you want to use
  61. cp, mv and rm or DOS's copy and delete commands for these functions.
  62.     Finally, there are lines reading:
  63.  
  64.     | next line defines the place for "magic" swap files
  65.     (prog_dir)tmp_dir!
  66.     | put swap files in same directory as MSH.EXE
  67.  
  68. They specify the directory to use for swap files (see ``Technical highlight
  69. no.   2'';  used when MSH cannot swap itself  to extended memory).    This
  70. should be a virtual disk or a fast hard disk if you have one.  You can set
  71. tmp_dir to the empty string ("") to disable swapping to disk.
  72.     Also, MSH does not provide a built-in editor:   the idea is rather  to
  73. let you use your own.   If  you do  not have  one,  we include MWE.EXE,  a
  74. multi-window editor which was developed as a demo of the power of TextLib,
  75. a  keyboard  and  screen  management  C  Library  distributed  by  OPENetwork.
  76. Similarly, you may use your own browser  instead of  the built-in one  (it
  77. will be slower).   Of course, you must specify what it is  to MSH; so,  in
  78. CONFIG.MSH you must adapt the lines which say:
  79.  
  80.     "mwe "editor!
  81.     "more "browser!
  82.  
  83. to  specify  what  is  your  editor  and browser;  for  instance,  if you  use
  84. the  mediocre  but  widespread  Wordstar  as  an  editor,  and  the  excellent
  85. public-domain browser list by V.Buerg, you may change the above lines to:
  86.  
  87.     "ws "editor!
  88.     "list "browser!
  89.  
  90. Some people have such a good editor, or like their  bad one so much,  that
  91. they will use it as their browser.   If  your editor  or browser does  not
  92. work with the simple syntax ``edit filename'' or needs extra arguments  or
  93. parameters after the filename, you can still manage, but you will have  to
  94. make more complex modifications to CONFIG.MSH.
  95.  
  96. Starting to use the default configuration
  97.     You can then start MSH just by typing its name.   The initial  display
  98. you get should be:  a menu bar at the top above two panels, each containing
  99. a display of the files in your current directory, and a list  of available
  100. drives.    All  this  is  completely  configurable.    We  describe  here  the
  101. behavior of MSH when you don't modify the CONFIG.MSH file.
  102.     We support extended video modes and extended versions of ANSI.SYS. The
  103. initial number of lines of a panel will be half the number of  total lines
  104. of your display(e.g. in 43-lines EGA mode, you will get 21 lines, and 25 in
  105. the 50-lines VGA mode instead of the usual 12 in  a 25-lines mode; if  you
  106. have a 132-columns mode you will get 3 panels, and 1 panel in a 40-columns
  107. mode).  If you have a VGA or EGA card, you can ask MSH to first switch the
  108. screen to given number n of lines by giving the option -ln on  the command
  109. line (the letter ell); for instance msh -l50 asks MSH to switch the screen
  110. to 50-line mode before starting.  The only values of n currently understood
  111. are 25, 43 and 50.
  112.  
  113.     The  first  line  of  a  panel contains  a  ``pattern'', i.e.  a  wildcard
  114. describing  all  files  in  the  current  directory  at  the  left   (e.g.
  115. c:\dos\*.*).   This is highlighted if the panel is the active  panel.   At
  116. the bottom of a panel are titles  for the various  columns of the  display
  117. (Name.ext, size, time) which are highlighted according to the current sort
  118. order of the panel.
  119.     Most of your interaction with MSH is via what you type on the  command
  120. line.   MSH monitors all your keystrokes and decides what to do with  them
  121. according  to  your  own  instructions  given  via  the CONFIG.MSH  file  (the
  122. default configuration sets things so that  you can  also execute  Mi-Shell
  123. script instructions directly from the command line with the key AltX).
  124.     MSH  when  started  always  tries to  locate  the file  CONFIG.MSH in  the
  125. directory where MSH.EXE is located, unless you give it an explicit filename
  126. as argument.  Two tutorials are on-line when you hit the F1 key to help you
  127. get started.
  128.  
  129. The Mi-Shell script language:
  130.  
  131.     The configuration of MSH is done by  its reading upon  start the  file
  132. CONFIG.MSH. This file is entirely in the  MSH script language.   Any  text
  133. following  a  non-quoted  |  up  to the  end of  a line  is a  comment and  is
  134. ignored.   The rest of the text represents instructions in the MSH  script
  135. language, which is a small Forth-like stack language.
  136.     As  we  proceed  to  describe  the  language,  you  can find  some  useful
  137. examples  which  might  help  in  the  section  ``quick  start  at  modifying
  138. CONFIG.MSH''.
  139.     The  only  elements  of  the  language  are  "  which  delimits  character
  140. strings, brackets () which delimit blocks of  code, and identifiers  which
  141. are  either  words  formed  from  the characters  a--z A--Z  0--9  or dot  (.)
  142. or  underscore  (_)  or  dollar  ($),  or  symbols  constituted by  any  other
  143. single character.   Identifiers represent primitive or user-defined actions
  144. (their  value  is  then  a  block  of code),  or  variables holding  character
  145. strings, excepted that identifiers starting with a digit are interpreted as
  146. character strings as if they were quoted.   This is to allow you to  write
  147. numbers without having to surround them with " (negative numbers like "-1"
  148. still have to be quoted).   A  number is  just a  particular string  whose
  149. content is interpretable as a number, and all string operation apply to it;
  150. only the arithmetic operations try to interpret their string arguments  as
  151. numbers.  Below are some strings:
  152.  
  153.     "abc", "you can put '\"' in a string", 3, "3".
  154.  
  155. The last 2 strings are the same.  Below are some identifiers
  156.  
  157.     foo, bar, foo_bar, +, !, f31.
  158.  
  159.     The  language  is  a  stack  language  like  FORTH.  The  stack  contains
  160. either character strings or pieces (blocks) of  code.   In the  subsequent
  161. descriptions  [top]  represents  the  stack  top,  [top+1] the  next  element,
  162. etc...; push something is the action of pushing something onto the  stack.
  163. Actions typically read one or more values by popping  them from the  stack
  164. (reading [top] always unstacks it) and return possible results by  pushing
  165. them on the stack.   Some actions are predicate-like:   the logical  value
  166. false is represented by the empty  string and  true by  any other  string.
  167. The variables false and true are primitives and contain the values ""  and
  168. "true" respectively.  Variables which hold the value true or false will be
  169. called boolean in what follows.
  170.     A  character  string  is  written  "string"  where  internal `"'  must  be
  171. quoted by preceding them with \; a character string may span several lines
  172. and contain embedded carriage returns.   Merely writing a character string
  173. pushes  it  onto  the  stack.    Other identifiers  cause their  corresponding
  174. actions to be executed or their value to be pushed when encountered, except
  175. that a sequence of actions (or character string denotations) between  `()'
  176. is pushed onto the stack as a piece of code instead.
  177.     A character string or a piece of code may be assigned to an identifier
  178. by the action !; e.g., "hello" "H"!  or ("")"false"!.  In BASIC, this would
  179. be written as H = "hello" or as
  180. false  =  "".    As  a  special  syntactic  convention,  the form  name!    is
  181. equivalent to "name"!, so the above examples may be written "hello"H!  and
  182. ("")false!.
  183.  
  184.     We should mention that some variables are ``system variables'':   like
  185. primitives, they are defined by the system.  Some of them can be set by the
  186. system as well as the user, and when the user sets them some sytem-defined
  187. action results.  An example is cwd, the current working directory:  setting
  188. its value will change the current directory.
  189.     Also,  as  a  special  facility,  a  variable name  beginning  with a  `$'
  190. represents a MS-DOS system variable (such  as PATH or  COMSPEC); the  name
  191. must  be  in  uppercase  letters  to  be  recognized  as  a  system  variable.
  192. Assigning  to  such  variables  will  modify  the  MS-DOS  environment.    For
  193. instance:
  194.  
  195.     $PATH ";\mydir"& $PATH!
  196.  
  197. can  be  used  to  modify  the PATH.  Beware!    Only the  local  copy of  the
  198. environment owned by MSH will be modified (which means that you will  lose
  199. your modifications to the environment when leaving MSH; we might provide a
  200. way around that in future versions).
  201.     Some  identifiers  represent  the  name  of  keys,  and  they  are  called
  202. whenever the corresponding key is pressed.   The definable keys and  their
  203. names are:
  204.     Function keys F1--F10 ShiftF1--ShiftF10
  205.                   CtrlF1--CtrlF10 AltF1--AltF10
  206.     Control keys  CtrlA--CtrlZ
  207.                   Ctrl Break is always a ``break'' key, used to  interrupt
  208.                   actions (like get out of loops)
  209.     ``Alt'' keys  AltA--AltZ Alt0--Alt9 AltMinus AltEqual
  210.     Other keys    Home End Left Right PgDn PgUp Down Up
  211.                   Delete Insert BackSpace
  212.                   CtrlHome CtrlEnd CtrlLeft CtrlRight
  213.                   CtrlPgDn CtrlPgUp
  214.                   ShiftDown  ShiftUp  ShiftLeft  ShiftRight  Esc  Tab  BackTab
  215.                   Enter CtrlEnter
  216.                   GreyPlus GreyMinus GreyStar CtrlPrint
  217.     We now proceed to list the primitive actions, arranged by category.
  218.  
  219. ``Language'' functions:
  220.  
  221.     drop       Do nothing with [top] (and so just unstack it).
  222.     dup        Duplicate [top].
  223.     pick       [top] should be some number n.  If these are the objects on
  224.                the stack, starting from the bottom:
  225.                O(n), O(n-1) ...  O(2) O(1) n
  226.                then after the command the stack will look like:
  227.                O(n) O(n-1) ...  O(2) O(1) O(n)
  228.                so that 1 pick is equivalent to dup.
  229.     swap       Exchange [top] and [top+1].
  230.     roll       [top] should be some number n.   If objects on top of stack
  231.                are:
  232.                O(n), O(n-1) ...  O(2) O(1) n
  233.                after the command they will be:
  234.                O(n-1) ...  O(2) O(1) O(n)
  235.                so that 2 roll is equivalent to swap.
  236.  
  237.     stack_size push as a number the size of the stack.
  238.     not        Push false if [top] is not false, true otherwise.
  239.     =          If [top]=[top+1], push [top] else push false.
  240.     &          push the catenation of [top] and [top+1].
  241.     match      If [top] matches [top+1], push [top] else push false.
  242.     cutfirst   Cuts [top+1] at [top], that is look for first occurence  of
  243.                string [top] in [top+1],  and replace [top] and [top+1]  by
  244.                the  part  of  [top+1]  after  [top] and  the  part of  [top+1]
  245.                before [top] (the first may be empty if [top] does not occur
  246.                in [top+1]).
  247.     cutlast    Like  cutfirst,  but  looks  for  last  occurence of  [top]  in
  248.                [top+1].
  249.     length     push the length of the string [top].
  250.  
  251.     substring  extract  from  [top+2]  the  substring  which starts  with  the
  252.                [top+1]th character and ends with the [top]th character, and
  253.                push it on the stack.
  254.     if         If [top+1] is not false execute [top] else do nothing.
  255.     ifnot      If [top+1] is false execute [top] else do nothing.
  256.  
  257.     ifelse     If [top+2] is false execute [top] else execute [top+1].
  258.     while      While  execution  of  [top+1]  does  not yield  false,  execute
  259.                [top].
  260.     #          Interpret the string [top] as a piece  of code and  execute
  261.                it.
  262.  
  263.     @          Interpret  [top]  as  an  identifier  name  and replace  it  by
  264.                its  value.    If  the  value  is  a  piece  of  code,  it  is
  265.                ``uncompiled'' as a character string.
  266.     isdefined  Interpret [top] as an identifier name.   Push true if  this
  267.                identifier has been assigned a value, false otherwise.
  268.     !          Interpret [top] as an identifier name and assign [top+1] to
  269.                it.
  270.  
  271.     +          Push [top+1]+[top](interpreted as numbers).
  272.     -          Push [top+1]-[top](interpreted as numbers).
  273.  
  274.     *          Push [top+1]*[top](interpreted as numbers).
  275.     /          Push [top+1]/[top](interpreted as numbers).
  276.     <          Push  true  if  [top+1]<[top](interpreted  as  numbers),  false
  277.                otherwise.
  278.  
  279.     le         Push true if [top+1]<=[top](interpreted as numbers),  false
  280.                otherwise.
  281.     >          Push "true" if [top+1]>[top](interpreted as numbers), false
  282.                otherwise.
  283.     ge         Push "true" if [top+1]>=[top](interpreted as numbers), false
  284.                otherwise.
  285.  
  286.     debug      System  variable.    If  "true",  MSH  is  in  ``debug''  mode:
  287.                before any identifier is executed, a window pops up showing
  288.                it and the current state of the stack.
  289.  
  290. Panels, menus, windows and mouse support:
  291.     MSH lets you manipulate several kinds of windows:
  292.   - Panels,  wich  are  ``directory  browsers''.    You  get  two of  them  in
  293.     the  default  configuration.    You  can move  them  around, change  their
  294.     attributes,  what  they  display,  keys  associated to  them,  etc...These
  295.     are ``permanent'' windows (they don't disappear when you have finished
  296.     interacting with them).   Permanent windows have numbers (``handles'')
  297.     associated  with  them  on  creation.    You  may  use  these  numbers  to
  298.     reactivate them (put them in front, ready to receive your  keystrokes)
  299.     later  (windows  can  also  be  activated  by clicking  on them  with  the
  300.     mouse).
  301.   - Menus,  which are actually general ``hypertext'' windows where  fields
  302.     in the window have actions associated  to them.   They  can be  either
  303.     permanent  (they  have  then  numbers  associated  to them)  or  temporary
  304.     (they disappear when you make a choice).
  305.   - Message, choice and dialog windows.  The error windows that the system
  306.     displays sometimes are of a similar kind.  These are temporary windows.
  307.     A message just displays some text.  A dialog window displays some text
  308.     and waits for your input.  A choice window allows you to give a Yes/No
  309.     answer.   A menu could do the  same job  but this  provides a  simpler
  310.     solution.
  311.     At  present,  mouse  support  is  limited to  actions done  on clicks  and
  312. double  clicks.     More  complex  interaction  (like  drags)  are  not  yet
  313. implemented,  mostly  because  of  the  complexity of  the necessary  language
  314. support to describe them.
  315.  
  316. Panels functions:
  317.     panel.install    Creates  a  new  panel.     Only  one  panel  displaying
  318.                      nothing (with number 1) exists at the  start.   Other
  319.                      panels  must  be  created  with  this  command.     One
  320.                      argument must be given on [top], the initial selection
  321.                      pattern  of  the  newly  created  panel.    The  current
  322.                      panel is set to the created panel.   Other attributes
  323.                      of a panel are set/modified with the following system
  324.                      variables.     panel.install  pushes  one  result,  the
  325.                      number assigned to the panel.
  326.     panel.pattern    System  variable.    Represents  the  `pattern'  of  the
  327.                      current panel (the selection pattern displayed at the
  328.                      top  of  the  panel).    Setting  this  variable  causes
  329.                      the  panel  to  be  refreshed  by reading  from disk  the
  330.                      list  of  files  matching  the  pattern (the  father  and
  331.                      subdirectories  of  the  current  directory  are  always
  332.                      displayed).     As  a  special  facility,  this  can  be
  333.                      assigned  a  pathname  composed  of  the  pathname  of  a
  334.                      ``.zip'' or ``.arj'' archive file + a  pattern.   The
  335.                      panel will then display the list of all files  inside
  336.                      that  archive  which  correspond  to  the given  pattern.
  337.                      We  might  add  support  for  other  kinds  of  archives
  338.                      (.lzh, .arc, .zoo) in the future.
  339.     panel.type       Returns  the  type  of  the  current  panel:    ""  for
  340.                      ordinary panels, ".zip" for a zip archive, ".arj" for
  341.                      an arj archive.
  342.  
  343.     panel.sort       System  variable.    Represents  the  sort  order of  the
  344.                      current  panel.    It  can  be  assigned  the  following
  345.                      values:
  346.                  "N" --- sort the panel by name;
  347.                  "S" --- sort the panel by size;
  348.                  "T" --- sort the panel by date;
  349.                  "E" --- sort the panel by extension.  Sorting by extension
  350.                      keeps as a secondary key the previous sort,  whatever
  351.                      it was.   This is reflected in the highlighted titles
  352.                      at the bottom of the panel.It also means that in  the
  353.                      case of an extension sort, the value of panel.sort is
  354.                      actually one of "EN", "ES" or "ET".
  355.     panel.size       Boolean  system  variable  which  controls  whether  the
  356.                      file size is displayed for each file  of the  current
  357.                      panel.
  358.     panel.attrs      Like panel.size, controls whether the read/write/system--
  359.                      /hidden attributes are displayed.
  360.     panel.date       Like  panel.size,  controls  whether  the  last  modified
  361.                      date is displayed.
  362.     panel.time       Like  panel.size,  controls  whether  the  last  modified
  363.                      time is displayed.
  364.     panel.sec        Like  panel.size,  controls  whether  the  last  modified
  365.                      time is displayed up to the second.
  366.  
  367.     panel.on         Boolean system variable.  Controls whether the current
  368.                      panel is on.   When off, the panel won't be displayed;
  369.                      this is useful to have temporarily an unimpeded  view
  370.                      of  the  screen  behind  the  panel (in  addition to  the
  371.                      panels, the menu bar can be shut off by  uninstalling
  372.                      it;  this  allows  the  use  of  MSH  as  a  ``silent''
  373.                      background task).
  374.     panel.rc         System  variable  representing  the  number  of rows  and
  375.                      columns  of  the  current  panel.    When  read causes  2
  376.                      values to be pushed on the stack, first the number of
  377.                      lines and then the number of columns.   Similarly  it
  378.                      should be set by pushing 2 values on the stack  (e.g.
  379.                      12 40 panel.rc!).
  380.  
  381.     panel.startrc    System variable.   Represents the start row and start
  382.                      column of the current panel (the  coordinates of  the
  383.                      top left corner).
  384.     panel.nbfiles    push the total number of entries of the current panel.
  385.  
  386.     panel.att        Function  taking  4  arguments  representing  the  video
  387.                      attributes used to display the pattern.   They should
  388.                      be given in ANSI format and represent:
  389.                      Normal --- the normal attribute for files in a panel;
  390.                      Current --- the attribute of current  name,  the file
  391.                      pointed to by the cursor;
  392.                      Selected --- the attribute of selected files;
  393.                      Selected + Current --- the attribute of current  name
  394.                      when it happens to be a selected file.
  395.  
  396.     current.name     push the filename of the entry pointed by the  cursor
  397.                      in  the  current  panel  (this  entry  will  be  called
  398.                      `current name' in the subsequent descriptions).
  399.  
  400.     current.isdir    push  false  if  current  name  is  not  a  directory,
  401.                      otherwise push current name (usable as a predicate).
  402.  
  403.     current.size     push the size (in bytes) of current name.
  404.  
  405.     current.time     push the last modified time of  current name.    This
  406.                      time is encoded as an integer by the formula:
  407.  
  408.                                        2x(seconds+
  409.                                       32x(minutes+
  410.                                       64x(hours+
  411.                                       32x(days+
  412.                                       32x(months+
  413.                                       16x(years-1980))))))
  414.  
  415.  
  416.  
  417.  
  418.     current.selected System variable whose value is true or false.  Setting
  419.                      it  to  true  selects  current  name;  this  highlights
  420.                      it  and  marks  it  as  ``selected''  which  means  that
  421.                      current.selected  will  return  true  until  it is  again
  422.                      deselected by setting current.selected to false.
  423.  
  424.     current.pos      System variable which represents the position of  the
  425.                      cursor  in  the  current  panel  relative  to  the  total
  426.                      number  of  files.    Setting  this  variable  moves  the
  427.                      cursor.   Values outside of the interval [0,panel.nb-
  428.                      files-1] are mapped to 0 or panel.nbfiles-1.
  429.  
  430.  
  431. Mouse actions:
  432.  
  433.     User-defined mouse actions on a panel are provided as follows:  when a
  434. mouse event on the panel is detected:
  435.   - It  is  activated  if  it  was not  active  (and panel.on_activate  (which
  436.     should contain an action) is executed).
  437.   - A two-part name is built and is executed (it should contain an action);
  438.   - The first part of the name describes the event:
  439.     LeftClick,  LeftDbleClick,  RightClick,  RightDbleClick,  MiddleClick,
  440.     MiddleDbleClick.
  441.   - The end part of the name  describes the area  of the  panel where  the
  442.     event occured:
  443.     N --- On the word ``name'' at the bottom of the panel.
  444.     E --- On the word ``ext''.
  445.     S --- On the word ``size''.
  446.     T --- On the word ``time''.
  447.     UA --- On the up arrow of the scroll bar.
  448.     DA --- On the down arrow of the scroll bar.
  449.     Entry --- On an entry.   In that  case before executing  the name  the
  450.     number of the entry is pushed.
  451.  
  452. Menu functions:
  453.     The only function proper to menus  is menu.install.   The  way a  menu
  454. works is by executing actions (pieces of code) associated to fields in its
  455. window (``menu selections'').  When a menu is active, the cursor keys move
  456. between menu selections.   The currently highlighted selection is executed
  457. when pressing the key Enter or when  clicking with the  mouse on  it.   An
  458. Escape or clicking outside a selection  field quits the  menu without  any
  459. selection being done.   The arguments to menu.install describe  completely
  460. the menu.  They are in order:
  461.   - A list of actions (pieces of  code) to  be executed  for various  menu
  462.     selections.
  463.   - A string, the text of the menu window.  Fields which should operate as
  464.     menu selections are delimited by % in that string (a  % can be put  in
  465.     the menu by doubling it:   %%).   The fields are matched to actions in
  466.     order.  There should be exactly as many actions as there are fields.
  467.   - An  action  which  is  executed  when  the  menu  is  exited  without  any
  468.     selection made (often the empty action  () is  suitable).   This  will
  469.     occur when the user has activated a menu and then hits ESC.
  470.   - The  coordinates  of  where  to  put the  upper left  corner  of the  menu
  471.     window (a "-1" means center the menu in that direction).
  472.   - Three video attributes given as ANSI strings, to use for displaying the
  473.     menu:
  474.     Normal --- the attribute for normal text in the menu window;
  475.     Selection --- the attribute of a menu selection;
  476.     Highlighted --- the attribute of the highlighted menu selection;
  477.   - A string which determines what kind of border the menu should have, and
  478.     if it should have a title:
  479.     "" --- no border.
  480.     ":" --- single line border.
  481.     "v:" --- single line horizontal / double line vertical border.
  482.     "h:" --- single line vertical /double line horizontal border.
  483.     "vh:" --- double line vertical /double line horizontal border.
  484.     To  specify  a  title  add  it to  the  string.   For  example,  "v:Hello"
  485. specifies a border with double vertical lines, and single horizontal lines,
  486. with 'Hello' as title.
  487.   - A boolean value wich determines if the menu should be permanent.
  488.     For a permanent menu, menu.install returns a value, the number assigned
  489. to the menu.
  490.  
  491.  
  492. Permanent Windows Control:
  493.     Two functions control permanent windows:
  494.     window.activate  Takes as argument the number of the window to activate
  495.                      (panel  or  menu).    An  active  menu  is recognized  by
  496.                      having a higlighted selection.   An active panel  has
  497.                      a highlighted title (and if any files are  displayed,
  498.                      current  name  is  highlighted).     When  activating  a
  499.                      panel, the action panel.on_activate is executed.  This
  500.                      can be set by the user; in the default  configuration
  501.                      what it does is attach to the directory of the panel.
  502.                      An active window is put on top of the others.
  503.     window.uninstall Takes as argument the number of the window to delete;
  504.                      deletes that window (menu or panel).
  505.  
  506.     It is sometimes convenient to give consecutive numbers to a series  of
  507. panels or menus (the functions next_panel and previous_panel of the default
  508. configuration do that).   The number given  to a newly  created window  is
  509. the first available number, so this can be arranged  by just creating  the
  510. windows consecutively when there has been no deletions.
  511.  
  512.  
  513. Other Windows:
  514.  
  515.     message   Display [top] as a message with title [top+1].   This message
  516.               is left displayed until any key is typed.  If the text of the
  517.               message does not fit on the screen, it is shown screenful by
  518.               screenful until the end.   This can provide a primitive kind
  519.               of browser.
  520.  
  521.     flash     Display [top] as a message with title [top+1].   This message
  522.               is left displayed for the number of milliseconds specified by
  523.               [top+2].
  524.  
  525.     ok        Display [top] as a message and ask confirmation with a Yes No
  526.               choice.   Replaces [top] by false in case of non confirmation
  527.               (so may be used as a predicate).
  528.  
  529.     input     Display [top+1] as a message and ask for input in a field of
  530.               length [top].  The input is pushed on the stack.
  531.  
  532.     get_key   Display [top] as a message with title [top+1].   Return as a
  533.               character string the name of the first key typed.
  534.  
  535.     alert_att System variable whose value represents (in ANSI format)  the
  536.               color attribute to be used for the message, flash, ok, input
  537.               and  get_key  windows.    (``alert''  refers  to  the  temporary
  538.               ``pop-up''  windows  of  MSH:  the  ones  mentioned  above,  the
  539.               warnings and the debug window).
  540.  
  541.  
  542. Command line:
  543.  
  544.     cmd.del       Delete the current character in the command line.
  545.  
  546.     cmd.pos       System variable representing the position of the  cursor
  547.                   in the command line (first position is 0).
  548.     cmd.wordleft  Go one word left in the command line.
  549.  
  550.     cmd.wordright Go one word right in the command line.
  551.     cmd.clear     Reset to zero the command line.
  552.  
  553.     cmd           System variable representing the command line.   Reading
  554.                   it pushes the command line contents.   Setting it writes
  555.                   [top]  to  the  command  line;  but note  that  the text  is
  556.                   added  to  the  command  line  where the  cursor  is in  it.
  557.                   Call cmd.clear first to replace the command line contents
  558.                   by new contents.
  559.  
  560.     cmd.imode     Boolean system variable representing if the command line
  561.                   is in insert mode.
  562.  
  563. Other:
  564.  
  565.     read          Read the file whose name is [top] and  push as a  string
  566.                   its contents.
  567.  
  568.     write         Writes  (creates  or  appends)  to  the file  whose name  is
  569.                   [top+1] the string [top].
  570.  
  571.     unlink        removes file whose name is [top].
  572.  
  573.     rename        renames  file  whose  name  is  [top+1]  to  name  given  by
  574.                   [top].   As for the DOS call,  it is possible to  rename
  575.                   empty directories, and to move files between directories
  576.                   of  the  same  drive  with  this  call.    pushes  [top]  if
  577.                   successful, false otherwise (e.g.  target exists or is in
  578.                   a different drive).
  579.  
  580.     copy          copies file whose name is [top+1] to name given by [top].
  581.                   [top] will be overwritten if it exists; copy works across
  582.                   different  drives.    pushes  [top]  if  successful,  false
  583.                   otherwise (e.g.   if there was a disk full on the target
  584.                   drive).
  585.  
  586.     testfile      Returns  false  if  there  exists  no file  with name  [top]
  587.                   (which includes the case when a directory with name [top]
  588.                   exists), otherwise pushes the size and last modified time
  589.                   (see format in current.time) of found file.  This routine
  590.                   can  test  if  a  file  exists  inside a  supported  archive
  591.                   type.
  592.  
  593.     tempname      Creates a temporary file name (a name guaranteed to be a
  594.                   non existent file) in the directory specified by [top].
  595.     disk_stats    pushes  the  following  information  on  the  drive  whose
  596.                   letter  is  given  by  [top]  (if  [top]  is  ""  returns
  597.                   information  on  current  drive):   size  of  a  cluster  in
  598.                   bytes,  number  of  available  clusters,  total  number  of
  599.                   clusters.
  600.  
  601.     capture_screenGrabs the contents of the screen  as a  string and  push
  602.                   it  on  the  stack.    Takes  one  boolean  argument:    if
  603.                   true, makes a graphic capture, encoding video attributes
  604.                   as  ansi  escape  sequences,  which  allows  to  redisplay
  605.                   the screen colors using the built-in browser  of MSH  or
  606.                   MS-DOS's ANSI.SYS.
  607.  
  608.     prog_pathname push the pathname of msh.exe.
  609.     cwd           System   variable   holding   the   name   of  the   current
  610.                   directory.   Setting it attaches to the directory  whose
  611.                   name is [top].
  612.  
  613.     linescols     System  variable  holding  the  total  number of  lines  and
  614.                   columns on the screen.   It may be  used in  conjunction
  615.                   with panel.rc and panel.startrc to program  a setup  for
  616.                   the screen.
  617.  
  618.     execute       Send [top] to command.com to be executed.
  619.  
  620.     magic         System  variable.     If  not  false,  should  specify  a
  621.                   directory where MSH will swap itself out of memory before
  622.                   sending any command to MS-DOS for execution if it cannot
  623.                   swap itself to extended memory.  As a special convention,
  624.                   if it starts with a `*', it means that swapping to XMS is
  625.                   not desired.  See ``Technical highlight no.  2''.
  626.     page          Call the built-in browser.   It takes 9 arguments:   the
  627.                   name of the file to browse followed  by the  coordinates
  628.                   of the window for the browser (start row, start  column,
  629.                   number  of  rows,  number  of  colums) and  by  the list  of
  630.                   video attributes to use in the browser:
  631.                   Browser  window  ---  the  attribute  of the  window of  the
  632.                   browser.
  633.                   Browser highlight --- the attribute of  the status  line
  634.                   and of highlighted text in the browser.
  635.                   Empty --- the attribute used when showing empty space in
  636.                   the browser.
  637.                   Tab  ---  the  attribute  used  when  showing  tabs  in  the
  638.                   browser.
  639.     beep          As its name says.
  640.     time          push   the   current   time   (in   the   same   format   as
  641.                   current.time).
  642.     timer         MSH has a ``timer'' which allows you to do some  actions
  643.                   at regular times (which may be used to show a clock)  or
  644.                   after some delay (which may be  used to  set an  alarm).
  645.                   [top]  should  contain  the  action  to do  (as  a piece  of
  646.                   code)  and  [top+1]  a  number  specifying  how  many  ticks
  647.                   (1=17 sec.)   from now this action should be  done.   To
  648.                   do an action repeatedly,  you can write an action  which
  649.                   contains  a  call  to  set  the  timer  with  itself,  e.g.
  650.                   after (f 1000 (g)timer)g!   a call to g  will execute  f
  651.                   repeatedly every 1000 ticks.
  652.     reinit_mouse  With  some  versions  of  the  Microsoft  mouse  driver  and
  653.                   some mouse programs, the mouse driver in MSH may  become
  654.                   inactivated when returning from execute.   This  command
  655.                   reinitializes it (it is not done systematically since it
  656.                   takes 1 to 2 seconds).
  657.     mouse.click   System variable.  Holds the interval between the 2 clicks
  658.                   of a mouse double click.  By default its value is 3 which
  659.                   means 3 ticks (ie 3 seventeenths of asec.).  You may want
  660.                   this to be a bit slower if you are not a Mac user ...
  661.     quit          Quit MSH.
  662.  
  663.  
  664. A quick start at modifying .MSH files:
  665.  
  666.     The first thing you might want to  do is add  to EXT.MSH  instructions
  667. to deal with other types of  files,  recognized by their extension.    For
  668. instance,  I  use  Knuth's  TeX  text-processing  language,  which  produces
  669. device-independent  output  files  ready  to  be  printed  or  viewed  on  the
  670. screen;  what  I  want  to  do  when I  point  to such  a file,  say  foo.dvi,
  671. and  order  MSH  to  act  by  pressing  the  Enter  key,  is  to  see  what's
  672.  
  673. in  it,  i.e.  call  my  previewer  (called  view)  with  a  command  such  as
  674. view  foo.dvi.    What  I  did  in order  to get  this is  add a  line to  the
  675. series of lines in EXT.MSH which end by extension_something (a typical one:
  676. (current.name pager)extension_cfg!)  saying:
  677.  
  678.     ("view "current.name & execute)extension_dvi!
  679.  
  680. how  does  this  work?    When  enter  is pressed,  by  a mechanism  described
  681. below, MSH sees that the command line is empty and decides to  execute the
  682. identifier extension_xxx where xxx is the extension of current  name.   It
  683. is the line above which gives a definition to the identifier extension_dvi.
  684. The final !   is the assignment  operator which  assigns to  extension_dvi
  685. what's  on  the  stack.    What  is  there  is the  code  in brackets  at  the
  686. beginning  of  the  line,  which  has  been  pushed by  the simple  virtue  of
  687. appearing  there.     What  does  this  code  do?     First,  it  pushes  the
  688. string "view " on the stack, then current name,  then catenates [top]  and
  689. [top+1](operator  &);  now  [top]  contains  "view foo.dvi";  finally  execute
  690. sends that string to MS-DOS to be executed; you can watch the  whole thing
  691. in action by doing the following steps:
  692.   - Position cursor on foo.dvi and make sure the command line is empty.
  693.   - Press AltD. If your configuration is the  default one,  this make  MSH
  694.     enter debug mode.
  695.   - Press Enter.   You will then see the debugger window, which includes a
  696.     view of the stack.  Press s to step through the code of extension_dvi.
  697.   - Press g (go) when in debug window to leave debug mode.
  698.  
  699.     Let us now have a more elaborate  text explanation by  looking at  the
  700. code which is executed when pressing  Enter.   The code  is the  following
  701. lines in KEYBIND.MSH:
  702.  
  703.     (cmd
  704.       (execsave)
  705.       (act_on_cur)
  706.       ifelse
  707.     )Enter!
  708.  
  709. We first put the contents of  the command  line on the  stack (cmd).    To
  710. understand  what  happens  next  you  have to  notice that  the rest  consists
  711. of  2  blocks  of  code  followed  by ifelse.    That's  a perfectly  ordinary
  712. if construct, excepted that control structures don't  always look nice  in
  713. reverse polish notation.  The way ifelse works is:  it expects 2 blocks of
  714. code on the stack, and, above that, a value which is false  (empty string)
  715. or not (non-empty string), and execute one or the other piece of code based
  716. on that value.   The net effect here is to execute the first piece of code
  717. if the command line is non-empty and the second otherwise.
  718.     The first piece is a definition:
  719.  
  720.     (cmd dup cmdlist nl&swap&cmdlist!execute
  721.           cmd.clear refresh)execsave!
  722.  
  723. it recalls again the command line, duplicates it, uses one copy to store in
  724. the circular list of commands cmdlist (where previously typed commands are
  725. kept, separated by newlines (the content of the variable nl), for reuse if
  726. recalled by the user), and executes the other copy; then clears the command
  727.  
  728. line and calls refresh; this last is itself a definition that you can find
  729. in STDDEFS.MSH:
  730.  
  731.     (cwd panel.pattern filepart makename panel.pattern!)
  732.            refresh!
  733.  
  734. The purpose is to refresh the display  in the current  panel, which  might
  735. be necessary since the executed command  may have  destroyed files  and/or
  736. changed directories.  To do that, we first get the current directory's name
  737. on the stack, then catenate to it the filename part of the wildcard of the
  738. current panel (usually "*.*", but it may be set  to something else),  then
  739. put that as the pattern to select files in the current panel.  filepart and
  740. makename are also definitions that we don't show here.
  741.  
  742.     Let's look now at what we do if the command line is empty:
  743.  
  744.     (current.isdir
  745.      (current.name cwd! refresh)
  746.      ("extension_" current.name extension&#)
  747.      ifelse
  748.     )act_on_cur!
  749.  
  750. We  have  again  an  if  which  tests  if  current  name  is  a  directory  or
  751. not.  current.isdir is a predicate, which as all predicates, by convention
  752. returns one of the strings "" (false)  or "true".   If  current name is  a
  753. directory, we attach to it (current.name cwd!)  and refresh.  Otherwise, we
  754. construct an identifier extension_xxx where xxx is the extension of current
  755. name and execute that (#).  extension is defined as follows:
  756.  
  757.     ("."cutlast swap drop)extension!
  758.  
  759. we cut the name into its part before the  "." and after  it, and drop  the
  760. part before it.
  761.     The  other  thing  I  want  to do  with dvi  files is  turn  them into  HP
  762. LaserJet output, which I do with dvihp.exe, and that second type of action
  763. was associated with the CtrlEnter key.
  764.  
  765.  
  766. Technical highlight number one:  long command lines and The Berkeley Utili-
  767. ties:
  768.     MSH supports (almost) arbitrarily long command lines for programs which
  769. recognize its conventions (like The Berkeley Utilities).  For instance, if
  770. you use the BERK.MSH configuration with cp, mv, rm  enabled, and select  a
  771. lot of files and press F6 (move), you will be asked to confirm a very long
  772. command starting with mv, and if you agree mv will correctly move the whole
  773. list to the next panel.   This is quite  advantageous compared to  looping
  774. on mv of each file,  since mv  is loaded  only once,  so the  job is  done
  775. much faster.  You may wonder how this is possible, since MS-DOS limits any
  776. command line to 127 characters.   We do this by a  simple trick, which  is
  777. understood by all The Berkeley Utilities, and which you may make your  own
  778. programs understand!  When the command line is greater than 127 characters,
  779. we send only the first 127 to dos; but  before that we  put the rest in  a
  780. buffer,  preceded by its length as a  2-byte integer,  and we  add to  the
  781. MS-DOS environment a variable CMD@=xx, where xx is the  adress (as a  long
  782.  
  783. decimal integer) of the buffer.   The called program has just to check  if
  784. that variable exists, and if it is the case  catenate to its command  line
  785. the rest of the command line gotten from the address that variable  holds.
  786. Here is some sample code which does just that; this should help  you write
  787. your own.
  788.  
  789.     #include <stddef.h>
  790.     #include <stdlib.h>
  791.     #include <string.h>
  792.     #include <malloc.h>
  793.     #include <dos.h>
  794.     /* this program prints the command line under MSH,
  795.        adding the extra part at the end of the normal command.
  796.        This version gets the psp by the TURBO C built-in
  797.        variable _psp. You have to get it another way
  798.        if you use another compiler. */
  799.     int main()
  800.     { unsigned cmdlen=*(char far *)((((long)_psp)<<16)+0x80),
  801.                extralen=0;
  802.       char *com;
  803.       int far *extra;
  804.       char *s=getenv("CMD@");
  805.       if(NULL!=s && (extra=(int far *)atol(s)))
  806.         extralen=*extra;
  807.       com=malloc(cmdlen+extralen+1);
  808.       movedata(_psp,0x81,
  809.                FP_SEG((char far *)com),
  810.                FP_OFF((char far *)com),cmdlen);
  811.       if(extralen)
  812.       { extra++;
  813.         movedata(FP_SEG(extra),FP_OFF(extra),
  814.                  FP_SEG((char far *)(com+cmdlen)),
  815.          FP_OFF((char far *)(com+cmdlen)),
  816.                  extralen);
  817.       }
  818.       com[cmdlen+extralen]=0;
  819.       printf("command=<%s>\n",com);
  820.       return 0;
  821.     }
  822.  
  823.  
  824. Technical highlight number two:  large memory for your commands:
  825.     MSH, like a few advanced products,  can let your  commands use  almost
  826. all available memory in the system when executing.   In order to do  that,
  827. MSH  swaps  itself  out  of  memory,  writing most  of its  image  to disk  or
  828. to extended memory (if available) and leaving only a  small (8K) image  in
  829. memory.  If you have no (or not enough) extended memory and cannot swap to
  830. a virtual disk (in low or expanded memory) this swapping takes some time so
  831. you may want to disable it.  It is under control of the variable magic:  if
  832. magic is false (the empty string), its default value, no swapping to  disk
  833. is done.   Otherwise magic must contain the  name of the  directory to  be
  834. used for swapping (you may specify ``.''   for the current directory,  but
  835. we don't recommend it since you will then have problems on a diskette; you
  836. should specify some directory on your hard disk or a virtual disk).  If you
  837.  
  838. want to run a program which requires the use  of all your extended  memory
  839. (this happens to be the case for Borland's BC++3.0 on my machine which has
  840. only 2megs), you may want to disable swapping to XMS: this is done  by the
  841. special convention of starting the variable magic with a `*'.
  842.  
  843.  
  844. Command line options:
  845.  
  846.     In addition to the -l option explained above, there is another possible
  847. option on the command line:
  848.  -m Disables mouse.  If for some reason, you have a mouse but want MSH not
  849.     to use it, use this option.
  850.  
  851.  
  852. How to add your own primitives coded in C to msh:
  853.  
  854.     Read the file TOOLKIT.DOC which is in the toolkit.
  855.