aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorJoakim Verona2010-10-18 22:05:07 +0200
committerJoakim Verona2010-10-18 22:05:07 +0200
commit13cfe8df462ab8da9f0028e16cc84dcaceaca3d1 (patch)
tree723f254768f9e503504ab4c8b68801f80a56591a /lisp/progmodes
parent35f4b80a934b299b3b18e62f5db44f64c240e65b (diff)
parente48eb34332dc91de823314090451459ba2ffacbf (diff)
downloademacs-13cfe8df462ab8da9f0028e16cc84dcaceaca3d1.tar.gz
emacs-13cfe8df462ab8da9f0028e16cc84dcaceaca3d1.zip
merge from upstream
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/antlr-mode.el2
-rw-r--r--lisp/progmodes/cc-engine.el240
-rw-r--r--lisp/progmodes/cc-fonts.el299
-rw-r--r--lisp/progmodes/cc-langs.el15
-rw-r--r--lisp/progmodes/cc-mode.el10
-rw-r--r--lisp/progmodes/cc-styles.el3
-rw-r--r--lisp/progmodes/compile.el3
-rw-r--r--lisp/progmodes/cperl-mode.el17
-rw-r--r--lisp/progmodes/etags.el6
-rw-r--r--lisp/progmodes/fortran.el69
-rw-r--r--lisp/progmodes/gdb-mi.el4
-rw-r--r--lisp/progmodes/gud.el7
-rw-r--r--lisp/progmodes/inf-lisp.el24
-rw-r--r--lisp/progmodes/js.el2
-rw-r--r--lisp/progmodes/ld-script.el22
-rw-r--r--lisp/progmodes/mixal-mode.el5
-rw-r--r--lisp/progmodes/modula2.el8
-rw-r--r--lisp/progmodes/octave-mod.el5
-rw-r--r--lisp/progmodes/pascal.el110
-rw-r--r--lisp/progmodes/prolog.el39
-rw-r--r--lisp/progmodes/sql.el608
21 files changed, 933 insertions, 565 deletions
diff --git a/lisp/progmodes/antlr-mode.el b/lisp/progmodes/antlr-mode.el
index 9b24ac7a1f4..742bcf726eb 100644
--- a/lisp/progmodes/antlr-mode.el
+++ b/lisp/progmodes/antlr-mode.el
@@ -951,7 +951,7 @@ group. The string matched by the first group is highlighted with
951 (3 antlr-keyword-face) 951 (3 antlr-keyword-face)
952 (4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser")) 952 (4 (if (member (match-string 4) '("Lexer" "Parser" "TreeParser"))
953 antlr-keyword-face 953 antlr-keyword-face
954 type-face))) 954 font-lock-type-face)))
955 (,(lambda (limit) 955 (,(lambda (limit)
956 (antlr-re-search-forward 956 (antlr-re-search-forward
957 "\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>" 957 "\\<\\(header\\|options\\|tokens\\|exception\\|catch\\|returns\\)\\>"
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index e389007065a..18010407eda 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -5449,49 +5449,47 @@ comment at the start of cc-engine.el for more info."
5449 (forward-char) 5449 (forward-char)
5450 5450
5451 (unless (looking-at c-<-op-cont-regexp) 5451 (unless (looking-at c-<-op-cont-regexp)
5452 (while (and 5452 (while (and
5453 (progn 5453 (progn
5454 (c-forward-syntactic-ws) 5454 (c-forward-syntactic-ws)
5455 (let ((orig-record-found-types c-record-found-types)) 5455 (let ((orig-record-found-types c-record-found-types))
5456 (when (or (and c-record-type-identifiers all-types) 5456 (when (or (and c-record-type-identifiers all-types)
5457 (c-major-mode-is 'java-mode)) 5457 (c-major-mode-is 'java-mode))
5458 ;; All encountered identifiers are types, so set the 5458 ;; All encountered identifiers are types, so set the
5459 ;; promote flag and parse the type. 5459 ;; promote flag and parse the type.
5460 (progn 5460 (progn
5461 (c-forward-syntactic-ws) 5461 (c-forward-syntactic-ws)
5462 (if (looking-at "\\?") 5462 (if (looking-at "\\?")
5463 (forward-char) 5463 (forward-char)
5464 (when (looking-at c-identifier-start) 5464 (when (looking-at c-identifier-start)
5465 (let ((c-promote-possible-types t) 5465 (let ((c-promote-possible-types t)
5466 (c-record-found-types t)) 5466 (c-record-found-types t))
5467 (c-forward-type)))) 5467 (c-forward-type))))
5468 5468
5469 (c-forward-syntactic-ws) 5469 (c-forward-syntactic-ws)
5470 5470
5471 (when (or (looking-at "extends") 5471 (when (or (looking-at "extends")
5472 (looking-at "super")) 5472 (looking-at "super"))
5473 (forward-word) 5473 (forward-word)
5474 (c-forward-syntactic-ws) 5474 (c-forward-syntactic-ws)
5475 (let ((c-promote-possible-types t) 5475 (let ((c-promote-possible-types t)
5476 (c-record-found-types t)) 5476 (c-record-found-types t))
5477 (c-forward-type) 5477 (c-forward-type)
5478 (c-forward-syntactic-ws)))))) 5478 (c-forward-syntactic-ws))))))
5479
5480 (setq pos (point))
5481
5482 (or
5483 ;; Note: These regexps exploit the match order in \| so
5484 ;; that "<>" is matched by "<" rather than "[^>:-]>".
5485 (c-syntactic-re-search-forward
5486 ;; Stop on ',', '|', '&', '+' and '-' to catch
5487 ;; common binary operators that could be between
5488 ;; two comparison expressions "a<b" and "c>d".
5489 "[<;{},|+&-]\\|[>)]"
5490 nil t t)
5491 t))
5492 5479
5493 (cond 5480 (setq pos (point))
5494 ((eq (char-before) ?>) 5481
5482 ;; Note: These regexps exploit the match order in \| so
5483 ;; that "<>" is matched by "<" rather than "[^>:-]>".
5484 (c-syntactic-re-search-forward
5485 ;; Stop on ',', '|', '&', '+' and '-' to catch
5486 ;; common binary operators that could be between
5487 ;; two comparison expressions "a<b" and "c>d".
5488 "[<;{},|+&-]\\|[>)]"
5489 nil t t))
5490
5491 (cond
5492 ((eq (char-before) ?>)
5495 ;; Either an operator starting with '>' or the end of 5493 ;; Either an operator starting with '>' or the end of
5496 ;; the angle bracket arglist. 5494 ;; the angle bracket arglist.
5497 5495
@@ -5532,14 +5530,14 @@ comment at the start of cc-engine.el for more info."
5532 (when (or (setq keyword-match 5530 (when (or (setq keyword-match
5533 (looking-at c-opt-<>-sexp-key)) 5531 (looking-at c-opt-<>-sexp-key))
5534 (not (looking-at c-keywords-regexp))) 5532 (not (looking-at c-keywords-regexp)))
5535 (setq id-start (point)))) 5533 (setq id-start (point))))
5536 5534
5537 (setq subres 5535 (setq subres
5538 (let ((c-promote-possible-types t) 5536 (let ((c-promote-possible-types t)
5539 (c-record-found-types t)) 5537 (c-record-found-types t))
5540 (c-forward-<>-arglist-recur 5538 (c-forward-<>-arglist-recur
5541 (and keyword-match 5539 (and keyword-match
5542 (c-keyword-member 5540 (c-keyword-member
5543 (c-keyword-sym (match-string 1)) 5541 (c-keyword-sym (match-string 1))
5544 'c-<>-type-kwds))))) 5542 'c-<>-type-kwds)))))
5545 ))) 5543 )))
@@ -5560,16 +5558,16 @@ comment at the start of cc-engine.el for more info."
5560 (c-forward-syntactic-ws) 5558 (c-forward-syntactic-ws)
5561 (looking-at c-opt-identifier-concat-key))) 5559 (looking-at c-opt-identifier-concat-key)))
5562 (c-record-ref-id (cons id-start id-end)) 5560 (c-record-ref-id (cons id-start id-end))
5563 (c-record-type-id (cons id-start id-end)))))) 5561 (c-record-type-id (cons id-start id-end))))))
5564 t) 5562 t)
5565 5563
5566 ((and (not c-restricted-<>-arglists) 5564 ((and (not c-restricted-<>-arglists)
5567 (or (and (eq (char-before) ?&) 5565 (or (and (eq (char-before) ?&)
5568 (not (eq (char-after) ?&))) 5566 (not (eq (char-after) ?&)))
5569 (eq (char-before) ?,))) 5567 (eq (char-before) ?,)))
5570 ;; Just another argument. Record the position. The 5568 ;; Just another argument. Record the position. The
5571 ;; type check stuff that made us stop at it is at 5569 ;; type check stuff that made us stop at it is at
5572 ;; the top of the loop. 5570 ;; the top of the loop.
5573 (setq arg-start-pos (cons (point) arg-start-pos))) 5571 (setq arg-start-pos (cons (point) arg-start-pos)))
5574 5572
5575 (t 5573 (t
@@ -5648,17 +5646,23 @@ comment at the start of cc-engine.el for more info."
5648 5646
5649(defun c-forward-name () 5647(defun c-forward-name ()
5650 ;; Move forward over a complete name if at the beginning of one, 5648 ;; Move forward over a complete name if at the beginning of one,
5651 ;; stopping at the next following token. If the point is not at 5649 ;; stopping at the next following token. A keyword, as such,
5652 ;; something that are recognized as name then it stays put. A name 5650 ;; doesn't count as a name. If the point is not at something that
5653 ;; could be something as simple as "foo" in C or something as 5651 ;; is recognized as a name then it stays put.
5652 ;;
5653 ;; A name could be something as simple as "foo" in C or something as
5654 ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> :: 5654 ;; complex as "X<Y<class A<int>::B, BIT_MAX >> b>, ::operator<> ::
5655 ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short 5655 ;; Z<(a>b)> :: operator const X<&foo>::T Q::G<unsigned short
5656 ;; int>::*volatile const" in C++ (this function is actually little 5656 ;; int>::*volatile const" in C++ (this function is actually little
5657 ;; more than a `looking-at' call in all modes except those that, 5657 ;; more than a `looking-at' call in all modes except those that,
5658 ;; like C++, have `c-recognize-<>-arglists' set). Return nil if no 5658 ;; like C++, have `c-recognize-<>-arglists' set).
5659 ;; name is found, 'template if it's an identifier ending with an 5659 ;;
5660 ;; angle bracket arglist, 'operator of it's an operator identifier, 5660 ;; Return
5661 ;; or t if it's some other kind of name. 5661 ;; o - nil if no name is found;
5662 ;; o - 'template if it's an identifier ending with an angle bracket
5663 ;; arglist;
5664 ;; o - 'operator of it's an operator identifier;
5665 ;; o - t if it's some other kind of name.
5662 ;; 5666 ;;
5663 ;; This function records identifier ranges on 5667 ;; This function records identifier ranges on
5664 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if 5668 ;; `c-record-type-identifiers' and `c-record-ref-identifiers' if
@@ -5810,16 +5814,28 @@ comment at the start of cc-engine.el for more info."
5810 (goto-char pos) 5814 (goto-char pos)
5811 res)) 5815 res))
5812 5816
5813(defun c-forward-type () 5817(defun c-forward-type (&optional brace-block-too)
5814 ;; Move forward over a type spec if at the beginning of one, 5818 ;; Move forward over a type spec if at the beginning of one,
5815 ;; stopping at the next following token. Return t if it's a known 5819 ;; stopping at the next following token. The keyword "typedef"
5816 ;; type that can't be a name or other expression, 'known if it's an 5820 ;; isn't part of a type spec here.
5817 ;; otherwise known type (according to `*-font-lock-extra-types'), 5821 ;;
5818 ;; 'prefix if it's a known prefix of a type, 'found if it's a type 5822 ;; BRACE-BLOCK-TOO, when non-nil, means move over the brace block in
5819 ;; that matches one in `c-found-types', 'maybe if it's an identfier 5823 ;; constructs like "struct foo {...} bar ;" or "struct {...} bar;".
5820 ;; that might be a type, or nil if it can't be a type (the point 5824 ;; The current (2009-03-10) intention is to convert all uses of
5821 ;; isn't moved then). The point is assumed to be at the beginning 5825 ;; `c-forward-type' to call with this parameter set, then to
5822 ;; of a token. 5826 ;; eliminate it.
5827 ;;
5828 ;; Return
5829 ;; o - t if it's a known type that can't be a name or other
5830 ;; expression;
5831 ;; o - 'known if it's an otherwise known type (according to
5832 ;; `*-font-lock-extra-types');
5833 ;; o - 'prefix if it's a known prefix of a type;
5834 ;; o - 'found if it's a type that matches one in `c-found-types';
5835 ;; o - 'maybe if it's an identfier that might be a type; or
5836 ;; o - nil if it can't be a type (the point isn't moved then).
5837 ;;
5838 ;; The point is assumed to be at the beginning of a token.
5823 ;; 5839 ;;
5824 ;; Note that this function doesn't skip past the brace definition 5840 ;; Note that this function doesn't skip past the brace definition
5825 ;; that might be considered part of the type, e.g. 5841 ;; that might be considered part of the type, e.g.
@@ -5838,32 +5854,39 @@ comment at the start of cc-engine.el for more info."
5838 5854
5839 ;; Skip leading type modifiers. If any are found we know it's a 5855 ;; Skip leading type modifiers. If any are found we know it's a
5840 ;; prefix of a type. 5856 ;; prefix of a type.
5841 (when c-opt-type-modifier-key 5857 (when c-opt-type-modifier-key ; e.g. "const" "volatile", but NOT "typedef"
5842 (while (looking-at c-opt-type-modifier-key) 5858 (while (looking-at c-opt-type-modifier-key)
5843 (goto-char (match-end 1)) 5859 (goto-char (match-end 1))
5844 (c-forward-syntactic-ws) 5860 (c-forward-syntactic-ws)
5845 (setq res 'prefix))) 5861 (setq res 'prefix)))
5846 5862
5847 (cond 5863 (cond
5848 ((looking-at c-type-prefix-key) 5864 ((looking-at c-type-prefix-key) ; e.g. "struct", "class", but NOT
5849 ;; Looking at a keyword that prefixes a type identifier, 5865 ; "typedef".
5850 ;; e.g. "class".
5851 (goto-char (match-end 1)) 5866 (goto-char (match-end 1))
5852 (c-forward-syntactic-ws) 5867 (c-forward-syntactic-ws)
5853 (setq pos (point)) 5868 (setq pos (point))
5854 (if (memq (setq name-res (c-forward-name)) '(t template)) 5869
5855 (progn 5870 (setq name-res (c-forward-name))
5856 (when (eq name-res t) 5871 (setq res (not (null name-res)))
5857 ;; In many languages the name can be used without the 5872 (when (eq name-res t)
5858 ;; prefix, so we add it to `c-found-types'. 5873 ;; In many languages the name can be used without the
5859 (c-add-type pos (point)) 5874 ;; prefix, so we add it to `c-found-types'.
5860 (when (and c-record-type-identifiers 5875 (c-add-type pos (point))
5861 c-last-identifier-range) 5876 (when (and c-record-type-identifiers
5862 (c-record-type-id c-last-identifier-range))) 5877 c-last-identifier-range)
5863 (setq res t)) 5878 (c-record-type-id c-last-identifier-range)))
5864 ;; Invalid syntax. 5879 (when (and brace-block-too
5865 (goto-char start) 5880 (memq res '(t nil))
5866 (setq res nil))) 5881 (eq (char-after) ?\{)
5882 (save-excursion
5883 (c-safe
5884 (progn (c-forward-sexp)
5885 (c-forward-syntactic-ws)
5886 (setq pos (point))))))
5887 (goto-char pos)
5888 (setq res t))
5889 (unless res (goto-char start))) ; invalid syntax
5867 5890
5868 ((progn 5891 ((progn
5869 (setq pos nil) 5892 (setq pos nil)
@@ -5953,14 +5976,13 @@ comment at the start of cc-engine.el for more info."
5953 (setq res nil))))) 5976 (setq res nil)))))
5954 5977
5955 (when res 5978 (when res
5956 ;; Skip trailing type modifiers. If any are found we know it's 5979 ;; Skip trailing type modifiers. If any are found we know it's
5957 ;; a type. 5980 ;; a type.
5958 (when c-opt-type-modifier-key 5981 (when c-opt-type-modifier-key
5959 (while (looking-at c-opt-type-modifier-key) 5982 (while (looking-at c-opt-type-modifier-key) ; e.g. "const", "volatile"
5960 (goto-char (match-end 1)) 5983 (goto-char (match-end 1))
5961 (c-forward-syntactic-ws) 5984 (c-forward-syntactic-ws)
5962 (setq res t))) 5985 (setq res t)))
5963
5964 ;; Step over any type suffix operator. Do not let the existence 5986 ;; Step over any type suffix operator. Do not let the existence
5965 ;; of these alter the classification of the found type, since 5987 ;; of these alter the classification of the found type, since
5966 ;; these operators typically are allowed in normal expressions 5988 ;; these operators typically are allowed in normal expressions
@@ -5970,7 +5992,7 @@ comment at the start of cc-engine.el for more info."
5970 (goto-char (match-end 1)) 5992 (goto-char (match-end 1))
5971 (c-forward-syntactic-ws))) 5993 (c-forward-syntactic-ws)))
5972 5994
5973 (when c-opt-type-concat-key 5995 (when c-opt-type-concat-key ; Only/mainly for pike.
5974 ;; Look for a trailing operator that concatenates the type 5996 ;; Look for a trailing operator that concatenates the type
5975 ;; with a following one, and if so step past that one through 5997 ;; with a following one, and if so step past that one through
5976 ;; a recursive call. Note that we don't record concatenated 5998 ;; a recursive call. Note that we don't record concatenated
@@ -6121,11 +6143,15 @@ comment at the start of cc-engine.el for more info."
6121 ;; car ^ ^ point 6143 ;; car ^ ^ point
6122 ;; Foo::Foo (int b) : Base (b) {} 6144 ;; Foo::Foo (int b) : Base (b) {}
6123 ;; car ^ ^ point 6145 ;; car ^ ^ point
6124 ;; 6146 ;;
6125 ;; The cdr of the return value is non-nil iff a `c-typedef-decl-kwds' 6147 ;; The cdr of the return value is non-nil when a
6126 ;; specifier (e.g. class, struct, enum, typedef) is found in the 6148 ;; `c-typedef-decl-kwds' specifier is found in the declaration.
6127 ;; declaration, i.e. the declared identifier(s) are types. 6149 ;; Specifically it is a dotted pair (A . B) where B is t when a
6128 ;; 6150 ;; `c-typedef-kwds' ("typedef") is present, and A is t when some
6151 ;; other `c-typedef-decl-kwds' (e.g. class, struct, enum)
6152 ;; specifier is present. I.e., (some of) the declared
6153 ;; identifier(s) are types.
6154 ;;
6129 ;; If a cast is parsed: 6155 ;; If a cast is parsed:
6130 ;; 6156 ;;
6131 ;; The point is left at the first token after the closing paren of 6157 ;; The point is left at the first token after the closing paren of
@@ -6183,9 +6209,11 @@ comment at the start of cc-engine.el for more info."
6183 ;; If `backup-at-type' is nil then the other variables have 6209 ;; If `backup-at-type' is nil then the other variables have
6184 ;; undefined values. 6210 ;; undefined values.
6185 backup-at-type backup-type-start backup-id-start 6211 backup-at-type backup-type-start backup-id-start
6186 ;; Set if we've found a specifier that makes the defined 6212 ;; Set if we've found a specifier (apart from "typedef") that makes
6187 ;; identifier(s) types. 6213 ;; the defined identifier(s) types.
6188 at-type-decl 6214 at-type-decl
6215 ;; Set if we've a "typedef" keyword.
6216 at-typedef
6189 ;; Set if we've found a specifier that can start a declaration 6217 ;; Set if we've found a specifier that can start a declaration
6190 ;; where there's no type. 6218 ;; where there's no type.
6191 maybe-typeless 6219 maybe-typeless
@@ -6225,12 +6253,14 @@ comment at the start of cc-engine.el for more info."
6225 6253
6226 ;; Look for a specifier keyword clause. 6254 ;; Look for a specifier keyword clause.
6227 (when (looking-at c-prefix-spec-kwds-re) 6255 (when (looking-at c-prefix-spec-kwds-re)
6256 (if (looking-at c-typedef-key)
6257 (setq at-typedef t))
6228 (setq kwd-sym (c-keyword-sym (match-string 1))) 6258 (setq kwd-sym (c-keyword-sym (match-string 1)))
6229 (save-excursion 6259 (save-excursion
6230 (c-forward-keyword-clause 1) 6260 (c-forward-keyword-clause 1)
6231 (setq kwd-clause-end (point)))) 6261 (setq kwd-clause-end (point))))
6232 6262
6233 (when (setq found-type (c-forward-type)) 6263 (when (setq found-type (c-forward-type t)) ; brace-block-too
6234 ;; Found a known or possible type or a prefix of a known type. 6264 ;; Found a known or possible type or a prefix of a known type.
6235 6265
6236 (when at-type 6266 (when at-type
@@ -6295,6 +6325,8 @@ comment at the start of cc-engine.el for more info."
6295 (setq backup-maybe-typeless t))) 6325 (setq backup-maybe-typeless t)))
6296 6326
6297 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds) 6327 (when (c-keyword-member kwd-sym 'c-typedef-decl-kwds)
6328 ;; This test only happens after we've scanned a type.
6329 ;; So, with valid syntax, kwd-sym can't be 'typedef.
6298 (setq at-type-decl t)) 6330 (setq at-type-decl t))
6299 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds) 6331 (when (c-keyword-member kwd-sym 'c-typeless-decl-kwds)
6300 (setq maybe-typeless t)) 6332 (setq maybe-typeless t))
@@ -6894,7 +6926,9 @@ comment at the start of cc-engine.el for more info."
6894 (goto-char type-start) 6926 (goto-char type-start)
6895 (c-forward-type)))) 6927 (c-forward-type))))
6896 6928
6897 (cons id-start at-type-decl)) 6929 (cons id-start
6930 (and (or at-type-decl at-typedef)
6931 (cons at-type-decl at-typedef))))
6898 6932
6899 (t 6933 (t
6900 ;; False alarm. Restore the recorded ranges. 6934 ;; False alarm. Restore the recorded ranges.
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 72703b9a5e4..a99876a6bfc 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -289,7 +289,7 @@
289 ;; bit of the overhead compared to a real matcher. The main reason 289 ;; bit of the overhead compared to a real matcher. The main reason
290 ;; is however to pass the real search limit to the anchored 290 ;; is however to pass the real search limit to the anchored
291 ;; matcher(s), since most (if not all) font-lock implementations 291 ;; matcher(s), since most (if not all) font-lock implementations
292 ;; arbitrarily limits anchored matchers to the same line, and also 292 ;; arbitrarily limit anchored matchers to the same line, and also
293 ;; to insulate against various other irritating differences between 293 ;; to insulate against various other irritating differences between
294 ;; the different (X)Emacs font-lock packages. 294 ;; the different (X)Emacs font-lock packages.
295 ;; 295 ;;
@@ -310,7 +310,7 @@
310 ;; covered by the font-lock context.) 310 ;; covered by the font-lock context.)
311 311
312 ;; Note: Replace `byte-compile' with `eval' to debug the generated 312 ;; Note: Replace `byte-compile' with `eval' to debug the generated
313 ;; lambda easier. 313 ;; lambda more easily.
314 (byte-compile 314 (byte-compile
315 `(lambda (limit) 315 `(lambda (limit)
316 (let (;; The font-lock package in Emacs is known to clobber 316 (let (;; The font-lock package in Emacs is known to clobber
@@ -721,16 +721,26 @@ casts and declarations are fontified. Used on level 2 and higher."
721 721
722 ;; Clear the list of found types if we start from the start of the 722 ;; Clear the list of found types if we start from the start of the
723 ;; buffer, to make it easier to get rid of misspelled types and 723 ;; buffer, to make it easier to get rid of misspelled types and
724 ;; variables that has gotten recognized as types in malformed code. 724 ;; variables that have gotten recognized as types in malformed code.
725 (when (bobp) 725 (when (bobp)
726 (c-clear-found-types)) 726 (c-clear-found-types))
727 727
728 ;; Clear the c-type char properties in the region to recalculate 728 ;; Clear the c-type char properties which mark the region, to recalculate
729 ;; them properly. This is necessary e.g. to handle constructs that 729 ;; them properly. The most interesting properties are those put on the
730 ;; might been required as declarations temporarily during editing. 730 ;; closest token before the region.
731 ;; The interesting properties are anyway those put on the closest 731 (save-excursion
732 ;; token before the region. 732 (let ((pos (point)))
733 (c-clear-char-properties (point) limit 'c-type) 733 (c-backward-syntactic-ws)
734 (c-clear-char-properties
735 (if (and (not (bobp))
736 (memq (c-get-char-property (1- (point)) 'c-type)
737 '(c-decl-arg-start
738 c-decl-end
739 c-decl-id-start
740 c-decl-type-start)))
741 (1- (point))
742 pos)
743 limit 'c-type)))
734 744
735 ;; Update `c-state-cache' to the beginning of the region. This will 745 ;; Update `c-state-cache' to the beginning of the region. This will
736 ;; make `c-beginning-of-syntax' go faster when it's used later on, 746 ;; make `c-beginning-of-syntax' go faster when it's used later on,
@@ -739,6 +749,8 @@ casts and declarations are fontified. Used on level 2 and higher."
739 749
740 ;; Check if the fontified region starts inside a declarator list so 750 ;; Check if the fontified region starts inside a declarator list so
741 ;; that `c-font-lock-declarators' should be called at the start. 751 ;; that `c-font-lock-declarators' should be called at the start.
752 ;; The declared identifiers are font-locked correctly as types, if
753 ;; that is what they are.
742 (let ((prop (save-excursion 754 (let ((prop (save-excursion
743 (c-backward-syntactic-ws) 755 (c-backward-syntactic-ws)
744 (unless (bobp) 756 (unless (bobp)
@@ -831,12 +843,19 @@ casts and declarations are fontified. Used on level 2 and higher."
831 nil) 843 nil)
832 844
833(defun c-font-lock-declarators (limit list types) 845(defun c-font-lock-declarators (limit list types)
834 ;; Assuming the point is at the start of a declarator in a 846 ;; Assuming the point is at the start of a declarator in a declaration,
835 ;; declaration, fontify it. If LIST is non-nil, fontify also all 847 ;; fontify the identifier it declares. (If TYPES is set, it does this via
836 ;; following declarators in a comma separated list (e.g. "foo" and 848 ;; the macro `c-fontify-types-and-refs'.)
837 ;; "bar" in "int foo = 17, bar;"). Stop at LIMIT. If TYPES is 849 ;;
838 ;; non-nil, fontify all identifiers as types. Nil is always 850 ;; If LIST is non-nil, also fontify the ids in any following declarators in
839 ;; returned. 851 ;; a comma separated list (e.g. "foo" and "*bar" in "int foo = 17, *bar;");
852 ;; additionally, mark the commas with c-type property 'c-decl-id-start or
853 ;; 'c-decl-type-start (according to TYPES). Stop at LIMIT.
854 ;;
855 ;; If TYPES is non-nil, fontify all identifiers as types.
856 ;;
857 ;; Nil is always returned. The function leaves point at the delimiter after
858 ;; the last declarator it processes.
840 ;; 859 ;;
841 ;; This function might do hidden buffer changes. 860 ;; This function might do hidden buffer changes.
842 861
@@ -848,18 +867,31 @@ casts and declarations are fontified. Used on level 2 and higher."
848 c-last-identifier-range 867 c-last-identifier-range
849 (separator-prop (if types 'c-decl-type-start 'c-decl-id-start))) 868 (separator-prop (if types 'c-decl-type-start 'c-decl-id-start)))
850 869
851 (while (and 870 ;; The following `while' fontifies a single declarator id each time round.
871 ;; It loops only when LIST is non-nil.
872 (while
873 ;; Inside the following "condition form", we move forward over the
874 ;; declarator's identifier up as far as any opening bracket (for array
875 ;; size) or paren (for parameters of function-type) or brace (for
876 ;; array/struct initialisation) or "=" or terminating delimiter
877 ;; (e.g. "," or ";" or "}").
878 (and
852 pos 879 pos
853 (< (point) limit) 880 (< (point) limit)
854 881
882 ;; The following form moves forward over the declarator's
883 ;; identifier (and what precedes it), returning t. If there
884 ;; wasn't one, it returns nil, terminating the `while'.
855 (let (got-identifier) 885 (let (got-identifier)
856 (setq paren-depth 0) 886 (setq paren-depth 0)
857 ;; Skip over type decl prefix operators. (Note similar 887 ;; Skip over type decl prefix operators, one for each iteration
858 ;; code in `c-forward-decl-or-cast-1'.) 888 ;; of the while. These are, e.g. "*" in "int *foo" or "(" and
889 ;; "*" in "int (*foo) (void)" (Note similar code in
890 ;; `c-forward-decl-or-cast-1'.)
859 (while (and (looking-at c-type-decl-prefix-key) 891 (while (and (looking-at c-type-decl-prefix-key)
860 (if (and (c-major-mode-is 'c++-mode) 892 (if (and (c-major-mode-is 'c++-mode)
861 (match-beginning 2)) 893 (match-beginning 3))
862 ;; If the second submatch matches in C++ then 894 ;; If the third submatch matches in C++ then
863 ;; we're looking at an identifier that's a 895 ;; we're looking at an identifier that's a
864 ;; prefix only if it specifies a member pointer. 896 ;; prefix only if it specifies a member pointer.
865 (progn 897 (progn
@@ -882,7 +914,7 @@ casts and declarations are fontified. Used on level 2 and higher."
882 (goto-char (match-end 1))) 914 (goto-char (match-end 1)))
883 (c-forward-syntactic-ws)) 915 (c-forward-syntactic-ws))
884 916
885 ;; If we didn't pass the identifier above already, do it now. 917 ;; If we haven't passed the identifier already, do it now.
886 (unless got-identifier 918 (unless got-identifier
887 (setq id-start (point)) 919 (setq id-start (point))
888 (c-forward-name)) 920 (c-forward-name))
@@ -890,12 +922,14 @@ casts and declarations are fontified. Used on level 2 and higher."
890 922
891 (/= id-end pos)) 923 (/= id-end pos))
892 924
893 ;; Skip out of the parens surrounding the identifier. 925 ;; Skip out of the parens surrounding the identifier. If closing
926 ;; parens are missing, this form returns nil.
894 (or (= paren-depth 0) 927 (or (= paren-depth 0)
895 (c-safe (goto-char (scan-lists (point) 1 paren-depth)))) 928 (c-safe (goto-char (scan-lists (point) 1 paren-depth))))
896 929
897 (<= (point) limit) 930 (<= (point) limit)
898 931
932 ;; Skip over any trailing bit, such as "__attribute__".
899 (progn 933 (progn
900 (when (looking-at c-decl-hangon-key) 934 (when (looking-at c-decl-hangon-key)
901 (c-forward-keyword-clause 1)) 935 (c-forward-keyword-clause 1))
@@ -936,7 +970,7 @@ casts and declarations are fontified. Used on level 2 and higher."
936 id-face))) 970 id-face)))
937 971
938 (goto-char next-pos) 972 (goto-char next-pos)
939 (setq pos nil) 973 (setq pos nil) ; So as to terminate the enclosing `while' form.
940 (when list 974 (when list
941 ;; Jump past any initializer or function prototype to see if 975 ;; Jump past any initializer or function prototype to see if
942 ;; there's a ',' to continue at. 976 ;; there's a ',' to continue at.
@@ -944,11 +978,11 @@ casts and declarations are fontified. Used on level 2 and higher."
944 (cond ((eq id-face 'font-lock-function-name-face) 978 (cond ((eq id-face 'font-lock-function-name-face)
945 ;; Skip a parenthesized initializer (C++) or a function 979 ;; Skip a parenthesized initializer (C++) or a function
946 ;; prototype. 980 ;; prototype.
947 (if (c-safe (c-forward-sexp 1) t) 981 (if (c-safe (c-forward-sexp 1) t) ; over the parameter list.
948 (c-forward-syntactic-ws limit) 982 (c-forward-syntactic-ws limit)
949 (goto-char limit))) 983 (goto-char limit))) ; unbalanced parens
950 984
951 (got-init 985 (got-init ; "=" sign OR opening "(", "[", or "{"
952 ;; Skip an initializer expression. If we're at a '=' 986 ;; Skip an initializer expression. If we're at a '='
953 ;; then accept a brace list directly after it to cope 987 ;; then accept a brace list directly after it to cope
954 ;; with array initializers. Otherwise stop at braces 988 ;; with array initializers. Otherwise stop at braces
@@ -956,7 +990,7 @@ casts and declarations are fontified. Used on level 2 and higher."
956 (and (if (and (eq got-init ?=) 990 (and (if (and (eq got-init ?=)
957 (= (c-forward-token-2 1 nil limit) 0) 991 (= (c-forward-token-2 1 nil limit) 0)
958 (looking-at "{")) 992 (looking-at "{"))
959 (c-safe (c-forward-sexp) t) 993 (c-safe (c-forward-sexp) t) ; over { .... }
960 t) 994 t)
961 ;; FIXME: Should look for c-decl-end markers here; 995 ;; FIXME: Should look for c-decl-end markers here;
962 ;; we might go far into the following declarations 996 ;; we might go far into the following declarations
@@ -971,7 +1005,7 @@ casts and declarations are fontified. Used on level 2 and higher."
971 (c-put-char-property (point) 'c-type separator-prop) 1005 (c-put-char-property (point) 'c-type separator-prop)
972 (forward-char) 1006 (forward-char)
973 (c-forward-syntactic-ws limit) 1007 (c-forward-syntactic-ws limit)
974 (setq pos (point)))))) 1008 (setq pos (point)))))) ; acts to make the `while' form continue.
975 nil) 1009 nil)
976 1010
977(defconst c-font-lock-maybe-decl-faces 1011(defconst c-font-lock-maybe-decl-faces
@@ -984,27 +1018,29 @@ casts and declarations are fontified. Used on level 2 and higher."
984 font-lock-keyword-face)) 1018 font-lock-keyword-face))
985 1019
986(defun c-font-lock-declarations (limit) 1020(defun c-font-lock-declarations (limit)
1021 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
1022 ;; Assumes that strings and comments have been fontified already.
1023 ;;
987 ;; This function will be called from font-lock for a region bounded by POINT 1024 ;; This function will be called from font-lock for a region bounded by POINT
988 ;; and LIMIT, as though it were to identify a keyword for 1025 ;; and LIMIT, as though it were to identify a keyword for
989 ;; font-lock-keyword-face. It always returns NIL to inhibit this and 1026 ;; font-lock-keyword-face. It always returns NIL to inhibit this and
990 ;; prevent a repeat invocation. See elisp/lispref page "Search-based 1027 ;; prevent a repeat invocation. See elisp/lispref page "Search-based
991 ;; Fontification". 1028 ;; Fontification".
992 ;; 1029 ;;
993 ;; Fontify all the declarations, casts and labels from the point to LIMIT.
994 ;; Assumes that strings and comments have been fontified already.
995 ;;
996 ;; This function might do hidden buffer changes. 1030 ;; This function might do hidden buffer changes.
997 1031
998 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit) 1032 ;;(message "c-font-lock-declarations search from %s to %s" (point) limit)
999 1033
1000 (save-restriction 1034 (save-restriction
1001 (let (;; The position where `c-find-decl-spots' stopped. 1035 (let (;; The position where `c-find-decl-spots' last stopped.
1002 start-pos 1036 start-pos
1003 ;; 'decl if we're in an arglist containing declarations (but 1037 ;; o - 'decl if we're in an arglist containing declarations
1004 ;; if `c-recognize-paren-inits' is set it might also be an 1038 ;; (but if `c-recognize-paren-inits' is set it might also be
1005 ;; initializer arglist), '<> if the arglist is of angle 1039 ;; an initializer arglist);
1006 ;; bracket type, 'arglist if it's some other arglist, or nil 1040 ;; o - '<> if the arglist is of angle bracket type;
1007 ;; if not in an arglist at all. 1041 ;; o - 'arglist if it's some other arglist;
1042 ;; o - nil, if not in an arglist at all. This includes the
1043 ;; parenthesised condition which follows "if", "while", etc.
1008 context 1044 context
1009 ;; The position of the next token after the closing paren of 1045 ;; The position of the next token after the closing paren of
1010 ;; the last detected cast. 1046 ;; the last detected cast.
@@ -1082,57 +1118,106 @@ casts and declarations are fontified. Used on level 2 and higher."
1082 ;; can't start a declaration. 1118 ;; can't start a declaration.
1083 t 1119 t
1084 1120
1085 ;; Set `context'. Look for "<" for the sake of C++-style template 1121 ;; Set `context' and `c-restricted-<>-arglists'. Look for
1086 ;; arglists. 1122 ;; "<" for the sake of C++-style template arglists.
1087 (if (memq (char-before match-pos) '(?\( ?, ?\[ ?<)) 1123 ;; Ignore "(" when it's part of a control flow construct
1088 1124 ;; (e.g. "for (").
1089 ;; Find out the type of the arglist. 1125 (let ((type (and (> match-pos (point-min))
1090 (if (<= match-pos (point-min)) 1126 (c-get-char-property (1- match-pos) 'c-type))))
1091 (setq context 'arglist) 1127 (cond ((not (memq (char-before match-pos) '(?\( ?, ?\[ ?<)))
1092 (let ((type (c-get-char-property (1- match-pos) 'c-type))) 1128 (setq context nil
1093 (cond ((eq type 'c-decl-arg-start) 1129 c-restricted-<>-arglists nil))
1094 ;; Got a cached hit in a declaration arglist. 1130 ;; A control flow expression
1095 (setq context 'decl)) 1131 ((and (eq (char-before match-pos) ?\()
1096 ((or (eq type 'c-<>-arg-sep) 1132 (save-excursion
1097 (eq (char-before match-pos) ?<)) 1133 (goto-char match-pos)
1098 ;; Inside an angle bracket arglist. 1134 (backward-char)
1099 (setq context '<>)) 1135 (c-backward-token-2)
1100 (type 1136 (looking-at c-block-stmt-2-key)))
1101 ;; Got a cached hit in some other type of arglist. 1137 (setq context nil
1102 (setq context 'arglist)) 1138 c-restricted-<>-arglists t))
1103 ((if inside-macro 1139 ;; Near BOB.
1104 (< match-pos max-type-decl-end-before-token) 1140 ((<= match-pos (point-min))
1105 (< match-pos max-type-decl-end)) 1141 (setq context 'arglist
1106 ;; The point is within the range of a previously 1142 c-restricted-<>-arglists t))
1107 ;; encountered type decl expression, so the arglist 1143 ;; Got a cached hit in a declaration arglist.
1108 ;; is probably one that contains declarations. 1144 ((eq type 'c-decl-arg-start)
1109 ;; However, if `c-recognize-paren-inits' is set it 1145 (setq context 'decl
1110 ;; might also be an initializer arglist. 1146 c-restricted-<>-arglists nil))
1111 (setq context 'decl) 1147 ;; Inside an angle bracket arglist.
1112 ;; The result of this check is cached with a char 1148 ((or (eq type 'c-<>-arg-sep)
1113 ;; property on the match token, so that we can look 1149 (eq (char-before match-pos) ?<))
1114 ;; it up again when refontifying single lines in a 1150 (setq context '<>
1115 ;; multiline declaration. 1151 c-restricted-<>-arglists nil))
1116 (c-put-char-property (1- match-pos) 1152 ;; Got a cached hit in some other type of arglist.
1117 'c-type 'c-decl-arg-start)) 1153 (type
1118 (t 1154 (setq context 'arglist
1119 (setq context 'arglist))))) 1155 c-restricted-<>-arglists t))
1120 1156 ((if inside-macro
1121 (setq context nil)) 1157 (< match-pos max-type-decl-end-before-token)
1122 1158 (< match-pos max-type-decl-end))
1123 ;; If we're in a normal arglist context we don't want to 1159 ;; The point is within the range of a previously
1124 ;; recognize commas in nested angle bracket arglists since 1160 ;; encountered type decl expression, so the arglist
1125 ;; those commas could be part of our own arglist. 1161 ;; is probably one that contains declarations.
1126 (setq c-restricted-<>-arglists (and c-recognize-<>-arglists 1162 ;; However, if `c-recognize-paren-inits' is set it
1127 (eq context 'arglist)) 1163 ;; might also be an initializer arglist.
1128 1164 (setq context 'decl
1129 ;; Now analyze the construct. 1165 c-restricted-<>-arglists nil)
1130 decl-or-cast (c-forward-decl-or-cast-1 1166 ;; The result of this check is cached with a char
1167 ;; property on the match token, so that we can look
1168 ;; it up again when refontifying single lines in a
1169 ;; multiline declaration.
1170 (c-put-char-property (1- match-pos)
1171 'c-type 'c-decl-arg-start))
1172 (t (setq context 'arglist
1173 c-restricted-<>-arglists t))))
1174
1175 ;; Check we haven't missed a preceding "typedef".
1176 (when (not (looking-at c-typedef-key))
1177 (c-backward-syntactic-ws)
1178 (c-backward-token-2)
1179 (or (looking-at c-typedef-key)
1180 (goto-char start-pos)))
1181
1182 ;; Now analyze the construct.
1183 (setq decl-or-cast (c-forward-decl-or-cast-1
1131 match-pos context last-cast-end)) 1184 match-pos context last-cast-end))
1132 1185
1133 (if (not decl-or-cast) 1186 (if (not decl-or-cast)
1134 ;; False alarm. Return t to go on to the next check. 1187 ;; Are we at a declarator?
1135 t 1188 ;; Try to go back to the declaration to check this.
1189 (let (paren-state bod-res lim encl-pos is-typedef)
1190 (goto-char start-pos)
1191 (save-excursion
1192 (setq lim (and (c-syntactic-skip-backward "^;" nil t)
1193 (point))))
1194 (save-excursion
1195 (setq bod-res (car (c-beginning-of-decl-1 lim)))
1196 (if (and (eq bod-res 'same)
1197 (progn
1198 (c-backward-syntactic-ws)
1199 (eq (char-before) ?\})))
1200 (c-beginning-of-decl-1 lim))
1201 ;; We're now putatively at the declaration.
1202 (setq paren-state (c-parse-state))
1203 ;; At top level or inside a "{"?
1204 (if (or (not (setq encl-pos
1205 (c-most-enclosing-brace paren-state)))
1206 (eq (char-after encl-pos) ?\{))
1207 (progn
1208 (when (looking-at c-typedef-key) ; "typedef"
1209 (setq is-typedef t)
1210 (goto-char (match-end 0))
1211 (c-forward-syntactic-ws))
1212 ;; At a real declaration?
1213 (if (memq (c-forward-type t) '(t known found))
1214 (progn
1215 (c-font-lock-declarators limit t is-typedef)
1216 nil)
1217 ;; False alarm. Return t to go on to the next check.
1218 (goto-char start-pos)
1219 t))
1220 t)))
1136 1221
1137 (if (eq decl-or-cast 'cast) 1222 (if (eq decl-or-cast 'cast)
1138 ;; Save the position after the previous cast so we can feed 1223 ;; Save the position after the previous cast so we can feed
@@ -1296,7 +1381,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1296 "Complex font lock matchers for types and declarations. Used on level 1381 "Complex font lock matchers for types and declarations. Used on level
12973 and higher." 13823 and higher."
1298 1383
1299 ;; Note: This code in this form dumps a number of funtions into the 1384 ;; Note: This code in this form dumps a number of functions into the
1300 ;; resulting constant, `c-matchers-3'. At run time, font lock will call 1385 ;; resulting constant, `c-matchers-3'. At run time, font lock will call
1301 ;; each of them as a "FUNCTION" (see Elisp page "Search-based 1386 ;; each of them as a "FUNCTION" (see Elisp page "Search-based
1302 ;; Fontification"). The font lock region is delimited by POINT and the 1387 ;; Fontification"). The font lock region is delimited by POINT and the
@@ -1348,7 +1433,7 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1348 `(,(concat "\\<\\(" re "\\)\\>") 1433 `(,(concat "\\<\\(" re "\\)\\>")
1349 1 'font-lock-type-face))) 1434 1 'font-lock-type-face)))
1350 1435
1351 ;; Fontify types preceded by `c-type-prefix-kwds'. 1436 ;; Fontify types preceded by `c-type-prefix-kwds' (e.g. "struct").
1352 ,@(when (c-lang-const c-type-prefix-kwds) 1437 ,@(when (c-lang-const c-type-prefix-kwds)
1353 `((,(byte-compile 1438 `((,(byte-compile
1354 `(lambda (limit) 1439 `(lambda (limit)
@@ -1396,23 +1481,25 @@ on level 2 only and so aren't combined with `c-complex-decl-matchers'."
1396 ;; override it if it turns out to be an new declaration, but 1481 ;; override it if it turns out to be an new declaration, but
1397 ;; it will be wrong if it's an expression (see the test 1482 ;; it will be wrong if it's an expression (see the test
1398 ;; decls-8.cc). 1483 ;; decls-8.cc).
1399 ,@(when (c-lang-const c-opt-block-decls-with-vars-key) 1484;; ,@(when (c-lang-const c-opt-block-decls-with-vars-key)
1400 `((,(c-make-font-lock-search-function 1485;; `((,(c-make-font-lock-search-function
1401 (concat "}" 1486;; (concat "}"
1402 (c-lang-const c-single-line-syntactic-ws) 1487;; (c-lang-const c-single-line-syntactic-ws)
1403 "\\(" ; 1 + c-single-line-syntactic-ws-depth 1488;; "\\(" ; 1 + c-single-line-syntactic-ws-depth
1404 (c-lang-const c-type-decl-prefix-key) 1489;; (c-lang-const c-type-decl-prefix-key)
1405 "\\|" 1490;; "\\|"
1406 (c-lang-const c-symbol-key) 1491;; (c-lang-const c-symbol-key)
1407 "\\)") 1492;; "\\)")
1408 `((c-font-lock-declarators limit t nil) 1493;; `((c-font-lock-declarators limit t nil) ; That `nil' says use `font-lock-variable-name-face';
1409 (progn 1494;; ; `t' would mean `font-lock-function-name-face'.
1410 (c-put-char-property (match-beginning 0) 'c-type 1495;; (progn
1411 'c-decl-id-start) 1496;; (c-put-char-property (match-beginning 0) 'c-type
1412 (goto-char (match-beginning 1497;; 'c-decl-id-start)
1413 ,(1+ (c-lang-const 1498;; ; 'c-decl-type-start)
1414 c-single-line-syntactic-ws-depth))))) 1499;; (goto-char (match-beginning
1415 (goto-char (match-end 0))))))) 1500;; ,(1+ (c-lang-const
1501;; c-single-line-syntactic-ws-depth)))))
1502;; (goto-char (match-end 0)))))))
1416 1503
1417 ;; Fontify the type in C++ "new" expressions. 1504 ;; Fontify the type in C++ "new" expressions.
1418 ,@(when (c-major-mode-is 'c++-mode) 1505 ,@(when (c-major-mode-is 'c++-mode)
@@ -1660,6 +1747,10 @@ need for `c-font-lock-extra-types'.")
1660;;; C++. 1747;;; C++.
1661 1748
1662(defun c-font-lock-c++-new (limit) 1749(defun c-font-lock-c++-new (limit)
1750 ;; FIXME!!! Put in a comment about the context of this function's
1751 ;; invocation. I think it's called as an ANCHORED-MATCHER within an
1752 ;; ANCHORED-HIGHLIGHTER. (2007/2/10).
1753 ;;
1663 ;; Assuming point is after a "new" word, check that it isn't inside 1754 ;; Assuming point is after a "new" word, check that it isn't inside
1664 ;; a string or comment, and if so try to fontify the type in the 1755 ;; a string or comment, and if so try to fontify the type in the
1665 ;; allocation expression. Nil is always returned. 1756 ;; allocation expression. Nil is always returned.
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 5cd5c0b95ca..ba056133651 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -1565,6 +1565,17 @@ be a subset of `c-primitive-type-kwds'."
1565 ;; In CORBA PSDL: 1565 ;; In CORBA PSDL:
1566 "strong")) 1566 "strong"))
1567 1567
1568(c-lang-defconst c-typedef-kwds
1569 "Prefix keyword\(s\) like \"typedef\" which make a type declaration out
1570of a variable declaration."
1571 t '("typedef")
1572 (awk idl java) nil)
1573
1574(c-lang-defconst c-typedef-key
1575 ;; Adorned regexp matching `c-typedef-kwds'.
1576 t (c-make-keywords-re t (c-lang-const c-typedef-kwds)))
1577(c-lang-defvar c-typedef-key (c-lang-const c-typedef-key))
1578
1568(c-lang-defconst c-type-prefix-kwds 1579(c-lang-defconst c-type-prefix-kwds
1569 "Keywords where the following name - if any - is a type name, and 1580 "Keywords where the following name - if any - is a type name, and
1570where the keyword together with the symbol works as a type in 1581where the keyword together with the symbol works as a type in
@@ -1731,6 +1742,10 @@ will be handled."
1731 ;; types in IDL since they only can occur in "raises" specs. 1742 ;; types in IDL since they only can occur in "raises" specs.
1732 idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil))) 1743 idl (delete "exception" (append (c-lang-const c-typedef-decl-kwds) nil)))
1733 1744
1745(c-lang-defconst c-typedef-decl-key
1746 t (c-make-keywords-re t (c-lang-const c-typedef-decl-kwds)))
1747(c-lang-defvar c-typedef-decl-key (c-lang-const c-typedef-decl-key))
1748
1734(c-lang-defconst c-typeless-decl-kwds 1749(c-lang-defconst c-typeless-decl-kwds
1735 "Keywords introducing declarations where the \(first) identifier 1750 "Keywords introducing declarations where the \(first) identifier
1736\(declarator) follows directly after the keyword, without any type. 1751\(declarator) follows directly after the keyword, without any type.
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 6a76a657829..505a5663ebc 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -100,7 +100,6 @@
100(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 100(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
101(cc-bytecomp-defun set-keymap-parents) ; XEmacs 101(cc-bytecomp-defun set-keymap-parents) ; XEmacs
102(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1 102(cc-bytecomp-defun run-mode-hooks) ; Emacs 21.1
103(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1.
104 103
105;; We set these variables during mode init, yet we don't require 104;; We set these variables during mode init, yet we don't require
106;; font-lock. 105;; font-lock.
@@ -600,9 +599,10 @@ that requires a literal mode spec at compile time."
600 599
601 ;; Install the functions that ensure that various internal caches 600 ;; Install the functions that ensure that various internal caches
602 ;; don't become invalid due to buffer changes. 601 ;; don't become invalid due to buffer changes.
603 (make-local-hook 'before-change-functions) 602 (when (featurep 'xemacs)
603 (make-local-hook 'before-change-functions)
604 (make-local-hook 'after-change-functions))
604 (add-hook 'before-change-functions 'c-before-change nil t) 605 (add-hook 'before-change-functions 'c-before-change nil t)
605 (make-local-hook 'after-change-functions)
606 (add-hook 'after-change-functions 'c-after-change nil t) 606 (add-hook 'after-change-functions 'c-after-change nil t)
607 (set (make-local-variable 'font-lock-extend-after-change-region-function) 607 (set (make-local-variable 'font-lock-extend-after-change-region-function)
608 'c-extend-after-change-region)) ; Currently (2009-05) used by all 608 'c-extend-after-change-region)) ; Currently (2009-05) used by all
@@ -1113,8 +1113,8 @@ This does not load the font-lock package. Use after
1113 c-beginning-of-syntax 1113 c-beginning-of-syntax
1114 (font-lock-mark-block-function 1114 (font-lock-mark-block-function
1115 . c-mark-function))) 1115 . c-mark-function)))
1116 1116 (if (featurep 'xemacs)
1117 (make-local-hook 'font-lock-mode-hook) 1117 (make-local-hook 'font-lock-mode-hook))
1118 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t)) 1118 (add-hook 'font-lock-mode-hook 'c-after-font-lock-init nil t))
1119 1119
1120(defun c-extend-after-change-region (beg end old-len) 1120(defun c-extend-after-change-region (beg end old-len)
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index 48120563b29..15d44f6538a 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -50,7 +50,6 @@
50 50
51;; Silence the compiler. 51;; Silence the compiler.
52(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 52(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
53(cc-bytecomp-obsolete-fun make-local-hook) ; Marked obsolete in Emacs 21.1.
54 53
55 54
56(defvar c-style-alist 55(defvar c-style-alist
@@ -649,7 +648,7 @@ any reason to call this function directly."
649 (mapc func varsyms) 648 (mapc func varsyms)
650 ;; Hooks must be handled specially 649 ;; Hooks must be handled specially
651 (if this-buf-only-p 650 (if this-buf-only-p
652 (make-local-hook 'c-special-indent-hook) 651 (if (featurep 'xemacs) (make-local-hook 'c-special-indent-hook))
653 (with-no-warnings (make-variable-buffer-local 'c-special-indent-hook)) 652 (with-no-warnings (make-variable-buffer-local 'c-special-indent-hook))
654 (setq c-style-variables-are-local-p t)) 653 (setq c-style-variables-are-local-p t))
655 )) 654 ))
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 7f0732ecffc..a335f3dd427 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -2425,9 +2425,6 @@ The file-structure looks like this:
2425 (or compilation-auto-jump-to-first-error 2425 (or compilation-auto-jump-to-first-error
2426 (eq compilation-scroll-output 'first-error)))) 2426 (eq compilation-scroll-output 'first-error))))
2427 2427
2428;;;###autoload
2429(add-to-list 'auto-mode-alist (cons (purecopy "\\.gcov\\'") 'compilation-mode))
2430
2431(provide 'compile) 2428(provide 'compile)
2432 2429
2433;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c 2430;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index d89e41b38fb..46002929791 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -1,8 +1,8 @@
1;;; cperl-mode.el --- Perl code editing commands for Emacs 1;;; cperl-mode.el --- Perl code editing commands for Emacs
2 2
3;; Copyright (C) 1985, 1986, 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 3;; Copyright (C) 1985, 1986, 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
4;; 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4;; 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
5;; Free Software Foundation, Inc. 5;; 2010 Free Software Foundation, Inc.
6 6
7;; Author: Ilya Zakharevich 7;; Author: Ilya Zakharevich
8;; Bob Olson 8;; Bob Olson
@@ -1802,13 +1802,12 @@ or as help on variables `cperl-tips', `cperl-problems',
1802 (set 'vc-rcs-header cperl-vc-rcs-header) 1802 (set 'vc-rcs-header cperl-vc-rcs-header)
1803 (make-local-variable 'vc-sccs-header) 1803 (make-local-variable 'vc-sccs-header)
1804 (set 'vc-sccs-header cperl-vc-sccs-header) 1804 (set 'vc-sccs-header cperl-vc-sccs-header)
1805 ;; This one is obsolete... 1805 (when (featurep 'xemacs)
1806 (make-local-variable 'vc-header-alist) 1806 ;; This one is obsolete...
1807 (with-no-warnings 1807 (make-local-variable 'vc-header-alist)
1808 (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning 1808 (set 'vc-header-alist (or cperl-vc-header-alist ; Avoid warning
1809 `((SCCS ,(car cperl-vc-sccs-header)) 1809 `((SCCS ,(car cperl-vc-sccs-header))
1810 (RCS ,(car cperl-vc-rcs-header))))) 1810 (RCS ,(car cperl-vc-rcs-header))))))
1811 )
1812 (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x 1811 (cond ((boundp 'compilation-error-regexp-alist-alist);; xemacs 20.x
1813 (make-local-variable 'compilation-error-regexp-alist-alist) 1812 (make-local-variable 'compilation-error-regexp-alist-alist)
1814 (set 'compilation-error-regexp-alist-alist 1813 (set 'compilation-error-regexp-alist-alist
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 2018a71574e..042cc8c33f6 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -68,12 +68,14 @@ Use the `etags' program to make a tags table file."
68 :type '(repeat file)) 68 :type '(repeat file))
69 69
70;;;###autoload 70;;;###autoload
71(defcustom tags-compression-info-list (purecopy '("" ".Z" ".bz2" ".gz" ".tgz")) 71(defcustom tags-compression-info-list
72 (purecopy '("" ".Z" ".bz2" ".gz" ".xz" ".tgz"))
72 "*List of extensions tried by etags when jka-compr is used. 73 "*List of extensions tried by etags when jka-compr is used.
73An empty string means search the non-compressed file. 74An empty string means search the non-compressed file.
74These extensions will be tried only if jka-compr was activated 75These extensions will be tried only if jka-compr was activated
75\(i.e. via customize of `auto-compression-mode' or by calling the function 76\(i.e. via customize of `auto-compression-mode' or by calling the function
76`auto-compression-mode')." 77`auto-compression-mode')."
78 :version "24.1" ; added xz
77 :type '(repeat string) 79 :type '(repeat string)
78 :group 'etags) 80 :group 'etags)
79 81
@@ -472,7 +474,7 @@ Subroutine of `visit-tags-table-buffer'.
472Looks for a tags table that has such tags or that includes a table 474Looks for a tags table that has such tags or that includes a table
473that has them. Returns the name of the first such table. 475that has them. Returns the name of the first such table.
474Non-nil CORE-ONLY means check only tags tables that are already in 476Non-nil CORE-ONLY means check only tags tables that are already in
475buffers. Nil CORE-ONLY is ignored." 477buffers. If CORE-ONLY is nil, it is ignored."
476 (let ((tables tags-table-computed-list) 478 (let ((tables tags-table-computed-list)
477 (found nil)) 479 (found nil))
478 ;; Loop over the list, looking for a table containing tags for THIS-FILE. 480 ;; Loop over the list, looking for a table containing tags for THIS-FILE.
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el
index daa0fd07364..91cfb646b66 100644
--- a/lisp/progmodes/fortran.el
+++ b/lisp/progmodes/fortran.el
@@ -483,19 +483,27 @@ The only difference is, it returns t in a case when the default returns nil."
483 "Maximum highlighting for Fortran mode. 483 "Maximum highlighting for Fortran mode.
484Consists of level 3 plus all other intrinsics not already highlighted.") 484Consists of level 3 plus all other intrinsics not already highlighted.")
485 485
486(defvar fortran--font-lock-syntactic-keywords)
487;; Comments are real pain in Fortran because there is no way to 486;; Comments are real pain in Fortran because there is no way to
488;; represent the standard comment syntax in an Emacs syntax table. 487;; represent the standard comment syntax in an Emacs syntax table.
489;; (We can do so for F90-style). Therefore an unmatched quote in a 488;; (We can do so for F90-style). Therefore an unmatched quote in a
490;; standard comment will throw fontification off on the wrong track. 489;; standard comment will throw fontification off on the wrong track.
491;; So we do syntactic fontification with regexps. 490;; So we do syntactic fontification with regexps.
492(defun fortran-font-lock-syntactic-keywords () 491(defun fortran-make-syntax-propertize-function (line-length)
493 "Return a value for `font-lock-syntactic-keywords' in Fortran mode. 492 "Return a value for `syntax-propertize-function' in Fortran mode.
494This varies according to the value of `fortran-line-length'. 493This varies according to the value of LINE-LENGTH.
495This is used to fontify fixed-format Fortran comments." 494This is used to fontify fixed-format Fortran comments."
496 `(("^[cd\\*]" 0 (11)) 495 ;; This results in a non-byte-compiled function. We could pass it through
497 (,(format "^[^cd\\*\t\n].\\{%d\\}\\([^\n]+\\)" (1- fortran-line-length)) 496 ;; `byte-compile', but simple benchmarks indicate that it's probably not
498 1 (11)))) 497 ;; worth the trouble (about ½% of slow down).
498 (eval ;I hate `eval', but it's hard to avoid it here.
499 `(syntax-propertize-rules
500 ("^[cd\\*]" (0 "<"))
501 ;; We mark all chars after line-length as "comment-start", rather than
502 ;; just the first one. This is so that a closing ' that's past the
503 ;; line-length will indeed be ignored (and will result in a string that
504 ;; leaks into subsequent lines).
505 ((format "^[^cd\\*\t\n].\\{%d\\}\\(.+\\)" (1- line-length))
506 (1 "<")))))
499 507
500(defvar fortran-font-lock-keywords fortran-font-lock-keywords-1 508(defvar fortran-font-lock-keywords fortran-font-lock-keywords-1
501 "Default expressions to highlight in Fortran mode.") 509 "Default expressions to highlight in Fortran mode.")
@@ -889,10 +897,8 @@ with no args, if that value is non-nil."
889 fortran-font-lock-keywords-4) 897 fortran-font-lock-keywords-4)
890 nil t ((?/ . "$/") ("_$" . "w")) 898 nil t ((?/ . "$/") ("_$" . "w"))
891 fortran-beginning-of-subprogram)) 899 fortran-beginning-of-subprogram))
892 (set (make-local-variable 'fortran--font-lock-syntactic-keywords)
893 (fortran-make-syntax-propertize-function))
894 (set (make-local-variable 'syntax-propertize-function) 900 (set (make-local-variable 'syntax-propertize-function)
895 (syntax-propertize-via-font-lock fortran--font-lock-syntactic-keywords)) 901 (fortran-make-syntax-propertize-function fortran-line-length))
896 (set (make-local-variable 'imenu-case-fold-search) t) 902 (set (make-local-variable 'imenu-case-fold-search) t)
897 (set (make-local-variable 'imenu-generic-expression) 903 (set (make-local-variable 'imenu-generic-expression)
898 fortran-imenu-generic-expression) 904 fortran-imenu-generic-expression)
@@ -912,27 +918,30 @@ with no args, if that value is non-nil."
912 "Set the length of fixed-form Fortran lines to NCHARS. 918 "Set the length of fixed-form Fortran lines to NCHARS.
913This normally only affects the current buffer, which must be in 919This normally only affects the current buffer, which must be in
914Fortran mode. If the optional argument GLOBAL is non-nil, it 920Fortran mode. If the optional argument GLOBAL is non-nil, it
915affects all Fortran buffers, and also the default." 921affects all Fortran buffers, and also the default.
916 (interactive "p") 922If a numeric prefix argument is specified, it will be used as NCHARS,
917 (let (new) 923otherwise is a non-numeric prefix arg is specified, the length will be
918 (mapc (lambda (buff) 924provided via the minibuffer, and otherwise the current column is used."
919 (with-current-buffer buff 925 (interactive
920 (when (eq major-mode 'fortran-mode) 926 (list (cond
921 (setq fortran-line-length nchars 927 ((numberp current-prefix-arg) current-prefix-arg)
922 fill-column fortran-line-length 928 (current-prefix-arg
923 new (fortran-make-syntax-propertize-function)) 929 (read-number "Line length: " (default-value 'fortran-line-length)))
924 ;; Refontify only if necessary. 930 (t (current-column)))))
925 (unless (equal new fortran--font-lock-syntactic-keywords) 931 (dolist (buff (if global
926 (setq fortran--font-lock-syntactic-keywords new) 932 (buffer-list)
927 (setq syntax-propertize-function 933 (list (current-buffer))))
928 (syntax-propertize-via-font-lock new)) 934 (with-current-buffer buff
929 (syntax-ppss-flush-cache (point-min)) 935 (when (derived-mode-p 'fortran-mode)
930 (if font-lock-mode (font-lock-mode 1)))))) 936 (unless (eq fortran-line-length nchars)
937 (setq fortran-line-length nchars
938 fill-column fortran-line-length
939 syntax-propertize-function
940 (fortran-make-syntax-propertize-function nchars))
941 (syntax-ppss-flush-cache (point-min))
942 (if font-lock-mode (font-lock-mode 1))))))
931 (if global 943 (if global
932 (buffer-list) 944 (setq-default fortran-line-length nchars)))
933 (list (current-buffer))))
934 (if global
935 (setq-default fortran-line-length nchars))))
936 945
937(defun fortran-hack-local-variables () 946(defun fortran-hack-local-variables ()
938 "Fortran mode adds this to `hack-local-variables-hook'." 947 "Fortran mode adds this to `hack-local-variables-hook'."
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 5b98ff427c3..3019f8bbf04 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -163,7 +163,7 @@ returned from -thread-info by `gdb-json-partial-output'. Updated in
163(defvar gdb-running-threads-count nil 163(defvar gdb-running-threads-count nil
164 "Number of currently running threads. 164 "Number of currently running threads.
165 165
166Nil means that no information is available. 166If nil, no information is available.
167 167
168Updated in `gdb-thread-list-handler-custom'.") 168Updated in `gdb-thread-list-handler-custom'.")
169 169
@@ -2051,7 +2051,7 @@ current thread and update GDB buffers."
2051Field names are wrapped in double quotes and equal signs are 2051Field names are wrapped in double quotes and equal signs are
2052replaced with semicolons. 2052replaced with semicolons.
2053 2053
2054If FIX-KEY is non-nil, strip all \"FIX-KEY=\" occurences from 2054If FIX-KEY is non-nil, strip all \"FIX-KEY=\" occurrences from
2055partial output. This is used to get rid of useless keys in lists 2055partial output. This is used to get rid of useless keys in lists
2056in MI messages, e.g.: [key=.., key=..]. -stack-list-frames and 2056in MI messages, e.g.: [key=.., key=..]. -stack-list-frames and
2057-break-info are examples of MI commands which issue such 2057-break-info are examples of MI commands which issue such
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 4c1471e39ec..8c35a13ac53 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -3218,13 +3218,6 @@ Treats actions as defuns."
3218 (goto-char (point-max))) 3218 (goto-char (point-max)))
3219 t) 3219 t)
3220 3220
3221;; Besides .gdbinit, gdb documents other names to be usable for init
3222;; files, cross-debuggers can use something like
3223;; .PROCESSORNAME-gdbinit so that the host and target gdbinit files
3224;; don't interfere with each other.
3225;;;###autoload
3226(add-to-list 'auto-mode-alist (cons (purecopy "/\\.[a-z0-9-]*gdbinit") 'gdb-script-mode))
3227
3228;;;###autoload 3221;;;###autoload
3229(define-derived-mode gdb-script-mode nil "GDB-Script" 3222(define-derived-mode gdb-script-mode nil "GDB-Script"
3230 "Major mode for editing GDB scripts." 3223 "Major mode for editing GDB scripts."
diff --git a/lisp/progmodes/inf-lisp.el b/lisp/progmodes/inf-lisp.el
index ee5e2a49ead..41ce378e966 100644
--- a/lisp/progmodes/inf-lisp.el
+++ b/lisp/progmodes/inf-lisp.el
@@ -80,19 +80,17 @@ mode. Default is whitespace followed by 0 or 1 single-letter colon-keyword
80 :type 'regexp 80 :type 'regexp
81 :group 'inferior-lisp) 81 :group 'inferior-lisp)
82 82
83(defvar inferior-lisp-mode-map nil) 83(defvar inferior-lisp-mode-map
84(unless inferior-lisp-mode-map 84 (let ((map (copy-keymap comint-mode-map)))
85 (setq inferior-lisp-mode-map (copy-keymap comint-mode-map)) 85 (set-keymap-parent map lisp-mode-shared-map)
86 (set-keymap-parent inferior-lisp-mode-map lisp-mode-shared-map) 86 (define-key map "\C-x\C-e" 'lisp-eval-last-sexp)
87 (define-key inferior-lisp-mode-map "\C-x\C-e" 'lisp-eval-last-sexp) 87 (define-key map "\C-c\C-l" 'lisp-load-file)
88 (define-key inferior-lisp-mode-map "\C-c\C-l" 'lisp-load-file) 88 (define-key map "\C-c\C-k" 'lisp-compile-file)
89 (define-key inferior-lisp-mode-map "\C-c\C-k" 'lisp-compile-file) 89 (define-key map "\C-c\C-a" 'lisp-show-arglist)
90 (define-key inferior-lisp-mode-map "\C-c\C-a" 'lisp-show-arglist) 90 (define-key map "\C-c\C-d" 'lisp-describe-sym)
91 (define-key inferior-lisp-mode-map "\C-c\C-d" 'lisp-describe-sym) 91 (define-key map "\C-c\C-f" 'lisp-show-function-documentation)
92 (define-key inferior-lisp-mode-map "\C-c\C-f" 92 (define-key map "\C-c\C-v" 'lisp-show-variable-documentation)
93 'lisp-show-function-documentation) 93 map))
94 (define-key inferior-lisp-mode-map "\C-c\C-v"
95 'lisp-show-variable-documentation))
96 94
97;;; These commands augment Lisp mode, so you can process Lisp code in 95;;; These commands augment Lisp mode, so you can process Lisp code in
98;;; the source files. 96;;; the source files.
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index ba70bb8ecce..aeb2e91b6af 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3304,7 +3304,7 @@ Key bindings:
3304 3304
3305 (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil) 3305 (set (make-local-variable 'open-paren-in-column-0-is-defun-start) nil)
3306 (set (make-local-variable 'font-lock-defaults) 3306 (set (make-local-variable 'font-lock-defaults)
3307 '(js--font-lock-keywords)) 3307 (list js--font-lock-keywords))
3308 (set (make-local-variable 'syntax-propertize-function) 3308 (set (make-local-variable 'syntax-propertize-function)
3309 js-syntax-propertize-function) 3309 js-syntax-propertize-function)
3310 3310
diff --git a/lisp/progmodes/ld-script.el b/lisp/progmodes/ld-script.el
index 3d07ed226b2..318456e9534 100644
--- a/lisp/progmodes/ld-script.el
+++ b/lisp/progmodes/ld-script.el
@@ -1,7 +1,7 @@
1;;; ld-script.el --- GNU linker script editing mode for Emacs 1;;; ld-script.el --- GNU linker script editing mode for Emacs
2 2
3;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 3;; Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
4;; Free Software Foundation, Inc. 4;; 2010 Free Software Foundation, Inc.
5 5
6;; Author: Masatake YAMATO<jet@gyve.org> 6;; Author: Masatake YAMATO<jet@gyve.org>
7;; Keywords: languages, faces 7;; Keywords: languages, faces
@@ -76,20 +76,20 @@
76(defvar ld-script-keywords 76(defvar ld-script-keywords
77 '( 77 '(
78 ;; 3.4.1 Setting the Entry Point 78 ;; 3.4.1 Setting the Entry Point
79 "ENTRY" 79 "ENTRY"
80 ;; 3.4.2 Commands Dealing with Files 80 ;; 3.4.2 Commands Dealing with Files
81 "INCLUDE" "INPUT" "GROUP" "AS_NEEDED" "OUTPUT" "SEARCH_DIR" "STARTUP" 81 "INCLUDE" "INPUT" "GROUP" "AS_NEEDED" "OUTPUT" "SEARCH_DIR" "STARTUP"
82 ;; 3.4.3 Commands Dealing with Object File Formats 82 ;; 3.4.3 Commands Dealing with Object File Formats
83 "OUTPUT_FORMAT" "TARGET" 83 "OUTPUT_FORMAT" "TARGET"
84 ;; 3.4.3 Other Linker Script Commands 84 ;; 3.4.3 Other Linker Script Commands
85 "ASSERT" "EXTERN" "FORCE_COMMON_ALLOCATION" 85 "ASSERT" "EXTERN" "FORCE_COMMON_ALLOCATION"
86 "INHIBIT_COMMON_ALLOCATION" "NOCROSSREFS" "OUTPUT_ARCH" 86 "INHIBIT_COMMON_ALLOCATION" "NOCROSSREFS" "OUTPUT_ARCH"
87 ;; 3.5.2 PROVIDE 87 ;; 3.5.2 PROVIDE
88 "PROVIDE" 88 "PROVIDE"
89 ;; 3.5.3 PROVIDE_HIDDEN 89 ;; 3.5.3 PROVIDE_HIDDEN
90 "PROVIDE_HIDDEN" 90 "PROVIDE_HIDDEN"
91 ;; 3.6 SECTIONS Command 91 ;; 3.6 SECTIONS Command
92 "SECTIONS" 92 "SECTIONS"
93 ;; 3.6.4.2 Input Section Wildcard Patterns 93 ;; 3.6.4.2 Input Section Wildcard Patterns
94 "SORT" "SORT_BY_NAME" "SORT_BY_ALIGNMENT" 94 "SORT" "SORT_BY_NAME" "SORT_BY_ALIGNMENT"
95 ;; 3.6.4.3 Input Section for Common Symbols 95 ;; 3.6.4.3 Input Section for Common Symbols
@@ -157,18 +157,6 @@
157 cpp-font-lock-keywords) 157 cpp-font-lock-keywords)
158 "Default font-lock-keywords for `ld-script-mode'.") 158 "Default font-lock-keywords for `ld-script-mode'.")
159 159
160;; Linux-2.6.9 uses some different suffix for linker scripts:
161;; "ld", "lds", "lds.S", "lds.in", "ld.script", and "ld.script.balo".
162;; eCos uses "ld" and "ldi".
163;; Netbsd uses "ldscript.*".
164;;;###autoload
165(add-to-list 'auto-mode-alist (purecopy '("\\.ld[si]?\\>" . ld-script-mode)))
166;;;###autoload
167(add-to-list 'auto-mode-alist (purecopy '("ld\\.?script\\>" . ld-script-mode)))
168
169;;;###autoload
170(add-to-list 'auto-mode-alist (purecopy '("\\.x[bdsru]?[cn]?\\'" . ld-script-mode)))
171
172;;;###autoload 160;;;###autoload
173(define-derived-mode ld-script-mode nil "LD-Script" 161(define-derived-mode ld-script-mode nil "LD-Script"
174 "A major mode to edit GNU ld script files" 162 "A major mode to edit GNU ld script files"
diff --git a/lisp/progmodes/mixal-mode.el b/lisp/progmodes/mixal-mode.el
index 94af563d88f..f2a7aa045e4 100644
--- a/lisp/progmodes/mixal-mode.el
+++ b/lisp/progmodes/mixal-mode.el
@@ -125,7 +125,7 @@ value.")
125(defvar mixal-operation-codes-alist 125(defvar mixal-operation-codes-alist
126 ;; FIXME: the codes FADD, FSUB, FMUL, FDIV, JRAD, and FCMP were in 126 ;; FIXME: the codes FADD, FSUB, FMUL, FDIV, JRAD, and FCMP were in
127 ;; mixal-operation-codes but not here. They should probably be added here. 127 ;; mixal-operation-codes but not here. They should probably be added here.
128 ;; 128 ;;
129 ;; We used to define this with a backquote and subexps like ,(+ 8 3) for 129 ;; We used to define this with a backquote and subexps like ,(+ 8 3) for
130 ;; better clarity, but the resulting code was too big and caused the 130 ;; better clarity, but the resulting code was too big and caused the
131 ;; byte-compiler to eat up all the stack space. Even using 131 ;; byte-compiler to eat up all the stack space. Even using
@@ -1123,9 +1123,6 @@ Assumes that file has been compiled with debugging support."
1123 (set (make-local-variable 'require-final-newline) 1123 (set (make-local-variable 'require-final-newline)
1124 mode-require-final-newline)) 1124 mode-require-final-newline))
1125 1125
1126;;;###autoload
1127(add-to-list 'auto-mode-alist '("\\.mixal\\'" . mixal-mode))
1128
1129(provide 'mixal-mode) 1126(provide 'mixal-mode)
1130 1127
1131;; arch-tag: be7c128a-bf61-4951-a90e-9398267ce3f3 1128;; arch-tag: be7c128a-bf61-4951-a90e-9398267ce3f3
diff --git a/lisp/progmodes/modula2.el b/lisp/progmodes/modula2.el
index 9d226cefbd4..3d2af5e217e 100644
--- a/lisp/progmodes/modula2.el
+++ b/lisp/progmodes/modula2.el
@@ -69,10 +69,7 @@
69 (setq m2-mode-syntax-table table))) 69 (setq m2-mode-syntax-table table)))
70 70
71;;; Added by TEP 71;;; Added by TEP
72(defvar m2-mode-map nil 72(defvar m2-mode-map
73 "Keymap used in Modula-2 mode.")
74
75(if m2-mode-map ()
76 (let ((map (make-sparse-keymap))) 73 (let ((map (make-sparse-keymap)))
77 (define-key map "\^i" 'm2-tab) 74 (define-key map "\^i" 'm2-tab)
78 (define-key map "\C-cb" 'm2-begin) 75 (define-key map "\C-cb" 'm2-begin)
@@ -103,7 +100,8 @@
103 (define-key map "\C-c\C-t" 'm2-toggle) 100 (define-key map "\C-c\C-t" 'm2-toggle)
104 (define-key map "\C-c\C-l" 'm2-link) 101 (define-key map "\C-c\C-l" 'm2-link)
105 (define-key map "\C-c\C-c" 'm2-compile) 102 (define-key map "\C-c\C-c" 'm2-compile)
106 (setq m2-mode-map map))) 103 map)
104 "Keymap used in Modula-2 mode.")
107 105
108(defcustom m2-indent 5 106(defcustom m2-indent 5
109 "*This variable gives the indentation in Modula-2-Mode." 107 "*This variable gives the indentation in Modula-2-Mode."
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el
index bbefdaa2ccf..56de9b869db 100644
--- a/lisp/progmodes/octave-mod.el
+++ b/lisp/progmodes/octave-mod.el
@@ -456,10 +456,7 @@ Non-nil means always go to the next Octave code line after sending."
456 octave-smie-bnf-table 456 octave-smie-bnf-table
457 '((assoc "\n" ";"))) 457 '((assoc "\n" ";")))
458 458
459 (smie-precs-precedence-table 459 (smie-precs-precedence-table octave-operator-table))))
460 (append octave-operator-table
461 '((nonassoc " -dummy- "))) ;Bogus anchor at the end.
462 ))))
463 460
464;; Tokenizing needs to be refined so that ";;" is treated as two 461;; Tokenizing needs to be refined so that ";;" is treated as two
465;; tokens and also so as to recognize the \n separator (and 462;; tokens and also so as to recognize the \n separator (and
diff --git a/lisp/progmodes/pascal.el b/lisp/progmodes/pascal.el
index d19fa08bf6c..acd49e71dd8 100644
--- a/lisp/progmodes/pascal.el
+++ b/lisp/progmodes/pascal.el
@@ -223,7 +223,7 @@ The name of the function or case is included between the braces."
223 "*List of contexts where auto lineup of :'s or ='s should be done. 223 "*List of contexts where auto lineup of :'s or ='s should be done.
224Elements can be of type: 'paramlist', 'declaration' or 'case', which will 224Elements can be of type: 'paramlist', 'declaration' or 'case', which will
225do auto lineup in parameterlist, declarations or case-statements 225do auto lineup in parameterlist, declarations or case-statements
226respectively. The word 'all' will do all lineups. '(case paramlist) for 226respectively. The word 'all' will do all lineups. '(case paramlist) for
227instance will do lineup in case-statements and parameterlist, while '(all) 227instance will do lineup in case-statements and parameterlist, while '(all)
228will do all lineups." 228will do all lineups."
229 :type '(set :extra-offset 8 229 :type '(set :extra-offset 8
@@ -311,7 +311,7 @@ are handled in another way, and should not be added to this list."
311 311
312 312
313;;;###autoload 313;;;###autoload
314(defun pascal-mode () 314(define-derived-mode pascal-mode prog-mode "Pascal"
315 "Major mode for editing Pascal code. \\<pascal-mode-map> 315 "Major mode for editing Pascal code. \\<pascal-mode-map>
316TAB indents for Pascal code. Delete converts tabs to spaces as it moves back. 316TAB indents for Pascal code. Delete converts tabs to spaces as it moves back.
317 317
@@ -334,60 +334,47 @@ Other useful functions are:
334 334
335Variables controlling indentation/edit style: 335Variables controlling indentation/edit style:
336 336
337 pascal-indent-level (default 3) 337 `pascal-indent-level' (default 3)
338 Indentation of Pascal statements with respect to containing block. 338 Indentation of Pascal statements with respect to containing block.
339 pascal-case-indent (default 2) 339 `pascal-case-indent' (default 2)
340 Indentation for case statements. 340 Indentation for case statements.
341 pascal-auto-newline (default nil) 341 `pascal-auto-newline' (default nil)
342 Non-nil means automatically newline after semicolons and the punctuation 342 Non-nil means automatically newline after semicolons and the punctuation
343 mark after an end. 343 mark after an end.
344 pascal-indent-nested-functions (default t) 344 `pascal-indent-nested-functions' (default t)
345 Non-nil means nested functions are indented. 345 Non-nil means nested functions are indented.
346 pascal-tab-always-indent (default t) 346 `pascal-tab-always-indent' (default t)
347 Non-nil means TAB in Pascal mode should always reindent the current line, 347 Non-nil means TAB in Pascal mode should always reindent the current line,
348 regardless of where in the line point is when the TAB command is used. 348 regardless of where in the line point is when the TAB command is used.
349 pascal-auto-endcomments (default t) 349 `pascal-auto-endcomments' (default t)
350 Non-nil means a comment { ... } is set after the ends which ends cases and 350 Non-nil means a comment { ... } is set after the ends which ends cases and
351 functions. The name of the function or case will be set between the braces. 351 functions. The name of the function or case will be set between the braces.
352 pascal-auto-lineup (default t) 352 `pascal-auto-lineup' (default t)
353 List of contexts where auto lineup of :'s or ='s should be done. 353 List of contexts where auto lineup of :'s or ='s should be done.
354 354
355See also the user variables pascal-type-keywords, pascal-start-keywords and 355See also the user variables `pascal-type-keywords', `pascal-start-keywords' and
356pascal-separator-keywords. 356`pascal-separator-keywords'.
357 357
358Turning on Pascal mode calls the value of the variable pascal-mode-hook with 358Turning on Pascal mode calls the value of the variable pascal-mode-hook with
359no args, if that value is non-nil." 359no args, if that value is non-nil."
360 (interactive) 360 (set (make-local-variable 'local-abbrev-table) pascal-mode-abbrev-table)
361 (kill-all-local-variables) 361 (set (make-local-variable 'indent-line-function) 'pascal-indent-line)
362 (use-local-map pascal-mode-map) 362 (set (make-local-variable 'comment-indent-function) 'pascal-indent-comment)
363 (setq major-mode 'pascal-mode) 363 (set (make-local-variable 'parse-sexp-ignore-comments) nil)
364 (setq mode-name "Pascal") 364 (set (make-local-variable 'blink-matching-paren-dont-ignore-comments) t)
365 (setq local-abbrev-table pascal-mode-abbrev-table) 365 (set (make-local-variable 'case-fold-search) t)
366 (set-syntax-table pascal-mode-syntax-table) 366 (set (make-local-variable 'comment-start) "{")
367 (make-local-variable 'indent-line-function) 367 (set (make-local-variable 'comment-start-skip) "(\\*+ *\\|{ *")
368 (setq indent-line-function 'pascal-indent-line) 368 (set (make-local-variable 'comment-end) "}")
369 (make-local-variable 'comment-indent-function)
370 (setq comment-indent-function 'pascal-indent-comment)
371 (make-local-variable 'parse-sexp-ignore-comments)
372 (setq parse-sexp-ignore-comments nil)
373 (make-local-variable 'blink-matching-paren-dont-ignore-comments)
374 (setq blink-matching-paren-dont-ignore-comments t)
375 (make-local-variable 'case-fold-search)
376 (setq case-fold-search t)
377 (make-local-variable 'comment-start)
378 (setq comment-start "{")
379 (make-local-variable 'comment-start-skip)
380 (setq comment-start-skip "(\\*+ *\\|{ *")
381 (make-local-variable 'comment-end)
382 (setq comment-end "}")
383 ;; Font lock support 369 ;; Font lock support
384 (make-local-variable 'font-lock-defaults) 370 (set (make-local-variable 'font-lock-defaults)
385 (setq font-lock-defaults '(pascal-font-lock-keywords nil t)) 371 '(pascal-font-lock-keywords nil t))
386 ;; Imenu support 372 ;; Imenu support
387 (make-local-variable 'imenu-generic-expression) 373 (set (make-local-variable 'imenu-generic-expression)
388 (setq imenu-generic-expression pascal-imenu-generic-expression) 374 pascal-imenu-generic-expression)
389 (setq imenu-case-fold-search t) 375 (set (make-local-variable 'imenu-case-fold-search) t)
390 (run-mode-hooks 'pascal-mode-hook)) 376 ;; Pascal-mode's own hide/show support.
377 (add-to-invisibility-spec '(pascal . t)))
391 378
392 379
393 380
@@ -1478,18 +1465,12 @@ Pascal Outline mode provides some additional commands.
1478 (unless pascal-outline-mode 1465 (unless pascal-outline-mode
1479 (pascal-show-all))) 1466 (pascal-show-all)))
1480 1467
1481(defun pascal-outline-change (b e pascal-flag) 1468(defun pascal-outline-change (b e hide)
1482 (save-excursion
1483 ;; This used to use selective display so the boundaries used by the
1484 ;; callers didn't have to be precise, since it just looked for \n or \^M
1485 ;; and switched them.
1486 (goto-char b) (setq b (line-end-position))
1487 (goto-char e) (setq e (line-end-position)))
1488 (when (> e b) 1469 (when (> e b)
1489 ;; We could try and optimize this in the case where the region is 1470 ;; We could try and optimize this in the case where the region is
1490 ;; already hidden. But I'm not sure it's worth the trouble. 1471 ;; already hidden. But I'm not sure it's worth the trouble.
1491 (remove-overlays b e 'invisible 'pascal) 1472 (remove-overlays b e 'invisible 'pascal)
1492 (when (eq pascal-flag ?\^M) 1473 (when hide
1493 (let ((ol (make-overlay b e nil t nil))) 1474 (let ((ol (make-overlay b e nil t nil)))
1494 (overlay-put ol 'invisible 'pascal) 1475 (overlay-put ol 'invisible 'pascal)
1495 (overlay-put ol 'evaporate t))))) 1476 (overlay-put ol 'evaporate t)))))
@@ -1497,7 +1478,7 @@ Pascal Outline mode provides some additional commands.
1497(defun pascal-show-all () 1478(defun pascal-show-all ()
1498 "Show all of the text in the buffer." 1479 "Show all of the text in the buffer."
1499 (interactive) 1480 (interactive)
1500 (pascal-outline-change (point-min) (point-max) ?\n)) 1481 (pascal-outline-change (point-min) (point-max) nil))
1501 1482
1502(defun pascal-hide-other-defuns () 1483(defun pascal-hide-other-defuns ()
1503 "Show only the current defun." 1484 "Show only the current defun."
@@ -1505,42 +1486,45 @@ Pascal Outline mode provides some additional commands.
1505 (save-excursion 1486 (save-excursion
1506 (let ((beg (progn (if (not (looking-at "\\(function\\|procedure\\)\\>")) 1487 (let ((beg (progn (if (not (looking-at "\\(function\\|procedure\\)\\>"))
1507 (pascal-beg-of-defun)) 1488 (pascal-beg-of-defun))
1508 (point))) 1489 (line-beginning-position)))
1509 (end (progn (pascal-end-of-defun) 1490 (end (progn (pascal-end-of-defun)
1510 (backward-sexp 1) 1491 (backward-sexp 1)
1511 (search-forward "\n\\|\^M" nil t) 1492 (line-beginning-position 2)))
1512 (point)))
1513 (opoint (point-min))) 1493 (opoint (point-min)))
1494 ;; BEG at BOL.
1495 ;; OPOINT at EOL.
1496 ;; END at BOL.
1514 (goto-char (point-min)) 1497 (goto-char (point-min))
1515 1498
1516 ;; Hide all functions before current function 1499 ;; Hide all functions before current function
1517 (while (re-search-forward "^\\(function\\|procedure\\)\\>" beg 'move) 1500 (while (re-search-forward "^[ \t]*\\(function\\|procedure\\)\\>"
1518 (pascal-outline-change opoint (1- (match-beginning 0)) ?\^M) 1501 beg 'move)
1519 (setq opoint (point)) 1502 (pascal-outline-change opoint (line-end-position 0) t)
1503 (setq opoint (line-end-position))
1520 ;; Functions may be nested 1504 ;; Functions may be nested
1521 (if (> (progn (pascal-end-of-defun) (point)) beg) 1505 (if (> (progn (pascal-end-of-defun) (point)) beg)
1522 (goto-char opoint))) 1506 (goto-char opoint)))
1523 (if (> beg opoint) 1507 (if (> beg opoint)
1524 (pascal-outline-change opoint (1- beg) ?\^M)) 1508 (pascal-outline-change opoint (1- beg) t))
1525 1509
1526 ;; Show current function 1510 ;; Show current function
1527 (pascal-outline-change beg end ?\n) 1511 (pascal-outline-change (1- beg) end nil)
1528 ;; Hide nested functions 1512 ;; Hide nested functions
1529 (forward-char 1) 1513 (forward-char 1)
1530 (while (re-search-forward "^\\(function\\|procedure\\)\\>" end 'move) 1514 (while (re-search-forward "^\\(function\\|procedure\\)\\>" end 'move)
1531 (setq opoint (point)) 1515 (setq opoint (line-end-position))
1532 (pascal-end-of-defun) 1516 (pascal-end-of-defun)
1533 (pascal-outline-change opoint (point) ?\^M)) 1517 (pascal-outline-change opoint (line-end-position) t))
1534 1518
1535 (goto-char end) 1519 (goto-char end)
1536 (setq opoint end) 1520 (setq opoint end)
1537 1521
1538 ;; Hide all function after current function 1522 ;; Hide all function after current function
1539 (while (re-search-forward "^\\(function\\|procedure\\)\\>" nil 'move) 1523 (while (re-search-forward "^\\(function\\|procedure\\)\\>" nil 'move)
1540 (pascal-outline-change opoint (1- (match-beginning 0)) ?\^M) 1524 (pascal-outline-change opoint (line-end-position 0) t)
1541 (setq opoint (point)) 1525 (setq opoint (line-end-position))
1542 (pascal-end-of-defun)) 1526 (pascal-end-of-defun))
1543 (pascal-outline-change opoint (point-max) ?\^M) 1527 (pascal-outline-change opoint (point-max) t)
1544 1528
1545 ;; Hide main program 1529 ;; Hide main program
1546 (if (< (progn (forward-line -1) (point)) end) 1530 (if (< (progn (forward-line -1) (point)) end)
@@ -1548,7 +1532,7 @@ Pascal Outline mode provides some additional commands.
1548 (goto-char beg) 1532 (goto-char beg)
1549 (pascal-end-of-defun) 1533 (pascal-end-of-defun)
1550 (backward-sexp 1) 1534 (backward-sexp 1)
1551 (pascal-outline-change (point) (point-max) ?\^M)))))) 1535 (pascal-outline-change (line-end-position) (point-max) t))))))
1552 1536
1553(defun pascal-outline-next-defun () 1537(defun pascal-outline-next-defun ()
1554 "Move to next function/procedure, hiding all others." 1538 "Move to next function/procedure, hiding all others."
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 77e334ca8d8..f3db7fad135 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -99,12 +99,36 @@ When nil, send actual operating system end of file."
99(defvar prolog-mode-abbrev-table nil) 99(defvar prolog-mode-abbrev-table nil)
100(define-abbrev-table 'prolog-mode-abbrev-table ()) 100(define-abbrev-table 'prolog-mode-abbrev-table ())
101 101
102(defun prolog-smie-forward-token ()
103 (forward-comment (point-max))
104 (buffer-substring-no-properties
105 (point)
106 (progn (cond
107 ((looking-at "[!;]") (forward-char 1))
108 ((not (zerop (skip-chars-forward "#&*+-./:<=>?@\\^`~"))))
109 ((not (zerop (skip-syntax-forward "w_'"))))
110 ;; In case of non-ASCII punctuation.
111 ((not (zerop (skip-syntax-forward ".")))))
112 (point))))
113
114(defun prolog-smie-backward-token ()
115 (forward-comment (- (point-max)))
116 (buffer-substring-no-properties
117 (point)
118 (progn (cond
119 ((memq (char-before) '(?! ?\;)) (forward-char -1))
120 ((not (zerop (skip-chars-backward "#&*+-./:<=>?@\\^`~"))))
121 ((not (zerop (skip-syntax-backward "w_'"))))
122 ;; In case of non-ASCII punctuation.
123 ((not (zerop (skip-syntax-backward ".")))))
124 (point))))
125
102(defconst prolog-smie-op-levels 126(defconst prolog-smie-op-levels
103 ;; Rather than construct the operator levels table from the BNF, 127 ;; Rather than construct the operator levels table from the BNF,
104 ;; we directly provide the operator precedences from GNU Prolog's 128 ;; we directly provide the operator precedences from GNU Prolog's
105 ;; manual. The only problem is that GNU Prolog's manual uses 129 ;; manual (7.14.10 op/3). The only problem is that GNU Prolog's
106 ;; precedence levels in the opposite sense (higher numbers bind less 130 ;; manual uses precedence levels in the opposite sense (higher
107 ;; tightly) than SMIE, so we use negative numbers. 131 ;; numbers bind less tightly) than SMIE, so we use negative numbers.
108 '(("." -10000 -10000) 132 '(("." -10000 -10000)
109 (":-" -1200 -1200) 133 (":-" -1200 -1200)
110 ("-->" -1200 -1200) 134 ("-->" -1200 -1200)
@@ -162,9 +186,18 @@ When nil, send actual operating system end of file."
162 (make-local-variable 'imenu-generic-expression) 186 (make-local-variable 'imenu-generic-expression)
163 (setq imenu-generic-expression '((nil "^\\sw+" 0))) 187 (setq imenu-generic-expression '((nil "^\\sw+" 0)))
164 (smie-setup prolog-smie-op-levels prolog-smie-indent-rules) 188 (smie-setup prolog-smie-op-levels prolog-smie-indent-rules)
189 (set (make-local-variable 'smie-forward-token-function)
190 #'prolog-smie-forward-token)
191 (set (make-local-variable 'smie-backward-token-function)
192 #'prolog-smie-backward-token)
165 (set (make-local-variable 'forward-sexp-function) 193 (set (make-local-variable 'forward-sexp-function)
166 'smie-forward-sexp-command) 194 'smie-forward-sexp-command)
167 (set (make-local-variable 'smie-indent-basic) prolog-indent-width) 195 (set (make-local-variable 'smie-indent-basic) prolog-indent-width)
196 (set (make-local-variable 'smie-blink-matching-triggers) '(?.))
197 (set (make-local-variable 'smie-closer-alist) '((t . ".")))
198 (add-hook 'post-self-insert-hook #'smie-blink-matching-open 'append 'local)
199 ;; There's no real closer in Prolog anyway.
200 (set (make-local-variable 'smie-blink-matching-inners) t)
168 (make-local-variable 'comment-start) 201 (make-local-variable 'comment-start)
169 (setq comment-start "%") 202 (setq comment-start "%")
170 (make-local-variable 'comment-start-skip) 203 (make-local-variable 'comment-start-skip)
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index a80a555c13f..7148027f487 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -5,10 +5,9 @@
5 5
6;; Author: Alex Schroeder <alex@gnu.org> 6;; Author: Alex Schroeder <alex@gnu.org>
7;; Maintainer: Michael Mauger <mmaug@yahoo.com> 7;; Maintainer: Michael Mauger <mmaug@yahoo.com>
8;; Version: 2.6 8;; Version: 2.8
9;; Keywords: comm languages processes 9;; Keywords: comm languages processes
10;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el 10;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el
11;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
12 11
13;; This file is part of GNU Emacs. 12;; This file is part of GNU Emacs.
14 13
@@ -286,6 +285,9 @@ Customizing your password will store it in your ~/.emacs file."
286 285
287(define-widget 'sql-login-params 'lazy 286(define-widget 'sql-login-params 'lazy
288 "Widget definition of the login parameters list" 287 "Widget definition of the login parameters list"
288 ;; FIXME: does not implement :default property for the user,
289 ;; database and server options. Anybody have some guidance on how to
290 ;; do this.
289 :tag "Login Parameters" 291 :tag "Login Parameters"
290 :type '(repeat (choice 292 :type '(repeat (choice
291 (const user) 293 (const user)
@@ -300,7 +302,7 @@ Customizing your password will store it in your ~/.emacs file."
300 (const :format "" server) 302 (const :format "" server)
301 (const :format "" :completion) 303 (const :format "" :completion)
302 (restricted-sexp 304 (restricted-sexp
303 :match-alternatives (listp symbolp)))) 305 :match-alternatives (listp stringp))))
304 (choice :tag "database" 306 (choice :tag "database"
305 (const database) 307 (const database)
306 (list :tag "file" 308 (list :tag "file"
@@ -311,7 +313,7 @@ Customizing your password will store it in your ~/.emacs file."
311 (const :format "" database) 313 (const :format "" database)
312 (const :format "" :completion) 314 (const :format "" :completion)
313 (restricted-sexp 315 (restricted-sexp
314 :match-alternatives (listp symbolp)))) 316 :match-alternatives (listp stringp))))
315 (const port)))) 317 (const port))))
316 318
317;; SQL Product support 319;; SQL Product support
@@ -401,6 +403,8 @@ Customizing your password will store it in your ~/.emacs file."
401 :sqli-options sql-mysql-options 403 :sqli-options sql-mysql-options
402 :sqli-login sql-mysql-login-params 404 :sqli-login sql-mysql-login-params
403 :sqli-comint-func sql-comint-mysql 405 :sqli-comint-func sql-comint-mysql
406 :list-all "SHOW TABLES;"
407 :list-table "DESCRIBE %s;"
404 :prompt-regexp "^mysql> " 408 :prompt-regexp "^mysql> "
405 :prompt-length 6 409 :prompt-length 6
406 :prompt-cont-regexp "^ -> " 410 :prompt-cont-regexp "^ -> "
@@ -428,6 +432,8 @@ Customizing your password will store it in your ~/.emacs file."
428 :sqli-options sql-postgres-options 432 :sqli-options sql-postgres-options
429 :sqli-login sql-postgres-login-params 433 :sqli-login sql-postgres-login-params
430 :sqli-comint-func sql-comint-postgres 434 :sqli-comint-func sql-comint-postgres
435 :list-all ("\\d+" . "\\dS+")
436 :list-table ("\\d+ %s" . "\\dS+ %s")
431 :prompt-regexp "^.*=[#>] " 437 :prompt-regexp "^.*=[#>] "
432 :prompt-length 5 438 :prompt-length 5
433 :prompt-cont-regexp "^.*[-(][#>] " 439 :prompt-cont-regexp "^.*[-(][#>] "
@@ -452,6 +458,8 @@ Customizing your password will store it in your ~/.emacs file."
452 :sqli-options sql-sqlite-options 458 :sqli-options sql-sqlite-options
453 :sqli-login sql-sqlite-login-params 459 :sqli-login sql-sqlite-login-params
454 :sqli-comint-func sql-comint-sqlite 460 :sqli-comint-func sql-comint-sqlite
461 :list-all ".tables"
462 :list-table ".schema %s"
455 :prompt-regexp "^sqlite> " 463 :prompt-regexp "^sqlite> "
456 :prompt-length 8 464 :prompt-length 8
457 :prompt-cont-regexp "^ ...> " 465 :prompt-cont-regexp "^ ...> "
@@ -510,6 +518,23 @@ may be any one of the following:
510 database. Do product specific 518 database. Do product specific
511 configuration of comint in this function. 519 configuration of comint in this function.
512 520
521 :list-all Command string or function which produces
522 a listing of all objects in the database.
523 If it's a cons cell, then the car
524 produces the standard list of objects and
525 the cdr produces an enhanced list of
526 objects. What \"enhanced\" means is
527 dependent on the SQL product and may not
528 exist. In general though, the
529 \"enhanced\" list should include visible
530 objects from other schemas.
531
532 :list-table Command string or function which produces
533 a detailed listing of a specific database
534 table. If its a cons cell, then the car
535 produces the standard list and the cdr
536 produces an enhanced list.
537
513 :prompt-regexp regular expression string that matches 538 :prompt-regexp regular expression string that matches
514 the prompt issued by the product 539 the prompt issued by the product
515 interpreter. 540 interpreter.
@@ -941,7 +966,9 @@ add your name with a \"-U\" prefix (such as \"-Umark\") to the list."
941 :version "20.8" 966 :version "20.8"
942 :group 'SQL) 967 :group 'SQL)
943 968
944(defcustom sql-postgres-login-params '(user database server) 969(defcustom sql-postgres-login-params `((user :default ,(user-login-name))
970 (database :default ,(user-login-name))
971 server)
945 "List of login parameters needed to connect to Postgres." 972 "List of login parameters needed to connect to Postgres."
946 :type 'sql-login-params 973 :type 'sql-login-params
947 :version "24.1" 974 :version "24.1"
@@ -1025,6 +1052,12 @@ Starts `sql-interactive-mode' after doing some setup."
1025 1052
1026;; Passwords are not kept in a history. 1053;; Passwords are not kept in a history.
1027 1054
1055(defvar sql-product-history nil
1056 "History of products used.")
1057
1058(defvar sql-connection-history nil
1059 "History of connections used.")
1060
1028(defvar sql-buffer nil 1061(defvar sql-buffer nil
1029 "Current SQLi buffer. 1062 "Current SQLi buffer.
1030 1063
@@ -1052,11 +1085,24 @@ You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
1052 1085
1053Used by `sql-rename-buffer'.") 1086Used by `sql-rename-buffer'.")
1054 1087
1055(defun sql-buffer-live-p (buffer) 1088(defun sql-buffer-live-p (buffer &optional product)
1056 "Returns non-nil if the process associated with buffer is live." 1089 "Returns non-nil if the process associated with buffer is live.
1057 (and buffer 1090
1058 (buffer-live-p (get-buffer buffer)) 1091BUFFER can be a buffer object or a buffer name. The buffer must
1059 (get-buffer-process buffer))) 1092be a live buffer, have an running process attached to it, be in
1093`sql-interactive-mode', and, if PRODUCT is specified, it's
1094`sql-product' must match."
1095
1096 (when buffer
1097 (setq buffer (get-buffer buffer))
1098 (and buffer
1099 (buffer-live-p buffer)
1100 (get-buffer-process buffer)
1101 (comint-check-proc buffer)
1102 (with-current-buffer buffer
1103 (and (derived-mode-p 'sql-interactive-mode)
1104 (or (not product)
1105 (eq product sql-product)))))))
1060 1106
1061;; Keymap for sql-interactive-mode. 1107;; Keymap for sql-interactive-mode.
1062 1108
@@ -1073,6 +1119,8 @@ Used by `sql-rename-buffer'.")
1073 (define-key map (kbd "O") 'sql-magic-go) 1119 (define-key map (kbd "O") 'sql-magic-go)
1074 (define-key map (kbd "o") 'sql-magic-go) 1120 (define-key map (kbd "o") 'sql-magic-go)
1075 (define-key map (kbd ";") 'sql-magic-semicolon) 1121 (define-key map (kbd ";") 'sql-magic-semicolon)
1122 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1123 (define-key map (kbd "C-c C-l t") 'sql-list-table)
1076 map) 1124 map)
1077 "Mode map used for `sql-interactive-mode'. 1125 "Mode map used for `sql-interactive-mode'.
1078Based on `comint-mode-map'.") 1126Based on `comint-mode-map'.")
@@ -1086,6 +1134,8 @@ Based on `comint-mode-map'.")
1086 (define-key map (kbd "C-c C-s") 'sql-send-string) 1134 (define-key map (kbd "C-c C-s") 'sql-send-string)
1087 (define-key map (kbd "C-c C-b") 'sql-send-buffer) 1135 (define-key map (kbd "C-c C-b") 'sql-send-buffer)
1088 (define-key map (kbd "C-c C-i") 'sql-product-interactive) 1136 (define-key map (kbd "C-c C-i") 'sql-product-interactive)
1137 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1138 (define-key map (kbd "C-c C-l t") 'sql-list-table)
1089 map) 1139 map)
1090 "Mode map used for `sql-mode'.") 1140 "Mode map used for `sql-mode'.")
1091 1141
@@ -1101,6 +1151,9 @@ Based on `comint-mode-map'.")
1101 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] 1151 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)]
1102 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] 1152 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)]
1103 "--" 1153 "--"
1154 ["List all objects" sql-list-all (sql-buffer-live-p sql-buffer)]
1155 ["List table details" sql-list-table (sql-buffer-live-p sql-buffer)]
1156 "--"
1104 ["Start SQLi session" sql-product-interactive 1157 ["Start SQLi session" sql-product-interactive
1105 :visible (not sql-connection-alist) 1158 :visible (not sql-connection-alist)
1106 :enable (sql-get-product-feature sql-product :sqli-comint-func)] 1159 :enable (sql-get-product-feature sql-product :sqli-comint-func)]
@@ -1139,7 +1192,10 @@ Based on `comint-mode-map'.")
1139 "Menu for `sql-interactive-mode'." 1192 "Menu for `sql-interactive-mode'."
1140 '("SQL" 1193 '("SQL"
1141 ["Rename Buffer" sql-rename-buffer t] 1194 ["Rename Buffer" sql-rename-buffer t]
1142 ["Save Connection" sql-save-connection (not sql-connection)])) 1195 ["Save Connection" sql-save-connection (not sql-connection)]
1196 "--"
1197 ["List all objects" sql-list-all t]
1198 ["List table details" sql-list-table t]))
1143 1199
1144;; Abbreviations -- if you want more of them, define them in your 1200;; Abbreviations -- if you want more of them, define them in your
1145;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. 1201;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
@@ -2122,6 +2178,16 @@ highlighting rules in SQL mode.")
2122 2178
2123;;; SQL Product support functions 2179;;; SQL Product support functions
2124 2180
2181(defun sql-read-product (prompt &optional initial)
2182 "Read a valid SQL product."
2183 (let ((init (or (and initial (symbol-name initial)) "ansi")))
2184 (intern (completing-read
2185 prompt
2186 (mapcar (lambda (info) (symbol-name (car info)))
2187 sql-product-alist)
2188 nil 'require-match
2189 init 'sql-product-history init))))
2190
2125(defun sql-add-product (product display &rest plist) 2191(defun sql-add-product (product display &rest plist)
2126 "Add support for a database product in `sql-mode'. 2192 "Add support for a database product in `sql-mode'.
2127 2193
@@ -2312,10 +2378,9 @@ adds a fontification pattern to fontify identifiers ending in
2312 (mapcar 2378 (mapcar
2313 (lambda (param) 2379 (lambda (param)
2314 (let ((token (or (and (listp param) (car param)) param)) 2380 (let ((token (or (and (listp param) (car param)) param))
2315 (type (or (and (listp param) (nth 1 param)) nil)) 2381 (plist (or (and (listp param) (cdr param)) nil)))
2316 (arg (or (and (listp param) (nth 2 param)) nil)))
2317 2382
2318 (funcall body token type arg))) 2383 (funcall body token plist)))
2319 login-params))) 2384 login-params)))
2320 2385
2321 2386
@@ -2335,11 +2400,7 @@ adds a fontification pattern to fontify identifiers ending in
2335(defun sql-set-product (product) 2400(defun sql-set-product (product)
2336 "Set `sql-product' to PRODUCT and enable appropriate highlighting." 2401 "Set `sql-product' to PRODUCT and enable appropriate highlighting."
2337 (interactive 2402 (interactive
2338 (list (completing-read "SQL product: " 2403 (list (sql-read-product "SQL product: ")))
2339 (mapcar (lambda (info) (symbol-name (car info)))
2340 sql-product-alist)
2341 nil 'require-match
2342 (or (and sql-product (symbol-name sql-product)) "ansi"))))
2343 (if (stringp product) (setq product (intern product))) 2404 (if (stringp product) (setq product (intern product)))
2344 (when (not (assoc product sql-product-alist)) 2405 (when (not (assoc product sql-product-alist))
2345 (error "SQL product %s is not supported; treated as ANSI" product) 2406 (error "SQL product %s is not supported; treated as ANSI" product)
@@ -2479,37 +2540,53 @@ appended to the SQLi buffer without disturbing your SQL buffer."
2479 "Read a password using PROMPT. Optional DEFAULT is password to start with." 2540 "Read a password using PROMPT. Optional DEFAULT is password to start with."
2480 (read-passwd prompt nil default)) 2541 (read-passwd prompt nil default))
2481 2542
2482(defun sql-get-login-ext (prompt last-value history-var type arg) 2543(defun sql-get-login-ext (prompt last-value history-var plist)
2483 "Prompt user with extended login parameters. 2544 "Prompt user with extended login parameters.
2484 2545
2485If TYPE is nil, then the user is simply prompted for a string 2546If PLIST is nil, then the user is simply prompted for a string
2486value. 2547value.
2487 2548
2488If TYPE is `:file', then the user is prompted for a file 2549The property `:default' specifies the default value. If the
2489name that must match the regexp pattern specified in the ARG 2550`:number' property is non-nil then ask for a number.
2490argument.
2491 2551
2492If TYPE is `:completion', then the user is prompted for a string 2552The `:file' property prompts for a file name that must match the
2493specified by ARG. (ARG is used as the PREDICATE argument to 2553regexp pattern specified in its value.
2494`completing-read'.)"
2495 (cond
2496 ((eq type nil)
2497 (read-from-minibuffer prompt last-value nil nil history-var))
2498 2554
2499 ((eq type :file) 2555The `:completion' property prompts for a string specified by its
2500 (let ((use-dialog-box nil)) 2556value. (The property value is used as the PREDICATE argument to
2557`completing-read'.)"
2558 (let* ((default (plist-get plist :default))
2559 (prompt-def
2560 (if default
2561 (if (string-match "\\(\\):[ \t]*\\'" prompt)
2562 (replace-match (format " (default \"%s\")" default) t t prompt 1)
2563 (replace-regexp-in-string "[ \t]*\\'"
2564 (format " (default \"%s\") " default)
2565 prompt t t))
2566 prompt))
2567 (use-dialog-box nil))
2568 (cond
2569 ((plist-member plist :file)
2501 (expand-file-name 2570 (expand-file-name
2502 (read-file-name prompt 2571 (read-file-name prompt
2503 (file-name-directory last-value) nil t 2572 (file-name-directory last-value) default t
2504 (file-name-nondirectory last-value) 2573 (file-name-nondirectory last-value)
2505 (if arg 2574 (when (plist-get plist :file)
2506 `(lambda (f) 2575 `(lambda (f)
2507 (string-match (concat "\\<" ,arg "\\>") 2576 (string-match
2508 (file-name-nondirectory f))) 2577 (concat "\\<" ,(plist-get plist :file) "\\>")
2509 nil))))) 2578 (file-name-nondirectory f)))))))
2510 2579
2511 ((eq type :completion) 2580 ((plist-member plist :completion)
2512 (completing-read prompt arg nil t last-value history-var)))) 2581 (completing-read prompt-def (plist-get plist :completion) nil t
2582 last-value history-var default))
2583
2584 ((plist-get plist :number)
2585 (read-number prompt (or default last-value 0)))
2586
2587 (t
2588 (let ((r (read-from-minibuffer prompt-def last-value nil nil history-var nil)))
2589 (if (string= "" r) (or default "") r))))))
2513 2590
2514(defun sql-get-login (&rest what) 2591(defun sql-get-login (&rest what)
2515 "Get username, password and database from the user. 2592 "Get username, password and database from the user.
@@ -2528,72 +2605,69 @@ symbol `password', for the server if it contains the symbol
2528`database'. The members of WHAT are processed in the order in 2605`database'. The members of WHAT are processed in the order in
2529which they are provided. 2606which they are provided.
2530 2607
2531The tokens for `database' and `server' may also be lists to 2608Each token may also be a list with the token in the car and a
2532control or limit the values that can be supplied. These can be 2609plist of options as the cdr. The following properties are
2533of the form: 2610supported:
2534
2535 \(database :file \".+\\\\.EXT\")
2536 \(database :completion FUNCTION)
2537 2611
2538The `server' token supports the same forms. 2612 :file <filename-regexp>
2613 :completion <list-of-strings-or-function>
2614 :default <default-value>
2615 :number t
2539 2616
2540In order to ask the user for username, password and database, call the 2617In order to ask the user for username, password and database, call the
2541function like this: (sql-get-login 'user 'password 'database)." 2618function like this: (sql-get-login 'user 'password 'database)."
2542 (interactive) 2619 (interactive)
2543 (mapcar 2620 (mapcar
2544 (lambda (w) 2621 (lambda (w)
2545 (let ((token (or (and (listp w) (car w)) w)) 2622 (let ((token (or (and (consp w) (car w)) w))
2546 (type (or (and (listp w) (nth 1 w)) nil)) 2623 (plist (or (and (consp w) (cdr w)) nil)))
2547 (arg (or (and (listp w) (nth 2 w)) nil))) 2624
2548 2625 (cond
2549 (cond 2626 ((eq token 'user) ; user
2550 ((eq token 'user) ; user 2627 (setq sql-user
2551 (setq sql-user 2628 (sql-get-login-ext "User: " sql-user
2552 (read-from-minibuffer "User: " sql-user nil nil 2629 'sql-user-history plist)))
2553 'sql-user-history))) 2630
2554 2631 ((eq token 'password) ; password
2555 ((eq token 'password) ; password 2632 (setq sql-password
2556 (setq sql-password 2633 (sql-read-passwd "Password: " sql-password)))
2557 (sql-read-passwd "Password: " sql-password))) 2634
2558 2635 ((eq token 'server) ; server
2559 ((eq token 'server) ; server 2636 (setq sql-server
2560 (setq sql-server 2637 (sql-get-login-ext "Server: " sql-server
2561 (sql-get-login-ext "Server: " sql-server 2638 'sql-server-history plist)))
2562 'sql-server-history type arg))) 2639
2563 2640 ((eq token 'database) ; database
2564 ((eq token 'database) ; database 2641 (setq sql-database
2565 (setq sql-database 2642 (sql-get-login-ext "Database: " sql-database
2566 (sql-get-login-ext "Database: " sql-database 2643 'sql-database-history plist)))
2567 'sql-database-history type arg))) 2644
2568 2645 ((eq token 'port) ; port
2569 ((eq token 'port) ; port 2646 (setq sql-port
2570 (setq sql-port 2647 (sql-get-login-ext "Port: " sql-port
2571 (read-number "Port: " (if (numberp sql-port) 2648 nil (append '(:number t) plist)))))))
2572 sql-port 2649 what))
2573 0))))))) 2650
2574 what)) 2651(defun sql-find-sqli-buffer (&optional product)
2575
2576(defun sql-find-sqli-buffer ()
2577 "Returns the name of the current default SQLi buffer or nil. 2652 "Returns the name of the current default SQLi buffer or nil.
2578In order to qualify, the SQLi buffer must be alive, be in 2653In order to qualify, the SQLi buffer must be alive, be in
2579`sql-interactive-mode' and have a process." 2654`sql-interactive-mode' and have a process."
2580 (let ((default-buffer (default-value 'sql-buffer)) 2655 (let ((buf sql-buffer)
2581 (current-product sql-product)) 2656 (prod (or product sql-product)))
2582 (if (sql-buffer-live-p default-buffer) 2657 (or
2583 default-buffer 2658 ;; Current sql-buffer, if there is one.
2584 (save-current-buffer 2659 (and (sql-buffer-live-p buf prod)
2585 (let ((buflist (buffer-list)) 2660 buf)
2586 (found)) 2661 ;; Global sql-buffer
2587 (while (not (or (null buflist) 2662 (and (setq buf (default-value 'sql-buffer))
2588 found)) 2663 (sql-buffer-live-p buf prod)
2589 (let ((candidate (car buflist))) 2664 buf)
2590 (set-buffer candidate) 2665 ;; Look thru each buffer
2591 (if (and (sql-buffer-live-p candidate) 2666 (car (apply 'append
2592 (derived-mode-p 'sql-interactive-mode) 2667 (mapcar (lambda (b)
2593 (eq sql-product current-product)) 2668 (and (sql-buffer-live-p b prod)
2594 (setq found (buffer-name candidate))) 2669 (list (buffer-name b))))
2595 (setq buflist (cdr buflist)))) 2670 (buffer-list)))))))
2596 found)))))
2597 2671
2598(defun sql-set-sqli-buffer-generally () 2672(defun sql-set-sqli-buffer-generally ()
2599 "Set SQLi buffer for all SQL buffers that have none. 2673 "Set SQLi buffer for all SQL buffers that have none.
@@ -2611,10 +2685,11 @@ using `sql-find-sqli-buffer'. If `sql-buffer' is set,
2611 (let ((candidate (car buflist))) 2685 (let ((candidate (car buflist)))
2612 (set-buffer candidate) 2686 (set-buffer candidate)
2613 (if (and (derived-mode-p 'sql-mode) 2687 (if (and (derived-mode-p 'sql-mode)
2614 (not (buffer-live-p sql-buffer))) 2688 (not (sql-buffer-live-p sql-buffer)))
2615 (progn 2689 (progn
2616 (setq sql-buffer default-buffer) 2690 (setq sql-buffer default-buffer)
2617 (run-hooks 'sql-set-sqli-hook)))) 2691 (when default-buffer
2692 (run-hooks 'sql-set-sqli-hook)))))
2618 (setq buflist (cdr buflist)))))) 2693 (setq buflist (cdr buflist))))))
2619 2694
2620(defun sql-set-sqli-buffer () 2695(defun sql-set-sqli-buffer ()
@@ -2632,19 +2707,13 @@ If you call it from anywhere else, it sets the global copy of
2632 (interactive) 2707 (interactive)
2633 (let ((default-buffer (sql-find-sqli-buffer))) 2708 (let ((default-buffer (sql-find-sqli-buffer)))
2634 (if (null default-buffer) 2709 (if (null default-buffer)
2635 (error "There is no suitable SQLi buffer")) 2710 (error "There is no suitable SQLi buffer")
2636 (let ((new-buffer 2711 (let ((new-buffer (read-buffer "New SQLi buffer: " default-buffer t)))
2637 (get-buffer 2712 (if (null (sql-buffer-live-p new-buffer))
2638 (read-buffer "New SQLi buffer: " default-buffer t)))) 2713 (error "Buffer %s is not a working SQLi buffer" new-buffer)
2639 (if (null (get-buffer-process new-buffer)) 2714 (when new-buffer
2640 (error "Buffer %s has no process" (buffer-name new-buffer))) 2715 (setq sql-buffer new-buffer)
2641 (if (null (with-current-buffer new-buffer 2716 (run-hooks 'sql-set-sqli-hook)))))))
2642 (derived-mode-p 'sql-interactive-mode)))
2643 (error "Buffer %s is no SQLi buffer" (buffer-name new-buffer)))
2644 (if new-buffer
2645 (progn
2646 (setq sql-buffer (buffer-name new-buffer))
2647 (run-hooks 'sql-set-sqli-hook))))))
2648 2717
2649(defun sql-show-sqli-buffer () 2718(defun sql-show-sqli-buffer ()
2650 "Show the name of current SQLi buffer. 2719 "Show the name of current SQLi buffer.
@@ -2682,7 +2751,7 @@ server/database name."
2682 (apply 'append nil 2751 (apply 'append nil
2683 (sql-for-each-login 2752 (sql-for-each-login
2684 (sql-get-product-feature sql-product :sqli-login) 2753 (sql-get-product-feature sql-product :sqli-login)
2685 (lambda (token type arg) 2754 (lambda (token plist)
2686 (cond 2755 (cond
2687 ((eq token 'user) 2756 ((eq token 'user)
2688 (unless (string= "" sql-user) 2757 (unless (string= "" sql-user)
@@ -2694,13 +2763,13 @@ server/database name."
2694 ((eq token 'server) 2763 ((eq token 'server)
2695 (unless (string= "" sql-server) 2764 (unless (string= "" sql-server)
2696 (list "." 2765 (list "."
2697 (if (eq type :file) 2766 (if (plist-member plist :file)
2698 (file-name-nondirectory sql-server) 2767 (file-name-nondirectory sql-server)
2699 sql-server)))) 2768 sql-server))))
2700 ((eq token 'database) 2769 ((eq token 'database)
2701 (unless (string= "" sql-database) 2770 (unless (string= "" sql-database)
2702 (list "@" 2771 (list "@"
2703 (if (eq type :file) 2772 (if (plist-member plist :file)
2704 (file-name-nondirectory sql-database) 2773 (file-name-nondirectory sql-database)
2705 sql-database)))) 2774 sql-database))))
2706 2775
@@ -2742,13 +2811,13 @@ NEW-NAME is empty, then the buffer name will be \"*SQL*\"."
2742 (if (not (derived-mode-p 'sql-interactive-mode)) 2811 (if (not (derived-mode-p 'sql-interactive-mode))
2743 (message "Current buffer is not a SQL interactive buffer") 2812 (message "Current buffer is not a SQL interactive buffer")
2744 2813
2745 (cond 2814 (setq sql-alternate-buffer-name
2746 ((stringp new-name) 2815 (cond
2747 (setq sql-alternate-buffer-name new-name)) 2816 ((stringp new-name) new-name)
2748 ((listp new-name) 2817 ((consp new-name)
2749 (setq sql-alternate-buffer-name
2750 (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): " 2818 (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): "
2751 sql-alternate-buffer-name)))) 2819 sql-alternate-buffer-name))
2820 (t sql-alternate-buffer-name)))
2752 2821
2753 (rename-buffer (if (string= "" sql-alternate-buffer-name) 2822 (rename-buffer (if (string= "" sql-alternate-buffer-name)
2754 "*SQL*" 2823 "*SQL*"
@@ -2994,6 +3063,171 @@ If given the optional parameter VALUE, sets
2994 3063
2995 3064
2996 3065
3066;;; Redirect output functions
3067
3068(defun sql-redirect (command combuf &optional outbuf save-prior)
3069 "Execute the SQL command and send output to OUTBUF.
3070
3071COMBUF must be an active SQL interactive buffer. OUTBUF may be
3072an existing buffer, or the name of a non-existing buffer. If
3073omitted the output is sent to a temporary buffer which will be
3074killed after the command completes. COMMAND should be a string
3075of commands accepted by the SQLi program."
3076
3077 (with-current-buffer combuf
3078 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
3079 (proc (get-buffer-process (current-buffer)))
3080 (comint-prompt-regexp (sql-get-product-feature sql-product
3081 :prompt-regexp))
3082 (start nil))
3083 (with-current-buffer buf
3084 (toggle-read-only -1)
3085 (unless save-prior
3086 (erase-buffer))
3087 (goto-char (point-max))
3088 (unless (zerop (buffer-size))
3089 (insert "\n"))
3090 (setq start (point)))
3091
3092 ;; Run the command
3093 (message "Executing SQL command...")
3094 (comint-redirect-send-command-to-process command buf proc nil t)
3095 (while (null comint-redirect-completed)
3096 (accept-process-output nil 1))
3097 (message "Executing SQL command...done")
3098
3099 ;; Clean up the output results
3100 (with-current-buffer buf
3101 ;; Remove trailing whitespace
3102 (goto-char (point-max))
3103 (when (looking-back "[ \t\f\n\r]*" start)
3104 (delete-region (match-beginning 0) (match-end 0)))
3105 ;; Remove echo if there was one
3106 (goto-char start)
3107 (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
3108 (delete-region (match-beginning 0) (match-end 0)))
3109 (goto-char start)))))
3110
3111(defun sql-redirect-value (command combuf regexp &optional regexp-groups)
3112 "Execute the SQL command and return part of result.
3113
3114COMBUF must be an active SQL interactive buffer. COMMAND should
3115be a string of commands accepted by the SQLi program. From the
3116output, the REGEXP is repeatedly matched and the list of
3117REGEXP-GROUPS submatches is returned. This behaves much like
3118\\[comint-redirect-results-list-from-process] but instead of
3119returning a single submatch it returns a list of each submatch
3120for each match."
3121
3122 (let ((outbuf " *SQL-Redirect-values*")
3123 (results nil))
3124 (sql-redirect command combuf outbuf nil)
3125 (with-current-buffer outbuf
3126 (while (re-search-forward regexp nil t)
3127 (push
3128 (cond
3129 ;; no groups-return all of them
3130 ((null regexp-groups)
3131 (let ((i 1)
3132 (r nil))
3133 (while (match-beginning i)
3134 (push (match-string i) r))
3135 (nreverse r)))
3136 ;; one group specified
3137 ((numberp regexp-groups)
3138 (match-string regexp-groups))
3139 ;; list of numbers; return the specified matches only
3140 ((consp regexp-groups)
3141 (mapcar (lambda (c)
3142 (cond
3143 ((numberp c) (match-string c))
3144 ((stringp c) (match-substitute-replacement c))
3145 (t (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" c))))
3146 regexp-groups))
3147 ;; String is specified; return replacement string
3148 ((stringp regexp-groups)
3149 (match-substitute-replacement regexp-groups))
3150 (t
3151 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
3152 regexp-groups)))
3153 results)))
3154 (nreverse results)))
3155
3156(defun sql-execute (sqlbuf outbuf command arg)
3157 "Executes a command in a SQL interacive buffer and captures the output.
3158
3159The commands are run in SQLBUF and the output saved in OUTBUF.
3160COMMAND must be a string, a function or a list of such elements.
3161Functions are called with SQLBUF, OUTBUF and ARG as parameters;
3162strings are formatted with ARG and executed.
3163
3164If the results are empty the OUTBUF is deleted, otherwise the
3165buffer is popped into a view window. "
3166 (mapc
3167 (lambda (c)
3168 (cond
3169 ((stringp c)
3170 (sql-redirect (if arg (format c arg) c) sqlbuf outbuf) t)
3171 ((functionp c)
3172 (apply c sqlbuf outbuf arg))
3173 (t (error "Unknown sql-execute item %s" c))))
3174 (if (consp command) command (cons command nil)))
3175
3176 (setq outbuf (get-buffer outbuf))
3177 (if (zerop (buffer-size outbuf))
3178 (kill-buffer outbuf)
3179 (let ((one-win (eq (selected-window)
3180 (get-lru-window))))
3181 (with-current-buffer outbuf
3182 (set-buffer-modified-p nil)
3183 (toggle-read-only 1))
3184 (view-buffer-other-window outbuf)
3185 (when one-win
3186 (shrink-window-if-larger-than-buffer)))))
3187
3188(defun sql-execute-feature (sqlbuf outbuf feature enhanced arg)
3189 "List objects or details in a separate display buffer."
3190 (let (command)
3191 (with-current-buffer sqlbuf
3192 (setq command (sql-get-product-feature sql-product feature)))
3193 (unless command
3194 (error "%s does not support %s" sql-product feature))
3195 (when (consp command)
3196 (setq command (if enhanced
3197 (cdr command)
3198 (car command))))
3199 (sql-execute sqlbuf outbuf command arg)))
3200
3201(defun sql-read-table-name (prompt)
3202 "Read the name of a database table."
3203 ;; TODO: Fetch table/view names from database and provide completion.
3204 ;; Also implement thing-at-point if the buffer has valid names in it
3205 ;; (i.e. sql-mode, sql-interactive-mode, or sql-list-all buffers)
3206 (read-from-minibuffer prompt))
3207
3208(defun sql-list-all (&optional enhanced)
3209 "List all database objects."
3210 (interactive "P")
3211 (let ((sqlbuf (sql-find-sqli-buffer)))
3212 (unless sqlbuf
3213 (error "No SQL interactive buffer found"))
3214 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil)))
3215
3216(defun sql-list-table (name &optional enhanced)
3217 "List the details of a database table. "
3218 (interactive
3219 (list (sql-read-table-name "Table name: ")
3220 current-prefix-arg))
3221 (let ((sqlbuf (sql-find-sqli-buffer)))
3222 (unless sqlbuf
3223 (error "No SQL interactive buffer found"))
3224 (unless name
3225 (error "No table name specified"))
3226 (sql-execute-feature sqlbuf (format "*List %s*" name)
3227 :list-table enhanced name)))
3228
3229
3230
2997;;; SQL mode -- uses SQL interactive mode 3231;;; SQL mode -- uses SQL interactive mode
2998 3232
2999;;;###autoload 3233;;;###autoload
@@ -3221,6 +3455,14 @@ Sentinels will always get the two parameters PROCESS and EVENT."
3221 3455
3222;;; Connection handling 3456;;; Connection handling
3223 3457
3458(defun sql-read-connection (prompt &optional initial default)
3459 "Read a connection name."
3460 (let ((completion-ignore-case t))
3461 (completing-read prompt
3462 (mapcar (lambda (c) (car c))
3463 sql-connection-alist)
3464 nil t initial 'sql-connection-history default)))
3465
3224;;;###autoload 3466;;;###autoload
3225(defun sql-connect (connection) 3467(defun sql-connect (connection)
3226 "Connect to an interactive session using CONNECTION settings. 3468 "Connect to an interactive session using CONNECTION settings.
@@ -3234,12 +3476,7 @@ is specified in the connection settings."
3234 ;; Prompt for the connection from those defined in the alist 3476 ;; Prompt for the connection from those defined in the alist
3235 (interactive 3477 (interactive
3236 (if sql-connection-alist 3478 (if sql-connection-alist
3237 (list 3479 (list (sql-read-connection "Connection: " nil '(nil)))
3238 (let ((completion-ignore-case t))
3239 (completing-read "Connection: "
3240 (mapcar (lambda (c) (car c))
3241 sql-connection-alist)
3242 nil t nil nil '(()))))
3243 nil)) 3480 nil))
3244 3481
3245 ;; Are there connections defined 3482 ;; Are there connections defined
@@ -3273,10 +3510,10 @@ is specified in the connection settings."
3273 ;; the remaining params (w/o the connection params) 3510 ;; the remaining params (w/o the connection params)
3274 (rem-params (sql-for-each-login 3511 (rem-params (sql-for-each-login
3275 login-params 3512 login-params
3276 (lambda (token type arg) 3513 (lambda (token plist)
3277 (unless (member token set-params) 3514 (unless (member token set-params)
3278 (if (or type arg) 3515 (if plist
3279 (list token type arg) 3516 (cons token plist)
3280 token))))) 3517 token)))))
3281 ;; Remember the connection 3518 ;; Remember the connection
3282 (sql-connection connection)) 3519 (sql-connection connection))
@@ -3317,7 +3554,7 @@ optionally is saved to the user's init file."
3317 (append (list name) 3554 (append (list name)
3318 (sql-for-each-login 3555 (sql-for-each-login
3319 `(product ,@login) 3556 `(product ,@login)
3320 (lambda (token type arg) 3557 (lambda (token plist)
3321 (cond 3558 (cond
3322 ((eq token 'product) `(sql-product ',sql-product)) 3559 ((eq token 'product) `(sql-product ',sql-product))
3323 ((eq token 'user) `(sql-user ,sql-user)) 3560 ((eq token 'user) `(sql-user ,sql-user))
@@ -3365,10 +3602,10 @@ the call to \\[sql-product-interactive] with
3365 3602
3366 ;; Handle universal arguments if specified 3603 ;; Handle universal arguments if specified
3367 (when (not (or executing-kbd-macro noninteractive)) 3604 (when (not (or executing-kbd-macro noninteractive))
3368 (when (and (listp product) 3605 (when (and (consp product)
3369 (not (cdr product)) 3606 (not (cdr product))
3370 (numberp (car product))) 3607 (numberp (car product)))
3371 (when (>= (car product) 16) 3608 (when (>= (prefix-numeric-value product) 16)
3372 (when (not new-name) 3609 (when (not new-name)
3373 (setq new-name '(4))) 3610 (setq new-name '(4)))
3374 (setq product '(4))))) 3611 (setq product '(4)))))
@@ -3376,61 +3613,53 @@ the call to \\[sql-product-interactive] with
3376 ;; Get the value of product that we need 3613 ;; Get the value of product that we need
3377 (setq product 3614 (setq product
3378 (cond 3615 (cond
3379 ((equal product '(4)) ; C-u, prompt for product
3380 (intern (completing-read "SQL product: "
3381 (mapcar (lambda (info) (symbol-name (car info)))
3382 sql-product-alist)
3383 nil 'require-match
3384 (or (and sql-product
3385 (symbol-name sql-product))
3386 "ansi"))))
3387 ((and product ; Product specified 3616 ((and product ; Product specified
3388 (symbolp product)) product) 3617 (symbolp product)) product)
3618 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product
3619 (sql-read-product "SQL product: " sql-product))
3389 (t sql-product))) ; Default to sql-product 3620 (t sql-product))) ; Default to sql-product
3390 3621
3391 ;; If we have a product and it has a interactive mode 3622 ;; If we have a product and it has a interactive mode
3392 (if product 3623 (if product
3393 (when (sql-get-product-feature product :sqli-comint-func) 3624 (when (sql-get-product-feature product :sqli-comint-func)
3394 ;; If no new name specified, fall back on sql-buffer if its for 3625 ;; If no new name specified, try to pop to an active SQL
3395 ;; the same product 3626 ;; interactive for the same product
3396 (if (and (not new-name) 3627 (let ((buf (sql-find-sqli-buffer product)))
3397 sql-buffer 3628 (if (and (not new-name) buf)
3398 (sql-buffer-live-p sql-buffer) 3629 (pop-to-buffer buf)
3399 (comint-check-proc sql-buffer) 3630
3400 (eq product (with-current-buffer sql-buffer sql-product))) 3631 ;; We have a new name or sql-buffer doesn't exist or match
3401 (pop-to-buffer sql-buffer) 3632 ;; Start by remembering where we start
3402 3633 (let ((start-buffer (current-buffer))
3403 ;; We have a new name or sql-buffer doesn't exist or match 3634 new-sqli-buffer)
3404 ;; Start by remembering where we start 3635
3405 (let* ((start-buffer (current-buffer)) 3636 ;; Get credentials.
3406 new-sqli-buffer) 3637 (apply 'sql-get-login (sql-get-product-feature product :sqli-login))
3407 3638
3408 ;; Get credentials. 3639 ;; Connect to database.
3409 (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) 3640 (message "Login...")
3410 3641 (funcall (sql-get-product-feature product :sqli-comint-func)
3411 ;; Connect to database. 3642 product
3412 (message "Login...") 3643 (sql-get-product-feature product :sqli-options))
3413 (funcall (sql-get-product-feature product :sqli-comint-func) 3644
3414 product 3645 ;; Set SQLi mode.
3415 (sql-get-product-feature product :sqli-options)) 3646 (setq new-sqli-buffer (current-buffer))
3416 3647 (let ((sql-interactive-product product))
3417 ;; Set SQLi mode. 3648 (sql-interactive-mode))
3418 (setq new-sqli-buffer (current-buffer)) 3649
3419 (let ((sql-interactive-product product)) 3650 ;; Set the new buffer name
3420 (sql-interactive-mode)) 3651 (when new-name
3421 3652 (sql-rename-buffer new-name))
3422 ;; Set the new buffer name 3653
3423 (when new-name 3654 ;; Set `sql-buffer' in the new buffer and the start buffer
3424 (sql-rename-buffer new-name)) 3655 (setq sql-buffer (buffer-name new-sqli-buffer))
3425 3656 (with-current-buffer start-buffer
3426 ;; Set `sql-buffer' in the start buffer 3657 (setq sql-buffer (buffer-name new-sqli-buffer))
3427 (setq sql-buffer (buffer-name new-sqli-buffer)) 3658 (run-hooks 'sql-set-sqli-hook))
3428 (with-current-buffer start-buffer 3659
3429 (setq sql-buffer (buffer-name new-sqli-buffer))) 3660 ;; All done.
3430 3661 (message "Login...done")
3431 ;; All done. 3662 (pop-to-buffer sql-buffer)))))
3432 (message "Login...done")
3433 (pop-to-buffer sql-buffer))))
3434 (message "No default SQL product defined. Set `sql-product'."))) 3663 (message "No default SQL product defined. Set `sql-product'.")))
3435 3664
3436(defun sql-comint (product params) 3665(defun sql-comint (product params)
@@ -3440,14 +3669,17 @@ PRODUCT is the SQL product. PARAMS is a list of strings which are
3440passed as command line arguments." 3669passed as command line arguments."
3441 (let ((program (sql-get-product-feature product :sqli-program)) 3670 (let ((program (sql-get-product-feature product :sqli-program))
3442 (buf-name "SQL")) 3671 (buf-name "SQL"))
3672 ;; make sure we can find the program
3673 (unless (executable-find program)
3674 (error "Unable to locate SQL program \'%s\'" program))
3443 ;; Make sure buffer name is unique 3675 ;; Make sure buffer name is unique
3444 (when (get-buffer (format "*%s*" buf-name)) 3676 (when (sql-buffer-live-p (format "*%s*" buf-name))
3445 (setq buf-name (format "SQL-%s" product)) 3677 (setq buf-name (format "SQL-%s" product))
3446 (when (get-buffer (format "*%s*" buf-name)) 3678 (when (sql-buffer-live-p (format "*%s*" buf-name))
3447 (let ((i 1)) 3679 (let ((i 1))
3448 (while (get-buffer (format "*%s*" 3680 (while (sql-buffer-live-p
3449 (setq buf-name 3681 (format "*%s*"
3450 (format "SQL-%s%d" product i)))) 3682 (setq buf-name (format "SQL-%s%d" product i))))
3451 (setq i (1+ i)))))) 3683 (setq i (1+ i))))))
3452 (set-buffer 3684 (set-buffer
3453 (apply 'make-comint buf-name program nil params)))) 3685 (apply 'make-comint buf-name program nil params))))
@@ -3890,6 +4122,8 @@ Try to set `comint-output-filter-functions' like this:
3890 (setq params (append (list "-h" sql-server) params))) 4122 (setq params (append (list "-h" sql-server) params)))
3891 (if (not (string= "" sql-user)) 4123 (if (not (string= "" sql-user))
3892 (setq params (append (list "-U" sql-user) params))) 4124 (setq params (append (list "-U" sql-user) params)))
4125 (if (not (= 0 sql-port))
4126 (setq params (append (list "-p" sql-port) params)))
3893 (sql-comint product params))) 4127 (sql-comint product params)))
3894 4128
3895 4129