home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / gnu / emacs / sources / 796 < prev    next >
Encoding:
Text File  |  1992-11-15  |  5.9 KB  |  204 lines

  1. Path: sparky!uunet!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!andrew.cmu.edu!ts49+
  2. From: strong+@CMU.EDU (Thomas W. Strong, Jr.)
  3. Newsgroups: gnu.emacs.sources
  4. Subject: csh-mode.el
  5. Message-ID: <of1mD2a00Vpd88mzs7@andrew.cmu.edu>
  6. Date: 15 Nov 92 18:29:54 GMT
  7. Article-I.D.: andrew.of1mD2a00Vpd88mzs7
  8. Organization: Pittsburgh Supercomputing Center, Carnegie Mellon, Pittsburgh, PA
  9. Lines: 193
  10.  
  11. Similar to the last one...  once again, comments and suggestions are
  12. welcome.
  13.  
  14. ---------------- cut here ---------------
  15. ;;; csh-mode.el
  16. ;;; 
  17. ;;; hacked out of forth.el from the tile-forth package
  18. ;;;
  19. ;;; comments/complaints/flames to strong+@cmu.edu
  20. ;;;
  21.  
  22. (defvar csh-mode-positives
  23.   " foreach while else then switch default: case "
  24.   "Contains all words which will cause the indent-level to be incremented
  25. on the next line.
  26. OBS! All words in csh-mode-positives must be surrounded by spaces.")
  27.  
  28. (defvar csh-mode-negatives
  29.   " endif else breaksw endsw end "
  30.   "Contains all words which will cause the indent-level to be decremented
  31. on the current line.
  32. OBS! All words in csh-mode-negatives must be surrounded by spaces.")
  33.  
  34. (defvar csh-mode-zeroes
  35.   " #!/bin/csh "
  36.   "Contains all words which causes the indent to go to zero")
  37.  
  38. (defvar csh-mode-abbrev-table nil
  39.   "Abbrev table in use in csh-mode buffers.")
  40.  
  41. (define-abbrev-table 'csh-mode-abbrev-table ())
  42.  
  43. (defvar csh-mode-map nil
  44.   "Keymap used in csh mode.")
  45.  
  46. (if (not csh-mode-map)
  47.     (setq csh-mode-map (make-sparse-keymap)))
  48.  
  49. (define-key csh-mode-map "\t" 'csh-indent-command)
  50. (define-key csh-mode-map "\C-m" 'reindent-then-newline-and-indent)
  51.  
  52. (defvar csh-mode-syntax-table nil
  53.   "Syntax table in use in csh-mode buffers.")
  54.  
  55. (defvar csh-indent-level 2
  56.   "*Indentation of csh statements.")
  57.  
  58. (defun csh-mode-variables ()
  59.   (setq local-abbrev-table csh-mode-abbrev-table)
  60.   (make-local-variable 'indent-line-function)
  61.   (setq indent-line-function 'csh-indent-line)
  62.   (make-local-variable 'require-final-newline)
  63.   (setq require-final-newline t)
  64.   (make-local-variable 'parse-sexp-ignore-comments)
  65.   (setq parse-sexp-ignore-comments t))
  66.   
  67. (defun csh-mode ()
  68.   "Major mode for editing csh scripts.
  69. \\[csh-indent-command] properly indents subexpressions of multi-line
  70. if, while, foreach, and switch statements, taking nesting into account.
  71. Caveats:
  72. The file must start with '#!/bin/csh' for the indentation to start properly.
  73. Extra spaces should be inserted to make sure the indentation algorithm can
  74. figure out what is a keyword, string, etc.  For example, write
  75.     if ($foo == \"bar\")
  76. not
  77.     if($foo==\"bar\")
  78. or later lines may get indented wrong.  (Many lines like this are also
  79. illegal csh code, so this shouldn't cramp your style.)
  80.  
  81. The variable csh-indent-level controls the amount of indentation.
  82. \\{csh-mode-map}"
  83.   (interactive)
  84.   (kill-all-local-variables)
  85.   (use-local-map csh-mode-map)
  86.   (setq mode-name "csh")
  87.   (setq major-mode 'csh-mode)
  88.   (csh-mode-variables)
  89.   (run-hooks 'csh-mode-hook))
  90.  
  91. (defun csh-current-indentation ()
  92.   (save-excursion
  93.     (beginning-of-line)
  94.     (back-to-indentation)
  95.     (current-column)))
  96.  
  97. (defun csh-delete-indentation ()
  98.   (let
  99.       ((b nil)
  100.        (m nil))
  101.     (save-excursion
  102.       (beginning-of-line)
  103.       (setq b (point))
  104.       (back-to-indentation)
  105.       (setq m (point)))
  106.     (delete-region b m)))
  107.  
  108. (defun csh-indent-line (&optional flag)
  109.   "Correct indentation of the current csh line."
  110.   (let
  111.       ((x (csh-calculate-indent)))
  112.     (csh-indent-to x)))
  113.   
  114. (defun csh-indent-command ()
  115.   (interactive)
  116.   (csh-indent-line t))
  117.  
  118. (defun csh-indent-to (x)
  119.   (let
  120.       ((p nil))
  121.     (setq p (- (current-column) (csh-current-indentation)))
  122.     (csh-delete-indentation)
  123.     (beginning-of-line)
  124.     (indent-to x)
  125.     (if (> p 0) (forward-char p))))
  126.  
  127. ;;Calculate indent
  128. (defun csh-calculate-indent ()
  129.   (let ((w1 nil)
  130.     (indent 0)
  131.     (centre 0))
  132.     (save-excursion
  133.       (beginning-of-line)
  134.       (skip-chars-backward " \t\n")
  135.       (beginning-of-line)
  136.       (back-to-indentation)
  137.       (setq indent (current-column))
  138.       (setq centre indent)
  139.       (setq indent (+ indent (csh-sum-line-indentation))))
  140.     (save-excursion
  141.       (beginning-of-line)
  142.       (back-to-indentation)
  143.       (let ((p (point)))
  144.     (skip-chars-forward "^ \t\n")
  145.     (setq w1 (buffer-substring p (point)))))
  146.     (if (> (- indent centre) csh-indent-level)
  147.     (setq indent (+ centre csh-indent-level)))
  148.     (if (> (- centre indent) csh-indent-level)
  149.     (setq indent (- centre csh-indent-level)))
  150.     (if (< indent 0) (setq indent 0))
  151.     (setq indent (- indent
  152.             (if (string-match 
  153.              (regexp-quote (concat " " w1 " "))
  154.              csh-mode-negatives)
  155.             csh-indent-level 0)))
  156.     (if (string-match (regexp-quote (concat " " w1 " ")) csh-mode-zeroes)
  157.     (setq indent 0))
  158.     indent))
  159.  
  160. (defun csh-sum-line-indentation ()
  161.   "Add up the positive and negative weights of all words on the current line."
  162.   (let ((b (point))
  163.     (e nil)
  164.     (sum 0)
  165.     (w nil)
  166.     (t1 nil)
  167.     (t2 nil)
  168.     (first t))
  169.     (end-of-line) (setq e (point))
  170.     (goto-char b)
  171.     (while (< (point) e)
  172.       (setq w (csh-next-word))
  173.       (setq t1 (string-match (regexp-quote (concat " " w " "))
  174.                  csh-mode-positives))
  175.       (setq t2 (string-match (regexp-quote (concat " " w " "))
  176.                  csh-mode-negatives))
  177.       (if (and t1 t2)
  178.       (setq sum (+ sum csh-indent-level)))
  179.       (if t1
  180.       (setq sum (+ sum csh-indent-level)))
  181.       (if (and t2 (not first))
  182.       (setq sum (- sum csh-indent-level)))
  183.       (skip-chars-forward " \t")
  184.       (setq first nil))
  185.     sum))
  186.  
  187. (defun csh-next-word ()
  188.   "Return the next csh-word. Skip anything enclosed in double quotes."
  189.   (let ((w1 nil))
  190.     (while (not w1)
  191.       (skip-chars-forward " \t\n")
  192.       (if (not (looking-at "\""))
  193.       (let ((p (point)))
  194.         (skip-chars-forward "^ \t\n")
  195.         (setq w1 (buffer-substring p (point))))
  196.     (skip-chars-forward "^\"")
  197.     (forward-char 1)))
  198.     w1))
  199.  
  200. ---------------- cut here ---------------
  201.  
  202.  -----------------------------------------------------------------
  203.   Tom Strong              N3NBB              ts49+@andrew.cmu.edu
  204.