aboutsummaryrefslogtreecommitdiff
path: root/contrib/tcsh/csh-mode.el
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tcsh/csh-mode.el')
-rw-r--r--contrib/tcsh/csh-mode.el935
1 files changed, 0 insertions, 935 deletions
diff --git a/contrib/tcsh/csh-mode.el b/contrib/tcsh/csh-mode.el
deleted file mode 100644
index 3b638dbad2b2..000000000000
--- a/contrib/tcsh/csh-mode.el
+++ /dev/null
@@ -1,935 +0,0 @@
-;; csh-mode.el --- csh (and tcsh) script editing mode for Emacs.
-;;
-;; Version: 1.2
-;; Date: April 2, 1999
-;; Maintainer: Dan Harkless <software@harkless.org>
-;;
-;; Description:
-;; csh and tcsh script editing mode for Emacs.
-;;
-;; Installation:
-;; Put csh-mode.el in some directory in your load-path and load it.
-;;
-;; Usage:
-;; This major mode assists shell script writers with indentation
-;; control and control structure construct matching in much the same
-;; fashion as other programming language modes. Invoke describe-mode
-;; for more information.
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Author key:
-;; DH - Dan Harkless <software@harkless.org>
-;; CM - Carlo Migliorini <migliorini@sodalia.it>
-;; JR - Jack Repenning <jackr@sgi.com>
-;; GE - Gary Ellison <Gary.F.Ellison@att.com>
-;;
-;; *** REVISION HISTORY ***
-;;
-;; DATE MOD. BY REASON FOR MODIFICATION
-;; --------- -- --------------------------------------------------------------
-;; 2 Apr 99 DH 1.2: Noticed an out-of-date comment referencing .bashrc etc.
-;; 11 Dec 96 DH 1.1: ksh-mode just indented continuation lines by 1 space.
-;; csh-mode looks at the first line and indents properly to line
-;; up under the open-paren, quote, or command.
-;; 11 Dec 96 DH Added fontification for history substitutions.
-;; 10 Dec 96 DH Added indentation and fontification for labels. Added
-;; fontification for variables and backquoted strings.
-;; 9 Dec 96 DH 1.0: Brought csh-mode up to the level of functionality of
-;; the original ksh-mode.
-;; 7 Oct 96 CM 0.1: Hacked ksh-mode.el into minimally functional csh-mode.el
-;; by doing search-and-replace and some keyword changes.
-;; 8 Aug 96 JR (Last modification to ksh-mode 2.6.)
-;; [...]
-;; 19 Jun 92 GE (Conception of ksh-mode.)
-;;
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-
-(defconst csh-mode-version "1.2"
- "*Version number of this version of csh-mode")
-
-(defvar csh-mode-hook
- '(lambda ()
- (auto-fill-mode 1))
- "Hook to run each time csh-mode is entered.")
-
-
-;;
-;; -------------------------------------------> Variables controlling completion
-;;
-(defvar csh-completion-list '())
-(make-variable-buffer-local 'csh-completion-list)
-(set-default 'csh-completion-list '())
-;;
-;; -type- : type number, 0:misc, 1:variable, 2:function
-;; -regexp-: regexp used to parse the script
-;; -match- : used by match-beginning/end to pickup target
-;;
-(defvar csh-completion-type-misc 0)
-(defvar csh-completion-regexp-var "\\([A-Za-z_0-9]+\\)=")
-(defvar csh-completion-type-var 1)
-(defvar csh-completion-match-var 1)
-(defvar csh-completion-regexp-var2 "\\$\\({\\|{#\\)?\\([A-Za-z_0-9]+\\)[#%:}]?")
-(defvar csh-completion-match-var2 2)
-(defvar csh-completion-regexp-function
- "\\(function\\)?[ \t]*\\([A-Za-z_0-9]+\\)[ \t]*([ \t]*)")
-(defvar csh-completion-type-function 2)
-(defvar csh-completion-match-function 2)
-
-
-;;
-;; ------------------------------------> Variables controlling indentation style
-;;
-(defvar csh-indent 4
- "*Indentation of csh statements with respect to containing block. A value
-of nil indicates compound list keyword \(\"do\" and \"then\"\) alignment.")
-
-(defvar csh-case-item-offset csh-indent
- "*Additional indentation for case items within a case statement.")
-(defvar csh-case-indent nil
- "*Additional indentation for statements under case items.")
-(defvar csh-comment-regexp "^\\s *#"
- "*Regular expression used to recognize comments. Customize to support
-csh-like languages.")
-(defvar csh-match-and-tell t
- "*If non-nil echo in the minibuffer the matching compound command
-for the \"breaksw\", \"end\", or \"endif\".")
-(defvar csh-tab-always-indent t
- "*Controls the operation of the TAB key. If t (the default), always
-reindent the current line. If nil, indent the current line only if
-point is at the left margin or in the line's indentation; otherwise
-insert a tab.")
-
-
-;;
-;; ----------------------------------------> Constants containing syntax regexps
-;;
-(defconst csh-case-default-re
- "^\\s *\\(case\\|default\\)\\b"
- "Regexp used to locate grouping keywords case and default" )
-
-(defconst csh-case-item-re "^\\s *\\(case .*\\|default\\):"
- "Regexp used to match case-items")
-
-(defconst csh-end-re "^\\s *end\\b"
- "Regexp used to match keyword: end")
-
-(defconst csh-endif-re "^\\s *endif\\b"
- "Regexp used to match keyword: endif")
-
-(defconst csh-endsw-re "^\\s *endsw\\b"
- "Regexp used to match keyword: endsw")
-
-(defconst csh-else-re "^\\s *\\belse\\(\\b\\|$\\)"
- "Regexp used to match keyword: else")
-
-(defconst csh-else-if-re "^\\s *\\belse if\\(\\b\\|$\\)"
- "Regexp used to match keyword pair: else if")
-
-(defconst csh-if-re "^\\s *if\\b.+\\(\\\\\\|\\bthen\\b\\)"
- "Regexp used to match non-one-line if statements")
-
-(defconst csh-iteration-keywords-re "^[^#\n]*\\s\"*\\b\\(while\\|foreach\\)\\b"
- "Match one of the keywords: while, foreach")
-
-(defconst csh-keywords-re
- "^\\s *\\(else\\b\\|foreach\\b\\|if\\b.+\\(\\\\\\|\\bthen\\b\\)\\|switch\\b\\|while\\b\\)"
- "Regexp used to detect compound command keywords: else, if, foreach, while")
-
-(defconst csh-label-re "^\\s *[^!#$\n ]+:"
- "Regexp used to match flow-control labels")
-
-(defconst csh-multiline-re "^.*\\\\$"
- "Regexp used to match a line with a statement using more lines.")
-
-(defconst csh-switch-re "^\\s *switch\\b"
- "Regexp used to match keyword: switch")
-
-
-;;
-;; ----------------------------------------> Variables controlling fontification
-;;
-(defvar csh-keywords '("@" "alias" "bg" "break" "breaksw" "case" "cd" "chdir"
- "continue" "default" "dirs" "echo" "else" "end" "endif"
- "endsw" "eval" "exec" "exit" "fg" "foreach" "glob" "goto"
- "hashstat" "history" "if" "jobs" "kill" "limit" "login"
- "logout" "limit" "notify" "onintr" "popd" "printenv"
- "pushd" "rehash" "repeat" "set" "setenv" "shift" "source"
- "stop" "suspend" "switch" "then" "time" "umask" "unalias"
- "unhash" "unlimit" "unset" "unsetenv" "wait" "while"
- ;; tcsh-keywords
- "alloc" "bindkey" "builtins" "complete" "echotc"
- "filetest" "hup" "log" "ls-F" "nice" "nohup" "sched"
- "settc" "setty" "telltc" "uncomplete" "where" "which"))
-
-(require 'font-lock) ; need to do this before referring to font-lock-* below
-
-(defconst csh-font-lock-keywords
- ;; NOTE: The order of some of the items in this list is significant. Do not
- ;; alphabetize or otherwise blindly rearrange.
- (list
- ;; Comments on line 1, which are missed by syntactic fontification.
- '("^#.*" 0 font-lock-comment-face)
-
- ;; Label definitions (1 means first parenthesized exp in regexp).
- '("^\\s *\\([^!#$\n ]+\\):" 1 font-lock-function-name-face)
-
- ;; Label references.
- '("\\b\\(goto\\|onintr\\)\\b\\s +\\([^!#$ \n\t]+\\)"
- 2 font-lock-function-name-face)
-
- ;; Variable settings.
- '("\\(@\\|set\\|setenv\\)\\s +\\([0-9A-Za-z_]+\\b\\)"
- 2 font-lock-variable-name-face)
-
- ;; Variable references not inside of strings.
- '("\\$[][0-9A-Za-z_#:?]+" 0 font-lock-variable-name-face)
-
- ;; Backquoted strings. 'keep' means to just fontify non-fontified text.
- '("`\\(.*\\)`" 1 font-lock-reference-face keep)
-
- ;; NOTE: The following variables need to be anchored to the beginning of
- ;; line to prevent re-fontifying text in comments. Due to this, we
- ;; can only catch a finite number of occurrences. More can be added.
- ;; The 't' means to override previous fontification.
- ;;
- ;; Variable references inside of " strings.
- '("^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*\""
- 1 font-lock-variable-name-face t) ; 1
- '("^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*\\$[][0-9A-Za-z_#:?]+.*\""
- 1 font-lock-variable-name-face t) ; 2
- (cons (concat "^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*"
- "\\$[][0-9A-Za-z_#:?]+.*\\$[][0-9A-Za-z_#:?]+.*\"")
- (list 1 font-lock-variable-name-face t)) ; 3
- ;;
- ;; History substitutions.
- '("^![^~= \n\t]+" 0 font-lock-reference-face t) ; BOL
- '("^[^#\n]*[^#\\\n]\\(![^~= \n\t]+\\)" 1 font-lock-reference-face t) ; 1
- '("^[^#\n]*[^#\\\n]\\(![^~= \n\t]+\\).*![^~= \n\t]+"
- 1 font-lock-reference-face t) ; 2
-
- ;; Keywords.
- (cons (concat
- "\\(\\<"
- (mapconcat 'identity csh-keywords "\\>\\|\\<")
- "\\>\\)")
- 1)
- ))
-
-(put 'csh-mode 'font-lock-keywords 'csh-font-lock-keywords)
-
-
-;;
-;; -------------------------------------------------------> Mode-specific tables
-;;
-(defvar csh-mode-abbrev-table nil
- "Abbrev table used while in csh mode.")
-(define-abbrev-table 'csh-mode-abbrev-table ())
-
-(defvar csh-mode-map nil
- "Keymap used in csh mode")
-(if csh-mode-map
- ()
- (setq csh-mode-map (make-sparse-keymap))
-;;(define-key csh-mode-map "\177" 'backward-delete-char-untabify)
- (define-key csh-mode-map "\C-c\t" 'csh-completion-init-and-pickup)
- (define-key csh-mode-map "\C-j" 'reindent-then-newline-and-indent)
- (define-key csh-mode-map "\e\t" 'csh-complete-symbol)
- (define-key csh-mode-map "\n" 'reindent-then-newline-and-indent)
- (define-key csh-mode-map '[return] 'reindent-then-newline-and-indent)
- (define-key csh-mode-map "\t" 'csh-indent-command)
-;;(define-key csh-mode-map "\t" 'csh-indent-line)
- )
-
-(defvar csh-mode-syntax-table nil
- "Syntax table used while in csh mode.")
-(if csh-mode-syntax-table
- ;; If it's already set up, don't change it.
- ()
- ;; Else, create it from the standard table and modify entries that need to be.
- (setq csh-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?& "." csh-mode-syntax-table) ; & -punctuation
- (modify-syntax-entry ?* "." csh-mode-syntax-table) ; * -punctuation
- (modify-syntax-entry ?- "." csh-mode-syntax-table) ; - -punctuation
- (modify-syntax-entry ?= "." csh-mode-syntax-table) ; = -punctuation
- (modify-syntax-entry ?+ "." csh-mode-syntax-table) ; + -punctuation
- (modify-syntax-entry ?| "." csh-mode-syntax-table) ; | -punctuation
- (modify-syntax-entry ?< "." csh-mode-syntax-table) ; < -punctuation
- (modify-syntax-entry ?> "." csh-mode-syntax-table) ; > -punctuation
- (modify-syntax-entry ?/ "." csh-mode-syntax-table) ; / -punctuation
- (modify-syntax-entry ?\' "\"" csh-mode-syntax-table) ; ' -string quote
- (modify-syntax-entry ?. "w" csh-mode-syntax-table) ; . -word constituent
- (modify-syntax-entry ?? "w" csh-mode-syntax-table) ; ? -word constituent
-
- ;; \n - comment ender, first character of 2-char comment sequence
- (modify-syntax-entry ?\n "> 1" csh-mode-syntax-table) ; # -word constituent
-
- ;; - whitespace, first character of 2-char comment sequence
- (modify-syntax-entry ? " 1" csh-mode-syntax-table) ;
-
- ;; \t - whitespace, first character of 2-char comment sequence
- (modify-syntax-entry ?\t " 1" csh-mode-syntax-table) ; # -word constituent
-
- ;; # - word constituent, second character of 2-char comment sequence
- (modify-syntax-entry ?# "w 2" csh-mode-syntax-table) ; # -word constituent
- )
-
-
-;;
-;; ------------------------------------------------------------------> Functions
-;;
-(defun csh-current-line ()
- "Return the vertical position of point in the buffer.
-Top line is 1."
- (+ (count-lines (point-min) (point))
- (if (= (current-column) 0) 1 0))
- )
-
-(defun csh-get-compound-level
- (begin-re end-re anchor-point &optional balance-list)
- "Determine how much to indent this structure. Return a list (level line)
-of the matching compound command or nil if no match found."
- (let*
- (;; Locate the next compound begin keyword bounded by point-min
- (match-point (if (re-search-backward begin-re (point-min) t)
- (match-beginning 0) 0))
- (nest-column (if (zerop match-point)
- 1
- (progn
- (goto-char match-point)
- (current-indentation))))
- (nest-list (cons 0 0)) ;; sentinel cons since cdr is >= 1
- )
- (if (zerop match-point)
- nil ;; graceful exit from recursion
- (progn
- (if (nlistp balance-list)
- (setq balance-list (list)))
- ;; Now search forward from matching start keyword for end keyword
- (while (and (consp nest-list) (zerop (cdr nest-list))
- (re-search-forward end-re anchor-point t))
- (if (not (memq (point) balance-list))
- (progn
- (setq balance-list (cons (point) balance-list))
- (goto-char match-point) ;; beginning of compound cmd
- (setq nest-list
- (csh-get-compound-level begin-re end-re
- anchor-point balance-list))
- )))
-
- (cond ((consp nest-list)
- (if (zerop (cdr nest-list))
- (progn
- (goto-char match-point)
- (cons nest-column (csh-current-line)))
- nest-list))
- (t nil)
- )
- )
- )
- )
- )
-
-(defun csh-get-nest-level ()
- "Return a 2 element list (nest-level nest-line) describing where the
-current line should nest."
- (let ((case-fold-search)
- (level))
- (save-excursion
- (forward-line -1)
- (while (and (not (bobp))
- (null level))
- (if (and (not (looking-at "^\\s *$"))
- (not (save-excursion
- (forward-line -1)
- (beginning-of-line)
- (looking-at csh-multiline-re)))
- (not (looking-at csh-comment-regexp)))
- (setq level (cons (current-indentation)
- (csh-current-line)))
- (forward-line -1)
- );; if
- );; while
- (if (null level)
- (cons (current-indentation) (csh-current-line))
- level)
- )
- )
- )
-
-(defun csh-get-nester-column (nest-line)
- "Return the column to indent to with respect to nest-line taking
-into consideration keywords and other nesting constructs."
- (save-excursion
- (let ((fence-post)
- (case-fold-search)
- (start-line (csh-current-line)))
- ;;
- ;; Handle case item indentation constructs for this line
- (cond ((looking-at csh-case-item-re)
- ;; This line is a case item...
- (save-excursion
- (goto-line nest-line)
- (let ((fence-post (save-excursion (end-of-line) (point))))
- (cond ((re-search-forward csh-switch-re fence-post t)
- ;; If this is the first case under the switch, indent.
- (goto-char (match-beginning 0))
- (+ (current-indentation) csh-case-item-offset))
-
- ((re-search-forward csh-case-item-re fence-post t)
- ;; If this is another case right under a previous case
- ;; without intervening code, stay at the same
- ;; indentation.
- (goto-char (match-beginning 0))
- (current-indentation))
-
- (t
- ;; Else, this is a new case. Outdent.
- (- (current-indentation) csh-case-item-offset))
- )
- )))
- (t;; Not a case-item. What to do relative to the nest-line?
- (save-excursion
- (goto-line nest-line)
- (setq fence-post (save-excursion (end-of-line) (point)))
- (save-excursion
- (cond
- ;;
- ;; Check if we are in a continued statement
- ((and (looking-at csh-multiline-re)
- (save-excursion
- (goto-line (1- start-line))
- (looking-at csh-multiline-re)))
- (if (looking-at ".*[\'\"]\\\\")
- ;; If this is a continued string, indent under
- ;; opening quote.
- (progn
- (re-search-forward "[\'\"]")
- (forward-char -1))
- (if (looking-at ".*([^\)\n]*\\\\")
- ;; Else if this is a continued parenthesized
- ;; list, indent after paren.
- (re-search-forward "(" fence-post t)
- ;; Else, indent after whitespace after first word.
- (re-search-forward "[^ \t]+[ \t]+" fence-post t)))
- (current-column))
-
- ;; In order to locate the column of the keyword,
- ;; which might be embedded within a case-item,
- ;; it is necessary to use re-search-forward.
- ;; Search by literal case, since shell is
- ;; case-sensitive.
- ((re-search-forward csh-keywords-re fence-post t)
- (goto-char (match-beginning 1))
- (if (looking-at csh-switch-re)
- (+ (current-indentation) csh-case-item-offset)
- (+ (current-indentation)
- (if (null csh-indent)
- 2 csh-indent)
- )))
-
- ((re-search-forward csh-case-default-re fence-post t)
- (if (null csh-indent)
- (progn
- (goto-char (match-end 1))
- (+ (current-indentation) 1))
- (progn
- (goto-char (match-beginning 1))
- (+ (current-indentation) csh-indent))
- ))
-
- ;;
- ;; Now detect first statement under a case item
- ((looking-at csh-case-item-re)
- (if (null csh-case-indent)
- (progn
- (re-search-forward csh-case-item-re fence-post t)
- (goto-char (match-end 1))
- (+ (current-column) 1))
- (+ (current-indentation) csh-case-indent)))
-
- ;;
- ;; If this is the first statement under a control-flow
- ;; label, indent one level.
- ((csh-looking-at-label)
- (+ (current-indentation) csh-indent))
-
- ;; This is hosed when using current-column
- ;; and there is a multi-command expression as the
- ;; nester.
- (t (current-indentation)))
- )
- ));; excursion over
- );; Not a case-item
- );;let
- );; excursion
- );; defun
-
-(defun csh-indent-command ()
- "Indent current line relative to containing block and allow for
-csh-tab-always-indent customization"
- (interactive)
- (let (case-fold-search)
- (cond ((save-excursion
- (skip-chars-backward " \t")
- (bolp))
- (csh-indent-line))
- (csh-tab-always-indent
- (save-excursion
- (csh-indent-line)))
- (t (insert-tab))
- ))
- )
-
-(defun csh-indent-line ()
- "Indent current line as far as it should go according
-to the syntax/context"
- (interactive)
- (let (case-fold-search)
- (save-excursion
- (beginning-of-line)
- (if (bobp)
- nil
- ;;
- ;; Align this line to current nesting level
- (let*
- (
- (level-list (csh-get-nest-level)) ; Where to nest against
- ;; (last-line-level (car level-list))
- (this-line-level (current-indentation))
- (nester-column (csh-get-nester-column (cdr level-list)))
- (struct-match (csh-match-structure-and-reindent))
- )
- (if struct-match
- (setq nester-column struct-match))
- (if (eq nester-column this-line-level)
- nil
- (beginning-of-line)
- (let ((beg (point)))
- (back-to-indentation)
- (delete-region beg (point)))
- (indent-to nester-column))
- );; let*
- );; if
- );; excursion
- ;;
- ;; Position point on this line
- (let*
- (
- (this-line-level (current-indentation))
- (this-bol (save-excursion
- (beginning-of-line)
- (point)))
- (this-point (- (point) this-bol))
- )
- (cond ((> this-line-level this-point);; point in initial white space
- (back-to-indentation))
- (t nil)
- );; cond
- );; let*
- );; let
- );; defun
-
-(defun csh-indent-region (start end)
- "From start to end, indent each line."
- ;; The algorithm is just moving through the region line by line with
- ;; the match noise turned off. Only modifies nonempty lines.
- (save-excursion
- (let (csh-match-and-tell
- (endmark (copy-marker end)))
-
- (goto-char start)
- (beginning-of-line)
- (setq start (point))
- (while (> (marker-position endmark) start)
- (if (not (and (bolp) (eolp)))
- (csh-indent-line))
- (forward-line 1)
- (setq start (point)))
-
- (set-marker endmark nil)
- )
- )
- )
-
-(defun csh-line-to-string ()
- "From point, construct a string from all characters on
-current line"
- (skip-chars-forward " \t") ;; skip tabs as well as spaces
- (buffer-substring (point)
- (progn
- (end-of-line 1)
- (point))))
-
-(defun csh-looking-at-label ()
- "Return true if current line is a label (not the default: case label)."
- (and
- (looking-at csh-label-re)
- (not (looking-at "^\\s *default:"))))
-
-(defun csh-match-indent-level (begin-re end-re)
- "Match the compound command and indent. Return nil on no match,
-indentation to use for this line otherwise."
- (interactive)
- (let* ((case-fold-search)
- (nest-list
- (save-excursion
- (csh-get-compound-level begin-re end-re (point))
- ))
- ) ;; bindings
- (if (null nest-list)
- (progn
- (if csh-match-and-tell
- (message "No matching compound command"))
- nil) ;; Propagate a miss.
- (let* (
- (nest-level (car nest-list))
- (match-line (cdr nest-list))
- ) ;; bindings
- (if csh-match-and-tell
- (save-excursion
- (goto-line match-line)
- (message "Matched ... %s" (csh-line-to-string))
- ) ;; excursion
- ) ;; if csh-match-and-tell
- nest-level ;;Propagate a hit.
- ) ;; let*
- ) ;; if
- ) ;; let*
- ) ;; defun csh-match-indent-level
-
-(defun csh-match-structure-and-reindent ()
- "If the current line matches one of the indenting keywords
-or one of the control structure ending keywords then reindent. Also
-if csh-match-and-tell is non-nil the matching structure will echo in
-the minibuffer"
- (interactive)
- (let (case-fold-search)
- (save-excursion
- (beginning-of-line)
- (cond ((looking-at csh-else-re)
- (csh-match-indent-level csh-if-re csh-endif-re))
- ((looking-at csh-else-if-re)
- (csh-match-indent-level csh-if-re csh-endif-re))
- ((looking-at csh-endif-re)
- (csh-match-indent-level csh-if-re csh-endif-re))
- ((looking-at csh-end-re)
- (csh-match-indent-level csh-iteration-keywords-re csh-end-re))
- ((looking-at csh-endsw-re)
- (csh-match-indent-level csh-switch-re csh-endsw-re))
- ((csh-looking-at-label)
- ;; Flush control-flow labels left since they don't nest.
- 0)
- ;;
- (t nil)
- );; cond
- )
- ))
-
-;;;###autoload
-(defun csh-mode ()
- "csh-mode 2.0 - Major mode for editing csh and tcsh scripts.
-Special key bindings and commands:
-\\{csh-mode-map}
-Variables controlling indentation style:
-csh-indent
- Indentation of csh statements with respect to containing block.
- Default value is 4.
-csh-case-indent
- Additional indentation for statements under case items.
- Default value is nil which will align the statements one position
- past the \")\" of the pattern.
-csh-case-item-offset
- Additional indentation for case items within a case statement.
- Default value is 2.
-csh-tab-always-indent
- Controls the operation of the TAB key. If t (the default), always
- reindent the current line. If nil, indent the current line only if
- point is at the left margin or in the line's indentation; otherwise
- insert a tab.
-csh-match-and-tell
- If non-nil echo in the minibuffer the matching compound command
- for the \"done\", \"}\", \"fi\", or \"endsw\". Default value is t.
-
-csh-comment-regexp
- Regular expression used to recognize comments. Customize to support
- csh-like languages. Default value is \"\^\\\\s *#\".
-
-Style Guide.
- By setting
- (setq csh-indent default-tab-width)
-
- The following style is obtained:
-
- if [ -z $foo ]
- then
- bar # <-- csh-group-offset is additive to csh-indent
- foo
- fi
-
- By setting
- (setq csh-indent default-tab-width)
- (setq csh-group-offset (- 0 csh-indent))
-
- The following style is obtained:
-
- if [ -z $foo ]
- then
- bar
- foo
- fi
-
- By setting
- (setq csh-case-item-offset 1)
- (setq csh-case-indent nil)
-
- The following style is obtained:
-
- case x in *
- foo) bar # <-- csh-case-item-offset
- baz;; # <-- csh-case-indent aligns with \")\"
- foobar) foo
- bar;;
- endsw
-
- By setting
- (setq csh-case-item-offset 1)
- (setq csh-case-indent 6)
-
- The following style is obtained:
-
- case x in *
- foo) bar # <-- csh-case-item-offset
- baz;; # <-- csh-case-indent
- foobar) foo
- bar;;
- endsw
-
-
-Installation:
- Put csh-mode.el in some directory in your load-path.
- Put the following forms in your .emacs file.
-
- (setq auto-mode-alist
- (append auto-mode-alist
- (list
- '(\"\\\\.csh$\" . csh-mode)
- '(\"\\\\.login\" . csh-mode))))
-
- (setq csh-mode-hook
- (function (lambda ()
- (font-lock-mode 1) ;; font-lock the buffer
- (setq csh-indent 8)
- (setq csh-tab-always-indent t)
- (setq csh-match-and-tell t)
- (setq csh-align-to-keyword t) ;; Turn on keyword alignment
- )))"
- (interactive)
- (kill-all-local-variables)
- (use-local-map csh-mode-map)
- (setq major-mode 'csh-mode)
- (setq mode-name "Csh")
- (setq local-abbrev-table csh-mode-abbrev-table)
- (set-syntax-table csh-mode-syntax-table)
- (make-local-variable 'indent-line-function)
- (setq indent-line-function 'csh-indent-line)
- (make-local-variable 'indent-region-function)
- (setq indent-region-function 'csh-indent-region)
- (make-local-variable 'comment-start)
- (setq comment-start "# ")
- (make-local-variable 'comment-end)
- (setq comment-end "")
- (make-local-variable 'comment-column)
- (setq comment-column 32)
- (make-local-variable 'comment-start-skip)
- (setq comment-start-skip "#+ *")
- ;;
- ;; config font-lock mode
- (make-local-variable 'font-lock-keywords)
- (setq font-lock-keywords csh-font-lock-keywords)
- ;;
- ;; Let the user customize
- (run-hooks 'csh-mode-hook)
- ) ;; defun
-
-;;
-;; Completion code supplied by Haavard Rue <hrue@imf.unit.no>.
-;;
-;;
-;; add a completion with a given type to the list
-;;
-(defun csh-addto-alist (completion type)
- (setq csh-completion-list
- (append csh-completion-list
- (list (cons completion type)))))
-
-(defun csh-bol-point ()
- (save-excursion
- (beginning-of-line)
- (point)))
-
-(defun csh-complete-symbol ()
- "Perform completion."
- (interactive)
- (let* ((case-fold-search)
- (end (point))
- (beg (unwind-protect
- (save-excursion
- (backward-sexp 1)
- (while (= (char-syntax (following-char)) ?\')
- (forward-char 1))
- (point))))
- (pattern (buffer-substring beg end))
- (predicate
- ;;
- ;; ` or $( mark a function
- ;;
- (save-excursion
- (goto-char beg)
- (if (or
- (save-excursion
- (backward-char 1)
- (looking-at "`"))
- (save-excursion
- (backward-char 2)
- (looking-at "\\$(")))
- (function (lambda (sym)
- (equal (cdr sym) csh-completion-type-function)))
- ;;
- ;; a $, ${ or ${# mark a variable
- ;;
- (if (or
- (save-excursion
- (backward-char 1)
- (looking-at "\\$"))
- (save-excursion
- (backward-char 2)
- (looking-at "\\${"))
- (save-excursion
- (backward-char 3)
- (looking-at "\\${#")))
- (function (lambda (sym)
- (equal (cdr sym)
- csh-completion-type-var)))
- ;;
- ;; don't know. use 'em all
- ;;
- (function (lambda (sym) t))))))
- ;;
- (completion (try-completion pattern csh-completion-list predicate)))
- ;;
- (cond ((eq completion t))
- ;;
- ;; oops, what is this ?
- ;;
- ((null completion)
- (message "Can't find completion for \"%s\"" pattern))
- ;;
- ;; insert
- ;;
- ((not (string= pattern completion))
- (delete-region beg end)
- (insert completion))
- ;;
- ;; write possible completion in the minibuffer,
- ;; use this instead of a seperate buffer (usual)
- ;;
- (t
- (let ((list (all-completions pattern csh-completion-list predicate))
- (string ""))
- (while list
- (progn
- (setq string (concat string (format "%s " (car list))))
- (setq list (cdr list))))
- (message string))))))
-
-;;
-;; init the list and pickup all
-;;
-(defun csh-completion-init-and-pickup ()
- (interactive)
- (let (case-fold-search)
- (csh-completion-list-init)
- (csh-pickup-all)))
-
-;;
-;; init the list
-;;
-(defun csh-completion-list-init ()
- (interactive)
- (setq csh-completion-list
- (list
- (cons "break" csh-completion-type-misc)
- (cons "breaksw" csh-completion-type-misc)
- (cons "case" csh-completion-type-misc)
- (cons "continue" csh-completion-type-misc)
- (cons "endif" csh-completion-type-misc)
- (cons "exit" csh-completion-type-misc)
- (cons "foreach" csh-completion-type-misc)
- (cons "if" csh-completion-type-misc)
- (cons "while" csh-completion-type-misc))))
-
-(defun csh-eol-point ()
- (save-excursion
- (end-of-line)
- (point)))
-
-(defun csh-pickup-all ()
- "Pickup all completions in buffer."
- (interactive)
- (csh-pickup-completion-driver (point-min) (point-max) t))
-
-(defun csh-pickup-completion (regexp type match pmin pmax)
- "Pickup completion in region and addit to the list, if not already
-there."
- (let ((i 0) kw obj)
- (save-excursion
- (goto-char pmin)
- (while (and
- (re-search-forward regexp pmax t)
- (match-beginning match)
- (setq kw (buffer-substring
- (match-beginning match)
- (match-end match))))
- (progn
- (setq obj (assoc kw csh-completion-list))
- (if (or (equal nil obj)
- (and (not (equal nil obj))
- (not (= type (cdr obj)))))
- (progn
- (setq i (1+ i))
- (csh-addto-alist kw type))))))
- i))
-
-(defun csh-pickup-completion-driver (pmin pmax message)
- "Driver routine for csh-pickup-completion."
- (if message
- (message "pickup completion..."))
- (let* (
- (i1
- (csh-pickup-completion csh-completion-regexp-var
- csh-completion-type-var
- csh-completion-match-var
- pmin pmax))
- (i2
- (csh-pickup-completion csh-completion-regexp-var2
- csh-completion-type-var
- csh-completion-match-var2
- pmin pmax))
- (i3
- (csh-pickup-completion csh-completion-regexp-function
- csh-completion-type-function
- csh-completion-match-function
- pmin pmax)))
- (if message
- (message "pickup %d variables and %d functions." (+ i1 i2) i3))))
-
-(defun csh-pickup-this-line ()
- "Pickup all completions in current line."
- (interactive)
- (csh-pickup-completion-driver (csh-bol-point) (csh-eol-point) nil))
-
-
-(provide 'csh-mode)
-;;; csh-mode.el ends here