(defun sh-font-lock-paren (start)
(unless (nth 8 (syntax-ppss))
(save-excursion
- (goto-char start)
- ;; Skip through all patterns
- (while
- (progn
- (while
- (progn
- (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_"))
- (/= 0 (skip-chars-backward "-$=?[]*@/\\\\"))
- (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)) ?\()
+ (let ((open nil))
+ (goto-char start)
+ ;; Skip through all patterns
+ (while
+ (progn
+ (while
+ (progn
+ (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_"))
+ (/= 0 (skip-chars-backward "-$=?[]*@/\\\\"))
+ (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).
+ (when (eq (char-before (point)) ?\()
+ (backward-char 1)
+ (setq open (point)))
+ (while (progn
+ (forward-comment (- (point-max)))
+ ;; Maybe we've bumped into an escaped newline.
+ (sh-is-quoted-p (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)))
- (and (> (point) (1+ (point-min)))
- (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,
- ;; we're not looking at a case-pattern.
- (not (looking-at "..[ \t\n]+esac[^[:word:]_]"))))
- sh-st-punc))))
+ (when (eq (char-before) ?|)
+ (backward-char 1) t)))
+ (and (> (point) (1+ (point-min)))
+ (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, we're not looking
+ ;; at a case-pattern.
+ (not (looking-at "..[ \t\n]+esac[^[:word:]_]"))))
+ (progn
+ (when open
+ (put-text-property open (1+ open) 'syntax-table sh-st-punc))
+ sh-st-punc))))))
(defun sh-font-lock-backslash-quote ()
(if (eq (save-excursion (nth 3 (syntax-ppss (match-beginning 0)))) ?\')
(cmd "|" cmd) (cmd "|&" cmd)
(cmd "&&" cmd) (cmd "||" cmd)
(cmd ";" cmd) (cmd "&" cmd))
- (pattern (pattern "|" pattern))
+ (rpattern (rpattern "|" rpattern))
+ (pattern (rpattern) ("case-(" rpattern))
(branches (branches ";;" branches)
(branches ";&" branches) (branches ";;&" branches) ;bash.
(pattern "case-)" cmd)))
(tok (smie-default-forward-token)))
(cond
((equal tok ")") "case-)")
+ ((equal tok "(") "case-(")
((and tok (string-match "\\`[a-z]" tok)
(assoc tok smie-grammar)
(not
(let ((tok (smie-default-backward-token)))
(cond
((equal tok ")") "case-)")
+ ((equal tok "(") "case-(")
((and tok (string-match "\\`[a-z]" tok)
(assoc tok smie-grammar)
(not (save-excursion (sh-smie--sh-keyword-p tok))))