diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2011-09-03 16:03:38 -0700 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2011-09-03 16:03:38 -0700 |
commit | b49e353d9d01adbe60bc5d0b1658b4ef978b0b06 (patch) | |
tree | 9f2ffa6f7a6562abf661a4951012b488ad8b1ae7 /lisp/progmodes | |
parent | 74b880cbc18bd0194c7b1fc44c4a983ee05adae2 (diff) | |
parent | bc3200871917d5c54c8c4299a06bf8f8ba2ea02d (diff) | |
download | emacs-b49e353d9d01adbe60bc5d0b1658b4ef978b0b06.tar.gz |
Merge from trunk.
Diffstat (limited to 'lisp/progmodes')
-rw-r--r-- | lisp/progmodes/cc-engine.el | 20 | ||||
-rw-r--r-- | lisp/progmodes/cc-fonts.el | 311 | ||||
-rw-r--r-- | lisp/progmodes/cc-langs.el | 17 | ||||
-rw-r--r-- | lisp/progmodes/cc-menus.el | 7 | ||||
-rw-r--r-- | lisp/progmodes/compile.el | 25 | ||||
-rw-r--r-- | lisp/progmodes/grep.el | 14 | ||||
-rw-r--r-- | lisp/progmodes/js.el | 70 | ||||
-rw-r--r-- | lisp/progmodes/python.el | 12 | ||||
-rw-r--r-- | lisp/progmodes/scheme.el | 28 | ||||
-rw-r--r-- | lisp/progmodes/sh-script.el | 66 |
10 files changed, 383 insertions, 187 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el index 0236a2be296..a1cbdc16560 100644 --- a/lisp/progmodes/cc-engine.el +++ b/lisp/progmodes/cc-engine.el @@ -2130,13 +2130,17 @@ comment at the start of cc-engine.el for more info." pos)) (defsubst c-state-cache-non-literal-place (pos state) - ;; Return a position outside of a string/comment at or before POS. + ;; Return a position outside of a string/comment/macro at or before POS. ;; STATE is the parse-partial-sexp state at POS. - (if (or (nth 3 state) ; in a string? - (nth 4 state)) ; in a comment? - (nth 8 state) - pos)) - + (let ((res (if (or (nth 3 state) ; in a string? + (nth 4 state)) ; in a comment? + (nth 8 state) + pos))) + (save-excursion + (goto-char res) + (if (c-beginning-of-macro) + (point) + res)))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Stuff to do with point-min, and coping with any literal there. @@ -6321,7 +6325,9 @@ comment at the start of cc-engine.el for more info." (let* ((start (point)) kwd-sym kwd-clause-end found-type) ;; Look for a specifier keyword clause. - (when (looking-at c-prefix-spec-kwds-re) + (when (or (looking-at c-prefix-spec-kwds-re) + (and (c-major-mode-is 'java-mode) + (looking-at "@[A-Za-z0-9]+"))) (if (looking-at c-typedef-key) (setq at-typedef t)) (setq kwd-sym (c-keyword-sym (match-string 1))) diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el index 2277ba760ab..bca95c97e8b 100644 --- a/lisp/progmodes/cc-fonts.el +++ b/lisp/progmodes/cc-fonts.el @@ -199,10 +199,16 @@ (set-face-foreground 'c-annotation-face "blue") (eval-and-compile - ;; We need the following functions during compilation since they're - ;; called when the `c-lang-defconst' initializers are evaluated. - ;; Define them at runtime too for the sake of derived modes. - + ;; We need the following definitions during compilation since they're + ;; used when the `c-lang-defconst' initializers are evaluated. Define + ;; them at runtime too for the sake of derived modes. + + ;; This indicates the "font locking context", and is set just before + ;; fontification is done. If non-nil, it says, e.g., point starts + ;; from within a #if preprocessor construct. + (defvar c-font-lock-context nil) + (make-variable-buffer-local 'c-font-lock-context) + (defmacro c-put-font-lock-face (from to face) ;; Put a face on a region (overriding any existing face) in the way ;; font-lock would do it. In XEmacs that means putting an @@ -283,6 +289,45 @@ nil))))) res)))) + (defun c-make-font-lock-search-form (regexp highlights) + ;; Return a lisp form which will fontify every occurence of REGEXP + ;; (a regular expression, NOT a function) between POINT and `limit' + ;; with HIGHLIGHTS, a list of highlighters as specified on page + ;; "Search-based Fontification" in the elisp manual. + `(while (re-search-forward ,regexp limit t) + (unless (progn + (goto-char (match-beginning 0)) + (c-skip-comments-and-strings limit)) + (goto-char (match-end 0)) + ,@(mapcar + (lambda (highlight) + (if (integerp (car highlight)) + ;; e.g. highlight is (1 font-lock-type-face t) + (progn + (unless (eq (nth 2 highlight) t) + (error + "The override flag must currently be t in %s" + highlight)) + (when (nth 3 highlight) + (error + "The laxmatch flag may currently not be set in %s" + highlight)) + `(save-match-data + (c-put-font-lock-face + (match-beginning ,(car highlight)) + (match-end ,(car highlight)) + ,(elt highlight 1)))) + ;; highlight is an "ANCHORED HIGHLIGHER" of the form + ;; (ANCHORED-MATCHER PRE-FORM POST-FORM SUBEXP-HIGHLIGHTERS...) + (when (nth 3 highlight) + (error "Match highlights currently not supported in %s" + highlight)) + `(progn + ,(nth 1 highlight) + (save-match-data ,(car highlight)) + ,(nth 2 highlight)))) + highlights)))) + (defun c-make-font-lock-search-function (regexp &rest highlights) ;; This function makes a byte compiled function that works much like ;; a matcher element in `font-lock-keywords'. It cuts out a little @@ -313,43 +358,154 @@ ;; lambda more easily. (byte-compile `(lambda (limit) - (let (;; The font-lock package in Emacs is known to clobber + (let ( ;; The font-lock package in Emacs is known to clobber ;; `parse-sexp-lookup-properties' (when it exists). (parse-sexp-lookup-properties (cc-eval-when-compile (boundp 'parse-sexp-lookup-properties)))) - (while (re-search-forward ,regexp limit t) - (unless (progn - (goto-char (match-beginning 0)) - (c-skip-comments-and-strings limit)) - (goto-char (match-end 0)) - ,@(mapcar - (lambda (highlight) - (if (integerp (car highlight)) - (progn - (unless (eq (nth 2 highlight) t) - (error - "The override flag must currently be t in %s" - highlight)) - (when (nth 3 highlight) - (error - "The laxmatch flag may currently not be set in %s" - highlight)) - `(save-match-data - (c-put-font-lock-face - (match-beginning ,(car highlight)) - (match-end ,(car highlight)) - ,(elt highlight 1)))) - (when (nth 3 highlight) - (error "Match highlights currently not supported in %s" - highlight)) - `(progn - ,(nth 1 highlight) - (save-match-data ,(car highlight)) - ,(nth 2 highlight)))) - highlights)))) + + ;; (while (re-search-forward ,regexp limit t) + ;; (unless (progn + ;; (goto-char (match-beginning 0)) + ;; (c-skip-comments-and-strings limit)) + ;; (goto-char (match-end 0)) + ;; ,@(mapcar + ;; (lambda (highlight) + ;; (if (integerp (car highlight)) + ;; (progn + ;; (unless (eq (nth 2 highlight) t) + ;; (error + ;; "The override flag must currently be t in %s" + ;; highlight)) + ;; (when (nth 3 highlight) + ;; (error + ;; "The laxmatch flag may currently not be set in %s" + ;; highlight)) + ;; `(save-match-data + ;; (c-put-font-lock-face + ;; (match-beginning ,(car highlight)) + ;; (match-end ,(car highlight)) + ;; ,(elt highlight 1)))) + ;; (when (nth 3 highlight) + ;; (error "Match highlights currently not supported in %s" + ;; highlight)) + ;; `(progn + ;; ,(nth 1 highlight) + ;; (save-match-data ,(car highlight)) + ;; ,(nth 2 highlight)))) + ;; highlights))) + ,(c-make-font-lock-search-form regexp highlights)) + nil))) + (defun c-make-font-lock-BO-decl-search-function (regexp &rest highlights) + ;; This function makes a byte compiled function that first moves back + ;; to the beginning of the current declaration (if any), then searches + ;; forward for matcher elements (as in `font-lock-keywords') and + ;; fontifies them. + ;; + ;; The motivation for moving back to the declaration start is to + ;; establish a context for the current text when, e.g., a character + ;; is typed on a C++ inheritance continuation line, or a jit-lock + ;; chunk starts there. + ;; + ;; The new function works much like a matcher element in + ;; `font-lock-keywords'. It cuts out a little bit of the overhead + ;; compared to a real matcher. The main reason is however to pass the + ;; real search limit to the anchored matcher(s), since most (if not + ;; all) font-lock implementations arbitrarily limit anchored matchers + ;; to the same line, and also to insulate against various other + ;; irritating differences between the different (X)Emacs font-lock + ;; packages. + ;; + ;; REGEXP is the matcher, which must be a regexp. Only matches + ;; where the beginning is outside any comment or string literal are + ;; significant. + ;; + ;; HIGHLIGHTS is a list of highlight specs, just like in + ;; `font-lock-keywords', with these limitations: The face is always + ;; overridden (no big disadvantage, since hits in comments etc are + ;; filtered anyway), there is no "laxmatch", and an anchored matcher + ;; is always a form which must do all the fontification directly. + ;; `limit' is a variable bound to the real limit in the context of + ;; the anchored matcher forms. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + + ;; Note: Replace `byte-compile' with `eval' to debug the generated + ;; lambda more easily. + (byte-compile + `(lambda (limit) + (let ( ;; The font-lock package in Emacs is known to clobber + ;; `parse-sexp-lookup-properties' (when it exists). + (parse-sexp-lookup-properties + (cc-eval-when-compile + (boundp 'parse-sexp-lookup-properties)))) + (goto-char + (let ((here (point))) + (if (eq (car (c-beginning-of-decl-1)) 'same) + (point) + here))) + ,(c-make-font-lock-search-form regexp highlights)) + nil))) + + (defun c-make-font-lock-context-search-function (normal &rest state-stanzas) + ;; This function makes a byte compiled function that works much like + ;; a matcher element in `font-lock-keywords', with the following + ;; enhancement: the generated function will test for particular "font + ;; lock contexts" at the start of the region, i.e. is this point in + ;; the middle of some particular construct? if so the generated + ;; function will first fontify the tail of the construct, before + ;; going into the main loop and fontify full constructs up to limit. + ;; + ;; The generated function takes one parameter called `limit', and + ;; will fontify the region between POINT and LIMIT. + ;; + ;; NORMAL is a list of the form (REGEXP HIGHLIGHTS .....), and is + ;; used to fontify the "regular" bit of the region. + ;; STATE-STANZAS is list of elements of the form (STATE LIM REGEXP + ;; HIGHLIGHTS), each element coding one possible font lock context. + + ;; o - REGEXP is a font-lock regular expression (NOT a function), + ;; o - HIGHLIGHTS is a list of zero or more highlighters as defined + ;; on page "Search-based Fontification" in the elisp manual. As + ;; yet (2009-06), they must have OVERRIDE set, and may not have + ;; LAXMATCH set. + ;; + ;; o - STATE is the "font lock context" (e.g. in-cpp-expr) and is + ;; not quoted. + ;; o - LIM is a lisp form whose evaluation will yield the limit + ;; position in the buffer for fontification by this stanza. + ;; + ;; This function does not do any hidden buffer changes, but the + ;; generated functions will. (They are however used in places + ;; covered by the font-lock context.) + ;; + ;; Note: Replace `byte-compile' with `eval' to debug the generated + ;; lambda more easily. + (byte-compile + `(lambda (limit) + (let ( ;; The font-lock package in Emacs is known to clobber + ;; `parse-sexp-lookup-properties' (when it exists). + (parse-sexp-lookup-properties + (cc-eval-when-compile + (boundp 'parse-sexp-lookup-properties)))) + ,@(mapcar + (lambda (stanza) + (let ((state (car stanza)) + (lim (nth 1 stanza)) + (regexp (nth 2 stanza)) + (highlights (cdr (cddr stanza)))) + `(if (eq c-font-lock-context ',state) + (let ((limit ,lim)) + ,(c-make-font-lock-search-form + regexp highlights))))) + state-stanzas) + ,(c-make-font-lock-search-form (car normal) (cdr normal)) + nil)))) + ; (eval-after-load "edebug" ; 2006-07-09: def-edebug-spec is now in subr.el. ; '(progn (def-edebug-spec c-fontify-types-and-refs let*) @@ -494,19 +650,24 @@ stuff. Used on level 1 and higher." (c-lang-const c-cpp-expr-directives))) (cef-re (c-make-keywords-re t (c-lang-const c-cpp-expr-functions)))) - `((,(c-make-font-lock-search-function - (concat noncontinued-line-end - (c-lang-const c-opt-cpp-prefix) - ced-re ; 1 + ncle-depth - ;; Match the whole logical line to look - ;; for the functions in. - "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") - `((let ((limit (match-end 0))) - (while (re-search-forward ,cef-re limit 'move) - (c-put-font-lock-face (match-beginning 1) - (match-end 1) - c-preprocessor-face-name))) - (goto-char (match-end ,(1+ ncle-depth))))))))) + + `((,(c-make-font-lock-context-search-function + `(,(concat noncontinued-line-end + (c-lang-const c-opt-cpp-prefix) + ced-re ; 1 + ncle-depth + ;; Match the whole logical line to look + ;; for the functions in. + "\\(\\\\\\(.\\|[\n\r]\\)\\|[^\n\r]\\)*") + ((let ((limit (match-end 0))) + (while (re-search-forward ,cef-re limit 'move) + (c-put-font-lock-face (match-beginning 1) + (match-end 1) + c-preprocessor-face-name))) + (goto-char (match-end ,(1+ ncle-depth))))) + `(in-cpp-expr + (save-excursion (c-end-of-macro) (point)) + ,cef-re + (1 c-preprocessor-face-name t))))))) ;; Fontify the directive names. (,(c-make-font-lock-search-function @@ -759,6 +920,12 @@ casts and declarations are fontified. Used on level 2 and higher." (c-forward-syntactic-ws limit) (c-font-lock-declarators limit t (eq prop 'c-decl-type-start)))) + (setq c-font-lock-context ;; (c-guess-font-lock-context) + (save-excursion + (if (and c-cpp-expr-intro-re + (c-beginning-of-macro) + (looking-at c-cpp-expr-intro-re)) + 'in-cpp-expr))) nil) (defun c-font-lock-<>-arglists (limit) @@ -1552,7 +1719,9 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'." (unless (c-skip-comments-and-strings limit) (c-forward-syntactic-ws) ;; Handle prefix declaration specifiers. - (when (looking-at c-prefix-spec-kwds-re) + (when (or (looking-at c-prefix-spec-kwds-re) + (and (c-major-mode-is 'java-mode) + (looking-at "@[A-Za-z0-9]+"))) (c-forward-keyword-clause 1)) ,(if (c-major-mode-is 'c++-mode) `(when (and (c-forward-type) @@ -1712,24 +1881,32 @@ higher." c-label-face-name nil t)))))) ;; Fontify the clauses after various keywords. - ,@(when (or (c-lang-const c-type-list-kwds) - (c-lang-const c-ref-list-kwds) - (c-lang-const c-colon-type-list-kwds) - (c-lang-const c-paren-type-kwds)) - `((,(c-make-font-lock-search-function - (concat "\\<\\(" - (c-make-keywords-re nil - (append (c-lang-const c-type-list-kwds) - (c-lang-const c-ref-list-kwds) - (c-lang-const c-colon-type-list-kwds) - (c-lang-const c-paren-type-kwds))) - "\\)\\>") - '((c-fontify-types-and-refs ((c-promote-possible-types t)) - (c-forward-keyword-clause 1) - (if (> (point) limit) (goto-char limit)))))))) - - ,@(when (c-major-mode-is 'java-mode) - `((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face)))) + ,@(when (or (c-lang-const c-type-list-kwds) + (c-lang-const c-ref-list-kwds) + (c-lang-const c-colon-type-list-kwds)) + `((,(c-make-font-lock-BO-decl-search-function + (concat "\\<\\(" + (c-make-keywords-re nil + (append (c-lang-const c-type-list-kwds) + (c-lang-const c-ref-list-kwds) + (c-lang-const c-colon-type-list-kwds))) + "\\)\\>") + '((c-fontify-types-and-refs ((c-promote-possible-types t)) + (c-forward-keyword-clause 1) + (if (> (point) limit) (goto-char limit)))))))) + + ,@(when (c-lang-const c-paren-type-kwds) + `((,(c-make-font-lock-search-function + (concat "\\<\\(" + (c-make-keywords-re nil + (c-lang-const c-paren-type-kwds)) + "\\)\\>") + '((c-fontify-types-and-refs ((c-promote-possible-types t)) + (c-forward-keyword-clause 1) + (if (> (point) limit) (goto-char limit)))))))) + + ,@(when (c-major-mode-is 'java-mode) + `((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face)))) )) (c-lang-defconst c-matchers-1 diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el index 35097242cb7..279c5e46c46 100644 --- a/lisp/progmodes/cc-langs.el +++ b/lisp/progmodes/cc-langs.el @@ -815,6 +815,16 @@ expression." t (if (c-lang-const c-opt-cpp-prefix) '("if" "elif"))) +(c-lang-defconst c-cpp-expr-intro-re + "Regexp which matches the start of a CPP directive which contains an +expression, or nil if there aren't any in the language." + t (if (c-lang-const c-cpp-expr-directives) + (concat + (c-lang-const c-opt-cpp-prefix) + (c-make-keywords-re t (c-lang-const c-cpp-expr-directives))))) +(c-lang-defvar c-cpp-expr-intro-re + (c-lang-const c-cpp-expr-intro-re)) + (c-lang-defconst c-cpp-expr-functions "List of functions in cpp expressions." t (if (c-lang-const c-opt-cpp-prefix) @@ -1813,7 +1823,7 @@ will be handled." "bindsTo" "delegatesTo" "implements" "proxy" "storedOn") ;; Note: "const" is not used in Java, but it's still a reserved keyword. java '("abstract" "const" "final" "native" "private" "protected" "public" - "static" "strictfp" "synchronized" "transient" "volatile" "@[A-Za-z0-9]+") + "static" "strictfp" "synchronized" "transient" "volatile") pike '("final" "inline" "local" "nomask" "optional" "private" "protected" "public" "static" "variant")) @@ -1899,10 +1909,7 @@ one of `c-type-list-kwds', `c-ref-list-kwds', (c-lang-defconst c-prefix-spec-kwds-re ;; Adorned regexp of `c-prefix-spec-kwds'. - t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds)) - java (replace-regexp-in-string - "\\\\\\[" "[" - (replace-regexp-in-string "\\\\\\+" "+" (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds))))) + t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds))) (c-lang-defvar c-prefix-spec-kwds-re (c-lang-const c-prefix-spec-kwds-re)) diff --git a/lisp/progmodes/cc-menus.el b/lisp/progmodes/cc-menus.el index f53a7da5186..4e9350de425 100644 --- a/lisp/progmodes/cc-menus.el +++ b/lisp/progmodes/cc-menus.el @@ -108,8 +108,11 @@ A sample value might look like: `\\(_P\\|_PROTO\\)'.") "[^" c-alnum "_:<>~]" ; match any non-identifier char "\\([" c-alpha "_][" c-alnum "_:<>~]*\\)" ; match function name "\\([ \t\n]\\|\\\\\n\\)*(" ; see above, BUT the arg list - "\\([ \t\n]\\|\\\\\n\\)*\\([^ \t\n(*][^)]*\\)?)" ; must not start - "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ; with an asterisk or parentheses + "\\([ \t\n]\\|\\\\\n\\)*" ; must not start + "\\([^ \t\n(*]" ; with an asterisk or parentheses + "[^()]*\\(([^()]*)[^()]*\\)*" ; Maybe function pointer arguments + "\\)?)" + "\\([ \t\n]\\|\\\\\n\\)*[^ \t\n;(]" ) 1) ;; Special case for definitions using phony prototype macros like: ;; `int main _PROTO( (int argc,char *argv[]) )'. diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index 503698f0f7b..5f99cfe0028 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el @@ -145,7 +145,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) (ant "^[ \t]*\\[[^] \n]+\\][ \t]*\\([^: \n]+\\):\\([0-9]+\\):\\(?:\\([0-9]+\\):\\([0-9]+\\):\\([0-9]+\\):\\)?\ -\\( warning\\)?" 1 (2 . 4) (3 . 5) (4)) +\\( warning\\)?" 1 (2 . 4) (3 . 5) (6)) (bash "^\\([^: \n\t]+\\): line \\([0-9]+\\):" 1 2) @@ -523,7 +523,7 @@ you may also want to change `compilation-page-delimiter'.") ;; Command output lines. Recognize `make[n]:' lines too. ("^\\([[:alnum:]_/.+-]+\\)\\(\\[\\([0-9]+\\)\\]\\)?[ \t]*:" (1 font-lock-function-name-face) (3 compilation-line-face nil t)) - (" -\\(?:o[= ]?\\|-\\(?:outfile\\|output\\)[= ]\\)\\(\\S +\\)" . 1) + (" --?o\\(?:utfile\\|utput\\)?[= ]\\(\\S +\\)" . 1) ("^Compilation \\(finished\\).*" (0 '(face nil compilation-message nil help-echo nil mouse-face nil) t) (1 compilation-info-face)) @@ -647,19 +647,19 @@ starting the compilation process.") (defvar compile-history nil) (defface compilation-error - '((t :inherit font-lock-warning-face)) + '((t :inherit error)) "Face used to highlight compiler errors." :group 'compilation :version "22.1") (defface compilation-warning - '((t :inherit font-lock-variable-name-face)) + '((t :inherit warning)) "Face used to highlight compiler warnings." :group 'compilation :version "22.1") (defface compilation-info - '((t :inherit font-lock-type-face)) + '((t :inherit success)) "Face used to highlight compiler information." :group 'compilation :version "22.1") @@ -985,12 +985,15 @@ POS and RES.") (let* ((prev (or (get-text-property (1- prev-pos) 'compilation-message) (get-text-property prev-pos 'compilation-message))) - (prev-struct - (car (nth 2 (car prev))))) + (prev-file-struct + (and prev + (compilation--loc->file-struct + (compilation--message->loc prev))))) + ;; Construct FILE . DIR from that. - (if prev-struct - (setq file (cons (car prev-struct) - (cadr prev-struct)))))) + (if prev-file-struct + (setq file (cons (caar prev-file-struct) + (cadr (car prev-file-struct))))))) (unless file (setq file '("*unknown*"))))) ;; All of these fields are optional, get them only if we have an index, and @@ -2410,7 +2413,7 @@ and overlay is highlighted between MK and END-MK." ;; display the source in another window. (let ((pop-up-windows t)) (pop-to-buffer (marker-buffer mk) 'other-window)) - (pop-to-buffer-same-window (marker-buffer mk))) + (switch-to-buffer (marker-buffer mk))) (unless (eq (goto-char mk) (point)) ;; If narrowing gets in the way of going to the right place, widen. (widen) diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 5561575ea20..709f01444bf 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el @@ -463,9 +463,12 @@ Set up `compilation-exit-message-function' and run `grep-setup-hook'." (set (make-local-variable 'compilation-exit-message-function) (lambda (status code msg) (if (eq status 'exit) - (cond ((zerop code) + ;; This relies on the fact that `compilation-start' + ;; sets buffer-modified to nil before running the command, + ;; so the buffer is still unmodified if there is no output. + (cond ((and (zerop code) (buffer-modified-p)) '("finished (matches found)\n" . "matched")) - ((= code 1) + ((or (= code 1) (not (buffer-modified-p))) '("finished with no matches found\n" . "no match")) (t (cons msg code))) @@ -965,7 +968,9 @@ This command shares argument histories with \\[lgrep] and \\[grep-find]." (unless (and dir (file-directory-p dir) (file-readable-p dir)) (setq dir default-directory)) (if (null files) - (if (not (string= regexp grep-find-command)) + (if (not (string= regexp (if (consp grep-find-command) + (car grep-find-command) + grep-find-command))) (compilation-start regexp 'grep-mode)) (setq dir (file-name-as-directory (expand-file-name dir))) (require 'find-dired) ; for `find-name-arg' @@ -1023,8 +1028,7 @@ This command shares argument histories with \\[lgrep] and \\[grep-find]." (read-from-minibuffer "Confirm: " command nil nil 'grep-find-history)) (add-to-history 'grep-find-history command)) - (let ((default-directory dir) - (process-connection-type nil)) + (let ((default-directory dir)) (compilation-start command 'grep-mode)) ;; Set default-directory if we started rgrep in the *grep* buffer. (if (eq next-error-last-buffer (current-buffer)) diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el index 1bdcb4cfa89..5505e8e94b2 100644 --- a/lisp/progmodes/js.el +++ b/lisp/progmodes/js.el @@ -61,6 +61,7 @@ (defvar inferior-moz-buffer) (defvar moz-repl-name) (defvar ido-cur-list) +(defvar electric-layout-rules) (declare-function ido-mode "ido") (declare-function inferior-moz-process "ext:mozrepl" ()) @@ -507,9 +508,6 @@ getting timeout messages." (defvar js-mode-map (let ((keymap (make-sparse-keymap))) - (mapc (lambda (key) - (define-key keymap key #'js-insert-and-indent)) - '("{" "}" "(" ")" ":" ";" ",")) (define-key keymap [(control ?c) (meta ?:)] #'js-eval) (define-key keymap [(control ?c) (control ?j)] #'js-set-js-context) (define-key keymap [(control meta ?x)] #'js-eval-defun) @@ -525,21 +523,6 @@ getting timeout messages." keymap) "Keymap for `js-mode'.") -(defun js-insert-and-indent (key) - "Run the command bound to KEY, and indent if necessary. -Indentation does not take place if point is in a string or -comment." - (interactive (list (this-command-keys))) - (call-interactively (lookup-key (current-global-map) key)) - (let ((syntax (save-restriction (widen) (syntax-ppss)))) - (when (or (and (not (nth 8 syntax)) - js-auto-indent-flag) - (and (nth 4 syntax) - (eq (current-column) - (1+ (current-indentation))))) - (indent-according-to-mode)))) - - ;;; Syntax table and parsing (defvar js-mode-syntax-table @@ -1653,21 +1636,35 @@ This performs fontification according to `js--class-styles'." js--font-lock-keywords-3) "Font lock keywords for `js-mode'. See `font-lock-keywords'.") -;; XXX: Javascript can continue a regexp literal across lines so long -;; as the newline is escaped with \. Account for that in the regexp -;; below. -(eval-and-compile - (defconst js--regexp-literal - "[=(,:]\\(?:\\s-\\|\n\\)*\\(/\\)\\(?:\\\\.\\|[^/*\\]\\)\\(?:\\\\.\\|[^/\\]\\)*\\(/\\)" - "Regexp matching a JavaScript regular expression literal. -Match groups 1 and 2 are the characters forming the beginning and -end of the literal.")) - -(defconst js-syntax-propertize-function - (syntax-propertize-rules - ;; We want to match regular expressions only at the beginning of - ;; expressions. - (js--regexp-literal (1 "\"") (2 "\"")))) +(defun js-syntax-propertize-regexp (end) + (when (eq (nth 3 (syntax-ppss)) ?/) + ;; A /.../ regexp. + (when (re-search-forward "\\(?:\\=\\|[^\\]\\)\\(?:\\\\\\\\\\)*/" end 'move) + (put-text-property (1- (point)) (point) + 'syntax-table (string-to-syntax "\"/"))))) + +(defun js-syntax-propertize (start end) + ;; Javascript allows immediate regular expression objects, written /.../. + (goto-char start) + (js-syntax-propertize-regexp end) + (funcall + (syntax-propertize-rules + ;; Distinguish /-division from /-regexp chars (and from /-comment-starter). + ("\\(?:^\\|[=([{,:;]\\)\\(?:[ \t]\\)*\\(/\\)[^/*]" + (1 (ignore + (forward-char -1) + (when (or (not (memq (char-after (match-beginning 0)) '(?\s ?\t))) + ;; If the / is at the beginning of line, we have to check + ;; the end of the previous text. + (save-excursion + (goto-char (match-beginning 0)) + (forward-comment (- (point))) + (memq (char-before) + (eval-when-compile (append "=({[,:;" '(nil)))))) + (put-text-property (match-beginning 1) (match-end 1) + 'syntax-table (string-to-syntax "\"/")) + (js-syntax-propertize-regexp end)))))) + (point) end)) ;;; Indentation @@ -3298,7 +3295,7 @@ If one hasn't been set, or if it's stale, prompt for a new one." (set (make-local-variable 'font-lock-defaults) (list js--font-lock-keywords)) (set (make-local-variable 'syntax-propertize-function) - js-syntax-propertize-function) + #'js-syntax-propertize) (set (make-local-variable 'parse-sexp-ignore-comments) t) (set (make-local-variable 'parse-sexp-lookup-properties) t) @@ -3331,6 +3328,11 @@ If one hasn't been set, or if it's stale, prompt for a new one." c-comment-start-regexp "/[*/]\\|\\s!" comment-start-skip "\\(//+\\|/\\*+\\)\\s *") + (set (make-local-variable 'electric-indent-chars) + (append "{}():;," electric-indent-chars)) + (set (make-local-variable 'electric-layout-rules) + '((?\; . after) (?\{ . after) (?\} . before))) + (let ((c-buffer-is-cc-mode t)) ;; FIXME: These are normally set by `c-basic-common-init'. Should ;; we call it instead? (Bug#6071) diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 4d2f15c69d8..3f923f496b9 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -296,7 +296,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." :filter (lambda (&rest junk) (abbrev-table-menu python-mode-abbrev-table))) "-" - ["Start interpreter" python-shell + ["Start interpreter" run-python :help "Run `inferior' Python in separate buffer"] ["Import/reload file" python-load-file :help "Load into inferior Python session"] @@ -328,14 +328,6 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." ;; eric has items including: (un)indent, (un)comment, restart script, ;; run script, debug script; also things for profiling, unit testing. -(defvar python-shell-map - (let ((map (copy-keymap comint-mode-map))) - (define-key map [tab] 'tab-to-tab-stop) - (define-key map "\C-c-" 'py-up-exception) - (define-key map "\C-c=" 'py-down-exception) - map) - "Keymap used in *Python* shell buffers.") - (defvar python-mode-syntax-table (let ((table (make-syntax-table))) ;; Give punctuation syntax to ASCII that normally has symbol @@ -1345,7 +1337,7 @@ local value.") (define-key map "\C-c\C-l" 'python-load-file) (define-key map "\C-c\C-v" 'python-check) ;; Note that we _can_ still use these commands which send to the - ;; Python process even at the prompt iff we have a normal prompt, + ;; Python process even at the prompt if we have a normal prompt, ;; i.e. '>>> ' and not '... '. See the comment before ;; python-send-region. Fixme: uncomment these if we address that. diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el index 4151e2bb79a..470b309434c 100644 --- a/lisp/progmodes/scheme.el +++ b/lisp/progmodes/scheme.el @@ -55,24 +55,24 @@ (defvar scheme-mode-syntax-table (let ((st (make-syntax-table)) (i 0)) - - ;; Default is atom-constituent. - (while (< i 256) + ;; Symbol constituents + ;; We used to treat chars 128-256 as symbol-constituent, but they + ;; should be valid word constituents (Bug#8843). Note that valid + ;; identifier characters are Scheme-implementation dependent. + (while (< i ?0) (modify-syntax-entry i "_ " st) (setq i (1+ i))) - - ;; Word components. - (setq i ?0) - (while (<= i ?9) - (modify-syntax-entry i "w " st) + (setq i (1+ ?9)) + (while (< i ?A) + (modify-syntax-entry i "_ " st) (setq i (1+ i))) - (setq i ?A) - (while (<= i ?Z) - (modify-syntax-entry i "w " st) + (setq i (1+ ?Z)) + (while (< i ?a) + (modify-syntax-entry i "_ " st) (setq i (1+ i))) - (setq i ?a) - (while (<= i ?z) - (modify-syntax-entry i "w " st) + (setq i (1+ ?z)) + (while (< i 128) + (modify-syntax-entry i "_ " st) (setq i (1+ i))) ;; Whitespace diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index 258f9be9237..7b949134c6c 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -460,6 +460,7 @@ This is buffer-local in every such buffer.") (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) @@ -1028,45 +1029,45 @@ subshells can nest." (defun sh-font-lock-paren (start) (unless (nth 8 (syntax-ppss)) - (save-excursion - (goto-char start) - ;; Skip through all patterns - (while - (progn + (save-excursion + (goto-char start) + ;; Skip through all patterns + (while + (progn (while (progn - (forward-comment (- (point-max))) + (forward-comment (- (point-max))) (when (and (eolp) (sh-is-quoted-p (point))) (forward-char -1) t))) - ;; Skip through one pattern - (while - (or (/= 0 (skip-syntax-backward "w_")) + ;; Skip through one pattern + (while + (or (/= 0 (skip-syntax-backward "w_")) (/= 0 (skip-chars-backward "-$=?[]*@/\\\\")) - (and (sh-is-quoted-p (1- (point))) - (goto-char (- (point) 2))) + (and (sh-is-quoted-p (1- (point))) + (goto-char (- (point) 2))) (when (memq (char-before) '(?\" ?\' ?\})) - (condition-case nil (progn (backward-sexp 1) t) - (error nil))))) - ;; Patterns can be preceded by an open-paren (Bug#1320). - (if (eq (char-before (point)) ?\() - (backward-char 1)) - (while (progn - (forward-comment (- (point-max))) - ;; Maybe we've bumped into an escaped newline. - (sh-is-quoted-p (point))) - (backward-char 1)) - (when (eq (char-before) ?|) - (backward-char 1) t))) - (when (progn (backward-char 2) - (if (> start (line-end-position)) - (put-text-property (point) (1+ start) - 'syntax-multiline t)) - ;; FIXME: The `in' may just be a random argument to - ;; a normal command rather than the real `in' keyword. - ;; I.e. we should look back to try and find the - ;; corresponding `case'. - (and (looking-at ";[;&]\\|in") + (condition-case nil (progn (backward-sexp 1) t) + (error nil))))) + ;; Patterns can be preceded by an open-paren (Bug#1320). + (if (eq (char-before (point)) ?\() + (backward-char 1)) + (while (progn + (forward-comment (- (point-max))) + ;; Maybe we've bumped into an escaped newline. + (sh-is-quoted-p (point))) + (backward-char 1)) + (when (eq (char-before) ?|) + (backward-char 1) t))) + (when (progn (backward-char 2) + (if (> start (line-end-position)) + (put-text-property (point) (1+ start) + 'syntax-multiline t)) + ;; FIXME: The `in' may just be a random argument to + ;; a normal command rather than the real `in' keyword. + ;; I.e. we should look back to try and find the + ;; corresponding `case'. + (and (looking-at ";[;&]\\|\\_<in") ;; ";; esac )" is a case that looks like a case-pattern ;; but it's really just a close paren after a case ;; statement. I.e. if we skipped over `esac' just now, @@ -3659,6 +3660,7 @@ The document is bounded by `sh-here-document-word'." (save-excursion (backward-char 2) (sh-quoted-p)) + (nth 8 (syntax-ppss)) (let ((tabs (if (string-match "\\`-" sh-here-document-word) (make-string (/ (current-indentation) tab-width) ?\t) "")) |