;;; 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>
: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
;; 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
;; "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
(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 ()
?\# "<"
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)
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)
'((bash sh-append posix
"." "alias" "bg" "bind" "builtin" "compgen" "complete"
"declare" "dirs" "disown" "enable" "fc" "fg" "help" "history"
- "jobs" "kill" "let" "local" "popd" "printf" "pushd" "source"
- "suspend" "typeset" "unalias")
+ "jobs" "kill" "let" "local" "popd" "printf" "pushd" "shopt"
+ "source" "suspend" "typeset" "unalias")
;; The next entry is only used for defining the others
(bourne sh-append shell
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)
(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)
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)
(defvar sh-font-lock-keywords
'((csh sh-append shell
- '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1
- font-lock-variable-name-face))
+ ("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1
+ font-lock-variable-name-face))
(es sh-append executable-font-lock-keywords
- '("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1
- font-lock-variable-name-face))
+ ("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1
+ font-lock-variable-name-face))
(rc sh-append es)
(sh sh-append shell
;; Variable names.
- '("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2
+ ("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2
font-lock-variable-name-face)
;; Function names.
- '("^\\(\\sw+\\)[ \t]*(" 1 font-lock-function-name-face)
- '("\\<\\(function\\)\\>[ \t]*\\(\\sw+\\)?"
+ ("^\\(\\sw+\\)[ \t]*(" 1 font-lock-function-name-face)
+ ("\\<\\(function\\)\\>[ \t]*\\(\\sw+\\)?"
(1 font-lock-keyword-face) (2 font-lock-function-name-face nil t)))
;; The next entry is only used for defining the others
(shell sh-append executable-font-lock-keywords
;; Using font-lock-string-face here confuses sh-get-indent-info.
- '("\\\\$" 0 font-lock-warning-face)
- '("\\\\[^A-Za-z0-9]" 0 font-lock-string-face)
- '("\\${?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\|[$*_]\\)" 1
+ ("\\\\$" 0 font-lock-warning-face)
+ ("\\\\[^A-Za-z0-9]" 0 font-lock-string-face)
+ ("\\${?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\|[$*_]\\)" 1
font-lock-variable-name-face))
(rpm sh-append rpm2
- '("%{?\\(\\sw+\\)" 1 font-lock-keyword-face))
+ ("%{?\\(\\sw+\\)" 1 font-lock-keyword-face))
(rpm2 sh-append shell
- '("^\\(\\sw+\\):" 1 font-lock-variable-name-face)))
+ ("^\\(\\sw+\\):" 1 font-lock-variable-name-face)))
"Default expressions to highlight in Shell Script modes. See `sh-feature'.")
(defvar sh-font-lock-keywords-1
;; 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) '(?\" ?\'))
(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))))
- (sh-feature alist))
+ (if (assq sh-shell alist)
+ (sh-feature alist)
+ (eval sh-shell)))
(cddr val)))))
(if function
(nconc alist
(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)
(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 ?\} )
(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
(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
> "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 _
_ \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
(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 ?\} )
"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
< < "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