diff options
| -rw-r--r-- | lisp/progmodes/sh-script.el | 242 |
1 files changed, 143 insertions, 99 deletions
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 5927a8069fe..b4db1b903c3 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el | |||
| @@ -138,12 +138,6 @@ Use this where the name of the executable doesn't correspond to the type of | |||
| 138 | shell it really is.") | 138 | shell it really is.") |
| 139 | 139 | ||
| 140 | 140 | ||
| 141 | (defvar sh-shells | ||
| 142 | '(("ash") ("bash") ("csh") ("dtksh") ("es") ("itcsh") ("jsh") ("ksh") | ||
| 143 | ("oash") ("pdksh") ("rc") ("sh") ("tcsh") ("wksh") ("wsh") ("zsh")) | ||
| 144 | "*Alist of shells available for completing read in `sh-set-shell'.") | ||
| 145 | |||
| 146 | |||
| 147 | (defvar sh-shell-path (or (getenv "SHELL") "/bin/sh") | 141 | (defvar sh-shell-path (or (getenv "SHELL") "/bin/sh") |
| 148 | "*The executable of the shell being programmed.") | 142 | "*The executable of the shell being programmed.") |
| 149 | 143 | ||
| @@ -347,13 +341,13 @@ That command is also used for setting this variable.") | |||
| 347 | 341 | ||
| 348 | 342 | ||
| 349 | (defvar sh-beginning-of-command | 343 | (defvar sh-beginning-of-command |
| 350 | "\\([;({`|&]\\|^\\)[ \t]*\\([/~:a-zA-Z0-9]\\)" | 344 | "\\([;({`|&]\\|\\`\\|[^\\]\n\\)[ \t]*\\([/~a-zA-Z0-9:]\\)" |
| 351 | "*Regexp to determine the beginning of a shell command. | 345 | "*Regexp to determine the beginning of a shell command. |
| 352 | The actual command starts at the beginning of the second \\(grouping\\).") | 346 | The actual command starts at the beginning of the second \\(grouping\\).") |
| 353 | 347 | ||
| 354 | 348 | ||
| 355 | (defvar sh-end-of-command | 349 | (defvar sh-end-of-command |
| 356 | "\\([/~:a-zA-Z0-9]\\)[ \t]*\\([;#)}`|&]\\|$\\)" | 350 | "\\([/~a-zA-Z0-9:]\\)[ \t]*\\([;#)}`|&]\\|$\\)" |
| 357 | "*Regexp to determine the end of a shell command. | 351 | "*Regexp to determine the end of a shell command. |
| 358 | The actual command ends at the end of the first \\(grouping\\).") | 352 | The actual command ends at the end of the first \\(grouping\\).") |
| 359 | 353 | ||
| @@ -369,28 +363,24 @@ The actual command ends at the end of the first \\(grouping\\).") | |||
| 369 | 363 | ||
| 370 | 364 | ||
| 371 | (defvar sh-builtins | 365 | (defvar sh-builtins |
| 372 | '((bash eval sh-append sh | 366 | '((bash eval sh-append posix |
| 373 | "alias" "bg" "bind" "builtin" "bye" "command" "declare" "dirs" | 367 | "alias" "bg" "bind" "builtin" "declare" "dirs" "enable" "fc" "fg" |
| 374 | "enable" "fc" "fg" "function" "help" "history" "jobs" "kill" "let" | 368 | "help" "history" "jobs" "kill" "let" "local" "popd" "pushd" "source" |
| 375 | "local" "logout" "popd" "pushd" "source" "suspend" "typeset" | 369 | "suspend" "typeset" "unalias") |
| 376 | "unalias") | ||
| 377 | 370 | ||
| 378 | ;; The next entry is only used for defining the others | 371 | ;; The next entry is only used for defining the others |
| 379 | (bourne eval sh-append shell | 372 | (bourne eval sh-append shell |
| 380 | "do" "done" "elif" "esac" "export" "fi" "for" "getopts" "in" | 373 | "eval" "export" "getopts" "newgrp" "pwd" "read" "readonly" |
| 381 | "newgrp" "pwd" "read" "readonly" "return" "times" "trap" "ulimit" | 374 | "times" "ulimit") |
| 382 | "until") | ||
| 383 | 375 | ||
| 384 | (csh eval sh-append shell | 376 | (csh eval sh-append shell |
| 385 | "alias" "breaksw" "chdir" "default:" "end" "endif" "endsw" "foreach" | 377 | "alias" "chdir" "glob" "history" "limit" "nice" "nohup" "rehash" |
| 386 | "glob" "goto" "history" "limit" "logout" "nice" "nohup" "onintr" | 378 | "setenv" "source" "time" "unalias" "unhash") |
| 387 | "rehash" "repeat" "setenv" "source" "switch" "time" "unalias" | 379 | |
| 388 | "unhash") | 380 | (dtksh eval identity wksh) |
| 389 | 381 | ||
| 390 | (es "access" "apids" "break" "catch" "cd" "echo" "eval" "exec" "exit" | 382 | (es "access" "apids" "cd" "echo" "eval" "false" "let" "limit" "local" |
| 391 | "false" "fn" "for" "forever" "fork" "if" "let" "limit" "local" | 383 | "newpgrp" "result" "time" "umask" "var" "vars" "wait" "whatis") |
| 392 | "newpgrp" "result" "return" "throw" "time" "true" "umask" | ||
| 393 | "unwind-protect" "var" "vars" "wait" "whatis" "while") | ||
| 394 | 384 | ||
| 395 | (jsh eval sh-append sh | 385 | (jsh eval sh-append sh |
| 396 | "bg" "fg" "jobs" "kill" "stop" "suspend") | 386 | "bg" "fg" "jobs" "kill" "stop" "suspend") |
| @@ -399,8 +389,8 @@ The actual command ends at the end of the first \\(grouping\\).") | |||
| 399 | "bg" "fg" "jobs" "kill" "notify" "stop" "suspend") | 389 | "bg" "fg" "jobs" "kill" "notify" "stop" "suspend") |
| 400 | 390 | ||
| 401 | (ksh88 eval sh-append bourne | 391 | (ksh88 eval sh-append bourne |
| 402 | "alias" "bg" "false" "fc" "fg" "function" "jobs" "kill" "let" | 392 | "alias" "bg" "false" "fc" "fg" "jobs" "kill" "let" "print" "time" |
| 403 | "print" "select" "time" "typeset" "unalias" "whence") | 393 | "typeset" "unalias" "whence") |
| 404 | 394 | ||
| 405 | (oash eval sh-append sh | 395 | (oash eval sh-append sh |
| 406 | "checkwin" "dateline" "error" "form" "menu" "newwin" "oadeinit" | 396 | "checkwin" "dateline" "error" "form" "menu" "newwin" "oadeinit" |
| @@ -414,55 +404,72 @@ The actual command ends at the end of the first \\(grouping\\).") | |||
| 414 | (posix eval sh-append sh | 404 | (posix eval sh-append sh |
| 415 | "command") | 405 | "command") |
| 416 | 406 | ||
| 417 | (rc "break" "builtin" "case" "cd" "echo" "else" "eval" "exec" "exit" "fn" | 407 | (rc "builtin" "cd" "echo" "eval" "limit" "newpgrp" "shift" "umask" "wait" |
| 418 | "for" "if" "in" "limit" "newpgrp" "return" "shift" "switch" "umask" | 408 | "whatis") |
| 419 | "wait" "whatis" "while") | ||
| 420 | 409 | ||
| 421 | (sh eval sh-append bourne | 410 | (sh eval sh-append bourne |
| 422 | "hash" "test" "type") | 411 | "hash" "test" "type") |
| 423 | 412 | ||
| 424 | ;; The next entry is only used for defining the others | 413 | ;; The next entry is only used for defining the others |
| 425 | (shell "break" "case" "cd" "continue" "echo" "else" "eval" "exec" "exit" | 414 | (shell "cd" "echo" "eval" "set" "shift" "umask" "unset" "wait") |
| 426 | "if" "set" "shift" "then" "umask" "unset" "wait" "while") | 415 | |
| 416 | (wksh eval sh-append ksh88 | ||
| 417 | "Xt[A-Z][A-Za-z]*") | ||
| 427 | 418 | ||
| 428 | (zsh eval sh-append ksh88 | 419 | (zsh eval sh-append ksh88 |
| 429 | "autoload" "bindkey" "builtin" "bye" "chdir" "compctl" "declare" | 420 | "autoload" "bindkey" "builtin" "chdir" "compctl" "declare" "dirs" |
| 430 | "dirs" "disable" "disown" "echotc" "enable" "functions" "getln" | 421 | "disable" "disown" "echotc" "enable" "functions" "getln" "hash" |
| 431 | "hash" "history" "integer" "limit" "local" "log" "logout" "popd" | 422 | "history" "integer" "limit" "local" "log" "popd" "pushd" "r" |
| 432 | "pushd" "r" "readonly" "rehash" "sched" "setopt" "source" "suspend" | 423 | "readonly" "rehash" "sched" "setopt" "source" "suspend" "true" |
| 433 | "true" "ttyctl" "type" "unfunction" "unhash" "unlimit" "unsetopt" | 424 | "ttyctl" "type" "unfunction" "unhash" "unlimit" "unsetopt" "vared" |
| 434 | "vared" "which")) | 425 | "which")) |
| 435 | "*List of all shell builtins for completing read and fontification. | 426 | "*List of all shell builtins for completing read and fontification. |
| 436 | Note that on some systems not all builtins are available or some are | 427 | Note that on some systems not all builtins are available or some are |
| 437 | implemented as aliases. See `sh-feature'.") | 428 | implemented as aliases. See `sh-feature'.") |
| 438 | 429 | ||
| 439 | 430 | ||
| 431 | |||
| 440 | (defvar sh-leading-keywords | 432 | (defvar sh-leading-keywords |
| 441 | '((bash eval sh-append sh | 433 | '((csh "else") |
| 442 | "builtin" "command" "enable") | 434 | |
| 435 | (es "true" "unwind-protect" "whatis") | ||
| 436 | |||
| 437 | (rc "else") | ||
| 438 | |||
| 439 | (sh "do" "elif" "else" "if" "then" "trap" "type" "until" "while")) | ||
| 440 | "*List of keywords that may be immediately followed by a builtin or keyword. | ||
| 441 | Given some confusion between keywords and builtins depending on shell and | ||
| 442 | system, the distinction here has been based on whether they influence the | ||
| 443 | flow of control or syntax. See `sh-feature'.") | ||
| 444 | |||
| 445 | |||
| 446 | (defvar sh-other-keywords | ||
| 447 | '((bash eval sh-append bourne | ||
| 448 | "bye" "logout") | ||
| 443 | 449 | ||
| 444 | ;; The next entry is only used for defining the others | 450 | ;; The next entry is only used for defining the others |
| 445 | (bourne "do" "elif" "else" "eval" "if" "then" "trap" "until" "while") | 451 | (bourne eval sh-append shell |
| 452 | "done" "esac" "fi" "for" "function" "in" "return") | ||
| 446 | 453 | ||
| 447 | (csh "else") | 454 | (csh eval sh-append shell |
| 455 | "breaksw" "default" "end" "endif" "endsw" "foreach" "goto" | ||
| 456 | "if" "logout" "onintr" "repeat" "switch" "then" "while") | ||
| 448 | 457 | ||
| 449 | (es "eval" "time" "true" "umask" | 458 | (es "break" "catch" "exec" "exit" "fn" "for" "forever" "fork" "if" |
| 450 | "unwind-protect" "whatis") | 459 | "return" "throw" "while") |
| 451 | 460 | ||
| 452 | (ksh88 eval sh-append bourne | 461 | (ksh88 eval sh-append bourne |
| 453 | "time" "whence") | 462 | "select") |
| 454 | 463 | ||
| 455 | (posix eval sh-append sh | 464 | (rc "break" "case" "exec" "exit" "fn" "for" "if" "in" "return" "switch" |
| 456 | "command") | 465 | "while") |
| 457 | |||
| 458 | (rc "builtin" "else" "eval" "whatis") | ||
| 459 | 466 | ||
| 460 | (sh eval sh-append bourne | 467 | ;; The next entry is only used for defining the others |
| 461 | "type") | 468 | (shell "break" "case" "continue" "exec" "exit") |
| 462 | 469 | ||
| 463 | (zsh eval sh-append ksh88 | 470 | (zsh eval sh-append bash |
| 464 | "builtin" "disable" "enable" "type" "unhash" "which")) | 471 | "select")) |
| 465 | "*List of keywords that may be immediately followed by a command(-name). | 472 | "*List of keywords not in `sh-leading-keywords'. |
| 466 | See `sh-feature'.") | 473 | See `sh-feature'.") |
| 467 | 474 | ||
| 468 | 475 | ||
| @@ -540,31 +547,30 @@ See `sh-feature'.") | |||
| 540 | '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1 | 547 | '("\\${?[#?]?\\([A-Za-z_][A-Za-z0-9_]*\\|0\\)" 1 |
| 541 | font-lock-variable-name-face)) | 548 | font-lock-variable-name-face)) |
| 542 | 549 | ||
| 543 | (dtksh eval identity wksh) | ||
| 544 | |||
| 545 | (es eval sh-append executable-font-lock-keywords | 550 | (es eval sh-append executable-font-lock-keywords |
| 546 | '("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1 | 551 | '("\\$#?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\)" 1 |
| 547 | font-lock-variable-name-face)) | 552 | font-lock-variable-name-face)) |
| 548 | 553 | ||
| 549 | (rc eval sh-append es | 554 | (rc eval identity es) |
| 550 | '("\\(^\\|[ \t]\\)\\(else\\( if\\)?\\)\\>" 2 | ||
| 551 | font-lock-keyword-face t)) | ||
| 552 | 555 | ||
| 553 | (sh eval sh-append shell | 556 | (sh eval sh-append shell |
| 554 | '("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2 | 557 | '("\\$\\({#?\\)?\\([A-Za-z_][A-Za-z0-9_]*\\|[-#?@!]\\)" 2 |
| 555 | font-lock-variable-name-face) | 558 | font-lock-variable-name-face)) |
| 556 | " in\\([ \t]\\|$\\)") | ||
| 557 | 559 | ||
| 558 | ;; The next entry is only used for defining the others | 560 | ;; The next entry is only used for defining the others |
| 559 | (shell eval sh-append executable-font-lock-keywords | 561 | (shell eval sh-append executable-font-lock-keywords |
| 560 | '("\\\\." 0 font-lock-string-face) | 562 | '("\\\\." 0 font-lock-string-face) |
| 561 | '("\\${?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\|[$*_]\\)" 1 | 563 | '("\\${?\\([A-Za-z_][A-Za-z0-9_]*\\|[0-9]+\\|[$*_]\\)" 1 |
| 562 | font-lock-variable-name-face)) | 564 | font-lock-variable-name-face))) |
| 563 | |||
| 564 | (wksh eval sh-append ksh88 | ||
| 565 | '("\\(^\\|[^-._A-Za-z0-9]\\)\\(Xt[A-Z][A-Za-z]*\\)\\($\\|[^-._A-Za-z0-9]\\)" 2 font-lock-keyword-face))) | ||
| 566 | "*Rules for highlighting shell scripts. See `sh-feature'.") | 565 | "*Rules for highlighting shell scripts. See `sh-feature'.") |
| 567 | 566 | ||
| 567 | (defvar sh-font-lock-keywords-1 | ||
| 568 | '((sh "[ \t]in[ \t]")) | ||
| 569 | "*Additional rules for highlighting shell scripts. See `sh-feature'.") | ||
| 570 | |||
| 571 | (defvar sh-font-lock-keywords-2 () | ||
| 572 | "*Yet more rules for highlighting shell scripts. See `sh-feature'.") | ||
| 573 | |||
| 568 | 574 | ||
| 569 | ;; mode-command and utility functions | 575 | ;; mode-command and utility functions |
| 570 | 576 | ||
| @@ -618,6 +624,7 @@ with your script for an edit-interpret-debug cycle." | |||
| 618 | (use-local-map sh-mode-map) | 624 | (use-local-map sh-mode-map) |
| 619 | (make-local-variable 'indent-line-function) | 625 | (make-local-variable 'indent-line-function) |
| 620 | (make-local-variable 'indent-region-function) | 626 | (make-local-variable 'indent-region-function) |
| 627 | (make-local-variable 'skeleton-end-hook) | ||
| 621 | (make-local-variable 'paragraph-start) | 628 | (make-local-variable 'paragraph-start) |
| 622 | (make-local-variable 'paragraph-separate) | 629 | (make-local-variable 'paragraph-separate) |
| 623 | (make-local-variable 'comment-start) | 630 | (make-local-variable 'comment-start) |
| @@ -628,10 +635,10 @@ with your script for an edit-interpret-debug cycle." | |||
| 628 | (make-local-variable 'sh-shell) | 635 | (make-local-variable 'sh-shell) |
| 629 | (make-local-variable 'skeleton-pair-alist) | 636 | (make-local-variable 'skeleton-pair-alist) |
| 630 | (make-local-variable 'skeleton-pair-filter) | 637 | (make-local-variable 'skeleton-pair-filter) |
| 631 | (make-local-variable 'font-lock-keywords) | ||
| 632 | (make-local-variable 'comint-dynamic-complete-functions) | 638 | (make-local-variable 'comint-dynamic-complete-functions) |
| 633 | (make-local-variable 'comint-prompt-regexp) | 639 | (make-local-variable 'comint-prompt-regexp) |
| 634 | (make-local-variable 'font-lock-keywords-case-fold-search) | 640 | (make-local-variable 'font-lock-keywords) |
| 641 | (make-local-variable 'font-lock-defaults) | ||
| 635 | (make-local-variable 'skeleton-filter) | 642 | (make-local-variable 'skeleton-filter) |
| 636 | (make-local-variable 'skeleton-newline-indent-rigidly) | 643 | (make-local-variable 'skeleton-newline-indent-rigidly) |
| 637 | (make-local-variable 'process-environment) | 644 | (make-local-variable 'process-environment) |
| @@ -640,14 +647,27 @@ with your script for an edit-interpret-debug cycle." | |||
| 640 | indent-line-function 'sh-indent-line | 647 | indent-line-function 'sh-indent-line |
| 641 | ;; not very clever, but enables wrapping skeletons around regions | 648 | ;; not very clever, but enables wrapping skeletons around regions |
| 642 | indent-region-function (lambda (b e) | 649 | indent-region-function (lambda (b e) |
| 643 | (indent-rigidly b e sh-indentation)) | 650 | (save-excursion |
| 651 | (goto-char b) | ||
| 652 | (skip-syntax-backward "-") | ||
| 653 | (setq b (point)) | ||
| 654 | (goto-char e) | ||
| 655 | (skip-syntax-backward "-") | ||
| 656 | (indent-rigidly b (point) sh-indentation))) | ||
| 657 | skeleton-end-hook (lambda () | ||
| 658 | (or (eolp) (newline) (indent-relative))) | ||
| 644 | paragraph-start "^$\\|^" | 659 | paragraph-start "^$\\|^" |
| 645 | paragraph-separate paragraph-start | 660 | paragraph-separate paragraph-start |
| 646 | comment-start "# " | 661 | comment-start "# " |
| 647 | font-lock-keywords-case-fold-search nil | ||
| 648 | comint-dynamic-complete-functions sh-dynamic-complete-functions | 662 | comint-dynamic-complete-functions sh-dynamic-complete-functions |
| 649 | ;; we can't look if previous line ended with `\' | 663 | ;; we can't look if previous line ended with `\' |
| 650 | comint-prompt-regexp "^[ \t]*" | 664 | comint-prompt-regexp "^[ \t]*" |
| 665 | font-lock-defaults | ||
| 666 | '((sh-font-lock-keywords | ||
| 667 | sh-font-lock-keywords-1 | ||
| 668 | sh-font-lock-keywords-2) | ||
| 669 | nil nil | ||
| 670 | ((?/ . "w") (?~ . "w") (?. . "w") (?- . "w") (?_ . "w"))) | ||
| 651 | skeleton-pair-alist '((?` _ ?`)) | 671 | skeleton-pair-alist '((?` _ ?`)) |
| 652 | skeleton-pair-filter 'sh-quoted-p | 672 | skeleton-pair-filter 'sh-quoted-p |
| 653 | skeleton-further-elements '((< '(- (min sh-indentation | 673 | skeleton-further-elements '((< '(- (min sh-indentation |
| @@ -659,19 +679,61 @@ with your script for an edit-interpret-debug cycle." | |||
| 659 | (goto-char (point-min)) | 679 | (goto-char (point-min)) |
| 660 | (sh-set-shell | 680 | (sh-set-shell |
| 661 | (if (looking-at "#![\t ]*\\([^\t\n ]+\\)") | 681 | (if (looking-at "#![\t ]*\\([^\t\n ]+\\)") |
| 662 | (buffer-substring (match-beginning 1) (match-end 1)) | 682 | (match-string 1) |
| 663 | sh-shell-path)) | 683 | sh-shell-path)) |
| 664 | (run-hooks 'sh-mode-hook)) | 684 | (run-hooks 'sh-mode-hook)) |
| 665 | ;;;###autoload | 685 | ;;;###autoload |
| 666 | (defalias 'shell-script-mode 'sh-mode) | 686 | (defalias 'shell-script-mode 'sh-mode) |
| 667 | 687 | ||
| 668 | 688 | ||
| 689 | (defun sh-font-lock-keywords (&optional keywords) | ||
| 690 | "Function to get simple fontification based on `sh-font-lock-keywords'. | ||
| 691 | This adds rules for comments and assignments." | ||
| 692 | (sh-feature sh-font-lock-keywords | ||
| 693 | (lambda (list) | ||
| 694 | `((,(concat (sh-feature sh-comment-prefix) "\\(#.*\\)") | ||
| 695 | 2 font-lock-comment-face t) | ||
| 696 | (,(sh-feature sh-assignment-regexp) | ||
| 697 | 1 font-lock-variable-name-face) | ||
| 698 | ,@keywords | ||
| 699 | ,@list)))) | ||
| 700 | |||
| 701 | (defun sh-font-lock-keywords-1 (&optional builtins) | ||
| 702 | "Function to get better fontification including keywords." | ||
| 703 | (let ((keywords (concat "\\([;(){}`|&]\\|^\\)[ \t]*\\(\\(\\(" | ||
| 704 | (mapconcat 'identity | ||
| 705 | (sh-feature sh-leading-keywords) | ||
| 706 | "\\|") | ||
| 707 | "\\)[ \t]+\\)?\\(" | ||
| 708 | (mapconcat 'identity | ||
| 709 | (append (sh-feature sh-leading-keywords) | ||
| 710 | (sh-feature sh-other-keywords)) | ||
| 711 | "\\|") | ||
| 712 | "\\)"))) | ||
| 713 | (sh-font-lock-keywords | ||
| 714 | `(,@(if builtins | ||
| 715 | `((,(concat keywords "[ \t]+\\)?\\(" | ||
| 716 | (mapconcat 'identity (sh-feature sh-builtins) "\\|") | ||
| 717 | "\\)\\>") | ||
| 718 | (2 font-lock-keyword-face nil t) | ||
| 719 | (6 font-lock-function-name-face)) | ||
| 720 | ,@(sh-feature sh-font-lock-keywords-2))) | ||
| 721 | (,(concat keywords "\\)\\>") | ||
| 722 | 2 font-lock-keyword-face) | ||
| 723 | ,@(sh-feature sh-font-lock-keywords-1))))) | ||
| 724 | |||
| 725 | (defun sh-font-lock-keywords-2 () | ||
| 726 | "Function to get better fontification including keywords and builtins." | ||
| 727 | (sh-font-lock-keywords-1 t)) | ||
| 728 | |||
| 669 | 729 | ||
| 670 | (defun sh-set-shell (shell) | 730 | (defun sh-set-shell (shell) |
| 671 | "Set this buffer's shell to SHELL (a string). | 731 | "Set this buffer's shell to SHELL (a string). |
| 672 | Makes this script executable via `executable-set-magic'. | 732 | Makes this script executable via `executable-set-magic'. |
| 673 | Calls the value of `sh-set-shell-hook' if set." | 733 | Calls the value of `sh-set-shell-hook' if set." |
| 674 | (interactive (list (completing-read "Name or path of shell: " sh-shells))) | 734 | (interactive (list (completing-read "Name or path of shell: " |
| 735 | interpreter-mode-alist | ||
| 736 | (lambda (x) (eq (cdr x) 'sh-mode))))) | ||
| 675 | (if (eq this-command 'sh-set-shell) | 737 | (if (eq this-command 'sh-set-shell) |
| 676 | ;; prevent querying | 738 | ;; prevent querying |
| 677 | (setq this-command 'executable-set-magic)) | 739 | (setq this-command 'executable-set-magic)) |
| @@ -681,32 +743,13 @@ Calls the value of `sh-set-shell-hook' if set." | |||
| 681 | sh-shell-path (executable-set-magic shell (sh-feature sh-shell-arg)) | 743 | sh-shell-path (executable-set-magic shell (sh-feature sh-shell-arg)) |
| 682 | local-abbrev-table (sh-feature sh-abbrevs) | 744 | local-abbrev-table (sh-feature sh-abbrevs) |
| 683 | require-final-newline (sh-feature sh-require-final-newline) | 745 | require-final-newline (sh-feature sh-require-final-newline) |
| 684 | font-lock-keywords | 746 | font-lock-keywords nil ; force resetting |
| 685 | (sh-feature | ||
| 686 | sh-font-lock-keywords | ||
| 687 | (lambda (list) | ||
| 688 | `((,(concat (sh-feature sh-comment-prefix) "\\(#.*\\)") | ||
| 689 | 2 font-lock-comment-face t) | ||
| 690 | (,(sh-feature sh-assignment-regexp) | ||
| 691 | 1 font-lock-variable-name-face) | ||
| 692 | ,@(if font-lock-maximum-decoration | ||
| 693 | `((,(concat "\\(^\\|[|&;()`!]\\)[ \t]*\\(\\(\\(" | ||
| 694 | (mapconcat 'identity | ||
| 695 | (sh-feature sh-leading-keywords) | ||
| 696 | "\\|") | ||
| 697 | "\\)[ \t]+\\)?\\(" | ||
| 698 | (mapconcat 'identity | ||
| 699 | (sh-feature sh-builtins) | ||
| 700 | "\\|") | ||
| 701 | "\\)\\)\\($\\|[ \t|&;()]\\)") | ||
| 702 | 2 font-lock-keyword-face 'keep) | ||
| 703 | ,@list) | ||
| 704 | list)))) | ||
| 705 | comment-start-skip (concat (sh-feature sh-comment-prefix) "#+[\t ]*") | 747 | comment-start-skip (concat (sh-feature sh-comment-prefix) "#+[\t ]*") |
| 706 | mode-line-process (format "[%s]" sh-shell) | 748 | mode-line-process (format "[%s]" sh-shell) |
| 707 | process-environment (default-value 'process-environment) | 749 | process-environment (default-value 'process-environment) |
| 708 | shell (sh-feature sh-variables)) | 750 | shell (sh-feature sh-variables)) |
| 709 | (set-syntax-table (sh-feature sh-mode-syntax-table)) | 751 | (set-syntax-table (sh-feature sh-mode-syntax-table)) |
| 752 | (setq font-lock-syntax-table) | ||
| 710 | (save-excursion | 753 | (save-excursion |
| 711 | (while (search-forward "=" nil t) | 754 | (while (search-forward "=" nil t) |
| 712 | (sh-assignment 0))) | 755 | (sh-assignment 0))) |
| @@ -941,6 +984,7 @@ region, clear header." | |||
| 941 | > _ \n | 984 | > _ \n |
| 942 | resume: | 985 | resume: |
| 943 | < < "esac")) | 986 | < < "esac")) |
| 987 | (put 'sh-case 'menu-enable '(sh-feature sh-case)) | ||
| 944 | 988 | ||
| 945 | 989 | ||
| 946 | 990 | ||
| @@ -1159,15 +1203,15 @@ region, clear header." | |||
| 1159 | (define-skeleton sh-while | 1203 | (define-skeleton sh-while |
| 1160 | "Insert a while loop. See `sh-feature'." | 1204 | "Insert a while loop. See `sh-feature'." |
| 1161 | (csh eval sh-modify sh | 1205 | (csh eval sh-modify sh |
| 1162 | 1 "while( " | 1206 | 2 "while( " |
| 1163 | 3 " )" | 1207 | 4 " )" |
| 1164 | 9 "end") | 1208 | 10 "end") |
| 1165 | (es eval sh-modify rc | 1209 | (es eval sh-modify rc |
| 1166 | 1 "while { " | 1210 | 2 "while { " |
| 1167 | 3 " } {") | 1211 | 4 " } {") |
| 1168 | (rc eval sh-modify csh | 1212 | (rc eval sh-modify csh |
| 1169 | 3 " ) {" | 1213 | 4 " ) {" |
| 1170 | 9 ?}) | 1214 | 10 ?}) |
| 1171 | (sh "condition: " | 1215 | (sh "condition: " |
| 1172 | '(setq input (sh-feature sh-test)) | 1216 | '(setq input (sh-feature sh-test)) |
| 1173 | "while " str "; do" \n | 1217 | "while " str "; do" \n |
| @@ -1252,7 +1296,7 @@ option followed by a colon `:' if the option accepts an argument." | |||
| 1252 | (prog1 (point) | 1296 | (prog1 (point) |
| 1253 | (beginning-of-line 1)) | 1297 | (beginning-of-line 1)) |
| 1254 | t) | 1298 | t) |
| 1255 | (buffer-substring (match-beginning 1) (match-end 1))))))) | 1299 | (match-string 1)))))) |
| 1256 | 1300 | ||
| 1257 | 1301 | ||
| 1258 | 1302 | ||