comparison lisp/progmodes/sh-script.el @ 33430:d2648645aa9b

(sh-mode-syntax-table) <defvar>: Make it into a simple syntax-table, shared among all submodes. (sh-heredoc-face): Re-introduce. (sh-font-lock-syntactic-face-function): New function. (sh-mode): Use it. Also use define-derived-mode. Remove old bogus setting of indent-region-function. (sh-set-shell): Don't set the syntax-table any more. (sh-mode-syntax-table) <defun>: Remove.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 12 Nov 2000 16:48:45 +0000
parents 6fe525e8880c
children f4733aab37df
comparison
equal deleted inserted replaced
33429:fc7270277aa9 33430:d2648645aa9b
385 ;;;Due to the internal workings of abbrev tables, the shell name symbol is 385 ;;;Due to the internal workings of abbrev tables, the shell name symbol is
386 ;;;actually defined as the table for the like of \\[edit-abbrevs].") 386 ;;;actually defined as the table for the like of \\[edit-abbrevs].")
387 387
388 388
389 389
390 (defvar sh-mode-syntax-table 390 (easy-mmode-defsyntax sh-mode-syntax-table
391 '((sh eval sh-mode-syntax-table () 391 '((?\# . "<")
392 ?\# "<" 392 (?\^l . ">#")
393 ?\^l ">#" 393 (?\n . ">#")
394 ?\n ">#" 394 (?\" . "\"\"")
395 ?\" "\"\"" 395 (?\' . "\"'")
396 ?\' "\"'" 396 (?\` . "\"`")
397 ?\` "\"`" 397 (?! . "_")
398 ?! "_" 398 (?% . "_")
399 ?% "_" 399 (?: . "_")
400 ?: "_" 400 (?. . "_")
401 ?. "_" 401 (?^ . "_")
402 ?^ "_" 402 (?~ . "_")
403 ?~ "_" 403 (?< . ".")
404 ?< "." 404 (?> . "."))
405 ?> ".") 405 "Syntax-table used in Shell-Script mode.")
406 (csh eval identity sh)
407 (rc eval identity sh))
408 "Syntax-table used in Shell-Script mode. See `sh-feature'.")
409
410 406
411 407
412 (defvar sh-mode-map 408 (defvar sh-mode-map
413 (let ((map (make-sparse-keymap)) 409 (let ((map (make-sparse-keymap))
414 (menu-map (make-sparse-keymap "Insert"))) 410 (menu-map (make-sparse-keymap "Insert")))
754 "STTY" "TIMEFMT" "TMOUT" "TMPPREFIX" "varcmds" "watch" "WATCH" 750 "STTY" "TIMEFMT" "TMOUT" "TMPPREFIX" "varcmds" "watch" "WATCH"
755 "WATCHFMT" "WORDCHARS" "ZDOTDIR")) 751 "WATCHFMT" "WORDCHARS" "ZDOTDIR"))
756 "List of all shell variables available for completing read. 752 "List of all shell variables available for completing read.
757 See `sh-feature'.") 753 See `sh-feature'.")
758 754
755
756 ;;; Font-Lock support
757
758 (defface sh-heredoc-face
759 '((((class color)
760 (background dark))
761 (:foreground "yellow" :bold t))
762 (((class color)
763 (background light))
764 (:foreground "tan" ))
765 (t
766 (:bold t)))
767 "Face to show a here-document"
768 :group 'sh-indentation)
769 (defvar sh-heredoc-face 'sh-heredoc-face)
759 770
760 771
761 (defvar sh-font-lock-keywords 772 (defvar sh-font-lock-keywords
762 '((csh eval sh-append shell 773 '((csh eval sh-append shell
763 '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1 774 '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1
866 4 (sh-font-lock-heredoc 877 4 (sh-font-lock-heredoc
867 (match-beginning 0) (match-string 2) (match-end 1))) 878 (match-beginning 0) (match-string 2) (match-end 1)))
868 ;; Distinguish the special close-paren in `case'. 879 ;; Distinguish the special close-paren in `case'.
869 (")" 0 (sh-font-lock-paren (match-beginning 0))))) 880 (")" 0 (sh-font-lock-paren (match-beginning 0)))))
870 881
882 (defun sh-font-lock-syntactic-face-function (state)
883 (if (nth 3 state)
884 (if (char-valid-p (nth 3 state))
885 font-lock-string-face
886 sh-heredoc-face)
887 font-lock-comment-face))
888
871 (defgroup sh-indentation nil 889 (defgroup sh-indentation nil
872 "Variables controlling indentation in shell scripts. 890 "Variables controlling indentation in shell scripts.
873 891
874 Note: customizing these variables will not affect existing buffers if 892 Note: customizing these variables will not affect existing buffers if
875 `sh-make-vars-local' is no-nil. See the documentation for 893 `sh-make-vars-local' is no-nil. See the documentation for
1090 (defcustom sh-indent-after-case '+ 1108 (defcustom sh-indent-after-case '+
1091 "*How much to indent a statement relative to the case statement. 1109 "*How much to indent a statement relative to the case statement.
1092 This is for the rc shell." 1110 This is for the rc shell."
1093 :type `(choice ,@ sh-number-or-symbol-list) 1111 :type `(choice ,@ sh-number-or-symbol-list)
1094 :group 'sh-indentation) 1112 :group 'sh-indentation)
1095
1096 1113
1097 ;; Internal use - not designed to be changed by the user: 1114 ;; Internal use - not designed to be changed by the user:
1098 1115
1099 (defun sh-mkword-regexpr (word) 1116 (defun sh-mkword-regexpr (word)
1100 "Make a regexp which matches WORD as a word. 1117 "Make a regexp which matches WORD as a word.
1161 1178
1162 ;;;###autoload 1179 ;;;###autoload
1163 (put 'sh-mode 'mode-class 'special) 1180 (put 'sh-mode 'mode-class 'special)
1164 1181
1165 ;;;###autoload 1182 ;;;###autoload
1166 (defun sh-mode () 1183 (define-derived-mode sh-mode nil "Shell-script"
1167 "Major mode for editing shell scripts. 1184 "Major mode for editing shell scripts.
1168 This mode works for many shells, since they all have roughly the same syntax, 1185 This mode works for many shells, since they all have roughly the same syntax,
1169 as far as commands, arguments, variables, pipes, comments etc. are concerned. 1186 as far as commands, arguments, variables, pipes, comments etc. are concerned.
1170 Unless the file's magic number indicates the shell, your usual shell is 1187 Unless the file's magic number indicates the shell, your usual shell is
1171 assumed. Since filenames rarely give a clue, they are not further analyzed. 1188 assumed. Since filenames rarely give a clue, they are not further analyzed.
1214 set `sh-shell-file' accordingly. If your shell's file name doesn't correctly 1231 set `sh-shell-file' accordingly. If your shell's file name doesn't correctly
1215 indicate what shell it is use `sh-alias-alist' to translate. 1232 indicate what shell it is use `sh-alias-alist' to translate.
1216 1233
1217 If your shell gives error messages with line numbers, you can use \\[executable-interpret] 1234 If your shell gives error messages with line numbers, you can use \\[executable-interpret]
1218 with your script for an edit-interpret-debug cycle." 1235 with your script for an edit-interpret-debug cycle."
1219 (interactive)
1220 (kill-all-local-variables)
1221 (use-local-map sh-mode-map)
1222 (make-local-variable 'skeleton-end-hook) 1236 (make-local-variable 'skeleton-end-hook)
1223 (make-local-variable 'paragraph-start) 1237 (make-local-variable 'paragraph-start)
1224 (make-local-variable 'paragraph-separate) 1238 (make-local-variable 'paragraph-separate)
1225 (make-local-variable 'comment-start) 1239 (make-local-variable 'comment-start)
1226 (make-local-variable 'comment-start-skip) 1240 (make-local-variable 'comment-start-skip)
1238 (make-local-variable 'sh-shell-variables) 1252 (make-local-variable 'sh-shell-variables)
1239 (make-local-variable 'sh-shell-variables-initialized) 1253 (make-local-variable 'sh-shell-variables-initialized)
1240 (make-local-variable 'imenu-generic-expression) 1254 (make-local-variable 'imenu-generic-expression)
1241 (make-local-variable 'sh-indent-supported-here) 1255 (make-local-variable 'sh-indent-supported-here)
1242 (make-local-variable 'font-lock-unfontify-region-function) 1256 (make-local-variable 'font-lock-unfontify-region-function)
1243 (setq major-mode 'sh-mode 1257 (setq skeleton-end-hook (lambda ()
1244 mode-name "Shell-script"
1245 ;; not very clever, but enables wrapping skeletons around regions
1246 indent-region-function (lambda (b e)
1247 (save-excursion
1248 (goto-char b)
1249 (skip-syntax-backward "-")
1250 (setq b (point))
1251 (goto-char e)
1252 (skip-syntax-backward "-")
1253 (indent-rigidly b (point) sh-indentation)))
1254 skeleton-end-hook (lambda ()
1255 (or (eolp) (newline) (indent-relative))) 1258 (or (eolp) (newline) (indent-relative)))
1256 paragraph-start (concat page-delimiter "\\|$") 1259 paragraph-start (concat page-delimiter "\\|$")
1257 paragraph-separate paragraph-start 1260 paragraph-separate paragraph-start
1258 comment-start "# " 1261 comment-start "# "
1259 comint-dynamic-complete-functions sh-dynamic-complete-functions 1262 comint-dynamic-complete-functions sh-dynamic-complete-functions
1264 sh-font-lock-keywords-1 sh-font-lock-keywords-2) 1267 sh-font-lock-keywords-1 sh-font-lock-keywords-2)
1265 nil nil 1268 nil nil
1266 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil 1269 ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w")) nil
1267 (font-lock-syntactic-keywords 1270 (font-lock-syntactic-keywords
1268 ;; Copy so we can use destructive update in `sh-font-lock-heredoc'. 1271 ;; Copy so we can use destructive update in `sh-font-lock-heredoc'.
1269 . ,(copy-sequence sh-font-lock-syntactic-keywords))) 1272 . ,(copy-sequence sh-font-lock-syntactic-keywords))
1273 (font-lock-syntactic-face-function
1274 . sh-font-lock-syntactic-face-function))
1270 skeleton-pair-alist '((?` _ ?`)) 1275 skeleton-pair-alist '((?` _ ?`))
1271 skeleton-pair-filter 'sh-quoted-p 1276 skeleton-pair-filter 'sh-quoted-p
1272 skeleton-further-elements '((< '(- (min sh-indentation 1277 skeleton-further-elements '((< '(- (min sh-indentation
1273 (current-column))))) 1278 (current-column)))))
1274 skeleton-filter 'sh-feature 1279 skeleton-filter 'sh-feature
1283 (cond ((looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)") 1288 (cond ((looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")
1284 (match-string 2)) 1289 (match-string 2))
1285 ((and buffer-file-name 1290 ((and buffer-file-name
1286 (string-match "\\.m?spec$" buffer-file-name)) 1291 (string-match "\\.m?spec$" buffer-file-name))
1287 "rpm"))))) 1292 "rpm")))))
1288 (if interpreter 1293 (sh-set-shell (or interpreter sh-shell-file) nil nil)))
1289 (sh-set-shell interpreter nil nil) 1294
1290 (sh-set-shell sh-shell-file nil nil))
1291 (run-hooks 'sh-mode-hook)))
1292 ;;;###autoload 1295 ;;;###autoload
1293 (defalias 'shell-script-mode 'sh-mode) 1296 (defalias 'shell-script-mode 'sh-mode)
1294 1297
1295 1298
1296 (defun sh-font-lock-keywords (&optional keywords) 1299 (defun sh-font-lock-keywords (&optional keywords)
1413 mode-line-process (format "[%s]" sh-shell) 1416 mode-line-process (format "[%s]" sh-shell)
1414 sh-shell-variables nil 1417 sh-shell-variables nil
1415 sh-shell-variables-initialized nil 1418 sh-shell-variables-initialized nil
1416 imenu-generic-expression (sh-feature sh-imenu-generic-expression) 1419 imenu-generic-expression (sh-feature sh-imenu-generic-expression)
1417 imenu-case-fold-search nil) 1420 imenu-case-fold-search nil)
1418 (set-syntax-table (or (sh-feature sh-mode-syntax-table)
1419 (standard-syntax-table)))
1420 (dolist (var (sh-feature sh-variables)) 1421 (dolist (var (sh-feature sh-variables))
1421 (sh-remember-variable var)) 1422 (sh-remember-variable var))
1422 (make-local-variable 'indent-line-function) 1423 (make-local-variable 'indent-line-function)
1423 (if (setq sh-indent-supported-here (sh-feature sh-indent-supported)) 1424 (if (setq sh-indent-supported-here (sh-feature sh-indent-supported))
1424 (progn 1425 (progn
1527 ;;; "") 1528 ;;; "")
1528 ;;; (if (symbolp (car (cdr list))) 1529 ;;; (if (symbolp (car (cdr list)))
1529 ;;; (car (cdr list)))) 1530 ;;; (car (cdr list))))
1530 ;;; (setq list (cdr (cdr list))))) 1531 ;;; (setq list (cdr (cdr list)))))
1531 ;;; (symbol-value sh-shell))) 1532 ;;; (symbol-value sh-shell)))
1532
1533
1534 (defun sh-mode-syntax-table (table &rest list)
1535 "Copy TABLE and set syntax for successive CHARs according to strings S."
1536 (setq table (copy-syntax-table table))
1537 (while list
1538 (modify-syntax-entry (pop list) (pop list) table))
1539 table)
1540 1533
1541 1534
1542 (defun sh-append (ancestor &rest list) 1535 (defun sh-append (ancestor &rest list)
1543 "Return list composed of first argument (a list) physically appended to rest." 1536 "Return list composed of first argument (a list) physically appended to rest."
1544 (nconc list ancestor)) 1537 (nconc list ancestor))
3299 "Insert a select statement. See `sh-feature'." 3292 "Insert a select statement. See `sh-feature'."
3300 (ksh88 "Index variable: " 3293 (ksh88 "Index variable: "
3301 > "select " str " in " _ "; do" \n 3294 > "select " str " in " _ "; do" \n
3302 > ?$ str \n 3295 > ?$ str \n
3303 "done" > ) 3296 "done" > )
3304 (bash eval sh-append ksh88) 3297 (bash eval sh-append ksh88))
3305 )
3306 ;;;(put 'sh-select 'menu-enable '(sh-feature sh-select)) 3298 ;;;(put 'sh-select 'menu-enable '(sh-feature sh-select))
3307 3299
3308 3300
3309 3301
3310 (define-skeleton sh-tmp-file 3302 (define-skeleton sh-tmp-file