diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/ChangeLog emacs-snapshot-24.1+0bzr108200~precise1/ChangeLog --- emacs-snapshot-24.1+0bzr108190~precise1/ChangeLog 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/ChangeLog 2012-05-12 00:34:45.000000000 +0000 @@ -1,3 +1,9 @@ +2012-05-11 Glenn Morris + + * Makefile.in (install-arch-indep): There are no more Makefile.c files. + Use INSTALL_DATA for the DOC file. + Remove dead code for ./lisp that never executes. + 2012-05-10 Glenn Morris * configure.in (LEIM_INSTALLDIR): New output variable. diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/debian/bzr-builder.manifest emacs-snapshot-24.1+0bzr108200~precise1/debian/bzr-builder.manifest --- emacs-snapshot-24.1+0bzr108190~precise1/debian/bzr-builder.manifest 2012-05-10 16:43:11.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/debian/bzr-builder.manifest 2012-05-12 00:34:56.000000000 +0000 @@ -1,3 +1,3 @@ -# bzr-builder format 0.3 deb-version 2:{debupstream}+0bzr108190 -lp:emacs revid:lekktu@gmail.com-20120510143443-msjlhoy2181m22rf -nest packaging lp:~hexmode/+junk/emacs-packaging debian revid:mah@everybody.org-20120510155943-3es9l23gb9npu397 +# bzr-builder format 0.3 deb-version 2:{debupstream}+0bzr108200 +lp:emacs revid:monnier@iro.umontreal.ca-20120511200519-jwxbfhlfbnth1j5j +nest packaging lp:~hexmode/+junk/emacs-packaging debian revid:mah@everybody.org-20120511003326-eykcvohlmodyuy3n diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/debian/changelog emacs-snapshot-24.1+0bzr108200~precise1/debian/changelog --- emacs-snapshot-24.1+0bzr108190~precise1/debian/changelog 2012-05-10 16:43:11.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/debian/changelog 2012-05-12 00:34:56.000000000 +0000 @@ -1,8 +1,8 @@ -emacs-snapshot (2:24.1+0bzr108190~precise1) precise; urgency=low +emacs-snapshot (2:24.1+0bzr108200~precise1) precise; urgency=low * Auto build. - -- Mark A. Hershberger Thu, 10 May 2012 16:43:11 +0000 + -- Mark A. Hershberger Sat, 12 May 2012 00:34:56 +0000 emacs-snapshot (3:24.1-0mah2) unstable; urgency=low diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/debian/rules emacs-snapshot-24.1+0bzr108200~precise1/debian/rules --- emacs-snapshot-24.1+0bzr108190~precise1/debian/rules 2012-05-10 16:43:11.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/debian/rules 2012-05-12 00:34:56.000000000 +0000 @@ -123,7 +123,7 @@ # We need extra pure space for Debian menu entries. CFLAGS := -DDEBIAN -DSITELOAD_PURESIZE_EXTRA=5000 -g -INFO_EXT := .info +export INFO_EXT=.info ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) CFLAGS += -O0 diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/etc/NEWS emacs-snapshot-24.1+0bzr108200~precise1/etc/NEWS --- emacs-snapshot-24.1+0bzr108190~precise1/etc/NEWS 2012-05-10 16:48:24.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/etc/NEWS 2012-05-12 00:37:14.000000000 +0000 @@ -90,6 +90,11 @@ * Changes in Specialized Modes and Packages in Emacs 24.2 +** `sh-script' +*** Pairing of parens/quotes uses electric-pair-mode instead of skeleton-pair. +*** `sh-electric-here-document-mode' now controls auto-insertion of here-docs. +*** `sh-use-smie' lets you choose a new indentation and navigation code. + ** reStructuredText mode *** Major merge with upstream development. diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/lisp/ChangeLog emacs-snapshot-24.1+0bzr108200~precise1/lisp/ChangeLog --- emacs-snapshot-24.1+0bzr108190~precise1/lisp/ChangeLog 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/lisp/ChangeLog 2012-05-12 00:34:45.000000000 +0000 @@ -1,3 +1,52 @@ +2012-05-11 Stefan Monnier + + * progmodes/prolog.el: Use SMIE. Cleanup regexp setup. + (prolog-upper-case-string, prolog-lower-case-string) + (prolog-atom-char-regexp, prolog-atom-regexp): Initialize in defconst. + (prolog-use-smie, prolog-smie-grammar): New vars. + (prolog-smie-forward-token, prolog-smie-backward-token) + (prolog-smie-rules): New funs. + (prolog-comment-indent): Remove. + (prolog-mode-variables): Use default comment indentation instead. + Setup SMIE. + (prolog-build-case-strings, prolog-set-atom-regexps): Remove. + (prolog-mode): Don't call them any more. + (prolog-electric-colon, prolog-electric-dash) + (prolog-edit-menu-insert-move): Use indent-according-to-mode. + + * dabbrev.el (dabbrev-expand): Make "no expansion found" a user-error. + + * minibuffer.el (completion--twq-all): Again, allow case differences. + + * term.el: Move keymap initialization code to be more idiomatic. + (term-signals-menu, term-mode-map, term-raw-map, term-raw-escape-map) + (term-terminal-menu): Move initialization into declaration. + (term-escape-char): Let the user set it in her .emacs. + + * progmodes/sh-script.el: Use post-self-insert-hook&electric-pair-mode. + Provide SMIE-based indentation (not enabled by default yet). + (sh-mode-map): Don't bind electric keys. + Use electric-pair-mode instead of skeleton-pair. + (sh-assignment-regexp): Fit within 80 columns. + (sh-indent-supported): Specify actual shell name instead of boolean. + (sh--maybe-here-document): New fun, from sh-maybe-here-document. + (sh-maybe-here-document): Use it. Make obsolete. + (sh-electric-here-document-mode) New minor mode. + (sh-mode): Use it. Don't set sh-indent-supported-here here. + (sh-smie-sh-grammar, sh-smie--sh-operators, sh-smie--sh-operators-re) + (sh-smie--sh-operators-back-re, sh-indent-after-continuation) + (sh-smie-rc-grammar, sh-use-smie): New vars. + (sh-smie--keyword-p, sh-smie--newline-semi-p, sh-smie--sh-keyword-p) + (sh-smie-sh-forward-token, sh-smie--looking-back-at-continuation-p) + (sh-smie-sh-backward-token, sh-smie--continuation-start-indent) + (sh-smie-sh-rules, sh-smie-rc-rules, sh-smie--sh-keyword-in-p) + (sh-smie--rc-after-special-arg-p, sh-smie-rc-backward-token) + (sh-smie-sh-rules, sh-smie--rc-newline-semi-p): New functions. + (sh-set-shell): Use smie-setup if requested. + + * term.el (term-set-escape-char): Properly set term-escape-char. + See http://stackoverflow.com/questions/10524656. + 2012-05-10 Chong Yidong * ffap.el (ffap-url-unwrap-local): Make it work right (Bug#9131). diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/lisp/dabbrev.el emacs-snapshot-24.1+0bzr108200~precise1/lisp/dabbrev.el --- emacs-snapshot-24.1+0bzr108190~precise1/lisp/dabbrev.el 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/lisp/dabbrev.el 2012-05-12 00:34:45.000000000 +0000 @@ -527,8 +527,8 @@ (search-backward old) (insert abbrev) (delete-region (point) (+ (point) (length old))))) - (error "No%s dynamic expansion for `%s' found" - (if old " further" "") abbrev)) + (user-error "No%s dynamic expansion for `%s' found" + (if old " further" "") abbrev)) (t (if (not (or (eq dabbrev--last-buffer dabbrev--last-buffer-found) (minibuffer-window-active-p (selected-window)))) diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/lisp/minibuffer.el emacs-snapshot-24.1+0bzr108200~precise1/lisp/minibuffer.el --- emacs-snapshot-24.1+0bzr108190~precise1/lisp/minibuffer.el 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/lisp/minibuffer.el 2012-05-12 00:34:45.000000000 +0000 @@ -519,9 +519,10 @@ (`(,qfullpos . ,qfun) (funcall requote (+ boundary (length prefix)) string)) (qfullprefix (substring string 0 qfullpos)) - (_ (assert (let ((uboundarystr (substring ustring 0 boundary))) - (equal (funcall unquote qfullprefix) - (concat uboundarystr prefix))))) + (_ (assert (eq t (compare-strings + (funcall unquote qfullprefix) nil nil + (concat (substring ustring 0 boundary) prefix) + nil nil 'ignore-case)))) (qboundary (car (funcall requote boundary string))) (_ (assert (<= qboundary qfullpos))) ;; FIXME: this split/quote/concat business messes up the carefully diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/lisp/progmodes/prolog.el emacs-snapshot-24.1+0bzr108200~precise1/lisp/progmodes/prolog.el --- emacs-snapshot-24.1+0bzr108190~precise1/lisp/progmodes/prolog.el 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/lisp/progmodes/prolog.el 2012-05-12 00:34:45.000000000 +0000 @@ -833,18 +833,116 @@ ) table)) (defvar prolog-mode-abbrev-table nil) -(defvar prolog-upper-case-string "" - "A string containing all upper case characters. -Set by prolog-build-case-strings.") -(defvar prolog-lower-case-string "" - "A string containing all lower case characters. -Set by prolog-build-case-strings.") - -(defvar prolog-atom-char-regexp "" - "Set by prolog-set-atom-regexps.") -;; "Regexp specifying characters which constitute atoms without quoting.") -(defvar prolog-atom-regexp "" - "Set by prolog-set-atom-regexps.") + +(if (eval-when-compile + (and (string-match "[[:upper:]]" "A") + (with-temp-buffer + (insert "A") (skip-chars-backward "[:upper:]") (bolp)))) + (progn + (defconst prolog-upper-case-string "[:upper:]" + "A string containing a char-range matching all upper case characters.") + (defconst prolog-lower-case-string "[:lower:]" + "A string containing a char-range matching all lower case characters.")) + + ;; GNU Emacs compatibility: GNU Emacs does not differentiate between + ;; ints and chars, or at least these two are interchangeable. + (defalias 'prolog-int-to-char + (if (fboundp 'int-to-char) #'int-to-char #'identity)) + + (defalias 'prolog-char-to-int + (if (fboundp 'char-to-int) #'char-to-int #'identity)) + + (defun prolog-ints-intervals (ints) + "Return a list of intervals (from . to) covering INTS." + (when ints + (setq ints (sort ints '<)) + (let ((prev (car ints)) + (interval-start (car ints)) + intervals) + (while ints + (let ((next (car ints))) + (when (> next (1+ prev)) ; start of new interval + (setq intervals (cons (cons interval-start prev) intervals)) + (setq interval-start next)) + (setq prev next) + (setq ints (cdr ints)))) + (setq intervals (cons (cons interval-start prev) intervals)) + (reverse intervals)))) + + (defun prolog-dash-letters (string) + "Return a condensed regexp covering all letters in STRING." + (let ((intervals (prolog-ints-intervals (mapcar #'prolog-char-to-int + (string-to-list string)))) + codes) + (while intervals + (let* ((i (car intervals)) + (from (car i)) + (to (cdr i)) + (c (cond ((= from to) `(,from)) + ((= (1+ from) to) `(,from ,to)) + (t `(,from ?- ,to))))) + (setq codes (cons c codes))) + (setq intervals (cdr intervals))) + (apply 'concat (reverse codes)))) + + (let ((up_string "") + (low_string "")) + ;; Use `map-char-table' if it is defined. Otherwise enumerate all + ;; numbers between 0 and 255. `map-char-table' is probably safer. + ;; + ;; `map-char-table' causes problems under Emacs 23.0.0.1, the + ;; while loop seems to do its job well (Ryszard Szopa) + ;; + ;;(if (and (not (featurep 'xemacs)) + ;; (fboundp 'map-char-table)) + ;; (map-char-table + ;; (lambda (key value) + ;; (cond + ;; ((and + ;; (eq (prolog-int-to-char key) (downcase key)) + ;; (eq (prolog-int-to-char key) (upcase key))) + ;; ;; Do nothing if upper and lower case are the same + ;; ) + ;; ((eq (prolog-int-to-char key) (downcase key)) + ;; ;; The char is lower case + ;; (setq low_string (format "%s%c" low_string key))) + ;; ((eq (prolog-int-to-char key) (upcase key)) + ;; ;; The char is upper case + ;; (setq up_string (format "%s%c" up_string key))) + ;; )) + ;; (current-case-table)) + ;; `map-char-table' was undefined. + (let ((key 0)) + (while (< key 256) + (cond + ((and + (eq (prolog-int-to-char key) (downcase key)) + (eq (prolog-int-to-char key) (upcase key))) + ;; Do nothing if upper and lower case are the same + ) + ((eq (prolog-int-to-char key) (downcase key)) + ;; The char is lower case + (setq low_string (format "%s%c" low_string key))) + ((eq (prolog-int-to-char key) (upcase key)) + ;; The char is upper case + (setq up_string (format "%s%c" up_string key))) + ) + (setq key (1+ key)))) + ;; ) + ;; The strings are single-byte strings. + (defconst prolog-upper-case-string (prolog-dash-letters up_string) + "A string containing a char-range matching all upper case characters.") + (defconst prolog-lower-case-string (prolog-dash-letters low_string) + "A string containing a char-range matching all lower case characters.") + )) + +(defconst prolog-atom-char-regexp + (if (string-match "[[:alnum:]]" "0") + "[[:alnum:]_$]" + (format "[%s%s0-9_$]" prolog-lower-case-string prolog-upper-case-string)) + "Regexp specifying characters which constitute atoms without quoting.") +(defconst prolog-atom-regexp + (format "[%s$]%s*" prolog-lower-case-string prolog-atom-char-regexp)) (defconst prolog-left-paren "[[({]" ;FIXME: Why not \\s(? "The characters used as left parentheses for the indentation code.") @@ -887,6 +985,96 @@ '(("dcg" . "-->") ("rule" . ":-") ("simplification" . "<=>") ("propagation" . "==>"))))) +;; SMIE support + +(require 'smie) + +(defvar prolog-use-smie t) + +(defun prolog-smie-forward-token () + ;; FIXME: Add support for 0', if needed after adding it to + ;; syntax-propertize-functions. + (forward-comment (point-max)) + (buffer-substring-no-properties + (point) + (progn (cond + ((looking-at "[!;]") (forward-char 1)) + ((not (zerop (skip-chars-forward "#&*+-./:<=>?@\\^`~")))) + ((not (zerop (skip-syntax-forward "w_'")))) + ;; In case of non-ASCII punctuation. + ((not (zerop (skip-syntax-forward "."))))) + (point)))) + +(defun prolog-smie-backward-token () + ;; FIXME: Add support for 0', if needed after adding it to + ;; syntax-propertize-functions. + (forward-comment (- (point-max))) + (buffer-substring-no-properties + (point) + (progn (cond + ((memq (char-before) '(?! ?\;)) (forward-char -1)) + ((not (zerop (skip-chars-backward "#&*+-./:<=>?@\\^`~")))) + ((not (zerop (skip-syntax-backward "w_'")))) + ;; In case of non-ASCII punctuation. + ((not (zerop (skip-syntax-backward "."))))) + (point)))) + +(defconst prolog-smie-grammar + ;; Rather than construct the operator levels table from the BNF, + ;; we directly provide the operator precedences from GNU Prolog's + ;; manual (7.14.10 op/3). The only problem is that GNU Prolog's + ;; manual uses precedence levels in the opposite sense (higher + ;; numbers bind less tightly) than SMIE, so we use negative numbers. + '(("." -10000 -10000) + (":-" -1200 -1200) + ("-->" -1200 -1200) + (";" -1100 -1100) + ("->" -1050 -1050) + ("," -1000 -1000) + ("\\+" -900 -900) + ("=" -700 -700) + ("\\=" -700 -700) + ("=.." -700 -700) + ("==" -700 -700) + ("\\==" -700 -700) + ("@<" -700 -700) + ("@=<" -700 -700) + ("@>" -700 -700) + ("@>=" -700 -700) + ("is" -700 -700) + ("=:=" -700 -700) + ("=\\=" -700 -700) + ("<" -700 -700) + ("=<" -700 -700) + (">" -700 -700) + (">=" -700 -700) + (":" -600 -600) + ("+" -500 -500) + ("-" -500 -500) + ("/\\" -500 -500) + ("\\/" -500 -500) + ("*" -400 -400) + ("/" -400 -400) + ("//" -400 -400) + ("rem" -400 -400) + ("mod" -400 -400) + ("<<" -400 -400) + (">>" -400 -400) + ("**" -200 -200) + ("^" -200 -200) + ;; Prefix + ;; ("+" 200 200) + ;; ("-" 200 200) + ;; ("\\" 200 200) + (:smie-closer-alist (t . ".")) + ) + "Precedence levels of infix operators.") + +(defun prolog-smie-rules (kind token) + (pcase (cons kind token) + (`(:elem . basic) prolog-indent-width) + (`(:after . ".") '(column . 0)) ;; To work around smie-closer-alist. + (`(:after . ,(or `":-" `"->" `"-->")) prolog-indent-width))) ;;------------------------------------------------------------------- @@ -959,7 +1147,6 @@ (set (make-local-variable 'paragraph-separate) paragraph-start) (set (make-local-variable 'paragraph-ignore-fill-prefix) t) (set (make-local-variable 'normal-auto-fill-function) 'prolog-do-auto-fill) - (set (make-local-variable 'indent-line-function) 'prolog-indent-line) (set (make-local-variable 'comment-start) "%") (set (make-local-variable 'comment-end) "") (set (make-local-variable 'comment-add) 1) @@ -968,7 +1155,6 @@ ;; inside quoted atoms or strings (format "^\\(\\(%s\\|%s\\|[^\n\'\"%%]\\)*\\)\\(/\\*+ *\\|%%+ *\\)" prolog-quoted-atom-regexp prolog-string-regexp)) - (set (make-local-variable 'comment-indent-function) 'prolog-comment-indent) (set (make-local-variable 'parens-require-spaces) nil) ;; Initialize Prolog system specific variables (dolist (var '(prolog-keywords prolog-types prolog-mode-specificators @@ -984,6 +1170,13 @@ '(prolog-font-lock-keywords nil nil ((?_ . "w")))) (set (make-local-variable 'syntax-propertize-function) prolog-syntax-propertize-function) + + (if prolog-use-smie + ;; Setup SMIE. + (smie-setup prolog-smie-grammar #'prolog-smie-rules + :forward-token #'prolog-smie-forward-token + :backward-token #'prolog-smie-backward-token) + (set (make-local-variable 'indent-line-function) 'prolog-indent-line)) ) (defun prolog-mode-keybindings-common (map) @@ -1096,11 +1289,9 @@ ((eq prolog-system 'gnu) "[GNU]") (t "")))) (prolog-mode-variables) - (prolog-build-case-strings) - (prolog-set-atom-regexps) (dolist (ar prolog-align-rules) (add-to-list 'align-rules-list ar)) - ;; imenu entry moved to the appropriate hook for consistency + ;; `imenu' entry moved to the appropriate hook for consistency. ;; Load SICStus debugger if suitable (if (and (eq prolog-system 'sicstus) @@ -1614,7 +1805,8 @@ limit t) (setq filepath (match-string 2))) - ;; ###### Does this work with SICStus under Windows (i.e. backslashes and stuff?) + ;; ###### Does this work with SICStus under Windows + ;; (i.e. backslashes and stuff?) (if (string-match "\\(.*/\\)\\([^/]*\\)$" filepath) (progn (setq dir (match-string 1 filepath)) @@ -1838,7 +2030,8 @@ (defface prolog-builtin-face '((((class color) (background light)) (:foreground "Purple")) (((class color) (background dark)) (:foreground "Cyan")) - (((class grayscale) (background light)) (:foreground "LightGray" :bold t)) + (((class grayscale) (background light)) + :foreground "LightGray" :bold t) (((class grayscale) (background dark)) (:foreground "DimGray" :bold t)) (t (:bold t))) "Face name to use for compiler warnings." @@ -2093,20 +2286,6 @@ (prolog-insert-spaces-after-paren)) )) -(defun prolog-comment-indent () - "Compute prolog comment indentation." - ;; FIXME: Only difference with default behavior is that %%% is not - ;; flushed to column 0 but just left where the user put it. - (cond ((looking-at "%%%") (prolog-indentation-level-of-line)) - ((looking-at "%%") (prolog-indent-level)) - (t - (save-excursion - (skip-chars-backward " \t") - ;; Insert one space at least, except at left margin. - (max (+ (current-column) (if (bolp) 0 1)) - comment-column))) - )) - (defun prolog-indent-level () "Compute prolog indentation level." (save-excursion @@ -3200,7 +3379,8 @@ (save-excursion (let ((state (prolog-clause-info)) (object (prolog-in-object))) - (if (or (equal (nth 0 state) "") (equal (prolog-in-string-or-comment) 'cmt)) + (if (or (equal (nth 0 state) "") + (equal (prolog-in-string-or-comment) 'cmt)) nil (if (and (eq prolog-system 'sicstus) object) @@ -3229,6 +3409,7 @@ (defun prolog-pred-start () "Return the starting point of the first clause of the current predicate." + ;; FIXME: Use SMIE. (save-excursion (goto-char (prolog-clause-start)) ;; Find first clause, unless it was a directive @@ -3261,8 +3442,9 @@ (defun prolog-pred-end () "Return the position at the end of the last clause of the current predicate." + ;; FIXME: Use SMIE. (save-excursion - (goto-char (prolog-clause-end)) ; if we are before the first predicate + (goto-char (prolog-clause-end)) ; If we are before the first predicate. (goto-char (prolog-clause-start)) (let* ((pinfo (prolog-clause-info)) (predname (nth 0 pinfo)) @@ -3517,6 +3699,7 @@ (defun prolog-beginning-of-predicate () "Go to the nearest beginning of predicate before current point. Return the final point or nil if no such a beginning was found." + ;; FIXME: Hook into beginning-of-defun. (interactive) (let ((op (point)) (pos (prolog-pred-start))) @@ -3536,6 +3719,7 @@ (defun prolog-end-of-predicate () "Go to the end of the current predicate." + ;; FIXME: Hook into end-of-defun. (interactive) (let ((op (point))) (goto-char (prolog-pred-end)) @@ -3657,7 +3841,7 @@ "Delete preceding character or whitespace. If `prolog-hungry-delete-key-flag' is non-nil, then all preceding whitespace is consumed. If however an ARG is supplied, or `prolog-hungry-delete-key-flag' is -nil, or point is inside a literal then the function in the variable +nil, or point is inside a literal then the function `backward-delete-char' is called." (interactive "P") (if (or (not prolog-hungry-delete-key-flag) @@ -3677,6 +3861,7 @@ (defun prolog-electric-if-then-else (arg) "If `prolog-electric-if-then-else-flag' is non-nil, indent if-then-else constructs. Bound to the >, ; and ( keys." + ;; FIXME: Use post-self-insert-hook or electric-indent-mode. (interactive "P") (self-insert-command (prefix-numeric-value arg)) (if prolog-electric-if-then-else-flag (prolog-insert-spaces-after-paren))) @@ -3686,6 +3871,7 @@ That is, insert space (if appropriate), `:-' and newline if colon is pressed at the end of a line that starts in the first column (i.e., clause heads)." + ;; FIXME: Use post-self-insert-hook. (interactive "P") (if (and prolog-electric-colon-flag (null arg) @@ -3696,7 +3882,7 @@ (unless (save-excursion (backward-char 1) (looking-at "\\s ")) (insert " ")) (insert ":-\n") - (prolog-indent-line)) + (indent-according-to-mode)) (self-insert-command (prefix-numeric-value arg)))) (defun prolog-electric-dash (arg) @@ -3704,6 +3890,7 @@ that is, insert space (if appropriate), `-->' and newline if dash is pressed at the end of a line that starts in the first column (i.e., DCG heads)." + ;; FIXME: Use post-self-insert-hook. (interactive "P") (if (and prolog-electric-dash-flag (null arg) @@ -3714,7 +3901,7 @@ (unless (save-excursion (backward-char 1) (looking-at "\\s ")) (insert " ")) (insert "-->\n") - (prolog-indent-line)) + (indent-according-to-mode)) (self-insert-command (prefix-numeric-value arg)))) (defun prolog-electric-dot (arg) @@ -3729,6 +3916,7 @@ of the current predicate. When called with prefix argument ARG, insert just dot." + ;; FIXME: Use post-self-insert-hook. (interactive "P") ;; Check for situations when the electricity should not be active (if (or (not prolog-electric-dot-flag) @@ -3788,6 +3976,7 @@ on a variable then replace the variable with underscore and skip the following comma and whitespace, if any. If the point is not on a variable then insert underscore." + ;; FIXME: Use post-self-insert-hook. (interactive) (if prolog-electric-underscore-flag (let (;start @@ -3862,144 +4051,36 @@ (backward-char))) ))) +;;(defun prolog-regexp-dash-continuous-chars (chars) +;; (let ((ints (mapcar #'prolog-char-to-int (string-to-list chars))) +;; (beg 0) +;; (end 0)) +;; (if (null ints) +;; chars +;; (while (and (< (+ beg 1) (length chars)) +;; (not (or (= (+ (nth beg ints) 1) (nth (+ beg 1) ints)) +;; (= (nth beg ints) (nth (+ beg 1) ints))))) +;; (setq beg (+ beg 1))) +;; (setq beg (+ beg 1) +;; end beg) +;; (while (and (< (+ end 1) (length chars)) +;; (or (= (+ (nth end ints) 1) (nth (+ end 1) ints)) +;; (= (nth end ints) (nth (+ end 1) ints)))) +;; (setq end (+ end 1))) +;; (if (equal (substring chars end) "") +;; (substring chars 0 beg) +;; (concat (substring chars 0 beg) "-" +;; (prolog-regexp-dash-continuous-chars (substring chars end)))) +;; ))) + +;;(defun prolog-condense-character-sets (regexp) +;; "Condense adjacent characters in character sets of REGEXP." +;; (let ((next -1)) +;; (while (setq next (string-match "\\[\\(.*?\\)\\]" regexp (1+ next))) +;; (setq regexp (replace-match (prolog-dash-letters (match-string 1 regexp)) +;; t t regexp 1)))) +;; regexp) -(defun prolog-set-atom-regexps () - "Set the `prolog-atom-char-regexp' and `prolog-atom-regexp' variables. -Must be called after `prolog-build-case-strings'." - (setq prolog-atom-char-regexp - (format "[%s%s0-9_$]" - ;; FIXME: why not a-zA-Z? - prolog-lower-case-string - prolog-upper-case-string)) - (setq prolog-atom-regexp - (format "[%s$]%s*" - prolog-lower-case-string - prolog-atom-char-regexp)) - ) - -(defun prolog-build-case-strings () - "Set `prolog-upper-case-string' and `prolog-lower-case-string'. -Uses the current case-table for extracting the relevant information." - (let ((up_string "") - (low_string "")) - ;; Use `map-char-table' if it is defined. Otherwise enumerate all - ;; numbers between 0 and 255. `map-char-table' is probably safer. - ;; - ;; `map-char-table' causes problems under Emacs 23.0.0.1, the - ;; while loop seems to do its job well (Ryszard Szopa) - ;; - ;;(if (and (not (featurep 'xemacs)) - ;; (fboundp 'map-char-table)) - ;; (map-char-table - ;; (lambda (key value) - ;; (cond - ;; ((and - ;; (eq (prolog-int-to-char key) (downcase key)) - ;; (eq (prolog-int-to-char key) (upcase key))) - ;; ;; Do nothing if upper and lower case are the same - ;; ) - ;; ((eq (prolog-int-to-char key) (downcase key)) - ;; ;; The char is lower case - ;; (setq low_string (format "%s%c" low_string key))) - ;; ((eq (prolog-int-to-char key) (upcase key)) - ;; ;; The char is upper case - ;; (setq up_string (format "%s%c" up_string key))) - ;; )) - ;; (current-case-table)) - ;; `map-char-table' was undefined. - (let ((key 0)) - (while (< key 256) - (cond - ((and - (eq (prolog-int-to-char key) (downcase key)) - (eq (prolog-int-to-char key) (upcase key))) - ;; Do nothing if upper and lower case are the same - ) - ((eq (prolog-int-to-char key) (downcase key)) - ;; The char is lower case - (setq low_string (format "%s%c" low_string key))) - ((eq (prolog-int-to-char key) (upcase key)) - ;; The char is upper case - (setq up_string (format "%s%c" up_string key))) - ) - (setq key (1+ key)))) - ;; ) - ;; The strings are single-byte strings - (setq prolog-upper-case-string (prolog-dash-letters up_string)) - (setq prolog-lower-case-string (prolog-dash-letters low_string)) - )) - -;(defun prolog-regexp-dash-continuous-chars (chars) -; (let ((ints (mapcar #'prolog-char-to-int (string-to-list chars))) -; (beg 0) -; (end 0)) -; (if (null ints) -; chars -; (while (and (< (+ beg 1) (length chars)) -; (not (or (= (+ (nth beg ints) 1) (nth (+ beg 1) ints)) -; (= (nth beg ints) (nth (+ beg 1) ints))))) -; (setq beg (+ beg 1))) -; (setq beg (+ beg 1) -; end beg) -; (while (and (< (+ end 1) (length chars)) -; (or (= (+ (nth end ints) 1) (nth (+ end 1) ints)) -; (= (nth end ints) (nth (+ end 1) ints)))) -; (setq end (+ end 1))) -; (if (equal (substring chars end) "") -; (substring chars 0 beg) -; (concat (substring chars 0 beg) "-" -; (prolog-regexp-dash-continuous-chars (substring chars end)))) -; ))) - -(defun prolog-ints-intervals (ints) - "Return a list of intervals (from . to) covering INTS." - (when ints - (setq ints (sort ints '<)) - (let ((prev (car ints)) - (interval-start (car ints)) - intervals) - (while ints - (let ((next (car ints))) - (when (> next (1+ prev)) ; start of new interval - (setq intervals (cons (cons interval-start prev) intervals)) - (setq interval-start next)) - (setq prev next) - (setq ints (cdr ints)))) - (setq intervals (cons (cons interval-start prev) intervals)) - (reverse intervals)))) - -(defun prolog-dash-letters (string) - "Return a condensed regexp covering all letters in STRING." - (let ((intervals (prolog-ints-intervals (mapcar #'prolog-char-to-int - (string-to-list string)))) - codes) - (while intervals - (let* ((i (car intervals)) - (from (car i)) - (to (cdr i)) - (c (cond ((= from to) `(,from)) - ((= (1+ from) to) `(,from ,to)) - (t `(,from ?- ,to))))) - (setq codes (cons c codes))) - (setq intervals (cdr intervals))) - (apply 'concat (reverse codes)))) - -;(defun prolog-condense-character-sets (regexp) -; "Condense adjacent characters in character sets of REGEXP." -; (let ((next -1)) -; (while (setq next (string-match "\\[\\(.*?\\)\\]" regexp (1+ next))) -; (setq regexp (replace-match (prolog-dash-letters (match-string 1 regexp)) -; t t regexp 1)))) -; regexp) - -;; GNU Emacs compatibility: GNU Emacs does not differentiate between -;; ints and chars, or at least these two are interchangeable. -(defalias 'prolog-int-to-char - (if (fboundp 'int-to-char) #'int-to-char #'identity)) - -(defalias 'prolog-char-to-int - (if (fboundp 'char-to-int) #'char-to-int #'identity)) - ;;------------------------------------------------------------------- ;; Menu stuff (both for the editing buffer and for the inferior ;; prolog buffer) @@ -4110,7 +4191,7 @@ ["Beginning of predicate" prolog-beginning-of-predicate t] ["End of predicate" prolog-end-of-predicate t] "---" - ["Indent line" prolog-indent-line t] + ["Indent line" indent-according-to-mode t] ["Indent region" indent-region (region-exists-p)] ["Indent predicate" prolog-indent-predicate t] ["Indent buffer" prolog-indent-buffer t] diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/lisp/progmodes/sh-script.el emacs-snapshot-24.1+0bzr108200~precise1/lisp/progmodes/sh-script.el --- emacs-snapshot-24.1+0bzr108190~precise1/lisp/progmodes/sh-script.el 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/lisp/progmodes/sh-script.el 2012-05-12 00:34:45.000000000 +0000 @@ -326,7 +326,9 @@ (defcustom sh-imenu-generic-expression `((sh - . ((nil "^\\s-*\\(function\\s-+\\)?\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*()" 2)))) + . ((nil + "^\\s-*\\(function\\s-+\\)?\\([[:alpha:]_][[:alnum:]_]+\\)\\s-*()" + 2)))) "Alist of regular expressions for recognizing shell function definitions. See `sh-feature' and `imenu-generic-expression'." :type '(alist :key-type (symbol :tag "Shell") @@ -460,14 +462,6 @@ (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) - (define-key map "[" 'skeleton-pair-insert-maybe) - (define-key map "'" 'skeleton-pair-insert-maybe) - (define-key map "`" 'skeleton-pair-insert-maybe) - (define-key map "\"" 'skeleton-pair-insert-maybe) (define-key map [remap complete-tag] 'comint-dynamic-complete) (define-key map [remap delete-backward-char] @@ -478,10 +472,10 @@ (define-key map [menu-bar sh-script] (cons "Sh-Script" menu-map)) (define-key menu-map [sh-learn-buffer-indent] '(menu-item "Learn buffer indentation" sh-learn-buffer-indent - :help "Learn how to indent the buffer the way it currently is.")) + :help "Learn how to indent the buffer the way it currently is.")) (define-key menu-map [sh-learn-line-indent] '(menu-item "Learn line indentation" sh-learn-line-indent - :help "Learn how to indent a line as it currently is indented")) + :help "Learn how to indent a line as it currently is indented")) (define-key menu-map [sh-show-indent] '(menu-item "Show indentation" sh-show-indent :help "Show the how the current line would be indented")) @@ -491,13 +485,9 @@ (define-key menu-map [sh-pair] '(menu-item "Insert braces and quotes in pairs" - (lambda () - (interactive) - (require 'skeleton) - (setq skeleton-pair (not skeleton-pair))) - :button (:toggle . (and (boundp 'skeleton-pair) - skeleton-pair)) - :help "Inserting a brace or quote automatically inserts the matching pair")) + electric-pair-mode + :button (:toggle . (bound-and-true-p electric-pair-mode)) + :help "Inserting a brace or quote automatically inserts the matching pair")) (define-key menu-map [sh-s0] '("--")) ;; Insert @@ -506,7 +496,7 @@ :help "Insert a function definition")) (define-key menu-map [sh-add] '(menu-item "Addition..." sh-add - :help "Insert an addition of VAR and prefix DELTA for Bourne (type) shell")) + :help "Insert an addition of VAR and prefix DELTA for Bourne (type) shell")) (define-key menu-map [sh-until] '(menu-item "Until Loop" sh-until :help "Insert an until loop")) @@ -537,16 +527,16 @@ (define-key menu-map [sh-s1] '("--")) (define-key menu-map [sh-exec] '(menu-item "Execute region" sh-execute-region - :help "Pass optional header and region to a subshell for noninteractive execution")) + :help "Pass optional header and region to a subshell for noninteractive execution")) (define-key menu-map [sh-exec-interpret] '(menu-item "Execute script..." executable-interpret - :help "Run script with user-specified args, and collect output in a buffer")) + :help "Run script with user-specified args, and collect output in a buffer")) (define-key menu-map [sh-set-shell] '(menu-item "Set shell type..." sh-set-shell :help "Set this buffer's shell to SHELL (a string)")) (define-key menu-map [sh-backslash-region] '(menu-item "Backslash region" sh-backslash-region - :help "Insert, align, or delete end-of-line backslashes on the lines in the region.")) + :help "Insert, align, or delete end-of-line backslashes on the lines in the region.")) map) "Keymap used in Shell-Script mode.") @@ -564,9 +554,10 @@ :group 'sh-script) (defcustom sh-assignment-regexp - '((csh . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*[-+*/%^]?=") + `((csh . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*[-+*/%^]?=") ;; actually spaces are only supported in let/(( ... )) - (ksh88 . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?[ \t]*\\([-+*/%&|~^]\\|<<\\|>>\\)?=") + (ksh88 . ,(concat "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?" + "[ \t]*\\(?:[-+*/%&|~^]\\|<<\\|>>\\)?=")) (bash . "\\<\\([[:alnum:]_]+\\)\\(\\[.+\\]\\)?\\+?=") (rc . "\\<\\([[:alnum:]_*]+\\)[ \t]*=") (sh . "\\<\\([[:alnum:]_]+\\)=")) @@ -1379,10 +1370,10 @@ (defconst sh-indent-supported - '((sh . t) + '((sh . sh) (csh . nil) - (rc . t)) - "Shell types that shell indenting can do something with.") + (rc . rc)) + "Indentation rule set to use for each shell type.") (defvar sh-indent-supported-here nil "Non-nil if we support indentation for the current buffer's shell type.") @@ -1464,9 +1455,8 @@ \\[sh-set-shell] Set this buffer's shell, and maybe its magic number. \\[sh-execute-region] Have optional header and region be executed in a subshell. -\\[sh-maybe-here-document] Without prefix, following an unquoted < inserts here document. -\{, (, [, ', \", ` - Unless quoted with \\, insert the pairs {}, (), [], or '', \"\", ``. +`sh-electric-here-document-mode' controls whether insertion of two +unquoted < insert a here document. If you generally program a shell different from your login shell you can set `sh-shell-file' accordingly. If your shell's file name doesn't correctly @@ -1503,13 +1493,13 @@ #'sh-syntax-propertize-function) (add-hook 'syntax-propertize-extend-region-functions #'syntax-propertize-multiline 'append 'local) + (sh-electric-here-document-mode 1) (set (make-local-variable 'skeleton-pair-alist) '((?` _ ?`))) (set (make-local-variable 'skeleton-pair-filter-function) 'sh-quoted-p) (set (make-local-variable 'skeleton-further-elements) '((< '(- (min sh-indentation (current-column)))))) (set (make-local-variable 'skeleton-filter-function) 'sh-feature) (set (make-local-variable 'skeleton-newline-indent-rigidly) t) - (set (make-local-variable 'sh-indent-supported-here) nil) (set (make-local-variable 'defun-prompt-regexp) (concat "^\\(function[ \t]\\|[[:alnum:]]+[ \t]+()[ \t]+\\)")) ;; Parse or insert magic number for exec, and set all variables depending @@ -1519,23 +1509,15 @@ (goto-char (point-min)) (looking-at "#![ \t]?\\([^ \t\n]*/bin/env[ \t]\\)?\\([^ \t\n]+\\)")) (match-string 2)) - ((not buffer-file-name) - sh-shell-file) + ((not buffer-file-name) sh-shell-file) ;; Checks that use `buffer-file-name' follow. - ((string-match "\\.m?spec\\'" buffer-file-name) - "rpm") - ((string-match "[.]sh\\>" buffer-file-name) - "sh") - ((string-match "[.]bash\\>" buffer-file-name) - "bash") - ((string-match "[.]ksh\\>" buffer-file-name) - "ksh") - ((string-match "[.]csh\\>" buffer-file-name) - "csh") - ((equal (file-name-nondirectory buffer-file-name) ".profile") - "sh") - (t - sh-shell-file)) + ((string-match "\\.m?spec\\'" buffer-file-name) "rpm") + ((string-match "[.]sh\\>" buffer-file-name) "sh") + ((string-match "[.]bash\\>" buffer-file-name) "bash") + ((string-match "[.]ksh\\>" buffer-file-name) "ksh") + ((string-match "[.]csh\\>" buffer-file-name) "csh") + ((equal (file-name-nondirectory buffer-file-name) ".profile") "sh") + (t sh-shell-file)) nil nil)) ;;;###autoload @@ -1578,6 +1560,426 @@ "Function to get better fontification including keywords and builtins." (sh-font-lock-keywords-1 t)) +;;; Indentation and navigation with SMIE. + +(require 'smie) + +;; The SMIE code should generally be preferred, but it currently does not obey +;; the various indentation custom-vars, and it misses some important features +;; of the old code, mostly: sh-learn-line/buffer-indent, sh-show-indent, +;; sh-name/save/load-style. +(defvar sh-use-smie nil + "Whether to use the SMIE code for navigation and indentation.") + +(defun sh-smie--keyword-p (tok) + "Non-nil if TOK (at which we're looking) really is a keyword." + (let ((prev (funcall smie-backward-token-function))) + (if (zerop (length prev)) + (looking-back "\\s(" (1- (point))) + (assoc prev smie-grammar)))) + +(defun sh-smie--newline-semi-p (&optional tok) + "Return non-nil if a newline should be treated as a semi-colon. +Here we assume that a newline should be treated as a semi-colon unless it +comes right after a special keyword. +This function does not pay attention to line-continuations. +If TOK is nil, point should be before the newline; otherwise, TOK is the token +before the newline and in that case point should be just before the token." + (save-excursion + (unless tok + (setq tok (funcall smie-backward-token-function))) + (if (and (zerop (length tok)) + (looking-back "\\s(" (1- (point)))) + nil + (not (numberp (nth 2 (assoc tok smie-grammar))))))) + +;;;; SMIE support for `sh'. + +(defconst sh-smie-sh-grammar + (smie-prec2->grammar + (smie-bnf->prec2 + '((exp) ;A constant, or a $var, or a sequence of them... + (cmd ("case" exp "in" branches "esac") + ("if" cmd "then" cmd "fi") + ("if" cmd "then" cmd "else" cmd "fi") + ("if" cmd "then" cmd "elif" cmd "then" cmd "fi") + ("if" cmd "then" cmd "elif" cmd "then" cmd "else" cmd "fi") + ("if" cmd "then" cmd "elif" cmd "then" cmd + "elif" cmd "then" cmd "else" cmd "fi") + ("while" cmd "do" cmd "done") + ("until" cmd "do" cmd "done") + ("for" exp "in" cmd "do" cmd "done") + ("for" exp "do" cmd "done") + ("select" exp "in" cmd "do" cmd "done") ;bash&zsh&ksh88. + ("repeat" exp "do" cmd "done") ;zsh. + (exp "always" exp) ;zsh. + (cmd "|" cmd) (cmd "|&" cmd) + (cmd "&&" cmd) (cmd "||" cmd) + (cmd ";" cmd) (cmd "&" cmd)) + (pattern (pattern "|" pattern)) + (branches (branches ";;" branches) + (branches ";&" branches) (branches ";;&" branches) ;bash. + (pattern "case-)" cmd))) + '((assoc ";;" ";&" ";;&")) + '((assoc ";" "&") (assoc "&&" "||") (assoc "|" "|&"))))) + +(defconst sh-smie--sh-operators + (delq nil (mapcar (lambda (x) + (setq x (car x)) + (and (stringp x) + (not (string-match "\\`[a-z]" x)) + x)) + sh-smie-sh-grammar))) + +(defconst sh-smie--sh-operators-re (regexp-opt sh-smie--sh-operators)) +(defconst sh-smie--sh-operators-back-re + (concat "\\(?:^\\|[^\\]\\)\\(?:\\\\\\\\\\)*" + "\\(" sh-smie--sh-operators-re "\\)")) + +(defun sh-smie--sh-keyword-in-p () + "Assuming we're looking at \"in\", return non-nil if it's a keyword. +Does not preserve point." + (let ((forward-sexp-function nil) + (words nil) ;We've seen words. + (newline nil) ;We've seen newlines after the words. + (res nil) + prev) + (while (not res) + (setq prev (funcall smie-backward-token-function)) + (cond + ((zerop (length prev)) + (if newline + (progn (assert words) (setq res 'word)) + (setq words t) + (condition-case nil + (forward-sexp -1) + (scan-error (setq res 'unknown))))) + ((equal prev ";") + (if words (setq newline t) + (setq res 'keyword))) + ((member prev '("case" "for" "select")) (setq res 'keyword)) + ((assoc prev smie-grammar) (setq res 'word)) + (t + (if newline + (progn (assert words) (setq res 'word)) + (setq words t))))) + (eq res 'keyword))) + +(defun sh-smie--sh-keyword-p (tok) + "Non-nil if TOK (at which we're looking) really is a keyword." + (if (equal tok "in") + (sh-smie--sh-keyword-in-p) + (sh-smie--keyword-p tok))) + +(defun sh-smie-sh-forward-token () + (if (and (looking-at "[ \t]*\\(?:#\\|\\(\\s|\\)\\|$\\)") + (save-excursion + (skip-chars-backward " \t") + (not (bolp)))) + (if (and (match-end 1) (not (nth 3 (syntax-ppss)))) + ;; Right before a here-doc. + (let ((forward-sexp-function nil)) + (forward-sexp 1) + ;; Pretend the here-document is a "newline representing a + ;; semi-colon", since the here-doc otherwise covers the newline(s). + ";") + (let ((semi (sh-smie--newline-semi-p))) + (forward-line 1) + (if semi ";" + (sh-smie-sh-forward-token)))) + (forward-comment (point-max)) + (cond + ((looking-at "\\\\\n") (forward-line 1) (sh-smie-sh-forward-token)) + ((looking-at sh-smie--sh-operators-re) + (goto-char (match-end 0)) + (let ((tok (match-string-no-properties 0))) + (if (and (memq (aref tok (1- (length tok))) '(?\; ?\& ?\|)) + (looking-at "[ \t]*\\(?:#\\|$\\)")) + (forward-line 1)) + tok)) + (t + (let* ((pos (point)) + (tok (smie-default-forward-token))) + (cond + ((equal tok ")") "case-)") + ((and tok (string-match "\\`[a-z]" tok) + (assoc tok smie-grammar) + (not + (save-excursion + (goto-char pos) + (sh-smie--sh-keyword-p tok)))) + " word ") + (t tok))))))) + +(defun sh-smie--looking-back-at-continuation-p () + (save-excursion + (and (if (eq (char-before) ?\n) (progn (forward-char -1) t) (eolp)) + (looking-back "\\(?:^\\|[^\\]\\)\\(?:\\\\\\\\\\)*\\\\" + (line-beginning-position))))) + +(defun sh-smie-sh-backward-token () + (let ((bol (line-beginning-position)) + pos tok) + (forward-comment (- (point))) + (cond + ((and (bolp) (not (bobp)) + (equal (syntax-after (1- (point))) (string-to-syntax "|")) + (not (nth 3 (syntax-ppss)))) + ;; Right after a here-document. + (let ((forward-sexp-function nil)) + (forward-sexp -1) + ;; Pretend the here-document is a "newline representing a + ;; semi-colon", since the here-doc otherwise covers the newline(s). + ";")) + ((< (point) bol) + (cond + ((sh-smie--looking-back-at-continuation-p) + (forward-char -1) + (funcall smie-backward-token-function)) + ((sh-smie--newline-semi-p) ";") + (t (funcall smie-backward-token-function)))) + ((looking-back sh-smie--sh-operators-back-re + (line-beginning-position) 'greedy) + (goto-char (match-beginning 1)) + (match-string-no-properties 1)) + (t + (let ((tok (smie-default-backward-token))) + (cond + ((equal tok ")") "case-)") + ((and tok (string-match "\\`[a-z]" tok) + (assoc tok smie-grammar) + (not (save-excursion (sh-smie--sh-keyword-p tok)))) + " word ") + (t tok))))))) + +(defcustom sh-indent-after-continuation t + "If non-nil, try to make sure text is indented after a line continuation." + :type 'boolean) + +(defun sh-smie--continuation-start-indent () + "Return the initial indentation of a continued line. +May return nil if the line should not be treated as continued." + (save-excursion + (forward-line -1) + (unless (sh-smie--looking-back-at-continuation-p) + (current-indentation)))) + +(defun sh-smie-sh-rules (kind token) + (pcase (cons kind token) + (`(:elem . basic) sh-indentation) + (`(:after . "case-)") (or sh-indentation smie-indent-basic)) + ((and `(:before . ,_) + (guard (when sh-indent-after-continuation + (save-excursion + (ignore-errors + (skip-chars-backward " \t") + (sh-smie--looking-back-at-continuation-p)))))) + ;; After a line-continuation, make sure the rest is indented. + (let* ((sh-indent-after-continuation nil) + (indent (smie-indent-calculate)) + (initial (sh-smie--continuation-start-indent))) + (when (and (numberp indent) (numberp initial) + (<= indent initial)) + `(column . ,(+ initial sh-indentation))))) + (`(:before . ,(or `"(" `"{" `"[")) + (if (smie-rule-hanging-p) (smie-rule-parent))) + ;; FIXME: Maybe this handling of ;; should be made into + ;; a smie-rule-terminator function that takes the substitute ";" as arg. + (`(:before . ,(or `";;" `";&" `";;&")) + (if (and (smie-rule-bolp) (looking-at ";;?&?[ \t]*\\(#\\|$\\)")) + (cons 'column (smie-indent-keyword ";")) + (smie-rule-separator kind))) + (`(:after . ,(or `";;" `";&" `";;&")) + (with-demoted-errors + (smie-backward-sexp token) + (cons 'column + (if (or (smie-rule-bolp) + (save-excursion + (and (member (funcall smie-backward-token-function) + '("in" ";;")) + (smie-rule-bolp)))) + (current-column) + (smie-indent-calculate))))) + (`(:after . "|") (if (smie-rule-parent-p "|") nil 4)) + )) + +;; (defconst sh-smie-csh-grammar +;; (smie-prec2->grammar +;; (smie-bnf->prec2 +;; '((exp) ;A constant, or a $var, or a sequence of them… +;; (elseifcmd (cmd) +;; (cmd "else" "else-if" exp "then" elseifcmd)) +;; (cmd ("switch" branches "endsw") +;; ("if" exp) +;; ("if" exp "then" cmd "endif") +;; ("if" exp "then" cmd "else" cmd "endif") +;; ("if" exp "then" elseifcmd "endif") +;; ;; ("if" exp "then" cmd "else" cmd "endif") +;; ;; ("if" exp "then" cmd "else" "if" exp "then" cmd "endif") +;; ;; ("if" exp "then" cmd "else" "if" exp "then" cmd +;; ;; "else" cmd "endif") +;; ;; ("if" exp "then" cmd "else" "if" exp "then" cmd +;; ;; "else" "if" exp "then" cmd "endif") +;; ("while" cmd "end") +;; ("foreach" cmd "end") +;; (cmd "|" cmd) (cmd "|&" cmd) +;; (cmd "&&" cmd) (cmd "||" cmd) +;; (cmd ";" cmd) (cmd "&" cmd)) +;; ;; This is a lie, but (combined with the corresponding disambiguation +;; ;; rule) it makes it more clear that `case' and `default' are the key +;; ;; separators and the `:' is a secondary tokens. +;; (branches (branches "case" branches) +;; (branches "default" branches) +;; (exp ":" branches))) +;; '((assoc "else" "then" "endif")) +;; '((assoc "case" "default") (nonassoc ":")) +;; '((assoc ";;" ";&" ";;&")) +;; '((assoc ";" "&") (assoc "&&" "||") (assoc "|" "|&"))))) + +;;;; SMIE support for `rc'. + +(defconst sh-smie-rc-grammar + (smie-prec2->grammar + (smie-bnf->prec2 + '((exp) ;A constant, or a $var, or a sequence of them... + (cmd (cmd "case" cmd) + ("if" exp) + ("switch" exp) + ("for" exp) ("while" exp) + (cmd "|" cmd) (cmd "|&" cmd) + (cmd "&&" cmd) (cmd "||" cmd) + (cmd ";" cmd) (cmd "&" cmd)) + (pattern (pattern "|" pattern)) + (branches (branches ";;" branches) + (branches ";&" branches) (branches ";;&" branches) ;bash. + (pattern "case-)" cmd))) + '((assoc ";;" ";&" ";;&")) + '((assoc "case") (assoc ";" "&") (assoc "&&" "||") (assoc "|" "|&"))))) + +(defun sh-smie--rc-after-special-arg-p () + "Check if we're after the first arg of an if/while/for/... construct. +Returns the construct's token and moves point before it, if so." + (forward-comment (- (point))) + (when (looking-back ")\\|\\_ /dev/null) || exit 1; \ + ${INSTALL_DATA} etc/$${docfile} $(DESTDIR)${docdir}/$${docfile}; \ (cd $(DESTDIR)$(docdir); \ $(set_installuser); \ - chown $${installuser} DOC*; chmod a+r DOC*; \ + chown $${installuser} DOC*; \ if test "`echo DOC-*`" != "DOC-*"; then rm -f DOC; fi); \ else true; fi -unset CDPATH; \ - if [ -r ./lisp ] \ - && [ -r ./lisp/simple.el ] \ - && [ x`(cd ./lisp; /bin/pwd)` != x`(cd $(DESTDIR)${lispdir}; /bin/pwd)` ] \ - && [ x`(cd ${srcdir}/lisp; /bin/pwd)` != x`(cd ./lisp; /bin/pwd)` ]; \ - then \ - echo "Copying lisp/*.el and lisp/*.elc to $(DESTDIR)${lispdir} ..." ; \ - (cd lisp; tar -chf - *.el *.elc) \ - |(cd $(DESTDIR)${lispdir}; umask 022; tar -xvf - && cat > /dev/null) || exit 1; \ - (cd $(DESTDIR)${lispdir}; \ - $(set_installuser); \ - find . -exec chown $${installuser} {} ';') ; \ - else true; fi - -unset CDPATH; \ if [ -n "${GZIP_PROG}" ]; \ then \ echo "Compressing *.el ..." ; \ diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/.pc/debian-emacs-news.diff/etc/NEWS emacs-snapshot-24.1+0bzr108200~precise1/.pc/debian-emacs-news.diff/etc/NEWS --- emacs-snapshot-24.1+0bzr108190~precise1/.pc/debian-emacs-news.diff/etc/NEWS 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/.pc/debian-emacs-news.diff/etc/NEWS 2012-05-12 00:34:45.000000000 +0000 @@ -90,6 +90,11 @@ * Changes in Specialized Modes and Packages in Emacs 24.2 +** `sh-script' +*** Pairing of parens/quotes uses electric-pair-mode instead of skeleton-pair. +*** `sh-electric-here-document-mode' now controls auto-insertion of here-docs. +*** `sh-use-smie' lets you choose a new indentation and navigation code. + ** reStructuredText mode *** Major merge with upstream development. diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/.pc/debian-inst.diff/Makefile.in emacs-snapshot-24.1+0bzr108200~precise1/.pc/debian-inst.diff/Makefile.in --- emacs-snapshot-24.1+0bzr108190~precise1/.pc/debian-inst.diff/Makefile.in 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/.pc/debian-inst.diff/Makefile.in 2012-05-12 00:34:45.000000000 +0000 @@ -455,6 +455,8 @@ ### Install the executables that were compiled specifically for this machine. ### It would be nice to do something for a parallel make ### to ensure that install-arch-indep finishes before this starts. +### (TODO Why would it be nice? Why not just make this depend on +### install-arch-indep then?) install-arch-dep: mkdir (cd lib-src; \ $(MAKE) install $(MFLAGS) prefix=${prefix} \ @@ -495,9 +497,17 @@ ## Note that we copy DOC* and then delete DOC ## as a workaround for a bug in tar on Ultrix 4.2. +## Ultrix is no longer supported since 23.1, but the relevant line +## has another effect. We copy the entire etc/ directory from the +## source tree first. For an in-tree build, this will include +## any DOC* files there may be. So rm DOC does have an effect. +## FIXME When we copy etc we should exclude DOC*, then copy only +## the relevant one. We cannot delete DOC* from the destination directory, +## because that may include pre-existing files from another emacs. ## We install only the relevant DOC file if possible ## (ie DOC-${version}.buildnumber), otherwise DOC-${version}*. +## (Note "otherwise" is inaccurate since 2009-08-23.) ## If people complain about the h flag in tar command, take that out. ## That flag is also used in leim/Makefile.in @@ -538,8 +548,7 @@ rm -f $${subdir}/*~ ; \ rm -f $${subdir}/*.orig ; \ [ "$${dir}" != "${srcdir}/etc" ] && \ - rm -f $${subdir}/[mM]akefile*.c $${subdir}/[mM]akefile*[.-]in \ - $${subdir}/[mM]akefile ; \ + rm -f $${subdir}/[mM]akefile*[.-]in $${subdir}/[mM]akefile ; \ rm -f $${subdir}/ChangeLog* ; \ done) ; \ done @@ -572,27 +581,13 @@ docfile="DOC"; \ fi; \ echo "Copying etc/$${docfile} to $(DESTDIR)${docdir} ..." ; \ - (cd ./etc; tar -chf - $${docfile}) \ - |(cd $(DESTDIR)${docdir}; umask 022; tar -xvf - && cat > /dev/null) || exit 1; \ + ${INSTALL_DATA} etc/$${docfile} $(DESTDIR)${docdir}/$${docfile}; \ (cd $(DESTDIR)$(docdir); \ $(set_installuser); \ - chown $${installuser} DOC*; chmod a+r DOC*; \ + chown $${installuser} DOC*; \ if test "`echo DOC-*`" != "DOC-*"; then rm -f DOC; fi); \ else true; fi -unset CDPATH; \ - if [ -r ./lisp ] \ - && [ -r ./lisp/simple.el ] \ - && [ x`(cd ./lisp; /bin/pwd)` != x`(cd $(DESTDIR)${lispdir}; /bin/pwd)` ] \ - && [ x`(cd ${srcdir}/lisp; /bin/pwd)` != x`(cd ./lisp; /bin/pwd)` ]; \ - then \ - echo "Copying lisp/*.el and lisp/*.elc to $(DESTDIR)${lispdir} ..." ; \ - (cd lisp; tar -chf - *.el *.elc) \ - |(cd $(DESTDIR)${lispdir}; umask 022; tar -xvf - && cat > /dev/null) || exit 1; \ - (cd $(DESTDIR)${lispdir}; \ - $(set_installuser); \ - find . -exec chown $${installuser} {} ';') ; \ - else true; fi - -unset CDPATH; \ if [ -n "${GZIP_PROG}" ]; \ then \ echo "Compressing *.el ..." ; \ diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/src/ChangeLog emacs-snapshot-24.1+0bzr108200~precise1/src/ChangeLog --- emacs-snapshot-24.1+0bzr108190~precise1/src/ChangeLog 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/src/ChangeLog 2012-05-12 00:34:45.000000000 +0000 @@ -1,3 +1,10 @@ +2012-05-11 Paul Eggert + + Remove unused function hourglass_started. + * dispextern.h (hourglass_started): + * w32fns.c (hourglass_started): + * xdisp.c (hourglass_started): Remove. + 2012-05-10 Juanma Barranquero * makefile.w32-in ($(BLD)/gmalloc.$(O), $(BLD)/w32menu.$(O)): diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/src/dispextern.h emacs-snapshot-24.1+0bzr108200~precise1/src/dispextern.h --- emacs-snapshot-24.1+0bzr108190~precise1/src/dispextern.h 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/src/dispextern.h 2012-05-12 00:34:45.000000000 +0000 @@ -3243,7 +3243,6 @@ EXFUN (Fx_hide_tip, 0); extern void start_hourglass (void); extern void cancel_hourglass (void); -extern int hourglass_started (void); extern int hourglass_shown_p; struct atimer; /* Defined in atimer.h. */ /* If non-null, an asynchronous timer that, when it expires, displays diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/src/w32fns.c emacs-snapshot-24.1+0bzr108200~precise1/src/w32fns.c --- emacs-snapshot-24.1+0bzr108190~precise1/src/w32fns.c 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/src/w32fns.c 2012-05-12 00:34:45.000000000 +0000 @@ -5016,16 +5016,6 @@ cursor. Duplicated from xdisp.c, but cannot use the version there due to lack of atimers on w32. */ #define DEFAULT_HOURGLASS_DELAY 1 -/* Return non-zero if hourglass timer has been started or hourglass is - shown. */ -/* PENDING: if W32 can use atimers (atimer.[hc]) then the common impl in - xdisp.c could be used. */ - -int -hourglass_started (void) -{ - return hourglass_shown_p || hourglass_timer; -} /* Cancel a currently active hourglass timer, and start a new one. */ diff -Nru emacs-snapshot-24.1+0bzr108190~precise1/src/xdisp.c emacs-snapshot-24.1+0bzr108200~precise1/src/xdisp.c --- emacs-snapshot-24.1+0bzr108190~precise1/src/xdisp.c 2012-05-10 16:42:56.000000000 +0000 +++ emacs-snapshot-24.1+0bzr108200~precise1/src/xdisp.c 2012-05-12 00:34:45.000000000 +0000 @@ -28882,14 +28882,6 @@ /* Platform-independent portion of hourglass implementation. */ -/* Return non-zero if hourglass timer has been started or hourglass is - shown. */ -int -hourglass_started (void) -{ - return hourglass_shown_p || hourglass_atimer != NULL; -} - /* Cancel a currently active hourglass timer, and start a new one. */ void start_hourglass (void)