home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / languages / elisp / modes / J-Shell-1.1 / DOC < prev    next >
Encoding:
Text File  |  1993-04-03  |  16.7 KB  |  443 lines

  1. This is Jim's Pretty-Good Shell Mode (J-Shell), a shell-mode for GNU Emacs.
  2.  
  3. Written and maintained by: Jim Thompson
  4.                jimt@sugar.neosoft.com
  5.  
  6. $Id: DOC,v 1.2 1993/04/03 23:49:55 jct Exp $
  7.  
  8. J-Shell is a shell mode derived from Emacs's shell mode (although it
  9. has been changed so much that it bears little resemblance to the
  10. original).  J-Shell fixes most of the major problems in shell-mode
  11. and adds many new features...
  12.  
  13.   *  Accurate working-directory tracking (for using cd, pushd,
  14.      and popd) 
  15.  
  16.   *  Input buffering (a fix for the ^G problem)
  17.  
  18.   *  Host tracking and a simple interface to ange-ftp
  19.  
  20.   *  A browseable command history stack
  21.  
  22.   *  Password detection and hiding (with some security features)
  23.  
  24.   *  Built-in filename completion
  25.  
  26.   *  Improved navigation commands
  27.  
  28.   *  Automatic generation of new buffers
  29.  
  30. J-Shell can be used with most popular shells; the exception is sh, which
  31. cannot be used because it provides no means of aliasing its cd command.
  32. (You *could* use sh with J-Shell, but you would have no directory
  33. tracking.)  Sh users would be better off using the shell-mode that comes
  34. with Emacs.
  35.  
  36.  
  37. Installing J-Shell
  38. ------------------
  39.  
  40. J-Shell should be byte-compiled and placed in your load-path.  You will
  41. also need to add some code to your shell's startup script (.bashrc, .cshrc,
  42. etc.)  and set some variables in your .emacs startup file.
  43.  
  44. Included in the J-Shell distribution are five files named dot-*rc.  Each
  45. contains an example script that needs to be copied into your shell's
  46. startup script.  Please examine the script for your shell BEFORE you copy
  47. it into your startup script.  The example scripts are for the following
  48. shells:
  49.  
  50.     dot-bashrc -  bash
  51.     dot-cshrc  -  csh and tcsh
  52.     dot-kshrc  -  ksh
  53.     dot-tclrc  -  the tcl shell
  54.     dot-zshrc  -  zsh
  55.  
  56. There is no script for sh because j-shell cannot be used with sh.
  57.  
  58. These scripts allow your shell to communicate with J-Shell so that the J-
  59. Shell buffer can keep its default directory synchronized with your shell's
  60. working directory (see "Directory Tracking" in the section "Using J-Shell",
  61. for more information).
  62.  
  63. In your .emacs file, you will probably need to set the following variable:
  64.  
  65.     jsh-prompt-pattern    - a regular expression matching your
  66.                 shell's input prompt.
  67.  
  68. You will also need to consider setting the following variables in your
  69. .emacs; the default values for these variables will probably work for most
  70. systems, but may need different values for others:
  71.  
  72.     jsh-password-pattern    - a regular expression matching
  73.                   prompts for passwords.
  74.  
  75.     jsh-home        - your home directory, if the value
  76.                   of $HOME is not correct.
  77.  
  78.     jsh-history-stack-size    - the number of commands to keep in
  79.                   j-shell's command history. Its
  80.                   default value is 256; you may
  81.                   want a smaller stack.
  82.  
  83. These are the variables that will most often need new values; however, some
  84. users may want or need to override the default values of other variables.
  85. Everyone should also examine the variable declarations near the top of j-
  86. shell.el.
  87.  
  88.  
  89. Invoking J-Shell
  90. ----------------
  91.  
  92. J-Shell should be loaded by a "load", "require", or "autoload" call:
  93.  
  94.     (load "j-shell")   ;or
  95.  
  96.     (require 'j-shell) ;or
  97.  
  98.     (autoload 'j-shell "j-shell")
  99.  
  100. To invoke J-Shell, simply type
  101.  
  102.     M-x j-shell
  103.  
  104. J-Shell will create a new buffer and run your default shell in it; to
  105. determine your default shell, J-Shell evaluates the following in order
  106. until one evaluates non-nil:
  107.  
  108.     The Emacs lisp variable explicit-shell-file-name
  109.  
  110.     The ESHELL environment variable
  111.  
  112.     The SHELL environment variable
  113.  
  114. If none of the above are set, J-Shell chooses /bin/csh as the default
  115. shell.
  116.  
  117. If J-Shell is invoked with a numeric prefix argument, it will prompt
  118. interactively for a shell to run, with the default chosen as above:
  119.  
  120.     C-u M-x j-shell
  121.  
  122. The function j-shell may also be given a specific shell to run as an
  123. argument.  I use this feature to bind the keys C-c t and C-c b to run tcsh
  124. and bash, respectively:
  125.  
  126.     (global-set-key "\C-ct" '(lambda () (interactive) (j-shell "tcsh")))
  127.     (global-set-key "\C-cb" '(lambda () (interactive) (j-shell "bash")))
  128.  
  129. If you accidentally exit the shell before you're through with it, you can
  130. start another shell in the same buffer by running jsh-start-program, which
  131. is bound to C-c C-s.
  132.  
  133. Invoking j-shell causes the hooks, if any, in jsh-mode-hooks to be called.
  134.  
  135. Starting a process in a j-shell buffer, either by invoking j-shell or
  136. through C-c C-s, causes any hooks in jsh-start-hooks to be called.
  137.  
  138.  
  139. Using J-Shell
  140. -------------
  141.  
  142. J-Shell works much like Emacs's shell-mode: the shell's output appears in
  143. the buffer; you enter commands at the end of the buffer and send them to
  144. the shell with the RET key.  Like shell-mode, you may also place the point
  145. on any line and send that line to the shell by pressing RET.
  146.  
  147.  
  148. Directory Tracking
  149.  
  150. A shell mode must keep track of your shell's working directory so that
  151. commands like find-file always default to the same directory your shell is
  152. working in.  Emacs's shell-mode does this by monitoring commands, such as
  153. "cd", "pushd", and "popd", that you send to your shell.  This works well
  154. most of the time, but when you enter a command like "cd !$" (which tells
  155. csh to change to the directory named as the last argument to the previous
  156. command), shell-mode loses track of your shell's working directory, because
  157. !$ isn't the literal name of the directory.
  158.  
  159. Directory tracking in J-Shell works differently.  The shell sends messages--
  160. unique strings containing the working directory--whenever the shell's
  161. working directory changes.  J-Shell's filter function recognizes the
  162. message and extracts from it the buffer's new working directory.
  163.  
  164. This message-passing scheme means that J-Shell's default directory always
  165. matches the shell's working directory, because your shell specifies it
  166. directly; since J-Shell isn't attempting to deduce the shell's working
  167. directory, there is little room for confusion.
  168.  
  169. The disadvantage to this message-passing scheme is that you have to modify
  170. your shell--by way of its startup script--to send the messages.  That's why
  171. you have to copy one of the dot-*shrc scripts into your shell's startup
  172. script.
  173.  
  174.  
  175. Host Tracking
  176.  
  177. J-Shell keeps track of what host you're running on, in the same way that it
  178. tracks your working directory; it uses this information to provide a simple
  179. interface to ange-ftp.
  180.  
  181. When you rlogin to another host, J-Shell receives a message from the shell
  182. indicating the name of the new host; J-shell changes Emacs's default
  183. directory so that it matches the form recognized by ange-ftp:
  184.  
  185.     /hostname:/working/directory
  186.  
  187. If you have ange-ftp loaded, you can retrieve files from the remote host,
  188. from the directory that you're working with in your shell.
  189.  
  190. One caveat: if the values returned by (system-name) and hostname(1) don't
  191. match, then J-Shell will incorrectly assume you're running on a remote
  192. host.  For example, at my site, hostname returns "sugar.neosoft.com", but
  193. (system-name) returns simply "sugar".  A fix is to override the standard
  194. system-name with one defined in .emacs:
  195.  
  196.    (defun system-name () "sugar.neosoft.com")
  197.  
  198.  
  199. Shell Input Buffering
  200.  
  201. Users of Emacs's shell-mode know that extremely long input lines cause the
  202. shell to output a series of ^G characters and refuse to recognize further
  203. input.  What happens is that the tty's input buffer overflows because of
  204. the long input; the '^G's are BELL characters that the tty sends to ring
  205. the "terminal" bell.
  206.  
  207. J-Shell breaks long input up into chunks of 250 characters and sends the
  208. chunks one at a time; this should prevent the ^G problem on most systems.
  209. In testing this feature, I have successfully entered lines of almost 40000
  210. characters without overflowing the tty's input buffer.
  211.  
  212. This feature does not work with all shells.  Some shells (csh under SunOS
  213. 4.1.1, for example) will still exhibit the overflow problem.  Other shells
  214. will see the second chunk of input as a second *line* of input.
  215.  
  216.  
  217. Command History Stack
  218.  
  219. Every command you send to the shell, or programs running in it, is entered
  220. into a command history stack; the stack has enough room for the last 256
  221. commands (assuming you haven't overridden the default).  Adjacent identical
  222. commands--such as "lpq", which you might run repeatedly while waiting for a
  223. file to print--are entered just once in the stack.
  224.  
  225. You can browse through the command history by typing M-p and M-n.  M-p
  226. takes you backward through the commands, and M-n takes you forward through
  227. the commands.  If you type a string at the prompt then type M-p, then the
  228. browsing is limited to those commands that begin with the string you
  229. specified.  For example, if you type "cd" then M-p, you will see the last
  230. command that began with the letters "cd"; every time you type M-p, you will
  231. see another cd command from the stack, until eventually you run out.  M-n
  232. will take you back forward through the "cd" commands.
  233.  
  234. Please note that the command history records all user input, whether to the
  235. shell or programs executed from the shell.
  236.  
  237.  
  238. Password Detection And Hiding.
  239.  
  240. One of the real shortcomings of Emacs's shell-mode is that passwords echo.
  241. This means that you either have to avoid using commands that take
  242. passwords, such as "su" and "rlogin", or live with the security risk.  Even
  243. if you delete the password from your buffer, it's still recorded in the
  244. last 100 keystrokes, which you (or someone else) can see by typing "C-h l"
  245. (view-lossage).
  246.  
  247. J-Shell attempts to remedy this problem by detecting password prompts, such
  248. as "Password:", and diverting subsequent keystrokes to a local variable, so
  249. the password doesn't appear in your buffer.  When you press RET, J-Shell
  250. sends the password to the shell and clears the local password variable.
  251.  
  252. While entering a password, all keys that normally enter text (that is,
  253. those that call self-insert-command) will enter the same character into the
  254. password, and the DEL key will remove characters from the password.  All
  255. other commands, such as C-k (kill-line) will operate on the buffer, not on
  256. the password.
  257.  
  258. If you find that password detection doesn't work on you system, check the
  259. variable jsh-password-pattern; it should contain a regular expression that
  260. matches the password prompt.
  261.  
  262. Sometimes, because of the way shell output arrives at J-Shell's filter
  263. function, J-Shell fails to enter password mode, even though the password
  264. pattern *does* match the prompt; when this happens, you can manually invoke
  265. password mode by typing C-c C-p.
  266.  
  267. As a security measure, J-Shell disables the command "view-lossage", and the
  268. related command "recent-keys", the first you enter a password.  Instead of
  269. displaying the last 100 keystrokes, view-lossage will display a message
  270. indicating why the keystrokes aren't available; recent-keys returns the
  271. same string.  Of course, no security measure is foolproof: caveat emptor.
  272.  
  273.  
  274. Built-In Filename Completion.
  275.  
  276. J-Shell's filename completion is based almost entirely upon the package
  277. written for Emacs's shell-mode by Shinichirou Sugou, albeit with different
  278. bindings.
  279.  
  280. To complete a partial filename, type TAB; to see all completions for a
  281. partial filename, type C-c C-?.  To expand a filename, type C-c C-i.
  282.  
  283. If a completion command causes the *completions* buffer to be displayed, J-
  284. Shell will hide it again when you enter a command.
  285.  
  286.  
  287. Improved Navigation Commands.
  288.  
  289. In addition to the standard Emacs navigation commands, J-Shell has some
  290. that use the regular expression in jsh-prompt-pattern to move about the
  291. buffer.  C-a moves the point to the beginning of the command on the same
  292. line with point, skipping the shell prompt; if you're already at the shell
  293. prompt, C-a moves the point to the beginning of the line.
  294.  
  295. The commands M-P and M-N (note uppercase P and N) move the point to the
  296. previous or next shell prompt; the commands attempt to skip over empty or
  297. "stacked" prompts.
  298.  
  299. The command C-c C-a jumps the point to the beginning of the pending input
  300. (regardless of the prompt).
  301.  
  302. If you type LFD on a line, that line (minus any shell prompt) will be
  303. copied to the end of the buffer where you can edit it for input to the
  304. shell.
  305.  
  306.  
  307. Automatic Generation of New Buffers
  308.  
  309. Each time you invoke J-Shell, a new buffer will be generated.  Buffer names
  310. are based on the value of the variable jsh-buffer-base-name.  If this
  311. variable contains a string, that string is the name of the buffer; if it
  312. contains t, the buffer is named after the shell running in it (tcsh, bash,
  313. etc.).  If jsh-buffer-base-name contains nil, the buffer is named "j-shell".
  314.  
  315.  
  316. Odds and Ends
  317. -------------
  318.  
  319. Signal Delivery
  320.  
  321. Using Emacs's shell mode, you can interrupt a foreground process by typing
  322. C-c C-c; shell mode uses interrupt-process to send an interrupt signal to
  323. the shell.  This works well unless you've used rlogin to log onto a remote
  324. host.  Interrupt-process uses signals, so you can't interrupt a job running
  325. in an rlogin session, short of killing the whole session.
  326.  
  327. J-Shell provides an alternative: by setting the variable
  328.  
  329.     jsh-send-char-signals
  330.  
  331. non-nil, the C-c C-c command will send a literal C-c character to the shell
  332. process instead of a signal.  If your shell's tty is configured correctly,
  333. via the stty(1) command, the C-c character should interrupt the foreground
  334. process the same way a signal would.  Signals generated this way, by the
  335. tty driver, can be sent to jobs running on remote hosts.
  336.  
  337.  
  338. Alternate Mode Line
  339.  
  340. J-Shell has an alternate mode-line which displays the buffer name, CWD, and
  341. (if display-time is enabled) the time.  By default J-Shell uses the
  342. standard Emacs mode-line, but the alternate mode-line may be enabled by
  343. setting jsh-use-alternate-modeline non-nil.
  344.  
  345.  
  346. Bang Regurgitation
  347.  
  348. J-Shell has some special processing for shells such as csh which use a bang
  349. notation.  When a csh command uses a bang substitution, it will echo the
  350. command with the bang references replaced by their actual arguments; for
  351. example, 
  352.  
  353.     % touch foo bar
  354.     % rm !*
  355.     rm foo bar
  356.     %
  357.  
  358. Before executing the rm command, csh echos the command with "!*" replaced by
  359. the actual arguments "foo bar".  If the variable
  360.  
  361.     jsh-regurgitate-bang-commands
  362.  
  363. has a non-nil value, then J-Shell will replace the literal command "rm !*"
  364. in its command history with the actual command "rm foo bar".
  365.  
  366. Some commands with bang references shouldn't be replaced in the command
  367. history; for example, in the command
  368.  
  369.     % !-5
  370.     -2: Event not found.
  371.  
  372. the error message can be mistaken by J-Shell for a regurgitated command; to
  373. prevent such mistakes, the variable jsh-dont-regurg-regex contains a
  374. regular expression matching shell output that shouldn't be placed into the
  375. command history.
  376.  
  377.  
  378. Notes
  379. -----
  380.  
  381. Performance
  382.  
  383. In order to find and respond to messages sent by the shell, J-Shell uses a
  384. filter function; every time output arrives from the shell, the filter
  385. searches the output for the strings that identify a message.  This
  386. searching takes some time to perform and as a result, J-Shell doesn't run
  387. quite as fast as shell-modes that don't use a filter function.
  388.  
  389. I performed some informal tests to attempt to measure the performance
  390. decrease of J-Shell as compared to Emacs's shell mode.  The test was
  391. performed by catting version 2.9.9 of the jargon file in a j-shell buffer.
  392. Emacs's shell took an average of 53.1 seconds to cat the file.  J-Shell
  393. took an average of 59.5 seconds to cat the same file, an average of twelve
  394. percent longer than Emacs's shell.
  395.  
  396. This seems an acceptable price to pay for the advantages of message
  397. passing; even with the performance hit, the text in the J-Shell buffer
  398. scrolls past far faster than I can read.
  399.  
  400.  
  401. Input Buffering Stress-Test
  402.  
  403. Here's how I stress-tested J-Shell's input buffering (on SunOS 4.1.1, epoch
  404. 4.2, and tcsh 6.01):
  405.  
  406. 1. Start a j-shell buffer and cd /usr/man
  407.  
  408. 2. Type "echo man[1-8]/*" and press RET.  It may take a minute for the
  409.    shell to glob and output all the file names.  The shell will print
  410.    the names of all the man pages on a single very long line.
  411.  
  412. 3. Type C-p C-a C-@.  This will set the mark at the beginning of all
  413.    those file names.  Then type C-e M-w; this will copy all the file
  414.    names into Emacs's kill ring.
  415.  
  416. 4. Go to the shell prompt.
  417.  
  418. 5. Type "ls -l " C-y; this will create a single very long line of
  419.    input.  Press RET and wait.  Again, it may take a minutes before
  420.    you see the output of the command.
  421.  
  422. If instead of output in step 5, you see a series of Control-G (^G)
  423. characters, then the input buffering has failed and overflowed the tty
  424. input buffer.  If anyone sees this using j-shell, I'd appreciate hearing
  425. from you.
  426.  
  427. This stress-test will, on occasion, hang Emacs; if this happens, you can
  428. type C-g to unhang it.  I'm still not sure why this happens, but I've never
  429. seen it under normal use of J-Shell--only when intentionally stress-
  430. testing.  I don't consider this a complete failure of the input buffering
  431. scheme since the shell process can be recovered with C-g.
  432.  
  433.  
  434.  
  435. BUGS
  436. ----
  437.  
  438. Extremely long input lines sometimes causes Emacs to hang.
  439.  
  440. Executing jsh-send-eof (C-c C-d) doesn't flush pending input.
  441.  
  442. Please report any new bugs to me, Jim Thompson, jimt@neosoft.com.
  443.