Lines Matching +full:noise +full:- +full:sensitive
1 ;; csh-mode.el --- csh (and tcsh) script editing mode for Emacs.
11 ;; Put csh-mode.el in some directory in your load-path and load it.
16 ;; fashion as other programming language modes. Invoke describe-mode
22 ;; DH - Dan Harkless <software@harkless.org>
23 ;; CM - Carlo Migliorini <migliorini@sodalia.it>
24 ;; JR - Jack Repenning <jackr@sgi.com>
25 ;; GE - Gary Ellison <Gary.F.Ellison@att.com>
30 ;; --------- -- --------------------------------------------------------------
31 ;; 2 Apr 99 DH 1.2: Noticed an out-of-date comment referencing .bashrc etc.
32 ;; 11 Dec 96 DH 1.1: ksh-mode just indented continuation lines by 1 space.
33 ;; csh-mode looks at the first line and indents properly to line
34 ;; up under the open-paren, quote, or command.
38 ;; 9 Dec 96 DH 1.0: Brought csh-mode up to the level of functionality of
39 ;; the original ksh-mode.
40 ;; 7 Oct 96 CM 0.1: Hacked ksh-mode.el into minimally functional csh-mode.el
41 ;; by doing search-and-replace and some keyword changes.
42 ;; 8 Aug 96 JR (Last modification to ksh-mode 2.6.)
44 ;; 19 Jun 92 GE (Conception of ksh-mode.)
49 (defconst csh-mode-version "1.2"
50 "*Version number of this version of csh-mode")
52 (defvar csh-mode-hook
54 (auto-fill-mode 1))
55 "Hook to run each time csh-mode is entered.")
59 ;; -------------------------------------------> Variables controlling completion
61 (defvar csh-completion-list '())
62 (make-variable-buffer-local 'csh-completion-list)
63 (set-default 'csh-completion-list '())
65 ;; -type- : type number, 0:misc, 1:variable, 2:function
66 ;; -regexp-: regexp used to parse the script
67 ;; -match- : used by match-beginning/end to pickup target
69 (defvar csh-completion-type-misc 0)
70 (defvar csh-completion-regexp-var "\\([A-Za-z_0-9]+\\)=")
71 (defvar csh-completion-type-var 1)
72 (defvar csh-completion-match-var 1)
73 (defvar csh-completion-regexp-var2 "\\$\\({\\|{#\\)?\\([A-Za-z_0-9]+\\)[#%:}]?")
74 (defvar csh-completion-match-var2 2)
75 (defvar csh-completion-regexp-function
76 "\\(function\\)?[ \t]*\\([A-Za-z_0-9]+\\)[ \t]*([ \t]*)")
77 (defvar csh-completion-type-function 2)
78 (defvar csh-completion-match-function 2)
82 ;; ------------------------------------> Variables controlling indentation style
84 (defvar csh-indent 4
88 (defvar csh-case-item-offset csh-indent
90 (defvar csh-case-indent nil
92 (defvar csh-comment-regexp "^\\s *#"
94 csh-like languages.")
95 (defvar csh-match-and-tell t
96 "*If non-nil echo in the minibuffer the matching compound command
98 (defvar csh-tab-always-indent t
106 ;; ----------------------------------------> Constants containing syntax regexps
108 (defconst csh-case-default-re
112 (defconst csh-case-item-re "^\\s *\\(case .*\\|default\\):"
113 "Regexp used to match case-items")
115 (defconst csh-end-re "^\\s *end\\b"
118 (defconst csh-endif-re "^\\s *endif\\b"
121 (defconst csh-endsw-re "^\\s *endsw\\b"
124 (defconst csh-else-re "^\\s *\\belse\\(\\b\\|$\\)"
127 (defconst csh-else-if-re "^\\s *\\belse if\\(\\b\\|$\\)"
130 (defconst csh-if-re "^\\s *if\\b.+\\(\\\\\\|\\bthen\\b\\)"
131 "Regexp used to match non-one-line if statements")
133 (defconst csh-iteration-keywords-re "^[^#\n]*\\s\"*\\b\\(while\\|foreach\\)\\b"
136 (defconst csh-keywords-re
140 (defconst csh-label-re "^\\s *[^!#$\n ]+:"
141 "Regexp used to match flow-control labels")
143 (defconst csh-multiline-re "^.*\\\\$"
146 (defconst csh-switch-re "^\\s *switch\\b"
151 ;; ----------------------------------------> Variables controlling fontification
153 (defvar csh-keywords '("@" "alias" "bg" "break" "breaksw" "case" "cd" "chdir"
161 ;; tcsh-keywords
163 "filetest" "hup" "log" "ls-F" "nice" "nohup" "sched"
166 (require 'font-lock) ; need to do this before referring to font-lock-* below
168 (defconst csh-font-lock-keywords
173 '("^#.*" 0 font-lock-comment-face)
176 '("^\\s *\\([^!#$\n ]+\\):" 1 font-lock-function-name-face)
180 2 font-lock-function-name-face)
183 '("\\(@\\|set\\|setenv\\)\\s +\\([0-9A-Za-z_]+\\b\\)"
184 2 font-lock-variable-name-face)
187 '("\\$[][0-9A-Za-z_#:?]+" 0 font-lock-variable-name-face)
189 ;; Backquoted strings. 'keep' means to just fontify non-fontified text.
190 '("`\\(.*\\)`" 1 font-lock-reference-face keep)
193 ;; line to prevent re-fontifying text in comments. Due to this, we
198 '("^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*\""
199 1 font-lock-variable-name-face t) ; 1
200 '("^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*\\$[][0-9A-Za-z_#:?]+.*\""
201 1 font-lock-variable-name-face t) ; 2
202 (cons (concat "^[^#\n]*\".*\\(\\$[][0-9A-Za-z_#:?]+\\).*"
203 "\\$[][0-9A-Za-z_#:?]+.*\\$[][0-9A-Za-z_#:?]+.*\"")
204 (list 1 font-lock-variable-name-face t)) ; 3
207 '("^![^~= \n\t]+" 0 font-lock-reference-face t) ; BOL
208 '("^[^#\n]*[^#\\\n]\\(![^~= \n\t]+\\)" 1 font-lock-reference-face t) ; 1
210 1 font-lock-reference-face t) ; 2
215 (mapconcat 'identity csh-keywords "\\>\\|\\<")
220 (put 'csh-mode 'font-lock-keywords 'csh-font-lock-keywords)
224 ;; -------------------------------------------------------> Mode-specific tables
226 (defvar csh-mode-abbrev-table nil
228 (define-abbrev-table 'csh-mode-abbrev-table ())
230 (defvar csh-mode-map nil
232 (if csh-mode-map
234 (setq csh-mode-map (make-sparse-keymap))
235 ;;(define-key csh-mode-map "\177" 'backward-delete-char-untabify)
236 (define-key csh-mode-map "\C-c\t" 'csh-completion-init-and-pickup)
237 (define-key csh-mode-map "\C-j" 'reindent-then-newline-and-indent)
238 (define-key csh-mode-map "\e\t" 'csh-complete-symbol)
239 (define-key csh-mode-map "\n" 'reindent-then-newline-and-indent)
240 (define-key csh-mode-map '[return] 'reindent-then-newline-and-indent)
241 (define-key csh-mode-map "\t" 'csh-indent-command)
242 ;;(define-key csh-mode-map "\t" 'csh-indent-line)
245 (defvar csh-mode-syntax-table nil
247 (if csh-mode-syntax-table
251 (setq csh-mode-syntax-table (make-syntax-table))
252 (modify-syntax-entry ?& "." csh-mode-syntax-table) ; & -punctuation
253 (modify-syntax-entry ?* "." csh-mode-syntax-table) ; * -punctuation
254 (modify-syntax-entry ?- "." csh-mode-syntax-table) ; - -punctuation
255 (modify-syntax-entry ?= "." csh-mode-syntax-table) ; = -punctuation
256 (modify-syntax-entry ?+ "." csh-mode-syntax-table) ; + -punctuation
257 (modify-syntax-entry ?| "." csh-mode-syntax-table) ; | -punctuation
258 (modify-syntax-entry ?< "." csh-mode-syntax-table) ; < -punctuation
259 (modify-syntax-entry ?> "." csh-mode-syntax-table) ; > -punctuation
260 (modify-syntax-entry ?/ "." csh-mode-syntax-table) ; / -punctuation
261 (modify-syntax-entry ?\' "\"" csh-mode-syntax-table) ; ' -string quote
262 (modify-syntax-entry ?. "w" csh-mode-syntax-table) ; . -word constituent
263 (modify-syntax-entry ?? "w" csh-mode-syntax-table) ; ? -word constituent
265 ;; \n - comment ender, first character of 2-char comment sequence
266 (modify-syntax-entry ?\n "> 1" csh-mode-syntax-table) ; # -word constituent
268 ;; - whitespace, first character of 2-char comment sequence
269 (modify-syntax-entry ? " 1" csh-mode-syntax-table) ;
271 ;; \t - whitespace, first character of 2-char comment sequence
272 (modify-syntax-entry ?\t " 1" csh-mode-syntax-table) ; # -word constituent
274 ;; # - word constituent, second character of 2-char comment sequence
275 (modify-syntax-entry ?# "w 2" csh-mode-syntax-table) ; # -word constituent
280 ;; ------------------------------------------------------------------> Functions
282 (defun csh-current-line ()
285 (+ (count-lines (point-min) (point))
286 (if (= (current-column) 0) 1 0))
289 (defun csh-get-compound-level
290 (begin-re end-re anchor-point &optional balance-list)
294 (;; Locate the next compound begin keyword bounded by point-min
295 (match-point (if (re-search-backward begin-re (point-min) t)
296 (match-beginning 0) 0))
297 (nest-column (if (zerop match-point)
300 (goto-char match-point)
301 (current-indentation))))
302 (nest-list (cons 0 0)) ;; sentinel cons since cdr is >= 1
304 (if (zerop match-point)
307 (if (nlistp balance-list)
308 (setq balance-list (list)))
310 (while (and (consp nest-list) (zerop (cdr nest-list))
311 (re-search-forward end-re anchor-point t))
312 (if (not (memq (point) balance-list))
314 (setq balance-list (cons (point) balance-list))
315 (goto-char match-point) ;; beginning of compound cmd
316 (setq nest-list
317 (csh-get-compound-level begin-re end-re
318 anchor-point balance-list))
321 (cond ((consp nest-list)
322 (if (zerop (cdr nest-list))
324 (goto-char match-point)
325 (cons nest-column (csh-current-line)))
326 nest-list))
334 (defun csh-get-nest-level ()
335 "Return a 2 element list (nest-level nest-line) describing where the
337 (let ((case-fold-search)
339 (save-excursion
340 (forward-line -1)
343 (if (and (not (looking-at "^\\s *$"))
344 (not (save-excursion
345 (forward-line -1)
346 (beginning-of-line)
347 (looking-at csh-multiline-re)))
348 (not (looking-at csh-comment-regexp)))
349 (setq level (cons (current-indentation)
350 (csh-current-line)))
351 (forward-line -1)
355 (cons (current-indentation) (csh-current-line))
361 (defun csh-get-nester-column (nest-line)
362 "Return the column to indent to with respect to nest-line taking
364 (save-excursion
365 (let ((fence-post)
366 (case-fold-search)
367 (start-line (csh-current-line)))
370 (cond ((looking-at csh-case-item-re)
372 (save-excursion
373 (goto-line nest-line)
374 (let ((fence-post (save-excursion (end-of-line) (point))))
375 (cond ((re-search-forward csh-switch-re fence-post t)
377 (goto-char (match-beginning 0))
378 (+ (current-indentation) csh-case-item-offset))
380 ((re-search-forward csh-case-item-re fence-post t)
384 (goto-char (match-beginning 0))
385 (current-indentation))
389 (- (current-indentation) csh-case-item-offset))
392 (t;; Not a case-item. What to do relative to the nest-line?
393 (save-excursion
394 (goto-line nest-line)
395 (setq fence-post (save-excursion (end-of-line) (point)))
396 (save-excursion
400 ((and (looking-at csh-multiline-re)
401 (save-excursion
402 (goto-line (1- start-line))
403 (looking-at csh-multiline-re)))
404 (if (looking-at ".*[\'\"]\\\\")
408 (re-search-forward "[\'\"]")
409 (forward-char -1))
410 (if (looking-at ".*([^\)\n]*\\\\")
413 (re-search-forward "(" fence-post t)
415 (re-search-forward "[^ \t]+[ \t]+" fence-post t)))
416 (current-column))
419 ;; which might be embedded within a case-item,
420 ;; it is necessary to use re-search-forward.
422 ;; case-sensitive.
423 ((re-search-forward csh-keywords-re fence-post t)
424 (goto-char (match-beginning 1))
425 (if (looking-at csh-switch-re)
426 (+ (current-indentation) csh-case-item-offset)
427 (+ (current-indentation)
428 (if (null csh-indent)
429 2 csh-indent)
432 ((re-search-forward csh-case-default-re fence-post t)
433 (if (null csh-indent)
435 (goto-char (match-end 1))
436 (+ (current-indentation) 1))
438 (goto-char (match-beginning 1))
439 (+ (current-indentation) csh-indent))
444 ((looking-at csh-case-item-re)
445 (if (null csh-case-indent)
447 (re-search-forward csh-case-item-re fence-post t)
448 (goto-char (match-end 1))
449 (+ (current-column) 1))
450 (+ (current-indentation) csh-case-indent)))
453 ;; If this is the first statement under a control-flow
455 ((csh-looking-at-label)
456 (+ (current-indentation) csh-indent))
458 ;; This is hosed when using current-column
459 ;; and there is a multi-command expression as the
461 (t (current-indentation)))
464 );; Not a case-item
469 (defun csh-indent-command ()
471 csh-tab-always-indent customization"
473 (let (case-fold-search)
474 (cond ((save-excursion
475 (skip-chars-backward " \t")
477 (csh-indent-line))
478 (csh-tab-always-indent
479 (save-excursion
480 (csh-indent-line)))
481 (t (insert-tab))
485 (defun csh-indent-line ()
489 (let (case-fold-search)
490 (save-excursion
491 (beginning-of-line)
498 (level-list (csh-get-nest-level)) ; Where to nest against
499 ;; (last-line-level (car level-list))
500 (this-line-level (current-indentation))
501 (nester-column (csh-get-nester-column (cdr level-list)))
502 (struct-match (csh-match-structure-and-reindent))
504 (if struct-match
505 (setq nester-column struct-match))
506 (if (eq nester-column this-line-level)
508 (beginning-of-line)
510 (back-to-indentation)
511 (delete-region beg (point)))
512 (indent-to nester-column))
520 (this-line-level (current-indentation))
521 (this-bol (save-excursion
522 (beginning-of-line)
524 (this-point (- (point) this-bol))
526 (cond ((> this-line-level this-point);; point in initial white space
527 (back-to-indentation))
534 (defun csh-indent-region (start end)
537 ;; the match noise turned off. Only modifies nonempty lines.
538 (save-excursion
539 (let (csh-match-and-tell
540 (endmark (copy-marker end)))
542 (goto-char start)
543 (beginning-of-line)
545 (while (> (marker-position endmark) start)
547 (csh-indent-line))
548 (forward-line 1)
551 (set-marker endmark nil)
556 (defun csh-line-to-string ()
559 (skip-chars-forward " \t") ;; skip tabs as well as spaces
560 (buffer-substring (point)
562 (end-of-line 1)
565 (defun csh-looking-at-label ()
568 (looking-at csh-label-re)
569 (not (looking-at "^\\s *default:"))))
571 (defun csh-match-indent-level (begin-re end-re)
575 (let* ((case-fold-search)
576 (nest-list
577 (save-excursion
578 (csh-get-compound-level begin-re end-re (point))
581 (if (null nest-list)
583 (if csh-match-and-tell
587 (nest-level (car nest-list))
588 (match-line (cdr nest-list))
590 (if csh-match-and-tell
591 (save-excursion
592 (goto-line match-line)
593 (message "Matched ... %s" (csh-line-to-string))
595 ) ;; if csh-match-and-tell
596 nest-level ;;Propagate a hit.
600 ) ;; defun csh-match-indent-level
602 (defun csh-match-structure-and-reindent ()
605 if csh-match-and-tell is non-nil the matching structure will echo in
608 (let (case-fold-search)
609 (save-excursion
610 (beginning-of-line)
611 (cond ((looking-at csh-else-re)
612 (csh-match-indent-level csh-if-re csh-endif-re))
613 ((looking-at csh-else-if-re)
614 (csh-match-indent-level csh-if-re csh-endif-re))
615 ((looking-at csh-endif-re)
616 (csh-match-indent-level csh-if-re csh-endif-re))
617 ((looking-at csh-end-re)
618 (csh-match-indent-level csh-iteration-keywords-re csh-end-re))
619 ((looking-at csh-endsw-re)
620 (csh-match-indent-level csh-switch-re csh-endsw-re))
621 ((csh-looking-at-label)
622 ;; Flush control-flow labels left since they don't nest.
631 (defun csh-mode ()
632 "csh-mode 2.0 - Major mode for editing csh and tcsh scripts.
634 \\{csh-mode-map}
636 csh-indent
639 csh-case-indent
643 csh-case-item-offset
646 csh-tab-always-indent
651 csh-match-and-tell
652 If non-nil echo in the minibuffer the matching compound command
655 csh-comment-regexp
657 csh-like languages. Default value is \"\^\\\\s *#\".
661 (setq csh-indent default-tab-width)
665 if [ -z $foo ]
667 bar # <-- csh-group-offset is additive to csh-indent
672 (setq csh-indent default-tab-width)
673 (setq csh-group-offset (- 0 csh-indent))
677 if [ -z $foo ]
684 (setq csh-case-item-offset 1)
685 (setq csh-case-indent nil)
690 foo) bar # <-- csh-case-item-offset
691 baz;; # <-- csh-case-indent aligns with \")\"
697 (setq csh-case-item-offset 1)
698 (setq csh-case-indent 6)
703 foo) bar # <-- csh-case-item-offset
704 baz;; # <-- csh-case-indent
711 Put csh-mode.el in some directory in your load-path.
714 (setq auto-mode-alist
715 (append auto-mode-alist
717 '(\"\\\\.csh$\" . csh-mode)
718 '(\"\\\\.login\" . csh-mode))))
720 (setq csh-mode-hook
722 (font-lock-mode 1) ;; font-lock the buffer
723 (setq csh-indent 8)
724 (setq csh-tab-always-indent t)
725 (setq csh-match-and-tell t)
726 (setq csh-align-to-keyword t) ;; Turn on keyword alignment
729 (kill-all-local-variables)
730 (use-local-map csh-mode-map)
731 (setq major-mode 'csh-mode)
732 (setq mode-name "Csh")
733 (setq local-abbrev-table csh-mode-abbrev-table)
734 (set-syntax-table csh-mode-syntax-table)
735 (make-local-variable 'indent-line-function)
736 (setq indent-line-function 'csh-indent-line)
737 (make-local-variable 'indent-region-function)
738 (setq indent-region-function 'csh-indent-region)
739 (make-local-variable 'comment-start)
740 (setq comment-start "# ")
741 (make-local-variable 'comment-end)
742 (setq comment-end "")
743 (make-local-variable 'comment-column)
744 (setq comment-column 32)
745 (make-local-variable 'comment-start-skip)
746 (setq comment-start-skip "#+ *")
748 ;; config font-lock mode
749 (make-local-variable 'font-lock-keywords)
750 (setq font-lock-keywords csh-font-lock-keywords)
753 (run-hooks 'csh-mode-hook)
762 (defun csh-addto-alist (completion type)
763 (setq csh-completion-list
764 (append csh-completion-list
767 (defun csh-bol-point ()
768 (save-excursion
769 (beginning-of-line)
772 (defun csh-complete-symbol ()
775 (let* ((case-fold-search)
777 (beg (unwind-protect
778 (save-excursion
779 (backward-sexp 1)
780 (while (= (char-syntax (following-char)) ?\')
781 (forward-char 1))
783 (pattern (buffer-substring beg end))
788 (save-excursion
789 (goto-char beg)
791 (save-excursion
792 (backward-char 1)
793 (looking-at "`"))
794 (save-excursion
795 (backward-char 2)
796 (looking-at "\\$(")))
798 (equal (cdr sym) csh-completion-type-function)))
803 (save-excursion
804 (backward-char 1)
805 (looking-at "\\$"))
806 (save-excursion
807 (backward-char 2)
808 (looking-at "\\${"))
809 (save-excursion
810 (backward-char 3)
811 (looking-at "\\${#")))
814 csh-completion-type-var)))
820 (completion (try-completion pattern csh-completion-list predicate)))
832 (delete-region beg end)
839 (let ((list (all-completions pattern csh-completion-list predicate))
850 (defun csh-completion-init-and-pickup ()
852 (let (case-fold-search)
853 (csh-completion-list-init)
854 (csh-pickup-all)))
859 (defun csh-completion-list-init ()
861 (setq csh-completion-list
863 (cons "break" csh-completion-type-misc)
864 (cons "breaksw" csh-completion-type-misc)
865 (cons "case" csh-completion-type-misc)
866 (cons "continue" csh-completion-type-misc)
867 (cons "endif" csh-completion-type-misc)
868 (cons "exit" csh-completion-type-misc)
869 (cons "foreach" csh-completion-type-misc)
870 (cons "if" csh-completion-type-misc)
871 (cons "while" csh-completion-type-misc))))
873 (defun csh-eol-point ()
874 (save-excursion
875 (end-of-line)
878 (defun csh-pickup-all ()
881 (csh-pickup-completion-driver (point-min) (point-max) t))
883 (defun csh-pickup-completion (regexp type match pmin pmax)
887 (save-excursion
888 (goto-char pmin)
890 (re-search-forward regexp pmax t)
891 (match-beginning match)
892 (setq kw (buffer-substring
893 (match-beginning match)
894 (match-end match))))
896 (setq obj (assoc kw csh-completion-list))
902 (csh-addto-alist kw type))))))
905 (defun csh-pickup-completion-driver (pmin pmax message)
906 "Driver routine for csh-pickup-completion."
911 (csh-pickup-completion csh-completion-regexp-var
912 csh-completion-type-var
913 csh-completion-match-var
916 (csh-pickup-completion csh-completion-regexp-var2
917 csh-completion-type-var
918 csh-completion-match-var2
921 (csh-pickup-completion csh-completion-regexp-function
922 csh-completion-type-function
923 csh-completion-match-function
928 (defun csh-pickup-this-line ()
931 (csh-pickup-completion-driver (csh-bol-point) (csh-eol-point) nil))
934 (provide 'csh-mode)
935 ;;; csh-mode.el ends here