Fix commit conflicts.
[bpt/emacs.git] / lisp / progmodes / sh-script.el
index 87eb30b..bcabc50 100644 (file)
@@ -1,6 +1,6 @@
 ;;; sh-script.el --- shell-script editing commands for Emacs
 
-;; Copyright (C) 1993, 94, 95, 96, 97, 1999, 2001, 2003
+;; Copyright (C) 1993, 94, 95, 96, 97, 1999, 2001, 03, 2004
 ;;  Free Software Foundation, Inc.
 
 ;; Author: Daniel Pfeiffer <occitan@esperanto.org>
@@ -315,9 +315,7 @@ shell it really is."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice (const :tag "No Arguments" nil)
                               (string :tag "Arguments")
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 (defcustom sh-imenu-generic-expression
@@ -355,24 +353,29 @@ the car and cdr are the same symbol.")
 (defvar sh-shell (sh-canonicalize-shell (file-name-nondirectory sh-shell-file))
   "The shell being programmed.  This is set by \\[sh-set-shell].")
 
+(defvar sh-mode-abbrev-table nil)
+
+(define-abbrev-table 'sh-mode-abbrev-table ())
+
+
 ;; I turned off this feature because it doesn't permit typing commands
 ;; in the usual way without help.
 ;;(defvar sh-abbrevs
-;;  '((csh eval sh-abbrevs shell
+;;  '((csh sh-abbrevs shell
 ;;      "switch" 'sh-case
 ;;      "getopts" 'sh-while-getopts)
 
-;;    (es eval sh-abbrevs shell
+;;    (es sh-abbrevs shell
 ;;     "function" 'sh-function)
 
-;;    (ksh88 eval sh-abbrevs sh
+;;    (ksh88 sh-abbrevs sh
 ;;        "select" 'sh-select)
 
-;;    (rc eval sh-abbrevs shell
+;;    (rc sh-abbrevs shell
 ;;     "case" 'sh-case
 ;;     "function" 'sh-function)
 
-;;    (sh eval sh-abbrevs shell
+;;    (sh sh-abbrevs shell
 ;;     "case" 'sh-case
 ;;     "function" 'sh-function
 ;;     "until" 'sh-until
@@ -385,7 +388,7 @@ the car and cdr are the same symbol.")
 ;;        "tmpfile" sh-tmp-file
 ;;        "while" sh-while)
 
-;;    (zsh eval sh-abbrevs ksh88
+;;    (zsh sh-abbrevs ksh88
 ;;      "repeat" 'sh-repeat))
 ;;  "Abbrev-table used in Shell-Script mode.  See `sh-feature'.
 ;;;Due to the internal workings of abbrev tables, the shell name symbol is
@@ -400,6 +403,10 @@ the car and cdr are the same symbol.")
     (modify-syntax-entry (pop list) (pop list) table))
   table)
 
+(defvar sh-mode-syntax-table nil
+  "The syntax table to use for Shell-Script mode.
+This is buffer-local in every such buffer.")
+
 (defvar sh-mode-default-syntax-table
   (sh-mode-syntax-table ()
        ?\# "<"
@@ -414,6 +421,7 @@ the car and cdr are the same symbol.")
        ?^ "_"
        ?~ "_"
        ?, "_"
+       ?= "."
        ?< "."
        ?> ".")
   "Default syntax table for shell mode.")
@@ -487,16 +495,13 @@ the car and cdr are the same symbol.")
 
 (defcustom sh-require-final-newline
   '((csh . t)
-    (pdksh . t)
-    (rc . require-final-newline)
-    (sh . require-final-newline))
+    (pdksh . t))
   "*Value of `require-final-newline' in Shell-Script mode buffers.
+\(SHELL . t) means use the value of `mode-require-final-newline' for SHELL.
 See `sh-feature'."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice (const :tag "require" t)
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 
@@ -511,9 +516,7 @@ First grouping matches the variable name.  This is upto and including the `='
 sign.  See `sh-feature'."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice regexp
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 
@@ -635,9 +638,7 @@ Note that on some systems not all builtins are available or some are
 implemented as aliases.  See `sh-feature'."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice (repeat string)
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 
@@ -652,16 +653,14 @@ implemented as aliases.  See `sh-feature'."
 
     (rc "else")
 
-    (sh "do" "elif" "else" "if" "then" "trap" "type" "until" "while"))
+    (sh "!" "do" "elif" "else" "if" "then" "trap" "type" "until" "while"))
   "*List of keywords that may be immediately followed by a builtin or keyword.
 Given some confusion between keywords and builtins depending on shell and
 system, the distinction here has been based on whether they influence the
 flow of control or syntax.  See `sh-feature'."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice (repeat string)
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 
@@ -698,9 +697,7 @@ flow of control or syntax.  See `sh-feature'."
 See `sh-feature'."
   :type '(repeat (cons (symbol :tag "Shell")
                       (choice (repeat string)
-                              (cons :format "Evaluate: %v"
-                                    (const :format "" eval)
-                                    sexp))))
+                              (sexp :format "Evaluate: %v"))))
   :group 'sh-script)
 
 
@@ -925,7 +922,7 @@ be indented (i.e. a <<- was used rather than just <<)."
          ;; Skip through one pattern
          (while
              (or (/= 0 (skip-syntax-backward "w_"))
-                 (/= 0 (skip-chars-backward "?[]*/\\"))
+                 (/= 0 (skip-chars-backward "?[]*@/\\"))
                  (and (sh-is-quoted-p (1- (point)))
                       (goto-char (- (point) 2)))
                  (when (memq (char-before) '(?\" ?\'))
@@ -1104,7 +1101,7 @@ does not affect then else elif or fi statements themselves."
   :type `(choice ,@ sh-number-or-symbol-list )
   :group 'sh-indentation)
 
-(defcustom sh-indent-for-then '+
+(defcustom sh-indent-for-then 0
   "*How much to indent a then relative to an if."
   :type `(choice ,@ sh-number-or-symbol-list )
   :group 'sh-indentation)
@@ -1487,11 +1484,11 @@ Calls the value of `sh-set-shell-hook' if set."
            (executable-set-magic shell (sh-feature sh-shell-arg)
                                  no-query-flag insert-flag)))
   (let ((tem (sh-feature sh-require-final-newline)))
-    (unless (eq tem 'require-final-newline)
-      (setq require-final-newline tem)))
+    (if (eq tem t)
+       (setq require-final-newline mode-require-final-newline)))
   (setq
        comment-start-skip "#+[\t ]*"
-;;;    local-abbrev-table (sh-feature sh-abbrevs)
+       local-abbrev-table sh-mode-abbrev-table
        mode-line-process (format "[%s]" sh-shell)
        sh-shell-variables nil
        sh-shell-variables-initialized nil
@@ -1563,10 +1560,10 @@ in ALIST."
        (unless elt
          (setq elt (assq 'sh alist)))
        (if (and (consp (setq val (cdr elt)))
-                (eq (car val) 'sh-append))
+                (memq (car val) '(sh-append sh-modify)))
            (setcdr elt
                    (setq val
-                         (apply 'sh-append
+                         (apply (car val)
                                 (let ((sh-shell (car (cdr val))))
                                    (if (assq sh-shell alist)
                                        (sh-feature alist)
@@ -2048,7 +2045,8 @@ STRING         This is ignored for the purposes of calculating
                    (progn
                      (setq result (append result val))
                      (setq align-point (point))))
-               (forward-char -1)
+               (or (bobp)
+                   (forward-char -1))
                (skip-chars-forward "[a-z0-9]*?")
                )
               ((string-match "[])}]" x)
@@ -3124,16 +3122,16 @@ This is always added to the end of the buffer."
 
 (define-skeleton sh-for
   "Insert a for loop.  See `sh-feature'."
-  (csh eval sh-modify sh
+  (csh sh-modify sh
        1 ""
        2 "foreach "
        4 " ( "
        6 " )"
        15 '<
        16 "end")
-  (es eval sh-modify rc
+  (es sh-modify rc
       4 " = ")
-  (rc eval sh-modify sh
+  (rc sh-modify sh
       2 "for( "
       6 " ) {"
       15 ?\} )
@@ -3146,14 +3144,14 @@ This is always added to the end of the buffer."
 
 (define-skeleton sh-indexed-loop
   "Insert an indexed loop from 1 to n.  See `sh-feature'."
-  (bash eval identity posix)
+  (bash sh-modify posix)
   (csh "Index variable: "
        "@ " str " = 1" \n
        "while( $" str " <= " (read-string "upper limit: ") " )" \n
        > _ ?$ str \n
        "@ " str "++" \n
        < "end" \n)
-  (es eval sh-modify rc
+  (es sh-modify rc
       4 " =")
   (ksh88 "Index variable: "
         > "integer " str "=0" \n
@@ -3251,13 +3249,13 @@ t means to return a list of all possible completions of STRING.
 
 (define-skeleton sh-function
   "Insert a function definition.  See `sh-feature'."
-  (bash eval sh-modify ksh88
+  (bash sh-modify ksh88
        3 "() {")
   (ksh88 "name: "
         "function " str " {" \n
         > _ \n
         < "}" \n)
-  (rc eval sh-modify ksh88
+  (rc sh-modify ksh88
       1 "fn ")
   (sh ()
       "() {" \n
@@ -3333,14 +3331,14 @@ t means to return a list of all possible completions of STRING.
         > "select " str " in " _ "; do" \n
         > ?$ str \n
         "done" > \n)
-  (bash eval sh-append ksh88))
+  (bash sh-append ksh88))
 ;;;(put 'sh-select 'menu-enable '(sh-feature sh-select))
 
 
 
 (define-skeleton sh-tmp-file
   "Insert code to setup temporary file handling.  See `sh-feature'."
-  (bash eval identity ksh88)
+  (bash sh-append ksh88)
   (csh (file-name-nondirectory (buffer-file-name))
        "set tmp = /tmp/" str ".$$" \n
        "onintr exit" \n _
@@ -3359,7 +3357,7 @@ t means to return a list of all possible completions of STRING.
       _ \n
       ?\} > \n
       ?\} > \n)
-  (ksh88 eval sh-modify sh
+  (ksh88 sh-modify sh
         7 "EXIT")
   (rc (file-name-nondirectory (buffer-file-name))
       > "tmp = /tmp/" str ".$pid" \n
@@ -3383,17 +3381,17 @@ t means to return a list of all possible completions of STRING.
 
 (define-skeleton sh-while
   "Insert a while loop.  See `sh-feature'."
-  (csh eval sh-modify sh
+  (csh sh-modify sh
        2 ""
        3 "while( "
        5 " )"
        10 '<
        11 "end")
-  (es eval sh-modify sh
+  (es sh-modify sh
       3 "while { "
       5 " } {"
       10 ?\} )
-  (rc eval sh-modify sh
+  (rc sh-modify sh
       3 "while( "
       5 " ) {"
       10 ?\} )
@@ -3409,7 +3407,7 @@ t means to return a list of all possible completions of STRING.
   "Insert a while getopts loop.  See `sh-feature'.
 Prompts for an options string which consists of letters for each recognized
 option followed by a colon `:' if the option accepts an argument."
-  (bash eval sh-modify sh
+  (bash sh-modify sh
        18 "${0##*/}")
   (csh nil
        "while( 1 )" \n
@@ -3434,11 +3432,11 @@ option followed by a colon `:' if the option accepts an argument."
        < < "endsw" \n
        "shift" \n
        < "end" \n)
-  (ksh88 eval sh-modify sh
+  (ksh88 sh-modify sh
         16 "print"
         18 "${0##*/}"
         37 "OPTIND-1")
-  (posix eval sh-modify sh
+  (posix sh-modify sh
         18 "$(basename $0)")
   (sh "optstring: "
       > "while getopts :" str " OPT; do" \n