aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorJoakim Verona2010-08-27 10:58:44 +0200
committerJoakim Verona2010-08-27 10:58:44 +0200
commit362120833bcbbaea94976b6701633e2ed75f6051 (patch)
tree632690a24a934bb51a32303add5172d63b6b9e00 /lisp/progmodes
parent1800c4865b15a9e1154bf1f03d87d1aaf750a527 (diff)
parent1a868076f51b5d6f1cf78117463e6f9c614551ec (diff)
downloademacs-362120833bcbbaea94976b6701633e2ed75f6051.tar.gz
emacs-362120833bcbbaea94976b6701633e2ed75f6051.zip
merge from trunk, fix conflicts
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-cmds.el28
-rw-r--r--lisp/progmodes/cc-engine.el330
-rw-r--r--lisp/progmodes/cc-fonts.el7
-rw-r--r--lisp/progmodes/cc-langs.el38
-rw-r--r--lisp/progmodes/cc-mode.el52
-rw-r--r--lisp/progmodes/cc-vars.el26
-rw-r--r--lisp/progmodes/compile.el15
-rw-r--r--lisp/progmodes/delphi.el39
-rw-r--r--lisp/progmodes/etags.el1
-rw-r--r--lisp/progmodes/flymake.el3
-rw-r--r--lisp/progmodes/gdb-mi.el5
-rw-r--r--lisp/progmodes/gud.el4
-rw-r--r--lisp/progmodes/idlwave.el2
-rw-r--r--lisp/progmodes/js.el52
-rw-r--r--lisp/progmodes/make-mode.el10
-rw-r--r--lisp/progmodes/octave-mod.el378
-rw-r--r--lisp/progmodes/prolog.el2
-rw-r--r--lisp/progmodes/ps-mode.el56
-rw-r--r--lisp/progmodes/python.el113
-rw-r--r--lisp/progmodes/ruby-mode.el8
-rw-r--r--lisp/progmodes/scheme.el2
-rw-r--r--lisp/progmodes/sh-script.el5
-rw-r--r--lisp/progmodes/simula.el2
-rw-r--r--lisp/progmodes/sql.el898
-rw-r--r--lisp/progmodes/tcl.el2
-rw-r--r--lisp/progmodes/which-func.el4
26 files changed, 1312 insertions, 770 deletions
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el
index 10267a6b2dc..02fc3950a34 100644
--- a/lisp/progmodes/cc-cmds.el
+++ b/lisp/progmodes/cc-cmds.el
@@ -3974,16 +3974,17 @@ command to conveniently insert and align the necessary backslashes."
3974 ;; "Invalid search bound (wrong side of point)" 3974 ;; "Invalid search bound (wrong side of point)"
3975 ;; error in the subsequent re-search. Maybe 3975 ;; error in the subsequent re-search. Maybe
3976 ;; another fix would be needed (2007-12-08). 3976 ;; another fix would be needed (2007-12-08).
3977 (and (> (- (cdr c-lit-limits) 2) (point)) 3977 (or (<= (- (cdr c-lit-limits) 2) (point))
3978 (and
3978 (search-forward-regexp 3979 (search-forward-regexp
3979 (concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)") 3980 (concat "\\=[ \t]*\\(" c-current-comment-prefix "\\)")
3980 (- (cdr c-lit-limits) 2) t) 3981 (- (cdr c-lit-limits) 2) t)
3981 (not (search-forward-regexp 3982 (not (search-forward-regexp
3982 "\\(\\s \\|\\sw\\)" 3983 "\\(\\s \\|\\sw\\)"
3983 (- (cdr c-lit-limits) 2) 'limit)) 3984 (- (cdr c-lit-limits) 2) 'limit))
3984 ;; The comment ender IS on its own line. Exclude 3985 ;; The comment ender IS on its own line. Exclude
3985 ;; this line from the filling. 3986 ;; this line from the filling.
3986 (set-marker end (c-point 'bol)))) 3987 (set-marker end (c-point 'bol)))))
3987 3988
3988 ;; The comment ender is hanging. Replace all space between it 3989 ;; The comment ender is hanging. Replace all space between it
3989 ;; and the last word either by one or two 'x's (when 3990 ;; and the last word either by one or two 'x's (when
@@ -4000,6 +4001,14 @@ command to conveniently insert and align the necessary backslashes."
4000 (goto-char ender-start) 4001 (goto-char ender-start)
4001 (current-column))) 4002 (current-column)))
4002 (point-rel (- ender-start here)) 4003 (point-rel (- ender-start here))
4004 (sentence-ends-comment
4005 (save-excursion
4006 (goto-char ender-start)
4007 (and (search-backward-regexp
4008 (c-sentence-end) (c-point 'bol) t)
4009 (goto-char (match-end 0))
4010 (looking-at "[ \t]*")
4011 (= (match-end 0) ender-start))))
4003 spaces) 4012 spaces)
4004 4013
4005 (save-excursion 4014 (save-excursion
@@ -4042,7 +4051,9 @@ command to conveniently insert and align the necessary backslashes."
4042 (setq spaces 4051 (setq spaces
4043 (max 4052 (max
4044 (min spaces 4053 (min spaces
4045 (if sentence-end-double-space 2 1)) 4054 (if (and sentence-ends-comment
4055 sentence-end-double-space)
4056 2 1))
4046 1))) 4057 1)))
4047 ;; Insert the filler first to keep marks right. 4058 ;; Insert the filler first to keep marks right.
4048 (insert-char ?x spaces t) 4059 (insert-char ?x spaces t)
@@ -4252,8 +4263,11 @@ Optional prefix ARG means justify paragraph as well."
4252 (let ((fill-paragraph-function 4263 (let ((fill-paragraph-function
4253 ;; Avoid infinite recursion. 4264 ;; Avoid infinite recursion.
4254 (if (not (eq fill-paragraph-function 'c-fill-paragraph)) 4265 (if (not (eq fill-paragraph-function 'c-fill-paragraph))
4255 fill-paragraph-function))) 4266 fill-paragraph-function))
4256 (c-mask-paragraph t nil 'fill-paragraph arg)) 4267 (start-point (point-marker)))
4268 (c-mask-paragraph
4269 t nil (lambda () (fill-region-as-paragraph (point-min) (point-max) arg)))
4270 (goto-char start-point))
4257 ;; Always return t. This has the effect that if filling isn't done 4271 ;; Always return t. This has the effect that if filling isn't done
4258 ;; above, it isn't done at all, and it's therefore effectively 4272 ;; above, it isn't done at all, and it's therefore effectively
4259 ;; disabled in normal code. 4273 ;; disabled in normal code.
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 9bbf82a0449..5aa03317491 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -1,8 +1,8 @@
1;;; cc-engine.el --- core syntax guessing engine for CC mode 1;;; cc-engine.el --- core syntax guessing engine for CC mode
2 2
3;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4;; 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;; Authors: 2001- Alan Mackenzie 7;; Authors: 2001- Alan Mackenzie
8;; 1998- Martin Stjernholm 8;; 1998- Martin Stjernholm
@@ -5023,6 +5023,10 @@ comment at the start of cc-engine.el for more info."
5023 (c-unmark-<->-as-paren pos)) 5023 (c-unmark-<->-as-paren pos))
5024 t))) 5024 t)))
5025 5025
5026;; Set by c-common-init in cc-mode.el.
5027(defvar c-new-BEG)
5028(defvar c-new-END)
5029
5026(defun c-before-change-check-<>-operators (beg end) 5030(defun c-before-change-check-<>-operators (beg end)
5027 ;; Unmark certain pairs of "< .... >" which are currently marked as 5031 ;; Unmark certain pairs of "< .... >" which are currently marked as
5028 ;; template/generic delimiters. (This marking is via syntax-table 5032 ;; template/generic delimiters. (This marking is via syntax-table
@@ -5366,6 +5370,9 @@ comment at the start of cc-engine.el for more info."
5366 (goto-char safe-pos) 5370 (goto-char safe-pos)
5367 t))) 5371 t)))
5368 5372
5373;; cc-mode requires cc-fonts.
5374(declare-function c-fontify-recorded-types-and-refs "cc-fonts" ())
5375
5369(defun c-forward-<>-arglist (all-types) 5376(defun c-forward-<>-arglist (all-types)
5370 ;; The point is assumed to be at a "<". Try to treat it as the open 5377 ;; The point is assumed to be at a "<". Try to treat it as the open
5371 ;; paren of an angle bracket arglist and move forward to the 5378 ;; paren of an angle bracket arglist and move forward to the
@@ -5401,6 +5408,7 @@ comment at the start of cc-engine.el for more info."
5401 ;; `nconc' doesn't mind that the tail of 5408 ;; `nconc' doesn't mind that the tail of
5402 ;; `c-record-found-types' is t. 5409 ;; `c-record-found-types' is t.
5403 (nconc c-record-found-types c-record-type-identifiers))) 5410 (nconc c-record-found-types c-record-type-identifiers)))
5411 (if (c-major-mode-is 'java-mode) (c-fontify-recorded-types-and-refs))
5404 t) 5412 t)
5405 5413
5406 (goto-char start) 5414 (goto-char start)
@@ -5420,7 +5428,6 @@ comment at the start of cc-engine.el for more info."
5420 ;; List that collects the positions after the argument 5428 ;; List that collects the positions after the argument
5421 ;; separating ',' in the arglist. 5429 ;; separating ',' in the arglist.
5422 arg-start-pos) 5430 arg-start-pos)
5423
5424 ;; If the '<' has paren open syntax then we've marked it as an angle 5431 ;; If the '<' has paren open syntax then we've marked it as an angle
5425 ;; bracket arglist before, so skip to the end. 5432 ;; bracket arglist before, so skip to the end.
5426 (if (and (not c-parse-and-markup-<>-arglists) 5433 (if (and (not c-parse-and-markup-<>-arglists)
@@ -5431,7 +5438,6 @@ comment at the start of cc-engine.el for more info."
5431 (if (and (c-go-up-list-forward) 5438 (if (and (c-go-up-list-forward)
5432 (eq (char-before) ?>)) 5439 (eq (char-before) ?>))
5433 t 5440 t
5434
5435 ;; Got unmatched paren angle brackets. We don't clear the paren 5441 ;; Got unmatched paren angle brackets. We don't clear the paren
5436 ;; syntax properties and retry, on the basis that it's very 5442 ;; syntax properties and retry, on the basis that it's very
5437 ;; unlikely that paren angle brackets become operators by code 5443 ;; unlikely that paren angle brackets become operators by code
@@ -5441,70 +5447,51 @@ comment at the start of cc-engine.el for more info."
5441 nil)) 5447 nil))
5442 5448
5443 (forward-char) 5449 (forward-char)
5450
5444 (unless (looking-at c-<-op-cont-regexp) 5451 (unless (looking-at c-<-op-cont-regexp)
5445 (while (and 5452 (while (and
5446 (progn 5453 (progn
5454 (c-forward-syntactic-ws)
5455 (let ((orig-record-found-types c-record-found-types))
5456 (when (or (and c-record-type-identifiers all-types)
5457 (c-major-mode-is 'java-mode))
5458 ;; All encountered identifiers are types, so set the
5459 ;; promote flag and parse the type.
5460 (progn
5461 (c-forward-syntactic-ws)
5462 (if (looking-at "\\?")
5463 (forward-char)
5464 (when (looking-at c-identifier-start)
5465 (let ((c-promote-possible-types t)
5466 (c-record-found-types t))
5467 (c-forward-type))))
5447 5468
5448 (when c-record-type-identifiers 5469 (c-forward-syntactic-ws)
5449 (if all-types
5450
5451 ;; All encountered identifiers are types, so set the
5452 ;; promote flag and parse the type.
5453 (progn
5454 (c-forward-syntactic-ws)
5455 (when (looking-at c-identifier-start)
5456 (let ((c-promote-possible-types t))
5457 (c-forward-type))))
5458
5459 ;; Check if this arglist argument is a sole type. If
5460 ;; it's known then it's recorded in
5461 ;; `c-record-type-identifiers'. If it only is found
5462 ;; then it's recorded in `c-record-found-types' which we
5463 ;; might roll back if it turns out that this isn't an
5464 ;; angle bracket arglist afterall.
5465 (when (memq (char-before) '(?, ?<))
5466 (let ((orig-record-found-types c-record-found-types))
5467 (c-forward-syntactic-ws)
5468 (and (memq (c-forward-type) '(known found))
5469 (not (looking-at "[,>]"))
5470 ;; A found type was recorded but it's not the
5471 ;; only thing in the arglist argument, so reset
5472 ;; `c-record-found-types'.
5473 (setq c-record-found-types
5474 orig-record-found-types))))))
5475 5470
5476 (setq pos (point)) 5471 (when (or (looking-at "extends")
5477 (or (when (eq (char-after) ?>) 5472 (looking-at "super"))
5478 ;; Must check for '>' at the very start separately, 5473 (forward-word)
5479 ;; since the regexp below has to avoid ">>" without 5474 (c-forward-syntactic-ws)
5480 ;; using \\=. 5475 (let ((c-promote-possible-types t)
5481 (forward-char) 5476 (c-record-found-types t))
5482 t) 5477 (c-forward-type)
5483 5478 (c-forward-syntactic-ws))))))
5484 ;; Note: These regexps exploit the match order in \| so 5479
5485 ;; that "<>" is matched by "<" rather than "[^>:-]>". 5480 (setq pos (point))
5486 (c-syntactic-re-search-forward 5481
5487 (if c-restricted-<>-arglists 5482 (or
5488 ;; Stop on ',', '|', '&', '+' and '-' to catch 5483 ;; Note: These regexps exploit the match order in \| so
5489 ;; common binary operators that could be between 5484 ;; that "<>" is matched by "<" rather than "[^>:-]>".
5490 ;; two comparison expressions "a<b" and "c>d". 5485 (c-syntactic-re-search-forward
5491 "[<;{},|&+-]\\|\\([^>:-]>\\)" 5486 ;; Stop on ',', '|', '&', '+' and '-' to catch
5492 ;; Otherwise we still stop on ',' to find the 5487 ;; common binary operators that could be between
5493 ;; argument start positions. 5488 ;; two comparison expressions "a<b" and "c>d".
5494 "[<;{},]\\|\\([^>:-]>\\)") 5489 "[<;{},|+&-]\\|[>)]"
5495 nil 'move t t 1) 5490 nil t t)
5496 5491 t))
5497 ;; If the arglist starter has lost its open paren
5498 ;; syntax but not the closer, we won't find the
5499 ;; closer above since we only search in the
5500 ;; balanced sexp. In that case we stop just short
5501 ;; of it so check if the following char is the closer.
5502 (when (eq (char-after) ?>)
5503 (forward-char)
5504 t)))
5505 5492
5506 (cond 5493 (cond
5507 ((eq (char-before) ?>) 5494 ((eq (char-before) ?>)
5508 ;; Either an operator starting with '>' or the end of 5495 ;; Either an operator starting with '>' or the end of
5509 ;; the angle bracket arglist. 5496 ;; the angle bracket arglist.
5510 5497
@@ -5526,7 +5513,6 @@ comment at the start of cc-engine.el for more info."
5526 5513
5527 ((eq (char-before) ?<) 5514 ((eq (char-before) ?<)
5528 ;; Either an operator starting with '<' or a nested arglist. 5515 ;; Either an operator starting with '<' or a nested arglist.
5529
5530 (setq pos (point)) 5516 (setq pos (point))
5531 (let (id-start id-end subres keyword-match) 5517 (let (id-start id-end subres keyword-match)
5532 (if (if (looking-at c-<-op-cont-regexp) 5518 (if (if (looking-at c-<-op-cont-regexp)
@@ -5546,14 +5532,14 @@ comment at the start of cc-engine.el for more info."
5546 (when (or (setq keyword-match 5532 (when (or (setq keyword-match
5547 (looking-at c-opt-<>-sexp-key)) 5533 (looking-at c-opt-<>-sexp-key))
5548 (not (looking-at c-keywords-regexp))) 5534 (not (looking-at c-keywords-regexp)))
5549 (setq id-start (point)))) 5535 (setq id-start (point))))
5550 5536
5551 (setq subres 5537 (setq subres
5552 (let ((c-record-type-identifiers nil) 5538 (let ((c-promote-possible-types t)
5553 (c-record-found-types nil)) 5539 (c-record-found-types t))
5554 (c-forward-<>-arglist-recur 5540 (c-forward-<>-arglist-recur
5555 (and keyword-match 5541 (and keyword-match
5556 (c-keyword-member 5542 (c-keyword-member
5557 (c-keyword-sym (match-string 1)) 5543 (c-keyword-sym (match-string 1))
5558 'c-<>-type-kwds))))) 5544 'c-<>-type-kwds)))))
5559 ))) 5545 )))
@@ -5574,14 +5560,16 @@ comment at the start of cc-engine.el for more info."
5574 (c-forward-syntactic-ws) 5560 (c-forward-syntactic-ws)
5575 (looking-at c-opt-identifier-concat-key))) 5561 (looking-at c-opt-identifier-concat-key)))
5576 (c-record-ref-id (cons id-start id-end)) 5562 (c-record-ref-id (cons id-start id-end))
5577 (c-record-type-id (cons id-start id-end)))))) 5563 (c-record-type-id (cons id-start id-end))))))
5578 t) 5564 t)
5579 5565
5580 ((and (eq (char-before) ?,) 5566 ((and (not c-restricted-<>-arglists)
5581 (not c-restricted-<>-arglists)) 5567 (or (and (eq (char-before) ?&)
5582 ;; Just another argument. Record the position. The 5568 (not (eq (char-after) ?&)))
5583 ;; type check stuff that made us stop at it is at 5569 (eq (char-before) ?,)))
5584 ;; the top of the loop. 5570 ;; Just another argument. Record the position. The
5571 ;; type check stuff that made us stop at it is at
5572 ;; the top of the loop.
5585 (setq arg-start-pos (cons (point) arg-start-pos))) 5573 (setq arg-start-pos (cons (point) arg-start-pos)))
5586 5574
5587 (t 5575 (t
@@ -5590,7 +5578,6 @@ comment at the start of cc-engine.el for more info."
5590 ;; it's useless to try to find a surrounding arglist 5578 ;; it's useless to try to find a surrounding arglist
5591 ;; if we're nested. 5579 ;; if we're nested.
5592 (throw 'angle-bracket-arglist-escape nil)))))) 5580 (throw 'angle-bracket-arglist-escape nil))))))
5593
5594 (if res 5581 (if res
5595 (or c-record-found-types t))))) 5582 (or c-record-found-types t)))))
5596 5583
@@ -5793,9 +5780,8 @@ comment at the start of cc-engine.el for more info."
5793 ((and c-recognize-<>-arglists 5780 ((and c-recognize-<>-arglists
5794 (eq (char-after) ?<)) 5781 (eq (char-after) ?<))
5795 ;; Maybe an angle bracket arglist. 5782 ;; Maybe an angle bracket arglist.
5796 5783 (when (let ((c-record-type-identifiers t)
5797 (when (let (c-record-type-identifiers 5784 (c-record-found-types t))
5798 c-record-found-types)
5799 (c-forward-<>-arglist nil)) 5785 (c-forward-<>-arglist nil))
5800 5786
5801 (c-add-type start (1+ pos)) 5787 (c-add-type start (1+ pos))
@@ -5844,6 +5830,9 @@ comment at the start of cc-engine.el for more info."
5844 ;; `c-record-type-identifiers' is non-nil. 5830 ;; `c-record-type-identifiers' is non-nil.
5845 ;; 5831 ;;
5846 ;; This function might do hidden buffer changes. 5832 ;; This function might do hidden buffer changes.
5833 (when (looking-at "<")
5834 (c-forward-<>-arglist t)
5835 (c-forward-syntactic-ws))
5847 5836
5848 (let ((start (point)) pos res name-res id-start id-end id-range) 5837 (let ((start (point)) pos res name-res id-start id-end id-range)
5849 5838
@@ -6043,6 +6032,18 @@ comment at the start of cc-engine.el for more info."
6043 6032
6044 res)) 6033 res))
6045 6034
6035(defun c-forward-annotation ()
6036 ;; Used for Java code only at the moment. Assumes point is on the
6037 ;; @, moves forward an annotation. returns nil if there is no
6038 ;; annotation at point.
6039 (and (looking-at "@")
6040 (progn (forward-char) t)
6041 (c-forward-type)
6042 (progn (c-forward-syntactic-ws) t)
6043 (if (looking-at "(")
6044 (c-go-list-forward)
6045 t)))
6046
6046 6047
6047;; Handling of large scale constructs like statements and declarations. 6048;; Handling of large scale constructs like statements and declarations.
6048 6049
@@ -6212,6 +6213,9 @@ comment at the start of cc-engine.el for more info."
6212 (save-rec-type-ids c-record-type-identifiers) 6213 (save-rec-type-ids c-record-type-identifiers)
6213 (save-rec-ref-ids c-record-ref-identifiers)) 6214 (save-rec-ref-ids c-record-ref-identifiers))
6214 6215
6216 (while (c-forward-annotation)
6217 (c-forward-syntactic-ws))
6218
6215 ;; Check for a type. Unknown symbols are treated as possible 6219 ;; Check for a type. Unknown symbols are treated as possible
6216 ;; types, but they could also be specifiers disguised through 6220 ;; types, but they could also be specifiers disguised through
6217 ;; macros like __INLINE__, so we recognize both types and known 6221 ;; macros like __INLINE__, so we recognize both types and known
@@ -6545,13 +6549,14 @@ comment at the start of cc-engine.el for more info."
6545 ;; CASE 3 6549 ;; CASE 3
6546 (when (= (point) start) 6550 (when (= (point) start)
6547 ;; Got a plain list of identifiers. If a colon follows it's 6551 ;; Got a plain list of identifiers. If a colon follows it's
6548 ;; a valid label. Otherwise the last one probably is the 6552 ;; a valid label. Otherwise the last one probably is the
6549 ;; declared identifier and we should back up to the previous 6553 ;; declared identifier and we should back up to the previous
6550 ;; type, providing it isn't a cast. 6554 ;; type, providing it isn't a cast.
6551 (if (eq (char-after) ?:) 6555 (if (and (eq (char-after) ?:)
6552 ;; If we've found a specifier keyword then it's a 6556 (not (c-major-mode-is 'java-mode)))
6553 ;; declaration regardless. 6557 ;; If we've found a specifier keyword then it's a
6554 (throw 'at-decl-or-cast (eq at-decl-or-cast t)) 6558 ;; declaration regardless.
6559 (throw 'at-decl-or-cast (eq at-decl-or-cast t))
6555 (setq backup-if-not-cast t) 6560 (setq backup-if-not-cast t)
6556 (throw 'at-decl-or-cast t))) 6561 (throw 'at-decl-or-cast t)))
6557 6562
@@ -8512,7 +8517,7 @@ comment at the start of cc-engine.el for more info."
8512 ;; 8517 ;;
8513 ;; This function might do hidden buffer changes. 8518 ;; This function might do hidden buffer changes.
8514 8519
8515 (let (special-brace-list) 8520 (let (special-brace-list placeholder)
8516 (goto-char indent-point) 8521 (goto-char indent-point)
8517 (skip-chars-forward " \t") 8522 (skip-chars-forward " \t")
8518 8523
@@ -8619,6 +8624,22 @@ comment at the start of cc-engine.el for more info."
8619 (c-add-stmt-syntax 'func-decl-cont nil t 8624 (c-add-stmt-syntax 'func-decl-cont nil t
8620 containing-sexp paren-state)) 8625 containing-sexp paren-state))
8621 8626
8627 ;;CASE F: continued statement and the only preceding items are
8628 ;;annotations.
8629 ((and (c-major-mode-is 'java-mode)
8630 (setq placeholder (point))
8631 (c-beginning-of-statement-1)
8632 (progn
8633 (while (and (c-forward-annotation)
8634 (< (point) placeholder))
8635 (c-forward-syntactic-ws))
8636 t)
8637 (prog1
8638 (>= (point) placeholder)
8639 (goto-char placeholder)))
8640 (c-beginning-of-statement-1 containing-sexp)
8641 (c-add-syntax 'annotation-var-cont (point)))
8642
8622 ;; CASE D: continued statement. 8643 ;; CASE D: continued statement.
8623 (t 8644 (t
8624 (c-beginning-of-statement-1 containing-sexp) 8645 (c-beginning-of-statement-1 containing-sexp)
@@ -8718,7 +8739,6 @@ comment at the start of cc-engine.el for more info."
8718 (when (and containing-sexp 8739 (when (and containing-sexp
8719 (eq (char-after containing-sexp) ?\()) 8740 (eq (char-after containing-sexp) ?\())
8720 (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma)) 8741 (setq c-stmt-delim-chars c-stmt-delim-chars-with-comma))
8721
8722 ;; cache char before and after indent point, and move point to 8742 ;; cache char before and after indent point, and move point to
8723 ;; the most likely position to perform the majority of tests 8743 ;; the most likely position to perform the majority of tests
8724 (goto-char indent-point) 8744 (goto-char indent-point)
@@ -9468,23 +9488,36 @@ comment at the start of cc-engine.el for more info."
9468 (c-add-syntax 'objc-method-args-cont placeholder)) 9488 (c-add-syntax 'objc-method-args-cont placeholder))
9469 9489
9470 ;; CASE 5L: we are at the first argument of a template 9490 ;; CASE 5L: we are at the first argument of a template
9471 ;; arglist that begins on the previous line. 9491 ;; arglist that begins on the previous line.
9472 ((and c-recognize-<>-arglists 9492 ((and c-recognize-<>-arglists
9473 (eq (char-before) ?<) 9493 (eq (char-before) ?<)
9474 (setq placeholder (1- (point))) 9494 (not (and c-overloadable-operators-regexp
9475 (not (and c-overloadable-operators-regexp 9495 (c-after-special-operator-id lim))))
9476 (c-after-special-operator-id lim)))) 9496 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
9477 (c-beginning-of-statement-1 (c-safe-position (point) paren-state)) 9497 (c-add-syntax 'template-args-cont (c-point 'boi)))
9478 (c-add-syntax 'template-args-cont (c-point 'boi) placeholder)) 9498
9479 9499 ;; CASE 5Q: we are at a statement within a macro.
9480 ;; CASE 5Q: we are at a statement within a macro. 9500 (macro-start
9481 (macro-start 9501 (c-beginning-of-statement-1 containing-sexp)
9482 (c-beginning-of-statement-1 containing-sexp) 9502 (c-add-stmt-syntax 'statement nil t containing-sexp paren-state))
9483 (c-add-stmt-syntax 'statement nil t containing-sexp paren-state)) 9503
9484 9504 ;;CASE 5N: We are at a tompmost continuation line and the only
9485 ;; CASE 5M: we are at a topmost continuation line 9505 ;;preceding items are annotations.
9486 (t 9506 ((and (c-major-mode-is 'java-mode)
9487 (c-beginning-of-statement-1 (c-safe-position (point) paren-state)) 9507 (setq placeholder (point))
9508 (c-beginning-of-statement-1)
9509 (progn
9510 (while (and (c-forward-annotation))
9511 (c-forward-syntactic-ws))
9512 t)
9513 (prog1
9514 (>= (point) placeholder)
9515 (goto-char placeholder)))
9516 (c-add-syntax 'annotation-top-cont (c-point 'boi)))
9517
9518 ;; CASE 5M: we are at a topmost continuation line
9519 (t
9520 (c-beginning-of-statement-1 (c-safe-position (point) paren-state))
9488 (when (c-major-mode-is 'objc-mode) 9521 (when (c-major-mode-is 'objc-mode)
9489 (setq placeholder (point)) 9522 (setq placeholder (point))
9490 (while (and (c-forward-objc-directive) 9523 (while (and (c-forward-objc-directive)
@@ -9495,43 +9528,20 @@ comment at the start of cc-engine.el for more info."
9495 (c-add-syntax 'topmost-intro-cont (c-point 'boi))) 9528 (c-add-syntax 'topmost-intro-cont (c-point 'boi)))
9496 )) 9529 ))
9497 9530
9498 ;; (CASE 6 has been removed.)
9499 9531
9500 ;; CASE 19: line is an expression, not a statement, and is directly 9532 ;; (CASE 6 has been removed.)
9501 ;; contained by a template delimiter. Most likely, we are in a
9502 ;; template arglist within a statement. This case is based on CASE
9503 ;; 7. At some point in the future, we may wish to create more
9504 ;; syntactic symbols such as `template-intro',
9505 ;; `template-cont-nonempty', etc., and distinguish between them as we
9506 ;; do for `arglist-intro' etc. (2009-12-07).
9507 ((and c-recognize-<>-arglists
9508 (setq containing-< (c-up-list-backward indent-point containing-sexp))
9509 (eq (char-after containing-<) ?\<))
9510 (setq placeholder (c-point 'boi containing-<))
9511 (goto-char containing-sexp) ; Most nested Lbrace/Lparen (but not
9512 ; '<') before indent-point.
9513 (if (>= (point) placeholder)
9514 (progn
9515 (forward-char)
9516 (skip-chars-forward " \t"))
9517 (goto-char placeholder))
9518 (c-add-stmt-syntax 'template-args-cont (list containing-<) t
9519 (c-most-enclosing-brace c-state-cache (point))
9520 paren-state))
9521
9522 9533
9523 ;; CASE 7: line is an expression, not a statement. Most 9534 ;; CASE 7: line is an expression, not a statement. Most
9524 ;; likely we are either in a function prototype or a function 9535 ;; likely we are either in a function prototype or a function
9525 ;; call argument list, or a template argument list. 9536 ;; call argument list
9526 ((not (or (and c-special-brace-lists 9537 ((not (or (and c-special-brace-lists
9527 (save-excursion 9538 (save-excursion
9528 (goto-char containing-sexp) 9539 (goto-char containing-sexp)
9529 (c-looking-at-special-brace-list))) 9540 (c-looking-at-special-brace-list)))
9530 (eq (char-after containing-sexp) ?{) 9541 (eq (char-after containing-sexp) ?{)))
9531 (eq (char-after containing-sexp) ?<))) 9542 (cond
9532 (cond
9533 9543
9534 ;; CASE 7A: we are looking at the arglist closing paren. 9544 ;; CASE 7A: we are looking at the arglist closing paren.
9535 ;; C.f. case 7F. 9545 ;; C.f. case 7F.
9536 ((memq char-after-ip '(?\) ?\])) 9546 ((memq char-after-ip '(?\) ?\]))
9537 (goto-char containing-sexp) 9547 (goto-char containing-sexp)
@@ -9543,12 +9553,34 @@ comment at the start of cc-engine.el for more info."
9543 (skip-chars-forward " \t")) 9553 (skip-chars-forward " \t"))
9544 (goto-char placeholder)) 9554 (goto-char placeholder))
9545 (c-add-stmt-syntax 'arglist-close (list containing-sexp) t 9555 (c-add-stmt-syntax 'arglist-close (list containing-sexp) t
9546 (c-most-enclosing-brace paren-state (point)) 9556 (c-most-enclosing-brace paren-state (point))
9547 paren-state)) 9557 paren-state))
9548 9558
9549 ;; CASE 7B: Looking at the opening brace of an 9559 ;; CASE 19: line is an expression, not a statement, and is directly
9550 ;; in-expression block or brace list. C.f. cases 4, 16A 9560 ;; contained by a template delimiter. Most likely, we are in a
9551 ;; and 17E. 9561 ;; template arglist within a statement. This case is based on CASE
9562 ;; 7. At some point in the future, we may wish to create more
9563 ;; syntactic symbols such as `template-intro',
9564 ;; `template-cont-nonempty', etc., and distinguish between them as we
9565 ;; do for `arglist-intro' etc. (2009-12-07).
9566 ((and c-recognize-<>-arglists
9567 (setq containing-< (c-up-list-backward indent-point containing-sexp))
9568 (eq (char-after containing-<) ?\<))
9569 (setq placeholder (c-point 'boi containing-<))
9570 (goto-char containing-sexp) ; Most nested Lbrace/Lparen (but not
9571 ; '<') before indent-point.
9572 (if (>= (point) placeholder)
9573 (progn
9574 (forward-char)
9575 (skip-chars-forward " \t"))
9576 (goto-char placeholder))
9577 (c-add-stmt-syntax 'template-args-cont (list containing-<) t
9578 (c-most-enclosing-brace c-state-cache (point))
9579 paren-state))
9580
9581 ;; CASE 7B: Looking at the opening brace of an
9582 ;; in-expression block or brace list. C.f. cases 4, 16A
9583 ;; and 17E.
9552 ((and (eq char-after-ip ?{) 9584 ((and (eq char-after-ip ?{)
9553 (progn 9585 (progn
9554 (setq placeholder (c-inside-bracelist-p (point) 9586 (setq placeholder (c-inside-bracelist-p (point)
diff --git a/lisp/progmodes/cc-fonts.el b/lisp/progmodes/cc-fonts.el
index 907c308daca..219eb25368c 100644
--- a/lisp/progmodes/cc-fonts.el
+++ b/lisp/progmodes/cc-fonts.el
@@ -194,6 +194,10 @@
194 (unless (face-property-instance oldface 'reverse) 194 (unless (face-property-instance oldface 'reverse)
195 (invert-face newface))))) 195 (invert-face newface)))))
196 196
197(defvar c-annotation-face (make-face 'c-annotation-face)
198 "Face used to highlight annotations in java-mode and other modes that may wish to use it.")
199(set-face-foreground 'c-annotation-face "blue")
200
197(eval-and-compile 201(eval-and-compile
198 ;; We need the following functions during compilation since they're 202 ;; We need the following functions during compilation since they're
199 ;; called when the `c-lang-defconst' initializers are evaluated. 203 ;; called when the `c-lang-defconst' initializers are evaluated.
@@ -1538,6 +1542,9 @@ higher."
1538 '((c-fontify-types-and-refs ((c-promote-possible-types t)) 1542 '((c-fontify-types-and-refs ((c-promote-possible-types t))
1539 (c-forward-keyword-clause 1) 1543 (c-forward-keyword-clause 1)
1540 (if (> (point) limit) (goto-char limit)))))))) 1544 (if (> (point) limit) (goto-char limit))))))))
1545
1546 ,@(when (c-major-mode-is 'java-mode)
1547 `((eval . (list "\\<\\(@[a-zA-Z0-9]+\\)\\>" 1 c-annotation-face))))
1541 )) 1548 ))
1542 1549
1543(c-lang-defconst c-matchers-1 1550(c-lang-defconst c-matchers-1
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index d3669f259de..ae0ed1b928a 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -359,7 +359,7 @@ The syntax tables aren't stored directly since they're quite large."
359 (let ((table (make-syntax-table))) 359 (let ((table (make-syntax-table)))
360 (c-populate-syntax-table table) 360 (c-populate-syntax-table table)
361 ;; Mode specific syntaxes. 361 ;; Mode specific syntaxes.
362 ,(cond ((c-major-mode-is 'objc-mode) 362 ,(cond ((or (c-major-mode-is 'objc-mode) (c-major-mode-is 'java-mode))
363 ;; Let '@' be part of symbols in ObjC to cope with 363 ;; Let '@' be part of symbols in ObjC to cope with
364 ;; its compiler directives as single keyword tokens. 364 ;; its compiler directives as single keyword tokens.
365 ;; This is then necessary since it's assumed that 365 ;; This is then necessary since it's assumed that
@@ -382,7 +382,7 @@ The syntax tables aren't stored directly since they're quite large."
382 ;; '<' and '>' characters. Therefore this syntax table might go 382 ;; '<' and '>' characters. Therefore this syntax table might go
383 ;; away when CC Mode handles templates correctly everywhere. 383 ;; away when CC Mode handles templates correctly everywhere.
384 t nil 384 t nil
385 c++ `(lambda () 385 (java c++) `(lambda ()
386 (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table)))) 386 (let ((table (funcall ,(c-lang-const c-make-mode-syntax-table))))
387 (modify-syntax-entry ?< "(>" table) 387 (modify-syntax-entry ?< "(>" table)
388 (modify-syntax-entry ?> ")<" table) 388 (modify-syntax-entry ?> ")<" table)
@@ -425,7 +425,7 @@ the new syntax, as accepted by `modify-syntax-entry'."
425 ;; it as an indentifier character since it's often used in various 425 ;; it as an indentifier character since it's often used in various
426 ;; machine generated identifiers. 426 ;; machine generated identifiers.
427 t '((?_ . "w") (?$ . "w")) 427 t '((?_ . "w") (?$ . "w"))
428 objc (append '((?@ . "w")) 428 (objc java) (append '((?@ . "w"))
429 (c-lang-const c-identifier-syntax-modifications)) 429 (c-lang-const c-identifier-syntax-modifications))
430 awk '((?_ . "w"))) 430 awk '((?_ . "w")))
431(c-lang-defvar c-identifier-syntax-modifications 431(c-lang-defvar c-identifier-syntax-modifications
@@ -502,9 +502,10 @@ parameters \(point-min), \(point-max) and <buffer size>."
502 502
503(c-lang-defconst c-symbol-start 503(c-lang-defconst c-symbol-start
504 "Regexp that matches the start of a symbol, i.e. any identifier or 504 "Regexp that matches the start of a symbol, i.e. any identifier or
505keyword. It's unspecified how far it matches. Does not contain a \\| 505keyword. It's unspecified how far it matches. Does not contain a \\|
506operator at the top level." 506operator at the top level."
507 t (concat "[" c-alpha "_]") 507 t (concat "[" c-alpha "_]")
508 java (concat "[" c-alpha "_@]")
508 objc (concat "[" c-alpha "@]") 509 objc (concat "[" c-alpha "@]")
509 pike (concat "[" c-alpha "_`]")) 510 pike (concat "[" c-alpha "_`]"))
510(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start)) 511(c-lang-defvar c-symbol-start (c-lang-const c-symbol-start))
@@ -859,7 +860,7 @@ since CC Mode treats every identifier as an expression."
859 860
860 ;; Primary. 861 ;; Primary.
861 ,@(c-lang-const c-identifier-ops) 862 ,@(c-lang-const c-identifier-ops)
862 ,@(cond ((c-major-mode-is 'c++-mode) 863 ,@(cond ((or (c-major-mode-is 'c++-mode) (c-major-mode-is 'java-mode))
863 `((postfix-if-paren "<" ">"))) ; Templates. 864 `((postfix-if-paren "<" ">"))) ; Templates.
864 ((c-major-mode-is 'pike-mode) 865 ((c-major-mode-is 'pike-mode)
865 `((prefix "global" "predef"))) 866 `((prefix "global" "predef")))
@@ -1118,6 +1119,7 @@ operators."
1118 t 1119 t
1119 "\\`<." 1120 "\\`<."
1120 (lambda (op) (substring op 1))))) 1121 (lambda (op) (substring op 1)))))
1122
1121(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp)) 1123(c-lang-defvar c-<-op-cont-regexp (c-lang-const c-<-op-cont-regexp))
1122 1124
1123(c-lang-defconst c->-op-cont-regexp 1125(c-lang-defconst c->-op-cont-regexp
@@ -1127,7 +1129,13 @@ operators."
1127 (c-filter-ops (c-lang-const c-all-op-syntax-tokens) 1129 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
1128 t 1130 t
1129 "\\`>." 1131 "\\`>."
1130 (lambda (op) (substring op 1))))) 1132 (lambda (op) (substring op 1))))
1133 java (c-make-keywords-re nil
1134 (c-filter-ops (c-lang-const c-all-op-syntax-tokens)
1135 t
1136 "\\`>[^>]\\|\\`>>[^>]"
1137 (lambda (op) (substring op 1)))))
1138
1131(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp)) 1139(c-lang-defvar c->-op-cont-regexp (c-lang-const c->-op-cont-regexp))
1132 1140
1133(c-lang-defconst c-stmt-delim-chars 1141(c-lang-defconst c-stmt-delim-chars
@@ -1628,7 +1636,7 @@ following identifier as a type; the keyword must also be present on
1628 c++ '("class" "struct" "union") 1636 c++ '("class" "struct" "union")
1629 objc '("struct" "union" 1637 objc '("struct" "union"
1630 "@interface" "@implementation" "@protocol") 1638 "@interface" "@implementation" "@protocol")
1631 java '("class" "interface") 1639 java '("class" "@interface" "interface")
1632 idl '("component" "eventtype" "exception" "home" "interface" "struct" 1640 idl '("component" "eventtype" "exception" "home" "interface" "struct"
1633 "union" "valuetype" 1641 "union" "valuetype"
1634 ;; In CORBA PSDL: 1642 ;; In CORBA PSDL:
@@ -1651,7 +1659,7 @@ If any of these also are on `c-type-list-kwds', `c-ref-list-kwds',
1651`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses 1659`c-<>-type-kwds', or `c-<>-arglist-kwds' then the associated clauses
1652will be handled." 1660will be handled."
1653 t '("enum") 1661 t '("enum")
1654 (java awk) nil) 1662 (awk) nil)
1655 1663
1656(c-lang-defconst c-brace-list-key 1664(c-lang-defconst c-brace-list-key
1657 ;; Regexp matching the start of declarations where the following 1665 ;; Regexp matching the start of declarations where the following
@@ -1772,7 +1780,7 @@ will be handled."
1772 "bindsTo" "delegatesTo" "implements" "proxy" "storedOn") 1780 "bindsTo" "delegatesTo" "implements" "proxy" "storedOn")
1773 ;; Note: "const" is not used in Java, but it's still a reserved keyword. 1781 ;; Note: "const" is not used in Java, but it's still a reserved keyword.
1774 java '("abstract" "const" "final" "native" "private" "protected" "public" 1782 java '("abstract" "const" "final" "native" "private" "protected" "public"
1775 "static" "strictfp" "synchronized" "transient" "volatile") 1783 "static" "strictfp" "synchronized" "transient" "volatile" "@[A-Za-z0-9]+")
1776 pike '("final" "inline" "local" "nomask" "optional" "private" "protected" 1784 pike '("final" "inline" "local" "nomask" "optional" "private" "protected"
1777 "public" "static" "variant")) 1785 "public" "static" "variant"))
1778 1786
@@ -1858,7 +1866,11 @@ one of `c-type-list-kwds', `c-ref-list-kwds',
1858 1866
1859(c-lang-defconst c-prefix-spec-kwds-re 1867(c-lang-defconst c-prefix-spec-kwds-re
1860 ;; Adorned regexp of `c-prefix-spec-kwds'. 1868 ;; Adorned regexp of `c-prefix-spec-kwds'.
1861 t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds))) 1869 t (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds))
1870 java (replace-regexp-in-string
1871 "\\\\\\[" "["
1872 (replace-regexp-in-string "\\\\\\+" "+" (c-make-keywords-re t (c-lang-const c-prefix-spec-kwds)))))
1873
1862(c-lang-defvar c-prefix-spec-kwds-re (c-lang-const c-prefix-spec-kwds-re)) 1874(c-lang-defvar c-prefix-spec-kwds-re (c-lang-const c-prefix-spec-kwds-re))
1863 1875
1864(c-lang-defconst c-specifier-key 1876(c-lang-defconst c-specifier-key
@@ -1950,7 +1962,7 @@ or variable identifier (that's being defined)."
1950 t nil 1962 t nil
1951 c++ '("operator") 1963 c++ '("operator")
1952 objc '("@class") 1964 objc '("@class")
1953 java '("import" "new" "extends" "implements" "throws") 1965 java '("import" "new" "extends" "super" "implements" "throws")
1954 idl '("manages" "native" "primarykey" "supports" 1966 idl '("manages" "native" "primarykey" "supports"
1955 ;; In CORBA PSDL: 1967 ;; In CORBA PSDL:
1956 "as" "implements" "of" "scope") 1968 "as" "implements" "of" "scope")
@@ -2499,7 +2511,7 @@ more info."
2499 ;; in all languages except Java for when a cpp macro definition 2511 ;; in all languages except Java for when a cpp macro definition
2500 ;; begins with a declaration. 2512 ;; begins with a declaration.
2501 t "\\([\{\}\(\);,]+\\)" 2513 t "\\([\{\}\(\);,]+\\)"
2502 java "\\([\{\}\(;,]+\\)" 2514 java "\\([\{\}\(;,<]+\\)"
2503 ;; Match "<" in C++ to get the first argument in a template arglist. 2515 ;; Match "<" in C++ to get the first argument in a template arglist.
2504 ;; In that case there's an additional check in `c-find-decl-spots' 2516 ;; In that case there's an additional check in `c-find-decl-spots'
2505 ;; that it got open paren syntax. 2517 ;; that it got open paren syntax.
@@ -2759,7 +2771,7 @@ It's undefined whether identifier syntax (see `c-identifier-syntax-table')
2759is in effect or not." 2771is in effect or not."
2760 t nil 2772 t nil
2761 (c c++ objc pike) "\\(\\.\\.\\.\\)" 2773 (c c++ objc pike) "\\(\\.\\.\\.\\)"
2762 java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\)")) 2774 java (concat "\\(\\[" (c-lang-const c-simple-ws) "*\\]\\|\\.\\.\\.\\)"))
2763(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key)) 2775(c-lang-defvar c-opt-type-suffix-key (c-lang-const c-opt-type-suffix-key))
2764 2776
2765(c-lang-defvar c-known-type-key 2777(c-lang-defvar c-known-type-key
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 9044b42a838..d61c8d42457 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -1,8 +1,8 @@
1;;; cc-mode.el --- major mode for editing C and similar languages 1;;; cc-mode.el --- major mode for editing C and similar languages
2 2
3;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 3;; Copyright (C) 1985, 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
4;; 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 4;; 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;; Authors: 2003- Alan Mackenzie 7;; Authors: 2003- Alan Mackenzie
8;; 1998- Martin Stjernholm 8;; 1998- Martin Stjernholm
@@ -522,7 +522,7 @@ that requires a literal mode spec at compile time."
522 522
523 (when (or c-recognize-<>-arglists 523 (when (or c-recognize-<>-arglists
524 (c-major-mode-is 'awk-mode) 524 (c-major-mode-is 'awk-mode)
525 (c-major-mode-is '(c-mode c++-mode objc-mode))) 525 (c-major-mode-is '(java-mode c-mode c++-mode objc-mode)))
526 ;; We'll use the syntax-table text property to change the syntax 526 ;; We'll use the syntax-table text property to change the syntax
527 ;; of some chars for this language, so do the necessary setup for 527 ;; of some chars for this language, so do the necessary setup for
528 ;; that. 528 ;; that.
@@ -616,6 +616,15 @@ that requires a literal mode spec at compile time."
616 (font-lock-mode 0) 616 (font-lock-mode 0)
617 (font-lock-mode 1))) 617 (font-lock-mode 1)))
618 618
619;; Buffer local variables defining the region to be fontified by a font lock
620;; after-change function. They are set in c-after-change to
621;; after-change-function's BEG and END, and may be modified by a
622;; `c-before-font-lock-function'.
623(defvar c-new-BEG 0)
624(make-variable-buffer-local 'c-new-BEG)
625(defvar c-new-END 0)
626(make-variable-buffer-local 'c-new-END)
627
619(defun c-common-init (&optional mode) 628(defun c-common-init (&optional mode)
620 "Common initialization for all CC Mode modes. 629 "Common initialization for all CC Mode modes.
621In addition to the work done by `c-basic-common-init' and 630In addition to the work done by `c-basic-common-init' and
@@ -662,6 +671,17 @@ compatible with old code; callers should always specify it."
662 (and (cdr rfn) 671 (and (cdr rfn)
663 (setq require-final-newline mode-require-final-newline))))) 672 (setq require-final-newline mode-require-final-newline)))))
664 673
674(defun c-count-cfss (lv-alist)
675 ;; LV-ALIST is an alist like `file-local-variables-alist'. Count how many
676 ;; elements with the key `c-file-style' there are in it.
677 (let ((elt-ptr lv-alist) elt (cownt 0))
678 (while elt-ptr
679 (setq elt (car elt-ptr)
680 elt-ptr (cdr elt-ptr))
681 (when (eq (car elt) 'c-file-style)
682 (setq cownt (1+ cownt))))
683 cownt))
684
665(defun c-before-hack-hook () 685(defun c-before-hack-hook ()
666 "Set the CC Mode style and \"offsets\" when in the buffer's local variables. 686 "Set the CC Mode style and \"offsets\" when in the buffer's local variables.
667They are set only when, respectively, the pseudo variables 687They are set only when, respectively, the pseudo variables
@@ -669,11 +689,24 @@ They are set only when, respectively, the pseudo variables
669 689
670This function is called from the hook `before-hack-local-variables-hook'." 690This function is called from the hook `before-hack-local-variables-hook'."
671 (when c-buffer-is-cc-mode 691 (when c-buffer-is-cc-mode
672 (let ((stile (cdr (assq 'c-file-style file-local-variables-alist))) 692 (let ((mode-cons (assq 'mode file-local-variables-alist))
693 (stile (cdr (assq 'c-file-style file-local-variables-alist)))
673 (offsets (cdr (assq 'c-file-offsets file-local-variables-alist)))) 694 (offsets (cdr (assq 'c-file-offsets file-local-variables-alist))))
695 (when mode-cons
696 (hack-one-local-variable (car mode-cons) (cdr mode-cons))
697 (setq file-local-variables-alist
698 (delq mode-cons file-local-variables-alist)))
674 (when stile 699 (when stile
675 (or (stringp stile) (error "c-file-style is not a string")) 700 (or (stringp stile) (error "c-file-style is not a string"))
676 (c-set-style stile)) 701 (if (boundp 'dir-local-variables-alist)
702 ;; Determine whether `c-file-style' was set in the file's local
703 ;; variables or in a .dir-locals.el (a directory setting).
704 (let ((cfs-in-file-and-dir-count
705 (c-count-cfss file-local-variables-alist))
706 (cfs-in-dir-count (c-count-cfss dir-local-variables-alist)))
707 (c-set-style stile
708 (= cfs-in-file-and-dir-count cfs-in-dir-count)))
709 (c-set-style stile)))
677 (when offsets 710 (when offsets
678 (mapc 711 (mapc
679 (lambda (langentry) 712 (lambda (langentry)
@@ -787,15 +820,6 @@ Note that the style variables are always made local to the buffer."
787 820
788;;; Change hooks, linking with Font Lock. 821;;; Change hooks, linking with Font Lock.
789 822
790;; Buffer local variables defining the region to be fontified by a font lock
791;; after-change function. They are set in c-after-change to
792;; after-change-function's BEG and END, and may be modified by a
793;; `c-before-font-lock-function'.
794(defvar c-new-BEG 0)
795(make-variable-buffer-local 'c-new-BEG)
796(defvar c-new-END 0)
797(make-variable-buffer-local 'c-new-END)
798
799;; Buffer local variables recording Beginning/End-of-Macro position before a 823;; Buffer local variables recording Beginning/End-of-Macro position before a
800;; change, when a macro straddles, respectively, the BEG or END (or both) of 824;; change, when a macro straddles, respectively, the BEG or END (or both) of
801;; the change region. Otherwise these have the values BEG/END. 825;; the change region. Otherwise these have the values BEG/END.
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index 82015687cb2..f61c2a9fd06 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1056,9 +1056,13 @@ can always override the use of `c-default-style' by making calls to
1056 ;; Anchor pos: Boi at the topmost intro line. 1056 ;; Anchor pos: Boi at the topmost intro line.
1057 (knr-argdecl . 0) 1057 (knr-argdecl . 0)
1058 ;; Anchor pos: At the beginning of the first K&R argdecl. 1058 ;; Anchor pos: At the beginning of the first K&R argdecl.
1059 (topmost-intro . 0) 1059 (topmost-intro . 0)
1060 ;; Anchor pos: Bol at the last line of previous construct. 1060 ;; Anchor pos: Bol at the last line of previous construct.
1061 (topmost-intro-cont . c-lineup-topmost-intro-cont) 1061 (topmost-intro-cont . c-lineup-topmost-intro-cont)
1062 ;;Anchor pos: Bol at the topmost annotation line
1063 (annotation-top-cont . 0)
1064 ;;Anchor pos: Bol at the topmost annotation line
1065 (annotation-var-cont . +)
1062 ;; Anchor pos: Boi at the topmost intro line. 1066 ;; Anchor pos: Boi at the topmost intro line.
1063 (member-init-intro . +) 1067 (member-init-intro . +)
1064 ;; Anchor pos: Boi at the func decl arglist open. 1068 ;; Anchor pos: Boi at the func decl arglist open.
@@ -1285,12 +1289,16 @@ Here is the current list of valid syntactic element symbols:
1285 between them; in C++ and Java, throws declarations 1289 between them; in C++ and Java, throws declarations
1286 and other things can appear in this context. 1290 and other things can appear in this context.
1287 knr-argdecl-intro -- First line of a K&R C argument declaration. 1291 knr-argdecl-intro -- First line of a K&R C argument declaration.
1288 knr-argdecl -- Subsequent lines in a K&R C argument declaration. 1292 knr-argdecl -- Subsequent lines in a K&R C argument declaration.
1289 topmost-intro -- The first line in a topmost construct definition. 1293 topmost-intro -- The first line in a topmost construct definition.
1290 topmost-intro-cont -- Topmost definition continuation lines. 1294 topmost-intro-cont -- Topmost definition continuation lines.
1291 member-init-intro -- First line in a member initialization list. 1295 annotation-top-cont -- Topmost definition continuation line where only
1292 member-init-cont -- Subsequent member initialization list lines. 1296 annotations are on previous lines.
1293 inher-intro -- First line of a multiple inheritance list. 1297 annotation-var-cont -- A continuation of a C (or like) statement where
1298 only annotations are on previous lines.
1299 member-init-intro -- First line in a member initialization list.
1300 member-init-cont -- Subsequent member initialization list lines.
1301 inher-intro -- First line of a multiple inheritance list.
1294 inher-cont -- Subsequent multiple inheritance lines. 1302 inher-cont -- Subsequent multiple inheritance lines.
1295 block-open -- Statement block open brace. 1303 block-open -- Statement block open brace.
1296 block-close -- Statement block close brace. 1304 block-close -- Statement block close brace.
@@ -1376,7 +1384,7 @@ Here is the current list of valid syntactic element symbols:
1376 '(defun-block-intro block-open block-close statement statement-cont 1384 '(defun-block-intro block-open block-close statement statement-cont
1377 statement-block-intro statement-case-intro statement-case-open 1385 statement-block-intro statement-case-intro statement-case-open
1378 substatement substatement-open substatement-label case-label label 1386 substatement substatement-open substatement-label case-label label
1379 do-while-closure else-clause catch-clause inlambda)) 1387 do-while-closure else-clause catch-clause inlambda annotation-var-cont))
1380 1388
1381(defcustom c-style-variables-are-local-p t 1389(defcustom c-style-variables-are-local-p t
1382 "*Whether style variables should be buffer local by default. 1390 "*Whether style variables should be buffer local by default.
@@ -1577,7 +1585,7 @@ names)."))
1577 :group 'c) 1585 :group 'c)
1578 1586
1579(defcustom java-font-lock-extra-types 1587(defcustom java-font-lock-extra-types
1580 (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw*")) 1588 (list (concat "[" c-upper "]\\sw*[" c-lower "]\\sw"))
1581 (c-make-font-lock-extra-types-blurb "Java" "java-mode" (concat 1589 (c-make-font-lock-extra-types-blurb "Java" "java-mode" (concat
1582"For example, a value of (\"[" c-upper "]\\\\sw*[" c-lower "]\\\\sw*\") means 1590"For example, a value of (\"[" c-upper "]\\\\sw*[" c-lower "]\\\\sw*\") means
1583capitalized words are treated as type names (the requirement for a 1591capitalized words are treated as type names (the requirement for a
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 7000b4bbc8a..a909006e0c0 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -47,7 +47,7 @@
47;; using the same *compilation* buffer. this necessitates re-parsing markers. 47;; using the same *compilation* buffer. this necessitates re-parsing markers.
48 48
49;; FILE-STRUCTURE is a list of 49;; FILE-STRUCTURE is a list of
50;; ((FILENAME . DIRECTORY) FORMATS (LINE LOC ...) ...) 50;; ((FILENAME DIRECTORY) FORMATS (LINE LOC ...) ...)
51 51
52;; FILENAME is a string parsed from an error message. DIRECTORY is a string 52;; FILENAME is a string parsed from an error message. DIRECTORY is a string
53;; obtained by following directory change messages. DIRECTORY will be nil for 53;; obtained by following directory change messages. DIRECTORY will be nil for
@@ -196,6 +196,10 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
196 "^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\ 196 "^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\
197\\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4)) 197\\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4))
198 198
199 (cucumber
200 "\\(?:^cucumber\\(?: -p [^[:space:]]+\\)?\\|#\\)\
201\\(?: \\)\\([^\(].*\\):\\([1-9][0-9]*\\)" 1 2)
202
199 (edg-1 203 (edg-1
200 "^\\([^ \n]+\\)(\\([0-9]+\\)): \\(?:error\\|warnin\\(g\\)\\|remar\\(k\\)\\)" 204 "^\\([^ \n]+\\)(\\([0-9]+\\)): \\(?:error\\|warnin\\(g\\)\\|remar\\(k\\)\\)"
201 1 2 nil (3 . 4)) 205 1 2 nil (3 . 4))
@@ -223,6 +227,10 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
223 "^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\ 227 "^[-[:alnum:]_/ ]+: \\(?:\\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*: \\)?\
224\\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2)) 228\\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2))
225 229
230 (ruby
231 "^[\t ]*\\(?:from \\)?\
232\\([^\(\n][^[:space:]\n]*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?.*$" 1 2)
233
226 (java 234 (java
227 "^\\(?:[ \t]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()\n]+\\):\\([0-9]+\\))$" 2 3 nil (1)) 235 "^\\(?:[ \t]+at \\|==[0-9]+== +\\(?:at\\|b\\(y\\)\\)\\).+(\\([^()\n]+\\):\\([0-9]+\\))$" 2 3 nil (1))
228 236
@@ -325,6 +333,9 @@ during global destruction\\.$\\)" 1 2)
325 "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)" 333 "\\(?:Parse\\|Fatal\\) error: \\(.*\\) in \\(.*\\) on line \\([0-9]+\\)"
326 2 3 nil nil) 334 2 3 nil nil)
327 335
336 (ruby-Test::Unit
337 "[\t ]*\\[\\([^\(].*\\):\\([1-9][0-9]*\\)\\(\\]\\)?:$" 1 2)
338
328 (rxp 339 (rxp
329 "^\\(?:Error\\|Warnin\\(g\\)\\):.*\n.* line \\([0-9]+\\) char\ 340 "^\\(?:Error\\|Warnin\\(g\\)\\):.*\n.* line \\([0-9]+\\) char\
330 \\([0-9]+\\) of file://\\(.+\\)" 341 \\([0-9]+\\) of file://\\(.+\\)"
@@ -2083,7 +2094,7 @@ and overlay is highlighted between MK and END-MK."
2083 pre-existing 2094 pre-existing
2084 (let ((display-buffer-reuse-frames t) 2095 (let ((display-buffer-reuse-frames t)
2085 (pop-up-windows t)) 2096 (pop-up-windows t))
2086 ;; Pop up a window. 2097 ;; Pop up a window.
2087 (display-buffer (marker-buffer msg))))) 2098 (display-buffer (marker-buffer msg)))))
2088 (highlight-regexp (with-current-buffer (marker-buffer msg) 2099 (highlight-regexp (with-current-buffer (marker-buffer msg)
2089 ;; also do this while we change buffer 2100 ;; also do this while we change buffer
diff --git a/lisp/progmodes/delphi.el b/lisp/progmodes/delphi.el
index 1e5f1f506b3..2558456bc07 100644
--- a/lisp/progmodes/delphi.el
+++ b/lisp/progmodes/delphi.el
@@ -628,7 +628,9 @@ routine.")
628(defun delphi-token-at (p) 628(defun delphi-token-at (p)
629 ;; Returns the token from parsing text at point p. 629 ;; Returns the token from parsing text at point p.
630 (when (and (<= (point-min) p) (<= p (point-max))) 630 (when (and (<= (point-min) p) (<= p (point-max)))
631 (cond ((delphi-literal-token-at p)) 631 (cond ((delphi-char-token-at p ?\n 'newline))
632
633 ((delphi-literal-token-at p))
632 634
633 ((delphi-space-token-at p)) 635 ((delphi-space-token-at p))
634 636
@@ -638,7 +640,6 @@ routine.")
638 ((delphi-char-token-at p ?\) 'close-group)) 640 ((delphi-char-token-at p ?\) 'close-group))
639 ((delphi-char-token-at p ?\[ 'open-group)) 641 ((delphi-char-token-at p ?\[ 'open-group))
640 ((delphi-char-token-at p ?\] 'close-group)) 642 ((delphi-char-token-at p ?\] 'close-group))
641 ((delphi-char-token-at p ?\n 'newline))
642 ((delphi-char-token-at p ?\; 'semicolon)) 643 ((delphi-char-token-at p ?\; 'semicolon))
643 ((delphi-char-token-at p ?. 'dot)) 644 ((delphi-char-token-at p ?. 'dot))
644 ((delphi-char-token-at p ?, 'comma)) 645 ((delphi-char-token-at p ?, 'comma))
@@ -888,7 +889,24 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do:
888 (setq token (delphi-block-start token))) 889 (setq token (delphi-block-start token)))
889 890
890 ;; Regular block start found. 891 ;; Regular block start found.
891 ((delphi-is token-kind delphi-block-statements) (throw 'done token)) 892 ((delphi-is token-kind delphi-block-statements)
893 (throw 'done
894 ;; As a special case, when a "case" block appears
895 ;; within a record declaration (to denote a variant
896 ;; part), the record declaration should be considered
897 ;; the enclosing block.
898 (if (eq 'case token-kind)
899 (let ((enclosing-token
900 (delphi-block-start token
901 'stop-on-class)))
902 (if
903 (eq 'record
904 (delphi-token-kind enclosing-token))
905 (if stop-on-class
906 enclosing-token
907 (delphi-previous-token enclosing-token))
908 token))
909 token)))
892 910
893 ;; A class/record start also begins a block. 911 ;; A class/record start also begins a block.
894 ((delphi-composite-type-start token last-token) 912 ((delphi-composite-type-start token last-token)
@@ -1058,6 +1076,7 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do:
1058 (token-kind nil) 1076 (token-kind nil)
1059 (from-kind (delphi-token-kind from-token)) 1077 (from-kind (delphi-token-kind from-token))
1060 (last-colon nil) 1078 (last-colon nil)
1079 (last-of nil)
1061 (last-token nil)) 1080 (last-token nil))
1062 (catch 'done 1081 (catch 'done
1063 (while token 1082 (while token
@@ -1101,9 +1120,17 @@ non-delphi buffer. Set to nil in a delphi buffer. To override, just do:
1101 ;; Ignore whitespace. 1120 ;; Ignore whitespace.
1102 ((delphi-is token-kind delphi-whitespace)) 1121 ((delphi-is token-kind delphi-whitespace))
1103 1122
1104 ;; Remember any ':' we encounter, since that affects how we indent to 1123 ;; Remember any "of" we encounter, since that affects how we
1105 ;; a case statement. 1124 ;; indent to a case statement within a record declaration
1106 ((eq 'colon token-kind) (setq last-colon token)) 1125 ;; (i.e. a variant part).
1126 ((eq 'of token-kind)
1127 (setq last-of token))
1128
1129 ;; Remember any ':' we encounter (until we reach an "of"),
1130 ;; since that affects how we indent to case statements in
1131 ;; general.
1132 ((eq 'colon token-kind)
1133 (unless last-of (setq last-colon token)))
1107 1134
1108 ;; A case statement delimits a previous statement. We indent labels 1135 ;; A case statement delimits a previous statement. We indent labels
1109 ;; specially. 1136 ;; specially.
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 4f0fcd77ab5..2018a71574e 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -40,6 +40,7 @@ If you set this variable, do not also set `tags-table-list'.
40Use the `etags' program to make a tags table file.") 40Use the `etags' program to make a tags table file.")
41;; Make M-x set-variable tags-file-name like M-x visit-tags-table. 41;; Make M-x set-variable tags-file-name like M-x visit-tags-table.
42;;;###autoload (put 'tags-file-name 'variable-interactive (purecopy "fVisit tags table: ")) 42;;;###autoload (put 'tags-file-name 'variable-interactive (purecopy "fVisit tags table: "))
43;;;###autoload (put 'tags-file-name 'safe-local-variable 'stringp)
43 44
44(defgroup etags nil "Tags tables." 45(defgroup etags nil "Tags tables."
45 :group 'tools) 46 :group 'tools)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 2a198215536..712af6fd288 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -1152,7 +1152,8 @@ For the format of LINE-ERR-INFO, see `flymake-ler-make-ler'."
1152 (when dir 1152 (when dir
1153 (let ((default-directory dir)) 1153 (let ((default-directory dir))
1154 (flymake-log 3 "starting process on dir %s" default-directory))) 1154 (flymake-log 3 "starting process on dir %s" default-directory)))
1155 (setq process (apply 'start-process "flymake-proc" (current-buffer) cmd args)) 1155 (setq process (apply 'start-file-process
1156 "flymake-proc" (current-buffer) cmd args))
1156 (set-process-sentinel process 'flymake-process-sentinel) 1157 (set-process-sentinel process 'flymake-process-sentinel)
1157 (set-process-filter process 'flymake-process-filter) 1158 (set-process-filter process 'flymake-process-filter)
1158 (push process flymake-processes) 1159 (push process flymake-processes)
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index e4cc32b972c..5b98ff427c3 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -795,7 +795,10 @@ detailed description of this mode.
795 (gdb-input 795 (gdb-input
796 ;; Needs GDB 6.4 onwards 796 ;; Needs GDB 6.4 onwards
797 (list (concat "-inferior-tty-set " 797 (list (concat "-inferior-tty-set "
798 (process-tty-name (get-process "gdb-inferior"))) 798 (or
799 ;; The process can run on a remote host.
800 (process-get (get-process "gdb-inferior") 'remote-tty)
801 (process-tty-name (get-process "gdb-inferior"))))
799 'ignore)) 802 'ignore))
800 (if (eq window-system 'w32) 803 (if (eq window-system 'w32)
801 (gdb-input (list "-gdb-set new-console off" 'ignore))) 804 (gdb-input (list "-gdb-set new-console off" 'ignore)))
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index da38a086782..d20a14682c7 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -145,7 +145,7 @@ Used to grey out relevant toolbar icons.")
145 (gud-call "suspend")) 145 (gud-call "suspend"))
146 ((eq gud-minor-mode 'gdbmi) 146 ((eq gud-minor-mode 'gdbmi)
147 (gud-call (gdb-gud-context-command "-exec-interrupt"))) 147 (gud-call (gdb-gud-context-command "-exec-interrupt")))
148 (t 148 (t
149 (comint-interrupt-subjob))))) 149 (comint-interrupt-subjob)))))
150 150
151(easy-mmode-defmap gud-menu-map 151(easy-mmode-defmap gud-menu-map
@@ -2513,7 +2513,7 @@ comint mode, which see."
2513 (setq w (cdr w))) 2513 (setq w (cdr w)))
2514 (if w 2514 (if w
2515 (setcar w 2515 (setcar w
2516 (if (file-remote-p default-directory) 2516 (if (file-remote-p file)
2517 ;; Tramp has already been loaded if we are here. 2517 ;; Tramp has already been loaded if we are here.
2518 (setq file (tramp-file-name-localname 2518 (setq file (tramp-file-name-localname
2519 (tramp-dissect-file-name file))) 2519 (tramp-dissect-file-name file)))
diff --git a/lisp/progmodes/idlwave.el b/lisp/progmodes/idlwave.el
index 402893c5946..1d042c99451 100644
--- a/lisp/progmodes/idlwave.el
+++ b/lisp/progmodes/idlwave.el
@@ -1602,7 +1602,7 @@ Capitalize system variables - action only
1602 `(lambda () 1602 `(lambda ()
1603 (interactive) 1603 (interactive)
1604 (self-insert-command 1) 1604 (self-insert-command 1)
1605 ,@(if (listp cmd) cmd (list cmd)))))) 1605 ,(if (listp cmd) cmd (list cmd))))))
1606 1606
1607;; Set action and key bindings. 1607;; Set action and key bindings.
1608;; See description of the function `idlwave-action-and-binding'. 1608;; See description of the function `idlwave-action-and-binding'.
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index 6bd8fbc2442..9fb4822436a 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -431,11 +431,32 @@ Match group 1 is the name of the macro.")
431 :group 'js) 431 :group 'js)
432 432
433(defcustom js-expr-indent-offset 0 433(defcustom js-expr-indent-offset 0
434 "Number of additional spaces used for indentation of continued expressions. 434 "Number of additional spaces for indenting continued expressions.
435The value must be no less than minus `js-indent-level'." 435The value must be no less than minus `js-indent-level'."
436 :type 'integer 436 :type 'integer
437 :group 'js) 437 :group 'js)
438 438
439(defcustom js-paren-indent-offset 0
440 "Number of additional spaces for indenting expressions in parentheses.
441The value must be no less than minus `js-indent-level'."
442 :type 'integer
443 :group 'js
444 :version "24.1")
445
446(defcustom js-square-indent-offset 0
447 "Number of additional spaces for indenting expressions in square braces.
448The value must be no less than minus `js-indent-level'."
449 :type 'integer
450 :group 'js
451 :version "24.1")
452
453(defcustom js-curly-indent-offset 0
454 "Number of additional spaces for indenting expressions in curly braces.
455The value must be no less than minus `js-indent-level'."
456 :type 'integer
457 :group 'js
458 :version "24.1")
459
439(defcustom js-auto-indent-flag t 460(defcustom js-auto-indent-flag t
440 "Whether to automatically indent when typing punctuation characters. 461 "Whether to automatically indent when typing punctuation characters.
441If non-nil, the characters {}();,: also indent the current line 462If non-nil, the characters {}();,: also indent the current line
@@ -474,8 +495,7 @@ for preventing Firefox from stealing the keyboard focus."
474(defcustom js-js-tmpdir 495(defcustom js-js-tmpdir
475 "~/.emacs.d/js/js" 496 "~/.emacs.d/js/js"
476 "Temporary directory used by `js-mode' to communicate with Mozilla. 497 "Temporary directory used by `js-mode' to communicate with Mozilla.
477This directory must be readable and writable by both Mozilla and 498This directory must be readable and writable by both Mozilla and Emacs."
478Emacs."
479 :type 'directory 499 :type 'directory
480 :group 'js) 500 :group 'js)
481 501
@@ -499,11 +519,11 @@ getting timeout messages."
499 (define-key keymap [(meta ?.)] #'js-find-symbol) 519 (define-key keymap [(meta ?.)] #'js-find-symbol)
500 (easy-menu-define nil keymap "Javascript Menu" 520 (easy-menu-define nil keymap "Javascript Menu"
501 '("Javascript" 521 '("Javascript"
502 ["Select new Mozilla context…" js-set-js-context 522 ["Select New Mozilla Context..." js-set-js-context
503 (fboundp #'inferior-moz-process)] 523 (fboundp #'inferior-moz-process)]
504 ["Evaluate expression in Mozilla context…" js-eval 524 ["Evaluate Expression in Mozilla Context..." js-eval
505 (fboundp #'inferior-moz-process)] 525 (fboundp #'inferior-moz-process)]
506 ["Send current function to Mozilla…" js-eval-defun 526 ["Send Current Function to Mozilla..." js-eval-defun
507 (fboundp #'inferior-moz-process)])) 527 (fboundp #'inferior-moz-process)]))
508 keymap) 528 keymap)
509 "Keymap for `js-mode'.") 529 "Keymap for `js-mode'.")
@@ -1770,14 +1790,17 @@ nil."
1770 ((eq (char-after) ?#) 0) 1790 ((eq (char-after) ?#) 0)
1771 ((save-excursion (js--beginning-of-macro)) 4) 1791 ((save-excursion (js--beginning-of-macro)) 4)
1772 ((nth 1 parse-status) 1792 ((nth 1 parse-status)
1793 ;; A single closing paren/bracket should be indented at the
1794 ;; same level as the opening statement. Same goes for
1795 ;; "case" and "default".
1773 (let ((same-indent-p (looking-at 1796 (let ((same-indent-p (looking-at
1774 "[]})]\\|\\_<case\\_>\\|\\_<default\\_>")) 1797 "[]})]\\|\\_<case\\_>\\|\\_<default\\_>"))
1775 (continued-expr-p (js--continued-expression-p))) 1798 (continued-expr-p (js--continued-expression-p)))
1776 (goto-char (nth 1 parse-status)) 1799 (goto-char (nth 1 parse-status)) ; go to the opening char
1777 (if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)") 1800 (if (looking-at "[({[]\\s-*\\(/[/*]\\|$\\)")
1778 (progn 1801 (progn ; nothing following the opening paren/bracket
1779 (skip-syntax-backward " ") 1802 (skip-syntax-backward " ")
1780 (when (eq (char-before) ?\)) (backward-list)) 1803 (when (eq (char-before) ?\)) (backward-list))
1781 (back-to-indentation) 1804 (back-to-indentation)
1782 (cond (same-indent-p 1805 (cond (same-indent-p
1783 (current-column)) 1806 (current-column))
@@ -1785,7 +1808,14 @@ nil."
1785 (+ (current-column) (* 2 js-indent-level) 1808 (+ (current-column) (* 2 js-indent-level)
1786 js-expr-indent-offset)) 1809 js-expr-indent-offset))
1787 (t 1810 (t
1788 (+ (current-column) js-indent-level)))) 1811 (+ (current-column) js-indent-level
1812 (case (char-after (nth 1 parse-status))
1813 (?\( js-paren-indent-offset)
1814 (?\[ js-square-indent-offset)
1815 (?\{ js-curly-indent-offset))))))
1816 ;; If there is something following the opening
1817 ;; paren/bracket, everything else should be indented at
1818 ;; the same level.
1789 (unless same-indent-p 1819 (unless same-indent-p
1790 (forward-char) 1820 (forward-char)
1791 (skip-chars-forward " \t")) 1821 (skip-chars-forward " \t"))
@@ -3269,7 +3299,7 @@ If one hasn't been set, or if it's stale, prompt for a new one."
3269;;; Main Function 3299;;; Main Function
3270 3300
3271;;;###autoload 3301;;;###autoload
3272(define-derived-mode js-mode nil "js" 3302(define-derived-mode js-mode prog-mode "js"
3273 "Major mode for editing JavaScript. 3303 "Major mode for editing JavaScript.
3274 3304
3275Key bindings: 3305Key bindings:
diff --git a/lisp/progmodes/make-mode.el b/lisp/progmodes/make-mode.el
index 7a1aa3e70f4..362a1db6c10 100644
--- a/lisp/progmodes/make-mode.el
+++ b/lisp/progmodes/make-mode.el
@@ -768,7 +768,7 @@ The function must satisfy this calling convention:
768;;; ------------------------------------------------------------ 768;;; ------------------------------------------------------------
769 769
770;;;###autoload 770;;;###autoload
771(define-derived-mode makefile-mode nil "Makefile" 771(define-derived-mode makefile-mode prog-mode "Makefile"
772 "Major mode for editing standard Makefiles. 772 "Major mode for editing standard Makefiles.
773 773
774If you are editing a file for a different make, try one of the 774If you are editing a file for a different make, try one of the
@@ -1300,7 +1300,9 @@ definition and conveniently use this command."
1300 (save-restriction 1300 (save-restriction
1301 (narrow-to-region beginning end) 1301 (narrow-to-region beginning end)
1302 (makefile-backslash-region (point-min) (point-max) t) 1302 (makefile-backslash-region (point-min) (point-max) t)
1303 (let ((fill-paragraph-function nil)) 1303 (let ((fill-paragraph-function nil)
1304 ;; Adjust fill-column to allow space for the backslash.
1305 (fill-column (- fill-column 1)))
1304 (fill-paragraph nil)) 1306 (fill-paragraph nil))
1305 (makefile-backslash-region (point-min) (point-max) nil) 1307 (makefile-backslash-region (point-min) (point-max) nil)
1306 (goto-char (point-max)) 1308 (goto-char (point-max))
@@ -1314,7 +1316,9 @@ definition and conveniently use this command."
1314 ;; resulting region. 1316 ;; resulting region.
1315 (save-restriction 1317 (save-restriction
1316 (narrow-to-region (point) (line-beginning-position 2)) 1318 (narrow-to-region (point) (line-beginning-position 2))
1317 (let ((fill-paragraph-function nil)) 1319 (let ((fill-paragraph-function nil)
1320 ;; Adjust fill-column to allow space for the backslash.
1321 (fill-column (- fill-column 1)))
1318 (fill-paragraph nil)) 1322 (fill-paragraph nil))
1319 (makefile-backslash-region (point-min) (point-max) nil)) 1323 (makefile-backslash-region (point-min) (point-max) nil))
1320 ;; Return non-nil to indicate it's been filled. 1324 ;; Return non-nil to indicate it's been filled.
diff --git a/lisp/progmodes/octave-mod.el b/lisp/progmodes/octave-mod.el
index 12f561c6814..11d86ecbde4 100644
--- a/lisp/progmodes/octave-mod.el
+++ b/lisp/progmodes/octave-mod.el
@@ -4,7 +4,7 @@
4;; Free Software Foundation, Inc. 4;; Free Software Foundation, Inc.
5 5
6;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> 6;; Author: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
7;; Author: John Eaton <jwe@bevo.che.wisc.edu> 7;; Author: John Eaton <jwe@octave.org>
8;; Maintainer: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at> 8;; Maintainer: Kurt Hornik <Kurt.Hornik@wu-wien.ac.at>
9;; Keywords: languages 9;; Keywords: languages
10 10
@@ -92,7 +92,7 @@ All Octave abbrevs start with a grave accent (`)."
92(defvar octave-comment-char ?# 92(defvar octave-comment-char ?#
93 "Character to start an Octave comment.") 93 "Character to start an Octave comment.")
94(defvar octave-comment-start 94(defvar octave-comment-start
95 (string octave-comment-char ?\ ) 95 (string octave-comment-char ?\s)
96 "String to insert to start a new Octave in-line comment.") 96 "String to insert to start a new Octave in-line comment.")
97(defvar octave-comment-start-skip "\\s<+\\s-*" 97(defvar octave-comment-start-skip "\\s<+\\s-*"
98 "Regexp to match the start of an Octave comment up to its body.") 98 "Regexp to match the start of an Octave comment up to its body.")
@@ -171,9 +171,7 @@ parenthetical grouping.")
171 'font-lock-builtin-face 171 'font-lock-builtin-face
172 'font-lock-preprocessor-face)) 172 'font-lock-preprocessor-face))
173 ;; Fontify all builtin variables. 173 ;; Fontify all builtin variables.
174 (cons (concat "\\<\\(" 174 (cons (concat "\\<" (regexp-opt octave-variables) "\\>")
175 (mapconcat 'identity octave-variables "\\|")
176 "\\)\\>")
177 'font-lock-variable-name-face) 175 'font-lock-variable-name-face)
178 ;; Fontify all function declarations. 176 ;; Fontify all function declarations.
179 (list octave-function-header-regexp 177 (list octave-function-header-regexp
@@ -181,6 +179,30 @@ parenthetical grouping.")
181 '(3 font-lock-function-name-face nil t))) 179 '(3 font-lock-function-name-face nil t)))
182 "Additional Octave expressions to highlight.") 180 "Additional Octave expressions to highlight.")
183 181
182(defvar octave-font-lock-syntactic-keywords
183 ;; Try to distinguish the string-quotes from the transpose-quotes.
184 '(("[[({,; ]\\('\\)" (1 "\"'"))
185 (octave-font-lock-close-quotes)))
186
187(defun octave-font-lock-close-quotes (limit)
188 "Fix the syntax-table of the closing quotes of single-quote strings."
189 ;; Freely inspired from perl-font-lock-special-syntactic-constructs.
190 (let ((state (syntax-ppss)))
191 (while (< (point) limit)
192 (cond
193 ((eq (nth 3 state) ?\')
194 ;; A '..' string.
195 (save-excursion
196 (when (and (or (looking-at "\\('\\)")
197 (re-search-forward "[^\\]\\(?:\\\\\\\\\\)*\\('\\)"
198 nil t))
199 (not (eobp)))
200 (put-text-property (match-beginning 1) (match-end 1)
201 'syntax-table (string-to-syntax "\"'"))))))
202
203 (setq state (parse-partial-sexp (point) limit nil nil state
204 'syntax-table)))))
205
184(defcustom inferior-octave-buffer "*Inferior Octave*" 206(defcustom inferior-octave-buffer "*Inferior Octave*"
185 "Name of buffer for running an inferior Octave process." 207 "Name of buffer for running an inferior Octave process."
186 :type 'string 208 :type 'string
@@ -194,15 +216,8 @@ parenthetical grouping.")
194 (define-key map ";" 'octave-electric-semi) 216 (define-key map ";" 'octave-electric-semi)
195 (define-key map " " 'octave-electric-space) 217 (define-key map " " 'octave-electric-space)
196 (define-key map "\n" 'octave-reindent-then-newline-and-indent) 218 (define-key map "\n" 'octave-reindent-then-newline-and-indent)
197 (define-key map "\e;" 'octave-indent-for-comment)
198 (define-key map "\e\n" 'octave-indent-new-comment-line) 219 (define-key map "\e\n" 'octave-indent-new-comment-line)
199 (define-key map "\e\t" 'octave-complete-symbol)
200 (define-key map "\M-\C-a" 'octave-beginning-of-defun)
201 (define-key map "\M-\C-e" 'octave-end-of-defun)
202 (define-key map "\M-\C-h" 'octave-mark-defun)
203 (define-key map "\M-\C-q" 'octave-indent-defun) 220 (define-key map "\M-\C-q" 'octave-indent-defun)
204 (define-key map "\C-c;" 'octave-comment-region)
205 (define-key map "\C-c:" 'octave-uncomment-region)
206 (define-key map "\C-c\C-b" 'octave-submit-bug-report) 221 (define-key map "\C-c\C-b" 'octave-submit-bug-report)
207 (define-key map "\C-c\C-p" 'octave-previous-code-line) 222 (define-key map "\C-c\C-p" 'octave-previous-code-line)
208 (define-key map "\C-c\C-n" 'octave-next-code-line) 223 (define-key map "\C-c\C-n" 'octave-next-code-line)
@@ -235,7 +250,9 @@ parenthetical grouping.")
235 "Keymap used in Octave mode.") 250 "Keymap used in Octave mode.")
236 251
237 252
238(defvar octave-mode-menu 253
254(easy-menu-define octave-mode-menu octave-mode-map
255 "Menu for Octave mode."
239 '("Octave" 256 '("Octave"
240 ("Lines" 257 ("Lines"
241 ["Previous Code Line" octave-previous-code-line t] 258 ["Previous Code Line" octave-previous-code-line t]
@@ -251,9 +268,6 @@ parenthetical grouping.")
251 ["Mark Block" octave-mark-block t] 268 ["Mark Block" octave-mark-block t]
252 ["Close Block" octave-close-block t]) 269 ["Close Block" octave-close-block t])
253 ("Functions" 270 ("Functions"
254 ["Begin of Function" octave-beginning-of-defun t]
255 ["End of Function" octave-end-of-defun t]
256 ["Mark Function" octave-mark-defun t]
257 ["Indent Function" octave-indent-defun t] 271 ["Indent Function" octave-indent-defun t]
258 ["Insert Function" octave-insert-defun t]) 272 ["Insert Function" octave-insert-defun t])
259 "-" 273 "-"
@@ -267,16 +281,17 @@ parenthetical grouping.")
267 ["Kill Process" octave-kill-process t]) 281 ["Kill Process" octave-kill-process t])
268 "-" 282 "-"
269 ["Indent Line" indent-according-to-mode t] 283 ["Indent Line" indent-according-to-mode t]
270 ["Complete Symbol" octave-complete-symbol t] 284 ["Complete Symbol" completion-at-point t]
271 "-" 285 "-"
272 ["Toggle Abbrev Mode" abbrev-mode t] 286 ["Toggle Abbrev Mode" abbrev-mode
273 ["Toggle Auto-Fill Mode" auto-fill-mode t] 287 :style toggle :selected abbrev-mode]
288 ["Toggle Auto-Fill Mode" auto-fill-mode
289 :style toggle :selected auto-fill-function]
274 "-" 290 "-"
275 ["Submit Bug Report" octave-submit-bug-report t] 291 ["Submit Bug Report" octave-submit-bug-report t]
276 "-" 292 "-"
277 ["Describe Octave Mode" octave-describe-major-mode t] 293 ["Describe Octave Mode" describe-mode t]
278 ["Lookup Octave Index" octave-help t]) 294 ["Lookup Octave Index" info-lookup-symbol t]))
279 "Menu for Octave mode.")
280 295
281(defvar octave-mode-syntax-table 296(defvar octave-mode-syntax-table
282 (let ((table (make-syntax-table))) 297 (let ((table (make-syntax-table)))
@@ -298,8 +313,16 @@ parenthetical grouping.")
298 (modify-syntax-entry ?\" "\"" table) 313 (modify-syntax-entry ?\" "\"" table)
299 (modify-syntax-entry ?. "w" table) 314 (modify-syntax-entry ?. "w" table)
300 (modify-syntax-entry ?_ "w" table) 315 (modify-syntax-entry ?_ "w" table)
301 (modify-syntax-entry ?\% "<" table) 316 ;; The "b" flag only applies to the second letter of the comstart
302 (modify-syntax-entry ?\# "<" table) 317 ;; and the first letter of the comend, i.e. the "4b" below is ineffective.
318 ;; If we try to put `b' on the single-line comments, we get a similar
319 ;; problem where the % and # chars appear as first chars of the 2-char
320 ;; comend, so the multi-line ender is also turned into style-b.
321 ;; So we need the new "c" comment style.
322 (modify-syntax-entry ?\% "< 13" table)
323 (modify-syntax-entry ?\# "< 13" table)
324 (modify-syntax-entry ?\{ "(} 2c" table)
325 (modify-syntax-entry ?\} "){ 4c" table)
303 (modify-syntax-entry ?\n ">" table) 326 (modify-syntax-entry ?\n ">" table)
304 table) 327 table)
305 "Syntax table in use in `octave-mode' buffers.") 328 "Syntax table in use in `octave-mode' buffers.")
@@ -320,6 +343,7 @@ Non-nil means show matching begin of block when inserting a space,
320newline or semicolon after an else or end keyword." 343newline or semicolon after an else or end keyword."
321 :type 'boolean 344 :type 'boolean
322 :group 'octave) 345 :group 'octave)
346
323(defcustom octave-block-offset 2 347(defcustom octave-block-offset 2
324 "Extra indentation applied to statements in Octave block structures." 348 "Extra indentation applied to statements in Octave block structures."
325 :type 'integer 349 :type 'integer
@@ -343,13 +367,13 @@ newline or semicolon after an else or end keyword."
343 (concat octave-block-else-regexp "\\|" octave-block-end-regexp)) 367 (concat octave-block-else-regexp "\\|" octave-block-end-regexp))
344(defvar octave-block-match-alist 368(defvar octave-block-match-alist
345 '(("do" . ("until")) 369 '(("do" . ("until"))
346 ("for" . ("endfor" "end")) 370 ("for" . ("end" "endfor"))
347 ("function" . ("endfunction")) 371 ("function" . ("end" "endfunction"))
348 ("if" . ("else" "elseif" "endif" "end")) 372 ("if" . ("else" "elseif" "end" "endif"))
349 ("switch" . ("case" "otherwise" "endswitch" "end")) 373 ("switch" . ("case" "otherwise" "end" "endswitch"))
350 ("try" . ("catch" "end_try_catch")) 374 ("try" . ("catch" "end" "end_try_catch"))
351 ("unwind_protect" . ("unwind_protect_cleanup" "end_unwind_protect")) 375 ("unwind_protect" . ("unwind_protect_cleanup" "end" "end_unwind_protect"))
352 ("while" . ("endwhile" "end"))) 376 ("while" . ("end" "endwhile")))
353 "Alist with Octave's matching block keywords. 377 "Alist with Octave's matching block keywords.
354Has Octave's begin keywords as keys and a list of the matching else or 378Has Octave's begin keywords as keys and a list of the matching else or
355end keywords as associated values.") 379end keywords as associated values.")
@@ -402,7 +426,7 @@ Non-nil means always go to the next Octave code line after sending."
402 426
403 427
404;;;###autoload 428;;;###autoload
405(defun octave-mode () 429(define-derived-mode octave-mode prog-mode "Octave"
406 "Major mode for editing Octave code. 430 "Major mode for editing Octave code.
407 431
408This mode makes it easier to write Octave code by helping with 432This mode makes it easier to write Octave code by helping with
@@ -485,57 +509,50 @@ an Octave mode buffer.
485This automatically sets up a mail buffer with version information 509This automatically sets up a mail buffer with version information
486already added. You just need to add a description of the problem, 510already added. You just need to add a description of the problem,
487including a reproducible test case and send the message." 511including a reproducible test case and send the message."
488 (interactive)
489 (kill-all-local-variables)
490
491 (use-local-map octave-mode-map)
492 (setq major-mode 'octave-mode)
493 (setq mode-name "Octave")
494 (setq local-abbrev-table octave-abbrev-table) 512 (setq local-abbrev-table octave-abbrev-table)
495 (set-syntax-table octave-mode-syntax-table) 513
496 514 (set (make-local-variable 'indent-line-function) 'octave-indent-line)
497 (make-local-variable 'indent-line-function) 515
498 (setq indent-line-function 'octave-indent-line) 516 (set (make-local-variable 'comment-start) octave-comment-start)
499 517 (set (make-local-variable 'comment-end) "")
500 (make-local-variable 'comment-start) 518 ;; Don't set it here: it's not really a property of the language,
501 (setq comment-start octave-comment-start) 519 ;; just a personal preference of the author.
502 (make-local-variable 'comment-end) 520 ;; (set (make-local-variable 'comment-column) 32)
503 (setq comment-end "") 521 (set (make-local-variable 'comment-start-skip) "\\s<+\\s-*")
504 (make-local-variable 'comment-column) 522 (set (make-local-variable 'comment-add) 1)
505 (setq comment-column 32) 523
506 (make-local-variable 'comment-start-skip) 524 (set (make-local-variable 'parse-sexp-ignore-comments) t)
507 (setq comment-start-skip "\\s<+\\s-*") 525 (set (make-local-variable 'paragraph-start)
508 (make-local-variable 'comment-indent-function) 526 (concat "\\s-*$\\|" page-delimiter))
509 (setq comment-indent-function 'octave-comment-indent) 527 (set (make-local-variable 'paragraph-separate) paragraph-start)
510 528 (set (make-local-variable 'paragraph-ignore-fill-prefix) t)
511 (make-local-variable 'parse-sexp-ignore-comments) 529 (set (make-local-variable 'fill-paragraph-function) 'octave-fill-paragraph)
512 (setq parse-sexp-ignore-comments t) 530 ;; FIXME: Why disable it?
513 (make-local-variable 'paragraph-start) 531 ;; (set (make-local-variable 'adaptive-fill-regexp) nil)
514 (setq paragraph-start (concat "\\s-*$\\|" page-delimiter)) 532 ;; Again, this is not a property of the language, don't set it here.
515 (make-local-variable 'paragraph-separate) 533 ;; (set (make-local-variable 'fill-column) 72)
516 (setq paragraph-separate paragraph-start) 534 (set (make-local-variable 'normal-auto-fill-function) 'octave-auto-fill)
517 (make-local-variable 'paragraph-ignore-fill-prefix) 535
518 (setq paragraph-ignore-fill-prefix t) 536 (set (make-local-variable 'font-lock-defaults)
519 (make-local-variable 'fill-paragraph-function) 537 '(octave-font-lock-keywords nil nil nil nil
520 (setq fill-paragraph-function 'octave-fill-paragraph) 538 (font-lock-syntactic-keywords . octave-font-lock-syntactic-keywords)
521 (make-local-variable 'adaptive-fill-regexp) 539 (parse-sexp-lookup-properties . t)))
522 (setq adaptive-fill-regexp nil) 540
523 (make-local-variable 'fill-column) 541 (set (make-local-variable 'imenu-generic-expression)
524 (setq fill-column 72) 542 octave-mode-imenu-generic-expression)
525 (make-local-variable 'normal-auto-fill-function) 543 (set (make-local-variable 'imenu-case-fold-search) nil)
526 (setq normal-auto-fill-function 'octave-auto-fill) 544
527 545 (add-hook 'completion-at-point-functions
528 (make-local-variable 'font-lock-defaults) 546 'octave-completion-at-point-function nil t)
529 (setq font-lock-defaults '(octave-font-lock-keywords nil nil)) 547 (set (make-local-variable 'beginning-of-defun-function)
530 548 'octave-beginning-of-defun)
531 (make-local-variable 'imenu-generic-expression) 549
532 (setq imenu-generic-expression octave-mode-imenu-generic-expression 550 (easy-menu-add octave-mode-menu)
533 imenu-case-fold-search nil)
534
535 (octave-add-octave-menu)
536 (octave-initialize-completions) 551 (octave-initialize-completions)
537 (run-mode-hooks 'octave-mode-hook)) 552 (run-mode-hooks 'octave-mode-hook))
538 553
554(defvar info-lookup-mode)
555
539(defun octave-help () 556(defun octave-help ()
540 "Get help on Octave symbols from the Octave info files. 557 "Get help on Octave symbols from the Octave info files.
541Look up symbol in the function, operator and variable indices of the info files." 558Look up symbol in the function, operator and variable indices of the info files."
@@ -543,25 +560,22 @@ Look up symbol in the function, operator and variable indices of the info files.
543 (call-interactively 'info-lookup-symbol))) 560 (call-interactively 'info-lookup-symbol)))
544 561
545;;; Miscellaneous useful functions 562;;; Miscellaneous useful functions
546(defun octave-describe-major-mode ()
547 "Describe the current major mode."
548 (interactive)
549 (describe-function major-mode))
550 563
551(defsubst octave-in-comment-p () 564(defsubst octave-in-comment-p ()
552 "Return t if point is inside an Octave comment." 565 "Return t if point is inside an Octave comment."
553 (interactive)
554 (save-excursion 566 (save-excursion
567 ;; FIXME: use syntax-ppss?
555 (nth 4 (parse-partial-sexp (line-beginning-position) (point))))) 568 (nth 4 (parse-partial-sexp (line-beginning-position) (point)))))
556 569
557(defsubst octave-in-string-p () 570(defsubst octave-in-string-p ()
558 "Return t if point is inside an Octave string." 571 "Return t if point is inside an Octave string."
559 (interactive)
560 (save-excursion 572 (save-excursion
573 ;; FIXME: use syntax-ppss?
561 (nth 3 (parse-partial-sexp (line-beginning-position) (point))))) 574 (nth 3 (parse-partial-sexp (line-beginning-position) (point)))))
562 575
563(defsubst octave-not-in-string-or-comment-p () 576(defsubst octave-not-in-string-or-comment-p ()
564 "Return t if point is not inside an Octave string or comment." 577 "Return t if point is not inside an Octave string or comment."
578 ;; FIXME: Use syntax-ppss?
565 (let ((pps (parse-partial-sexp (line-beginning-position) (point)))) 579 (let ((pps (parse-partial-sexp (line-beginning-position) (point))))
566 (not (or (nth 3 pps) (nth 4 pps))))) 580 (not (or (nth 3 pps) (nth 4 pps)))))
567 581
@@ -595,22 +609,6 @@ to end after the end keyword."
595 (let ((case-fold-search nil)) 609 (let ((case-fold-search nil))
596 (re-search-backward regexp nil 'move count))) 610 (re-search-backward regexp nil 'move count)))
597 611
598(defun octave-in-defun-p ()
599 "Return t if point is inside an Octave function declaration.
600The function is taken to start at the `f' of `function' and to end after
601the end keyword."
602 (let ((pos (point)))
603 (save-excursion
604 (or (and (octave-looking-at-kw "\\<function\\>")
605 (octave-not-in-string-or-comment-p))
606 (and (octave-beginning-of-defun)
607 (condition-case nil
608 (progn
609 (octave-forward-block)
610 t)
611 (error nil))
612 (< pos (point)))))))
613
614(defun octave-maybe-insert-continuation-string () 612(defun octave-maybe-insert-continuation-string ()
615 (if (or (octave-in-comment-p) 613 (if (or (octave-in-comment-p)
616 (save-excursion 614 (save-excursion
@@ -620,23 +618,9 @@ the end keyword."
620 (delete-horizontal-space) 618 (delete-horizontal-space)
621 (insert (concat " " octave-continuation-string)))) 619 (insert (concat " " octave-continuation-string))))
622 620
623;;; Comments
624(defun octave-comment-region (beg end &optional arg)
625 "Comment or uncomment each line in the region as Octave code.
626See `comment-region'."
627 (interactive "r\nP")
628 (let ((comment-start (char-to-string octave-comment-char)))
629 (comment-region beg end arg)))
630
631(defun octave-uncomment-region (beg end &optional arg)
632 "Uncomment each line in the region as Octave code."
633 (interactive "r\nP")
634 (or arg (setq arg 1))
635 (octave-comment-region beg end (- arg)))
636
637 621
638;;; Indentation 622;;; Indentation
639(defun calculate-octave-indent () 623(defun octave-indent-calculate ()
640 "Return appropriate indentation for current line as Octave code. 624 "Return appropriate indentation for current line as Octave code.
641Returns an integer (the column to indent to) unless the line is a 625Returns an integer (the column to indent to) unless the line is a
642comment line with fixed goal golumn. In that case, returns a list whose 626comment line with fixed goal golumn. In that case, returns a list whose
@@ -722,36 +706,13 @@ level."
722 (beginning-of-line) 706 (beginning-of-line)
723 (and (bobp) (looking-at "\\s-*#!")))) 707 (and (bobp) (looking-at "\\s-*#!"))))
724 708
725(defun octave-comment-indent ()
726 (if (or (looking-at "\\s<\\s<\\s<")
727 (octave-before-magic-comment-p))
728 0
729 (if (looking-at "\\s<\\s<")
730 (calculate-octave-indent)
731 (skip-syntax-backward " ")
732 (max (if (bolp) 0 (+ 1 (current-column)))
733 comment-column))))
734
735(defun octave-indent-for-comment ()
736 "Maybe insert and indent an Octave comment.
737If there is no comment already on this line, create a code-level comment
738\(started by two comment characters) if the line is empty, or an in-line
739comment (started by one comment character) otherwise.
740Point is left after the start of the comment which is properly aligned."
741 (interactive)
742 (beginning-of-line)
743 (if (looking-at "^\\s-*$")
744 (insert octave-block-comment-start)
745 (indent-for-comment))
746 (indent-according-to-mode))
747
748(defun octave-indent-line (&optional arg) 709(defun octave-indent-line (&optional arg)
749 "Indent current line as Octave code. 710 "Indent current line as Octave code.
750With optional ARG, use this as offset unless this line is a comment with 711With optional ARG, use this as offset unless this line is a comment with
751fixed goal column." 712fixed goal column."
752 (interactive) 713 (interactive)
753 (or arg (setq arg 0)) 714 (or arg (setq arg 0))
754 (let ((icol (calculate-octave-indent)) 715 (let ((icol (octave-indent-calculate))
755 (relpos (- (current-column) (current-indentation)))) 716 (relpos (- (current-column) (current-indentation))))
756 (if (listp icol) 717 (if (listp icol)
757 (setq icol (car icol)) 718 (setq icol (car icol))
@@ -782,7 +743,7 @@ The new line is properly indented."
782 "Properly indent the Octave function which contains point." 743 "Properly indent the Octave function which contains point."
783 (interactive) 744 (interactive)
784 (save-excursion 745 (save-excursion
785 (octave-mark-defun) 746 (mark-defun)
786 (message "Indenting function...") 747 (message "Indenting function...")
787 (indent-region (point) (mark) nil)) 748 (indent-region (point) (mark) nil))
788 (message "Indenting function...done.")) 749 (message "Indenting function...done."))
@@ -1039,16 +1000,16 @@ Signal an error if the keywords are incompatible."
1039With positive ARG, do it that many times. Negative argument -N means 1000With positive ARG, do it that many times. Negative argument -N means
1040move forward to Nth following beginning of a function. 1001move forward to Nth following beginning of a function.
1041Returns t unless search stops at the beginning or end of the buffer." 1002Returns t unless search stops at the beginning or end of the buffer."
1042 (interactive "p")
1043 (let* ((arg (or arg 1)) 1003 (let* ((arg (or arg 1))
1044 (inc (if (> arg 0) 1 -1)) 1004 (inc (if (> arg 0) 1 -1))
1045 (found)) 1005 (found nil)
1006 (case-fold-search nil))
1046 (and (not (eobp)) 1007 (and (not (eobp))
1047 (not (and (> arg 0) (octave-looking-at-kw "\\<function\\>"))) 1008 (not (and (> arg 0) (looking-at "\\<function\\>")))
1048 (skip-syntax-forward "w")) 1009 (skip-syntax-forward "w"))
1049 (while (and (/= arg 0) 1010 (while (and (/= arg 0)
1050 (setq found 1011 (setq found
1051 (octave-re-search-backward-kw "\\<function\\>" inc))) 1012 (re-search-backward "\\<function\\>" inc)))
1052 (if (octave-not-in-string-or-comment-p) 1013 (if (octave-not-in-string-or-comment-p)
1053 (setq arg (- arg inc)))) 1014 (setq arg (- arg inc))))
1054 (if found 1015 (if found
@@ -1056,40 +1017,6 @@ Returns t unless search stops at the beginning or end of the buffer."
1056 (and (< inc 0) (goto-char (match-beginning 0))) 1017 (and (< inc 0) (goto-char (match-beginning 0)))
1057 t)))) 1018 t))))
1058 1019
1059(defun octave-end-of-defun (&optional arg)
1060 "Move forward to the end of an Octave function.
1061With positive ARG, do it that many times. Negative argument -N means
1062move back to Nth preceding end of a function.
1063
1064An end of a function occurs right after the end keyword matching the
1065`function' keyword that starts the function."
1066 (interactive "p")
1067 (or arg (setq arg 1))
1068 (and (< arg 0) (skip-syntax-backward "w"))
1069 (and (> arg 0) (skip-syntax-forward "w"))
1070 (if (octave-in-defun-p)
1071 (setq arg (- arg 1)))
1072 (if (= arg 0) (setq arg -1))
1073 (if (octave-beginning-of-defun (- arg))
1074 (octave-forward-block)))
1075
1076(defun octave-mark-defun ()
1077 "Put point at the beginning of this Octave function, mark at its end.
1078The function marked is the one containing point or following point."
1079 (interactive)
1080 (let ((pos (point)))
1081 (if (or (octave-in-defun-p)
1082 (and (octave-beginning-of-defun -1)
1083 (octave-in-defun-p)))
1084 (progn
1085 (skip-syntax-forward "w")
1086 (octave-beginning-of-defun)
1087 (push-mark (point))
1088 (octave-end-of-defun)
1089 (exchange-point-and-mark))
1090 (goto-char pos)
1091 (message "No function to mark found"))))
1092
1093 1020
1094;;; Filling 1021;;; Filling
1095(defun octave-auto-fill () 1022(defun octave-auto-fill ()
@@ -1166,7 +1093,7 @@ otherwise."
1166 (beginning-of-line) 1093 (beginning-of-line)
1167 (point))) 1094 (point)))
1168 (cfc (current-fill-column)) 1095 (cfc (current-fill-column))
1169 (ind (calculate-octave-indent)) 1096 (ind (octave-indent-calculate))
1170 comment-prefix) 1097 comment-prefix)
1171 (save-restriction 1098 (save-restriction
1172 (goto-char beg) 1099 (goto-char beg)
@@ -1237,34 +1164,37 @@ otherwise."
1237 (if octave-completion-alist 1164 (if octave-completion-alist
1238 () 1165 ()
1239 (setq octave-completion-alist 1166 (setq octave-completion-alist
1240 (mapcar '(lambda (var) (cons var var)) 1167 (append octave-reserved-words
1241 (append octave-reserved-words 1168 octave-text-functions
1242 octave-text-functions 1169 octave-variables))))
1243 octave-variables))))) 1170
1171(defun octave-completion-at-point-function ()
1172 "Find the text to complete and the corresponding table."
1173 (let* ((beg (save-excursion (backward-sexp 1) (point)))
1174 (end (point)))
1175 (if (< beg (point))
1176 ;; Extend region past point, if applicable.
1177 (save-excursion (goto-char beg) (forward-sexp 1)
1178 (setq end (max end (point)))))
1179 (list beg end octave-completion-alist)))
1244 1180
1245(defun octave-complete-symbol () 1181(defun octave-complete-symbol ()
1246 "Perform completion on Octave symbol preceding point. 1182 "Perform completion on Octave symbol preceding point.
1247Compare that symbol against Octave's reserved words and builtin 1183Compare that symbol against Octave's reserved words and builtin
1248variables." 1184variables."
1249 (interactive) 1185 (interactive)
1250 (let* ((end (point)) 1186 (apply 'completion-in-region (octave-completion-at-point-function)))
1251 (beg (save-excursion (backward-sexp 1) (point))))
1252 (completion-in-region beg end octave-completion-alist)))
1253
1254 1187
1255;;; Electric characters && friends 1188;;; Electric characters && friends
1256(defun octave-reindent-then-newline-and-indent () 1189(defun octave-reindent-then-newline-and-indent ()
1257 "Reindent current Octave line, insert newline, and indent the new line. 1190 "Reindent current Octave line, insert newline, and indent the new line.
1258If Abbrev mode is on, expand abbrevs first." 1191If Abbrev mode is on, expand abbrevs first."
1192 ;; FIXME: None of this is Octave-specific.
1259 (interactive) 1193 (interactive)
1260 (if abbrev-mode (expand-abbrev)) 1194 (if abbrev-mode (expand-abbrev))
1261 (if octave-blink-matching-block 1195 (if octave-blink-matching-block
1262 (octave-blink-matching-block-open)) 1196 (octave-blink-matching-block-open))
1263 (save-excursion 1197 (reindent-then-newline-and-indent))
1264 (delete-region (point) (progn (skip-chars-backward " \t") (point)))
1265 (indent-according-to-mode))
1266 (insert "\n")
1267 (indent-according-to-mode))
1268 1198
1269(defun octave-electric-semi () 1199(defun octave-electric-semi ()
1270 "Insert a semicolon in Octave mode. 1200 "Insert a semicolon in Octave mode.
@@ -1324,51 +1254,27 @@ Note that all Octave mode abbrevs start with a grave accent."
1324 (list-abbrevs)) 1254 (list-abbrevs))
1325 (setq unread-command-events (list c)))))) 1255 (setq unread-command-events (list c))))))
1326 1256
1327(defun octave-insert-defun (name args vals) 1257(define-skeleton octave-insert-defun
1328 "Insert an Octave function skeleton. 1258 "Insert an Octave function skeleton.
1329Prompt for the function's name, arguments and return values (to be 1259Prompt for the function's name, arguments and return values (to be
1330entered without parens)." 1260entered without parens)."
1331 (interactive 1261 (let* ((defname (substring (buffer-name) 0 -2))
1332 (list 1262 (name (read-string (format "Function name (default %s): " defname)
1333 (read-from-minibuffer "Function name: " 1263 nil nil defname))
1334 (substring (buffer-name) 0 -2)) 1264 (args (read-string "Arguments: "))
1335 (read-from-minibuffer "Arguments: ") 1265 (vals (read-string "Return values: ")))
1336 (read-from-minibuffer "Return values: "))) 1266 (format "%s%s (%s)"
1337 (let ((string (format "%s %s (%s)" 1267 (cond
1338 (cond 1268 ((string-equal vals "") vals)
1339 ((string-equal vals "") 1269 ((string-match "[ ,]" vals) (concat "[" vals "] = "))
1340 vals) 1270 (t (concat vals " = ")))
1341 ((string-match "[ ,]" vals) 1271 name
1342 (concat " [" vals "] =")) 1272 args))
1343 (t 1273 \n "function " > str \n \n
1344 (concat " " vals " ="))) 1274 octave-block-comment-start "usage: " str \n
1345 name 1275 octave-block-comment-start \n octave-block-comment-start
1346 args)) 1276 \n _ \n
1347 (prefix octave-block-comment-start)) 1277 "endfunction" > \n)
1348 (if (not (bobp)) (newline))
1349 (insert "function" string)
1350 (indent-according-to-mode)
1351 (newline 2)
1352 (insert prefix "usage: " string)
1353 (reindent-then-newline-and-indent)
1354 (insert prefix)
1355 (reindent-then-newline-and-indent)
1356 (insert prefix)
1357 (indent-according-to-mode)
1358 (save-excursion
1359 (newline 2)
1360 (insert "endfunction")
1361 (indent-according-to-mode))))
1362
1363
1364;;; Menu
1365(defun octave-add-octave-menu ()
1366 "Add the `Octave' menu to the menu bar in Octave mode."
1367 (require 'easymenu)
1368 (easy-menu-define octave-mode-menu-map octave-mode-map
1369 "Menu keymap for Octave mode." octave-mode-menu)
1370 (easy-menu-add octave-mode-menu-map octave-mode-map))
1371
1372 1278
1373;;; Communication with the inferior Octave process 1279;;; Communication with the inferior Octave process
1374(defun octave-kill-process () 1280(defun octave-kill-process ()
@@ -1435,7 +1341,7 @@ entered without parens)."
1435 "Send current Octave function to the inferior Octave process." 1341 "Send current Octave function to the inferior Octave process."
1436 (interactive) 1342 (interactive)
1437 (save-excursion 1343 (save-excursion
1438 (octave-mark-defun) 1344 (mark-defun)
1439 (octave-send-region (point) (mark)))) 1345 (octave-send-region (point) (mark))))
1440 1346
1441(defun octave-send-line (&optional arg) 1347(defun octave-send-line (&optional arg)
diff --git a/lisp/progmodes/prolog.el b/lisp/progmodes/prolog.el
index 64277dc4f82..77e334ca8d8 100644
--- a/lisp/progmodes/prolog.el
+++ b/lisp/progmodes/prolog.el
@@ -31,7 +31,7 @@
31 31
32(defvar comint-prompt-regexp) 32(defvar comint-prompt-regexp)
33(defvar comint-process-echoes) 33(defvar comint-process-echoes)
34(defvar smie-indent-basic) 34(require 'smie)
35 35
36(defgroup prolog nil 36(defgroup prolog nil
37 "Major mode for editing and running Prolog under Emacs." 37 "Major mode for editing and running Prolog under Emacs."
diff --git a/lisp/progmodes/ps-mode.el b/lisp/progmodes/ps-mode.el
index 7b235bc3b68..387a0cb6e00 100644
--- a/lisp/progmodes/ps-mode.el
+++ b/lisp/progmodes/ps-mode.el
@@ -39,6 +39,7 @@
39(defconst ps-mode-version "1.1h, 16 Jun 2005") 39(defconst ps-mode-version "1.1h, 16 Jun 2005")
40(defconst ps-mode-maintainer-address "Peter Kleiweg <p.c.j.kleiweg@rug.nl>") 40(defconst ps-mode-maintainer-address "Peter Kleiweg <p.c.j.kleiweg@rug.nl>")
41 41
42(require 'comint)
42(require 'easymenu) 43(require 'easymenu)
43 44
44;; Define core `PostScript' group. 45;; Define core `PostScript' group.
@@ -431,12 +432,11 @@ If nil, use `temporary-file-directory'."
431 432
432(unless ps-run-mode-map 433(unless ps-run-mode-map
433 (setq ps-run-mode-map (make-sparse-keymap)) 434 (setq ps-run-mode-map (make-sparse-keymap))
435 (set-keymap-parent ps-run-mode-map comint-mode-map)
434 (define-key ps-run-mode-map "\C-c\C-q" 'ps-run-quit) 436 (define-key ps-run-mode-map "\C-c\C-q" 'ps-run-quit)
435 (define-key ps-run-mode-map "\C-c\C-k" 'ps-run-kill) 437 (define-key ps-run-mode-map "\C-c\C-k" 'ps-run-kill)
436 (define-key ps-run-mode-map "\C-c\C-e" 'ps-run-goto-error) 438 (define-key ps-run-mode-map "\C-c\C-e" 'ps-run-goto-error)
437 (define-key ps-run-mode-map [mouse-2] 'ps-run-mouse-goto-error) 439 (define-key ps-run-mode-map [mouse-2] 'ps-run-mouse-goto-error))
438 (define-key ps-run-mode-map "\r" 'ps-run-newline)
439 (define-key ps-run-mode-map [return] 'ps-run-newline))
440 440
441 441
442;; Syntax table. 442;; Syntax table.
@@ -718,12 +718,9 @@ defines the beginning of a group. These tokens are: { [ <<"
718 (blink-matching-open)) 718 (blink-matching-open))
719 719
720(defun ps-mode-other-newline () 720(defun ps-mode-other-newline ()
721 "Perform newline in `*ps run*' buffer." 721 "Perform newline in `*ps-run*' buffer."
722 (interactive) 722 (interactive)
723 (let ((buf (current-buffer))) 723 (ps-run-send-string ""))
724 (set-buffer "*ps run*")
725 (ps-run-newline)
726 (set-buffer buf)))
727 724
728 725
729;; Print PostScript. 726;; Print PostScript.
@@ -980,7 +977,7 @@ plus the usually uncoded characters inserted on positions 1 through 28."
980 977
981;; Interactive PostScript interpreter. 978;; Interactive PostScript interpreter.
982 979
983(define-derived-mode ps-run-mode fundamental-mode "Interactive PS" 980(define-derived-mode ps-run-mode comint-mode "Interactive PS"
984 "Major mode in interactive PostScript window. 981 "Major mode in interactive PostScript window.
985This mode is invoked from `ps-mode' and should not be called directly. 982This mode is invoked from `ps-mode' and should not be called directly.
986 983
@@ -1014,20 +1011,23 @@ This mode is invoked from `ps-mode' and should not be called directly.
1014 (setq init-file (ps-run-make-tmp-filename)) 1011 (setq init-file (ps-run-make-tmp-filename))
1015 (write-region (concat ps-run-init "\n") 0 init-file) 1012 (write-region (concat ps-run-init "\n") 0 init-file)
1016 (setq init-file (list init-file))) 1013 (setq init-file (list init-file)))
1017 (pop-to-buffer "*ps run*") 1014 (pop-to-buffer "*ps-run*")
1018 (ps-run-mode) 1015 (ps-run-mode)
1019 (when (process-status "ps-run") 1016 (when (process-status "ps-run")
1020 (delete-process "ps-run")) 1017 (delete-process "ps-run"))
1021 (erase-buffer) 1018 (erase-buffer)
1022 (setq command (append command init-file)) 1019 (setq command (append command init-file))
1023 (insert (mapconcat 'identity command " ") "\n") 1020 (insert (mapconcat 'identity command " ") "\n")
1024 (apply 'start-process "ps-run" "*ps run*" command) 1021 (apply 'make-comint "ps-run" (car command) nil (cdr command))
1022 (with-current-buffer "*ps-run*"
1023 (use-local-map ps-run-mode-map)
1024 (setq comint-prompt-regexp ps-run-prompt))
1025 (select-window oldwin))) 1025 (select-window oldwin)))
1026 1026
1027(defun ps-run-quit () 1027(defun ps-run-quit ()
1028 "Quit interactive PostScript." 1028 "Quit interactive PostScript."
1029 (interactive) 1029 (interactive)
1030 (ps-run-send-string "quit" t) 1030 (ps-run-send-string "quit")
1031 (ps-run-cleanup)) 1031 (ps-run-cleanup))
1032 1032
1033(defun ps-run-kill () 1033(defun ps-run-kill ()
@@ -1039,9 +1039,9 @@ This mode is invoked from `ps-mode' and should not be called directly.
1039(defun ps-run-clear () 1039(defun ps-run-clear ()
1040 "Clear/reset PostScript graphics." 1040 "Clear/reset PostScript graphics."
1041 (interactive) 1041 (interactive)
1042 (ps-run-send-string "showpage" t) 1042 (ps-run-send-string "showpage")
1043 (sit-for 1) 1043 (sit-for 1)
1044 (ps-run-send-string "" t)) 1044 (ps-run-send-string ""))
1045 1045
1046(defun ps-run-buffer () 1046(defun ps-run-buffer ()
1047 "Send buffer to PostScript interpreter." 1047 "Send buffer to PostScript interpreter."
@@ -1056,7 +1056,7 @@ This mode is invoked from `ps-mode' and should not be called directly.
1056 (let ((f (ps-run-make-tmp-filename))) 1056 (let ((f (ps-run-make-tmp-filename)))
1057 (set-marker ps-run-mark begin) 1057 (set-marker ps-run-mark begin)
1058 (write-region begin end f) 1058 (write-region begin end f)
1059 (ps-run-send-string (format "(%s) run" f) t))) 1059 (ps-run-send-string (format "(%s) run" f))))
1060 1060
1061(defun ps-run-boundingbox () 1061(defun ps-run-boundingbox ()
1062 "View BoundingBox." 1062 "View BoundingBox."
@@ -1104,17 +1104,15 @@ grestore
1104" x1 y1 x2 y1 x2 y2 x1 y2) 1104" x1 y1 x2 y1 x2 y2 x1 y2)
1105 0 1105 0
1106 f) 1106 f)
1107 (ps-run-send-string (format "(%s) run" f) t) 1107 (ps-run-send-string (format "(%s) run" f))
1108 (set-buffer buf))) 1108 (set-buffer buf)))
1109 1109
1110(defun ps-run-send-string (string &optional echo) 1110(defun ps-run-send-string (string)
1111 (let ((oldwin (selected-window))) 1111 (let ((oldwin (selected-window)))
1112 (pop-to-buffer "*ps run*") 1112 (pop-to-buffer "*ps-run*")
1113 (goto-char (point-max)) 1113 (comint-goto-process-mark)
1114 (when echo 1114 (insert string)
1115 (insert string "\n")) 1115 (comint-send-input)
1116 (set-marker (process-mark (get-process "ps-run")) (point))
1117 (process-send-string "ps-run" (concat string "\n"))
1118 (select-window oldwin))) 1116 (select-window oldwin)))
1119 1117
1120(defun ps-run-make-tmp-filename () 1118(defun ps-run-make-tmp-filename ()
@@ -1140,18 +1138,6 @@ grestore
1140 (mouse-set-point event) 1138 (mouse-set-point event)
1141 (ps-run-goto-error)) 1139 (ps-run-goto-error))
1142 1140
1143(defun ps-run-newline ()
1144 "Process newline in PostScript interpreter window."
1145 (interactive)
1146 (end-of-line)
1147 (insert "\n")
1148 (forward-line -1)
1149 (when (looking-at ps-run-prompt)
1150 (goto-char (match-end 0)))
1151 (looking-at ".*")
1152 (goto-char (1+ (match-end 0)))
1153 (ps-run-send-string (buffer-substring (match-beginning 0) (match-end 0))))
1154
1155(defun ps-run-goto-error () 1141(defun ps-run-goto-error ()
1156 "Jump to buffer position read as integer at point. 1142 "Jump to buffer position read as integer at point.
1157Use line numbers if `ps-run-error-line-numbers' is not nil" 1143Use line numbers if `ps-run-error-line-numbers' is not nil"
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 4e0f326e2d4..849951a633a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -93,7 +93,7 @@
93 93
94(defvar python-font-lock-keywords 94(defvar python-font-lock-keywords
95 `(,(rx symbol-start 95 `(,(rx symbol-start
96 ;; From v 2.5 reference, § keywords. 96 ;; From v 2.7 reference, § keywords.
97 ;; def and class dealt with separately below 97 ;; def and class dealt with separately below
98 (or "and" "as" "assert" "break" "continue" "del" "elif" "else" 98 (or "and" "as" "assert" "break" "continue" "del" "elif" "else"
99 "except" "exec" "finally" "for" "from" "global" "if" 99 "except" "exec" "finally" "for" "from" "global" "if"
@@ -102,7 +102,7 @@
102 ;; Not real keywords, but close enough to be fontified as such 102 ;; Not real keywords, but close enough to be fontified as such
103 "self" "True" "False") 103 "self" "True" "False")
104 symbol-end) 104 symbol-end)
105 (,(rx symbol-start "None" symbol-end) ; see § Keywords in 2.5 manual 105 (,(rx symbol-start "None" symbol-end) ; see § Keywords in 2.7 manual
106 . font-lock-constant-face) 106 . font-lock-constant-face)
107 ;; Definitions 107 ;; Definitions
108 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_)))) 108 (,(rx symbol-start (group "class") (1+ space) (group (1+ (or word ?_))))
@@ -117,7 +117,7 @@
117 (0+ "." (1+ (or word ?_))))) 117 (0+ "." (1+ (or word ?_)))))
118 (1 font-lock-type-face)) 118 (1 font-lock-type-face))
119 ;; Built-ins. (The next three blocks are from 119 ;; Built-ins. (The next three blocks are from
120 ;; `__builtin__.__dict__.keys()' in Python 2.5.1.) These patterns 120 ;; `__builtin__.__dict__.keys()' in Python 2.7) These patterns
121 ;; are debateable, but they at least help to spot possible 121 ;; are debateable, but they at least help to spot possible
122 ;; shadowing of builtins. 122 ;; shadowing of builtins.
123 (,(rx symbol-start (or 123 (,(rx symbol-start (or
@@ -135,7 +135,9 @@
135 "SystemExit" "TabError" "TypeError" "UnboundLocalError" 135 "SystemExit" "TabError" "TypeError" "UnboundLocalError"
136 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError" 136 "UnicodeDecodeError" "UnicodeEncodeError" "UnicodeError"
137 "UnicodeTranslateError" "UnicodeWarning" "UserWarning" 137 "UnicodeTranslateError" "UnicodeWarning" "UserWarning"
138 "ValueError" "Warning" "ZeroDivisionError") symbol-end) 138 "ValueError" "Warning" "ZeroDivisionError"
139 ;; Python 2.7
140 "BufferError" "BytesWarning" "WindowsError") symbol-end)
139 . font-lock-type-face) 141 . font-lock-type-face)
140 (,(rx (or line-start (not (any ". \t"))) (* (any " \t")) symbol-start 142 (,(rx (or line-start (not (any ". \t"))) (* (any " \t")) symbol-start
141 (group (or 143 (group (or
@@ -152,12 +154,16 @@
152 "range" "raw_input" "reduce" "reload" "repr" "reversed" 154 "range" "raw_input" "reduce" "reload" "repr" "reversed"
153 "round" "set" "setattr" "slice" "sorted" "staticmethod" 155 "round" "set" "setattr" "slice" "sorted" "staticmethod"
154 "str" "sum" "super" "tuple" "type" "unichr" "unicode" "vars" 156 "str" "sum" "super" "tuple" "type" "unichr" "unicode" "vars"
155 "xrange" "zip")) symbol-end) 157 "xrange" "zip"
158 ;; Python 2.7.
159 "bin" "bytearray" "bytes" "format" "memoryview" "next" "print"
160 )) symbol-end)
156 (1 font-lock-builtin-face)) 161 (1 font-lock-builtin-face))
157 (,(rx symbol-start (or 162 (,(rx symbol-start (or
158 ;; other built-ins 163 ;; other built-ins
159 "True" "False" "None" "Ellipsis" 164 "True" "False" "None" "Ellipsis"
160 "_" "__debug__" "__doc__" "__import__" "__name__") symbol-end) 165 "_" "__debug__" "__doc__" "__import__" "__name__" "__package__")
166 symbol-end)
161 . font-lock-builtin-face))) 167 . font-lock-builtin-face)))
162 168
163(defconst python-font-lock-syntactic-keywords 169(defconst python-font-lock-syntactic-keywords
@@ -573,6 +579,33 @@ having to restart the program."
573 "Queue of Python temp files awaiting execution. 579 "Queue of Python temp files awaiting execution.
574Currently-active file is at the head of the list.") 580Currently-active file is at the head of the list.")
575 581
582(defcustom python-shell-prompt-alist
583 '(("ipython" . "^In \\[[0-9]+\\]: *")
584 (t . "^>>> "))
585 "Alist of Python input prompts.
586Each element has the form (PROGRAM . REGEXP), where PROGRAM is
587the value of `python-python-command' for the python process and
588REGEXP is a regular expression matching the Python prompt.
589PROGRAM can also be t, which specifies the default when no other
590element matches `python-python-command'."
591 :type 'string
592 :group 'python
593 :version "24.1")
594
595(defcustom python-shell-continuation-prompt-alist
596 '(("ipython" . "^ [.][.][.]+: *")
597 (t . "^[.][.][.] "))
598 "Alist of Python continued-line prompts.
599Each element has the form (PROGRAM . REGEXP), where PROGRAM is
600the value of `python-python-command' for the python process and
601REGEXP is a regular expression matching the Python prompt for
602continued lines.
603PROGRAM can also be t, which specifies the default when no other
604element matches `python-python-command'."
605 :type 'string
606 :group 'python
607 :version "24.1")
608
576(defvar python-pdbtrack-is-tracking-p nil) 609(defvar python-pdbtrack-is-tracking-p nil)
577 610
578(defconst python-pdbtrack-stack-entry-regexp 611(defconst python-pdbtrack-stack-entry-regexp
@@ -1305,13 +1338,9 @@ See `python-check-command' for the default."
1305 1338
1306;;;; Inferior mode stuff (following cmuscheme). 1339;;;; Inferior mode stuff (following cmuscheme).
1307 1340
1308;; Fixme: Make sure we can work with IPython.
1309
1310(defcustom python-python-command "python" 1341(defcustom python-python-command "python"
1311 "Shell command to run Python interpreter. 1342 "Shell command to run Python interpreter.
1312Any arguments can't contain whitespace. 1343Any arguments can't contain whitespace."
1313Note that IPython may not work properly; it must at least be used
1314with the `-cl' flag, i.e. use `ipython -cl'."
1315 :group 'python 1344 :group 'python
1316 :type 'string) 1345 :type 'string)
1317 1346
@@ -1389,6 +1418,23 @@ local value.")
1389;; Autoloaded. 1418;; Autoloaded.
1390(declare-function compilation-shell-minor-mode "compile" (&optional arg)) 1419(declare-function compilation-shell-minor-mode "compile" (&optional arg))
1391 1420
1421(defvar python--prompt-regexp nil)
1422
1423(defun python--set-prompt-regexp ()
1424 (let ((prompt (cdr-safe (or (assoc python-python-command
1425 python-shell-prompt-alist)
1426 (assq t python-shell-prompt-alist))))
1427 (cprompt (cdr-safe (or (assoc python-python-command
1428 python-shell-continuation-prompt-alist)
1429 (assq t python-shell-continuation-prompt-alist)))))
1430 (set (make-local-variable 'comint-prompt-regexp)
1431 (concat "\\("
1432 (mapconcat 'identity
1433 (delq nil (list prompt cprompt "^([Pp]db) "))
1434 "\\|")
1435 "\\)"))
1436 (set (make-local-variable 'python--prompt-regexp) prompt)))
1437
1392;; Fixme: This should inherit some stuff from `python-mode', but I'm 1438;; Fixme: This should inherit some stuff from `python-mode', but I'm
1393;; not sure how much: at least some keybindings, like C-c C-f; 1439;; not sure how much: at least some keybindings, like C-c C-f;
1394;; syntax?; font-locking, e.g. for triple-quoted strings? 1440;; syntax?; font-locking, e.g. for triple-quoted strings?
@@ -1411,14 +1457,12 @@ For running multiple processes in multiple buffers, see `run-python' and
1411 1457
1412\\{inferior-python-mode-map}" 1458\\{inferior-python-mode-map}"
1413 :group 'python 1459 :group 'python
1460 (require 'ansi-color) ; for ipython
1414 (setq mode-line-process '(":%s")) 1461 (setq mode-line-process '(":%s"))
1415 (set (make-local-variable 'comint-input-filter) 'python-input-filter) 1462 (set (make-local-variable 'comint-input-filter) 'python-input-filter)
1416 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter 1463 (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter
1417 nil t) 1464 nil t)
1418 ;; Still required by `comint-redirect-send-command', for instance 1465 (python--set-prompt-regexp)
1419 ;; (and we need to match things like `>>> ... >>> '):
1420 (set (make-local-variable 'comint-prompt-regexp)
1421 (rx line-start (1+ (and (or (repeat 3 (any ">.")) "(Pdb)") " "))))
1422 (set (make-local-variable 'compilation-error-regexp-alist) 1466 (set (make-local-variable 'compilation-error-regexp-alist)
1423 python-compilation-regexp-alist) 1467 python-compilation-regexp-alist)
1424 (compilation-shell-minor-mode 1)) 1468 (compilation-shell-minor-mode 1))
@@ -1515,12 +1559,12 @@ Don't save anything for STR matching `inferior-python-filter-regexp'."
1515 cmd))) 1559 cmd)))
1516 (unless (shell-command-to-string cmd) 1560 (unless (shell-command-to-string cmd)
1517 (error "Can't run Python command `%s'" cmd)) 1561 (error "Can't run Python command `%s'" cmd))
1518 (let* ((res (shell-command-to-string (concat cmd " --version")))) 1562 (let* ((res (shell-command-to-string
1519 (string-match "Python \\([0-9]\\)\\.\\([0-9]\\)" res) 1563 (concat cmd
1520 (unless (and (equal "2" (match-string 1 res)) 1564 " -c \"from sys import version_info;\
1521 (match-beginning 2) 1565print version_info >= (2, 2) and version_info < (3, 0)\""))))
1522 (>= (string-to-number (match-string 2 res)) 2)) 1566 (unless (string-match "True" res)
1523 (error "Only Python versions >= 2.2 and < 3.0 supported"))) 1567 (error "Only Python versions >= 2.2 and < 3.0 are supported")))
1524 (setq python-version-checked t))) 1568 (setq python-version-checked t)))
1525 1569
1526;;;###autoload 1570;;;###autoload
@@ -1543,6 +1587,7 @@ buffer for a list of commands.)"
1543 (interactive (if current-prefix-arg 1587 (interactive (if current-prefix-arg
1544 (list (read-string "Run Python: " python-command) nil t) 1588 (list (read-string "Run Python: " python-command) nil t)
1545 (list python-command))) 1589 (list python-command)))
1590 (require 'ansi-color) ; for ipython
1546 (unless cmd (setq cmd python-command)) 1591 (unless cmd (setq cmd python-command))
1547 (python-check-version cmd) 1592 (python-check-version cmd)
1548 (setq python-command cmd) 1593 (setq python-command cmd)
@@ -1560,8 +1605,10 @@ buffer for a list of commands.)"
1560 (if path (concat path path-separator)) 1605 (if path (concat path path-separator))
1561 data-directory) 1606 data-directory)
1562 process-environment)) 1607 process-environment))
1563 ;; Suppress use of pager for help output: 1608 ;; If we use a pipe, unicode characters are not printed
1564 (process-connection-type nil)) 1609 ;; correctly (Bug#5794) and IPython does not work at
1610 ;; all (Bug#5390).
1611 (process-connection-type t))
1565 (apply 'make-comint-in-buffer "Python" 1612 (apply 'make-comint-in-buffer "Python"
1566 (generate-new-buffer "*Python*") 1613 (generate-new-buffer "*Python*")
1567 (car cmdlist) nil (cdr cmdlist))) 1614 (car cmdlist) nil (cdr cmdlist)))
@@ -1617,7 +1664,12 @@ buffer for a list of commands.)"
1617 ;; non-ASCII. 1664 ;; non-ASCII.
1618 (interactive "r") 1665 (interactive "r")
1619 (let* ((f (make-temp-file "py")) 1666 (let* ((f (make-temp-file "py"))
1620 (command (format "emacs.eexecfile(%S)" f)) 1667 (command
1668 ;; IPython puts the FakeModule module into __main__ so
1669 ;; emacs.eexecfile becomes useless.
1670 (if (string-match "^ipython" python-command)
1671 (format "execfile %S" f)
1672 (format "emacs.eexecfile(%S)" f)))
1621 (orig-start (copy-marker start))) 1673 (orig-start (copy-marker start)))
1622 (when (save-excursion 1674 (when (save-excursion
1623 (goto-char start) 1675 (goto-char start)
@@ -1817,7 +1869,9 @@ If there isn't, it's probably not appropriate to send input to return Eldoc
1817information etc. If PROC is non-nil, check the buffer for that process." 1869information etc. If PROC is non-nil, check the buffer for that process."
1818 (with-current-buffer (process-buffer (or proc (python-proc))) 1870 (with-current-buffer (process-buffer (or proc (python-proc)))
1819 (save-excursion 1871 (save-excursion
1820 (save-match-data (re-search-backward ">>> \\=" nil t))))) 1872 (save-match-data
1873 (re-search-backward (concat python--prompt-regexp " *\\=")
1874 nil t)))))
1821 1875
1822;; Fixme: Is there anything reasonable we can do with random methods? 1876;; Fixme: Is there anything reasonable we can do with random methods?
1823;; (Currently only works with functions.) 1877;; (Currently only works with functions.)
@@ -2533,9 +2587,7 @@ Runs `jython-mode-hook' after `python-mode-hook'."
2533 "Watch output for Python prompt and exec next file waiting in queue. 2587 "Watch output for Python prompt and exec next file waiting in queue.
2534This function is appropriate for `comint-output-filter-functions'." 2588This function is appropriate for `comint-output-filter-functions'."
2535 ;; TBD: this should probably use split-string 2589 ;; TBD: this should probably use split-string
2536 (when (and (or (string-equal string ">>> ") 2590 (when (and (string-match python--prompt-regexp string)
2537 (and (>= (length string) 5)
2538 (string-equal (substring string -5) "\n>>> ")))
2539 python-file-queue) 2591 python-file-queue)
2540 (condition-case nil 2592 (condition-case nil
2541 (delete-file (car python-file-queue)) 2593 (delete-file (car python-file-queue))
@@ -2747,6 +2799,7 @@ comint believe the user typed this string so that
2747 (funcall (process-filter proc) proc msg)) 2799 (funcall (process-filter proc) proc msg))
2748 (set-buffer curbuf)) 2800 (set-buffer curbuf))
2749 (process-send-string proc cmd))) 2801 (process-send-string proc cmd)))
2802
2750;;;###autoload 2803;;;###autoload
2751(defun python-shell (&optional argprompt) 2804(defun python-shell (&optional argprompt)
2752 "Start an interactive Python interpreter in another window. 2805 "Start an interactive Python interpreter in another window.
@@ -2786,6 +2839,7 @@ interaction between undo and process filters; the same problem exists in
2786non-Python process buffers using the default (Emacs-supplied) process 2839non-Python process buffers using the default (Emacs-supplied) process
2787filter." 2840filter."
2788 (interactive "P") 2841 (interactive "P")
2842 (require 'ansi-color) ; For ipython
2789 ;; Set the default shell if not already set 2843 ;; Set the default shell if not already set
2790 (when (null python-which-shell) 2844 (when (null python-which-shell)
2791 (python-toggle-shells python-default-interpreter)) 2845 (python-toggle-shells python-default-interpreter))
@@ -2802,10 +2856,9 @@ filter."
2802 )))) 2856 ))))
2803 (switch-to-buffer-other-window 2857 (switch-to-buffer-other-window
2804 (apply 'make-comint python-which-bufname python-which-shell nil args)) 2858 (apply 'make-comint python-which-bufname python-which-shell nil args))
2805 (make-local-variable 'comint-prompt-regexp)
2806 (set-process-sentinel (get-buffer-process (current-buffer)) 2859 (set-process-sentinel (get-buffer-process (current-buffer))
2807 'python-sentinel) 2860 'python-sentinel)
2808 (setq comint-prompt-regexp "^>>> \\|^[.][.][.] \\|^(pdb) ") 2861 (python--set-prompt-regexp)
2809 (add-hook 'comint-output-filter-functions 2862 (add-hook 'comint-output-filter-functions
2810 'python-comint-output-filter-function nil t) 2863 'python-comint-output-filter-function nil t)
2811 ;; pdbtrack 2864 ;; pdbtrack
diff --git a/lisp/progmodes/ruby-mode.el b/lisp/progmodes/ruby-mode.el
index 59d85e60eef..0b92234bf1c 100644
--- a/lisp/progmodes/ruby-mode.el
+++ b/lisp/progmodes/ruby-mode.el
@@ -43,6 +43,11 @@
43 43
44(eval-when-compile (require 'cl)) 44(eval-when-compile (require 'cl))
45 45
46(defgroup ruby nil
47 "Major mode for editing Ruby code."
48 :prefix "ruby-"
49 :group 'languages)
50
46(defconst ruby-keyword-end-re 51(defconst ruby-keyword-end-re
47 (if (string-match "\\_>" "ruby") 52 (if (string-match "\\_>" "ruby")
48 "\\_>" 53 "\\_>"
@@ -166,7 +171,6 @@ This should only be called after matching against `ruby-here-doc-end-re'."
166 (define-key map (kbd "M-C-n") 'ruby-end-of-block) 171 (define-key map (kbd "M-C-n") 'ruby-end-of-block)
167 (define-key map (kbd "M-C-h") 'ruby-mark-defun) 172 (define-key map (kbd "M-C-h") 'ruby-mark-defun)
168 (define-key map (kbd "M-C-q") 'ruby-indent-exp) 173 (define-key map (kbd "M-C-q") 'ruby-indent-exp)
169 (define-key map (kbd "TAB") 'ruby-indent-line)
170 (define-key map (kbd "C-M-h") 'backward-kill-word) 174 (define-key map (kbd "C-M-h") 'backward-kill-word)
171 (define-key map (kbd "C-j") 'reindent-then-newline-and-indent) 175 (define-key map (kbd "C-j") 'reindent-then-newline-and-indent)
172 (define-key map (kbd "C-m") 'newline) 176 (define-key map (kbd "C-m") 'newline)
@@ -1390,6 +1394,8 @@ The variable `ruby-indent-level' controls the amount of indentation.
1390 (setq major-mode 'ruby-mode) 1394 (setq major-mode 'ruby-mode)
1391 (ruby-mode-variables) 1395 (ruby-mode-variables)
1392 1396
1397 (set (make-local-variable 'indent-line-function)
1398 'ruby-indent-line)
1393 (set (make-local-variable 'imenu-create-index-function) 1399 (set (make-local-variable 'imenu-create-index-function)
1394 'ruby-imenu-create-index) 1400 'ruby-imenu-create-index)
1395 (set (make-local-variable 'add-log-current-defun-function) 1401 (set (make-local-variable 'add-log-current-defun-function)
diff --git a/lisp/progmodes/scheme.el b/lisp/progmodes/scheme.el
index ce8a34220e4..da143db5ffb 100644
--- a/lisp/progmodes/scheme.el
+++ b/lisp/progmodes/scheme.el
@@ -107,7 +107,7 @@
107 ;; Special characters 107 ;; Special characters
108 (modify-syntax-entry ?, "' " st) 108 (modify-syntax-entry ?, "' " st)
109 (modify-syntax-entry ?@ "' " st) 109 (modify-syntax-entry ?@ "' " st)
110 (modify-syntax-entry ?# "' 14b" st) 110 (modify-syntax-entry ?# "' 14" st)
111 (modify-syntax-entry ?\\ "\\ " st) 111 (modify-syntax-entry ?\\ "\\ " st)
112 st)) 112 st))
113 113
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el
index 5f4028af89a..9041bd50259 100644
--- a/lisp/progmodes/sh-script.el
+++ b/lisp/progmodes/sh-script.el
@@ -2207,10 +2207,9 @@ STRING This is ignored for the purposes of calculating
2207 ;; Note: setting result to t means we are done and will return nil. 2207 ;; Note: setting result to t means we are done and will return nil.
2208 ;;(This function never returns just t.) 2208 ;;(This function never returns just t.)
2209 (cond 2209 (cond
2210 ((or (and (boundp 'font-lock-string-face) (not (bobp)) 2210 ((or (nth 3 (syntax-ppss (point)))
2211 (eq (get-text-property (1- (point)) 'face)
2212 font-lock-string-face))
2213 (eq (get-text-property (point) 'face) sh-heredoc-face)) 2211 (eq (get-text-property (point) 'face) sh-heredoc-face))
2212 ;; String continuation -- don't indent
2214 (setq result t) 2213 (setq result t)
2215 (setq have-result t)) 2214 (setq have-result t))
2216 ((looking-at "\\s-*#") ; was (equal this-kw "#") 2215 ((looking-at "\\s-*#") ; was (equal this-kw "#")
diff --git a/lisp/progmodes/simula.el b/lisp/progmodes/simula.el
index 3f842903b0d..f8d1a6aca97 100644
--- a/lisp/progmodes/simula.el
+++ b/lisp/progmodes/simula.el
@@ -330,7 +330,7 @@ for SIMULA mode to function correctly."
330 (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu))) 330 (popup-menu (cons (concat mode-name " Mode Commands") simula-mode-menu)))
331 331
332;;;###autoload 332;;;###autoload
333(define-derived-mode simula-mode nil "Simula" 333(define-derived-mode simula-mode prog-mode "Simula"
334 "Major mode for editing SIMULA code. 334 "Major mode for editing SIMULA code.
335\\{simula-mode-map} 335\\{simula-mode-map}
336Variables controlling indentation style: 336Variables controlling indentation style:
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 19e60da7ea2..e44504688f2 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -5,7 +5,7 @@
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.1 8;; Version: 2.5
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 11;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
@@ -152,11 +152,7 @@
152 152
153;; (defcustom my-sql-xyz-login-params '(user password server database) 153;; (defcustom my-sql-xyz-login-params '(user password server database)
154;; "Login parameters to needed to connect to XyzDB." 154;; "Login parameters to needed to connect to XyzDB."
155;; :type '(repeat (choice 155;; :type 'sql-login-params
156;; (const user)
157;; (const password)
158;; (const server)
159;; (const database)))
160;; :group 'SQL) 156;; :group 'SQL)
161;; 157;;
162;; (sql-set-product-feature 'xyz 158;; (sql-set-product-feature 'xyz
@@ -170,7 +166,7 @@
170;; (sql-set-product-feature 'xyz 166;; (sql-set-product-feature 'xyz
171;; :sqli-options 'my-sql-xyz-options)) 167;; :sqli-options 'my-sql-xyz-options))
172 168
173;; (defun my-sql-connect-xyz (product options) 169;; (defun my-sql-comint-xyz (product options)
174;; "Connect ti XyzDB in a comint buffer." 170;; "Connect ti XyzDB in a comint buffer."
175;; 171;;
176;; ;; Do something with `sql-user', `sql-password', 172;; ;; Do something with `sql-user', `sql-password',
@@ -184,10 +180,10 @@
184;; (setq params (append (list "-P" sql-password) params))) 180;; (setq params (append (list "-P" sql-password) params)))
185;; (if (not (string= "" sql-user)) 181;; (if (not (string= "" sql-user))
186;; (setq params (append (list "-U" sql-user) params))) 182;; (setq params (append (list "-U" sql-user) params)))
187;; (sql-connect product params))) 183;; (sql-comint product params)))
188;; 184;;
189;; (sql-set-product-feature 'xyz 185;; (sql-set-product-feature 'xyz
190;; :sqli-connect-func 'my-sql-connect-xyz) 186;; :sqli-comint-func 'my-sql-comint-xyz)
191 187
192;; 6) Define a convienence function to invoke the SQL interpreter. 188;; 6) Define a convienence function to invoke the SQL interpreter.
193 189
@@ -236,7 +232,7 @@
236 (require 'regexp-opt)) 232 (require 'regexp-opt))
237(require 'custom) 233(require 'custom)
238(eval-when-compile ;; needed in Emacs 19, 20 234(eval-when-compile ;; needed in Emacs 19, 20
239 (setq max-specpdl-size 2000)) 235 (setq max-specpdl-size (max max-specpdl-size 2000)))
240 236
241(defvar font-lock-keyword-face) 237(defvar font-lock-keyword-face)
242(defvar font-lock-set-defaults) 238(defvar font-lock-set-defaults)
@@ -255,8 +251,8 @@
255(defcustom sql-user "" 251(defcustom sql-user ""
256 "Default username." 252 "Default username."
257 :type 'string 253 :type 'string
258 :group 'SQL) 254 :group 'SQL
259(put 'sql-user 'safe-local-variable 'stringp) 255 :safe 'stringp)
260 256
261(defcustom sql-password "" 257(defcustom sql-password ""
262 "Default password. 258 "Default password.
@@ -264,32 +260,68 @@
264Storing your password in a textfile such as ~/.emacs could be dangerous. 260Storing your password in a textfile such as ~/.emacs could be dangerous.
265Customizing your password will store it in your ~/.emacs file." 261Customizing your password will store it in your ~/.emacs file."
266 :type 'string 262 :type 'string
267 :group 'SQL) 263 :group 'SQL
268(put 'sql-password 'risky-local-variable t) 264 :risky t)
269 265
270(defcustom sql-database "" 266(defcustom sql-database ""
271 "Default database." 267 "Default database."
272 :type 'string 268 :type 'string
273 :group 'SQL) 269 :group 'SQL
274(put 'sql-database 'safe-local-variable 'stringp) 270 :safe 'stringp)
275 271
276(defcustom sql-server "" 272(defcustom sql-server ""
277 "Default server or host." 273 "Default server or host."
278 :type 'string 274 :type 'string
279 :group 'SQL) 275 :group 'SQL
280(put 'sql-server 'safe-local-variable 'stringp) 276 :safe 'stringp)
281 277
282(defcustom sql-port nil 278(defcustom sql-port nil
283 "Default server or host." 279 "Default server or host."
280 :version "24.1"
284 :type 'number 281 :type 'number
285 :group 'SQL) 282 :group 'SQL
286(put 'sql-port 'safe-local-variable 'numberp) 283 :safe 'numberp)
284
285;; Login parameter type
286
287(define-widget 'sql-login-params 'lazy
288 "Widget definition of the login parameters list"
289 :tag "Login Parameters"
290 :type '(repeat (choice
291 (const user)
292 (const password)
293 (choice :tag "server"
294 (const server)
295 (list :tag "file"
296 (const :format "" server)
297 (const :format "" :file)
298 regexp)
299 (list :tag "completion"
300 (const :format "" server)
301 (const :format "" :completion)
302 (restricted-sexp
303 :match-alternatives (listp symbolp))))
304 (choice :tag "database"
305 (const database)
306 (list :tag "file"
307 (const :format "" database)
308 (const :format "" :file)
309 regexp)
310 (list :tag "completion"
311 (const :format "" database)
312 (const :format "" :completion)
313 (restricted-sexp
314 :match-alternatives (listp symbolp))))
315 (const port))))
287 316
288;; SQL Product support 317;; SQL Product support
289 318
290(defvar sql-interactive-product nil 319(defvar sql-interactive-product nil
291 "Product under `sql-interactive-mode'.") 320 "Product under `sql-interactive-mode'.")
292 321
322(defvar sql-connection nil
323 "Connection name if interactive session started by `sql-connect'.")
324
293(defvar sql-product-alist 325(defvar sql-product-alist
294 '((ansi 326 '((ansi
295 :name "ANSI" 327 :name "ANSI"
@@ -301,9 +333,10 @@ Customizing your password will store it in your ~/.emacs file."
301 :sqli-program sql-db2-program 333 :sqli-program sql-db2-program
302 :sqli-options sql-db2-options 334 :sqli-options sql-db2-options
303 :sqli-login sql-db2-login-params 335 :sqli-login sql-db2-login-params
304 :sqli-connect-func sql-connect-db2 336 :sqli-comint-func sql-comint-db2
305 :prompt-regexp "^db2 => " 337 :prompt-regexp "^db2 => "
306 :prompt-length 7 338 :prompt-length 7
339 :prompt-cont-regexp "^db2 (cont\.) => "
307 :input-filter sql-escape-newlines-filter) 340 :input-filter sql-escape-newlines-filter)
308 341
309 (informix 342 (informix
@@ -312,7 +345,7 @@ Customizing your password will store it in your ~/.emacs file."
312 :sqli-program sql-informix-program 345 :sqli-program sql-informix-program
313 :sqli-options sql-informix-options 346 :sqli-options sql-informix-options
314 :sqli-login sql-informix-login-params 347 :sqli-login sql-informix-login-params
315 :sqli-connect-func sql-connect-informix 348 :sqli-comint-func sql-comint-informix
316 :prompt-regexp "^> " 349 :prompt-regexp "^> "
317 :prompt-length 2 350 :prompt-length 2
318 :syntax-alist ((?{ . "<") (?} . ">"))) 351 :syntax-alist ((?{ . "<") (?} . ">")))
@@ -323,9 +356,10 @@ Customizing your password will store it in your ~/.emacs file."
323 :sqli-program sql-ingres-program 356 :sqli-program sql-ingres-program
324 :sqli-options sql-ingres-options 357 :sqli-options sql-ingres-options
325 :sqli-login sql-ingres-login-params 358 :sqli-login sql-ingres-login-params
326 :sqli-connect-func sql-connect-ingres 359 :sqli-comint-func sql-comint-ingres
327 :prompt-regexp "^\* " 360 :prompt-regexp "^\* "
328 :prompt-length 2) 361 :prompt-length 2
362 :prompt-cont-regexp "^\* ")
329 363
330 (interbase 364 (interbase
331 :name "Interbase" 365 :name "Interbase"
@@ -333,7 +367,7 @@ Customizing your password will store it in your ~/.emacs file."
333 :sqli-program sql-interbase-program 367 :sqli-program sql-interbase-program
334 :sqli-options sql-interbase-options 368 :sqli-options sql-interbase-options
335 :sqli-login sql-interbase-login-params 369 :sqli-login sql-interbase-login-params
336 :sqli-connect-func sql-connect-interbase 370 :sqli-comint-func sql-comint-interbase
337 :prompt-regexp "^SQL> " 371 :prompt-regexp "^SQL> "
338 :prompt-length 5) 372 :prompt-length 5)
339 373
@@ -343,7 +377,7 @@ Customizing your password will store it in your ~/.emacs file."
343 :sqli-program sql-linter-program 377 :sqli-program sql-linter-program
344 :sqli-options sql-linter-options 378 :sqli-options sql-linter-options
345 :sqli-login sql-linter-login-params 379 :sqli-login sql-linter-login-params
346 :sqli-connect-func sql-connect-linter 380 :sqli-comint-func sql-comint-linter
347 :prompt-regexp "^SQL>" 381 :prompt-regexp "^SQL>"
348 :prompt-length 4) 382 :prompt-length 4)
349 383
@@ -353,7 +387,7 @@ Customizing your password will store it in your ~/.emacs file."
353 :sqli-program sql-ms-program 387 :sqli-program sql-ms-program
354 :sqli-options sql-ms-options 388 :sqli-options sql-ms-options
355 :sqli-login sql-ms-login-params 389 :sqli-login sql-ms-login-params
356 :sqli-connect-func sql-connect-ms 390 :sqli-comint-func sql-comint-ms
357 :prompt-regexp "^[0-9]*>" 391 :prompt-regexp "^[0-9]*>"
358 :prompt-length 5 392 :prompt-length 5
359 :syntax-alist ((?@ . "w")) 393 :syntax-alist ((?@ . "w"))
@@ -366,9 +400,10 @@ Customizing your password will store it in your ~/.emacs file."
366 :sqli-program sql-mysql-program 400 :sqli-program sql-mysql-program
367 :sqli-options sql-mysql-options 401 :sqli-options sql-mysql-options
368 :sqli-login sql-mysql-login-params 402 :sqli-login sql-mysql-login-params
369 :sqli-connect-func sql-connect-mysql 403 :sqli-comint-func sql-comint-mysql
370 :prompt-regexp "^mysql> " 404 :prompt-regexp "^mysql> "
371 :prompt-length 6 405 :prompt-length 6
406 :prompt-cont-regexp "^ -> "
372 :input-filter sql-remove-tabs-filter) 407 :input-filter sql-remove-tabs-filter)
373 408
374 (oracle 409 (oracle
@@ -377,9 +412,10 @@ Customizing your password will store it in your ~/.emacs file."
377 :sqli-program sql-oracle-program 412 :sqli-program sql-oracle-program
378 :sqli-options sql-oracle-options 413 :sqli-options sql-oracle-options
379 :sqli-login sql-oracle-login-params 414 :sqli-login sql-oracle-login-params
380 :sqli-connect-func sql-connect-oracle 415 :sqli-comint-func sql-comint-oracle
381 :prompt-regexp "^SQL> " 416 :prompt-regexp "^SQL> "
382 :prompt-length 5 417 :prompt-length 5
418 :prompt-cont-regexp "^\\s-*\\d+> "
383 :syntax-alist ((?$ . "w") (?# . "w")) 419 :syntax-alist ((?$ . "w") (?# . "w"))
384 :terminator ("\\(^/\\|;\\)" . "/") 420 :terminator ("\\(^/\\|;\\)" . "/")
385 :input-filter sql-placeholders-filter) 421 :input-filter sql-placeholders-filter)
@@ -391,9 +427,10 @@ Customizing your password will store it in your ~/.emacs file."
391 :sqli-program sql-postgres-program 427 :sqli-program sql-postgres-program
392 :sqli-options sql-postgres-options 428 :sqli-options sql-postgres-options
393 :sqli-login sql-postgres-login-params 429 :sqli-login sql-postgres-login-params
394 :sqli-connect-func sql-connect-postgres 430 :sqli-comint-func sql-comint-postgres
395 :prompt-regexp "^.*[#>] *" 431 :prompt-regexp "^.*=[#>] "
396 :prompt-length 5 432 :prompt-length 5
433 :prompt-cont-regexp "^.*-[#>] "
397 :input-filter sql-remove-tabs-filter 434 :input-filter sql-remove-tabs-filter
398 :terminator ("\\(^[\\]g\\|;\\)" . ";")) 435 :terminator ("\\(^[\\]g\\|;\\)" . ";"))
399 436
@@ -403,7 +440,7 @@ Customizing your password will store it in your ~/.emacs file."
403 :sqli-program sql-solid-program 440 :sqli-program sql-solid-program
404 :sqli-options sql-solid-options 441 :sqli-options sql-solid-options
405 :sqli-login sql-solid-login-params 442 :sqli-login sql-solid-login-params
406 :sqli-connect-func sql-connect-solid 443 :sqli-comint-func sql-comint-solid
407 :prompt-regexp "^" 444 :prompt-regexp "^"
408 :prompt-length 0) 445 :prompt-length 0)
409 446
@@ -414,9 +451,11 @@ Customizing your password will store it in your ~/.emacs file."
414 :sqli-program sql-sqlite-program 451 :sqli-program sql-sqlite-program
415 :sqli-options sql-sqlite-options 452 :sqli-options sql-sqlite-options
416 :sqli-login sql-sqlite-login-params 453 :sqli-login sql-sqlite-login-params
417 :sqli-connect-func sql-connect-sqlite 454 :sqli-comint-func sql-comint-sqlite
418 :prompt-regexp "^sqlite> " 455 :prompt-regexp "^sqlite> "
419 :prompt-length 8) 456 :prompt-length 8
457 :prompt-cont-regexp "^ ...> "
458 :terminator ";")
420 459
421 (sybase 460 (sybase
422 :name "Sybase" 461 :name "Sybase"
@@ -424,7 +463,7 @@ Customizing your password will store it in your ~/.emacs file."
424 :sqli-program sql-sybase-program 463 :sqli-program sql-sybase-program
425 :sqli-options sql-sybase-options 464 :sqli-options sql-sybase-options
426 :sqli-login sql-sybase-login-params 465 :sqli-login sql-sybase-login-params
427 :sqli-connect-func sql-connect-sybase 466 :sqli-comint-func sql-comint-sybase
428 :prompt-regexp "^SQL> " 467 :prompt-regexp "^SQL> "
429 :prompt-length 5 468 :prompt-length 5
430 :syntax-alist ((?@ . "w")) 469 :syntax-alist ((?@ . "w"))
@@ -463,7 +502,7 @@ may be any one of the following:
463 database and server) needed to connect to 502 database and server) needed to connect to
464 the database. 503 the database.
465 504
466 :sqli-connect-func name of a function which accepts no 505 :sqli-comint-func name of a function which accepts no
467 parameters that will use the values of 506 parameters that will use the values of
468 `sql-user', `sql-password', 507 `sql-user', `sql-password',
469 `sql-database' and `sql-server' to open a 508 `sql-database' and `sql-server' to open a
@@ -477,6 +516,10 @@ may be any one of the following:
477 516
478 :prompt-length length of the prompt on the line. 517 :prompt-length length of the prompt on the line.
479 518
519 :prompt-cont-regexp regular expression string that matches
520 the continuation prompt issued by the
521 product interpreter.
522
480 :input-filter function which can filter strings sent to 523 :input-filter function which can filter strings sent to
481 the command interpreter. It is also used 524 the command interpreter. It is also used
482 by the `sql-send-string', 525 by the `sql-send-string',
@@ -484,7 +527,8 @@ may be any one of the following:
484 and `sql-send-buffer' functions. The 527 and `sql-send-buffer' functions. The
485 function is passed the string sent to the 528 function is passed the string sent to the
486 command interpreter and must return the 529 command interpreter and must return the
487 filtered string. 530 filtered string. May also be a list of
531 such functions.
488 532
489 :terminator the terminator to be sent after a 533 :terminator the terminator to be sent after a
490 `sql-send-string', `sql-send-region', 534 `sql-send-string', `sql-send-region',
@@ -508,6 +552,55 @@ settings.")
508 '(:font-lock :sqli-program :sqli-options :sqli-login)) 552 '(:font-lock :sqli-program :sqli-options :sqli-login))
509 553
510;;;###autoload 554;;;###autoload
555(defcustom sql-connection-alist nil
556 "An alist of connection parameters for interacting with a SQL
557 product.
558
559Each element of the alist is as follows:
560
561 \(CONNECTION \(SQL-VARIABLE VALUE) ...)
562
563Where CONNECTION is a symbol identifying the connection, SQL-VARIABLE
564is the symbol name of a SQL mode variable, and VALUE is the value to
565be assigned to the variable.
566
567The most common SQL-VARIABLE settings associated with a connection
568are:
569
570 `sql-product'
571 `sql-user'
572 `sql-password'
573 `sql-port'
574 `sql-server'
575 `sql-database'
576
577If a SQL-VARIABLE is part of the connection, it will not be
578prompted for during login."
579
580 :type `(alist :key-type (string :tag "Connection")
581 :value-type
582 (set
583 (group (const :tag "Product" sql-product)
584 (choice
585 ,@(mapcar (lambda (prod-info)
586 `(const :tag
587 ,(or (plist-get (cdr prod-info) :name)
588 (capitalize (symbol-name (car prod-info))))
589 (quote ,(car prod-info))))
590 sql-product-alist)))
591 (group (const :tag "Username" sql-user) string)
592 (group (const :tag "Password" sql-password) string)
593 (group (const :tag "Server" sql-server) string)
594 (group (const :tag "Database" sql-database) string)
595 (group (const :tag "Port" sql-port) integer)
596 (repeat :inline t
597 (list :tab "Other"
598 (symbol :tag " Variable Symbol")
599 (sexp :tag "Value Expression")))))
600 :version "24.1"
601 :group 'SQL)
602
603;;;###autoload
511(defcustom sql-product 'ansi 604(defcustom sql-product 'ansi
512 "Select the SQL database product used so that buffers can be 605 "Select the SQL database product used so that buffers can be
513highlighted properly when you open them." 606highlighted properly when you open them."
@@ -518,11 +611,8 @@ highlighted properly when you open them."
518 (capitalize (symbol-name (car prod-info)))) 611 (capitalize (symbol-name (car prod-info))))
519 ,(car prod-info))) 612 ,(car prod-info)))
520 sql-product-alist)) 613 sql-product-alist))
521 :group 'SQL) 614 :group 'SQL
522(put 'sql-product 'safe-local-variable 'symbolp) 615 :safe 'symbolp)
523
524(defvar sql-interactive-product nil
525 "Product under `sql-interactive-mode'.")
526 616
527;; misc customization of sql.el behaviour 617;; misc customization of sql.el behaviour
528 618
@@ -677,11 +767,7 @@ You will find the file in your Orant\\bin directory."
677 767
678(defcustom sql-oracle-login-params '(user password database) 768(defcustom sql-oracle-login-params '(user password database)
679 "List of login parameters needed to connect to Oracle." 769 "List of login parameters needed to connect to Oracle."
680 :type '(repeat (choice 770 :type 'sql-login-params
681 (const user)
682 (const password)
683 (const server)
684 (const database)))
685 :version "24.1" 771 :version "24.1"
686 :group 'SQL) 772 :group 'SQL)
687 773
@@ -702,7 +788,7 @@ to be safe:
702 788
703;; Customization for SQLite 789;; Customization for SQLite
704 790
705(defcustom sql-sqlite-program "sqlite" 791(defcustom sql-sqlite-program "sqlite3"
706 "Command to start SQLite. 792 "Command to start SQLite.
707 793
708Starts `sql-interactive-mode' after doing some setup." 794Starts `sql-interactive-mode' after doing some setup."
@@ -715,13 +801,9 @@ Starts `sql-interactive-mode' after doing some setup."
715 :version "20.8" 801 :version "20.8"
716 :group 'SQL) 802 :group 'SQL)
717 803
718(defcustom sql-sqlite-login-params '(database) 804(defcustom sql-sqlite-login-params '((database :file ".*\\.db"))
719 "List of login parameters needed to connect to SQLite." 805 "List of login parameters needed to connect to SQLite."
720 :type '(repeat (choice 806 :type 'sql-login-params
721 (const user)
722 (const password)
723 (const server)
724 (const database)))
725 :version "24.1" 807 :version "24.1"
726 :group 'SQL) 808 :group 'SQL)
727 809
@@ -744,12 +826,7 @@ on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
744 826
745(defcustom sql-mysql-login-params '(user password database server) 827(defcustom sql-mysql-login-params '(user password database server)
746 "List of login parameters needed to connect to MySql." 828 "List of login parameters needed to connect to MySql."
747 :type '(repeat (choice 829 :type 'sql-login-params
748 (const user)
749 (const password)
750 (const server)
751 (const database)
752 (const port)))
753 :version "24.1" 830 :version "24.1"
754 :group 'SQL) 831 :group 'SQL)
755 832
@@ -764,11 +841,7 @@ Starts `sql-interactive-mode' after doing some setup."
764 841
765(defcustom sql-solid-login-params '(user password server) 842(defcustom sql-solid-login-params '(user password server)
766 "List of login parameters needed to connect to Solid." 843 "List of login parameters needed to connect to Solid."
767 :type '(repeat (choice 844 :type 'sql-login-params
768 (const user)
769 (const password)
770 (const server)
771 (const database)))
772 :version "24.1" 845 :version "24.1"
773 :group 'SQL) 846 :group 'SQL)
774 847
@@ -790,11 +863,7 @@ Some versions of isql might require the -n option in order to work."
790 863
791(defcustom sql-sybase-login-params '(server user password database) 864(defcustom sql-sybase-login-params '(server user password database)
792 "List of login parameters needed to connect to Sybase." 865 "List of login parameters needed to connect to Sybase."
793 :type '(repeat (choice 866 :type 'sql-login-params
794 (const user)
795 (const password)
796 (const server)
797 (const database)))
798 :version "24.1" 867 :version "24.1"
799 :group 'SQL) 868 :group 'SQL)
800 869
@@ -809,11 +878,7 @@ Starts `sql-interactive-mode' after doing some setup."
809 878
810(defcustom sql-informix-login-params '(database) 879(defcustom sql-informix-login-params '(database)
811 "List of login parameters needed to connect to Informix." 880 "List of login parameters needed to connect to Informix."
812 :type '(repeat (choice 881 :type 'sql-login-params
813 (const user)
814 (const password)
815 (const server)
816 (const database)))
817 :version "24.1" 882 :version "24.1"
818 :group 'SQL) 883 :group 'SQL)
819 884
@@ -828,11 +893,7 @@ Starts `sql-interactive-mode' after doing some setup."
828 893
829(defcustom sql-ingres-login-params '(database) 894(defcustom sql-ingres-login-params '(database)
830 "List of login parameters needed to connect to Ingres." 895 "List of login parameters needed to connect to Ingres."
831 :type '(repeat (choice 896 :type 'sql-login-params
832 (const user)
833 (const password)
834 (const server)
835 (const database)))
836 :version "24.1" 897 :version "24.1"
837 :group 'SQL) 898 :group 'SQL)
838 899
@@ -854,11 +915,7 @@ Starts `sql-interactive-mode' after doing some setup."
854 915
855(defcustom sql-ms-login-params '(user password server database) 916(defcustom sql-ms-login-params '(user password server database)
856 "List of login parameters needed to connect to Microsoft." 917 "List of login parameters needed to connect to Microsoft."
857 :type '(repeat (choice 918 :type 'sql-login-params
858 (const user)
859 (const password)
860 (const server)
861 (const database)))
862 :version "24.1" 919 :version "24.1"
863 :group 'SQL) 920 :group 'SQL)
864 921
@@ -885,11 +942,7 @@ add your name with a \"-U\" prefix (such as \"-Umark\") to the list."
885 942
886(defcustom sql-postgres-login-params '(user database server) 943(defcustom sql-postgres-login-params '(user database server)
887 "List of login parameters needed to connect to Postgres." 944 "List of login parameters needed to connect to Postgres."
888 :type '(repeat (choice 945 :type 'sql-login-params
889 (const user)
890 (const password)
891 (const server)
892 (const database)))
893 :version "24.1" 946 :version "24.1"
894 :group 'SQL) 947 :group 'SQL)
895 948
@@ -910,11 +963,7 @@ Starts `sql-interactive-mode' after doing some setup."
910 963
911(defcustom sql-interbase-login-params '(user password database) 964(defcustom sql-interbase-login-params '(user password database)
912 "List of login parameters needed to connect to Interbase." 965 "List of login parameters needed to connect to Interbase."
913 :type '(repeat (choice 966 :type 'sql-login-params
914 (const user)
915 (const password)
916 (const server)
917 (const database)))
918 :version "24.1" 967 :version "24.1"
919 :group 'SQL) 968 :group 'SQL)
920 969
@@ -935,11 +984,7 @@ Starts `sql-interactive-mode' after doing some setup."
935 984
936(defcustom sql-db2-login-params nil 985(defcustom sql-db2-login-params nil
937 "List of login parameters needed to connect to DB2." 986 "List of login parameters needed to connect to DB2."
938 :type '(repeat (choice 987 :type 'sql-login-params
939 (const user)
940 (const password)
941 (const server)
942 (const database)))
943 :version "24.1" 988 :version "24.1"
944 :group 'SQL) 989 :group 'SQL)
945 990
@@ -960,11 +1005,7 @@ Starts `sql-interactive-mode' after doing some setup."
960 1005
961(defcustom sql-linter-login-params '(user password database server) 1006(defcustom sql-linter-login-params '(user password database server)
962 "Login parameters to needed to connect to Linter." 1007 "Login parameters to needed to connect to Linter."
963 :type '(repeat (choice 1008 :type 'sql-login-params
964 (const user)
965 (const password)
966 (const server)
967 (const database)))
968 :version "24.1" 1009 :version "24.1"
969 :group 'SQL) 1010 :group 'SQL)
970 1011
@@ -1005,6 +1046,9 @@ You can change `sql-prompt-regexp' on `sql-interactive-mode-hook'.")
1005 1046
1006You can change `sql-prompt-length' on `sql-interactive-mode-hook'.") 1047You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
1007 1048
1049(defvar sql-prompt-cont-regexp nil
1050 "Prompt pattern of statement continuation prompts.")
1051
1008(defvar sql-alternate-buffer-name nil 1052(defvar sql-alternate-buffer-name nil
1009 "Buffer-local string used to possibly rename the SQLi buffer. 1053 "Buffer-local string used to possibly rename the SQLi buffer.
1010 1054
@@ -1056,8 +1100,17 @@ Based on `comint-mode-map'.")
1056 (get-buffer-process sql-buffer))] 1100 (get-buffer-process sql-buffer))]
1057 ["Send String" sql-send-string (and (buffer-live-p sql-buffer) 1101 ["Send String" sql-send-string (and (buffer-live-p sql-buffer)
1058 (get-buffer-process sql-buffer))] 1102 (get-buffer-process sql-buffer))]
1059 ["--" nil nil] 1103 "--"
1060 ["Start SQLi session" sql-product-interactive (sql-get-product-feature sql-product :sqli-connect-func)] 1104 ["Start SQLi session" sql-product-interactive
1105 :visible (not sql-connection-alist)
1106 :enable (sql-get-product-feature sql-product :sqli-comint-func)]
1107 ("Start..."
1108 :visible sql-connection-alist
1109 :filter sql-connection-menu-filter
1110 "--"
1111 ["New SQLi Session" sql-product-interactive (sql-get-product-feature sql-product :sqli-comint-func)])
1112 ["--"
1113 :visible sql-connection-alist]
1061 ["Show SQLi buffer" sql-show-sqli-buffer t] 1114 ["Show SQLi buffer" sql-show-sqli-buffer t]
1062 ["Set SQLi buffer" sql-set-sqli-buffer t] 1115 ["Set SQLi buffer" sql-set-sqli-buffer t]
1063 ["Pop to SQLi buffer after send" 1116 ["Pop to SQLi buffer after send"
@@ -1085,7 +1138,8 @@ Based on `comint-mode-map'.")
1085 sql-interactive-mode-menu sql-interactive-mode-map 1138 sql-interactive-mode-menu sql-interactive-mode-map
1086 "Menu for `sql-interactive-mode'." 1139 "Menu for `sql-interactive-mode'."
1087 '("SQL" 1140 '("SQL"
1088 ["Rename Buffer" sql-rename-buffer t])) 1141 ["Rename Buffer" sql-rename-buffer t]
1142 ["Save Connection" sql-save-connection (not sql-connection)]))
1089 1143
1090;; Abbreviations -- if you want more of them, define them in your 1144;; Abbreviations -- if you want more of them, define them in your
1091;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. 1145;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
@@ -1922,7 +1976,51 @@ regular expressions are created during compilation by calling the
1922function `regexp-opt'. Therefore, take a look at the source before 1976function `regexp-opt'. Therefore, take a look at the source before
1923you define your own `sql-mode-mysql-font-lock-keywords'.") 1977you define your own `sql-mode-mysql-font-lock-keywords'.")
1924 1978
1925(defvar sql-mode-sqlite-font-lock-keywords nil 1979(defvar sql-mode-sqlite-font-lock-keywords
1980 (eval-when-compile
1981 (list
1982 ;; SQLite Keyword
1983 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1984"abort" "action" "add" "after" "all" "alter" "analyze" "and" "as"
1985"asc" "attach" "autoincrement" "before" "begin" "between" "by"
1986"cascade" "case" "cast" "check" "collate" "column" "commit" "conflict"
1987"constraint" "create" "cross" "database" "default" "deferrable"
1988"deferred" "delete" "desc" "detach" "distinct" "drop" "each" "else"
1989"end" "escape" "except" "exclusive" "exists" "explain" "fail" "for"
1990"foreign" "from" "full" "glob" "group" "having" "if" "ignore"
1991"immediate" "in" "index" "indexed" "initially" "inner" "insert"
1992"instead" "intersect" "into" "is" "isnull" "join" "key" "left" "like"
1993"limit" "match" "natural" "no" "not" "notnull" "null" "of" "offset"
1994"on" "or" "order" "outer" "plan" "pragma" "primary" "query" "raise"
1995"references" "regexp" "reindex" "release" "rename" "replace"
1996"restrict" "right" "rollback" "row" "savepoint" "select" "set" "table"
1997"temp" "temporary" "then" "to" "transaction" "trigger" "union"
1998"unique" "update" "using" "vacuum" "values" "view" "virtual" "when"
1999"where"
2000)
2001 ;; SQLite Data types
2002 (sql-font-lock-keywords-builder 'font-lock-type-face nil
2003"int" "integer" "tinyint" "smallint" "mediumint" "bigint" "unsigned"
2004"big" "int2" "int8" "character" "varchar" "varying" "nchar" "native"
2005"nvarchar" "text" "clob" "blob" "real" "double" "precision" "float"
2006"numeric" "number" "decimal" "boolean" "date" "datetime"
2007)
2008 ;; SQLite Functions
2009 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
2010;; Core functions
2011"abs" "changes" "coalesce" "glob" "ifnull" "hex" "last_insert_rowid"
2012"length" "like" "load_extension" "lower" "ltrim" "max" "min" "nullif"
2013"quote" "random" "randomblob" "replace" "round" "rtrim" "soundex"
2014"sqlite_compileoption_get" "sqlite_compileoption_used"
2015"sqlite_source_id" "sqlite_version" "substr" "total_changes" "trim"
2016"typeof" "upper" "zeroblob"
2017;; Date/time functions
2018"time" "julianday" "strftime"
2019"current_date" "current_time" "current_timestamp"
2020;; Aggregate functions
2021"avg" "count" "group_concat" "max" "min" "sum" "total"
2022)))
2023
1926 "SQLite SQL keywords used by font-lock. 2024 "SQLite SQL keywords used by font-lock.
1927 2025
1928This variable is used by `sql-mode' and `sql-interactive-mode'. The 2026This variable is used by `sql-mode' and `sql-interactive-mode'. The
@@ -1969,7 +2067,7 @@ configuration."
1969 ;; Each product is represented by a radio 2067 ;; Each product is represented by a radio
1970 ;; button with it's display name. 2068 ;; button with it's display name.
1971 `[,display 2069 `[,display
1972 (lambda () (interactive) (sql-set-product ',product)) 2070 (sql-set-product ',product)
1973 :style radio 2071 :style radio
1974 :selected (eq sql-product ',product)] 2072 :selected (eq sql-product ',product)]
1975 ;; Maintain the product list in 2073 ;; Maintain the product list in
@@ -2016,13 +2114,17 @@ argument must be a plist keyword accepted by
2016 (setcdr p (plist-put (cdr p) feature newvalue))) 2114 (setcdr p (plist-put (cdr p) feature newvalue)))
2017 (message "`%s' is not a known product; use `sql-add-product' to add it first." product)))) 2115 (message "`%s' is not a known product; use `sql-add-product' to add it first." product))))
2018 2116
2019(defun sql-get-product-feature (product feature &optional fallback) 2117(defun sql-get-product-feature (product feature &optional fallback not-indirect)
2020 "Lookup FEATURE associated with a SQL PRODUCT. 2118 "Lookup FEATURE associated with a SQL PRODUCT.
2021 2119
2022If the FEATURE is nil for PRODUCT, and FALLBACK is specified, 2120If the FEATURE is nil for PRODUCT, and FALLBACK is specified,
2023then the FEATURE associated with the FALLBACK product is 2121then the FEATURE associated with the FALLBACK product is
2024returned. 2122returned.
2025 2123
2124If the FEATURE is in the list `sql-indirect-features', and the
2125NOT-INDIRECT parameter is not set, then the value of the symbol
2126stored in the connect alist is returned.
2127
2026See `sql-product-alist' for a list of products and supported features." 2128See `sql-product-alist' for a list of products and supported features."
2027 (let* ((p (assoc product sql-product-alist)) 2129 (let* ((p (assoc product sql-product-alist))
2028 (v (plist-get (cdr p) feature))) 2130 (v (plist-get (cdr p) feature)))
@@ -2036,10 +2138,12 @@ See `sql-product-alist' for a list of products and supported features."
2036 2138
2037 (if (and 2139 (if (and
2038 (member feature sql-indirect-features) 2140 (member feature sql-indirect-features)
2141 (not not-indirect)
2039 (symbolp v)) 2142 (symbolp v))
2040 (symbol-value v) 2143 (symbol-value v)
2041 v)) 2144 v))
2042 (message "`%s' is not a known product; use `sql-add-product' to add it first." product)))) 2145 (message "`%s' is not a known product; use `sql-add-product' to add it first." product)
2146 nil)))
2043 2147
2044(defun sql-product-font-lock (keywords-only imenu) 2148(defun sql-product-font-lock (keywords-only imenu)
2045 "Configure font-lock and imenu with product-specific settings. 2149 "Configure font-lock and imenu with product-specific settings.
@@ -2126,6 +2230,19 @@ adds a fontification pattern to fontify identifiers ending in
2126 (append old-val keywords) 2230 (append old-val keywords)
2127 (append keywords old-val)))))) 2231 (append keywords old-val))))))
2128 2232
2233(defun sql-for-each-login (login-params body)
2234 "Iterates through login parameters and returns a list of results."
2235
2236 (delq nil
2237 (mapcar
2238 (lambda (param)
2239 (let ((token (or (and (listp param) (car param)) param))
2240 (type (or (and (listp param) (nth 1 param)) nil))
2241 (arg (or (and (listp param) (nth 2 param)) nil)))
2242
2243 (funcall body token type arg)))
2244 login-params)))
2245
2129 2246
2130 2247
2131;;; Functions to switch highlighting 2248;;; Functions to switch highlighting
@@ -2287,6 +2404,38 @@ appended to the SQLi buffer without disturbing your SQL buffer."
2287 "Read a password using PROMPT. Optional DEFAULT is password to start with." 2404 "Read a password using PROMPT. Optional DEFAULT is password to start with."
2288 (read-passwd prompt nil default)) 2405 (read-passwd prompt nil default))
2289 2406
2407(defun sql-get-login-ext (prompt last-value history-var type arg)
2408 "Prompt user with extended login parameters.
2409
2410If TYPE is nil, then the user is simply prompted for a string
2411value.
2412
2413If TYPE is `:file', then the user is prompted for a file
2414name that must match the regexp pattern specified in the ARG
2415argument.
2416
2417If TYPE is `:completion', then the user is prompted for a string
2418specified by ARG. (ARG is used as the PREDICATE argument to
2419`completing-read'.)"
2420 (cond
2421 ((eq type nil)
2422 (read-from-minibuffer prompt last-value nil nil history-var))
2423
2424 ((eq type :file)
2425 (let ((use-dialog-box nil))
2426 (expand-file-name
2427 (read-file-name prompt
2428 (file-name-directory last-value) nil t
2429 (file-name-nondirectory last-value)
2430 (if arg
2431 `(lambda (f)
2432 (string-match (concat "\\<" ,arg "\\>")
2433 (file-name-nondirectory f)))
2434 nil)))))
2435
2436 ((eq type :completion)
2437 (completing-read prompt arg nil t last-value history-var))))
2438
2290(defun sql-get-login (&rest what) 2439(defun sql-get-login (&rest what)
2291 "Get username, password and database from the user. 2440 "Get username, password and database from the user.
2292 2441
@@ -2304,32 +2453,48 @@ symbol `password', for the server if it contains the symbol
2304`database'. The members of WHAT are processed in the order in 2453`database'. The members of WHAT are processed in the order in
2305which they are provided. 2454which they are provided.
2306 2455
2456The tokens for `database' and `server' may also be lists to
2457control or limit the values that can be supplied. These can be
2458of the form:
2459
2460 \(database :file \".+\\\\.EXT\")
2461 \(database :completion FUNCTION)
2462
2463The `server' token supports the same forms.
2464
2307In order to ask the user for username, password and database, call the 2465In order to ask the user for username, password and database, call the
2308function like this: (sql-get-login 'user 'password 'database)." 2466function like this: (sql-get-login 'user 'password 'database)."
2309 (interactive) 2467 (interactive)
2310 (while what 2468 (mapcar
2311 (cond 2469 (lambda (w)
2312 ((eq (car what) 'user) ; user 2470 (let ((token (or (and (listp w) (car w)) w))
2313 (setq sql-user 2471 (type (or (and (listp w) (nth 1 w)) nil))
2314 (read-from-minibuffer "User: " sql-user nil nil 2472 (arg (or (and (listp w) (nth 2 w)) nil)))
2315 'sql-user-history))) 2473
2316 ((eq (car what) 'password) ; password 2474 (cond
2317 (setq sql-password 2475 ((eq token 'user) ; user
2318 (sql-read-passwd "Password: " sql-password))) 2476 (setq sql-user
2319 2477 (read-from-minibuffer "User: " sql-user nil nil
2320 ((eq (car what) 'server) ; server 2478 'sql-user-history)))
2321 (setq sql-server 2479
2322 (read-from-minibuffer "Server: " sql-server nil nil 2480 ((eq token 'password) ; password
2323 'sql-server-history))) 2481 (setq sql-password
2324 ((eq (car what) 'port) ; port 2482 (sql-read-passwd "Password: " sql-password)))
2325 (setq sql-port 2483
2326 (read-from-minibuffer "Port: " sql-port nil nil 2484 ((eq token 'server) ; server
2327 'sql-port-history))) 2485 (setq sql-server
2328 ((eq (car what) 'database) ; database 2486 (sql-get-login-ext "Server: " sql-server
2329 (setq sql-database 2487 'sql-server-history type arg)))
2330 (read-from-minibuffer "Database: " sql-database nil nil 2488
2331 'sql-database-history)))) 2489 ((eq token 'database) ; database
2332 (setq what (cdr what)))) 2490 (setq sql-database
2491 (sql-get-login-ext "Database: " sql-database
2492 'sql-database-history type arg)))
2493
2494 ((eq token 'port) ; port
2495 (setq sql-port
2496 (read-number "Port: " sql-port))))))
2497 what))
2333 2498
2334(defun sql-find-sqli-buffer () 2499(defun sql-find-sqli-buffer ()
2335 "Returns the current default SQLi buffer or nil. 2500 "Returns the current default SQLi buffer or nil.
@@ -2419,17 +2584,70 @@ variable `sql-buffer'. See `sql-help' on how to create such a buffer."
2419 "Return a string that can be used to rename a SQLi buffer. 2584 "Return a string that can be used to rename a SQLi buffer.
2420 2585
2421This is used to set `sql-alternate-buffer-name' within 2586This is used to set `sql-alternate-buffer-name' within
2422`sql-interactive-mode'." 2587`sql-interactive-mode'.
2423 (concat (if (string= "" sql-user) 2588
2424 (if (string= "" (user-login-name)) 2589If the session was started with `sql-connect' then the alternate
2425 () 2590name would be the name of the connection.
2426 (concat (user-login-name) "/")) 2591
2427 (concat sql-user "/")) 2592Otherwise, it uses the parameters identified by the :sqlilogin
2428 (if (string= "" sql-database) 2593parameter.
2429 (if (string= "" sql-server) 2594
2430 (system-name) 2595If all else fails, the alternate name would be the user and
2431 sql-server) 2596server/database name."
2432 sql-database))) 2597
2598 (let ((name ""))
2599
2600 ;; Build a name using the :sqli-login setting
2601 (setq name
2602 (apply 'concat
2603 (cdr
2604 (apply 'append nil
2605 (sql-for-each-login
2606 (sql-get-product-feature sql-product :sqli-login)
2607 (lambda (token type arg)
2608 (cond
2609 ((eq token 'user)
2610 (unless (string= "" sql-user)
2611 (list "/" sql-user)))
2612 ((eq token 'port)
2613 (unless (= 0 sql-port)
2614 (list ":" sql-port)))
2615 ((eq token 'server)
2616 (unless (string= "" sql-server)
2617 (list "."
2618 (if (eq type :file)
2619 (file-name-nondirectory sql-server)
2620 sql-server))))
2621 ((eq token 'database)
2622 (when (string= "" sql-database)
2623 (list "@"
2624 (if (eq type :file)
2625 (file-name-nondirectory sql-database)
2626 sql-database))))
2627
2628 ((eq token 'password) nil)
2629 (t nil))))))))
2630
2631 ;; If there's a connection, use it and the name thus far
2632 (if sql-connection
2633 (format "<%s>%s" sql-connection (or name ""))
2634
2635 ;; If there is no name, try to create something meaningful
2636 (if (string= "" (or name ""))
2637 (concat
2638 (if (string= "" sql-user)
2639 (if (string= "" (user-login-name))
2640 ()
2641 (concat (user-login-name) "/"))
2642 (concat sql-user "/"))
2643 (if (string= "" sql-database)
2644 (if (string= "" sql-server)
2645 (system-name)
2646 sql-server)
2647 sql-database))
2648
2649 ;; Use the name we've got
2650 name))))
2433 2651
2434(defun sql-rename-buffer () 2652(defun sql-rename-buffer ()
2435 "Rename a SQLi buffer." 2653 "Rename a SQLi buffer."
@@ -2507,14 +2725,73 @@ Every newline in STRING will be preceded with a space and a backslash."
2507 2725
2508;;; Input sender for SQLi buffers 2726;;; Input sender for SQLi buffers
2509 2727
2728(defvar sql-output-newline-count 0
2729 "Number of newlines in the input string.
2730
2731Allows the suppression of continuation prompts.")
2732
2733(defvar sql-output-by-send nil
2734 "Non-nil if the command in the input was generated by `sql-send-string'.")
2735
2510(defun sql-input-sender (proc string) 2736(defun sql-input-sender (proc string)
2511 "Send STRING to PROC after applying filters." 2737 "Send STRING to PROC after applying filters."
2512 2738
2513 (let* ((product (with-current-buffer (process-buffer proc) sql-product)) 2739 (let* ((product (with-current-buffer (process-buffer proc) sql-product))
2514 (filter (sql-get-product-feature product :input-filter))) 2740 (filter (sql-get-product-feature product :input-filter)))
2515 2741
2742 ;; Apply filter(s)
2743 (cond
2744 ((not filter)
2745 nil)
2746 ((functionp filter)
2747 (setq string (funcall filter string)))
2748 ((listp filter)
2749 (mapc (lambda (f) (setq string (funcall f string))) filter))
2750 (t nil))
2751
2752 ;; Count how many newlines in the string
2753 (setq sql-output-newline-count 0)
2754 (mapc (lambda (ch)
2755 (when (eq ch ?\n)
2756 (setq sql-output-newline-count (1+ sql-output-newline-count))))
2757 string)
2758
2516 ;; Send the string 2759 ;; Send the string
2517 (comint-simple-send proc (if filter (funcall filter string) string)))) 2760 (comint-simple-send proc string)))
2761
2762;;; Strip out continuation prompts
2763
2764(defun sql-interactive-remove-continuation-prompt (oline)
2765 "Strip out continuation prompts out of the OLINE.
2766
2767Added to the `comint-preoutput-filter-functions' hook in a SQL
2768interactive buffer. If `sql-outut-newline-count' is greater than
2769zero, then an output line matching the continuation prompt is filtered
2770out. If the count is one, then the prompt is replaced with a newline
2771to force the output from the query to appear on a new line."
2772 (if (and sql-prompt-cont-regexp
2773 sql-output-newline-count
2774 (numberp sql-output-newline-count)
2775 (>= sql-output-newline-count 1))
2776 (progn
2777 (while (and oline
2778 sql-output-newline-count
2779 (> sql-output-newline-count 0)
2780 (string-match sql-prompt-cont-regexp oline))
2781
2782 (setq oline
2783 (replace-match (if (and
2784 (= 1 sql-output-newline-count)
2785 sql-output-by-send)
2786 "\n" "")
2787 nil nil oline)
2788 sql-output-newline-count
2789 (1- sql-output-newline-count)))
2790 (if (= sql-output-newline-count 0)
2791 (setq sql-output-newline-count nil))
2792 (setq sql-output-by-send nil))
2793 (setq sql-output-newline-count nil))
2794 oline)
2518 2795
2519;;; Sending the region to the SQLi buffer. 2796;;; Sending the region to the SQLi buffer.
2520 2797
@@ -2522,26 +2799,20 @@ Every newline in STRING will be preceded with a space and a backslash."
2522 "Send the string STR to the SQL process." 2799 "Send the string STR to the SQL process."
2523 (interactive "sSQL Text: ") 2800 (interactive "sSQL Text: ")
2524 2801
2525 (let (comint-input-sender-no-newline proc) 2802 (let ((comint-input-sender-no-newline nil)
2803 (s (replace-regexp-in-string "[[:space:]\n\r]+\\'" "" str)))
2526 (if (buffer-live-p sql-buffer) 2804 (if (buffer-live-p sql-buffer)
2527 (progn 2805 (progn
2528 ;; Ignore the hoping around... 2806 ;; Ignore the hoping around...
2529 (save-excursion 2807 (save-excursion
2530 ;; Get the process
2531 (setq proc (get-buffer-process sql-buffer))
2532
2533 ;; Set product context 2808 ;; Set product context
2534 (with-current-buffer sql-buffer 2809 (with-current-buffer sql-buffer
2535 ;; Send the string 2810 ;; Send the string (trim the trailing whitespace)
2536 (sql-input-sender proc str) 2811 (sql-input-sender (get-buffer-process sql-buffer) s)
2537
2538 ;; Send a newline if there wasn't one on the end of the string
2539 (unless (string-equal "\n" (substring str (1- (length str))))
2540 (comint-send-string proc "\n"))
2541 2812
2542 ;; Send a command terminator if we must 2813 ;; Send a command terminator if we must
2543 (if sql-send-terminator 2814 (if sql-send-terminator
2544 (sql-send-magic-terminator sql-buffer str sql-send-terminator)) 2815 (sql-send-magic-terminator sql-buffer s sql-send-terminator))
2545 2816
2546 (message "Sent string to buffer %s." (buffer-name sql-buffer)))) 2817 (message "Sent string to buffer %s." (buffer-name sql-buffer))))
2547 2818
@@ -2576,7 +2847,7 @@ Every newline in STRING will be preceded with a space and a backslash."
2576 2847
2577(defun sql-send-magic-terminator (buf str terminator) 2848(defun sql-send-magic-terminator (buf str terminator)
2578 "Send TERMINATOR to buffer BUF if its not present in STR." 2849 "Send TERMINATOR to buffer BUF if its not present in STR."
2579 (let (pat term) 2850 (let (comint-input-sender-no-newline pat term)
2580 ;; If flag is merely on(t), get product-specific terminator 2851 ;; If flag is merely on(t), get product-specific terminator
2581 (if (eq terminator t) 2852 (if (eq terminator t)
2582 (setq terminator (sql-get-product-feature sql-product :terminator))) 2853 (setq terminator (sql-get-product-feature sql-product :terminator)))
@@ -2597,8 +2868,13 @@ Every newline in STRING will be preceded with a space and a backslash."
2597 2868
2598 ;; Check to see if the pattern is present in the str already sent 2869 ;; Check to see if the pattern is present in the str already sent
2599 (unless (and pat term 2870 (unless (and pat term
2600 (string-match (concat pat "\n?\\'") str)) 2871 (string-match (concat pat "\\'") str))
2601 (comint-send-string buf (concat term "\n"))))) 2872 (comint-simple-send (get-buffer-process buf) term)
2873 (setq sql-output-newline-count
2874 (if sql-output-newline-count
2875 (1+ sql-output-newline-count)
2876 1)))
2877 (setq sql-output-by-send t)))
2602 2878
2603(defun sql-remove-tabs-filter (str) 2879(defun sql-remove-tabs-filter (str)
2604 "Replace tab characters with spaces." 2880 "Replace tab characters with spaces."
@@ -2788,6 +3064,8 @@ you entered, right above the output it created.
2788 (setq abbrev-all-caps 1) 3064 (setq abbrev-all-caps 1)
2789 ;; Exiting the process will call sql-stop. 3065 ;; Exiting the process will call sql-stop.
2790 (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop) 3066 (set-process-sentinel (get-buffer-process sql-buffer) 'sql-stop)
3067 ;; Save the connection name
3068 (make-local-variable 'sql-connection)
2791 ;; Create a usefull name for renaming this buffer later. 3069 ;; Create a usefull name for renaming this buffer later.
2792 (make-local-variable 'sql-alternate-buffer-name) 3070 (make-local-variable 'sql-alternate-buffer-name)
2793 (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name)) 3071 (setq sql-alternate-buffer-name (sql-make-alternate-buffer-name))
@@ -2796,13 +3074,22 @@ you entered, right above the output it created.
2796 (sql-get-product-feature sql-product :prompt-regexp)) 3074 (sql-get-product-feature sql-product :prompt-regexp))
2797 (set (make-local-variable 'sql-prompt-length) 3075 (set (make-local-variable 'sql-prompt-length)
2798 (sql-get-product-feature sql-product :prompt-length)) 3076 (sql-get-product-feature sql-product :prompt-length))
3077 (set (make-local-variable 'sql-prompt-cont-regexp)
3078 (sql-get-product-feature sql-product :prompt-cont-regexp))
3079 (make-local-variable 'sql-output-newline-count)
3080 (make-local-variable 'sql-output-by-send)
3081 (add-hook 'comint-preoutput-filter-functions
3082 'sql-interactive-remove-continuation-prompt nil t)
2799 (make-local-variable 'sql-input-ring-separator) 3083 (make-local-variable 'sql-input-ring-separator)
2800 (make-local-variable 'sql-input-ring-file-name) 3084 (make-local-variable 'sql-input-ring-file-name)
2801 (setq comint-process-echoes t)
2802 ;; Run the mode hook (along with comint's hooks). 3085 ;; Run the mode hook (along with comint's hooks).
2803 (run-mode-hooks 'sql-interactive-mode-hook) 3086 (run-mode-hooks 'sql-interactive-mode-hook)
2804 ;; Set comint based on user overrides. 3087 ;; Set comint based on user overrides.
2805 (setq comint-prompt-regexp sql-prompt-regexp) 3088 (setq comint-prompt-regexp
3089 (if sql-prompt-cont-regexp
3090 (concat "\\(" sql-prompt-regexp
3091 "\\|" sql-prompt-cont-regexp "\\)")
3092 sql-prompt-regexp))
2806 (setq left-margin sql-prompt-length) 3093 (setq left-margin sql-prompt-length)
2807 ;; Install input sender 3094 ;; Install input sender
2808 (set (make-local-variable 'comint-input-sender) 'sql-input-sender) 3095 (set (make-local-variable 'comint-input-sender) 'sql-input-sender)
@@ -2831,6 +3118,133 @@ Sentinels will always get the two parameters PROCESS and EVENT."
2831 3118
2832 3119
2833 3120
3121;;; Connection handling
3122
3123;;;###autoload
3124(defun sql-connect (connection)
3125 "Connect to an interactive session using CONNECTION settings.
3126
3127See `sql-connection-alist' to see how to define connections and
3128their settings.
3129
3130The user will not be prompted for any login parameters if a value
3131is specified in the connection settings."
3132
3133 ;; Prompt for the connection from those defined in the alist
3134 (interactive
3135 (if sql-connection-alist
3136 (list
3137 (let ((completion-ignore-case t))
3138 (completing-read "Connection: "
3139 (mapcar (lambda (c) (car c))
3140 sql-connection-alist)
3141 nil t nil nil '(()))))
3142 nil))
3143
3144 ;; Are there connections defined
3145 (if sql-connection-alist
3146 ;; Was one selected
3147 (when connection
3148 ;; Get connection settings
3149 (let ((connect-set (assoc connection sql-connection-alist)))
3150 ;; Settings are defined
3151 (if connect-set
3152 ;; Set the desired parameters
3153 (eval `(let*
3154 (,@(cdr connect-set)
3155 ;; :sqli-login params variable
3156 (param-var (sql-get-product-feature sql-product
3157 :sqli-login nil t))
3158 ;; :sqli-login params value
3159 (login-params (sql-get-product-feature sql-product
3160 :sqli-login))
3161 ;; which params are in the connection
3162 (set-params (mapcar
3163 (lambda (v)
3164 (cond
3165 ((eq (car v) 'sql-user) 'user)
3166 ((eq (car v) 'sql-password) 'password)
3167 ((eq (car v) 'sql-server) 'server)
3168 ((eq (car v) 'sql-database) 'database)
3169 ((eq (car v) 'sql-port) 'port)
3170 (t (car v))))
3171 (cdr connect-set)))
3172 ;; the remaining params (w/o the connection params)
3173 (rem-params (sql-for-each-login
3174 login-params
3175 (lambda (token type arg)
3176 (unless (member token set-params)
3177 (if (or type arg)
3178 (list token type arg)
3179 token)))))
3180 ;; Remember the connection
3181 (sql-connection connection))
3182
3183 ;; Set the remaining parameters and start the
3184 ;; interactive session
3185 (eval `(let ((,param-var ',rem-params))
3186 (sql-product-interactive sql-product)))))
3187 (message "SQL Connection <%s> does not exist" connection)
3188 nil)))
3189 (message "No SQL Connections defined")
3190 nil))
3191
3192(defun sql-save-connection (name)
3193 "Captures the connection information of the current SQLi session.
3194
3195The information is appended to `sql-connection-alist' and
3196optionally is saved to the user's init file."
3197
3198 (interactive "sNew connection name: ")
3199
3200 (if sql-connection
3201 (message "This session was started by a connection; it's already been saved.")
3202
3203 (let ((login (sql-get-product-feature sql-product :sqli-login))
3204 (alist sql-connection-alist)
3205 connect)
3206
3207 ;; Remove the existing connection if the user says so
3208 (when (and (assoc name alist)
3209 (yes-or-no-p (format "Replace connection definition <%s>? " name)))
3210 (setq alist (assq-delete-all name alist)))
3211
3212 ;; Add the new connection if it doesn't exist
3213 (if (assoc name alist)
3214 (message "Connection <%s> already exists" name)
3215 (setq connect
3216 (append (list name)
3217 (sql-for-each-login
3218 `(product ,@login)
3219 (lambda (token type arg)
3220 (cond
3221 ((eq token 'product) `(sql-product ',sql-product))
3222 ((eq token 'user) `(sql-user ,sql-user))
3223 ((eq token 'database) `(sql-database ,sql-database))
3224 ((eq token 'server) `(sql-server ,sql-server))
3225 ((eq token 'port) `(sql-port ,sql-port)))))))
3226
3227 (setq alist (append alist (list connect)))
3228
3229 ;; confirm whether we want to save the connections
3230 (if (yes-or-no-p "Save the connections for future sessions? ")
3231 (customize-save-variable 'sql-connection-alist alist)
3232 (customize-set-variable 'sql-connection-alist alist))))))
3233
3234(defun sql-connection-menu-filter (tail)
3235 "Generates menu entries for using each connection."
3236 (append
3237 (mapcar
3238 (lambda (conn)
3239 (vector
3240 (format "Connection <%s>" (car conn))
3241 (list 'sql-connect (car conn))
3242 t))
3243 sql-connection-alist)
3244 tail))
3245
3246
3247
2834;;; Entry functions for different SQL interpreters. 3248;;; Entry functions for different SQL interpreters.
2835 3249
2836;;;###autoload 3250;;;###autoload
@@ -2851,66 +3265,67 @@ If buffer exists and a process is running, just switch to buffer `*SQL*'.
2851 sql-product-alist) 3265 sql-product-alist)
2852 nil 'require-match 3266 nil 'require-match
2853 (or (and sql-product (symbol-name sql-product)) "ansi")))) 3267 (or (and sql-product (symbol-name sql-product)) "ansi"))))
2854 ((symbolp product) product) ; Product specified 3268 ((and product ; Product specified
3269 (symbolp product)) product)
2855 (t sql-product))) ; Default to sql-product 3270 (t sql-product))) ; Default to sql-product
2856 3271
2857 (when (sql-get-product-feature product :sqli-connect-func) 3272 (if product
2858 (if (and sql-buffer 3273 (when (sql-get-product-feature product :sqli-comint-func)
2859 (buffer-live-p sql-buffer) 3274 (if (and sql-buffer
2860 (comint-check-proc sql-buffer)) 3275 (buffer-live-p sql-buffer)
2861 (pop-to-buffer sql-buffer) 3276 (comint-check-proc sql-buffer))
2862 3277 (pop-to-buffer sql-buffer)
2863 ;; Is the current buffer in sql-mode and 3278
2864 ;; there is a buffer local setting of sql-buffer 3279 ;; Is the current buffer in sql-mode and
2865 (let* ((start-buffer 3280 ;; there is a buffer local setting of sql-buffer
2866 (and (derived-mode-p 'sql-mode) 3281 (let* ((start-buffer
2867 (current-buffer))) 3282 (and (derived-mode-p 'sql-mode)
2868 (start-sql-buffer 3283 (current-buffer)))
2869 (and start-buffer 3284 (start-sql-buffer
2870 (let (found) 3285 (and start-buffer
2871 (dolist (var (buffer-local-variables)) 3286 (let (found)
2872 (and (consp var) 3287 (dolist (var (buffer-local-variables))
2873 (eq (car var) 'sql-buffer) 3288 (and (consp var)
2874 (buffer-live-p (cdr var)) 3289 (eq (car var) 'sql-buffer)
2875 (get-buffer-process (cdr var)) 3290 (buffer-live-p (cdr var))
2876 (setq found (cdr var)))) 3291 (get-buffer-process (cdr var))
2877 found))) 3292 (setq found (cdr var))))
2878 new-sqli-buffer) 3293 found)))
2879 3294 new-sqli-buffer)
2880 ;; Get credentials. 3295
2881 (apply 'sql-get-login (sql-get-product-feature product :sqli-login)) 3296 ;; Get credentials.
2882 3297 (apply 'sql-get-login (sql-get-product-feature product :sqli-login))
2883 ;; Connect to database. 3298
2884 (message "Login...") 3299 ;; Connect to database.
2885 (funcall (sql-get-product-feature product :sqli-connect-func) 3300 (message "Login...")
2886 product 3301 (funcall (sql-get-product-feature product :sqli-comint-func)
2887 (sql-get-product-feature product :sqli-options)) 3302 product
2888 3303 (sql-get-product-feature product :sqli-options))
2889 ;; Set SQLi mode. 3304
2890 (setq sql-interactive-product product 3305 ;; Set SQLi mode.
2891 new-sqli-buffer (current-buffer) 3306 (setq sql-interactive-product product
2892 sql-buffer new-sqli-buffer) 3307 new-sqli-buffer (current-buffer)
2893 (sql-interactive-mode) 3308 sql-buffer new-sqli-buffer)
2894 3309 (sql-interactive-mode)
2895 ;; Set `sql-buffer' in the start buffer 3310
2896 (when (and start-buffer (not start-sql-buffer)) 3311 ;; Set `sql-buffer' in the start buffer
2897 (with-current-buffer start-buffer 3312 (when (and start-buffer (not start-sql-buffer))
2898 (setq sql-buffer new-sqli-buffer))) 3313 (with-current-buffer start-buffer
2899 3314 (setq sql-buffer new-sqli-buffer)))
2900 ;; All done. 3315
2901 (message "Login...done") 3316 ;; All done.
2902 (pop-to-buffer sql-buffer))))) 3317 (message "Login...done")
2903 3318 (pop-to-buffer sql-buffer))))
2904(defun sql-connect (product params) 3319 (message "No default SQL product defined. Set `sql-product'.")))
2905 "Set up a comint buffer to connect to the SQL processor. 3320
3321(defun sql-comint (product params)
3322 "Set up a comint buffer to run the SQL processor.
2906 3323
2907PRODUCT is the SQL product. PARAMS is a list of strings which are 3324PRODUCT is the SQL product. PARAMS is a list of strings which are
2908passed as command line arguments." 3325passed as command line arguments."
2909 (let ((program (sql-get-product-feature product :sqli-program))) 3326 (let ((program (sql-get-product-feature product :sqli-program)))
2910 (set-buffer 3327 (set-buffer
2911 (if params 3328 (apply 'make-comint "SQL" program nil params))))
2912 (apply 'make-comint "SQL" program nil params)
2913 (make-comint "SQL" program nil)))))
2914 3329
2915;;;###autoload 3330;;;###autoload
2916(defun sql-oracle () 3331(defun sql-oracle ()
@@ -2939,7 +3354,7 @@ The default comes from `process-coding-system-alist' and
2939 (interactive) 3354 (interactive)
2940 (sql-product-interactive 'oracle)) 3355 (sql-product-interactive 'oracle))
2941 3356
2942(defun sql-connect-oracle (product options) 3357(defun sql-comint-oracle (product options)
2943 "Create comint buffer and connect to Oracle." 3358 "Create comint buffer and connect to Oracle."
2944 ;; Produce user/password@database construct. Password without user 3359 ;; Produce user/password@database construct. Password without user
2945 ;; is meaningless; database without user/password is meaningless, 3360 ;; is meaningless; database without user/password is meaningless,
@@ -2955,7 +3370,7 @@ The default comes from `process-coding-system-alist' and
2955 (if parameter 3370 (if parameter
2956 (setq parameter (nconc (list parameter) options)) 3371 (setq parameter (nconc (list parameter) options))
2957 (setq parameter options)) 3372 (setq parameter options))
2958 (sql-connect product parameter))) 3373 (sql-comint product parameter)))
2959 3374
2960 3375
2961 3376
@@ -2986,7 +3401,7 @@ The default comes from `process-coding-system-alist' and
2986 (interactive) 3401 (interactive)
2987 (sql-product-interactive 'sybase)) 3402 (sql-product-interactive 'sybase))
2988 3403
2989(defun sql-connect-sybase (product options) 3404(defun sql-comint-sybase (product options)
2990 "Create comint buffer and connect to Sybase." 3405 "Create comint buffer and connect to Sybase."
2991 ;; Put all parameters to the program (if defined) in a list and call 3406 ;; Put all parameters to the program (if defined) in a list and call
2992 ;; make-comint. 3407 ;; make-comint.
@@ -2999,7 +3414,7 @@ The default comes from `process-coding-system-alist' and
2999 (setq params (append (list "-P" sql-password) params))) 3414 (setq params (append (list "-P" sql-password) params)))
3000 (if (not (string= "" sql-user)) 3415 (if (not (string= "" sql-user))
3001 (setq params (append (list "-U" sql-user) params))) 3416 (setq params (append (list "-U" sql-user) params)))
3002 (sql-connect product params))) 3417 (sql-comint product params)))
3003 3418
3004 3419
3005 3420
@@ -3028,7 +3443,7 @@ The default comes from `process-coding-system-alist' and
3028 (interactive) 3443 (interactive)
3029 (sql-product-interactive 'informix)) 3444 (sql-product-interactive 'informix))
3030 3445
3031(defun sql-connect-informix (product options) 3446(defun sql-comint-informix (product options)
3032 "Create comint buffer and connect to Informix." 3447 "Create comint buffer and connect to Informix."
3033 ;; username and password are ignored. 3448 ;; username and password are ignored.
3034 (let ((db (if (string= "" sql-database) 3449 (let ((db (if (string= "" sql-database)
@@ -3036,7 +3451,7 @@ The default comes from `process-coding-system-alist' and
3036 (if (string= "" sql-server) 3451 (if (string= "" sql-server)
3037 sql-database 3452 sql-database
3038 (concat sql-database "@" sql-server))))) 3453 (concat sql-database "@" sql-server)))))
3039 (sql-connect product (append `(,db "-") options)))) 3454 (sql-comint product (append `(,db "-") options))))
3040 3455
3041 3456
3042 3457
@@ -3069,15 +3484,16 @@ The default comes from `process-coding-system-alist' and
3069 (interactive) 3484 (interactive)
3070 (sql-product-interactive 'sqlite)) 3485 (sql-product-interactive 'sqlite))
3071 3486
3072(defun sql-connect-sqlite (product options) 3487(defun sql-comint-sqlite (product options)
3073 "Create comint buffer and connect to SQLite." 3488 "Create comint buffer and connect to SQLite."
3074 ;; Put all parameters to the program (if defined) in a list and call 3489 ;; Put all parameters to the program (if defined) in a list and call
3075 ;; make-comint. 3490 ;; make-comint.
3076 (let ((params)) 3491 (let ((params))
3077 (if (not (string= "" sql-database)) 3492 (if (not (string= "" sql-database))
3078 (setq params (append (list sql-database) params))) 3493 (setq params (append (list (expand-file-name sql-database))
3494 params)))
3079 (setq params (append options params)) 3495 (setq params (append options params))
3080 (sql-connect product params))) 3496 (sql-comint product params)))
3081 3497
3082 3498
3083 3499
@@ -3110,7 +3526,7 @@ The default comes from `process-coding-system-alist' and
3110 (interactive) 3526 (interactive)
3111 (sql-product-interactive 'mysql)) 3527 (sql-product-interactive 'mysql))
3112 3528
3113(defun sql-connect-mysql (product options) 3529(defun sql-comint-mysql (product options)
3114 "Create comint buffer and connect to MySQL." 3530 "Create comint buffer and connect to MySQL."
3115 ;; Put all parameters to the program (if defined) in a list and call 3531 ;; Put all parameters to the program (if defined) in a list and call
3116 ;; make-comint. 3532 ;; make-comint.
@@ -3126,7 +3542,7 @@ The default comes from `process-coding-system-alist' and
3126 (if (not (string= "" sql-user)) 3542 (if (not (string= "" sql-user))
3127 (setq params (append (list (concat "--user=" sql-user)) params))) 3543 (setq params (append (list (concat "--user=" sql-user)) params)))
3128 (setq params (append options params)) 3544 (setq params (append options params))
3129 (sql-connect product params))) 3545 (sql-comint product params)))
3130 3546
3131 3547
3132 3548
@@ -3156,7 +3572,7 @@ The default comes from `process-coding-system-alist' and
3156 (interactive) 3572 (interactive)
3157 (sql-product-interactive 'solid)) 3573 (sql-product-interactive 'solid))
3158 3574
3159(defun sql-connect-solid (product options) 3575(defun sql-comint-solid (product options)
3160 "Create comint buffer and connect to Solid." 3576 "Create comint buffer and connect to Solid."
3161 ;; Put all parameters to the program (if defined) in a list and call 3577 ;; Put all parameters to the program (if defined) in a list and call
3162 ;; make-comint. 3578 ;; make-comint.
@@ -3167,7 +3583,7 @@ The default comes from `process-coding-system-alist' and
3167 (setq params (append (list sql-user sql-password) params))) 3583 (setq params (append (list sql-user sql-password) params)))
3168 (if (not (string= "" sql-server)) 3584 (if (not (string= "" sql-server))
3169 (setq params (append (list sql-server) params))) 3585 (setq params (append (list sql-server) params)))
3170 (sql-connect product params))) 3586 (sql-comint product params)))
3171 3587
3172 3588
3173 3589
@@ -3196,10 +3612,10 @@ The default comes from `process-coding-system-alist' and
3196 (interactive) 3612 (interactive)
3197 (sql-product-interactive 'ingres)) 3613 (sql-product-interactive 'ingres))
3198 3614
3199(defun sql-connect-ingres (product options) 3615(defun sql-comint-ingres (product options)
3200 "Create comint buffer and connect to Ingres." 3616 "Create comint buffer and connect to Ingres."
3201 ;; username and password are ignored. 3617 ;; username and password are ignored.
3202 (sql-connect product 3618 (sql-comint product
3203 (append (if (string= "" sql-database) 3619 (append (if (string= "" sql-database)
3204 nil 3620 nil
3205 (list sql-database)) 3621 (list sql-database))
@@ -3234,7 +3650,7 @@ The default comes from `process-coding-system-alist' and
3234 (interactive) 3650 (interactive)
3235 (sql-product-interactive 'ms)) 3651 (sql-product-interactive 'ms))
3236 3652
3237(defun sql-connect-ms (product options) 3653(defun sql-comint-ms (product options)
3238 "Create comint buffer and connect to Microsoft SQL Server." 3654 "Create comint buffer and connect to Microsoft SQL Server."
3239 ;; Put all parameters to the program (if defined) in a list and call 3655 ;; Put all parameters to the program (if defined) in a list and call
3240 ;; make-comint. 3656 ;; make-comint.
@@ -3254,7 +3670,7 @@ The default comes from `process-coding-system-alist' and
3254 ;; If -P is passed to ISQL as the last argument without a 3670 ;; If -P is passed to ISQL as the last argument without a
3255 ;; password, it's considered null. 3671 ;; password, it's considered null.
3256 (setq params (append params (list "-P"))))) 3672 (setq params (append params (list "-P")))))
3257 (sql-connect product params))) 3673 (sql-comint product params)))
3258 3674
3259 3675
3260 3676
@@ -3290,7 +3706,7 @@ Try to set `comint-output-filter-functions' like this:
3290 (interactive) 3706 (interactive)
3291 (sql-product-interactive 'postgres)) 3707 (sql-product-interactive 'postgres))
3292 3708
3293(defun sql-connect-postgres (product options) 3709(defun sql-comint-postgres (product options)
3294 "Create comint buffer and connect to Postgres." 3710 "Create comint buffer and connect to Postgres."
3295 ;; username and password are ignored. Mark Stosberg suggest to add 3711 ;; username and password are ignored. Mark Stosberg suggest to add
3296 ;; the database at the end. Jason Beegan suggest using --pset and 3712 ;; the database at the end. Jason Beegan suggest using --pset and
@@ -3304,7 +3720,7 @@ Try to set `comint-output-filter-functions' like this:
3304 (setq params (append (list "-h" sql-server) params))) 3720 (setq params (append (list "-h" sql-server) params)))
3305 (if (not (string= "" sql-user)) 3721 (if (not (string= "" sql-user))
3306 (setq params (append (list "-U" sql-user) params))) 3722 (setq params (append (list "-U" sql-user) params)))
3307 (sql-connect product params))) 3723 (sql-comint product params)))
3308 3724
3309 3725
3310 3726
@@ -3334,7 +3750,7 @@ The default comes from `process-coding-system-alist' and
3334 (interactive) 3750 (interactive)
3335 (sql-product-interactive 'interbase)) 3751 (sql-product-interactive 'interbase))
3336 3752
3337(defun sql-connect-interbase (product options) 3753(defun sql-comint-interbase (product options)
3338 "Create comint buffer and connect to Interbase." 3754 "Create comint buffer and connect to Interbase."
3339 ;; Put all parameters to the program (if defined) in a list and call 3755 ;; Put all parameters to the program (if defined) in a list and call
3340 ;; make-comint. 3756 ;; make-comint.
@@ -3345,7 +3761,7 @@ The default comes from `process-coding-system-alist' and
3345 (setq params (append (list "-p" sql-password) params))) 3761 (setq params (append (list "-p" sql-password) params)))
3346 (if (not (string= "" sql-database)) 3762 (if (not (string= "" sql-database))
3347 (setq params (cons sql-database params))) ; add to the front! 3763 (setq params (cons sql-database params))) ; add to the front!
3348 (sql-connect product params))) 3764 (sql-comint product params)))
3349 3765
3350 3766
3351 3767
@@ -3379,11 +3795,11 @@ The default comes from `process-coding-system-alist' and
3379 (interactive) 3795 (interactive)
3380 (sql-product-interactive 'db2)) 3796 (sql-product-interactive 'db2))
3381 3797
3382(defun sql-connect-db2 (product options) 3798(defun sql-comint-db2 (product options)
3383 "Create comint buffer and connect to DB2." 3799 "Create comint buffer and connect to DB2."
3384 ;; Put all parameters to the program (if defined) in a list and call 3800 ;; Put all parameters to the program (if defined) in a list and call
3385 ;; make-comint. 3801 ;; make-comint.
3386 (sql-connect product options) 3802 (sql-comint product options)
3387) 3803)
3388;; ;; Properly escape newlines when DB2 is interactive. 3804;; ;; Properly escape newlines when DB2 is interactive.
3389;; (setq comint-input-sender 'sql-escape-newlines-and-send)) 3805;; (setq comint-input-sender 'sql-escape-newlines-and-send))
@@ -3415,7 +3831,7 @@ input. See `sql-interactive-mode'.
3415 (interactive) 3831 (interactive)
3416 (sql-product-interactive 'linter)) 3832 (sql-product-interactive 'linter))
3417 3833
3418(defun sql-connect-linter (product options) 3834(defun sql-comint-linter (product options)
3419 "Create comint buffer and connect to Linter." 3835 "Create comint buffer and connect to Linter."
3420 ;; Put all parameters to the program (if defined) in a list and call 3836 ;; Put all parameters to the program (if defined) in a list and call
3421 ;; make-comint. 3837 ;; make-comint.
@@ -3430,7 +3846,7 @@ input. See `sql-interactive-mode'.
3430 (if (string= "" sql-database) 3846 (if (string= "" sql-database)
3431 (setenv "LINTER_MBX" nil) 3847 (setenv "LINTER_MBX" nil)
3432 (setenv "LINTER_MBX" sql-database)) 3848 (setenv "LINTER_MBX" sql-database))
3433 (sql-connect product params) 3849 (sql-comint product params)
3434 (setenv "LINTER_MBX" old-mbx))) 3850 (setenv "LINTER_MBX" old-mbx)))
3435 3851
3436 3852
diff --git a/lisp/progmodes/tcl.el b/lisp/progmodes/tcl.el
index 58b8be8c7ba..29096a23046 100644
--- a/lisp/progmodes/tcl.el
+++ b/lisp/progmodes/tcl.el
@@ -545,7 +545,7 @@ Uses variables `tcl-proc-regexp' and `tcl-keyword-list'."
545;; 545;;
546 546
547;;;###autoload 547;;;###autoload
548(define-derived-mode tcl-mode nil "Tcl" 548(define-derived-mode tcl-mode prog-mode "Tcl"
549 "Major mode for editing Tcl code. 549 "Major mode for editing Tcl code.
550Expression and list commands understand all Tcl brackets. 550Expression and list commands understand all Tcl brackets.
551Tab indents for Tcl code. 551Tab indents for Tcl code.
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 6a72c161429..469786e04dd 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -145,7 +145,9 @@ Zero means compute the Imenu menu regardless of size."
145 local-map ,which-func-keymap 145 local-map ,which-func-keymap
146 face which-func 146 face which-func
147 ;;mouse-face highlight ; currently not evaluated :-( 147 ;;mouse-face highlight ; currently not evaluated :-(
148 help-echo "mouse-1: go to beginning, mouse-2: toggle rest visibility, mouse-3: go to end") 148 help-echo "mouse-1: go to beginning\n\
149mouse-2: toggle rest visibility\n\
150mouse-3: go to end")
149 "]") 151 "]")
150 "Format for displaying the function in the mode line." 152 "Format for displaying the function in the mode line."
151 :group 'which-func 153 :group 'which-func