home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!ogicse!das-news.harvard.edu!cantaloupe.srv.cs.cmu.edu!crabapple.srv.cs.cmu.edu!andrew.cmu.edu!ts49+
- From: strong+@CMU.EDU (Thomas W. Strong, Jr.)
- Newsgroups: gnu.emacs.sources
- Subject: csh-mode.el
- Message-ID: <of1mD2a00Vpd88mzs7@andrew.cmu.edu>
- Date: 15 Nov 92 18:29:54 GMT
- Article-I.D.: andrew.of1mD2a00Vpd88mzs7
- Organization: Pittsburgh Supercomputing Center, Carnegie Mellon, Pittsburgh, PA
- Lines: 193
-
- Similar to the last one... once again, comments and suggestions are
- welcome.
-
- ---------------- cut here ---------------
- ;;; csh-mode.el
- ;;;
- ;;; hacked out of forth.el from the tile-forth package
- ;;;
- ;;; comments/complaints/flames to strong+@cmu.edu
- ;;;
-
- (defvar csh-mode-positives
- " foreach while else then switch default: case "
- "Contains all words which will cause the indent-level to be incremented
- on the next line.
- OBS! All words in csh-mode-positives must be surrounded by spaces.")
-
- (defvar csh-mode-negatives
- " endif else breaksw endsw end "
- "Contains all words which will cause the indent-level to be decremented
- on the current line.
- OBS! All words in csh-mode-negatives must be surrounded by spaces.")
-
- (defvar csh-mode-zeroes
- " #!/bin/csh "
- "Contains all words which causes the indent to go to zero")
-
- (defvar csh-mode-abbrev-table nil
- "Abbrev table in use in csh-mode buffers.")
-
- (define-abbrev-table 'csh-mode-abbrev-table ())
-
- (defvar csh-mode-map nil
- "Keymap used in csh mode.")
-
- (if (not csh-mode-map)
- (setq csh-mode-map (make-sparse-keymap)))
-
- (define-key csh-mode-map "\t" 'csh-indent-command)
- (define-key csh-mode-map "\C-m" 'reindent-then-newline-and-indent)
-
- (defvar csh-mode-syntax-table nil
- "Syntax table in use in csh-mode buffers.")
-
- (defvar csh-indent-level 2
- "*Indentation of csh statements.")
-
- (defun csh-mode-variables ()
- (setq local-abbrev-table csh-mode-abbrev-table)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'csh-indent-line)
- (make-local-variable 'require-final-newline)
- (setq require-final-newline t)
- (make-local-variable 'parse-sexp-ignore-comments)
- (setq parse-sexp-ignore-comments t))
-
- (defun csh-mode ()
- "Major mode for editing csh scripts.
- \\[csh-indent-command] properly indents subexpressions of multi-line
- if, while, foreach, and switch statements, taking nesting into account.
- Caveats:
- The file must start with '#!/bin/csh' for the indentation to start properly.
- Extra spaces should be inserted to make sure the indentation algorithm can
- figure out what is a keyword, string, etc. For example, write
- if ($foo == \"bar\")
- not
- if($foo==\"bar\")
- or later lines may get indented wrong. (Many lines like this are also
- illegal csh code, so this shouldn't cramp your style.)
-
- The variable csh-indent-level controls the amount of indentation.
- \\{csh-mode-map}"
- (interactive)
- (kill-all-local-variables)
- (use-local-map csh-mode-map)
- (setq mode-name "csh")
- (setq major-mode 'csh-mode)
- (csh-mode-variables)
- (run-hooks 'csh-mode-hook))
-
- (defun csh-current-indentation ()
- (save-excursion
- (beginning-of-line)
- (back-to-indentation)
- (current-column)))
-
- (defun csh-delete-indentation ()
- (let
- ((b nil)
- (m nil))
- (save-excursion
- (beginning-of-line)
- (setq b (point))
- (back-to-indentation)
- (setq m (point)))
- (delete-region b m)))
-
- (defun csh-indent-line (&optional flag)
- "Correct indentation of the current csh line."
- (let
- ((x (csh-calculate-indent)))
- (csh-indent-to x)))
-
- (defun csh-indent-command ()
- (interactive)
- (csh-indent-line t))
-
- (defun csh-indent-to (x)
- (let
- ((p nil))
- (setq p (- (current-column) (csh-current-indentation)))
- (csh-delete-indentation)
- (beginning-of-line)
- (indent-to x)
- (if (> p 0) (forward-char p))))
-
- ;;Calculate indent
- (defun csh-calculate-indent ()
- (let ((w1 nil)
- (indent 0)
- (centre 0))
- (save-excursion
- (beginning-of-line)
- (skip-chars-backward " \t\n")
- (beginning-of-line)
- (back-to-indentation)
- (setq indent (current-column))
- (setq centre indent)
- (setq indent (+ indent (csh-sum-line-indentation))))
- (save-excursion
- (beginning-of-line)
- (back-to-indentation)
- (let ((p (point)))
- (skip-chars-forward "^ \t\n")
- (setq w1 (buffer-substring p (point)))))
- (if (> (- indent centre) csh-indent-level)
- (setq indent (+ centre csh-indent-level)))
- (if (> (- centre indent) csh-indent-level)
- (setq indent (- centre csh-indent-level)))
- (if (< indent 0) (setq indent 0))
- (setq indent (- indent
- (if (string-match
- (regexp-quote (concat " " w1 " "))
- csh-mode-negatives)
- csh-indent-level 0)))
- (if (string-match (regexp-quote (concat " " w1 " ")) csh-mode-zeroes)
- (setq indent 0))
- indent))
-
- (defun csh-sum-line-indentation ()
- "Add up the positive and negative weights of all words on the current line."
- (let ((b (point))
- (e nil)
- (sum 0)
- (w nil)
- (t1 nil)
- (t2 nil)
- (first t))
- (end-of-line) (setq e (point))
- (goto-char b)
- (while (< (point) e)
- (setq w (csh-next-word))
- (setq t1 (string-match (regexp-quote (concat " " w " "))
- csh-mode-positives))
- (setq t2 (string-match (regexp-quote (concat " " w " "))
- csh-mode-negatives))
- (if (and t1 t2)
- (setq sum (+ sum csh-indent-level)))
- (if t1
- (setq sum (+ sum csh-indent-level)))
- (if (and t2 (not first))
- (setq sum (- sum csh-indent-level)))
- (skip-chars-forward " \t")
- (setq first nil))
- sum))
-
- (defun csh-next-word ()
- "Return the next csh-word. Skip anything enclosed in double quotes."
- (let ((w1 nil))
- (while (not w1)
- (skip-chars-forward " \t\n")
- (if (not (looking-at "\""))
- (let ((p (point)))
- (skip-chars-forward "^ \t\n")
- (setq w1 (buffer-substring p (point))))
- (skip-chars-forward "^\"")
- (forward-char 1)))
- w1))
-
- ---------------- cut here ---------------
-
- -----------------------------------------------------------------
- Tom Strong N3NBB ts49+@andrew.cmu.edu
-