;;; sh-script.el --- shell-script editing commands for Emacs
-;; Copyright (C) 1993-1997, 1999, 2001-2011 Free Software Foundation, Inc.
+;; Copyright (C) 1993-1997, 1999, 2001-2012 Free Software Foundation, Inc.
;; Author: Daniel Pfeiffer <occitan@esperanto.org>
;; Version: 2.0f
(define-key map "\C-c+" 'sh-add)
(define-key map "\C-\M-x" 'sh-execute-region)
(define-key map "\C-c\C-x" 'executable-interpret)
+ ;; FIXME: Use post-self-insert-hook.
(define-key map "<" 'sh-maybe-here-document)
(define-key map "(" 'skeleton-pair-insert-maybe)
(define-key map "{" 'skeleton-pair-insert-maybe)
'((csh . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*[-+*/%^]?=")
;; actually spaces are only supported in let/(( ... ))
(ksh88 . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*\\([-+*/%&|~^]\\|<<\\|>>\\)?=")
+ (bash . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?\\+?=")
(rc . "\\<\\([[:alnum:]_*]+\\)[ \t]*=")
(sh . "\\<\\([[:alnum:]_]+\\)="))
"Regexp for the variable name and what may follow in an assignment.
font-lock-variable-name-face))
(rc sh-append es)
- (bash sh-append shell ("\\$(\\(\\sw+\\)" (1 'sh-quoted-exec t) ))
+ (bash sh-append sh ("\\$(\\(\\sw+\\)" (1 'sh-quoted-exec t) ))
(sh sh-append shell
;; Variable names.
("\\$\\({#?\\)?\\([[:alpha:]_][[:alnum:]_]*\\|[-#?@!]\\)" 2
subshells can nest."
;; FIXME: This can (and often does) match multiple lines, yet it makes no
;; effort to handle multiline cases correctly, so it ends up being
- ;; rather flakey.
+ ;; rather flaky.
(when (eq ?\" (nth 3 (syntax-ppss))) ; Check we matched an opening quote.
;; bingo we have a $( or a ` inside a ""
- (let ((char (char-after (point)))
- ;; `state' can be: double-quote, backquote, code.
+ (let (;; `state' can be: double-quote, backquote, code.
(state (if (eq (char-before) ?`) 'backquote 'code))
;; Stacked states in the context.
(states '(double-quote)))
(defun sh-font-lock-paren (start)
(unless (nth 8 (syntax-ppss))
- (save-excursion
- (goto-char start)
- ;; Skip through all patterns
- (while
- (progn
+ (save-excursion
+ (goto-char start)
+ ;; Skip through all patterns
+ (while
+ (progn
(while
(progn
- (forward-comment (- (point-max)))
+ (forward-comment (- (point-max)))
(when (and (eolp) (sh-is-quoted-p (point)))
(forward-char -1)
t)))
- ;; Skip through one pattern
- (while
- (or (/= 0 (skip-syntax-backward "w_"))
+ ;; Skip through one pattern
+ (while
+ (or (/= 0 (skip-syntax-backward "w_"))
(/= 0 (skip-chars-backward "-$=?[]*@/\\\\"))
- (and (sh-is-quoted-p (1- (point)))
- (goto-char (- (point) 2)))
+ (and (sh-is-quoted-p (1- (point)))
+ (goto-char (- (point) 2)))
(when (memq (char-before) '(?\" ?\' ?\}))
- (condition-case nil (progn (backward-sexp 1) t)
- (error nil)))))
- ;; Patterns can be preceded by an open-paren (Bug#1320).
- (if (eq (char-before (point)) ?\()
- (backward-char 1))
- (while (progn
- (forward-comment (- (point-max)))
- ;; Maybe we've bumped into an escaped newline.
- (sh-is-quoted-p (point)))
- (backward-char 1))
- (when (eq (char-before) ?|)
- (backward-char 1) t)))
- (when (progn (backward-char 2)
- (if (> start (line-end-position))
- (put-text-property (point) (1+ start)
- 'syntax-multiline t))
- ;; FIXME: The `in' may just be a random argument to
- ;; a normal command rather than the real `in' keyword.
- ;; I.e. we should look back to try and find the
- ;; corresponding `case'.
- (and (looking-at ";[;&]\\|in")
+ (condition-case nil (progn (backward-sexp 1) t)
+ (error nil)))))
+ ;; Patterns can be preceded by an open-paren (Bug#1320).
+ (if (eq (char-before (point)) ?\()
+ (backward-char 1))
+ (while (progn
+ (forward-comment (- (point-max)))
+ ;; Maybe we've bumped into an escaped newline.
+ (sh-is-quoted-p (point)))
+ (backward-char 1))
+ (when (eq (char-before) ?|)
+ (backward-char 1) t)))
+ (when (progn (backward-char 2)
+ (if (> start (line-end-position))
+ (put-text-property (point) (1+ start)
+ 'syntax-multiline t))
+ ;; FIXME: The `in' may just be a random argument to
+ ;; a normal command rather than the real `in' keyword.
+ ;; I.e. we should look back to try and find the
+ ;; corresponding `case'.
+ (and (looking-at ";[;&]\\|\\_<in")
;; ";; esac )" is a case that looks like a case-pattern
;; but it's really just a close paren after a case
;; statement. I.e. if we skipped over `esac' just now,
;; "For debugging: display message ARGS if variable SH-DEBUG is non-nil."
;; (if sh-debug
;; (apply 'message args)))
-(defmacro sh-debug (&rest args))
+(defmacro sh-debug (&rest _args))
(defconst sh-symbol-list
'((const :tag "+ " :value +
values of variables, and for the commands using indentation styles.")
(defvar sh-make-vars-local t
- "*Controls whether indentation variables are local to the buffer.
+ "Controls whether indentation variables are local to the buffer.
If non-nil, indentation variables are made local initially.
If nil, you can later make the variables local by invoking
command `sh-make-vars-local'.
\f
;; Indentation stuff.
(defun sh-must-support-indent ()
- "*Signal an error if the shell type for this buffer is not supported.
+ "Signal an error if the shell type for this buffer is not supported.
Also, the buffer must be in Shell-script mode."
(unless sh-indent-supported-here
(error "This buffer's shell does not support indentation through Emacs")))
(save-excursion
(let ((have-result nil)
this-kw
- start
val
(result nil)
(align-point nil)
;; We start off at beginning of this line.
;; Scan previous statements while this is <=
;; start of previous line.
- (setq start (point)) ;; for debug only
(goto-char prev-line-end)
(setq x t)
(while (and x (setq x (sh-prev-thing)))
If INFO is supplied it is used, else it is calculated from current line."
(let ((ofs 0)
(base-value 0)
- elt a b var val)
+ elt a b val)
(or info
(setq info (sh-get-indent-info)))
(when info
;; Is this really worth having?
(defvar sh-learned-buffer-hook nil
- "*An abnormal hook, called with an alist of learned variables.")
+ "An abnormal hook, called with an alist of learned variables.")
;; Example of how to use sh-learned-buffer-hook
;;
;; (defun what-i-learned (list)
(save-excursion
(backward-char 2)
(sh-quoted-p))
+ (nth 8 (syntax-ppss))
(let ((tabs (if (string-match "\\`-" sh-here-document-word)
(make-string (/ (current-indentation) tab-width) ?\t)
""))