aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes
diff options
context:
space:
mode:
authorJoakim Verona2011-07-15 04:39:29 +0200
committerJoakim Verona2011-07-15 04:39:29 +0200
commit4f616a2e7ed1db28da98df90266e9751a8ae9ee1 (patch)
tree74a9dcbe13e945e712ae04a4a94c2202ca720591 /lisp/progmodes
parentff2be00005c3aeda6e11d7ed264ce86f02b60958 (diff)
parentec2bc542a4d0127425625e8cb458684bd825675a (diff)
downloademacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.tar.gz
emacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.zip
merge from upstream
Diffstat (limited to 'lisp/progmodes')
-rw-r--r--lisp/progmodes/cc-engine.el29
-rw-r--r--lisp/progmodes/cc-guess.el574
-rw-r--r--lisp/progmodes/cc-langs.el13
-rw-r--r--lisp/progmodes/cc-mode.el10
-rw-r--r--lisp/progmodes/cc-styles.el9
-rw-r--r--lisp/progmodes/cc-vars.el3
-rw-r--r--lisp/progmodes/cfengine.el268
-rw-r--r--lisp/progmodes/compile.el11
-rw-r--r--lisp/progmodes/cperl-mode.el2
-rw-r--r--lisp/progmodes/etags.el6
-rw-r--r--lisp/progmodes/flymake.el11
-rw-r--r--lisp/progmodes/gdb-mi.el1058
-rw-r--r--lisp/progmodes/grep.el3
-rw-r--r--lisp/progmodes/gud.el3
-rw-r--r--lisp/progmodes/js.el4
-rw-r--r--lisp/progmodes/sql.el1155
-rw-r--r--lisp/progmodes/which-func.el3
17 files changed, 2347 insertions, 815 deletions
diff --git a/lisp/progmodes/cc-engine.el b/lisp/progmodes/cc-engine.el
index 0eec54fab6f..38f66b4504e 100644
--- a/lisp/progmodes/cc-engine.el
+++ b/lisp/progmodes/cc-engine.el
@@ -8712,6 +8712,35 @@ comment at the start of cc-engine.el for more info."
8712 (c-beginning-of-statement-1 containing-sexp) 8712 (c-beginning-of-statement-1 containing-sexp)
8713 (c-add-syntax 'annotation-var-cont (point))) 8713 (c-add-syntax 'annotation-var-cont (point)))
8714 8714
8715 ;; CASE G: a template list continuation?
8716 ;; Mostly a duplication of case 5D.3 to fix templates-19:
8717 ((and (c-major-mode-is 'c++-mode)
8718 (save-excursion
8719 (goto-char indent-point)
8720 (c-with-syntax-table c++-template-syntax-table
8721 (setq placeholder (c-up-list-backward)))
8722 (and placeholder
8723 (eq (char-after placeholder) ?<)
8724 (/= (char-before placeholder) ?<)
8725 (progn
8726 (goto-char (1+ placeholder))
8727 (not (looking-at c-<-op-cont-regexp))))))
8728 (c-with-syntax-table c++-template-syntax-table
8729 (goto-char placeholder)
8730 (c-beginning-of-statement-1 containing-sexp t)
8731 (if (save-excursion
8732 (c-backward-syntactic-ws containing-sexp)
8733 (eq (char-before) ?<))
8734 ;; In a nested template arglist.
8735 (progn
8736 (goto-char placeholder)
8737 (c-syntactic-skip-backward "^,;" containing-sexp t)
8738 (c-forward-syntactic-ws))
8739 (back-to-indentation)))
8740 ;; FIXME: Should use c-add-stmt-syntax, but it's not yet
8741 ;; template aware.
8742 (c-add-syntax 'template-args-cont (point) placeholder))
8743
8715 ;; CASE D: continued statement. 8744 ;; CASE D: continued statement.
8716 (t 8745 (t
8717 (c-beginning-of-statement-1 containing-sexp) 8746 (c-beginning-of-statement-1 containing-sexp)
diff --git a/lisp/progmodes/cc-guess.el b/lisp/progmodes/cc-guess.el
new file mode 100644
index 00000000000..6553021e783
--- /dev/null
+++ b/lisp/progmodes/cc-guess.el
@@ -0,0 +1,574 @@
1;;; cc-guess.el --- guess indentation values by scanning existing code
2
3;; Copyright (C) 1985, 1987, 1992-2006, 2011
4;; Free Software Foundation, Inc.
5
6;; Author: 1994-1995 Barry A. Warsaw
7;; 2011- Masatake YAMATO
8;; Maintainer: bug-cc-mode@gnu.org
9;; Created: August 1994, split from cc-mode.el
10;; Version: See cc-mode.el
11;; Keywords: c languages oop
12
13;; This file is part of GNU Emacs.
14
15;; GNU Emacs is free software: you can redistribute it and/or modify
16;; it under the terms of the GNU General Public License as published by
17;; the Free Software Foundation, either version 3 of the License, or
18;; (at your option) any later version.
19
20;; GNU Emacs is distributed in the hope that it will be useful,
21;; but WITHOUT ANY WARRANTY; without even the implied warranty of
22;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23;; GNU General Public License for more details.
24
25;; You should have received a copy of the GNU General Public License
26;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
27
28;;; Commentary:
29;;
30;; This file contains routines that help guess the cc-mode style in a
31;; particular region/buffer. Here style means `c-offsets-alist' and
32;; `c-basic-offset'.
33;;
34;; The main entry point of this program is `c-guess' command but there
35;; are some variants.
36;;
37;; Suppose the major mode for the current buffer is one of the modes
38;; provided by cc-mode. `c-guess' guesses the indentation style by
39;; examining the indentation in the region between beginning of buffer
40;; and `c-guess-region-max'.
41
42;; and installs the guessed style. The name for installed style is given
43;; by `c-guess-style-name'.
44;;
45;; `c-guess-buffer' does the same but in the whole buffer.
46;; `c-guess-region' does the same but in the region between the point
47;; and the mark. `c-guess-no-install', `c-guess-buffer-no-install'
48;; and `c-guess-region-no-install' guess the indentation style but
49;; don't install it. You can review a guessed style with `c-guess-view'.
50;; After reviewing, use `c-guess-install' to install the style
51;; if you prefer it.
52;;
53;; If you want to reuse the guessed style in another buffer,
54;; run `c-set-style' command with the name of the guessed style:
55;; "*c-guess*:<name-of-file-which-examined-when-guessing>".
56;; Once the guessed style is installed explicitly with `c-guess-install'
57;; or implicitly with `c-guess', `c-guess-buffer', or `c-guess-region',
58;; a style name is given by `c-guess-style-name' with the above form.
59;;
60;; If you want to reuse the guessed style in future emacs sessions,
61;; you may want to put it to your .emacs. `c-guess-view' is for
62;; you. It emits emacs lisp code which defines the last guessed
63;; style, in a temporary buffer. You can put the emitted code into
64;; your .emacs. This command was suggested by Alan Mackenzie.
65
66;;; Code:
67
68(eval-when-compile
69 (let ((load-path
70 (if (and (boundp 'byte-compile-dest-file)
71 (stringp byte-compile-dest-file))
72 (cons (file-name-directory byte-compile-dest-file) load-path)
73 load-path)))
74 (load "cc-bytecomp" nil t)))
75
76(cc-require 'cc-defs)
77(cc-require 'cc-engine)
78(cc-require 'cc-styles)
79
80
81
82(defcustom c-guess-offset-threshold 10
83 "Threshold of acceptable offsets when examining indent information.
84Discard an examined offset if its absolute value is greater than this.
85
86The offset of a line included in the indent information returned by
87`c-guess-basic-syntax'."
88 :type 'integer
89 :group 'c)
90
91(defcustom c-guess-region-max 50000
92 "The maximum region size for examining indent information with `c-guess'.
93It takes a long time to examine indent information from a large region;
94this option helps you limit that time. `nil' means no limit."
95 :type 'integer
96 :group 'c)
97
98
99;;;###autoload
100(defvar c-guess-guessed-offsets-alist nil
101 "Currently guessed offsets-alist.")
102;;;###autoload
103(defvar c-guess-guessed-basic-offset nil
104 "Currently guessed basic-offset.")
105
106(defvar c-guess-accumulator nil)
107;; Accumulated examined indent information. Information is represented
108;; in a list. Each element in it has following structure:
109;;
110;; (syntactic-symbol ((indentation-offset1 . number-of-times1)
111;; (indentation-offset2 . number-of-times2)
112;; ...))
113;;
114;; This structure is built by `c-guess-accumulate-offset'.
115;;
116;; Here we call the pair (indentation-offset1 . number-of-times1) a
117;; counter. `c-guess-sort-accumulator' sorts the order of
118;; counters by number-of-times.
119;; Use `c-guess-dump-accumulator' to see the value.
120
121(defconst c-guess-conversions
122 '((c . c-lineup-C-comments)
123 (inher-cont . c-lineup-multi-inher)
124 (string . -1000)
125 (comment-intro . c-lineup-comment)
126 (arglist-cont-nonempty . c-lineup-arglist)
127 (arglist-close . c-lineup-close-paren)
128 (cpp-macro . -1000)))
129
130
131;;;###autoload
132(defun c-guess (&optional accumulate)
133 "Guess the style in the region up to `c-guess-region-max', and install it.
134
135The style is given a name based on the file's absolute file name.
136
137If given a prefix argument (or if the optional argument ACCUMULATE is
138non-nil) then the previous guess is extended, otherwise a new guess is
139made from scratch."
140 (interactive "P")
141 (c-guess-region (point-min)
142 (min (point-max) (or c-guess-region-max
143 (point-max)))
144 accumulate))
145
146;;;###autoload
147(defun c-guess-no-install (&optional accumulate)
148 "Guess the style in the region up to `c-guess-region-max'; don't install it.
149
150If given a prefix argument (or if the optional argument ACCUMULATE is
151non-nil) then the previous guess is extended, otherwise a new guess is
152made from scratch."
153 (interactive "P")
154 (c-guess-region-no-install (point-min)
155 (min (point-max) (or c-guess-region-max
156 (point-max)))
157 accumulate))
158
159;;;###autoload
160(defun c-guess-buffer (&optional accumulate)
161 "Guess the style on the whole current buffer, and install it.
162
163The style is given a name based on the file's absolute file name.
164
165If given a prefix argument (or if the optional argument ACCUMULATE is
166non-nil) then the previous guess is extended, otherwise a new guess is
167made from scratch."
168 (interactive "P")
169 (c-guess-region (point-min)
170 (point-max)
171 accumulate))
172
173;;;###autoload
174(defun c-guess-buffer-no-install (&optional accumulate)
175 "Guess the style on the whole current buffer; don't install it.
176
177If given a prefix argument (or if the optional argument ACCUMULATE is
178non-nil) then the previous guess is extended, otherwise a new guess is
179made from scratch."
180 (interactive "P")
181 (c-guess-region-no-install (point-min)
182 (point-max)
183 accumulate))
184
185;;;###autoload
186(defun c-guess-region (start end &optional accumulate)
187 "Guess the style on the region and install it.
188
189The style is given a name based on the file's absolute file name.
190
191If given a prefix argument (or if the optional argument ACCUMULATE is
192non-nil) then the previous guess is extended, otherwise a new guess is
193made from scratch."
194 (interactive "r\nP")
195 (c-guess-region-no-install start end accumulate)
196 (c-guess-install))
197
198
199(defsubst c-guess-empty-line-p ()
200 (eq (line-beginning-position)
201 (line-end-position)))
202
203;;;###autoload
204(defun c-guess-region-no-install (start end &optional accumulate)
205 "Guess the style on the region; don't install it.
206
207Every line of code in the region is examined and values for the following two
208variables are guessed:
209
210* `c-basic-offset', and
211* the indentation values of the various syntactic symbols in
212 `c-offsets-alist'.
213
214The guessed values are put into `c-guess-guessed-basic-offset' and
215`c-guess-guessed-offsets-alist'.
216
217Frequencies of use are taken into account when guessing, so minor
218inconsistencies in the indentation style shouldn't produce wrong guesses.
219
220If given a prefix argument (or if the optional argument ACCUMULATE is
221non-nil) then the previous examination is extended, otherwise a new
222guess is made from scratch.
223
224Note that the larger the region to guess in, the slower the guessing.
225So you can limit the region with `c-guess-region-max'."
226 (interactive "r\nP")
227 (let ((accumulator (when accumulate c-guess-accumulator)))
228 (setq c-guess-accumulator (c-guess-examine start end accumulator))
229 (let ((pair (c-guess-guess c-guess-accumulator)))
230 (setq c-guess-guessed-basic-offset (car pair)
231 c-guess-guessed-offsets-alist (cdr pair)))))
232
233
234(defun c-guess-examine (start end accumulator)
235 (let ((reporter (when (fboundp 'make-progress-reporter)
236 (make-progress-reporter "Examining Indentation "
237 start
238 end))))
239 (save-excursion
240 (goto-char start)
241 (while (< (point) end)
242 (unless (c-guess-empty-line-p)
243 (mapc (lambda (s)
244 (setq accumulator (or (c-guess-accumulate accumulator s)
245 accumulator)))
246 (c-save-buffer-state () (c-guess-basic-syntax))))
247 (when reporter (progress-reporter-update reporter (point)))
248 (forward-line 1)))
249 (when reporter (progress-reporter-done reporter)))
250 (c-guess-sort-accumulator accumulator))
251
252(defun c-guess-guess (accumulator)
253 ;; Guess basic-offset and offsets-alist from ACCUMULATOR,
254 ;; then return them as a cons: (basic-offset . offsets-alist).
255 ;; See the comments at `c-guess-accumulator' about the format
256 ;; ACCUMULATOR.
257 (let* ((basic-offset (c-guess-make-basic-offset accumulator))
258 (typical-offsets-alist (c-guess-make-offsets-alist
259 accumulator))
260 (symbolic-offsets-alist (c-guess-symbolize-offsets-alist
261 typical-offsets-alist
262 basic-offset))
263 (merged-offsets-alist (c-guess-merge-offsets-alists
264 (copy-tree c-guess-conversions)
265 symbolic-offsets-alist)))
266 (cons basic-offset merged-offsets-alist)))
267
268(defun c-guess-current-offset (relpos)
269 ;; Calculate relative indentation (point) to RELPOS.
270 (- (progn (back-to-indentation)
271 (current-column))
272 (save-excursion
273 (goto-char relpos)
274 (current-column))))
275
276(defun c-guess-accumulate (accumulator syntax-element)
277 ;; Add SYNTAX-ELEMENT to ACCUMULATOR.
278 (let ((symbol (car syntax-element))
279 (relpos (cadr syntax-element)))
280 (when (numberp relpos)
281 (let ((offset (c-guess-current-offset relpos)))
282 (when (< (abs offset) c-guess-offset-threshold)
283 (c-guess-accumulate-offset accumulator
284 symbol
285 offset))))))
286
287(defun c-guess-accumulate-offset (accumulator symbol offset)
288 ;; Added SYMBOL and OFFSET to ACCUMULATOR. See
289 ;; `c-guess-accumulator' about the structure of ACCUMULATOR.
290 (let* ((entry (assoc symbol accumulator))
291 (counters (cdr entry))
292 counter)
293 (if entry
294 (progn
295 (setq counter (assoc offset counters))
296 (if counter
297 (setcdr counter (1+ (cdr counter)))
298 (setq counters (cons (cons offset 1) counters))
299 (setcdr entry counters))
300 accumulator)
301 (cons (cons symbol (cons (cons offset 1) nil)) accumulator))))
302
303(defun c-guess-sort-accumulator (accumulator)
304 ;; Sort each element of ACCUMULATOR by the number-of-times. See
305 ;; `c-guess-accumulator' for more details.
306 (mapcar
307 (lambda (entry)
308 (let ((symbol (car entry))
309 (counters (cdr entry)))
310 (cons symbol (sort counters
311 (lambda (a b)
312 (if (> (cdr a) (cdr b))
313 t
314 (and
315 (eq (cdr a) (cdr b))
316 (< (car a) (car b)))))))))
317 accumulator))
318
319(defun c-guess-make-offsets-alist (accumulator)
320 ;; Throw away the rare cases in accumulator and make an offsets-alist structure.
321 (mapcar
322 (lambda (entry)
323 (cons (car entry)
324 (car (car (cdr entry)))))
325 accumulator))
326
327(defun c-guess-merge-offsets-alists (strong weak)
328 ;; Merge two offsets-alists into one.
329 ;; When two offsets-alists have the same symbol
330 ;; entry, give STRONG priority over WEAK.
331 (mapc
332 (lambda (weak-elt)
333 (unless (assoc (car weak-elt) strong)
334 (setq strong (cons weak-elt strong))))
335 weak)
336 strong)
337
338(defun c-guess-make-basic-offset (accumulator)
339 ;; As candidate for `c-basic-offset', find the most frequently appearing
340 ;; indentation-offset in ACCUMULATOR.
341 (let* (;; Drop the value related to `c' syntactic-symbol.
342 ;; (`c': Inside a multiline C style block comment.)
343 ;; The impact for values of `c' is too large for guessing
344 ;; `basic-offset' if the target source file is small and its license
345 ;; notice is at top of the file.
346 (accumulator (assq-delete-all 'c (copy-tree accumulator)))
347 ;; Drop syntactic-symbols from ACCUMULATOR.
348 (alist (apply #'append (mapcar (lambda (elts)
349 (mapcar (lambda (elt)
350 (cons (abs (car elt))
351 (cdr elt)))
352 (cdr elts)))
353 accumulator)))
354 ;; Gather all indentation-offsets other than 0.
355 ;; 0 is meaningless as `basic-offset'.
356 (offset-list (delete 0
357 (delete-dups (mapcar
358 (lambda (elt) (car elt))
359 alist))))
360 ;; Sum of number-of-times for offset:
361 ;; (offset . sum)
362 (summed (mapcar (lambda (offset)
363 (cons offset
364 (apply #'+
365 (mapcar (lambda (a)
366 (if (eq (car a) offset)
367 (cdr a)
368 0))
369 alist))))
370 offset-list)))
371 ;;
372 ;; Find the majority.
373 ;;
374 (let ((majority '(nil . 0)))
375 (while summed
376 (when (< (cdr majority) (cdr (car summed)))
377 (setq majority (car summed)))
378 (setq summed (cdr summed)))
379 (car majority))))
380
381(defun c-guess-symbolize-offsets-alist (offsets-alist basic-offset)
382 ;; Convert the representation of OFFSETS-ALIST to an alist using
383 ;; `+', `-', `++', `--', `*', or `/'. These symbols represent
384 ;; a value relative to BASIC-OFFSET. Their meaning can be found
385 ;; in the CC Mode manual.
386 (mapcar
387 (lambda (elt)
388 (let ((s (car elt))
389 (v (cdr elt)))
390 (cond
391 ((integerp v)
392 (cons s (c-guess-symbolize-integer v
393 basic-offset)))
394 (t elt))))
395 offsets-alist))
396
397(defun c-guess-symbolize-integer (int basic-offset)
398 (let ((aint (abs int)))
399 (cond
400 ((eq int basic-offset) '+)
401 ((eq aint basic-offset) '-)
402 ((eq int (* 2 basic-offset)) '++)
403 ((eq aint (* 2 basic-offset)) '--)
404 ((eq (* 2 int) basic-offset) '*)
405 ((eq (* 2 aint) basic-offset) '-)
406 (t int))))
407
408(defun c-guess-style-name ()
409 ;; Make a style name for the guessed style.
410 (format "*c-guess*:%s" (buffer-file-name)))
411
412(defun c-guess-make-style (basic-offset offsets-alist)
413 (when basic-offset
414 ;; Make a style from guessed values.
415 (let* ((offsets-alist (c-guess-merge-offsets-alists
416 offsets-alist
417 c-offsets-alist)))
418 `((c-basic-offset . ,basic-offset)
419 (c-offsets-alist . ,offsets-alist)))))
420
421;;;###autoload
422(defun c-guess-install (&optional style-name)
423 "Install the latest guessed style into the current buffer.
424\(This guessed style is a combination of `c-guess-guessed-basic-offset',
425`c-guess-guessed-offsets-alist' and `c-offsets-alist'.)
426
427The style is entered into CC Mode's style system by
428`c-add-style'. Its name is either STYLE-NAME, or a name based on
429the absolute file name of the file if STYLE-NAME is nil."
430 (interactive "sNew style name (empty for default name): ")
431 (let* ((style (c-guess-make-style c-guess-guessed-basic-offset
432 c-guess-guessed-offsets-alist)))
433 (if style
434 (let ((style-name (or (if (equal style-name "")
435 nil
436 style-name)
437 (c-guess-style-name))))
438 (c-add-style style-name style t)
439 (message "Style \"%s\" is installed" style-name))
440 (error "Not yet guessed"))))
441
442(defun c-guess-dump-accumulator ()
443 "Show `c-guess-accumulator'."
444 (interactive)
445 (with-output-to-temp-buffer "*Accumulated Examined Indent Information*"
446 (pp c-guess-accumulator)))
447
448(defun c-guess-reset-accumulator ()
449 "Reset `c-guess-accumulator'."
450 (interactive)
451 (setq c-guess-accumulator nil))
452
453(defun c-guess-dump-guessed-values ()
454 "Show `c-guess-guessed-basic-offset' and `c-guess-guessed-offsets-alist'."
455 (interactive)
456 (with-output-to-temp-buffer "*Guessed Values*"
457 (princ "basic-offset: \n\t")
458 (pp c-guess-guessed-basic-offset)
459 (princ "\n\n")
460 (princ "offsets-alist: \n")
461 (pp c-guess-guessed-offsets-alist)
462 ))
463
464(defun c-guess-dump-guessed-style (&optional printer)
465 "Show the guessed style.
466`pp' is used to print the style but if PRINTER is given,
467PRINTER is used instead. If PRINTER is not `nil', it
468is called with one argument, the guessed style."
469 (interactive)
470 (let ((style (c-guess-make-style c-guess-guessed-basic-offset
471 c-guess-guessed-offsets-alist)))
472 (if style
473 (with-output-to-temp-buffer "*Guessed Style*"
474 (funcall (if printer printer 'pp) style))
475 (error "Not yet guessed"))))
476
477(defun c-guess-guessed-syntactic-symbols ()
478 ;; Return syntactic symbols in c-guess-guessed-offsets-alist
479 ;; but not in c-guess-conversions.
480 (let ((alist c-guess-guessed-offsets-alist)
481 elt
482 (symbols nil))
483 (while alist
484 (setq elt (car alist)
485 alist (cdr alist))
486 (unless (assq (car elt) c-guess-conversions)
487 (setq symbols (cons (car elt)
488 symbols))))
489 symbols))
490
491(defun c-guess-view-reorder-offsets-alist-in-style (style guessed-syntactic-symbols)
492 ;; Reorder the `c-offsets-alist' field of STYLE.
493 ;; If an entry in `c-offsets-alist' holds a guessed value, move it to
494 ;; front in the field. In addition alphabetical sort by entry name is done.
495 (setq style (copy-tree style))
496 (let ((offsets-alist-cell (assq 'c-offsets-alist style))
497 (guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols)))
498 (setcdr offsets-alist-cell
499 (sort (cdr offsets-alist-cell)
500 (lambda (a b)
501 (let ((a-guessed? (memq (car a) guessed-syntactic-symbols))
502 (b-guessed? (memq (car b) guessed-syntactic-symbols)))
503 (cond
504 ((or (and a-guessed? b-guessed?)
505 (not (or a-guessed? b-guessed?)))
506 (string-lessp (symbol-name (car a))
507 (symbol-name (car b))))
508 (a-guessed? t)
509 (b-guessed? nil)))))))
510 style)
511
512(defun c-guess-view-mark-guessed-entries (guessed-syntactic-symbols)
513 ;; Put " ; Guess value" markers on all entries which hold
514 ;; guessed values.
515 ;; `c-basic-offset' is always considered as holding a guessed value.
516 (let ((needs-markers (cons 'c-basic-offset
517 guessed-syntactic-symbols)))
518 (while needs-markers
519 (goto-char (point-min))
520 (when (search-forward (concat "("
521 (symbol-name (car needs-markers))
522 " ") nil t)
523 (move-end-of-line 1)
524 (comment-dwim nil)
525 (insert " Guessed value"))
526 (setq needs-markers
527 (cdr needs-markers)))))
528
529(defun c-guess-view (&optional with-name)
530 "Emit emacs lisp code which defines the last guessed style.
531So you can put the code into .emacs if you prefer the
532guessed code.
533\"STYLE NAME HERE\" is used as the name for the style in the
534emitted code. If WITH-NAME is given, it is used instead.
535WITH-NAME is expected as a string but if this function
536called interactively with prefix argument, the value for
537WITH-NAME is asked to the user."
538 (interactive "P")
539 (let* ((temporary-style-name (cond
540 ((stringp with-name) with-name)
541 (with-name (read-from-minibuffer
542 "New style name: "))
543 (t
544 "STYLE NAME HERE")))
545 (guessed-style-name (c-guess-style-name))
546 (current-style-name c-indentation-style)
547 (parent-style-name (if (string-equal guessed-style-name
548 current-style-name)
549 ;; The guessed style is already installed.
550 ;; It cannot be used as the parent style.
551 ;; Use the default style for the current
552 ;; major mode as the parent style.
553 (cc-choose-style-for-mode
554 major-mode
555 c-default-style)
556 ;; The guessed style is not installed yet.
557 current-style-name)))
558 (c-guess-dump-guessed-style
559 (lambda (style)
560 (let ((guessed-syntactic-symbols (c-guess-guessed-syntactic-symbols)))
561 (pp `(c-add-style ,temporary-style-name
562 ',(cons parent-style-name
563 (c-guess-view-reorder-offsets-alist-in-style
564 style
565 guessed-syntactic-symbols))))
566 (with-current-buffer standard-output
567 (lisp-interaction-mode)
568 (c-guess-view-mark-guessed-entries
569 guessed-syntactic-symbols)
570 (buffer-enable-undo)))))))
571
572
573(cc-provide 'cc-guess)
574;;; cc-guess.el ends here
diff --git a/lisp/progmodes/cc-langs.el b/lisp/progmodes/cc-langs.el
index 86a963bcf55..a6459e1724f 100644
--- a/lisp/progmodes/cc-langs.el
+++ b/lisp/progmodes/cc-langs.el
@@ -295,6 +295,19 @@ the evaluated constant value at compile time."
295 ["Backslashify" c-backslash-region 295 ["Backslashify" c-backslash-region
296 (c-fn-region-is-active-p)])) 296 (c-fn-region-is-active-p)]))
297 "----" 297 "----"
298 ("Style..."
299 ["Set Style..." c-set-style t]
300 ["Show Current Style Name" (message
301 "Style Name: %s"
302 c-indentation-style) t]
303 ["Guess Style from this Buffer" c-guess-buffer-no-install t]
304 ["Install the Last Guessed Style..." c-guess-install
305 (and c-guess-guessed-offsets-alist
306 c-guess-guessed-basic-offset) ]
307 ["View the Last Guessed Style" c-guess-view
308 (and c-guess-guessed-offsets-alist
309 c-guess-guessed-basic-offset) ])
310 "----"
298 ("Toggle..." 311 ("Toggle..."
299 ["Syntactic indentation" c-toggle-syntactic-indentation 312 ["Syntactic indentation" c-toggle-syntactic-indentation
300 :style toggle :selected c-syntactic-indentation] 313 :style toggle :selected c-syntactic-indentation]
diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el
index 3a5a643a2a8..1adc6c2eac0 100644
--- a/lisp/progmodes/cc-mode.el
+++ b/lisp/progmodes/cc-mode.el
@@ -93,6 +93,7 @@
93(cc-require 'cc-cmds) 93(cc-require 'cc-cmds)
94(cc-require 'cc-align) 94(cc-require 'cc-align)
95(cc-require 'cc-menus) 95(cc-require 'cc-menus)
96(cc-require 'cc-guess)
96 97
97;; Silence the compiler. 98;; Silence the compiler.
98(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs 99(cc-bytecomp-defvar adaptive-fill-first-line-regexp) ; Emacs
@@ -553,11 +554,7 @@ that requires a literal mode spec at compile time."
553 (c-clear-found-types) 554 (c-clear-found-types)
554 555
555 ;; now set the mode style based on default-style 556 ;; now set the mode style based on default-style
556 (let ((style (if (stringp default-style) 557 (let ((style (cc-choose-style-for-mode mode default-style)))
557 default-style
558 (or (cdr (assq mode default-style))
559 (cdr (assq 'other default-style))
560 "gnu"))))
561 ;; Override style variables if `c-old-style-variable-behavior' is 558 ;; Override style variables if `c-old-style-variable-behavior' is
562 ;; set. Also override if we are using global style variables, 559 ;; set. Also override if we are using global style variables,
563 ;; have already initialized a style once, and are switching to a 560 ;; have already initialized a style once, and are switching to a
@@ -692,7 +689,8 @@ This function is called from the hook `before-hack-local-variables-hook'."
692 (c-count-cfss file-local-variables-alist)) 689 (c-count-cfss file-local-variables-alist))
693 (cfs-in-dir-count (c-count-cfss dir-local-variables-alist))) 690 (cfs-in-dir-count (c-count-cfss dir-local-variables-alist)))
694 (c-set-style stile 691 (c-set-style stile
695 (= cfs-in-file-and-dir-count cfs-in-dir-count))) 692 (and (= cfs-in-file-and-dir-count cfs-in-dir-count)
693 'keep-defaults)))
696 (c-set-style stile))) 694 (c-set-style stile)))
697 (when offsets 695 (when offsets
698 (mapc 696 (mapc
diff --git a/lisp/progmodes/cc-styles.el b/lisp/progmodes/cc-styles.el
index e161eb6d0f5..96cb15f2a72 100644
--- a/lisp/progmodes/cc-styles.el
+++ b/lisp/progmodes/cc-styles.el
@@ -650,6 +650,15 @@ any reason to call this function directly."
650 (setq c-style-variables-are-local-p t)) 650 (setq c-style-variables-are-local-p t))
651 )) 651 ))
652 652
653(defun cc-choose-style-for-mode (mode default-style)
654 "Return suitable style for MODE from DEFAULT-STYLE.
655DEFAULT-STYLE has the same format as `c-default-style'."
656 (if (stringp default-style)
657 default-style
658 (or (cdr (assq mode default-style))
659 (cdr (assq 'other default-style))
660 "gnu")))
661
653 662
654 663
655(cc-provide 'cc-styles) 664(cc-provide 'cc-styles)
diff --git a/lisp/progmodes/cc-vars.el b/lisp/progmodes/cc-vars.el
index d2a5d117635..58dc1737c5a 100644
--- a/lisp/progmodes/cc-vars.el
+++ b/lisp/progmodes/cc-vars.el
@@ -1633,8 +1633,7 @@ as designated in the variable `c-file-style'.")
1633;; It isn't possible to specify a doc-string without specifying an 1633;; It isn't possible to specify a doc-string without specifying an
1634;; initial value with `defvar', so the following two variables have been 1634;; initial value with `defvar', so the following two variables have been
1635;; given doc-strings by setting the property `variable-documentation' 1635;; given doc-strings by setting the property `variable-documentation'
1636;; directly. C-h v will read this documentation only for versions of GNU 1636;; directly. It's really good not to have an initial value for
1637;; Emacs from 22.1. It's really good not to have an initial value for
1638;; variables like these that always should be dynamically bound, so it's 1637;; variables like these that always should be dynamically bound, so it's
1639;; worth the inconvenience. 1638;; worth the inconvenience.
1640 1639
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 22ece17cb28..7989c60f80c 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -3,6 +3,7 @@
3;; Copyright (C) 2001-2011 Free Software Foundation, Inc. 3;; Copyright (C) 2001-2011 Free Software Foundation, Inc.
4 4
5;; Author: Dave Love <fx@gnu.org> 5;; Author: Dave Love <fx@gnu.org>
6;; Maintainer: Ted Zlatanov <tzz@lifelogs.com>
6;; Keywords: languages 7;; Keywords: languages
7 8
8;; This file is part of GNU Emacs. 9;; This file is part of GNU Emacs.
@@ -28,6 +29,13 @@
28;; Possible customization for auto-mode selection: 29;; Possible customization for auto-mode selection:
29;; (push '(("^cfagent.conf\\'" . cfengine-mode)) auto-mode-alist) 30;; (push '(("^cfagent.conf\\'" . cfengine-mode)) auto-mode-alist)
30;; (push '(("^cf\\." . cfengine-mode)) auto-mode-alist) 31;; (push '(("^cf\\." . cfengine-mode)) auto-mode-alist)
32;; (push '(("\\.cf\\'" . cfengine-mode)) auto-mode-alist)
33
34;; Or, if you want to use the CFEngine 3.x support:
35
36;; (push '(("^cfagent.conf\\'" . cfengine3-mode)) auto-mode-alist)
37;; (push '(("^cf\\." . cfengine3-mode)) auto-mode-alist)
38;; (push '(("\\.cf\\'" . cfengine3-mode)) auto-mode-alist)
31 39
32;; This is not the same as the mode written by Rolf Ebert 40;; This is not the same as the mode written by Rolf Ebert
33;; <ebert@waporo.muc.de>, distributed with cfengine-2.0.5. It does 41;; <ebert@waporo.muc.de>, distributed with cfengine-2.0.5. It does
@@ -63,7 +71,27 @@
63 ;; cfservd 71 ;; cfservd
64 "admit" "grant" "deny") 72 "admit" "grant" "deny")
65 "List of the action keywords supported by Cfengine. 73 "List of the action keywords supported by Cfengine.
66This includes those for cfservd as well as cfagent.")) 74This includes those for cfservd as well as cfagent.")
75
76 (defconst cfengine3-defuns
77 (mapcar
78 'symbol-name
79 '(bundle body))
80 "List of the CFEngine 3.x defun headings.")
81
82 (defconst cfengine3-defuns-regex
83 (regexp-opt cfengine3-defuns t)
84 "Regex to match the CFEngine 3.x defuns.")
85
86 (defconst cfengine3-class-selector-regex "\\([[:alnum:]_().&|!]+\\)::")
87
88 (defconst cfengine3-category-regex "\\([[:alnum:]_]+\\):")
89
90 (defconst cfengine3-vartypes
91 (mapcar
92 'symbol-name
93 '(string int real slist ilist rlist irange rrange counter))
94 "List of the CFEngine 3.x variable types."))
67 95
68(defvar cfengine-font-lock-keywords 96(defvar cfengine-font-lock-keywords
69 `(;; Actions. 97 `(;; Actions.
@@ -82,6 +110,31 @@ This includes those for cfservd as well as cfagent."))
82 ;; File, acl &c in group: { token ... } 110 ;; File, acl &c in group: { token ... }
83 ("{[ \t]*\\([^ \t\n]+\\)" 1 font-lock-constant-face))) 111 ("{[ \t]*\\([^ \t\n]+\\)" 1 font-lock-constant-face)))
84 112
113(defvar cfengine3-font-lock-keywords
114 `(
115 (,(concat "^[ \t]*" cfengine3-class-selector-regex)
116 1 font-lock-keyword-face)
117 (,(concat "^[ \t]*" cfengine3-category-regex)
118 1 font-lock-builtin-face)
119 ;; Variables, including scope, e.g. module.var
120 ("[@$](\\([[:alnum:]_.]+\\))" 1 font-lock-variable-name-face)
121 ("[@$]{\\([[:alnum:]_.]+\\)}" 1 font-lock-variable-name-face)
122 ;; Variable definitions.
123 ("\\<\\([[:alnum:]_]+\\)[ \t]*=[ \t]*(" 1 font-lock-variable-name-face)
124
125 ;; CFEngine 3.x faces
126 ;; defuns
127 (,(concat "\\<" cfengine3-defuns-regex "\\>"
128 "[ \t]+\\<\\([[:alnum:]_]+\\)\\>"
129 "[ \t]+\\<\\([[:alnum:]_]+\\)\\((\\([^)]*\\))\\)?")
130 (1 font-lock-builtin-face)
131 (2 font-lock-constant-name-face)
132 (3 font-lock-function-name-face)
133 (5 font-lock-variable-name-face))
134 ;; variable types
135 (,(concat "\\<" (eval-when-compile (regexp-opt cfengine3-vartypes t)) "\\>")
136 1 font-lock-type-face)))
137
85(defvar cfengine-imenu-expression 138(defvar cfengine-imenu-expression
86 `((nil ,(concat "^[ \t]*" (eval-when-compile 139 `((nil ,(concat "^[ \t]*" (eval-when-compile
87 (regexp-opt cfengine-actions t)) 140 (regexp-opt cfengine-actions t))
@@ -197,6 +250,191 @@ Intended as the value of `indent-line-function'."
197 (fill-paragraph justify)) 250 (fill-paragraph justify))
198 t)) 251 t))
199 252
253(defun cfengine3-beginning-of-defun ()
254 "`beginning-of-defun' function for Cfengine 3 mode.
255Treats body/bundle blocks as defuns."
256 (unless (<= (current-column) (current-indentation))
257 (end-of-line))
258 (if (re-search-backward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t)
259 (beginning-of-line)
260 (goto-char (point-min)))
261 t)
262
263(defun cfengine3-end-of-defun ()
264 "`end-of-defun' function for Cfengine 3 mode.
265Treats body/bundle blocks as defuns."
266 (end-of-line)
267 (if (re-search-forward (concat "^[ \t]*" cfengine3-defuns-regex "\\>") nil t)
268 (beginning-of-line)
269 (goto-char (point-max)))
270 t)
271
272(defun cfengine3-indent-line ()
273 "Indent a line in Cfengine 3 mode.
274Intended as the value of `indent-line-function'."
275 (let ((pos (- (point-max) (point)))
276 parse)
277 (save-restriction
278 (narrow-to-defun)
279 (back-to-indentation)
280 (setq parse (parse-partial-sexp (point-min) (point)))
281 (message "%S" parse)
282 (cond
283 ;; body/bundle blocks start at 0
284 ((looking-at (concat cfengine3-defuns-regex "\\>"))
285 (indent-line-to 0))
286 ;; categories are indented one step
287 ((looking-at (concat cfengine3-category-regex "[ \t]*$"))
288 (indent-line-to cfengine-indent))
289 ;; class selectors are indented two steps
290 ((looking-at (concat cfengine3-class-selector-regex "[ \t]*$"))
291 (indent-line-to (* 2 cfengine-indent)))
292 ;; Outdent leading close brackets one step.
293 ((or (eq ?\} (char-after))
294 (eq ?\) (char-after)))
295 (condition-case ()
296 (indent-line-to (save-excursion
297 (forward-char)
298 (backward-sexp)
299 (current-column)))
300 (error nil)))
301 ;; inside a string and it starts before this line
302 ((and (nth 3 parse)
303 (< (nth 8 parse) (save-excursion (beginning-of-line) (point))))
304 (indent-line-to 0))
305 ;; inside a defun, but not a nested list (depth is 1)
306 ((= 1 (nth 0 parse))
307 (indent-line-to (* (+ 2 (nth 0 parse)) cfengine-indent)))
308 ;; Inside brackets/parens: indent to start column of non-comment
309 ;; token on line following open bracket or by one step from open
310 ;; bracket's column.
311 ((condition-case ()
312 (progn (indent-line-to (save-excursion
313 (backward-up-list)
314 (forward-char)
315 (skip-chars-forward " \t")
316 (cond
317 ((looking-at "[^\n#]")
318 (current-column))
319 ((looking-at "[^\n#]")
320 (current-column))
321 (t
322 (skip-chars-backward " \t")
323 (+ (current-column) -1
324 cfengine-indent)))))
325 t)
326 (error nil)))
327 ;; Else don't indent.
328 (t (indent-line-to 0))))
329 ;; If initial point was within line's indentation,
330 ;; position after the indentation. Else stay at same point in text.
331 (if (> (- (point-max) pos) (point))
332 (goto-char (- (point-max) pos)))))
333
334;; CFEngine 3.x grammar
335
336;; specification: blocks
337;; blocks: block | blocks block;
338;; block: bundle typeid blockid bundlebody
339;; | bundle typeid blockid usearglist bundlebody
340;; | body typeid blockid bodybody
341;; | body typeid blockid usearglist bodybody;
342
343;; typeid: id
344;; blockid: id
345;; usearglist: '(' aitems ')';
346;; aitems: aitem | aitem ',' aitems |;
347;; aitem: id
348
349;; bundlebody: '{' statements '}'
350;; statements: statement | statements statement;
351;; statement: category | classpromises;
352
353;; bodybody: '{' bodyattribs '}'
354;; bodyattribs: bodyattrib | bodyattribs bodyattrib;
355;; bodyattrib: class | selections;
356;; selections: selection | selections selection;
357;; selection: id ASSIGN rval ';' ;
358
359;; classpromises: classpromise | classpromises classpromise;
360;; classpromise: class | promises;
361;; promises: promise | promises promise;
362;; category: CATEGORY
363;; promise: promiser ARROW rval constraints ';' | promiser constraints ';';
364;; constraints: constraint | constraints ',' constraint |;
365;; constraint: id ASSIGN rval;
366;; class: CLASS
367;; id: ID
368;; rval: ID | QSTRING | NAKEDVAR | list | usefunction
369;; list: '{' litems '}' ;
370;; litems: litem | litem ',' litems |;
371;; litem: ID | QSTRING | NAKEDVAR | list | usefunction
372
373;; functionid: ID | NAKEDVAR
374;; promiser: QSTRING
375;; usefunction: functionid givearglist
376;; givearglist: '(' gaitems ')'
377;; gaitems: gaitem | gaitems ',' gaitem |;
378;; gaitem: ID | QSTRING | NAKEDVAR | list | usefunction
379
380;; # from lexer:
381
382;; bundle: "bundle"
383;; body: "body"
384;; COMMENT #[^\n]*
385;; NAKEDVAR [$@][(][a-zA-Z0-9_\200-\377.]+[)]|[$@][{][a-zA-Z0-9_\200-\377.]+[}]
386;; ID: [a-zA-Z0-9_\200-\377]+
387;; ASSIGN: "=>"
388;; ARROW: "->"
389;; QSTRING: \"((\\\")|[^"])*\"|\'((\\\')|[^'])*\'|`[^`]*`
390;; CLASS: [.|&!()a-zA-Z0-9_\200-\377]+::
391;; CATEGORY: [a-zA-Z_]+:
392
393(defun cfengine-common-settings ()
394 (set (make-local-variable 'syntax-propertize-function)
395 ;; In the main syntax-table, \ is marked as a punctuation, because
396 ;; of its use in DOS-style directory separators. Here we try to
397 ;; recognize the cases where \ is used as an escape inside strings.
398 (syntax-propertize-rules ("\\(\\(?:\\\\\\)+\\)\"" (1 "\\"))))
399 (set (make-local-variable 'parens-require-spaces) nil)
400 (set (make-local-variable 'comment-start) "# ")
401 (set (make-local-variable 'comment-start-skip)
402 "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*")
403 ;; Like Lisp mode. Without this, we lose with, say,
404 ;; `backward-up-list' when there's an unbalanced quote in a
405 ;; preceding comment.
406 (set (make-local-variable 'parse-sexp-ignore-comments) t))
407
408(defun cfengine-common-syntax (table)
409 ;; the syntax defaults seem OK to give reasonable word movement
410 (modify-syntax-entry ?# "<" table)
411 (modify-syntax-entry ?\n ">#" table)
412 (modify-syntax-entry ?\" "\"" table)
413 ;; variable substitution:
414 (modify-syntax-entry ?$ "." table)
415 ;; Doze path separators:
416 (modify-syntax-entry ?\\ "." table))
417
418;;;###autoload
419(define-derived-mode cfengine3-mode prog-mode "CFEngine3"
420 "Major mode for editing cfengine input.
421There are no special keybindings by default.
422
423Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves
424to the action header."
425 (cfengine-common-settings)
426 (cfengine-common-syntax cfengine3-mode-syntax-table)
427
428 (set (make-local-variable 'indent-line-function) #'cfengine3-indent-line)
429 (setq font-lock-defaults
430 '(cfengine3-font-lock-keywords nil nil nil beginning-of-defun))
431
432 ;; use defuns as the essential syntax block
433 (set (make-local-variable 'beginning-of-defun-function)
434 #'cfengine3-beginning-of-defun)
435 (set (make-local-variable 'end-of-defun-function)
436 #'cfengine3-end-of-defun))
437
200;;;###autoload 438;;;###autoload
201(define-derived-mode cfengine-mode prog-mode "Cfengine" 439(define-derived-mode cfengine-mode prog-mode "Cfengine"
202 "Major mode for editing cfengine input. 440 "Major mode for editing cfengine input.
@@ -204,25 +442,15 @@ There are no special keybindings by default.
204 442
205Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves 443Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves
206to the action header." 444to the action header."
207 (modify-syntax-entry ?# "<" cfengine-mode-syntax-table) 445 (cfengine-common-settings)
208 (modify-syntax-entry ?\n ">#" cfengine-mode-syntax-table) 446 (cfengine-common-syntax cfengine-mode-syntax-table)
447
209 ;; Shell commands can be quoted by single, double or back quotes. 448 ;; Shell commands can be quoted by single, double or back quotes.
210 ;; It's debatable whether we should define string syntax, but it 449 ;; It's debatable whether we should define string syntax, but it
211 ;; should avoid potential confusion in some cases. 450 ;; should avoid potential confusion in some cases.
212 (modify-syntax-entry ?\" "\"" cfengine-mode-syntax-table)
213 (modify-syntax-entry ?\' "\"" cfengine-mode-syntax-table) 451 (modify-syntax-entry ?\' "\"" cfengine-mode-syntax-table)
214 (modify-syntax-entry ?\` "\"" cfengine-mode-syntax-table) 452 (modify-syntax-entry ?\` "\"" cfengine-mode-syntax-table)
215 ;; variable substitution:
216 (modify-syntax-entry ?$ "." cfengine-mode-syntax-table)
217 ;; Doze path separators:
218 (modify-syntax-entry ?\\ "." cfengine-mode-syntax-table)
219 ;; Otherwise, syntax defaults seem OK to give reasonable word
220 ;; movement.
221 453
222 (set (make-local-variable 'parens-require-spaces) nil)
223 (set (make-local-variable 'comment-start) "# ")
224 (set (make-local-variable 'comment-start-skip)
225 "\\(\\(?:^\\|[^\\\\\n]\\)\\(?:\\\\\\\\\\)*\\)#+[ \t]*")
226 (set (make-local-variable 'indent-line-function) #'cfengine-indent-line) 454 (set (make-local-variable 'indent-line-function) #'cfengine-indent-line)
227 (set (make-local-variable 'outline-regexp) "[ \t]*\\(\\sw\\|\\s_\\)+:+") 455 (set (make-local-variable 'outline-regexp) "[ \t]*\\(\\sw\\|\\s_\\)+:+")
228 (set (make-local-variable 'outline-level) #'cfengine-outline-level) 456 (set (make-local-variable 'outline-level) #'cfengine-outline-level)
@@ -233,20 +461,12 @@ to the action header."
233 '(cfengine-font-lock-keywords nil nil nil beginning-of-line)) 461 '(cfengine-font-lock-keywords nil nil nil beginning-of-line))
234 ;; Fixme: set the args of functions in evaluated classes to string 462 ;; Fixme: set the args of functions in evaluated classes to string
235 ;; syntax, and then obey syntax properties. 463 ;; syntax, and then obey syntax properties.
236 (set (make-local-variable 'syntax-propertize-function)
237 ;; In the main syntax-table, \ is marked as a punctuation, because
238 ;; of its use in DOS-style directory separators. Here we try to
239 ;; recognize the cases where \ is used as an escape inside strings.
240 (syntax-propertize-rules ("\\(\\(?:\\\\\\)+\\)\"" (1 "\\"))))
241 (setq imenu-generic-expression cfengine-imenu-expression) 464 (setq imenu-generic-expression cfengine-imenu-expression)
242 (set (make-local-variable 'beginning-of-defun-function) 465 (set (make-local-variable 'beginning-of-defun-function)
243 #'cfengine-beginning-of-defun) 466 #'cfengine-beginning-of-defun)
244 (set (make-local-variable 'end-of-defun-function) #'cfengine-end-of-defun) 467 (set (make-local-variable 'end-of-defun-function) #'cfengine-end-of-defun))
245 ;; Like Lisp mode. Without this, we lose with, say,
246 ;; `backward-up-list' when there's an unbalanced quote in a
247 ;; preceding comment.
248 (set (make-local-variable 'parse-sexp-ignore-comments) t))
249 468
469(provide 'cfengine3)
250(provide 'cfengine) 470(provide 'cfengine)
251 471
252;;; cfengine.el ends here 472;;; cfengine.el ends here
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el
index 1a23cd112af..503698f0f7b 100644
--- a/lisp/progmodes/compile.el
+++ b/lisp/progmodes/compile.el
@@ -253,7 +253,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1))
253\\(?:-\\([0-9]+\\)?\\(?:\\.\\([0-9]+\\)\\)?\\)?:\ 253\\(?:-\\([0-9]+\\)?\\(?:\\.\\([0-9]+\\)\\)?\\)?:\
254\\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\ 254\\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\
255 *\\([Ii]nfo\\(?:\\>\\|rmationa?l?\\)\\|I:\\|instantiated from\\|[Nn]ote\\)\\|\ 255 *\\([Ii]nfo\\(?:\\>\\|rmationa?l?\\)\\|I:\\|instantiated from\\|[Nn]ote\\)\\|\
256\[0-9]?\\(?:[^0-9\n]\\|$\\)\\|[0-9][0-9][0-9]\\)" 256 *[Ee]rror\\|\[0-9]?\\(?:[^0-9\n]\\|$\\)\\|[0-9][0-9][0-9]\\)"
257 1 (2 . 4) (3 . 5) (6 . 7)) 257 1 (2 . 4) (3 . 5) (6 . 7))
258 258
259 (lcc 259 (lcc
@@ -400,15 +400,16 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?"
400 "^# Failed test [0-9]+ in \\([^ \t\r\n]+\\) at line \\([0-9]+\\)" 400 "^# Failed test [0-9]+ in \\([^ \t\r\n]+\\) at line \\([0-9]+\\)"
401 1 2) 401 1 2)
402 (perl--Test2 402 (perl--Test2
403 ;; Or when comparing got/want values, 403 ;; Or when comparing got/want values, with a "fail #n" if repeated
404 ;; # Test 2 got: "xx" (t-compilation-perl-2.t at line 10) 404 ;; # Test 2 got: "xx" (t-compilation-perl-2.t at line 10)
405 ;; # Test 3 got: "xx" (t-compilation-perl-2.t at line 10 fail #2)
405 ;; 406 ;;
406 ;; And under Test::Harness they're preceded by progress stuff with 407 ;; And under Test::Harness they're preceded by progress stuff with
407 ;; \r and "NOK", 408 ;; \r and "NOK",
408 ;; ... NOK 1# Test 1 got: "1234" (t/foo.t at line 46) 409 ;; ... NOK 1# Test 1 got: "1234" (t/foo.t at line 46)
409 ;; 410 ;;
410 "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^ \t\r\n]+\\) at line \ 411 "^\\(.*NOK.*\\)?# Test [0-9]+ got:.* (\\([^ \t\r\n]+\\) at line \
411\\([0-9]+\\))" 412\\([0-9]+\\)\\( fail #[0-9]+\\)?)"
412 2 3) 413 2 3)
413 (perl--Test::Harness 414 (perl--Test::Harness
414 ;; perl Test::Harness output, eg. 415 ;; perl Test::Harness output, eg.
@@ -2409,9 +2410,7 @@ and overlay is highlighted between MK and END-MK."
2409 ;; display the source in another window. 2410 ;; display the source in another window.
2410 (let ((pop-up-windows t)) 2411 (let ((pop-up-windows t))
2411 (pop-to-buffer (marker-buffer mk) 'other-window)) 2412 (pop-to-buffer (marker-buffer mk) 'other-window))
2412 (if (window-dedicated-p (selected-window)) 2413 (pop-to-buffer-same-window (marker-buffer mk)))
2413 (pop-to-buffer (marker-buffer mk))
2414 (switch-to-buffer (marker-buffer mk))))
2415 (unless (eq (goto-char mk) (point)) 2414 (unless (eq (goto-char mk) (point))
2416 ;; If narrowing gets in the way of going to the right place, widen. 2415 ;; If narrowing gets in the way of going to the right place, widen.
2417 (widen) 2416 (widen)
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el
index 48df73a678f..ad3b777977c 100644
--- a/lisp/progmodes/cperl-mode.el
+++ b/lisp/progmodes/cperl-mode.el
@@ -613,7 +613,7 @@ One should tune up `cperl-close-paren-offset' as well."
613(defcustom cperl-syntaxify-by-font-lock 613(defcustom cperl-syntaxify-by-font-lock
614 (and cperl-can-font-lock 614 (and cperl-can-font-lock
615 (boundp 'parse-sexp-lookup-properties)) 615 (boundp 'parse-sexp-lookup-properties))
616 "*Non-nil means that CPerl uses `font-lock's routines for syntaxification." 616 "*Non-nil means that CPerl uses the `font-lock' routines for syntaxification."
617 :type '(choice (const message) boolean) 617 :type '(choice (const message) boolean)
618 :group 'cperl-speed) 618 :group 'cperl-speed)
619 619
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el
index 8abf298bb76..385adf1af0a 100644
--- a/lisp/progmodes/etags.el
+++ b/lisp/progmodes/etags.el
@@ -1860,7 +1860,11 @@ nil, we exit; otherwise we scan the next file."
1860Stops when a match is found. 1860Stops when a match is found.
1861To continue searching for next match, use command \\[tags-loop-continue]. 1861To continue searching for next match, use command \\[tags-loop-continue].
1862 1862
1863See documentation of variable `tags-file-name'." 1863If `file-list-form' is non-nil, it should be a form that, when
1864evaluated, will return a list of file names. The search will be
1865restricted to these files.
1866
1867Aleso see the documentation of the `tags-file-name' variable."
1864 (interactive "sTags search (regexp): ") 1868 (interactive "sTags search (regexp): ")
1865 (if (and (equal regexp "") 1869 (if (and (equal regexp "")
1866 (eq (car tags-loop-scan) 're-search-forward) 1870 (eq (car tags-loop-scan) 're-search-forward)
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el
index 8f617b44dae..1c138f053d3 100644
--- a/lisp/progmodes/flymake.el
+++ b/lisp/progmodes/flymake.el
@@ -1339,8 +1339,12 @@ With arg, turn Flymake mode on if and only if arg is positive."
1339 1339
1340 ;; Turning the mode ON. 1340 ;; Turning the mode ON.
1341 (flymake-mode 1341 (flymake-mode
1342 (if (not (flymake-can-syntax-check-file buffer-file-name)) 1342 (cond
1343 (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)) 1343 ((not buffer-file-name)
1344 (message "Flymake unable to run without a buffer file name"))
1345 ((not (flymake-can-syntax-check-file buffer-file-name))
1346 (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)))
1347 (t
1344 (add-hook 'after-change-functions 'flymake-after-change-function nil t) 1348 (add-hook 'after-change-functions 'flymake-after-change-function nil t)
1345 (add-hook 'after-save-hook 'flymake-after-save-hook nil t) 1349 (add-hook 'after-save-hook 'flymake-after-save-hook nil t)
1346 (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t) 1350 (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook nil t)
@@ -1352,7 +1356,7 @@ With arg, turn Flymake mode on if and only if arg is positive."
1352 (run-at-time nil 1 'flymake-on-timer-event (current-buffer))) 1356 (run-at-time nil 1 'flymake-on-timer-event (current-buffer)))
1353 1357
1354 (when flymake-start-syntax-check-on-find-file 1358 (when flymake-start-syntax-check-on-find-file
1355 (flymake-start-syntax-check)))) 1359 (flymake-start-syntax-check)))))
1356 1360
1357 ;; Turning the mode OFF. 1361 ;; Turning the mode OFF.
1358 (t 1362 (t
@@ -1406,6 +1410,7 @@ With arg, turn Flymake mode on if and only if arg is positive."
1406 (cancel-timer flymake-timer) 1410 (cancel-timer flymake-timer)
1407 (setq flymake-timer nil))) 1411 (setq flymake-timer nil)))
1408 1412
1413;;;###autoload
1409(defun flymake-find-file-hook () 1414(defun flymake-find-file-hook ()
1410 ;;+(when flymake-start-syntax-check-on-find-file 1415 ;;+(when flymake-start-syntax-check-on-find-file
1411 ;;+ (flymake-log 3 "starting syntax check on file open") 1416 ;;+ (flymake-log 3 "starting syntax check on file open")
diff --git a/lisp/progmodes/gdb-mi.el b/lisp/progmodes/gdb-mi.el
index 61055ef4342..87209a78ffb 100644
--- a/lisp/progmodes/gdb-mi.el
+++ b/lisp/progmodes/gdb-mi.el
@@ -104,7 +104,8 @@
104(require 'bindat) 104(require 'bindat)
105(eval-when-compile (require 'cl)) 105(eval-when-compile (require 'cl))
106 106
107(declare-function speedbar-change-initial-expansion-list "speedbar" (new-default)) 107(declare-function speedbar-change-initial-expansion-list
108 "speedbar" (new-default))
108(declare-function speedbar-timer-fn "speedbar" ()) 109(declare-function speedbar-timer-fn "speedbar" ())
109(declare-function speedbar-line-text "speedbar" (&optional p)) 110(declare-function speedbar-line-text "speedbar" (&optional p))
110(declare-function speedbar-change-expand-button-char "speedbar" (char)) 111(declare-function speedbar-change-expand-button-char "speedbar" (char))
@@ -190,7 +191,8 @@ as returned from \"-break-list\" by `gdb-json-partial-output'
190(defvar gdb-current-language nil) 191(defvar gdb-current-language nil)
191(defvar gdb-var-list nil 192(defvar gdb-var-list nil
192 "List of variables in watch window. 193 "List of variables in watch window.
193Each element has the form (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS HAS_MORE FP) 194Each element has the form
195 (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS HAS_MORE FP)
194where STATUS is nil (`unchanged'), `changed' or `out-of-scope', FP the frame 196where STATUS is nil (`unchanged'), `changed' or `out-of-scope', FP the frame
195address for root variables.") 197address for root variables.")
196(defvar gdb-main-file nil "Source file from which program execution begins.") 198(defvar gdb-main-file nil "Source file from which program execution begins.")
@@ -329,7 +331,7 @@ valid signal handlers.")
329 "Maximum size of `gdb-debug-log'. If nil, size is unlimited." 331 "Maximum size of `gdb-debug-log'. If nil, size is unlimited."
330 :group 'gdb 332 :group 'gdb
331 :type '(choice (integer :tag "Number of elements") 333 :type '(choice (integer :tag "Number of elements")
332 (const :tag "Unlimited" nil)) 334 (const :tag "Unlimited" nil))
333 :version "22.1") 335 :version "22.1")
334 336
335(defcustom gdb-non-stop-setting t 337(defcustom gdb-non-stop-setting t
@@ -367,13 +369,18 @@ Emacs always switches to the thread which caused the stop."
367 (set :tag "Selection of reasons..." 369 (set :tag "Selection of reasons..."
368 (const :tag "A breakpoint was reached." "breakpoint-hit") 370 (const :tag "A breakpoint was reached." "breakpoint-hit")
369 (const :tag "A watchpoint was triggered." "watchpoint-trigger") 371 (const :tag "A watchpoint was triggered." "watchpoint-trigger")
370 (const :tag "A read watchpoint was triggered." "read-watchpoint-trigger") 372 (const :tag "A read watchpoint was triggered."
371 (const :tag "An access watchpoint was triggered." "access-watchpoint-trigger") 373 "read-watchpoint-trigger")
374 (const :tag "An access watchpoint was triggered."
375 "access-watchpoint-trigger")
372 (const :tag "Function finished execution." "function-finished") 376 (const :tag "Function finished execution." "function-finished")
373 (const :tag "Location reached." "location-reached") 377 (const :tag "Location reached." "location-reached")
374 (const :tag "Watchpoint has gone out of scope" "watchpoint-scope") 378 (const :tag "Watchpoint has gone out of scope"
375 (const :tag "End of stepping range reached." "end-stepping-range") 379 "watchpoint-scope")
376 (const :tag "Signal received (like interruption)." "signal-received")) 380 (const :tag "End of stepping range reached."
381 "end-stepping-range")
382 (const :tag "Signal received (like interruption)."
383 "signal-received"))
377 (const :tag "None" nil)) 384 (const :tag "None" nil))
378 :group 'gdb-non-stop 385 :group 'gdb-non-stop
379 :version "23.2" 386 :version "23.2"
@@ -488,17 +495,17 @@ predefined macros."
488 :group 'gdb 495 :group 'gdb
489 :version "22.1") 496 :version "22.1")
490 497
491 (defcustom gdb-create-source-file-list t 498(defcustom gdb-create-source-file-list t
492 "Non-nil means create a list of files from which the executable was built. 499 "Non-nil means create a list of files from which the executable was built.
493 Set this to nil if the GUD buffer displays \"initializing...\" in the mode 500 Set this to nil if the GUD buffer displays \"initializing...\" in the mode
494 line for a long time when starting, possibly because your executable was 501 line for a long time when starting, possibly because your executable was
495 built from a large number of files. This allows quicker initialization 502 built from a large number of files. This allows quicker initialization
496 but means that these files are not automatically enabled for debugging, 503 but means that these files are not automatically enabled for debugging,
497 e.g., you won't be able to click in the fringe to set a breakpoint until 504 e.g., you won't be able to click in the fringe to set a breakpoint until
498 execution has already stopped there." 505 execution has already stopped there."
499 :type 'boolean 506 :type 'boolean
500 :group 'gdb 507 :group 'gdb
501 :version "23.1") 508 :version "23.1")
502 509
503(defcustom gdb-show-main nil 510(defcustom gdb-show-main nil
504 "Non-nil means display source file containing the main routine at startup. 511 "Non-nil means display source file containing the main routine at startup.
@@ -644,12 +651,12 @@ detailed description of this mode.
644 (interactive (list (gud-query-cmdline 'gdb))) 651 (interactive (list (gud-query-cmdline 'gdb)))
645 652
646 (when (and gud-comint-buffer 653 (when (and gud-comint-buffer
647 (buffer-name gud-comint-buffer) 654 (buffer-name gud-comint-buffer)
648 (get-buffer-process gud-comint-buffer) 655 (get-buffer-process gud-comint-buffer)
649 (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba))) 656 (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)))
650 (gdb-restore-windows) 657 (gdb-restore-windows)
651 (error 658 (error
652 "Multiple debugging requires restarting in text command mode")) 659 "Multiple debugging requires restarting in text command mode"))
653 ;; 660 ;;
654 (gud-common-init command-line nil 'gud-gdbmi-marker-filter) 661 (gud-common-init command-line nil 'gud-gdbmi-marker-filter)
655 (set (make-local-variable 'gud-minor-mode) 'gdbmi) 662 (set (make-local-variable 'gud-minor-mode) 'gdbmi)
@@ -663,7 +670,7 @@ detailed description of this mode.
663 (hsize (getenv "HISTSIZE"))) 670 (hsize (getenv "HISTSIZE")))
664 (dolist (file (append '("~/.gdbinit") 671 (dolist (file (append '("~/.gdbinit")
665 (unless (string-equal (expand-file-name ".") 672 (unless (string-equal (expand-file-name ".")
666 (expand-file-name "~")) 673 (expand-file-name "~"))
667 '(".gdbinit")))) 674 '(".gdbinit"))))
668 (if (file-readable-p (setq file (expand-file-name file))) 675 (if (file-readable-p (setq file (expand-file-name file)))
669 (with-temp-buffer 676 (with-temp-buffer
@@ -763,7 +770,7 @@ detailed description of this mode.
763 'gdb-mouse-set-clear-breakpoint) 770 'gdb-mouse-set-clear-breakpoint)
764 (define-key gud-minor-mode-map [left-fringe mouse-1] 771 (define-key gud-minor-mode-map [left-fringe mouse-1]
765 'gdb-mouse-set-clear-breakpoint) 772 'gdb-mouse-set-clear-breakpoint)
766 (define-key gud-minor-mode-map [left-margin C-mouse-1] 773 (define-key gud-minor-mode-map [left-margin C-mouse-1]
767 'gdb-mouse-toggle-breakpoint-margin) 774 'gdb-mouse-toggle-breakpoint-margin)
768 (define-key gud-minor-mode-map [left-fringe C-mouse-1] 775 (define-key gud-minor-mode-map [left-fringe C-mouse-1]
769 'gdb-mouse-toggle-breakpoint-fringe) 776 'gdb-mouse-toggle-breakpoint-fringe)
@@ -786,7 +793,10 @@ detailed description of this mode.
786 (define-key gud-minor-mode-map [left-margin C-mouse-3] 793 (define-key gud-minor-mode-map [left-margin C-mouse-3]
787 'gdb-mouse-jump) 794 'gdb-mouse-jump)
788 795
789 (local-set-key "\C-i" 'gud-gdb-complete-command) 796 (add-hook 'completion-at-point-functions #'gud-gdb-completion-at-point
797 nil 'local)
798 (local-set-key "\C-i" 'completion-at-point)
799
790 (setq gdb-first-prompt t) 800 (setq gdb-first-prompt t)
791 (setq gud-running nil) 801 (setq gud-running nil)
792 802
@@ -846,11 +856,11 @@ detailed description of this mode.
846 856
847 ;; find source file and compilation directory here 857 ;; find source file and compilation directory here
848 (gdb-input 858 (gdb-input
849 ; Needs GDB 6.2 onwards. 859 ; Needs GDB 6.2 onwards.
850 (list "-file-list-exec-source-files" 'gdb-get-source-file-list)) 860 (list "-file-list-exec-source-files" 'gdb-get-source-file-list))
851 (if gdb-create-source-file-list 861 (if gdb-create-source-file-list
852 (gdb-input 862 (gdb-input
853 ; Needs GDB 6.0 onwards. 863 ; Needs GDB 6.0 onwards.
854 (list "-file-list-exec-source-file" 'gdb-get-source-file))) 864 (list "-file-list-exec-source-file" 'gdb-get-source-file)))
855 (gdb-input 865 (gdb-input
856 (list "-gdb-show prompt" 'gdb-get-prompt))) 866 (list "-gdb-show prompt" 'gdb-get-prompt)))
@@ -859,7 +869,8 @@ detailed description of this mode.
859 (goto-char (point-min)) 869 (goto-char (point-min))
860 (if (re-search-forward "No symbol" nil t) 870 (if (re-search-forward "No symbol" nil t)
861 (progn 871 (progn
862 (message "This version of GDB doesn't support non-stop mode. Turning it off.") 872 (message
873 "This version of GDB doesn't support non-stop mode. Turning it off.")
863 (setq gdb-non-stop nil) 874 (setq gdb-non-stop nil)
864 (setq gdb-version "pre-7.0")) 875 (setq gdb-version "pre-7.0"))
865 (setq gdb-version "7.0+") 876 (setq gdb-version "7.0+")
@@ -882,8 +893,8 @@ detailed description of this mode.
882 (list t nil) nil "-c" 893 (list t nil) nil "-c"
883 (concat gdb-cpp-define-alist-program " " 894 (concat gdb-cpp-define-alist-program " "
884 gdb-cpp-define-alist-flags)))))) 895 gdb-cpp-define-alist-flags))))))
885 (define-list (split-string output "\n" t)) 896 (define-list (split-string output "\n" t))
886 (name)) 897 (name))
887 (setq gdb-define-alist nil) 898 (setq gdb-define-alist nil)
888 (dolist (define define-list) 899 (dolist (define define-list)
889 (setq name (nth 1 (split-string define "[( ]"))) 900 (setq name (nth 1 (split-string define "[( ]")))
@@ -893,13 +904,13 @@ detailed description of this mode.
893(defvar tooltip-use-echo-area) 904(defvar tooltip-use-echo-area)
894 905
895(defun gdb-tooltip-print (expr) 906(defun gdb-tooltip-print (expr)
896 (with-current-buffer (gdb-get-buffer 'gdb-partial-output-buffer) 907 (with-current-buffer (gdb-get-buffer 'gdb-partial-output-buffer)
897 (goto-char (point-min)) 908 (goto-char (point-min))
898 (if (re-search-forward ".*value=\\(\".*\"\\)" nil t) 909 (if (re-search-forward ".*value=\\(\".*\"\\)" nil t)
899 (tooltip-show 910 (tooltip-show
900 (concat expr " = " (read (match-string 1))) 911 (concat expr " = " (read (match-string 1)))
901 (or gud-tooltip-echo-area tooltip-use-echo-area 912 (or gud-tooltip-echo-area tooltip-use-echo-area
902 (not (display-graphic-p))))))) 913 (not (display-graphic-p)))))))
903 914
904;; If expr is a macro for a function don't print because of possible dangerous 915;; If expr is a macro for a function don't print because of possible dangerous
905;; side-effects. Also printing a function within a tooltip generates an 916;; side-effects. Also printing a function within a tooltip generates an
@@ -923,13 +934,13 @@ detailed description of this mode.
923 934
924(defmacro gdb-if-arrow (arrow-position &rest body) 935(defmacro gdb-if-arrow (arrow-position &rest body)
925 `(if ,arrow-position 936 `(if ,arrow-position
926 (let ((buffer (marker-buffer ,arrow-position)) (line)) 937 (let ((buffer (marker-buffer ,arrow-position)) (line))
927 (if (equal buffer (window-buffer (posn-window end))) 938 (if (equal buffer (window-buffer (posn-window end)))
928 (with-current-buffer buffer 939 (with-current-buffer buffer
929 (when (or (equal start end) 940 (when (or (equal start end)
930 (equal (posn-point start) 941 (equal (posn-point start)
931 (marker-position ,arrow-position))) 942 (marker-position ,arrow-position)))
932 ,@body)))))) 943 ,@body))))))
933 944
934(defun gdb-mouse-until (event) 945(defun gdb-mouse-until (event)
935 "Continue running until a source line past the current line. 946 "Continue running until a source line past the current line.
@@ -1060,7 +1071,7 @@ With arg, enter name of variable to be watched in the minibuffer."
1060 (bindat-get-field result 'value) 1071 (bindat-get-field result 'value)
1061 nil 1072 nil
1062 (bindat-get-field result 'has_more) 1073 (bindat-get-field result 'has_more)
1063 gdb-frame-address))) 1074 gdb-frame-address)))
1064 (push var gdb-var-list) 1075 (push var gdb-var-list)
1065 (speedbar 1) 1076 (speedbar 1)
1066 (unless (string-equal 1077 (unless (string-equal
@@ -1091,20 +1102,20 @@ With arg, enter name of variable to be watched in the minibuffer."
1091 (setcar (nthcdr 4 var) (read (match-string 1))))) 1102 (setcar (nthcdr 4 var) (read (match-string 1)))))
1092 (gdb-speedbar-update)) 1103 (gdb-speedbar-update))
1093 1104
1094; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards. 1105 ; Uses "-var-list-children --all-values". Needs GDB 6.1 onwards.
1095(defun gdb-var-list-children (varnum) 1106(defun gdb-var-list-children (varnum)
1096 (gdb-input 1107 (gdb-input
1097 (list (concat "-var-update " varnum) 'ignore)) 1108 (list (concat "-var-update " varnum) 'ignore))
1098 (gdb-input 1109 (gdb-input
1099 (list (concat "-var-list-children --all-values " 1110 (list (concat "-var-list-children --all-values "
1100 varnum) 1111 varnum)
1101 `(lambda () (gdb-var-list-children-handler ,varnum))))) 1112 `(lambda () (gdb-var-list-children-handler ,varnum)))))
1102 1113
1103(defun gdb-var-list-children-handler (varnum) 1114(defun gdb-var-list-children-handler (varnum)
1104 (let* ((var-list nil) 1115 (let* ((var-list nil)
1105 (output (bindat-get-field (gdb-json-partial-output "child"))) 1116 (output (bindat-get-field (gdb-json-partial-output "child")))
1106 (children (bindat-get-field output 'children))) 1117 (children (bindat-get-field output 'children)))
1107 (catch 'child-already-watched 1118 (catch 'child-already-watched
1108 (dolist (var gdb-var-list) 1119 (dolist (var gdb-var-list)
1109 (if (string-equal varnum (car var)) 1120 (if (string-equal varnum (car var))
1110 (progn 1121 (progn
@@ -1147,11 +1158,11 @@ With arg, enter name of variable to be watched in the minibuffer."
1147 (interactive) 1158 (interactive)
1148 (let ((text (speedbar-line-text))) 1159 (let ((text (speedbar-line-text)))
1149 (string-match "\\(\\S-+\\)" text) 1160 (string-match "\\(\\S-+\\)" text)
1150 (let* ((var (nth (- (count-lines (point-min) (point)) 2) gdb-var-list)) 1161 (let* ((var (nth (- (count-lines (point-min) (point)) 2) gdb-var-list))
1151 (varnum (car var))) 1162 (varnum (car var)))
1152 (if (string-match "\\." (car var)) 1163 (if (string-match "\\." (car var))
1153 (message-box "Can only delete a root expression") 1164 (message-box "Can only delete a root expression")
1154 (gdb-var-delete-1 var varnum))))) 1165 (gdb-var-delete-1 var varnum)))))
1155 1166
1156(defun gdb-var-delete-children (varnum) 1167(defun gdb-var-delete-children (varnum)
1157 "Delete children of variable object at point from the speedbar." 1168 "Delete children of variable object at point from the speedbar."
@@ -1174,7 +1185,7 @@ With arg, enter name of variable to be watched in the minibuffer."
1174 (if (re-search-forward gdb-error-regexp nil t) 1185 (if (re-search-forward gdb-error-regexp nil t)
1175 (message-box "Invalid number or expression (%s)" value))) 1186 (message-box "Invalid number or expression (%s)" value)))
1176 1187
1177; Uses "-var-update --all-values". Needs GDB 6.4 onwards. 1188 ; Uses "-var-update --all-values". Needs GDB 6.4 onwards.
1178(defun gdb-var-update () 1189(defun gdb-var-update ()
1179 (if (not (gdb-pending-p 'gdb-var-update)) 1190 (if (not (gdb-pending-p 'gdb-var-update))
1180 (gdb-input 1191 (gdb-input
@@ -1210,38 +1221,38 @@ With arg, enter name of variable to be watched in the minibuffer."
1210 (gdb-var-delete-1 var varnum))))) 1221 (gdb-var-delete-1 var varnum)))))
1211 (let ((var-list nil) var1 1222 (let ((var-list nil) var1
1212 (children (bindat-get-field change 'new_children))) 1223 (children (bindat-get-field change 'new_children)))
1213 (if new-num 1224 (when new-num
1214 (progn 1225 (setq var1 (pop temp-var-list))
1215 (setq var1 (pop temp-var-list)) 1226 (while var1
1216 (while var1 1227 (if (string-equal varnum (car var1))
1217 (if (string-equal varnum (car var1)) 1228 (let ((new (string-to-number new-num))
1218 (let ((new (string-to-number new-num)) 1229 (previous (string-to-number (nth 2 var1))))
1219 (previous (string-to-number (nth 2 var1)))) 1230 (setcar (nthcdr 2 var1) new-num)
1220 (setcar (nthcdr 2 var1) new-num) 1231 (push var1 var-list)
1221 (push var1 var-list) 1232 (cond
1222 (cond ((> new previous) 1233 ((> new previous)
1223 ;; Add new children to list. 1234 ;; Add new children to list.
1224 (dotimes (dummy previous) 1235 (dotimes (dummy previous)
1225 (push (pop temp-var-list) var-list)) 1236 (push (pop temp-var-list) var-list))
1226 (dolist (child children) 1237 (dolist (child children)
1227 (let ((varchild 1238 (let ((varchild
1228 (list (bindat-get-field child 'name) 1239 (list (bindat-get-field child 'name)
1229 (bindat-get-field child 'exp) 1240 (bindat-get-field child 'exp)
1230 (bindat-get-field child 'numchild) 1241 (bindat-get-field child 'numchild)
1231 (bindat-get-field child 'type) 1242 (bindat-get-field child 'type)
1232 (bindat-get-field child 'value) 1243 (bindat-get-field child 'value)
1233 'changed 1244 'changed
1234 (bindat-get-field child 'has_more)))) 1245 (bindat-get-field child 'has_more))))
1235 (push varchild var-list)))) 1246 (push varchild var-list))))
1236 ;; Remove deleted children from list. 1247 ;; Remove deleted children from list.
1237 ((< new previous) 1248 ((< new previous)
1238 (dotimes (dummy new) 1249 (dotimes (dummy new)
1239 (push (pop temp-var-list) var-list)) 1250 (push (pop temp-var-list) var-list))
1240 (dotimes (dummy (- previous new)) 1251 (dotimes (dummy (- previous new))
1241 (pop temp-var-list))))) 1252 (pop temp-var-list)))))
1242 (push var1 var-list)) 1253 (push var1 var-list))
1243 (setq var1 (pop temp-var-list))) 1254 (setq var1 (pop temp-var-list)))
1244 (setq gdb-var-list (nreverse var-list))))))))) 1255 (setq gdb-var-list (nreverse var-list))))))))
1245 (setq gdb-pending-triggers 1256 (setq gdb-pending-triggers
1246 (delq 'gdb-var-update gdb-pending-triggers)) 1257 (delq 'gdb-var-update gdb-pending-triggers))
1247 (gdb-speedbar-update)) 1258 (gdb-speedbar-update))
@@ -1369,7 +1380,8 @@ this trigger is subscribed to `gdb-buf-publisher' and called with
1369 (when trigger 1380 (when trigger
1370 (gdb-add-subscriber gdb-buf-publisher 1381 (gdb-add-subscriber gdb-buf-publisher
1371 (cons (current-buffer) 1382 (cons (current-buffer)
1372 (gdb-bind-function-to-buffer trigger (current-buffer)))) 1383 (gdb-bind-function-to-buffer
1384 trigger (current-buffer))))
1373 (funcall trigger 'start)) 1385 (funcall trigger 'start))
1374 (current-buffer)))))) 1386 (current-buffer))))))
1375 1387
@@ -1783,8 +1795,8 @@ is running."
1783;; visited breakpoint is, use that window. 1795;; visited breakpoint is, use that window.
1784(defun gdb-display-source-buffer (buffer) 1796(defun gdb-display-source-buffer (buffer)
1785 (let* ((last-window (if gud-last-last-frame 1797 (let* ((last-window (if gud-last-last-frame
1786 (get-buffer-window 1798 (get-buffer-window
1787 (gud-find-file (car gud-last-last-frame))))) 1799 (gud-find-file (car gud-last-last-frame)))))
1788 (source-window (or last-window 1800 (source-window (or last-window
1789 (if (and gdb-source-window 1801 (if (and gdb-source-window
1790 (window-live-p gdb-source-window)) 1802 (window-live-p gdb-source-window))
@@ -1857,7 +1869,7 @@ is running."
1857 ;; Suppress "No registers." since GDB 6.8 and earlier duplicates MI 1869 ;; Suppress "No registers." since GDB 6.8 and earlier duplicates MI
1858 ;; error message on internal stream. Don't print to GUD buffer. 1870 ;; error message on internal stream. Don't print to GUD buffer.
1859 (unless (and (eq record-type 'gdb-internals) 1871 (unless (and (eq record-type 'gdb-internals)
1860 (string-equal (read arg1) "No registers.\n")) 1872 (string-equal (read arg1) "No registers.\n"))
1861 (funcall record-type arg1)))))) 1873 (funcall record-type arg1))))))
1862 1874
1863 (setq gdb-output-sink 'user) 1875 (setq gdb-output-sink 'user)
@@ -1881,15 +1893,15 @@ is running."
1881(defun gdb-thread-exited (output-field) 1893(defun gdb-thread-exited (output-field)
1882 "Handle =thread-exited async record: unset `gdb-thread-number' 1894 "Handle =thread-exited async record: unset `gdb-thread-number'
1883 if current thread exited and update threads list." 1895 if current thread exited and update threads list."
1884 (let* ((thread-id (bindat-get-field (gdb-json-string output-field) 'id))) 1896 (let* ((thread-id (bindat-get-field (gdb-json-string output-field) 'id)))
1885 (if (string= gdb-thread-number thread-id) 1897 (if (string= gdb-thread-number thread-id)
1886 (gdb-setq-thread-number nil)) 1898 (gdb-setq-thread-number nil))
1887 ;; When we continue current thread and it quickly exits, 1899 ;; When we continue current thread and it quickly exits,
1888 ;; gdb-pending-triggers left after gdb-running disallow us to 1900 ;; gdb-pending-triggers left after gdb-running disallow us to
1889 ;; properly call -thread-info without --thread option. Thus we 1901 ;; properly call -thread-info without --thread option. Thus we
1890 ;; need to use gdb-wait-for-pending. 1902 ;; need to use gdb-wait-for-pending.
1891 (gdb-wait-for-pending 1903 (gdb-wait-for-pending
1892 (gdb-emit-signal gdb-buf-publisher 'update-threads)))) 1904 (gdb-emit-signal gdb-buf-publisher 'update-threads))))
1893 1905
1894(defun gdb-thread-selected (output-field) 1906(defun gdb-thread-selected (output-field)
1895 "Handler for =thread-selected MI output record. 1907 "Handler for =thread-selected MI output record.
@@ -1909,7 +1921,8 @@ Sets `gdb-thread-number' to new id."
1909 (gdb-update)))) 1921 (gdb-update))))
1910 1922
1911(defun gdb-running (output-field) 1923(defun gdb-running (output-field)
1912 (let* ((thread-id (bindat-get-field (gdb-json-string output-field) 'thread-id))) 1924 (let* ((thread-id
1925 (bindat-get-field (gdb-json-string output-field) 'thread-id)))
1913 ;; We reset gdb-frame-number to nil if current thread has gone 1926 ;; We reset gdb-frame-number to nil if current thread has gone
1914 ;; running. This can't be done in gdb-thread-list-handler-custom 1927 ;; running. This can't be done in gdb-thread-list-handler-custom
1915 ;; because we need correct gdb-frame-number by the time 1928 ;; because we need correct gdb-frame-number by the time
@@ -1984,23 +1997,23 @@ current thread and update GDB buffers."
1984 ;; reasons 1997 ;; reasons
1985 (if (or (eq gdb-switch-reasons t) 1998 (if (or (eq gdb-switch-reasons t)
1986 (member reason gdb-switch-reasons)) 1999 (member reason gdb-switch-reasons))
1987 (when (not (string-equal gdb-thread-number thread-id)) 2000 (when (not (string-equal gdb-thread-number thread-id))
1988 (message (concat "Switched to thread " thread-id)) 2001 (message (concat "Switched to thread " thread-id))
1989 (gdb-setq-thread-number thread-id)) 2002 (gdb-setq-thread-number thread-id))
1990 (message (format "Thread %s stopped" thread-id))))) 2003 (message (format "Thread %s stopped" thread-id)))))
1991 2004
1992 ;; Print "(gdb)" to GUD console 2005 ;; Print "(gdb)" to GUD console
1993 (when gdb-first-done-or-error 2006 (when gdb-first-done-or-error
1994 (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name))) 2007 (setq gdb-filter-output (concat gdb-filter-output gdb-prompt-name)))
1995 2008
1996 ;; In non-stop, we update information as soon as another thread gets 2009 ;; In non-stop, we update information as soon as another thread gets
1997 ;; stopped 2010 ;; stopped
1998 (when (or gdb-first-done-or-error 2011 (when (or gdb-first-done-or-error
1999 gdb-non-stop) 2012 gdb-non-stop)
2000 ;; In all-stop this updates gud-running properly as well. 2013 ;; In all-stop this updates gud-running properly as well.
2001 (gdb-update) 2014 (gdb-update)
2002 (setq gdb-first-done-or-error nil)) 2015 (setq gdb-first-done-or-error nil))
2003 (run-hook-with-args 'gdb-stopped-hooks result))) 2016 (run-hook-with-args 'gdb-stopped-hooks result)))
2004 2017
2005;; Remove the trimmings from log stream containing debugging messages 2018;; Remove the trimmings from log stream containing debugging messages
2006;; being produced by GDB's internals, use warning face and send to GUD 2019;; being produced by GDB's internals, use warning face and send to GUD
@@ -2020,7 +2033,7 @@ current thread and update GDB buffers."
2020;; Remove the trimmings from the console stream and send to GUD buffer 2033;; Remove the trimmings from the console stream and send to GUD buffer
2021;; (frontend MI commands should not print to this stream) 2034;; (frontend MI commands should not print to this stream)
2022(defun gdb-console (output-field) 2035(defun gdb-console (output-field)
2023 (setq gdb-filter-output 2036 (setq gdb-filter-output
2024 (gdb-concat-output 2037 (gdb-concat-output
2025 gdb-filter-output 2038 gdb-filter-output
2026 (read output-field)))) 2039 (read output-field))))
@@ -2033,11 +2046,11 @@ current thread and update GDB buffers."
2033 (setq token-number nil) 2046 (setq token-number nil)
2034 ;; MI error - send to minibuffer 2047 ;; MI error - send to minibuffer
2035 (when (eq type 'error) 2048 (when (eq type 'error)
2036 ;; Skip "msg=" from `output-field' 2049 ;; Skip "msg=" from `output-field'
2037 (message (read (substring output-field 4))) 2050 (message (read (substring output-field 4)))
2038 ;; Don't send to the console twice. (If it is a console error 2051 ;; Don't send to the console twice. (If it is a console error
2039 ;; it is also in the console stream.) 2052 ;; it is also in the console stream.)
2040 (setq output-field nil))) 2053 (setq output-field nil)))
2041 ;; Output from command from frontend. 2054 ;; Output from command from frontend.
2042 (setq gdb-output-sink 'emacs)) 2055 (setq gdb-output-sink 'emacs))
2043 2056
@@ -2215,11 +2228,11 @@ calling `gdb-table-string'."
2215 (append row-properties (list properties))) 2228 (append row-properties (list properties)))
2216 (setf (gdb-table-column-sizes table) 2229 (setf (gdb-table-column-sizes table)
2217 (gdb-mapcar* (lambda (x s) 2230 (gdb-mapcar* (lambda (x s)
2218 (let ((new-x 2231 (let ((new-x
2219 (max (abs x) (string-width (or s ""))))) 2232 (max (abs x) (string-width (or s "")))))
2220 (if right-align new-x (- new-x)))) 2233 (if right-align new-x (- new-x))))
2221 (gdb-table-column-sizes table) 2234 (gdb-table-column-sizes table)
2222 row)) 2235 row))
2223 ;; Avoid trailing whitespace at eol 2236 ;; Avoid trailing whitespace at eol
2224 (if (not (gdb-table-right-align table)) 2237 (if (not (gdb-table-right-align table))
2225 (setcar (last (gdb-table-column-sizes table)) 0)))) 2238 (setcar (last (gdb-table-column-sizes table)) 0))))
@@ -2308,8 +2321,8 @@ If NOPRESERVE is non-nil, window point is not restored after CUSTOM-DEFUN."
2308 '(set-window-point window p))))) 2321 '(set-window-point window p)))))
2309 2322
2310(defmacro def-gdb-trigger-and-handler (trigger-name gdb-command 2323(defmacro def-gdb-trigger-and-handler (trigger-name gdb-command
2311 handler-name custom-defun 2324 handler-name custom-defun
2312 &optional signal-list) 2325 &optional signal-list)
2313 "Define trigger and handler. 2326 "Define trigger and handler.
2314 2327
2315TRIGGER-NAME trigger is defined to send GDB-COMMAND. See 2328TRIGGER-NAME trigger is defined to send GDB-COMMAND. See
@@ -2353,29 +2366,29 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
2353 (pending (bindat-get-field breakpoint 'pending)) 2366 (pending (bindat-get-field breakpoint 'pending))
2354 (func (bindat-get-field breakpoint 'func)) 2367 (func (bindat-get-field breakpoint 'func))
2355 (type (bindat-get-field breakpoint 'type))) 2368 (type (bindat-get-field breakpoint 'type)))
2356 (gdb-table-add-row table 2369 (gdb-table-add-row table
2357 (list 2370 (list
2358 (bindat-get-field breakpoint 'number) 2371 (bindat-get-field breakpoint 'number)
2359 type 2372 type
2360 (bindat-get-field breakpoint 'disp) 2373 (bindat-get-field breakpoint 'disp)
2361 (let ((flag (bindat-get-field breakpoint 'enabled))) 2374 (let ((flag (bindat-get-field breakpoint 'enabled)))
2362 (if (string-equal flag "y") 2375 (if (string-equal flag "y")
2363 (propertize "y" 'font-lock-face font-lock-warning-face) 2376 (propertize "y" 'font-lock-face font-lock-warning-face)
2364 (propertize "n" 'font-lock-face font-lock-comment-face))) 2377 (propertize "n" 'font-lock-face font-lock-comment-face)))
2365 (bindat-get-field breakpoint 'addr) 2378 (bindat-get-field breakpoint 'addr)
2366 (bindat-get-field breakpoint 'times) 2379 (bindat-get-field breakpoint 'times)
2367 (if (string-match ".*watchpoint" type) 2380 (if (string-match ".*watchpoint" type)
2368 (bindat-get-field breakpoint 'what) 2381 (bindat-get-field breakpoint 'what)
2369 (or pending at 2382 (or pending at
2370 (concat "in " 2383 (concat "in "
2371 (propertize (or func "unknown") 2384 (propertize (or func "unknown")
2372 'font-lock-face font-lock-function-name-face) 2385 'font-lock-face font-lock-function-name-face)
2373 (gdb-frame-location breakpoint))))) 2386 (gdb-frame-location breakpoint)))))
2374 ;; Add clickable properties only for breakpoints with file:line 2387 ;; Add clickable properties only for breakpoints with file:line
2375 ;; information 2388 ;; information
2376 (append (list 'gdb-breakpoint breakpoint) 2389 (append (list 'gdb-breakpoint breakpoint)
2377 (when func '(help-echo "mouse-2, RET: visit breakpoint" 2390 (when func '(help-echo "mouse-2, RET: visit breakpoint"
2378 mouse-face highlight)))))) 2391 mouse-face highlight))))))
2379 (insert (gdb-table-string table " ")) 2392 (insert (gdb-table-string table " "))
2380 (gdb-place-breakpoints))) 2393 (gdb-place-breakpoints)))
2381 2394
@@ -2389,7 +2402,7 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
2389 (gdb-remove-breakpoint-icons (point-min) (point-max))))) 2402 (gdb-remove-breakpoint-icons (point-min) (point-max)))))
2390 (dolist (breakpoint gdb-breakpoints-list) 2403 (dolist (breakpoint gdb-breakpoints-list)
2391 (let* ((breakpoint (cdr breakpoint)) ; gdb-breakpoints-list is 2404 (let* ((breakpoint (cdr breakpoint)) ; gdb-breakpoints-list is
2392 ; an associative list 2405 ; an associative list
2393 (line (bindat-get-field breakpoint 'line))) 2406 (line (bindat-get-field breakpoint 'line)))
2394 (when line 2407 (when line
2395 (let ((file (bindat-get-field breakpoint 'fullname)) 2408 (let ((file (bindat-get-field breakpoint 'fullname))
@@ -2411,7 +2424,7 @@ HANDLER-NAME handler uses customization of CUSTOM-DEFUN. See
2411 (gdb-input 2424 (gdb-input
2412 (list "-file-list-exec-source-file" 2425 (list "-file-list-exec-source-file"
2413 `(lambda () (gdb-get-location 2426 `(lambda () (gdb-get-location
2414 ,bptno ,line ,flag)))))))))) 2427 ,bptno ,line ,flag))))))))))
2415 2428
2416(defvar gdb-source-file-regexp "fullname=\"\\(.*?\\)\"") 2429(defvar gdb-source-file-regexp "fullname=\"\\(.*?\\)\"")
2417 2430
@@ -2422,7 +2435,7 @@ Put in buffer and place breakpoint icon."
2422 (catch 'file-not-found 2435 (catch 'file-not-found
2423 (if (re-search-forward gdb-source-file-regexp nil t) 2436 (if (re-search-forward gdb-source-file-regexp nil t)
2424 (delete (cons bptno "File not found") gdb-location-alist) 2437 (delete (cons bptno "File not found") gdb-location-alist)
2425 (push (cons bptno (match-string 1)) gdb-location-alist) 2438 (push (cons bptno (match-string 1)) gdb-location-alist)
2426 (gdb-resync) 2439 (gdb-resync)
2427 (unless (assoc bptno gdb-location-alist) 2440 (unless (assoc bptno gdb-location-alist)
2428 (push (cons bptno "File not found") gdb-location-alist) 2441 (push (cons bptno "File not found") gdb-location-alist)
@@ -2510,20 +2523,20 @@ If not in a source or disassembly buffer just set point."
2510 (if (get-text-property 0 'gdb-enabled obj) 2523 (if (get-text-property 0 'gdb-enabled obj)
2511 "-break-disable " 2524 "-break-disable "
2512 "-break-enable ") 2525 "-break-enable ")
2513 (get-text-property 0 'gdb-bptno obj))))))))) 2526 (get-text-property 0 'gdb-bptno obj)))))))))
2514 2527
2515(defun gdb-breakpoints-buffer-name () 2528(defun gdb-breakpoints-buffer-name ()
2516 (concat "*breakpoints of " (gdb-get-target-string) "*")) 2529 (concat "*breakpoints of " (gdb-get-target-string) "*"))
2517 2530
2518(def-gdb-display-buffer 2531(def-gdb-display-buffer
2519 gdb-display-breakpoints-buffer 2532 gdb-display-breakpoints-buffer
2520 'gdb-breakpoints-buffer 2533 'gdb-breakpoints-buffer
2521 "Display status of user-settable breakpoints.") 2534 "Display status of user-settable breakpoints.")
2522 2535
2523(def-gdb-frame-for-buffer 2536(def-gdb-frame-for-buffer
2524 gdb-frame-breakpoints-buffer 2537 gdb-frame-breakpoints-buffer
2525 'gdb-breakpoints-buffer 2538 'gdb-breakpoints-buffer
2526 "Display status of user-settable breakpoints in a new frame.") 2539 "Display status of user-settable breakpoints in a new frame.")
2527 2540
2528(defvar gdb-breakpoints-mode-map 2541(defvar gdb-breakpoints-mode-map
2529 (let ((map (make-sparse-keymap)) 2542 (let ((map (make-sparse-keymap))
@@ -2540,9 +2553,9 @@ If not in a source or disassembly buffer just set point."
2540 (define-key map "q" 'gdb-delete-frame-or-window) 2553 (define-key map "q" 'gdb-delete-frame-or-window)
2541 (define-key map "\r" 'gdb-goto-breakpoint) 2554 (define-key map "\r" 'gdb-goto-breakpoint)
2542 (define-key map "\t" (lambda () 2555 (define-key map "\t" (lambda ()
2543 (interactive) 2556 (interactive)
2544 (gdb-set-window-buffer 2557 (gdb-set-window-buffer
2545 (gdb-get-buffer-create 'gdb-threads-buffer) t))) 2558 (gdb-get-buffer-create 'gdb-threads-buffer) t)))
2546 (define-key map [mouse-2] 'gdb-goto-breakpoint) 2559 (define-key map [mouse-2] 'gdb-goto-breakpoint)
2547 (define-key map [follow-link] 'mouse-face) 2560 (define-key map [follow-link] 'mouse-face)
2548 map)) 2561 map))
@@ -2585,14 +2598,14 @@ corresponding to the mode line clicked."
2585 (concat "*threads of " (gdb-get-target-string) "*")) 2598 (concat "*threads of " (gdb-get-target-string) "*"))
2586 2599
2587(def-gdb-display-buffer 2600(def-gdb-display-buffer
2588 gdb-display-threads-buffer 2601 gdb-display-threads-buffer
2589 'gdb-threads-buffer 2602 'gdb-threads-buffer
2590 "Display GDB threads.") 2603 "Display GDB threads.")
2591 2604
2592(def-gdb-frame-for-buffer 2605(def-gdb-frame-for-buffer
2593 gdb-frame-threads-buffer 2606 gdb-frame-threads-buffer
2594 'gdb-threads-buffer 2607 'gdb-threads-buffer
2595 "Display GDB threads in a new frame.") 2608 "Display GDB threads in a new frame.")
2596 2609
2597(def-gdb-trigger-and-handler 2610(def-gdb-trigger-and-handler
2598 gdb-invalidate-threads (gdb-current-context-command "-thread-info") 2611 gdb-invalidate-threads (gdb-current-context-command "-thread-info")
@@ -2626,18 +2639,20 @@ corresponding to the mode line clicked."
2626 (define-key map "i" 'gdb-interrupt-thread) 2639 (define-key map "i" 'gdb-interrupt-thread)
2627 (define-key map "c" 'gdb-continue-thread) 2640 (define-key map "c" 'gdb-continue-thread)
2628 (define-key map "s" 'gdb-step-thread) 2641 (define-key map "s" 'gdb-step-thread)
2629 (define-key map "\t" (lambda () 2642 (define-key map "\t"
2630 (interactive) 2643 (lambda ()
2631 (gdb-set-window-buffer 2644 (interactive)
2632 (gdb-get-buffer-create 'gdb-breakpoints-buffer) t))) 2645 (gdb-set-window-buffer
2646 (gdb-get-buffer-create 'gdb-breakpoints-buffer) t)))
2633 (define-key map [mouse-2] 'gdb-select-thread) 2647 (define-key map [mouse-2] 'gdb-select-thread)
2634 (define-key map [follow-link] 'mouse-face) 2648 (define-key map [follow-link] 'mouse-face)
2635 map)) 2649 map))
2636 2650
2637(defvar gdb-threads-header 2651(defvar gdb-threads-header
2638 (list 2652 (list
2639 (gdb-propertize-header "Breakpoints" gdb-breakpoints-buffer 2653 (gdb-propertize-header
2640 "mouse-1: select" mode-line-highlight mode-line-inactive) 2654 "Breakpoints" gdb-breakpoints-buffer
2655 "mouse-1: select" mode-line-highlight mode-line-inactive)
2641 " " 2656 " "
2642 (gdb-propertize-header "Threads" gdb-threads-buffer 2657 (gdb-propertize-header "Threads" gdb-threads-buffer
2643 nil nil mode-line))) 2658 nil nil mode-line)))
@@ -2661,44 +2676,45 @@ corresponding to the mode line clicked."
2661 (set-marker gdb-thread-position nil) 2676 (set-marker gdb-thread-position nil)
2662 2677
2663 (dolist (thread (reverse threads-list)) 2678 (dolist (thread (reverse threads-list))
2664 (let ((running (string-equal (bindat-get-field thread 'state) "running"))) 2679 (let ((running (equal (bindat-get-field thread 'state) "running")))
2665 (add-to-list 'gdb-threads-list 2680 (add-to-list 'gdb-threads-list
2666 (cons (bindat-get-field thread 'id) 2681 (cons (bindat-get-field thread 'id)
2667 thread)) 2682 thread))
2668 (if running 2683 (if running
2669 (incf gdb-running-threads-count) 2684 (incf gdb-running-threads-count)
2670 (incf gdb-stopped-threads-count)) 2685 (incf gdb-stopped-threads-count))
2671 2686
2672 (gdb-table-add-row table 2687 (gdb-table-add-row table
2673 (list 2688 (list
2674 (bindat-get-field thread 'id) 2689 (bindat-get-field thread 'id)
2675 (concat 2690 (concat
2676 (if gdb-thread-buffer-verbose-names 2691 (if gdb-thread-buffer-verbose-names
2677 (concat (bindat-get-field thread 'target-id) " ") "") 2692 (concat (bindat-get-field thread 'target-id) " ") "")
2678 (bindat-get-field thread 'state) 2693 (bindat-get-field thread 'state)
2679 ;; Include frame information for stopped threads 2694 ;; Include frame information for stopped threads
2680 (if (not running) 2695 (if (not running)
2681 (concat 2696 (concat
2682 " in " (bindat-get-field thread 'frame 'func) 2697 " in " (bindat-get-field thread 'frame 'func)
2683 (if gdb-thread-buffer-arguments 2698 (if gdb-thread-buffer-arguments
2684 (concat 2699 (concat
2685 " (" 2700 " ("
2686 (let ((args (bindat-get-field thread 'frame 'args))) 2701 (let ((args (bindat-get-field thread 'frame 'args)))
2687 (mapconcat 2702 (mapconcat
2688 (lambda (arg) 2703 (lambda (arg)
2689 (apply 'format `("%s=%s" ,@(gdb-get-many-fields arg 'name 'value)))) 2704 (apply #'format "%s=%s"
2690 args ",")) 2705 (gdb-get-many-fields arg 'name 'value)))
2691 ")") 2706 args ","))
2692 "") 2707 ")")
2693 (if gdb-thread-buffer-locations 2708 "")
2694 (gdb-frame-location (bindat-get-field thread 'frame)) "") 2709 (if gdb-thread-buffer-locations
2695 (if gdb-thread-buffer-addresses 2710 (gdb-frame-location (bindat-get-field thread 'frame)) "")
2696 (concat " at " (bindat-get-field thread 'frame 'addr)) "")) 2711 (if gdb-thread-buffer-addresses
2697 ""))) 2712 (concat " at " (bindat-get-field thread 'frame 'addr)) ""))
2698 (list 2713 "")))
2699 'gdb-thread thread 2714 (list
2700 'mouse-face 'highlight 2715 'gdb-thread thread
2701 'help-echo "mouse-2, RET: select thread"))) 2716 'mouse-face 'highlight
2717 'help-echo "mouse-2, RET: select thread")))
2702 (when (string-equal gdb-thread-number 2718 (when (string-equal gdb-thread-number
2703 (bindat-get-field thread 'id)) 2719 (bindat-get-field thread 'id))
2704 (setq marked-line (length gdb-threads-list)))) 2720 (setq marked-line (length gdb-threads-list))))
@@ -2727,7 +2743,8 @@ be the value of 'gdb-thread property of the current line. If
2727 ,custom-defun 2743 ,custom-defun
2728 (error "Not recognized as thread line")))))) 2744 (error "Not recognized as thread line"))))))
2729 2745
2730(defmacro def-gdb-thread-buffer-simple-command (name buffer-command &optional doc) 2746(defmacro def-gdb-thread-buffer-simple-command (name buffer-command
2747 &optional doc)
2731 "Define a NAME which will call BUFFER-COMMAND with id of thread 2748 "Define a NAME which will call BUFFER-COMMAND with id of thread
2732on the current line." 2749on the current line."
2733 `(def-gdb-thread-buffer-command ,name 2750 `(def-gdb-thread-buffer-command ,name
@@ -2830,19 +2847,19 @@ line."
2830(defcustom gdb-memory-format "x" 2847(defcustom gdb-memory-format "x"
2831 "Display format of data items in memory window." 2848 "Display format of data items in memory window."
2832 :type '(choice (const :tag "Hexadecimal" "x") 2849 :type '(choice (const :tag "Hexadecimal" "x")
2833 (const :tag "Signed decimal" "d") 2850 (const :tag "Signed decimal" "d")
2834 (const :tag "Unsigned decimal" "u") 2851 (const :tag "Unsigned decimal" "u")
2835 (const :tag "Octal" "o") 2852 (const :tag "Octal" "o")
2836 (const :tag "Binary" "t")) 2853 (const :tag "Binary" "t"))
2837 :group 'gud 2854 :group 'gud
2838 :version "22.1") 2855 :version "22.1")
2839 2856
2840(defcustom gdb-memory-unit 4 2857(defcustom gdb-memory-unit 4
2841 "Unit size of data items in memory window." 2858 "Unit size of data items in memory window."
2842 :type '(choice (const :tag "Byte" 1) 2859 :type '(choice (const :tag "Byte" 1)
2843 (const :tag "Halfword" 2) 2860 (const :tag "Halfword" 2)
2844 (const :tag "Word" 4) 2861 (const :tag "Word" 4)
2845 (const :tag "Giant word" 8)) 2862 (const :tag "Giant word" 8))
2846 :group 'gud 2863 :group 'gud
2847 :version "23.2") 2864 :version "23.2")
2848 2865
@@ -2893,14 +2910,14 @@ in `gdb-memory-format'."
2893 (setq gdb-memory-next-page (bindat-get-field res 'next-page)) 2910 (setq gdb-memory-next-page (bindat-get-field res 'next-page))
2894 (setq gdb-memory-prev-page (bindat-get-field res 'prev-page)) 2911 (setq gdb-memory-prev-page (bindat-get-field res 'prev-page))
2895 (setq gdb-memory-last-address gdb-memory-address) 2912 (setq gdb-memory-last-address gdb-memory-address)
2896 (dolist (row memory) 2913 (dolist (row memory)
2897 (insert (concat (bindat-get-field row 'addr) ":")) 2914 (insert (concat (bindat-get-field row 'addr) ":"))
2898 (dolist (column (bindat-get-field row 'data)) 2915 (dolist (column (bindat-get-field row 'data))
2899 (insert (gdb-pad-string column 2916 (insert (gdb-pad-string column
2900 (+ 2 (gdb-memory-column-width 2917 (+ 2 (gdb-memory-column-width
2901 gdb-memory-unit 2918 gdb-memory-unit
2902 gdb-memory-format))))) 2919 gdb-memory-format)))))
2903 (newline))) 2920 (newline)))
2904 ;; Show last page instead of empty buffer when out of bounds 2921 ;; Show last page instead of empty buffer when out of bounds
2905 (progn 2922 (progn
2906 (let ((gdb-memory-address gdb-memory-last-address)) 2923 (let ((gdb-memory-address gdb-memory-last-address))
@@ -2925,7 +2942,7 @@ in `gdb-memory-format'."
2925 (define-key map "g" 'gdb-memory-unit-giant) 2942 (define-key map "g" 'gdb-memory-unit-giant)
2926 (define-key map "R" 'gdb-memory-set-rows) 2943 (define-key map "R" 'gdb-memory-set-rows)
2927 (define-key map "C" 'gdb-memory-set-columns) 2944 (define-key map "C" 'gdb-memory-set-columns)
2928 map)) 2945 map))
2929 2946
2930(defun gdb-memory-set-address-event (event) 2947(defun gdb-memory-set-address-event (event)
2931 "Handle a click on address field in memory buffer header." 2948 "Handle a click on address field in memory buffer header."
@@ -3115,8 +3132,8 @@ DOC is an optional documentation string."
3115 3132
3116(defvar gdb-memory-font-lock-keywords 3133(defvar gdb-memory-font-lock-keywords
3117 '(;; <__function.name+n> 3134 '(;; <__function.name+n>
3118 ("<\\(\\(\\sw\\|[_.]\\)+\\)\\(\\+[0-9]+\\)?>" (1 font-lock-function-name-face)) 3135 ("<\\(\\(\\sw\\|[_.]\\)+\\)\\(\\+[0-9]+\\)?>"
3119 ) 3136 (1 font-lock-function-name-face)))
3120 "Font lock keywords used in `gdb-memory-mode'.") 3137 "Font lock keywords used in `gdb-memory-mode'.")
3121 3138
3122(defvar gdb-memory-header 3139(defvar gdb-memory-header
@@ -3124,52 +3141,52 @@ DOC is an optional documentation string."
3124 (concat 3141 (concat
3125 "Start address[" 3142 "Start address["
3126 (propertize "-" 3143 (propertize "-"
3127 'face font-lock-warning-face 3144 'face font-lock-warning-face
3128 'help-echo "mouse-1: decrement address" 3145 'help-echo "mouse-1: decrement address"
3129 'mouse-face 'mode-line-highlight 3146 'mouse-face 'mode-line-highlight
3130 'local-map (gdb-make-header-line-mouse-map 3147 'local-map (gdb-make-header-line-mouse-map
3131 'mouse-1 3148 'mouse-1
3132 #'gdb-memory-show-previous-page)) 3149 #'gdb-memory-show-previous-page))
3133 "|" 3150 "|"
3134 (propertize "+" 3151 (propertize "+"
3135 'face font-lock-warning-face 3152 'face font-lock-warning-face
3136 'help-echo "mouse-1: increment address" 3153 'help-echo "mouse-1: increment address"
3137 'mouse-face 'mode-line-highlight 3154 'mouse-face 'mode-line-highlight
3138 'local-map (gdb-make-header-line-mouse-map 3155 'local-map (gdb-make-header-line-mouse-map
3139 'mouse-1 3156 'mouse-1
3140 #'gdb-memory-show-next-page)) 3157 #'gdb-memory-show-next-page))
3141 "]: " 3158 "]: "
3142 (propertize gdb-memory-address 3159 (propertize gdb-memory-address
3143 'face font-lock-warning-face 3160 'face font-lock-warning-face
3144 'help-echo "mouse-1: set start address" 3161 'help-echo "mouse-1: set start address"
3145 'mouse-face 'mode-line-highlight 3162 'mouse-face 'mode-line-highlight
3146 'local-map (gdb-make-header-line-mouse-map 3163 'local-map (gdb-make-header-line-mouse-map
3147 'mouse-1 3164 'mouse-1
3148 #'gdb-memory-set-address-event)) 3165 #'gdb-memory-set-address-event))
3149 " Rows: " 3166 " Rows: "
3150 (propertize (number-to-string gdb-memory-rows) 3167 (propertize (number-to-string gdb-memory-rows)
3151 'face font-lock-warning-face 3168 'face font-lock-warning-face
3152 'help-echo "mouse-1: set number of columns" 3169 'help-echo "mouse-1: set number of columns"
3153 'mouse-face 'mode-line-highlight 3170 'mouse-face 'mode-line-highlight
3154 'local-map (gdb-make-header-line-mouse-map 3171 'local-map (gdb-make-header-line-mouse-map
3155 'mouse-1 3172 'mouse-1
3156 #'gdb-memory-set-rows)) 3173 #'gdb-memory-set-rows))
3157 " Columns: " 3174 " Columns: "
3158 (propertize (number-to-string gdb-memory-columns) 3175 (propertize (number-to-string gdb-memory-columns)
3159 'face font-lock-warning-face 3176 'face font-lock-warning-face
3160 'help-echo "mouse-1: set number of columns" 3177 'help-echo "mouse-1: set number of columns"
3161 'mouse-face 'mode-line-highlight 3178 'mouse-face 'mode-line-highlight
3162 'local-map (gdb-make-header-line-mouse-map 3179 'local-map (gdb-make-header-line-mouse-map
3163 'mouse-1 3180 'mouse-1
3164 #'gdb-memory-set-columns)) 3181 #'gdb-memory-set-columns))
3165 " Display Format: " 3182 " Display Format: "
3166 (propertize gdb-memory-format 3183 (propertize gdb-memory-format
3167 'face font-lock-warning-face 3184 'face font-lock-warning-face
3168 'help-echo "mouse-3: select display format" 3185 'help-echo "mouse-3: select display format"
3169 'mouse-face 'mode-line-highlight 3186 'mouse-face 'mode-line-highlight
3170 'local-map gdb-memory-format-map) 3187 'local-map gdb-memory-format-map)
3171 " Unit Size: " 3188 " Unit Size: "
3172 (propertize (number-to-string gdb-memory-unit) 3189 (propertize (number-to-string gdb-memory-unit)
3173 'face font-lock-warning-face 3190 'face font-lock-warning-face
3174 'help-echo "mouse-3: select unit size" 3191 'help-echo "mouse-3: select unit size"
3175 'mouse-face 'mode-line-highlight 3192 'mouse-face 'mode-line-highlight
@@ -3210,18 +3227,18 @@ DOC is an optional documentation string."
3210 (concat "disassembly of " (gdb-get-target-string)))) 3227 (concat "disassembly of " (gdb-get-target-string))))
3211 3228
3212(def-gdb-display-buffer 3229(def-gdb-display-buffer
3213 gdb-display-disassembly-buffer 3230 gdb-display-disassembly-buffer
3214 'gdb-disassembly-buffer 3231 'gdb-disassembly-buffer
3215 "Display disassembly for current stack frame.") 3232 "Display disassembly for current stack frame.")
3216 3233
3217(def-gdb-preempt-display-buffer 3234(def-gdb-preempt-display-buffer
3218 gdb-preemptively-display-disassembly-buffer 3235 gdb-preemptively-display-disassembly-buffer
3219 'gdb-disassembly-buffer) 3236 'gdb-disassembly-buffer)
3220 3237
3221(def-gdb-frame-for-buffer 3238(def-gdb-frame-for-buffer
3222 gdb-frame-disassembly-buffer 3239 gdb-frame-disassembly-buffer
3223 'gdb-disassembly-buffer 3240 'gdb-disassembly-buffer
3224 "Display disassembly in a new frame.") 3241 "Display disassembly in a new frame.")
3225 3242
3226(def-gdb-auto-update-trigger gdb-invalidate-disassembly 3243(def-gdb-auto-update-trigger gdb-invalidate-disassembly
3227 (let* ((frame (gdb-current-buffer-frame)) 3244 (let* ((frame (gdb-current-buffer-frame))
@@ -3266,7 +3283,7 @@ DOC is an optional documentation string."
3266 (let ((map (make-sparse-keymap))) 3283 (let ((map (make-sparse-keymap)))
3267 (suppress-keymap map) 3284 (suppress-keymap map)
3268 (define-key map "q" 'kill-this-buffer) 3285 (define-key map "q" 'kill-this-buffer)
3269 map)) 3286 map))
3270 3287
3271(define-derived-mode gdb-disassembly-mode gdb-parent-mode "Disassembly" 3288(define-derived-mode gdb-disassembly-mode gdb-parent-mode "Disassembly"
3272 "Major mode for GDB disassembly information." 3289 "Major mode for GDB disassembly information."
@@ -3283,12 +3300,13 @@ DOC is an optional documentation string."
3283 (address (bindat-get-field (gdb-current-buffer-frame) 'addr)) 3300 (address (bindat-get-field (gdb-current-buffer-frame) 'addr))
3284 (table (make-gdb-table)) 3301 (table (make-gdb-table))
3285 (marked-line nil)) 3302 (marked-line nil))
3286 (dolist (instr instructions) 3303 (dolist (instr instructions)
3287 (gdb-table-add-row table 3304 (gdb-table-add-row table
3288 (list 3305 (list
3289 (bindat-get-field instr 'address) 3306 (bindat-get-field instr 'address)
3290 (apply 'format `("<%s+%s>:" ,@(gdb-get-many-fields instr 'func-name 'offset))) 3307 (apply #'format "<%s+%s>:"
3291 (bindat-get-field instr 'inst))) 3308 (gdb-get-many-fields instr 'func-name 'offset))
3309 (bindat-get-field instr 'inst)))
3292 (when (string-equal (bindat-get-field instr 'address) 3310 (when (string-equal (bindat-get-field instr 'address)
3293 address) 3311 address)
3294 (progn 3312 (progn
@@ -3297,17 +3315,18 @@ DOC is an optional documentation string."
3297 (if (string-equal gdb-frame-number "0") 3315 (if (string-equal gdb-frame-number "0")
3298 nil 3316 nil
3299 '((overlay-arrow . hollow-right-triangle))))))) 3317 '((overlay-arrow . hollow-right-triangle)))))))
3300 (insert (gdb-table-string table " ")) 3318 (insert (gdb-table-string table " "))
3301 (gdb-disassembly-place-breakpoints) 3319 (gdb-disassembly-place-breakpoints)
3302 ;; Mark current position with overlay arrow and scroll window to 3320 ;; Mark current position with overlay arrow and scroll window to
3303 ;; that point 3321 ;; that point
3304 (when marked-line 3322 (when marked-line
3305 (let ((window (get-buffer-window (current-buffer) 0))) 3323 (let ((window (get-buffer-window (current-buffer) 0)))
3306 (set-window-point window (gdb-mark-line marked-line gdb-disassembly-position)))) 3324 (set-window-point window (gdb-mark-line marked-line
3307 (setq mode-name 3325 gdb-disassembly-position))))
3308 (gdb-current-context-mode-name 3326 (setq mode-name
3309 (concat "Disassembly: " 3327 (gdb-current-context-mode-name
3310 (bindat-get-field (gdb-current-buffer-frame) 'func)))))) 3328 (concat "Disassembly: "
3329 (bindat-get-field (gdb-current-buffer-frame) 'func))))))
3311 3330
3312(defun gdb-disassembly-place-breakpoints () 3331(defun gdb-disassembly-place-breakpoints ()
3313 (gdb-remove-breakpoint-icons (point-min) (point-max)) 3332 (gdb-remove-breakpoint-icons (point-min) (point-max))
@@ -3328,7 +3347,8 @@ DOC is an optional documentation string."
3328 nil nil mode-line) 3347 nil nil mode-line)
3329 " " 3348 " "
3330 (gdb-propertize-header "Threads" gdb-threads-buffer 3349 (gdb-propertize-header "Threads" gdb-threads-buffer
3331 "mouse-1: select" mode-line-highlight mode-line-inactive))) 3350 "mouse-1: select" mode-line-highlight
3351 mode-line-inactive)))
3332 3352
3333;;; Breakpoints view 3353;;; Breakpoints view
3334(define-derived-mode gdb-breakpoints-mode gdb-parent-mode "Breakpoints" 3354(define-derived-mode gdb-breakpoints-mode gdb-parent-mode "Breakpoints"
@@ -3344,7 +3364,7 @@ DOC is an optional documentation string."
3344 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 3364 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
3345 (if breakpoint 3365 (if breakpoint
3346 (gud-basic-call 3366 (gud-basic-call
3347 (concat (if (string-equal "y" (bindat-get-field breakpoint 'enabled)) 3367 (concat (if (equal "y" (bindat-get-field breakpoint 'enabled))
3348 "-break-disable " 3368 "-break-disable "
3349 "-break-enable ") 3369 "-break-enable ")
3350 (bindat-get-field breakpoint 'number))) 3370 (bindat-get-field breakpoint 'number)))
@@ -3354,11 +3374,12 @@ DOC is an optional documentation string."
3354 "Delete the breakpoint at current line of breakpoints buffer." 3374 "Delete the breakpoint at current line of breakpoints buffer."
3355 (interactive) 3375 (interactive)
3356 (save-excursion 3376 (save-excursion
3357 (beginning-of-line) 3377 (beginning-of-line)
3358 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 3378 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
3359 (if breakpoint 3379 (if breakpoint
3360 (gud-basic-call (concat "-break-delete " (bindat-get-field breakpoint 'number))) 3380 (gud-basic-call (concat "-break-delete "
3361 (error "Not recognized as break/watchpoint line"))))) 3381 (bindat-get-field breakpoint 'number)))
3382 (error "Not recognized as break/watchpoint line")))))
3362 3383
3363(defun gdb-goto-breakpoint (&optional event) 3384(defun gdb-goto-breakpoint (&optional event)
3364 "Go to the location of breakpoint at current line of 3385 "Go to the location of breakpoint at current line of
@@ -3369,24 +3390,24 @@ breakpoints buffer."
3369 (let ((window (get-buffer-window gud-comint-buffer))) 3390 (let ((window (get-buffer-window gud-comint-buffer)))
3370 (if window (save-selected-window (select-window window)))) 3391 (if window (save-selected-window (select-window window))))
3371 (save-excursion 3392 (save-excursion
3372 (beginning-of-line) 3393 (beginning-of-line)
3373 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint))) 3394 (let ((breakpoint (get-text-property (point) 'gdb-breakpoint)))
3374 (if breakpoint 3395 (if breakpoint
3375 (let ((bptno (bindat-get-field breakpoint 'number)) 3396 (let ((bptno (bindat-get-field breakpoint 'number))
3376 (file (bindat-get-field breakpoint 'fullname)) 3397 (file (bindat-get-field breakpoint 'fullname))
3377 (line (bindat-get-field breakpoint 'line))) 3398 (line (bindat-get-field breakpoint 'line)))
3378 (save-selected-window 3399 (save-selected-window
3379 (let* ((buffer (find-file-noselect 3400 (let* ((buffer (find-file-noselect
3380 (if (file-exists-p file) file 3401 (if (file-exists-p file) file
3381 (cdr (assoc bptno gdb-location-alist))))) 3402 (cdr (assoc bptno gdb-location-alist)))))
3382 (window (or (gdb-display-source-buffer buffer) 3403 (window (or (gdb-display-source-buffer buffer)
3383 (display-buffer buffer)))) 3404 (display-buffer buffer))))
3384 (setq gdb-source-window window) 3405 (setq gdb-source-window window)
3385 (with-current-buffer buffer 3406 (with-current-buffer buffer
3386 (goto-char (point-min)) 3407 (goto-char (point-min))
3387 (forward-line (1- (string-to-number line))) 3408 (forward-line (1- (string-to-number line)))
3388 (set-window-point window (point)))))) 3409 (set-window-point window (point))))))
3389 (error "Not recognized as break/watchpoint line"))))) 3410 (error "Not recognized as break/watchpoint line")))))
3390 3411
3391 3412
3392;; Frames buffer. This displays a perpetually correct bactrack trace. 3413;; Frames buffer. This displays a perpetually correct bactrack trace.
@@ -3418,21 +3439,21 @@ member."
3418 (let ((stack (bindat-get-field (gdb-json-partial-output "frame") 'stack)) 3439 (let ((stack (bindat-get-field (gdb-json-partial-output "frame") 'stack))
3419 (table (make-gdb-table))) 3440 (table (make-gdb-table)))
3420 (set-marker gdb-stack-position nil) 3441 (set-marker gdb-stack-position nil)
3421 (dolist (frame stack) 3442 (dolist (frame stack)
3422 (gdb-table-add-row table 3443 (gdb-table-add-row table
3423 (list 3444 (list
3424 (bindat-get-field frame 'level) 3445 (bindat-get-field frame 'level)
3425 "in" 3446 "in"
3426 (concat 3447 (concat
3427 (bindat-get-field frame 'func) 3448 (bindat-get-field frame 'func)
3428 (if gdb-stack-buffer-locations 3449 (if gdb-stack-buffer-locations
3429 (gdb-frame-location frame) "") 3450 (gdb-frame-location frame) "")
3430 (if gdb-stack-buffer-addresses 3451 (if gdb-stack-buffer-addresses
3431 (concat " at " (bindat-get-field frame 'addr)) ""))) 3452 (concat " at " (bindat-get-field frame 'addr)) "")))
3432 `(mouse-face highlight 3453 `(mouse-face highlight
3433 help-echo "mouse-2, RET: Select frame" 3454 help-echo "mouse-2, RET: Select frame"
3434 gdb-frame ,frame))) 3455 gdb-frame ,frame)))
3435 (insert (gdb-table-string table " "))) 3456 (insert (gdb-table-string table " ")))
3436 (when (and gdb-frame-number 3457 (when (and gdb-frame-number
3437 (gdb-buffer-shows-main-thread-p)) 3458 (gdb-buffer-shows-main-thread-p))
3438 (gdb-mark-line (1+ (string-to-number gdb-frame-number)) 3459 (gdb-mark-line (1+ (string-to-number gdb-frame-number))
@@ -3445,18 +3466,18 @@ member."
3445 (concat "stack frames of " (gdb-get-target-string)))) 3466 (concat "stack frames of " (gdb-get-target-string))))
3446 3467
3447(def-gdb-display-buffer 3468(def-gdb-display-buffer
3448 gdb-display-stack-buffer 3469 gdb-display-stack-buffer
3449 'gdb-stack-buffer 3470 'gdb-stack-buffer
3450 "Display backtrace of current stack.") 3471 "Display backtrace of current stack.")
3451 3472
3452(def-gdb-preempt-display-buffer 3473(def-gdb-preempt-display-buffer
3453 gdb-preemptively-display-stack-buffer 3474 gdb-preemptively-display-stack-buffer
3454 'gdb-stack-buffer nil t) 3475 'gdb-stack-buffer nil t)
3455 3476
3456(def-gdb-frame-for-buffer 3477(def-gdb-frame-for-buffer
3457 gdb-frame-stack-buffer 3478 gdb-frame-stack-buffer
3458 'gdb-stack-buffer 3479 'gdb-stack-buffer
3459 "Display backtrace of current stack in a new frame.") 3480 "Display backtrace of current stack in a new frame.")
3460 3481
3461(defvar gdb-frames-mode-map 3482(defvar gdb-frames-mode-map
3462 (let ((map (make-sparse-keymap))) 3483 (let ((map (make-sparse-keymap)))
@@ -3489,7 +3510,8 @@ member."
3489 (if (gdb-buffer-shows-main-thread-p) 3510 (if (gdb-buffer-shows-main-thread-p)
3490 (let ((new-level (bindat-get-field frame 'level))) 3511 (let ((new-level (bindat-get-field frame 'level)))
3491 (setq gdb-frame-number new-level) 3512 (setq gdb-frame-number new-level)
3492 (gdb-input (list (concat "-stack-select-frame " new-level) 'ignore)) 3513 (gdb-input (list (concat "-stack-select-frame " new-level)
3514 'ignore))
3493 (gdb-update)) 3515 (gdb-update))
3494 (error "Could not select frame for non-current thread")) 3516 (error "Could not select frame for non-current thread"))
3495 (error "Not recognized as frame line")))) 3517 (error "Not recognized as frame line"))))
@@ -3499,7 +3521,8 @@ member."
3499;; uses "-stack-list-locals --simple-values". Needs GDB 6.1 onwards. 3521;; uses "-stack-list-locals --simple-values". Needs GDB 6.1 onwards.
3500(def-gdb-trigger-and-handler 3522(def-gdb-trigger-and-handler
3501 gdb-invalidate-locals 3523 gdb-invalidate-locals
3502 (concat (gdb-current-context-command "-stack-list-locals") " --simple-values") 3524 (concat (gdb-current-context-command "-stack-list-locals")
3525 " --simple-values")
3503 gdb-locals-handler gdb-locals-handler-custom 3526 gdb-locals-handler gdb-locals-handler-custom
3504 '(start update)) 3527 '(start update))
3505 3528
@@ -3515,7 +3538,7 @@ member."
3515 (define-key map "\r" 'gud-watch) 3538 (define-key map "\r" 'gud-watch)
3516 (define-key map [mouse-2] 'gud-watch) 3539 (define-key map [mouse-2] 'gud-watch)
3517 map) 3540 map)
3518 "Keymap to create watch expression of a complex data type local variable.") 3541 "Keymap to create watch expression of a complex data type local variable.")
3519 3542
3520(defvar gdb-edit-locals-map-1 3543(defvar gdb-edit-locals-map-1
3521 (let ((map (make-sparse-keymap))) 3544 (let ((map (make-sparse-keymap)))
@@ -3523,7 +3546,7 @@ member."
3523 (define-key map "\r" 'gdb-edit-locals-value) 3546 (define-key map "\r" 'gdb-edit-locals-value)
3524 (define-key map [mouse-2] 'gdb-edit-locals-value) 3547 (define-key map [mouse-2] 'gdb-edit-locals-value)
3525 map) 3548 map)
3526 "Keymap to edit value of a simple data type local variable.") 3549 "Keymap to edit value of a simple data type local variable.")
3527 3550
3528(defun gdb-edit-locals-value (&optional event) 3551(defun gdb-edit-locals-value (&optional event)
3529 "Assign a value to a variable displayed in the locals buffer." 3552 "Assign a value to a variable displayed in the locals buffer."
@@ -3549,14 +3572,14 @@ member."
3549 (if (or (not value) 3572 (if (or (not value)
3550 (string-match "\\0x" value)) 3573 (string-match "\\0x" value))
3551 (add-text-properties 0 (length name) 3574 (add-text-properties 0 (length name)
3552 `(mouse-face highlight 3575 `(mouse-face highlight
3553 help-echo "mouse-2: create watch expression" 3576 help-echo "mouse-2: create watch expression"
3554 local-map ,gdb-locals-watch-map) 3577 local-map ,gdb-locals-watch-map)
3555 name) 3578 name)
3556 (add-text-properties 0 (length value) 3579 (add-text-properties 0 (length value)
3557 `(mouse-face highlight 3580 `(mouse-face highlight
3558 help-echo "mouse-2: edit value" 3581 help-echo "mouse-2: edit value"
3559 local-map ,gdb-edit-locals-map-1) 3582 local-map ,gdb-edit-locals-map-1)
3560 value)) 3583 value))
3561 (gdb-table-add-row 3584 (gdb-table-add-row
3562 table 3585 table
@@ -3568,7 +3591,8 @@ member."
3568 (insert (gdb-table-string table " ")) 3591 (insert (gdb-table-string table " "))
3569 (setq mode-name 3592 (setq mode-name
3570 (gdb-current-context-mode-name 3593 (gdb-current-context-mode-name
3571 (concat "Locals: " (bindat-get-field (gdb-current-buffer-frame) 'func)))))) 3594 (concat "Locals: "
3595 (bindat-get-field (gdb-current-buffer-frame) 'func))))))
3572 3596
3573(defvar gdb-locals-header 3597(defvar gdb-locals-header
3574 (list 3598 (list
@@ -3576,19 +3600,20 @@ member."
3576 nil nil mode-line) 3600 nil nil mode-line)
3577 " " 3601 " "
3578 (gdb-propertize-header "Registers" gdb-registers-buffer 3602 (gdb-propertize-header "Registers" gdb-registers-buffer
3579 "mouse-1: select" mode-line-highlight mode-line-inactive))) 3603 "mouse-1: select" mode-line-highlight
3604 mode-line-inactive)))
3580 3605
3581(defvar gdb-locals-mode-map 3606(defvar gdb-locals-mode-map
3582 (let ((map (make-sparse-keymap))) 3607 (let ((map (make-sparse-keymap)))
3583 (suppress-keymap map) 3608 (suppress-keymap map)
3584 (define-key map "q" 'kill-this-buffer) 3609 (define-key map "q" 'kill-this-buffer)
3585 (define-key map "\t" (lambda () 3610 (define-key map "\t" (lambda ()
3586 (interactive) 3611 (interactive)
3587 (gdb-set-window-buffer 3612 (gdb-set-window-buffer
3588 (gdb-get-buffer-create 3613 (gdb-get-buffer-create
3589 'gdb-registers-buffer 3614 'gdb-registers-buffer
3590 gdb-thread-number) t))) 3615 gdb-thread-number) t)))
3591 map)) 3616 map))
3592 3617
3593(define-derived-mode gdb-locals-mode gdb-parent-mode "Locals" 3618(define-derived-mode gdb-locals-mode gdb-parent-mode "Locals"
3594 "Major mode for gdb locals." 3619 "Major mode for gdb locals."
@@ -3600,18 +3625,18 @@ member."
3600 (concat "locals of " (gdb-get-target-string)))) 3625 (concat "locals of " (gdb-get-target-string))))
3601 3626
3602(def-gdb-display-buffer 3627(def-gdb-display-buffer
3603 gdb-display-locals-buffer 3628 gdb-display-locals-buffer
3604 'gdb-locals-buffer 3629 'gdb-locals-buffer
3605 "Display local variables of current stack and their values.") 3630 "Display local variables of current stack and their values.")
3606 3631
3607(def-gdb-preempt-display-buffer 3632(def-gdb-preempt-display-buffer
3608 gdb-preemptively-display-locals-buffer 3633 gdb-preemptively-display-locals-buffer
3609 'gdb-locals-buffer nil t) 3634 'gdb-locals-buffer nil t)
3610 3635
3611(def-gdb-frame-for-buffer 3636(def-gdb-frame-for-buffer
3612 gdb-frame-locals-buffer 3637 gdb-frame-locals-buffer
3613 'gdb-locals-buffer 3638 'gdb-locals-buffer
3614 "Display local variables of current stack and their values in a new frame.") 3639 "Display local variables of current stack and their values in a new frame.")
3615 3640
3616 3641
3617;; Registers buffer. 3642;; Registers buffer.
@@ -3631,7 +3656,8 @@ member."
3631 3656
3632(defun gdb-registers-handler-custom () 3657(defun gdb-registers-handler-custom ()
3633 (when gdb-register-names 3658 (when gdb-register-names
3634 (let ((register-values (bindat-get-field (gdb-json-partial-output) 'register-values)) 3659 (let ((register-values
3660 (bindat-get-field (gdb-json-partial-output) 'register-values))
3635 (table (make-gdb-table))) 3661 (table (make-gdb-table)))
3636 (dolist (register register-values) 3662 (dolist (register register-values)
3637 (let* ((register-number (bindat-get-field register 'number)) 3663 (let* ((register-number (bindat-get-field register 'number))
@@ -3641,7 +3667,8 @@ member."
3641 (gdb-table-add-row 3667 (gdb-table-add-row
3642 table 3668 table
3643 (list 3669 (list
3644 (propertize register-name 'font-lock-face font-lock-variable-name-face) 3670 (propertize register-name
3671 'font-lock-face font-lock-variable-name-face)
3645 (if (member register-number gdb-changed-registers) 3672 (if (member register-number gdb-changed-registers)
3646 (propertize value 'font-lock-face font-lock-warning-face) 3673 (propertize value 'font-lock-face font-lock-warning-face)
3647 value)) 3674 value))
@@ -3671,17 +3698,18 @@ member."
3671 (define-key map [mouse-2] 'gdb-edit-register-value) 3698 (define-key map [mouse-2] 'gdb-edit-register-value)
3672 (define-key map "q" 'kill-this-buffer) 3699 (define-key map "q" 'kill-this-buffer)
3673 (define-key map "\t" (lambda () 3700 (define-key map "\t" (lambda ()
3674 (interactive) 3701 (interactive)
3675 (gdb-set-window-buffer 3702 (gdb-set-window-buffer
3676 (gdb-get-buffer-create 3703 (gdb-get-buffer-create
3677 'gdb-locals-buffer 3704 'gdb-locals-buffer
3678 gdb-thread-number) t))) 3705 gdb-thread-number) t)))
3679 map)) 3706 map))
3680 3707
3681(defvar gdb-registers-header 3708(defvar gdb-registers-header
3682 (list 3709 (list
3683 (gdb-propertize-header "Locals" gdb-locals-buffer 3710 (gdb-propertize-header "Locals" gdb-locals-buffer
3684 "mouse-1: select" mode-line-highlight mode-line-inactive) 3711 "mouse-1: select" mode-line-highlight
3712 mode-line-inactive)
3685 " " 3713 " "
3686 (gdb-propertize-header "Registers" gdb-registers-buffer 3714 (gdb-propertize-header "Registers" gdb-registers-buffer
3687 nil nil mode-line))) 3715 nil nil mode-line)))
@@ -3696,17 +3724,17 @@ member."
3696 (concat "registers of " (gdb-get-target-string)))) 3724 (concat "registers of " (gdb-get-target-string))))
3697 3725
3698(def-gdb-display-buffer 3726(def-gdb-display-buffer
3699 gdb-display-registers-buffer 3727 gdb-display-registers-buffer
3700 'gdb-registers-buffer 3728 'gdb-registers-buffer
3701 "Display integer register contents.") 3729 "Display integer register contents.")
3702 3730
3703(def-gdb-preempt-display-buffer 3731(def-gdb-preempt-display-buffer
3704 gdb-preemptively-display-registers-buffer 3732 gdb-preemptively-display-registers-buffer
3705 'gdb-registers-buffer nil t) 3733 'gdb-registers-buffer nil t)
3706 3734
3707(def-gdb-frame-for-buffer 3735(def-gdb-frame-for-buffer
3708 gdb-frame-registers-buffer 3736 gdb-frame-registers-buffer
3709 'gdb-registers-buffer 3737 'gdb-registers-buffer
3710 "Display integer register contents in a new frame.") 3738 "Display integer register contents in a new frame.")
3711 3739
3712;; Needs GDB 6.4 onwards (used to fail with no stack). 3740;; Needs GDB 6.4 onwards (used to fail with no stack).
@@ -3723,14 +3751,16 @@ member."
3723(defun gdb-changed-registers-handler () 3751(defun gdb-changed-registers-handler ()
3724 (gdb-delete-pending 'gdb-get-changed-registers) 3752 (gdb-delete-pending 'gdb-get-changed-registers)
3725 (setq gdb-changed-registers nil) 3753 (setq gdb-changed-registers nil)
3726 (dolist (register-number (bindat-get-field (gdb-json-partial-output) 'changed-registers)) 3754 (dolist (register-number
3755 (bindat-get-field (gdb-json-partial-output) 'changed-registers))
3727 (push register-number gdb-changed-registers))) 3756 (push register-number gdb-changed-registers)))
3728 3757
3729(defun gdb-register-names-handler () 3758(defun gdb-register-names-handler ()
3730 ;; Don't use gdb-pending-triggers because this handler is called 3759 ;; Don't use gdb-pending-triggers because this handler is called
3731 ;; only once (in gdb-init-1) 3760 ;; only once (in gdb-init-1)
3732 (setq gdb-register-names nil) 3761 (setq gdb-register-names nil)
3733 (dolist (register-name (bindat-get-field (gdb-json-partial-output) 'register-names)) 3762 (dolist (register-name
3763 (bindat-get-field (gdb-json-partial-output) 'register-names))
3734 (push register-name gdb-register-names)) 3764 (push register-name gdb-register-names))
3735 (setq gdb-register-names (reverse gdb-register-names))) 3765 (setq gdb-register-names (reverse gdb-register-names)))
3736 3766
@@ -3755,7 +3785,8 @@ thread. Called from `gdb-update'."
3755 (if (not (gdb-pending-p 'gdb-get-main-selected-frame)) 3785 (if (not (gdb-pending-p 'gdb-get-main-selected-frame))
3756 (progn 3786 (progn
3757 (gdb-input 3787 (gdb-input
3758 (list (gdb-current-context-command "-stack-info-frame") 'gdb-frame-handler)) 3788 (list (gdb-current-context-command "-stack-info-frame")
3789 'gdb-frame-handler))
3759 (gdb-add-pending 'gdb-get-main-selected-frame)))) 3790 (gdb-add-pending 'gdb-get-main-selected-frame))))
3760 3791
3761(defun gdb-frame-handler () 3792(defun gdb-frame-handler ()
@@ -3806,10 +3837,10 @@ window and show BUF there, if the window is not used for GDB
3806already, in which case that window is splitted first." 3837already, in which case that window is splitted first."
3807 (let ((answer (get-buffer-window buf (or frame 0)))) 3838 (let ((answer (get-buffer-window buf (or frame 0))))
3808 (if answer 3839 (if answer
3809 (display-buffer buf nil (or frame 0)) ;Deiconify the frame if necessary. 3840 (display-buffer buf nil (or frame 0)) ;Deiconify frame if necessary.
3810 (let ((window (get-lru-window))) 3841 (let ((window (get-lru-window)))
3811 (if (eq (buffer-local-value 'gud-minor-mode (window-buffer window)) 3842 (if (eq (buffer-local-value 'gud-minor-mode (window-buffer window))
3812 'gdbmi) 3843 'gdbmi)
3813 (let ((largest (get-largest-window))) 3844 (let ((largest (get-largest-window)))
3814 (setq answer (split-window largest)) 3845 (setq answer (split-window largest))
3815 (set-window-buffer answer buf) 3846 (set-window-buffer answer buf)
@@ -3872,7 +3903,8 @@ SPLIT-HORIZONTAL and show BUF in the new window."
3872 (define-key menu [gdb] '("Gdb" . gdb-frame-gdb-buffer)) 3903 (define-key menu [gdb] '("Gdb" . gdb-frame-gdb-buffer))
3873 (define-key menu [threads] '("Threads" . gdb-frame-threads-buffer)) 3904 (define-key menu [threads] '("Threads" . gdb-frame-threads-buffer))
3874 (define-key menu [memory] '("Memory" . gdb-frame-memory-buffer)) 3905 (define-key menu [memory] '("Memory" . gdb-frame-memory-buffer))
3875 (define-key menu [disassembly] '("Disassembly" . gdb-frame-disassembly-buffer)) 3906 (define-key menu [disassembly]
3907 '("Disassembly" . gdb-frame-disassembly-buffer))
3876 (define-key menu [registers] '("Registers" . gdb-frame-registers-buffer)) 3908 (define-key menu [registers] '("Registers" . gdb-frame-registers-buffer))
3877 (define-key menu [inferior] 3909 (define-key menu [inferior]
3878 '("IO" . gdb-frame-io-buffer)) 3910 '("IO" . gdb-frame-io-buffer))
@@ -3883,40 +3915,41 @@ SPLIT-HORIZONTAL and show BUF in the new window."
3883 3915
3884(let ((menu (make-sparse-keymap "GDB-MI"))) 3916(let ((menu (make-sparse-keymap "GDB-MI")))
3885 (define-key menu [gdb-customize] 3917 (define-key menu [gdb-customize]
3886 '(menu-item "Customize" (lambda () (interactive) (customize-group 'gdb)) 3918 '(menu-item "Customize" (lambda () (interactive) (customize-group 'gdb))
3887 :help "Customize Gdb Graphical Mode options.")) 3919 :help "Customize Gdb Graphical Mode options."))
3888 (define-key menu [gdb-many-windows] 3920 (define-key menu [gdb-many-windows]
3889 '(menu-item "Display Other Windows" gdb-many-windows 3921 '(menu-item "Display Other Windows" gdb-many-windows
3890 :help "Toggle display of locals, stack and breakpoint information" 3922 :help "Toggle display of locals, stack and breakpoint information"
3891 :button (:toggle . gdb-many-windows))) 3923 :button (:toggle . gdb-many-windows)))
3892 (define-key menu [gdb-restore-windows] 3924 (define-key menu [gdb-restore-windows]
3893 '(menu-item "Restore Window Layout" gdb-restore-windows 3925 '(menu-item "Restore Window Layout" gdb-restore-windows
3894 :help "Restore standard layout for debug session.")) 3926 :help "Restore standard layout for debug session."))
3895 (define-key menu [sep1] 3927 (define-key menu [sep1]
3896 '(menu-item "--")) 3928 '(menu-item "--"))
3897 (define-key menu [all-threads] 3929 (define-key menu [all-threads]
3898 '(menu-item "GUD controls all threads" 3930 '(menu-item "GUD controls all threads"
3899 (lambda () 3931 (lambda ()
3900 (interactive) 3932 (interactive)
3901 (setq gdb-gud-control-all-threads t)) 3933 (setq gdb-gud-control-all-threads t))
3902 :help "GUD start/stop commands apply to all threads" 3934 :help "GUD start/stop commands apply to all threads"
3903 :button (:radio . gdb-gud-control-all-threads))) 3935 :button (:radio . gdb-gud-control-all-threads)))
3904 (define-key menu [current-thread] 3936 (define-key menu [current-thread]
3905 '(menu-item "GUD controls current thread" 3937 '(menu-item "GUD controls current thread"
3906 (lambda () 3938 (lambda ()
3907 (interactive) 3939 (interactive)
3908 (setq gdb-gud-control-all-threads nil)) 3940 (setq gdb-gud-control-all-threads nil))
3909 :help "GUD start/stop commands apply to current thread only" 3941 :help "GUD start/stop commands apply to current thread only"
3910 :button (:radio . (not gdb-gud-control-all-threads)))) 3942 :button (:radio . (not gdb-gud-control-all-threads))))
3911 (define-key menu [sep2] 3943 (define-key menu [sep2]
3912 '(menu-item "--")) 3944 '(menu-item "--"))
3913 (define-key menu [gdb-customize-reasons] 3945 (define-key menu [gdb-customize-reasons]
3914 '(menu-item "Customize switching..." 3946 '(menu-item "Customize switching..."
3915 (lambda () 3947 (lambda ()
3916 (interactive) 3948 (interactive)
3917 (customize-option 'gdb-switch-reasons)))) 3949 (customize-option 'gdb-switch-reasons))))
3918 (define-key menu [gdb-switch-when-another-stopped] 3950 (define-key menu [gdb-switch-when-another-stopped]
3919 (menu-bar-make-toggle gdb-toggle-switch-when-another-stopped gdb-switch-when-another-stopped 3951 (menu-bar-make-toggle gdb-toggle-switch-when-another-stopped
3952 gdb-switch-when-another-stopped
3920 "Automatically switch to stopped thread" 3953 "Automatically switch to stopped thread"
3921 "GDB thread switching %s" 3954 "GDB thread switching %s"
3922 "Switch to stopped thread")) 3955 "Switch to stopped thread"))
@@ -3930,18 +3963,18 @@ SPLIT-HORIZONTAL and show BUF in the new window."
3930;; show up right before Run button. 3963;; show up right before Run button.
3931(define-key-after gud-tool-bar-map [all-threads] 3964(define-key-after gud-tool-bar-map [all-threads]
3932 '(menu-item "Switch to non-stop/A mode" gdb-control-all-threads 3965 '(menu-item "Switch to non-stop/A mode" gdb-control-all-threads
3933 :image (find-image '((:type xpm :file "gud/thread.xpm"))) 3966 :image (find-image '((:type xpm :file "gud/thread.xpm")))
3934 :visible (and (eq gud-minor-mode 'gdbmi) 3967 :visible (and (eq gud-minor-mode 'gdbmi)
3935 gdb-non-stop 3968 gdb-non-stop
3936 (not gdb-gud-control-all-threads))) 3969 (not gdb-gud-control-all-threads)))
3937 'run) 3970 'run)
3938 3971
3939(define-key-after gud-tool-bar-map [current-thread] 3972(define-key-after gud-tool-bar-map [current-thread]
3940 '(menu-item "Switch to non-stop/T mode" gdb-control-current-thread 3973 '(menu-item "Switch to non-stop/T mode" gdb-control-current-thread
3941 :image (find-image '((:type xpm :file "gud/all.xpm"))) 3974 :image (find-image '((:type xpm :file "gud/all.xpm")))
3942 :visible (and (eq gud-minor-mode 'gdbmi) 3975 :visible (and (eq gud-minor-mode 'gdbmi)
3943 gdb-non-stop 3976 gdb-non-stop
3944 gdb-gud-control-all-threads)) 3977 gdb-gud-control-all-threads))
3945 'all-threads) 3978 'all-threads)
3946 3979
3947(defun gdb-frame-gdb-buffer () 3980(defun gdb-frame-gdb-buffer ()
@@ -3960,15 +3993,16 @@ SPLIT-HORIZONTAL and show BUF in the new window."
3960 (let ((same-window-regexps nil)) 3993 (let ((same-window-regexps nil))
3961 (select-window (display-buffer gud-comint-buffer nil 0)))) 3994 (select-window (display-buffer gud-comint-buffer nil 0))))
3962 3995
3963(defun gdb-set-window-buffer (name &optional ignore-dedicated) 3996(defun gdb-set-window-buffer (name &optional ignore-dedicated window)
3964 "Set buffer of selected window to NAME and dedicate window. 3997 "Set buffer of selected window to NAME and dedicate window.
3965 3998
3966When IGNORE-DEDICATED is non-nil, buffer is set even if selected 3999When IGNORE-DEDICATED is non-nil, buffer is set even if selected
3967window is dedicated." 4000window is dedicated."
4001 (unless window (setq window (selected-window)))
3968 (when ignore-dedicated 4002 (when ignore-dedicated
3969 (set-window-dedicated-p (selected-window) nil)) 4003 (set-window-dedicated-p window nil))
3970 (set-window-buffer (selected-window) (get-buffer name)) 4004 (set-window-buffer window (get-buffer name))
3971 (set-window-dedicated-p (selected-window) t)) 4005 (set-window-dedicated-p window t))
3972 4006
3973(defun gdb-setup-windows () 4007(defun gdb-setup-windows ()
3974 "Layout the window pattern for `gdb-many-windows'." 4008 "Layout the window pattern for `gdb-many-windows'."
@@ -3977,35 +4011,35 @@ window is dedicated."
3977 (delete-other-windows) 4011 (delete-other-windows)
3978 (gdb-display-breakpoints-buffer) 4012 (gdb-display-breakpoints-buffer)
3979 (delete-other-windows) 4013 (delete-other-windows)
3980 ; Don't dedicate. 4014 ;; Don't dedicate.
3981 (pop-to-buffer gud-comint-buffer) 4015 (pop-to-buffer gud-comint-buffer)
3982 (split-window nil ( / ( * (window-height) 3) 4)) 4016 (let ((win0 (selected-window))
3983 (split-window nil ( / (window-height) 3)) 4017 (win1 (split-window nil ( / ( * (window-height) 3) 4)))
3984 (split-window-horizontally) 4018 (win2 (split-window nil ( / (window-height) 3)))
3985 (other-window 1) 4019 (win3 (split-window-horizontally)))
3986 (gdb-set-window-buffer (gdb-locals-buffer-name)) 4020 (gdb-set-window-buffer (gdb-locals-buffer-name) nil win3)
3987 (other-window 1) 4021 (select-window win2)
3988 (switch-to-buffer 4022 (set-window-buffer
3989 (if gud-last-last-frame 4023 win2
3990 (gud-find-file (car gud-last-last-frame)) 4024 (if gud-last-last-frame
3991 (if gdb-main-file 4025 (gud-find-file (car gud-last-last-frame))
3992 (gud-find-file gdb-main-file) 4026 (if gdb-main-file
3993 ;; Put buffer list in window if we 4027 (gud-find-file gdb-main-file)
3994 ;; can't find a source file. 4028 ;; Put buffer list in window if we
3995 (list-buffers-noselect)))) 4029 ;; can't find a source file.
3996 (setq gdb-source-window (selected-window)) 4030 (list-buffers-noselect))))
3997 (split-window-horizontally) 4031 (setq gdb-source-window (selected-window))
3998 (other-window 1) 4032 (let ((win4 (split-window-horizontally)))
3999 (gdb-set-window-buffer 4033 (gdb-set-window-buffer
4000 (gdb-get-buffer-create 'gdb-inferior-io)) 4034 (gdb-get-buffer-create 'gdb-inferior-io) nil win4))
4001 (other-window 1) 4035 (select-window win1)
4002 (gdb-set-window-buffer (gdb-stack-buffer-name)) 4036 (gdb-set-window-buffer (gdb-stack-buffer-name))
4003 (split-window-horizontally) 4037 (let ((win5 (split-window-horizontally)))
4004 (other-window 1) 4038 (gdb-set-window-buffer (if gdb-show-threads-by-default
4005 (gdb-set-window-buffer (if gdb-show-threads-by-default 4039 (gdb-threads-buffer-name)
4006 (gdb-threads-buffer-name) 4040 (gdb-breakpoints-buffer-name))
4007 (gdb-breakpoints-buffer-name))) 4041 nil win5))
4008 (other-window 1)) 4042 (select-window win0)))
4009 4043
4010(defcustom gdb-many-windows nil 4044(defcustom gdb-many-windows nil
4011 "If nil just pop up the GUD buffer unless `gdb-show-main' is t. 4045 "If nil just pop up the GUD buffer unless `gdb-show-main' is t.
@@ -4022,34 +4056,33 @@ of the debugged program. Non-nil means display the layout shown for
4022With arg, display additional buffers iff arg is positive." 4056With arg, display additional buffers iff arg is positive."
4023 (interactive "P") 4057 (interactive "P")
4024 (setq gdb-many-windows 4058 (setq gdb-many-windows
4025 (if (null arg) 4059 (if (null arg)
4026 (not gdb-many-windows) 4060 (not gdb-many-windows)
4027 (> (prefix-numeric-value arg) 0))) 4061 (> (prefix-numeric-value arg) 0)))
4028 (message (format "Display of other windows %sabled" 4062 (message (format "Display of other windows %sabled"
4029 (if gdb-many-windows "en" "dis"))) 4063 (if gdb-many-windows "en" "dis")))
4030 (if (and gud-comint-buffer 4064 (if (and gud-comint-buffer
4031 (buffer-name gud-comint-buffer)) 4065 (buffer-name gud-comint-buffer))
4032 (condition-case nil 4066 (condition-case nil
4033 (gdb-restore-windows) 4067 (gdb-restore-windows)
4034 (error nil)))) 4068 (error nil))))
4035 4069
4036(defun gdb-restore-windows () 4070(defun gdb-restore-windows ()
4037 "Restore the basic arrangement of windows used by gdb. 4071 "Restore the basic arrangement of windows used by gdb.
4038This arrangement depends on the value of `gdb-many-windows'." 4072This arrangement depends on the value of `gdb-many-windows'."
4039 (interactive) 4073 (interactive)
4040 (pop-to-buffer gud-comint-buffer) ;Select the right window and frame. 4074 (pop-to-buffer gud-comint-buffer) ;Select the right window and frame.
4041 (delete-other-windows) 4075 (delete-other-windows)
4042 (if gdb-many-windows 4076 (if gdb-many-windows
4043 (gdb-setup-windows) 4077 (gdb-setup-windows)
4044 (when (or gud-last-last-frame gdb-show-main) 4078 (when (or gud-last-last-frame gdb-show-main)
4045 (split-window) 4079 (let ((win (split-window)))
4046 (other-window 1) 4080 (set-window-buffer
4047 (switch-to-buffer 4081 win
4048 (if gud-last-last-frame 4082 (if gud-last-last-frame
4049 (gud-find-file (car gud-last-last-frame)) 4083 (gud-find-file (car gud-last-last-frame))
4050 (gud-find-file gdb-main-file))) 4084 (gud-find-file gdb-main-file)))
4051 (setq gdb-source-window (selected-window)) 4085 (setq gdb-source-window win)))))
4052 (other-window 1))))
4053 4086
4054(defun gdb-reset () 4087(defun gdb-reset ()
4055 "Exit a debugging session cleanly. 4088 "Exit a debugging session cleanly.
@@ -4057,23 +4090,23 @@ Kills the gdb buffers, and resets variables and the source buffers."
4057 (dolist (buffer (buffer-list)) 4090 (dolist (buffer (buffer-list))
4058 (unless (eq buffer gud-comint-buffer) 4091 (unless (eq buffer gud-comint-buffer)
4059 (with-current-buffer buffer 4092 (with-current-buffer buffer
4060 (if (eq gud-minor-mode 'gdbmi) 4093 (if (eq gud-minor-mode 'gdbmi)
4061 (if (string-match "\\` ?\\*.+\\*\\'" (buffer-name)) 4094 (if (string-match "\\` ?\\*.+\\*\\'" (buffer-name))
4062 (kill-buffer nil) 4095 (kill-buffer nil)
4063 (gdb-remove-breakpoint-icons (point-min) (point-max) t) 4096 (gdb-remove-breakpoint-icons (point-min) (point-max) t)
4064 (setq gud-minor-mode nil) 4097 (setq gud-minor-mode nil)
4065 (kill-local-variable 'tool-bar-map) 4098 (kill-local-variable 'tool-bar-map)
4066 (kill-local-variable 'gdb-define-alist)))))) 4099 (kill-local-variable 'gdb-define-alist))))))
4067 (setq gdb-disassembly-position nil) 4100 (setq gdb-disassembly-position nil)
4068 (setq overlay-arrow-variable-list 4101 (setq overlay-arrow-variable-list
4069 (delq 'gdb-disassembly-position overlay-arrow-variable-list)) 4102 (delq 'gdb-disassembly-position overlay-arrow-variable-list))
4070 (setq fringe-indicator-alist '((overlay-arrow . right-triangle))) 4103 (setq fringe-indicator-alist '((overlay-arrow . right-triangle)))
4071 (setq gdb-stack-position nil) 4104 (setq gdb-stack-position nil)
4072 (setq overlay-arrow-variable-list 4105 (setq overlay-arrow-variable-list
4073 (delq 'gdb-stack-position overlay-arrow-variable-list)) 4106 (delq 'gdb-stack-position overlay-arrow-variable-list))
4074 (setq gdb-thread-position nil) 4107 (setq gdb-thread-position nil)
4075 (setq overlay-arrow-variable-list 4108 (setq overlay-arrow-variable-list
4076 (delq 'gdb-thread-position overlay-arrow-variable-list)) 4109 (delq 'gdb-thread-position overlay-arrow-variable-list))
4077 (if (boundp 'speedbar-frame) (speedbar-timer-fn)) 4110 (if (boundp 'speedbar-frame) (speedbar-timer-fn))
4078 (setq gud-running nil) 4111 (setq gud-running nil)
4079 (setq gdb-active-process nil) 4112 (setq gdb-active-process nil)
@@ -4085,12 +4118,12 @@ buffers, if required."
4085 (goto-char (point-min)) 4118 (goto-char (point-min))
4086 (if (re-search-forward gdb-source-file-regexp nil t) 4119 (if (re-search-forward gdb-source-file-regexp nil t)
4087 (setq gdb-main-file (match-string 1))) 4120 (setq gdb-main-file (match-string 1)))
4088 (if gdb-many-windows 4121 (if gdb-many-windows
4089 (gdb-setup-windows) 4122 (gdb-setup-windows)
4090 (gdb-get-buffer-create 'gdb-breakpoints-buffer) 4123 (gdb-get-buffer-create 'gdb-breakpoints-buffer)
4091 (if gdb-show-main 4124 (if gdb-show-main
4092 (let ((pop-up-windows t)) 4125 (let ((pop-up-windows t))
4093 (display-buffer (gud-find-file gdb-main-file)))))) 4126 (display-buffer (gud-find-file gdb-main-file))))))
4094 4127
4095;;from put-image 4128;;from put-image
4096(defun gdb-put-string (putstring pos &optional dprop &rest sprops) 4129(defun gdb-put-string (putstring pos &optional dprop &rest sprops)
@@ -4099,14 +4132,14 @@ PUTSTRING is displayed by putting an overlay into the current buffer with a
4099`before-string' string that has a `display' property whose value is 4132`before-string' string that has a `display' property whose value is
4100PUTSTRING." 4133PUTSTRING."
4101 (let ((string (make-string 1 ?x)) 4134 (let ((string (make-string 1 ?x))
4102 (buffer (current-buffer))) 4135 (buffer (current-buffer)))
4103 (setq putstring (copy-sequence putstring)) 4136 (setq putstring (copy-sequence putstring))
4104 (let ((overlay (make-overlay pos pos buffer)) 4137 (let ((overlay (make-overlay pos pos buffer))
4105 (prop (or dprop 4138 (prop (or dprop
4106 (list (list 'margin 'left-margin) putstring)))) 4139 (list (list 'margin 'left-margin) putstring))))
4107 (put-text-property 0 1 'display prop string) 4140 (put-text-property 0 1 'display prop string)
4108 (if sprops 4141 (if sprops
4109 (add-text-properties 0 1 sprops string)) 4142 (add-text-properties 0 1 sprops string))
4110 (overlay-put overlay 'put-break t) 4143 (overlay-put overlay 'put-break t)
4111 (overlay-put overlay 'before-string string)))) 4144 (overlay-put overlay 'before-string string))))
4112 4145
@@ -4119,7 +4152,7 @@ BUFFER nil or omitted means use the current buffer."
4119 (setq buffer (current-buffer))) 4152 (setq buffer (current-buffer)))
4120 (dolist (overlay (overlays-in start end)) 4153 (dolist (overlay (overlays-in start end))
4121 (when (overlay-get overlay 'put-break) 4154 (when (overlay-get overlay 'put-break)
4122 (delete-overlay overlay)))) 4155 (delete-overlay overlay))))
4123 4156
4124(defun gdb-put-breakpoint-icon (enabled bptno &optional line) 4157(defun gdb-put-breakpoint-icon (enabled bptno &optional line)
4125 (let* ((posns (gdb-line-posns (or line (line-number-at-pos)))) 4158 (let* ((posns (gdb-line-posns (or line (line-number-at-pos))))
@@ -4131,62 +4164,63 @@ BUFFER nil or omitted means use the current buffer."
4131 0 1 '(help-echo "mouse-1: clear bkpt, mouse-3: enable/disable bkpt") 4164 0 1 '(help-echo "mouse-1: clear bkpt, mouse-3: enable/disable bkpt")
4132 putstring) 4165 putstring)
4133 (if enabled 4166 (if enabled
4134 (add-text-properties 4167 (add-text-properties
4135 0 1 `(gdb-bptno ,bptno gdb-enabled t) putstring) 4168 0 1 `(gdb-bptno ,bptno gdb-enabled t) putstring)
4136 (add-text-properties 4169 (add-text-properties
4137 0 1 `(gdb-bptno ,bptno gdb-enabled nil) putstring)) 4170 0 1 `(gdb-bptno ,bptno gdb-enabled nil) putstring))
4138 (gdb-remove-breakpoint-icons start end) 4171 (gdb-remove-breakpoint-icons start end)
4139 (if (display-images-p) 4172 (if (display-images-p)
4140 (if (>= (or left-fringe-width 4173 (if (>= (or left-fringe-width
4141 (if source-window (car (window-fringes source-window))) 4174 (if source-window (car (window-fringes source-window)))
4142 gdb-buffer-fringe-width) 8) 4175 gdb-buffer-fringe-width) 8)
4143 (gdb-put-string 4176 (gdb-put-string
4144 nil (1+ start) 4177 nil (1+ start)
4145 `(left-fringe breakpoint 4178 `(left-fringe breakpoint
4146 ,(if enabled 4179 ,(if enabled
4147 'breakpoint-enabled 4180 'breakpoint-enabled
4148 'breakpoint-disabled)) 4181 'breakpoint-disabled))
4149 'gdb-bptno bptno 4182 'gdb-bptno bptno
4150 'gdb-enabled enabled) 4183 'gdb-enabled enabled)
4151 (when (< left-margin-width 2) 4184 (when (< left-margin-width 2)
4152 (save-current-buffer 4185 (save-current-buffer
4153 (setq left-margin-width 2) 4186 (setq left-margin-width 2)
4154 (if source-window 4187 (if source-window
4155 (set-window-margins 4188 (set-window-margins
4156 source-window 4189 source-window
4157 left-margin-width right-margin-width)))) 4190 left-margin-width right-margin-width))))
4158 (put-image 4191 (put-image
4159 (if enabled 4192 (if enabled
4160 (or breakpoint-enabled-icon 4193 (or breakpoint-enabled-icon
4161 (setq breakpoint-enabled-icon 4194 (setq breakpoint-enabled-icon
4162 (find-image `((:type xpm :data 4195 (find-image `((:type xpm :data
4163 ,breakpoint-xpm-data 4196 ,breakpoint-xpm-data
4164 :ascent 100 :pointer hand) 4197 :ascent 100 :pointer hand)
4165 (:type pbm :data 4198 (:type pbm :data
4166 ,breakpoint-enabled-pbm-data 4199 ,breakpoint-enabled-pbm-data
4167 :ascent 100 :pointer hand))))) 4200 :ascent 100 :pointer hand)))))
4168 (or breakpoint-disabled-icon 4201 (or breakpoint-disabled-icon
4169 (setq breakpoint-disabled-icon 4202 (setq breakpoint-disabled-icon
4170 (find-image `((:type xpm :data 4203 (find-image `((:type xpm :data
4171 ,breakpoint-xpm-data 4204 ,breakpoint-xpm-data
4172 :conversion disabled 4205 :conversion disabled
4173 :ascent 100 :pointer hand) 4206 :ascent 100 :pointer hand)
4174 (:type pbm :data 4207 (:type pbm :data
4175 ,breakpoint-disabled-pbm-data 4208 ,breakpoint-disabled-pbm-data
4176 :ascent 100 :pointer hand)))))) 4209 :ascent 100 :pointer hand))))))
4177 (+ start 1) 4210 (+ start 1)
4178 putstring 4211 putstring
4179 'left-margin)) 4212 'left-margin))
4180 (when (< left-margin-width 2) 4213 (when (< left-margin-width 2)
4181 (save-current-buffer 4214 (save-current-buffer
4182 (setq left-margin-width 2) 4215 (setq left-margin-width 2)
4183 (let ((window (get-buffer-window (current-buffer) 0))) 4216 (let ((window (get-buffer-window (current-buffer) 0)))
4184 (if window 4217 (if window
4185 (set-window-margins 4218 (set-window-margins
4186 window left-margin-width right-margin-width))))) 4219 window left-margin-width right-margin-width)))))
4187 (gdb-put-string 4220 (gdb-put-string
4188 (propertize putstring 4221 (propertize putstring
4189 'face (if enabled 'breakpoint-enabled 'breakpoint-disabled)) 4222 'face (if enabled
4223 'breakpoint-enabled 'breakpoint-disabled))
4190 (1+ start))))) 4224 (1+ start)))))
4191 4225
4192(defun gdb-remove-breakpoint-icons (start end &optional remove-margin) 4226(defun gdb-remove-breakpoint-icons (start end &optional remove-margin)
@@ -4197,8 +4231,8 @@ BUFFER nil or omitted means use the current buffer."
4197 (setq left-margin-width 0) 4231 (setq left-margin-width 0)
4198 (let ((window (get-buffer-window (current-buffer) 0))) 4232 (let ((window (get-buffer-window (current-buffer) 0)))
4199 (if window 4233 (if window
4200 (set-window-margins 4234 (set-window-margins
4201 window left-margin-width right-margin-width))))) 4235 window left-margin-width right-margin-width)))))
4202 4236
4203(provide 'gdb-mi) 4237(provide 'gdb-mi)
4204 4238
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el
index db8e82193b3..5561575ea20 100644
--- a/lisp/progmodes/grep.el
+++ b/lisp/progmodes/grep.el
@@ -1023,7 +1023,8 @@ This command shares argument histories with \\[lgrep] and \\[grep-find]."
1023 (read-from-minibuffer "Confirm: " 1023 (read-from-minibuffer "Confirm: "
1024 command nil nil 'grep-find-history)) 1024 command nil nil 'grep-find-history))
1025 (add-to-history 'grep-find-history command)) 1025 (add-to-history 'grep-find-history command))
1026 (let ((default-directory dir)) 1026 (let ((default-directory dir)
1027 (process-connection-type nil))
1027 (compilation-start command 'grep-mode)) 1028 (compilation-start command 'grep-mode))
1028 ;; Set default-directory if we started rgrep in the *grep* buffer. 1029 ;; Set default-directory if we started rgrep in the *grep* buffer.
1029 (if (eq next-error-last-buffer (current-buffer)) 1030 (if (eq next-error-last-buffer (current-buffer))
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el
index 259ee81c9ba..a54d1438368 100644
--- a/lisp/progmodes/gud.el
+++ b/lisp/progmodes/gud.el
@@ -1581,7 +1581,8 @@ and source-file directory for your debugger."
1581;; Last group is for return value, e.g. "> test.py(2)foo()->None" 1581;; Last group is for return value, e.g. "> test.py(2)foo()->None"
1582;; Either file or function name may be omitted: "> <string>(0)?()" 1582;; Either file or function name may be omitted: "> <string>(0)?()"
1583(defvar gud-pdb-marker-regexp 1583(defvar gud-pdb-marker-regexp
1584 "^> \\([-a-zA-Z0-9_/.:\\]*\\|<string>\\)(\\([0-9]+\\))\\([a-zA-Z0-9_]*\\|\\?\\|<module>\\)()\\(->[^\n]*\\)?\n") 1584 "^> \\([-a-zA-Z0-9_/.:\\]*\\|<string>\\)(\\([0-9]+\\))\\([a-zA-Z0-9_]*\\|\\?\\|<module>\\)()\\(->[^\n\r]*\\)?[\n\r]")
1585
1585(defvar gud-pdb-marker-regexp-file-group 1) 1586(defvar gud-pdb-marker-regexp-file-group 1)
1586(defvar gud-pdb-marker-regexp-line-group 2) 1587(defvar gud-pdb-marker-regexp-line-group 2)
1587(defvar gud-pdb-marker-regexp-fnname-group 3) 1588(defvar gud-pdb-marker-regexp-fnname-group 3)
diff --git a/lisp/progmodes/js.el b/lisp/progmodes/js.el
index a0437ccf9ae..1bdcb4cfa89 100644
--- a/lisp/progmodes/js.el
+++ b/lisp/progmodes/js.el
@@ -3306,8 +3306,8 @@ If one hasn't been set, or if it's stale, prompt for a new one."
3306 #'js--which-func-joiner) 3306 #'js--which-func-joiner)
3307 3307
3308 ;; Comments 3308 ;; Comments
3309 (setq comment-start "// ") 3309 (set (make-local-variable 'comment-start) "// ")
3310 (setq comment-end "") 3310 (set (make-local-variable 'comment-end) "")
3311 (set (make-local-variable 'fill-paragraph-function) 3311 (set (make-local-variable 'fill-paragraph-function)
3312 'js-c-fill-paragraph) 3312 'js-c-fill-paragraph)
3313 3313
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index 1da819660d2..80358e1c651 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -4,10 +4,9 @@
4 4
5;; Author: Alex Schroeder <alex@gnu.org> 5;; Author: Alex Schroeder <alex@gnu.org>
6;; Maintainer: Michael Mauger <mmaug@yahoo.com> 6;; Maintainer: Michael Mauger <mmaug@yahoo.com>
7;; Version: 2.8 7;; Version: 3.0
8;; Keywords: comm languages processes 8;; Keywords: comm languages processes
9;; URL: http://savannah.gnu.org/projects/emacs/ 9;; URL: http://savannah.gnu.org/projects/emacs/
10;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
11 10
12;; This file is part of GNU Emacs. 11;; This file is part of GNU Emacs.
13 12
@@ -46,7 +45,7 @@
46;; available in early versions of sql.el. This support has been 45;; available in early versions of sql.el. This support has been
47;; extended and formalized in later versions. Part of the impetus for 46;; extended and formalized in later versions. Part of the impetus for
48;; the improved support of SQL flavors was borne out of the current 47;; the improved support of SQL flavors was borne out of the current
49;; maintainer's consulting experience. In the past fifteen years, I 48;; maintainers consulting experience. In the past twenty years, I
50;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer. 49;; have used Oracle, Sybase, Informix, MySQL, Postgres, and SQLServer.
51;; On some assignments, I have used two or more of these concurrently. 50;; On some assignments, I have used two or more of these concurrently.
52 51
@@ -130,7 +129,7 @@
130;; identifier characters. 129;; identifier characters.
131 130
132;; (sql-set-product-feature 'xyz 131;; (sql-set-product-feature 'xyz
133;; :syntax-alist ((?# . "w"))) 132;; :syntax-alist ((?# . "_")))
134 133
135;; 4) Define the interactive command interpreter for the database 134;; 4) Define the interactive command interpreter for the database
136;; product. 135;; product.
@@ -184,7 +183,7 @@
184;; (sql-set-product-feature 'xyz 183;; (sql-set-product-feature 'xyz
185;; :sqli-comint-func 'my-sql-comint-xyz) 184;; :sqli-comint-func 'my-sql-comint-xyz)
186 185
187;; 6) Define a convienence function to invoke the SQL interpreter. 186;; 6) Define a convenience function to invoke the SQL interpreter.
188 187
189;; (defun my-sql-xyz (&optional buffer) 188;; (defun my-sql-xyz (&optional buffer)
190;; "Run ixyz by XyzDB as an inferior process." 189;; "Run ixyz by XyzDB as an inferior process."
@@ -230,9 +229,18 @@
230(eval-when-compile 229(eval-when-compile
231 (require 'regexp-opt)) 230 (require 'regexp-opt))
232(require 'custom) 231(require 'custom)
232(require 'thingatpt)
233(eval-when-compile ;; needed in Emacs 19, 20 233(eval-when-compile ;; needed in Emacs 19, 20
234 (setq max-specpdl-size (max max-specpdl-size 2000))) 234 (setq max-specpdl-size (max max-specpdl-size 2000)))
235 235
236(defun sql-signum (n)
237 "Return 1, 0, or -1 to identify the sign of N."
238 (cond
239 ((not (numberp n)) nil)
240 ((< n 0) -1)
241 ((> n 0) 1)
242 (t 0)))
243
236(defvar font-lock-keyword-face) 244(defvar font-lock-keyword-face)
237(defvar font-lock-set-defaults) 245(defvar font-lock-set-defaults)
238(defvar font-lock-string-face) 246(defvar font-lock-string-face)
@@ -327,7 +335,8 @@ Customizing your password will store it in your ~/.emacs file."
327(defvar sql-product-alist 335(defvar sql-product-alist
328 '((ansi 336 '((ansi
329 :name "ANSI" 337 :name "ANSI"
330 :font-lock sql-mode-ansi-font-lock-keywords) 338 :font-lock sql-mode-ansi-font-lock-keywords
339 :statement sql-ansi-statement-starters)
331 340
332 (db2 341 (db2
333 :name "DB2" 342 :name "DB2"
@@ -392,7 +401,7 @@ Customizing your password will store it in your ~/.emacs file."
392 :sqli-comint-func sql-comint-ms 401 :sqli-comint-func sql-comint-ms
393 :prompt-regexp "^[0-9]*>" 402 :prompt-regexp "^[0-9]*>"
394 :prompt-length 5 403 :prompt-length 5
395 :syntax-alist ((?@ . "w")) 404 :syntax-alist ((?@ . "_"))
396 :terminator ("^go" . "go")) 405 :terminator ("^go" . "go"))
397 406
398 (mysql 407 (mysql
@@ -408,6 +417,7 @@ Customizing your password will store it in your ~/.emacs file."
408 :prompt-regexp "^mysql> " 417 :prompt-regexp "^mysql> "
409 :prompt-length 6 418 :prompt-length 6
410 :prompt-cont-regexp "^ -> " 419 :prompt-cont-regexp "^ -> "
420 :syntax-alist ((?# . "< b"))
411 :input-filter sql-remove-tabs-filter) 421 :input-filter sql-remove-tabs-filter)
412 422
413 (oracle 423 (oracle
@@ -417,11 +427,15 @@ Customizing your password will store it in your ~/.emacs file."
417 :sqli-options sql-oracle-options 427 :sqli-options sql-oracle-options
418 :sqli-login sql-oracle-login-params 428 :sqli-login sql-oracle-login-params
419 :sqli-comint-func sql-comint-oracle 429 :sqli-comint-func sql-comint-oracle
430 :list-all sql-oracle-list-all
431 :list-table sql-oracle-list-table
432 :completion-object sql-oracle-completion-object
420 :prompt-regexp "^SQL> " 433 :prompt-regexp "^SQL> "
421 :prompt-length 5 434 :prompt-length 5
422 :prompt-cont-regexp "^\\s-*\\d+> " 435 :prompt-cont-regexp "^\\s-*[[:digit:]]+ "
423 :syntax-alist ((?$ . "w") (?# . "w")) 436 :statement sql-oracle-statement-starters
424 :terminator ("\\(^/\\|;\\)" . "/") 437 :syntax-alist ((?$ . "_") (?# . "_"))
438 :terminator ("\\(^/\\|;\\)$" . "/")
425 :input-filter sql-placeholders-filter) 439 :input-filter sql-placeholders-filter)
426 440
427 (postgres 441 (postgres
@@ -434,11 +448,12 @@ Customizing your password will store it in your ~/.emacs file."
434 :sqli-comint-func sql-comint-postgres 448 :sqli-comint-func sql-comint-postgres
435 :list-all ("\\d+" . "\\dS+") 449 :list-all ("\\d+" . "\\dS+")
436 :list-table ("\\d+ %s" . "\\dS+ %s") 450 :list-table ("\\d+ %s" . "\\dS+ %s")
437 :prompt-regexp "^.*=[#>] " 451 :completion-object sql-postgres-completion-object
452 :prompt-regexp "^\\w*=[#>] "
438 :prompt-length 5 453 :prompt-length 5
439 :prompt-cont-regexp "^.*[-(][#>] " 454 :prompt-cont-regexp "^\\w*[-(][#>] "
440 :input-filter sql-remove-tabs-filter 455 :input-filter sql-remove-tabs-filter
441 :terminator ("\\(^\\s-*\\\\g\\|;\\)" . ";")) 456 :terminator ("\\(^\\s-*\\\\g$\\|;\\)" . "\\g"))
442 457
443 (solid 458 (solid
444 :name "Solid" 459 :name "Solid"
@@ -460,9 +475,10 @@ Customizing your password will store it in your ~/.emacs file."
460 :sqli-comint-func sql-comint-sqlite 475 :sqli-comint-func sql-comint-sqlite
461 :list-all ".tables" 476 :list-all ".tables"
462 :list-table ".schema %s" 477 :list-table ".schema %s"
478 :completion-object sql-sqlite-completion-object
463 :prompt-regexp "^sqlite> " 479 :prompt-regexp "^sqlite> "
464 :prompt-length 8 480 :prompt-length 8
465 :prompt-cont-regexp "^ ...> " 481 :prompt-cont-regexp "^ \.\.\.> "
466 :terminator ";") 482 :terminator ";")
467 483
468 (sybase 484 (sybase
@@ -474,7 +490,7 @@ Customizing your password will store it in your ~/.emacs file."
474 :sqli-comint-func sql-comint-sybase 490 :sqli-comint-func sql-comint-sybase
475 :prompt-regexp "^SQL> " 491 :prompt-regexp "^SQL> "
476 :prompt-length 5 492 :prompt-length 5
477 :syntax-alist ((?@ . "w")) 493 :syntax-alist ((?@ . "_"))
478 :terminator ("^go" . "go")) 494 :terminator ("^go" . "go"))
479 ) 495 )
480 "An alist of product specific configuration settings. 496 "An alist of product specific configuration settings.
@@ -513,10 +529,11 @@ may be any one of the following:
513 :sqli-comint-func name of a function which accepts no 529 :sqli-comint-func name of a function which accepts no
514 parameters that will use the values of 530 parameters that will use the values of
515 `sql-user', `sql-password', 531 `sql-user', `sql-password',
516 `sql-database' and `sql-server' to open a 532 `sql-database', `sql-server' and
517 comint buffer and connect to the 533 `sql-port' to open a comint buffer and
518 database. Do product specific 534 connect to the database. Do product
519 configuration of comint in this function. 535 specific configuration of comint in this
536 function.
520 537
521 :list-all Command string or function which produces 538 :list-all Command string or function which produces
522 a listing of all objects in the database. 539 a listing of all objects in the database.
@@ -535,6 +552,20 @@ may be any one of the following:
535 produces the standard list and the cdr 552 produces the standard list and the cdr
536 produces an enhanced list. 553 produces an enhanced list.
537 554
555 :completion-object A function that returns a list of
556 objects. Called with a single
557 parameter--if nil then list objects
558 accessible in the current schema, if
559 not-nil it is the name of a schema whose
560 objects should be listed.
561
562 :completion-column A function that returns a list of
563 columns. Called with a single
564 parameter--if nil then list objects
565 accessible in the current schema, if
566 not-nil it is the name of a schema whose
567 objects should be listed.
568
538 :prompt-regexp regular expression string that matches 569 :prompt-regexp regular expression string that matches
539 the prompt issued by the product 570 the prompt issued by the product
540 interpreter. 571 interpreter.
@@ -555,6 +586,9 @@ may be any one of the following:
555 filtered string. May also be a list of 586 filtered string. May also be a list of
556 such functions. 587 such functions.
557 588
589 :statement name of a variable containing a regexp that
590 matches the beginning of SQL statements.
591
558 :terminator the terminator to be sent after a 592 :terminator the terminator to be sent after a
559 `sql-send-string', `sql-send-region', 593 `sql-send-string', `sql-send-region',
560 `sql-send-paragraph' and 594 `sql-send-paragraph' and
@@ -574,7 +608,7 @@ using `sql-get-product-feature' to lookup the product specific
574settings.") 608settings.")
575 609
576(defvar sql-indirect-features 610(defvar sql-indirect-features
577 '(:font-lock :sqli-program :sqli-options :sqli-login)) 611 '(:font-lock :sqli-program :sqli-options :sqli-login :statement))
578 612
579(defcustom sql-connection-alist nil 613(defcustom sql-connection-alist nil
580 "An alist of connection parameters for interacting with a SQL 614 "An alist of connection parameters for interacting with a SQL
@@ -683,6 +717,13 @@ it automatically."
683 :version "22.2" 717 :version "22.2"
684 :group 'SQL) 718 :group 'SQL)
685 719
720(defvar sql-contains-names nil
721 "When non-nil, the current buffer contains database names.
722
723Globally should be set to nil; it will be non-nil in `sql-mode',
724`sql-interactive-mode' and list all buffers.")
725
726
686(defcustom sql-pop-to-buffer-after-send-region nil 727(defcustom sql-pop-to-buffer-after-send-region nil
687 "When non-nil, pop to the buffer SQL statements are sent to. 728 "When non-nil, pop to the buffer SQL statements are sent to.
688 729
@@ -770,6 +811,19 @@ is changed."
770 :type 'hook 811 :type 'hook
771 :group 'SQL) 812 :group 'SQL)
772 813
814;; Customization for ANSI
815
816(defcustom sql-ansi-statement-starters (regexp-opt '(
817 "create" "alter" "drop"
818 "select" "insert" "update" "delete" "merge"
819 "grant" "revoke"
820))
821 "Regexp of keywords that start SQL commands
822
823All products share this list; products should define a regexp to
824identify additional keywords in a variable defined by
825the :statement feature.")
826
773;; Customization for Oracle 827;; Customization for Oracle
774 828
775(defcustom sql-oracle-program "sqlplus" 829(defcustom sql-oracle-program "sqlplus"
@@ -795,18 +849,22 @@ You will find the file in your Orant\\bin directory."
795 :version "24.1" 849 :version "24.1"
796 :group 'SQL) 850 :group 'SQL)
797 851
852(defcustom sql-oracle-statement-starters (regexp-opt '("declare" "begin" "with"))
853 "Additional statement starting keywords in Oracle.")
854
798(defcustom sql-oracle-scan-on t 855(defcustom sql-oracle-scan-on t
799 "Non-nil if placeholders should be replaced in Oracle SQLi. 856 "Non-nil if placeholders should be replaced in Oracle SQLi.
800 857
801When non-nil, Emacs will scan text sent to sqlplus and prompt 858When non-nil, Emacs will scan text sent to sqlplus and prompt
802for replacement text for & placeholders as sqlplus does. This 859for replacement text for & placeholders as sqlplus does. This
803is needed on Windows where sqlplus output is buffered and the 860is needed on Windows where SQL*Plus output is buffered and the
804prompts are not shown until after the text is entered. 861prompts are not shown until after the text is entered.
805 862
806You will probably want to issue the following command in sqlplus 863You need to issue the following command in SQL*Plus to be safe:
807to be safe: 864
865 SET DEFINE OFF
808 866
809 SET SCAN OFF" 867In older versions of SQL*Plus, this was the SET SCAN OFF command."
810 :type 'boolean 868 :type 'boolean
811 :group 'SQL) 869 :group 'SQL)
812 870
@@ -833,7 +891,7 @@ Starts `sql-interactive-mode' after doing some setup."
833 :version "24.1" 891 :version "24.1"
834 :group 'SQL) 892 :group 'SQL)
835 893
836;; Customization for MySql 894;; Customization for MySQL
837 895
838(defcustom sql-mysql-program "mysql" 896(defcustom sql-mysql-program "mysql"
839 "Command to start mysql by TcX. 897 "Command to start mysql by TcX.
@@ -851,7 +909,7 @@ on Windows: \"-C\" \"-t\" \"-f\" \"-n\"."
851 :group 'SQL) 909 :group 'SQL)
852 910
853(defcustom sql-mysql-login-params '(user password database server) 911(defcustom sql-mysql-login-params '(user password database server)
854 "List of login parameters needed to connect to MySql." 912 "List of login parameters needed to connect to MySQL."
855 :type 'sql-login-params 913 :type 'sql-login-params
856 :version "24.1" 914 :version "24.1"
857 :group 'SQL) 915 :group 'SQL)
@@ -1085,13 +1143,13 @@ You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
1085 1143
1086Used by `sql-rename-buffer'.") 1144Used by `sql-rename-buffer'.")
1087 1145
1088(defun sql-buffer-live-p (buffer &optional product) 1146(defun sql-buffer-live-p (buffer &optional product connection)
1089 "Returns non-nil if the process associated with buffer is live. 1147 "Returns non-nil if the process associated with buffer is live.
1090 1148
1091BUFFER can be a buffer object or a buffer name. The buffer must 1149BUFFER can be a buffer object or a buffer name. The buffer must
1092be a live buffer, have an running process attached to it, be in 1150be a live buffer, have an running process attached to it, be in
1093`sql-interactive-mode', and, if PRODUCT is specified, it's 1151`sql-interactive-mode', and, if PRODUCT or CONNECTION are
1094`sql-product' must match." 1152specified, it's `sql-product' or `sql-connection' must match."
1095 1153
1096 (when buffer 1154 (when buffer
1097 (setq buffer (get-buffer buffer)) 1155 (setq buffer (get-buffer buffer))
@@ -1102,7 +1160,9 @@ be a live buffer, have an running process attached to it, be in
1102 (with-current-buffer buffer 1160 (with-current-buffer buffer
1103 (and (derived-mode-p 'sql-interactive-mode) 1161 (and (derived-mode-p 'sql-interactive-mode)
1104 (or (not product) 1162 (or (not product)
1105 (eq product sql-product))))))) 1163 (eq product sql-product))
1164 (or (not connection)
1165 (eq connection sql-connection)))))))
1106 1166
1107;; Keymap for sql-interactive-mode. 1167;; Keymap for sql-interactive-mode.
1108 1168
@@ -1136,6 +1196,8 @@ Based on `comint-mode-map'.")
1136 (define-key map (kbd "C-c C-i") 'sql-product-interactive) 1196 (define-key map (kbd "C-c C-i") 'sql-product-interactive)
1137 (define-key map (kbd "C-c C-l a") 'sql-list-all) 1197 (define-key map (kbd "C-c C-l a") 'sql-list-all)
1138 (define-key map (kbd "C-c C-l t") 'sql-list-table) 1198 (define-key map (kbd "C-c C-l t") 'sql-list-table)
1199 (define-key map [remap beginning-of-defun] 'sql-beginning-of-statement)
1200 (define-key map [remap end-of-defun] 'sql-end-of-statement)
1139 map) 1201 map)
1140 "Mode map used for `sql-mode'.") 1202 "Mode map used for `sql-mode'.")
1141 1203
@@ -1151,8 +1213,10 @@ Based on `comint-mode-map'.")
1151 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)] 1213 ["Send Buffer" sql-send-buffer (sql-buffer-live-p sql-buffer)]
1152 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)] 1214 ["Send String" sql-send-string (sql-buffer-live-p sql-buffer)]
1153 "--" 1215 "--"
1154 ["List all objects" sql-list-all (sql-buffer-live-p sql-buffer)] 1216 ["List all objects" sql-list-all (and (sql-buffer-live-p sql-buffer)
1155 ["List table details" sql-list-table (sql-buffer-live-p sql-buffer)] 1217 (sql-get-product-feature sql-product :list-all))]
1218 ["List table details" sql-list-table (and (sql-buffer-live-p sql-buffer)
1219 (sql-get-product-feature sql-product :list-table))]
1156 "--" 1220 "--"
1157 ["Start SQLi session" sql-product-interactive 1221 ["Start SQLi session" sql-product-interactive
1158 :visible (not sql-connection-alist) 1222 :visible (not sql-connection-alist)
@@ -1194,8 +1258,8 @@ Based on `comint-mode-map'.")
1194 ["Rename Buffer" sql-rename-buffer t] 1258 ["Rename Buffer" sql-rename-buffer t]
1195 ["Save Connection" sql-save-connection (not sql-connection)] 1259 ["Save Connection" sql-save-connection (not sql-connection)]
1196 "--" 1260 "--"
1197 ["List all objects" sql-list-all t] 1261 ["List all objects" sql-list-all (sql-get-product-feature sql-product :list-all)]
1198 ["List table details" sql-list-table t])) 1262 ["List table details" sql-list-table (sql-get-product-feature sql-product :list-table)]))
1199 1263
1200;; Abbreviations -- if you want more of them, define them in your 1264;; Abbreviations -- if you want more of them, define them in your
1201;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too. 1265;; ~/.emacs file. Abbrevs have to be enabled in your ~/.emacs, too.
@@ -1238,8 +1302,9 @@ Based on `comint-mode-map'.")
1238 (modify-syntax-entry ?' "\"" table) 1302 (modify-syntax-entry ?' "\"" table)
1239 ;; double quotes (") don't delimit strings 1303 ;; double quotes (") don't delimit strings
1240 (modify-syntax-entry ?\" "." table) 1304 (modify-syntax-entry ?\" "." table)
1241 ;; backslash is no escape character 1305 ;; Make these all punctuation
1242 (modify-syntax-entry ?\\ "." table) 1306 (mapc (lambda (c) (modify-syntax-entry c "." table))
1307 (string-to-list "!#$%&+,.:;<=>?@\\|"))
1243 table) 1308 table)
1244 "Syntax table used in `sql-mode' and `sql-interactive-mode'.") 1309 "Syntax table used in `sql-mode' and `sql-interactive-mode'.")
1245 1310
@@ -1298,20 +1363,45 @@ statement. The format of variable should be a valid
1298 1363
1299 ;; Remove keywords that are defined in ANSI 1364 ;; Remove keywords that are defined in ANSI
1300 (setq kwd keywords) 1365 (setq kwd keywords)
1301 (dolist (k keywords) 1366 ;; (dolist (k keywords)
1302 (catch 'next 1367 ;; (catch 'next
1303 (dolist (a sql-mode-ansi-font-lock-keywords) 1368 ;; (dolist (a sql-mode-ansi-font-lock-keywords)
1304 (when (and (eq face (cdr a)) 1369 ;; (when (and (eq face (cdr a))
1305 (eq (string-match (car a) k 0) 0) 1370 ;; (eq (string-match (car a) k 0) 0)
1306 (eq (match-end 0) (length k))) 1371 ;; (eq (match-end 0) (length k)))
1307 (setq kwd (delq k kwd)) 1372 ;; (setq kwd (delq k kwd))
1308 (throw 'next nil))))) 1373 ;; (throw 'next nil)))))
1309 1374
1310 ;; Create a properly formed font-lock-keywords item 1375 ;; Create a properly formed font-lock-keywords item
1311 (cons (concat (car bdy) 1376 (cons (concat (car bdy)
1312 (regexp-opt kwd t) 1377 (regexp-opt kwd t)
1313 (cdr bdy)) 1378 (cdr bdy))
1314 face)))) 1379 face)))
1380
1381 (defun sql-regexp-abbrev (keyword)
1382 (let ((brk (string-match "[~]" keyword))
1383 (len (length keyword))
1384 (sep "\\(?:")
1385 re i)
1386 (if (not brk)
1387 keyword
1388 (setq re (substring keyword 0 brk)
1389 i (+ 2 brk)
1390 brk (1+ brk))
1391 (while (<= i len)
1392 (setq re (concat re sep (substring keyword brk i))
1393 sep "\\|"
1394 i (1+ i)))
1395 (concat re "\\)?"))))
1396
1397 (defun sql-regexp-abbrev-list (&rest keyw-list)
1398 (let ((re nil)
1399 (sep "\\<\\(?:"))
1400 (while keyw-list
1401 (setq re (concat re sep (sql-regexp-abbrev (car keyw-list)))
1402 sep "\\|"
1403 keyw-list (cdr keyw-list)))
1404 (concat re "\\)\\>"))))
1315 1405
1316(eval-when-compile 1406(eval-when-compile
1317 (setq sql-mode-ansi-font-lock-keywords 1407 (setq sql-mode-ansi-font-lock-keywords
@@ -1346,6 +1436,7 @@ statement. The format of variable should be a valid
1346"user_defined_type_catalog" "user_defined_type_name" 1436"user_defined_type_catalog" "user_defined_type_name"
1347"user_defined_type_schema" 1437"user_defined_type_schema"
1348) 1438)
1439
1349 ;; ANSI Reserved keywords 1440 ;; ANSI Reserved keywords
1350 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1441 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1351"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all" 1442"absolute" "action" "add" "admin" "after" "aggregate" "alias" "all"
@@ -1395,6 +1486,7 @@ statement. The format of variable should be a valid
1395"substring" "sum" "system_user" "translate" "treat" "trim" "upper" 1486"substring" "sum" "system_user" "translate" "treat" "trim" "upper"
1396"user" 1487"user"
1397) 1488)
1489
1398 ;; ANSI Data Types 1490 ;; ANSI Data Types
1399 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1491 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1400"array" "binary" "bit" "blob" "boolean" "char" "character" "clob" 1492"array" "binary" "bit" "blob" "boolean" "char" "character" "clob"
@@ -1414,86 +1506,142 @@ function `regexp-opt'. Therefore, take a look at the source before
1414you define your own `sql-mode-ansi-font-lock-keywords'. You may want 1506you define your own `sql-mode-ansi-font-lock-keywords'. You may want
1415to add functions and PL/SQL keywords.") 1507to add functions and PL/SQL keywords.")
1416 1508
1509(defun sql-oracle-show-reserved-words ()
1510 ;; This function is for use by the maintainer of SQL.EL only.
1511 (interactive)
1512 (if (or (and (not (derived-mode-p 'sql-mode))
1513 (not (derived-mode-p 'sql-interactive-mode)))
1514 (not sql-buffer)
1515 (not (eq sql-product 'oracle)))
1516 (error "Not an Oracle buffer")
1517
1518 (let ((b "*RESERVED WORDS*"))
1519 (sql-execute sql-buffer b
1520 (concat "SELECT "
1521 " keyword "
1522 ", reserved AS \"Res\" "
1523 ", res_type AS \"Type\" "
1524 ", res_attr AS \"Attr\" "
1525 ", res_semi AS \"Semi\" "
1526 ", duplicate AS \"Dup\" "
1527 "FROM V$RESERVED_WORDS "
1528 "WHERE length > 1 "
1529 "AND SUBSTR(keyword, 1, 1) BETWEEN 'A' AND 'Z' "
1530 "ORDER BY 2 DESC, 3 DESC, 4 DESC, 5 DESC, 6 DESC, 1;")
1531 nil nil)
1532 (with-current-buffer b
1533 (set (make-local-variable 'sql-product) 'oracle)
1534 (sql-product-font-lock t nil)
1535 (font-lock-mode +1)))))
1536
1417(defvar sql-mode-oracle-font-lock-keywords 1537(defvar sql-mode-oracle-font-lock-keywords
1418 (eval-when-compile 1538 (eval-when-compile
1419 (list 1539 (list
1420 ;; Oracle SQL*Plus Commands 1540 ;; Oracle SQL*Plus Commands
1421 (cons 1541 ;; Only recognized in they start in column 1 and the
1422 (concat 1542 ;; abbreviation is followed by a space or the end of line.
1423 "^\\s-*\\(?:\\(?:" (regexp-opt '(
1424"@" "@@" "accept" "append" "archive" "attribute" "break"
1425"btitle" "change" "clear" "column" "connect" "copy" "define"
1426"del" "describe" "disconnect" "edit" "execute" "exit" "get" "help"
1427"host" "input" "list" "password" "pause" "print" "prompt" "recover"
1428"remark" "repfooter" "repheader" "run" "save" "show" "shutdown"
1429"spool" "start" "startup" "store" "timing" "ttitle" "undefine"
1430"variable" "whenever"
1431) t)
1432 1543
1433 "\\)\\|" 1544 "\\|"
1434 "\\(?:compute\\s-+\\(?:avg\\|cou\\|min\\|max\\|num\\|sum\\|std\\|var\\)\\)\\|" 1545 (list (concat "^" (sql-regexp-abbrev "rem~ark") "\\(?:\\s-.*\\)?$")
1435 "\\(?:set\\s-+\\(" 1546 0 'font-lock-comment-face t)
1436 1547
1437 (regexp-opt 1548 (list
1438 '("appi" "appinfo" "array" "arraysize" "auto" "autocommit" 1549 (concat
1439 "autop" "autoprint" "autorecovery" "autot" "autotrace" "blo" 1550 "^\\(?:"
1440 "blockterminator" "buffer" "closecursor" "cmds" "cmdsep" 1551 (sql-regexp-abbrev-list
1441 "colsep" "com" "compatibility" "con" "concat" "constraint" 1552 "[@]\\{1,2\\}" "acc~ept" "a~ppend" "archive" "attribute"
1442 "constraints" "copyc" "copycommit" "copytypecheck" "database" 1553 "bre~ak" "bti~tle" "c~hange" "cl~ear" "col~umn" "conn~ect"
1443 "def" "define" "document" "echo" "editf" "editfile" "emb" 1554 "copy" "def~ine" "del" "desc~ribe" "disc~onnect" "ed~it"
1444 "embedded" "esc" "escape" "feed" "feedback" "flagger" "flu" 1555 "exec~ute" "exit" "get" "help" "ho~st" "[$]" "i~nput" "l~ist"
1445 "flush" "hea" "heading" "heads" "headsep" "instance" "lin" 1556 "passw~ord" "pau~se" "pri~nt" "pro~mpt" "quit" "recover"
1446 "linesize" "lobof" "loboffset" "logsource" "long" "longc" 1557 "repf~ooter" "reph~eader" "r~un" "sav~e" "sho~w" "shutdown"
1447 "longchunksize" "maxdata" "newp" "newpage" "null" "num" 1558 "spo~ol" "sta~rt" "startup" "store" "tim~ing" "tti~tle"
1448 "numf" "numformat" "numwidth" "pages" "pagesize" "pau" 1559 "undef~ine" "var~iable" "whenever")
1449 "pause" "recsep" "recsepchar" "role" "scan" "serveroutput" 1560 "\\|"
1450 "shift" "shiftinout" "show" "showmode" "space" "sqlbl" 1561 (concat "\\(?:"
1451 "sqlblanklines" "sqlc" "sqlcase" "sqlco" "sqlcontinue" "sqln" 1562 (sql-regexp-abbrev "comp~ute")
1452 "sqlnumber" "sqlp" "sqlpluscompat" "sqlpluscompatibility" 1563 "\\s-+"
1453 "sqlpre" "sqlprefix" "sqlprompt" "sqlt" "sqlterminator" 1564 (sql-regexp-abbrev-list
1454 "statement_id" "suf" "suffix" "tab" "term" "termout" "ti" 1565 "avg" "cou~nt" "min~imum" "max~imum" "num~ber" "sum"
1455 "time" "timi" "timing" "transaction" "trim" "trimout" "trims" 1566 "std" "var~iance")
1456 "trimspool" "truncate" "und" "underline" "ver" "verify" "wra" 1567 "\\)")
1457 "wrap")) "\\)\\)" 1568 "\\|"
1458 1569 (concat "\\(?:set\\s-+"
1459 "\\)\\b.*" 1570 (sql-regexp-abbrev-list
1460 ) 1571 "appi~nfo" "array~size" "auto~commit" "autop~rint"
1461 'font-lock-doc-face) 1572 "autorecovery" "autot~race" "blo~ckterminator"
1462 '("^\\s-*rem\\(?:ark\\)?\\>.*" . font-lock-comment-face) 1573 "cmds~ep" "colsep" "com~patibility" "con~cat"
1574 "copyc~ommit" "copytypecheck" "def~ine" "describe"
1575 "echo" "editf~ile" "emb~edded" "esc~ape" "feed~back"
1576 "flagger" "flu~sh" "hea~ding" "heads~ep" "instance"
1577 "lin~esize" "lobof~fset" "long" "longc~hunksize"
1578 "mark~up" "newp~age" "null" "numf~ormat" "num~width"
1579 "pages~ize" "pau~se" "recsep" "recsepchar"
1580 "scan" "serverout~put" "shift~inout" "show~mode"
1581 "sqlbl~anklines" "sqlc~ase" "sqlco~ntinue"
1582 "sqln~umber" "sqlpluscompat~ibility" "sqlpre~fix"
1583 "sqlp~rompt" "sqlt~erminator" "suf~fix" "tab"
1584 "term~out" "ti~me" "timi~ng" "trim~out" "trims~pool"
1585 "und~erline" "ver~ify" "wra~p")
1586 "\\)")
1587
1588 "\\)\\(?:\\s-.*\\)?\\(?:[-]\n.*\\)*$")
1589 0 'font-lock-doc-face t)
1463 1590
1464 ;; Oracle Functions 1591 ;; Oracle Functions
1465 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil 1592 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
1466"abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2" 1593"abs" "acos" "add_months" "appendchildxml" "ascii" "asciistr" "asin"
1467"avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid" 1594"atan" "atan2" "avg" "bfilename" "bin_to_num" "bitand" "cardinality"
1468"chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh" 1595"cast" "ceil" "chartorowid" "chr" "cluster_id" "cluster_probability"
1469"count" "covar_pop" "covar_samp" "cume_dist" "current_date" 1596"cluster_set" "coalesce" "collect" "compose" "concat" "convert" "corr"
1470"current_timestamp" "current_user" "dbtimezone" "decode" "decompose" 1597"corr_k" "corr_s" "cos" "cosh" "count" "covar_pop" "covar_samp"
1471"dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp" 1598"cube_table" "cume_dist" "currrent_date" "currrent_timestamp" "cv"
1472"extract" "extractvalue" "first" "first_value" "floor" "following" 1599"dataobj_to_partition" "dbtimezone" "decode" "decompose" "deletexml"
1473"from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap" 1600"dense_rank" "depth" "deref" "dump" "empty_blob" "empty_clob"
1474"instr" "lag" "last" "last_day" "last_value" "lead" "least" "length" 1601"existsnode" "exp" "extract" "extractvalue" "feature_id" "feature_set"
1475"ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min" 1602"feature_value" "first" "first_value" "floor" "from_tz" "greatest"
1476"mod" "months_between" "new_time" "next_day" "nls_charset_decl_len" 1603"grouping" "grouping_id" "group_id" "hextoraw" "initcap"
1604"insertchildxml" "insertchildxmlafter" "insertchildxmlbefore"
1605"insertxmlafter" "insertxmlbefore" "instr" "instr2" "instr4" "instrb"
1606"instrc" "iteration_number" "lag" "last" "last_day" "last_value"
1607"lead" "least" "length" "length2" "length4" "lengthb" "lengthc"
1608"listagg" "ln" "lnnvl" "localtimestamp" "log" "lower" "lpad" "ltrim"
1609"make_ref" "max" "median" "min" "mod" "months_between" "nanvl" "nchr"
1610"new_time" "next_day" "nlssort" "nls_charset_decl_len"
1477"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower" 1611"nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower"
1478"nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval" 1612"nls_upper" "nth_value" "ntile" "nullif" "numtodsinterval"
1479"numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank" 1613"numtoyminterval" "nvl" "nvl2" "ora_dst_affected" "ora_dst_convert"
1480"percentile_cont" "percentile_disc" "power" "preceding" "rank" 1614"ora_dst_error" "ora_hash" "path" "percentile_cont" "percentile_disc"
1481"ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_" 1615"percent_rank" "power" "powermultiset" "powermultiset_by_cardinality"
1482"regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2" 1616"prediction" "prediction_bounds" "prediction_cost"
1483"regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round" 1617"prediction_details" "prediction_probability" "prediction_set"
1484"row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim" 1618"presentnnv" "presentv" "previous" "rank" "ratio_to_report" "rawtohex"
1485"sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev" 1619"rawtonhex" "ref" "reftohex" "regexp_count" "regexp_instr"
1486"stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path" 1620"regexp_replace" "regexp_substr" "regr_avgx" "regr_avgy" "regr_count"
1487"sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" 1621"regr_intercept" "regr_r2" "regr_slope" "regr_sxx" "regr_sxy"
1488"sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh" 1622"regr_syy" "remainder" "replace" "round" "rowidtochar" "rowidtonchar"
1623"row_number" "rpad" "rtrim" "scn_to_timestamp" "sessiontimezone" "set"
1624"sign" "sin" "sinh" "soundex" "sqrt" "stats_binomial_test"
1625"stats_crosstab" "stats_f_test" "stats_ks_test" "stats_mode"
1626"stats_mw_test" "stats_one_way_anova" "stats_t_test_indep"
1627"stats_t_test_indepu" "stats_t_test_one" "stats_t_test_paired"
1628"stats_wsr_test" "stddev" "stddev_pop" "stddev_samp" "substr"
1629"substr2" "substr4" "substrb" "substrc" "sum" "sysdate" "systimestamp"
1630"sys_connect_by_path" "sys_context" "sys_dburigen" "sys_extract_utc"
1631"sys_guid" "sys_typeid" "sys_xmlagg" "sys_xmlgen" "tan" "tanh"
1632"timestamp_to_scn" "to_binary_double" "to_binary_float" "to_blob"
1489"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" 1633"to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte"
1490"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" 1634"to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp"
1491"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" 1635"to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc"
1492"tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user" 1636"tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv"
1493"userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml" 1637"value" "variance" "var_pop" "var_samp" "vsize" "width_bucket"
1494"xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement" 1638"xmlagg" "xmlcast" "xmlcdata" "xmlcolattval" "xmlcomment" "xmlconcat"
1495"xmlforest" "xmlsequence" "xmltransform" 1639"xmldiff" "xmlelement" "xmlexists" "xmlforest" "xmlisvalid" "xmlparse"
1640"xmlpatch" "xmlpi" "xmlquery" "xmlroot" "xmlsequence" "xmlserialize"
1641"xmltable" "xmltransform"
1496) 1642)
1643
1644 ;; See the table V$RESERVED_WORDS
1497 ;; Oracle Keywords 1645 ;; Oracle Keywords
1498 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1646 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1499"abort" "access" "accessed" "account" "activate" "add" "admin" 1647"abort" "access" "accessed" "account" "activate" "add" "admin"
@@ -1582,52 +1730,120 @@ to add functions and PL/SQL keywords.")
1582"varray" "version" "view" "wait" "when" "whenever" "where" "with" 1730"varray" "version" "view" "wait" "when" "whenever" "where" "with"
1583"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype" 1731"without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype"
1584) 1732)
1733
1585 ;; Oracle Data Types 1734 ;; Oracle Data Types
1586 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1735 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1587"bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal" 1736"bfile" "binary_double" "binary_float" "blob" "byte" "char" "charbyte"
1588"double" "float" "int" "integer" "interval" "long" "national" "nchar" 1737"clob" "date" "day" "float" "interval" "local" "long" "longraw"
1589"nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real" 1738"minute" "month" "nchar" "nclob" "number" "nvarchar2" "raw" "rowid" "second"
1590"rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar" 1739"time" "timestamp" "urowid" "varchar2" "with" "year" "zone"
1591"varchar2" "varying" "year" "zone"
1592) 1740)
1593 1741
1594 ;; Oracle PL/SQL Attributes 1742 ;; Oracle PL/SQL Attributes
1595 (sql-font-lock-keywords-builder 'font-lock-builtin-face '("" . "\\b") 1743 (sql-font-lock-keywords-builder 'font-lock-builtin-face '("%" . "\\b")
1596"%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype" 1744"bulk_exceptions" "bulk_rowcount" "found" "isopen" "notfound"
1597"%type" 1745"rowcount" "rowtype" "type"
1598) 1746)
1599 1747
1600 ;; Oracle PL/SQL Functions 1748 ;; Oracle PL/SQL Functions
1601 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil 1749 (sql-font-lock-keywords-builder 'font-lock-builtin-face nil
1602"extend" "prior" 1750"delete" "trim" "extend" "exists" "first" "last" "count" "limit"
1751"prior" "next"
1752)
1753
1754 ;; Oracle PL/SQL Reserved words
1755 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1756"all" "alter" "and" "any" "as" "asc" "at" "begin" "between" "by"
1757"case" "check" "clusters" "cluster" "colauth" "columns" "compress"
1758"connect" "crash" "create" "cursor" "declare" "default" "desc"
1759"distinct" "drop" "else" "end" "exception" "exclusive" "fetch" "for"
1760"from" "function" "goto" "grant" "group" "having" "identified" "if"
1761"in" "index" "indexes" "insert" "intersect" "into" "is" "like" "lock"
1762"minus" "mode" "nocompress" "not" "nowait" "null" "of" "on" "option"
1763"or" "order" "overlaps" "procedure" "public" "resource" "revoke"
1764"select" "share" "size" "sql" "start" "subtype" "tabauth" "table"
1765"then" "to" "type" "union" "unique" "update" "values" "view" "views"
1766"when" "where" "with"
1767
1768"true" "false"
1769"raise_application_error"
1603) 1770)
1604 1771
1605 ;; Oracle PL/SQL Keywords 1772 ;; Oracle PL/SQL Keywords
1606 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil 1773 (sql-font-lock-keywords-builder 'font-lock-keyword-face nil
1607"autonomous_transaction" "bulk" "char_base" "collect" "constant" 1774"a" "add" "agent" "aggregate" "array" "attribute" "authid" "avg"
1608"cursor" "declare" "do" "elsif" "exception_init" "execute" "exit" 1775"bfile_base" "binary" "blob_base" "block" "body" "both" "bound" "bulk"
1609"extends" "false" "fetch" "forall" "goto" "hour" "if" "interface" 1776"byte" "c" "call" "calling" "cascade" "char" "char_base" "character"
1610"loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype" 1777"charset" "charsetform" "charsetid" "clob_base" "close" "collect"
1611"separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype" 1778"comment" "commit" "committed" "compiled" "constant" "constructor"
1612"the" "timezone_abbr" "timezone_hour" "timezone_minute" 1779"context" "continue" "convert" "count" "current" "customdatum"
1613"timezone_region" "true" "varrying" "while" 1780"dangling" "data" "date" "date_base" "day" "define" "delete"
1781"deterministic" "double" "duration" "element" "elsif" "empty" "escape"
1782"except" "exceptions" "execute" "exists" "exit" "external" "final"
1783"fixed" "float" "forall" "force" "general" "hash" "heap" "hidden"
1784"hour" "immediate" "including" "indicator" "indices" "infinite"
1785"instantiable" "int" "interface" "interval" "invalidate" "isolation"
1786"java" "language" "large" "leading" "length" "level" "library" "like2"
1787"like4" "likec" "limit" "limited" "local" "long" "loop" "map" "max"
1788"maxlen" "member" "merge" "min" "minute" "mod" "modify" "month"
1789"multiset" "name" "nan" "national" "native" "nchar" "new" "nocopy"
1790"number_base" "object" "ocicoll" "ocidate" "ocidatetime" "ociduration"
1791"ociinterval" "ociloblocator" "ocinumber" "ociraw" "ociref"
1792"ocirefcursor" "ocirowid" "ocistring" "ocitype" "old" "only" "opaque"
1793"open" "operator" "oracle" "oradata" "organization" "orlany" "orlvary"
1794"others" "out" "overriding" "package" "parallel_enable" "parameter"
1795"parameters" "parent" "partition" "pascal" "pipe" "pipelined" "pragma"
1796"precision" "prior" "private" "raise" "range" "raw" "read" "record"
1797"ref" "reference" "relies_on" "rem" "remainder" "rename" "result"
1798"result_cache" "return" "returning" "reverse" "rollback" "row"
1799"sample" "save" "savepoint" "sb1" "sb2" "sb4" "second" "segment"
1800"self" "separate" "sequence" "serializable" "set" "short" "size_t"
1801"some" "sparse" "sqlcode" "sqldata" "sqlname" "sqlstate" "standard"
1802"static" "stddev" "stored" "string" "struct" "style" "submultiset"
1803"subpartition" "substitutable" "sum" "synonym" "tdo" "the" "time"
1804"timestamp" "timezone_abbr" "timezone_hour" "timezone_minute"
1805"timezone_region" "trailing" "transaction" "transactional" "trusted"
1806"ub1" "ub2" "ub4" "under" "unsigned" "untrusted" "use" "using"
1807"valist" "value" "variable" "variance" "varray" "varying" "void"
1808"while" "work" "wrapped" "write" "year" "zone"
1809;; Pragma
1810"autonomous_transaction" "exception_init" "inline"
1811"restrict_references" "serially_reusable"
1614) 1812)
1615 1813
1616 ;; Oracle PL/SQL Data Types 1814 ;; Oracle PL/SQL Data Types
1617 (sql-font-lock-keywords-builder 'font-lock-type-face nil 1815 (sql-font-lock-keywords-builder 'font-lock-type-face nil
1618"binary_integer" "boolean" "naturaln" "pls_integer" "positive" 1816"\"BINARY LARGE OBJECT\"" "\"CHAR LARGE OBJECT\"" "\"CHAR VARYING\""
1619"positiven" "record" "signtype" "string" 1817"\"CHARACTER LARGE OBJECT\"" "\"CHARACTER VARYING\""
1818"\"DOUBLE PRECISION\"" "\"INTERVAL DAY TO SECOND\""
1819"\"INTERVAL YEAR TO MONTH\"" "\"LONG RAW\"" "\"NATIONAL CHAR\""
1820"\"NATIONAL CHARACTER LARGE OBJECT\"" "\"NATIONAL CHARACTER\""
1821"\"NCHAR LARGE OBJECT\"" "\"NCHAR\"" "\"NCLOB\"" "\"NVARCHAR2\""
1822"\"TIME WITH TIME ZONE\"" "\"TIMESTAMP WITH LOCAL TIME ZONE\""
1823"\"TIMESTAMP WITH TIME ZONE\""
1824"bfile" "bfile_base" "binary_double" "binary_float" "binary_integer"
1825"blob" "blob_base" "boolean" "char" "character" "char_base" "clob"
1826"clob_base" "cursor" "date" "day" "dec" "decimal"
1827"dsinterval_unconstrained" "float" "int" "integer" "interval" "local"
1828"long" "mlslabel" "month" "natural" "naturaln" "nchar_cs" "number"
1829"number_base" "numeric" "pls_integer" "positive" "positiven" "raw"
1830"real" "ref" "rowid" "second" "signtype" "simple_double"
1831"simple_float" "simple_integer" "smallint" "string" "time" "timestamp"
1832"timestamp_ltz_unconstrained" "timestamp_tz_unconstrained"
1833"timestamp_unconstrained" "time_tz_unconstrained" "time_unconstrained"
1834"to" "urowid" "varchar" "varchar2" "with" "year"
1835"yminterval_unconstrained" "zone"
1620) 1836)
1621 1837
1622 ;; Oracle PL/SQL Exceptions 1838 ;; Oracle PL/SQL Exceptions
1623 (sql-font-lock-keywords-builder 'font-lock-warning-face nil 1839 (sql-font-lock-keywords-builder 'font-lock-warning-face nil
1624"access_into_null" "case_not_found" "collection_is_null" 1840"access_into_null" "case_not_found" "collection_is_null"
1625"cursor_already_open" "dup_val_on_index" "invalid_cursor" 1841"cursor_already_open" "dup_val_on_index" "invalid_cursor"
1626"invalid_number" "login_denied" "no_data_found" "not_logged_on" 1842"invalid_number" "login_denied" "no_data_found" "no_data_needed"
1627"program_error" "rowtype_mismatch" "self_is_null" "storage_error" 1843"not_logged_on" "program_error" "rowtype_mismatch" "self_is_null"
1628"subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid" 1844"storage_error" "subscript_beyond_count" "subscript_outside_limit"
1629"timeout_on_resource" "too_many_rows" "value_error" "zero_divide" 1845"sys_invalid_rowid" "timeout_on_resource" "too_many_rows"
1630"exception" "notfound" 1846"value_error" "zero_divide"
1631))) 1847)))
1632 1848
1633 "Oracle SQL keywords used by font-lock. 1849 "Oracle SQL keywords used by font-lock.
@@ -2296,10 +2512,7 @@ also be configured."
2296 2512
2297 (let 2513 (let
2298 ;; Get the product-specific syntax-alist. 2514 ;; Get the product-specific syntax-alist.
2299 ((syntax-alist 2515 ((syntax-alist (sql-product-font-lock-syntax-alist)))
2300 (append
2301 (sql-get-product-feature sql-product :syntax-alist)
2302 '((?_ . "w") (?. . "w")))))
2303 2516
2304 ;; Get the product-specific keywords. 2517 ;; Get the product-specific keywords.
2305 (set (make-local-variable 'sql-mode-font-lock-keywords) 2518 (set (make-local-variable 'sql-mode-font-lock-keywords)
@@ -2388,9 +2601,30 @@ adds a fontification pattern to fontify identifiers ending in
2388 2601
2389;;; Functions to switch highlighting 2602;;; Functions to switch highlighting
2390 2603
2604(defun sql-product-syntax-table ()
2605 (let ((table (copy-syntax-table sql-mode-syntax-table)))
2606 (mapc (lambda (entry)
2607 (modify-syntax-entry (car entry) (cdr entry) table))
2608 (sql-get-product-feature sql-product :syntax-alist))
2609 table))
2610
2611(defun sql-product-font-lock-syntax-alist ()
2612 (append
2613 ;; Change all symbol character to word characters
2614 (mapcar
2615 (lambda (entry) (if (string= (substring (cdr entry) 0 1) "_")
2616 (cons (car entry)
2617 (concat "w" (substring (cdr entry) 1)))
2618 entry))
2619 (sql-get-product-feature sql-product :syntax-alist))
2620 '((?_ . "w"))))
2621
2391(defun sql-highlight-product () 2622(defun sql-highlight-product ()
2392 "Turn on the font highlighting for the SQL product selected." 2623 "Turn on the font highlighting for the SQL product selected."
2393 (when (derived-mode-p 'sql-mode) 2624 (when (derived-mode-p 'sql-mode)
2625 ;; Enhance the syntax table for the product
2626 (set-syntax-table (sql-product-syntax-table))
2627
2394 ;; Setup font-lock 2628 ;; Setup font-lock
2395 (sql-product-font-lock nil t) 2629 (sql-product-font-lock nil t)
2396 2630
@@ -2418,11 +2652,77 @@ adds a fontification pattern to fontify identifiers ending in
2418 ;; comint-line-beginning-position is defined in Emacs 21 2652 ;; comint-line-beginning-position is defined in Emacs 21
2419 (defun comint-line-beginning-position () 2653 (defun comint-line-beginning-position ()
2420 "Return the buffer position of the beginning of the line, after any prompt. 2654 "Return the buffer position of the beginning of the line, after any prompt.
2421The prompt is assumed to be any text at the beginning of the line matching 2655The prompt is assumed to be any text at the beginning of the line
2422the regular expression `comint-prompt-regexp', a buffer local variable." 2656matching the regular expression `comint-prompt-regexp', a buffer
2657local variable."
2423 (save-excursion (comint-bol nil) (point)))) 2658 (save-excursion (comint-bol nil) (point))))
2424 2659
2425 2660;;; Motion Functions
2661
2662(defun sql-statement-regexp (prod)
2663 (let* ((ansi-stmt (sql-get-product-feature 'ansi :statement))
2664 (prod-stmt (sql-get-product-feature prod :statement)))
2665 (concat "^\\<"
2666 (if prod-stmt
2667 ansi-stmt
2668 (concat "\\(" ansi-stmt "\\|" prod-stmt "\\)"))
2669 "\\>")))
2670
2671(defun sql-beginning-of-statement (arg)
2672 "Moves the cursor to the beginning of the current SQL statement."
2673 (interactive "p")
2674
2675 (let ((here (point))
2676 (regexp (sql-statement-regexp sql-product))
2677 last next)
2678
2679 ;; Go to the end of the statement before the start we desire
2680 (setq last (or (sql-end-of-statement (- arg))
2681 (point-min)))
2682 ;; And find the end after that
2683 (setq next (or (sql-end-of-statement 1)
2684 (point-max)))
2685
2686 ;; Our start must be between them
2687 (goto-char last)
2688 ;; Find an beginning-of-stmt that's not in a comment
2689 (while (and (re-search-forward regexp next t 1)
2690 (nth 7 (syntax-ppss)))
2691 (goto-char (match-end 0)))
2692 (goto-char
2693 (if (match-data)
2694 (match-beginning 0)
2695 last))
2696 (beginning-of-line)
2697 ;; If we didn't move, try again
2698 (when (= here (point))
2699 (sql-beginning-of-statement (* 2 (sql-signum arg))))))
2700
2701(defun sql-end-of-statement (arg)
2702 "Moves the cursor to the end of the current SQL statement."
2703 (interactive "p")
2704 (let ((term (sql-get-product-feature sql-product :terminator))
2705 (re-search (if (> 0 arg) 're-search-backward 're-search-forward))
2706 (here (point))
2707 (n 0))
2708 (when (consp term)
2709 (setq term (car term)))
2710 ;; Iterate until we've moved the desired number of stmt ends
2711 (while (not (= (sql-signum arg) 0))
2712 ;; if we're looking at the terminator, jump by 2
2713 (if (or (and (> 0 arg) (looking-back term))
2714 (and (< 0 arg) (looking-at term)))
2715 (setq n 2)
2716 (setq n 1))
2717 ;; If we found another end-of-stmt
2718 (if (not (apply re-search term nil t n nil))
2719 (setq arg 0)
2720 ;; count it if we're not in a comment
2721 (unless (nth 7 (syntax-ppss))
2722 (setq arg (- arg (sql-signum arg))))))
2723 (goto-char (if (match-data)
2724 (match-end 0)
2725 here))))
2426 2726
2427;;; Small functions 2727;;; Small functions
2428 2728
@@ -2456,7 +2756,7 @@ the regular expression `comint-prompt-regexp', a buffer local variable."
2456(defun sql-help-list-products (indent freep) 2756(defun sql-help-list-products (indent freep)
2457 "Generate listing of products available for use under SQLi. 2757 "Generate listing of products available for use under SQLi.
2458 2758
2459List products with :free-softare attribute set to FREEP. Indent 2759List products with :free-software attribute set to FREEP. Indent
2460each line with INDENT." 2760each line with INDENT."
2461 2761
2462 (let (sqli-func doc) 2762 (let (sqli-func doc)
@@ -2649,7 +2949,7 @@ function like this: (sql-get-login 'user 'password 'database)."
2649 nil (append '(:number t) plist))))))) 2949 nil (append '(:number t) plist)))))))
2650 what)) 2950 what))
2651 2951
2652(defun sql-find-sqli-buffer (&optional product) 2952(defun sql-find-sqli-buffer (&optional product connection)
2653 "Returns the name of the current default SQLi buffer or nil. 2953 "Returns the name of the current default SQLi buffer or nil.
2654In order to qualify, the SQLi buffer must be alive, be in 2954In order to qualify, the SQLi buffer must be alive, be in
2655`sql-interactive-mode' and have a process." 2955`sql-interactive-mode' and have a process."
@@ -2657,16 +2957,16 @@ In order to qualify, the SQLi buffer must be alive, be in
2657 (prod (or product sql-product))) 2957 (prod (or product sql-product)))
2658 (or 2958 (or
2659 ;; Current sql-buffer, if there is one. 2959 ;; Current sql-buffer, if there is one.
2660 (and (sql-buffer-live-p buf prod) 2960 (and (sql-buffer-live-p buf prod connection)
2661 buf) 2961 buf)
2662 ;; Global sql-buffer 2962 ;; Global sql-buffer
2663 (and (setq buf (default-value 'sql-buffer)) 2963 (and (setq buf (default-value 'sql-buffer))
2664 (sql-buffer-live-p buf prod) 2964 (sql-buffer-live-p buf prod connection)
2665 buf) 2965 buf)
2666 ;; Look thru each buffer 2966 ;; Look thru each buffer
2667 (car (apply 'append 2967 (car (apply 'append
2668 (mapcar (lambda (b) 2968 (mapcar (lambda (b)
2669 (and (sql-buffer-live-p b prod) 2969 (and (sql-buffer-live-p b prod connection)
2670 (list (buffer-name b)))) 2970 (list (buffer-name b))))
2671 (buffer-list))))))) 2971 (buffer-list)))))))
2672 2972
@@ -2722,7 +3022,8 @@ If you call it from anywhere else, it sets the global copy of
2722This is the buffer SQL strings are sent to. It is stored in the 3022This is the buffer SQL strings are sent to. It is stored in the
2723variable `sql-buffer'. See `sql-help' on how to create such a buffer." 3023variable `sql-buffer'. See `sql-help' on how to create such a buffer."
2724 (interactive) 3024 (interactive)
2725 (if (null (buffer-live-p (get-buffer sql-buffer))) 3025 (if (or (null sql-buffer)
3026 (null (buffer-live-p (get-buffer sql-buffer))))
2726 (message "%s has no SQLi buffer set." (buffer-name (current-buffer))) 3027 (message "%s has no SQLi buffer set." (buffer-name (current-buffer)))
2727 (if (null (get-buffer-process sql-buffer)) 3028 (if (null (get-buffer-process sql-buffer))
2728 (message "Buffer %s has no process." sql-buffer) 3029 (message "Buffer %s has no process." sql-buffer)
@@ -2932,37 +3233,58 @@ Allows the suppression of continuation prompts.")
2932 3233
2933;;; Strip out continuation prompts 3234;;; Strip out continuation prompts
2934 3235
3236(defvar sql-preoutput-hold nil)
3237
2935(defun sql-interactive-remove-continuation-prompt (oline) 3238(defun sql-interactive-remove-continuation-prompt (oline)
2936 "Strip out continuation prompts out of the OLINE. 3239 "Strip out continuation prompts out of the OLINE.
2937 3240
2938Added to the `comint-preoutput-filter-functions' hook in a SQL 3241Added to the `comint-preoutput-filter-functions' hook in a SQL
2939interactive buffer. If `sql-outut-newline-count' is greater than 3242interactive buffer. If `sql-output-newline-count' is greater than
2940zero, then an output line matching the continuation prompt is filtered 3243zero, then an output line matching the continuation prompt is filtered
2941out. If the count is one, then the prompt is replaced with a newline 3244out. If the count is zero, then a newline is inserted into the output
2942to force the output from the query to appear on a new line." 3245to force the output from the query to appear on a new line.
2943 (if (and sql-prompt-cont-regexp 3246
2944 sql-output-newline-count 3247The complication to this filter is that the continuation prompts
2945 (numberp sql-output-newline-count) 3248may arrive in multiple chunks. If they do, then the function
2946 (>= sql-output-newline-count 1)) 3249saves any unfiltered output in a buffer and prepends that buffer
2947 (progn 3250to the next chunk to properly match the broken-up prompt.
2948 (while (and oline 3251
2949 sql-output-newline-count 3252If the filter gets confused, it should reset and stop filtering
2950 (> sql-output-newline-count 0) 3253to avoid deleting non-prompt output."
2951 (string-match sql-prompt-cont-regexp oline)) 3254
2952 3255 (let (did-filter)
2953 (setq oline 3256 (setq oline (concat (or sql-preoutput-hold "") oline)
2954 (replace-match (if (and 3257 sql-preoutput-hold nil)
2955 (= 1 sql-output-newline-count) 3258
2956 sql-output-by-send) 3259 (if (and comint-prompt-regexp
2957 "\n" "") 3260 (integerp sql-output-newline-count)
2958 nil nil oline) 3261 (>= sql-output-newline-count 1))
2959 sql-output-newline-count 3262 (progn
2960 (1- sql-output-newline-count))) 3263 (while (and (not (string= oline ""))
2961 (if (= sql-output-newline-count 0) 3264 (> sql-output-newline-count 0)
2962 (setq sql-output-newline-count nil)) 3265 (string-match comint-prompt-regexp oline)
2963 (setq sql-output-by-send nil)) 3266 (= (match-beginning 0) 0))
2964 (setq sql-output-newline-count nil)) 3267
2965 oline) 3268 (setq oline (replace-match "" nil nil oline)
3269 sql-output-newline-count (1- sql-output-newline-count)
3270 did-filter t))
3271
3272 (if (= sql-output-newline-count 0)
3273 (setq sql-output-newline-count nil
3274 oline (concat "\n" oline)
3275 sql-output-by-send nil)
3276
3277 (setq sql-preoutput-hold oline
3278 oline ""))
3279
3280 (unless did-filter
3281 (setq oline (or sql-preoutput-hold "")
3282 sql-preoutput-hold nil
3283 sql-output-newline-count nil)))
3284
3285 (setq sql-output-newline-count nil))
3286
3287 oline))
2966 3288
2967;;; Sending the region to the SQLi buffer. 3289;;; Sending the region to the SQLi buffer.
2968 3290
@@ -3066,16 +3388,35 @@ If given the optional parameter VALUE, sets
3066 3388
3067;;; Redirect output functions 3389;;; Redirect output functions
3068 3390
3069(defun sql-redirect (command combuf &optional outbuf save-prior) 3391(defvar sql-debug-redirect nil
3392 "If non-nil, display messages related to the use of redirection.")
3393
3394(defun sql-str-literal (s)
3395 (concat "'" (replace-regexp-in-string "[']" "''" s) "'"))
3396
3397(defun sql-redirect (sqlbuf command &optional outbuf save-prior)
3070 "Execute the SQL command and send output to OUTBUF. 3398 "Execute the SQL command and send output to OUTBUF.
3071 3399
3072COMBUF must be an active SQL interactive buffer. OUTBUF may be 3400SQLBUF must be an active SQL interactive buffer. OUTBUF may be
3073an existing buffer, or the name of a non-existing buffer. If 3401an existing buffer, or the name of a non-existing buffer. If
3074omitted the output is sent to a temporary buffer which will be 3402omitted the output is sent to a temporary buffer which will be
3075killed after the command completes. COMMAND should be a string 3403killed after the command completes. COMMAND should be a string
3076of commands accepted by the SQLi program." 3404of commands accepted by the SQLi program. COMMAND may also be a
3077 3405list of SQLi command strings."
3078 (with-current-buffer combuf 3406
3407 (let* ((visible (and outbuf
3408 (not (string= " " (substring outbuf 0 1))))))
3409 (when visible
3410 (message "Executing SQL command..."))
3411 (if (consp command)
3412 (mapc (lambda (c) (sql-redirect-one sqlbuf c outbuf save-prior))
3413 command)
3414 (sql-redirect-one sqlbuf command outbuf save-prior))
3415 (when visible
3416 (message "Executing SQL command...done"))))
3417
3418(defun sql-redirect-one (sqlbuf command outbuf save-prior)
3419 (with-current-buffer sqlbuf
3079 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*"))) 3420 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
3080 (proc (get-buffer-process (current-buffer))) 3421 (proc (get-buffer-process (current-buffer)))
3081 (comint-prompt-regexp (sql-get-product-feature sql-product 3422 (comint-prompt-regexp (sql-get-product-feature sql-product
@@ -3090,12 +3431,13 @@ of commands accepted by the SQLi program."
3090 (insert "\n")) 3431 (insert "\n"))
3091 (setq start (point))) 3432 (setq start (point)))
3092 3433
3434 (when sql-debug-redirect
3435 (message ">>SQL> %S" command))
3436
3093 ;; Run the command 3437 ;; Run the command
3094 (message "Executing SQL command...")
3095 (comint-redirect-send-command-to-process command buf proc nil t) 3438 (comint-redirect-send-command-to-process command buf proc nil t)
3096 (while (null comint-redirect-completed) 3439 (while (null comint-redirect-completed)
3097 (accept-process-output nil 1)) 3440 (accept-process-output nil 1))
3098 (message "Executing SQL command...done")
3099 3441
3100 ;; Clean up the output results 3442 ;; Clean up the output results
3101 (with-current-buffer buf 3443 (with-current-buffer buf
@@ -3107,12 +3449,16 @@ of commands accepted by the SQLi program."
3107 (goto-char start) 3449 (goto-char start)
3108 (when (looking-at (concat "^" (regexp-quote command) "[\\n]")) 3450 (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
3109 (delete-region (match-beginning 0) (match-end 0))) 3451 (delete-region (match-beginning 0) (match-end 0)))
3452 ;; Remove Ctrl-Ms
3453 (goto-char start)
3454 (while (re-search-forward "\r+$" nil t)
3455 (replace-match "" t t))
3110 (goto-char start))))) 3456 (goto-char start)))))
3111 3457
3112(defun sql-redirect-value (command combuf regexp &optional regexp-groups) 3458(defun sql-redirect-value (sqlbuf command regexp &optional regexp-groups)
3113 "Execute the SQL command and return part of result. 3459 "Execute the SQL command and return part of result.
3114 3460
3115COMBUF must be an active SQL interactive buffer. COMMAND should 3461SQLBUF must be an active SQL interactive buffer. COMMAND should
3116be a string of commands accepted by the SQLi program. From the 3462be a string of commands accepted by the SQLi program. From the
3117output, the REGEXP is repeatedly matched and the list of 3463output, the REGEXP is repeatedly matched and the list of
3118REGEXP-GROUPS submatches is returned. This behaves much like 3464REGEXP-GROUPS submatches is returned. This behaves much like
@@ -3122,18 +3468,19 @@ for each match."
3122 3468
3123 (let ((outbuf " *SQL-Redirect-values*") 3469 (let ((outbuf " *SQL-Redirect-values*")
3124 (results nil)) 3470 (results nil))
3125 (sql-redirect command combuf outbuf nil) 3471 (sql-redirect sqlbuf command outbuf nil)
3126 (with-current-buffer outbuf 3472 (with-current-buffer outbuf
3127 (while (re-search-forward regexp nil t) 3473 (while (re-search-forward regexp nil t)
3128 (push 3474 (push
3129 (cond 3475 (cond
3130 ;; no groups-return all of them 3476 ;; no groups-return all of them
3131 ((null regexp-groups) 3477 ((null regexp-groups)
3132 (let ((i 1) 3478 (let ((i (/ (length (match-data)) 2))
3133 (r nil)) 3479 (r nil))
3134 (while (match-beginning i) 3480 (while (> i 0)
3481 (setq i (1- i))
3135 (push (match-string i) r)) 3482 (push (match-string i) r))
3136 (nreverse r))) 3483 r))
3137 ;; one group specified 3484 ;; one group specified
3138 ((numberp regexp-groups) 3485 ((numberp regexp-groups)
3139 (match-string regexp-groups)) 3486 (match-string regexp-groups))
@@ -3152,10 +3499,14 @@ for each match."
3152 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" 3499 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
3153 regexp-groups))) 3500 regexp-groups)))
3154 results))) 3501 results)))
3155 (nreverse results)))
3156 3502
3157(defun sql-execute (sqlbuf outbuf command arg) 3503 (when sql-debug-redirect
3158 "Executes a command in a SQL interacive buffer and captures the output. 3504 (message ">>SQL> = %S" (reverse results)))
3505
3506 (nreverse results)))
3507
3508(defun sql-execute (sqlbuf outbuf command enhanced arg)
3509 "Executes a command in a SQL interactive buffer and captures the output.
3159 3510
3160The commands are run in SQLBUF and the output saved in OUTBUF. 3511The commands are run in SQLBUF and the output saved in OUTBUF.
3161COMMAND must be a string, a function or a list of such elements. 3512COMMAND must be a string, a function or a list of such elements.
@@ -3168,9 +3519,9 @@ buffer is popped into a view window. "
3168 (lambda (c) 3519 (lambda (c)
3169 (cond 3520 (cond
3170 ((stringp c) 3521 ((stringp c)
3171 (sql-redirect (if arg (format c arg) c) sqlbuf outbuf) t) 3522 (sql-redirect sqlbuf (if arg (format c arg) c) outbuf) t)
3172 ((functionp c) 3523 ((functionp c)
3173 (apply c sqlbuf outbuf arg)) 3524 (apply c sqlbuf outbuf enhanced arg nil))
3174 (t (error "Unknown sql-execute item %s" c)))) 3525 (t (error "Unknown sql-execute item %s" c))))
3175 (if (consp command) command (cons command nil))) 3526 (if (consp command) command (cons command nil)))
3176 3527
@@ -3197,14 +3548,92 @@ buffer is popped into a view window. "
3197 (setq command (if enhanced 3548 (setq command (if enhanced
3198 (cdr command) 3549 (cdr command)
3199 (car command)))) 3550 (car command))))
3200 (sql-execute sqlbuf outbuf command arg))) 3551 (sql-execute sqlbuf outbuf command enhanced arg)))
3552
3553(defvar sql-completion-object nil
3554 "A list of database objects used for completion.
3555
3556The list is maintained in SQL interactive buffers.")
3557
3558(defvar sql-completion-column nil
3559 "A list of column names used for completion.
3560
3561The list is maintained in SQL interactive buffers.")
3562
3563(defun sql-build-completions-1 (schema completion-list feature)
3564 "Generate a list of objects in the database for use as completions."
3565 (let ((f (sql-get-product-feature sql-product feature)))
3566 (when f
3567 (set completion-list
3568 (let (cl)
3569 (dolist (e (append (symbol-value completion-list)
3570 (apply f (current-buffer) (cons schema nil)))
3571 cl)
3572 (unless (member e cl) (setq cl (cons e cl))))
3573 (sort cl (function string<)))))))
3574
3575(defun sql-build-completions (schema)
3576 "Generate a list of names in the database for use as completions."
3577 (sql-build-completions-1 schema 'sql-completion-object :completion-object)
3578 (sql-build-completions-1 schema 'sql-completion-column :completion-column))
3579
3580(defvar sql-completion-sqlbuf nil)
3581
3582(defun sql-try-completion (string collection &optional predicate)
3583 (when sql-completion-sqlbuf
3584 (with-current-buffer sql-completion-sqlbuf
3585 (let ((schema (and (string-match "\\`\\(\\sw\\(:?\\sw\\|\\s_\\)*\\)[.]" string)
3586 (downcase (match-string 1 string)))))
3587
3588 ;; If we haven't loaded any object name yet, load local schema
3589 (unless sql-completion-object
3590 (sql-build-completions nil))
3591
3592 ;; If they want another schema, load it if we haven't yet
3593 (when schema
3594 (let ((schema-dot (concat schema "."))
3595 (schema-len (1+ (length schema)))
3596 (names sql-completion-object)
3597 has-schema)
3598
3599 (while (and (not has-schema) names)
3600 (setq has-schema (and
3601 (>= (length (car names)) schema-len)
3602 (string= schema-dot
3603 (downcase (substring (car names)
3604 0 schema-len))))
3605 names (cdr names)))
3606 (unless has-schema
3607 (sql-build-completions schema)))))
3608
3609 ;; Try to find the completion
3610 (cond
3611 ((not predicate)
3612 (try-completion string sql-completion-object))
3613 ((eq predicate t)
3614 (all-completions string sql-completion-object))
3615 ((eq predicate 'lambda)
3616 (test-completion string sql-completion-object))
3617 ((eq (car predicate) 'boundaries)
3618 (completion-boundaries string sql-completion-object nil (cdr predicate)))))))
3201 3619
3202(defun sql-read-table-name (prompt) 3620(defun sql-read-table-name (prompt)
3203 "Read the name of a database table." 3621 "Read the name of a database table."
3204 ;; TODO: Fetch table/view names from database and provide completion. 3622 (let* ((tname
3205 ;; Also implement thing-at-point if the buffer has valid names in it 3623 (and (buffer-local-value 'sql-contains-names (current-buffer))
3206 ;; (i.e. sql-mode, sql-interactive-mode, or sql-list-all buffers) 3624 (thing-at-point-looking-at
3207 (read-from-minibuffer prompt)) 3625 (concat "\\_<\\sw\\(:?\\sw\\|\\s_\\)*"
3626 "\\(?:[.]+\\sw\\(?:\\sw\\|\\s_\\)*\\)*\\_>"))
3627 (buffer-substring-no-properties (match-beginning 0)
3628 (match-end 0))))
3629 (sql-completion-sqlbuf (sql-find-sqli-buffer))
3630 (product (with-current-buffer sql-completion-sqlbuf sql-product))
3631 (completion-ignore-case t))
3632
3633 (if (sql-get-product-feature product :completion-object)
3634 (completing-read prompt (function sql-try-completion)
3635 nil nil tname)
3636 (read-from-minibuffer prompt tname))))
3208 3637
3209(defun sql-list-all (&optional enhanced) 3638(defun sql-list-all (&optional enhanced)
3210 "List all database objects." 3639 "List all database objects."
@@ -3212,7 +3641,11 @@ buffer is popped into a view window. "
3212 (let ((sqlbuf (sql-find-sqli-buffer))) 3641 (let ((sqlbuf (sql-find-sqli-buffer)))
3213 (unless sqlbuf 3642 (unless sqlbuf
3214 (error "No SQL interactive buffer found")) 3643 (error "No SQL interactive buffer found"))
3215 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil))) 3644 (sql-execute-feature sqlbuf "*List All*" :list-all enhanced nil)
3645 (with-current-buffer sqlbuf
3646 ;; Contains the name of database objects
3647 (set (make-local-variable 'sql-contains-names) t)
3648 (set (make-local-variable 'sql-buffer) sqlbuf))))
3216 3649
3217(defun sql-list-table (name &optional enhanced) 3650(defun sql-list-table (name &optional enhanced)
3218 "List the details of a database table. " 3651 "List the details of a database table. "
@@ -3226,7 +3659,6 @@ buffer is popped into a view window. "
3226 (error "No table name specified")) 3659 (error "No table name specified"))
3227 (sql-execute-feature sqlbuf (format "*List %s*" name) 3660 (sql-execute-feature sqlbuf (format "*List %s*" name)
3228 :list-table enhanced name))) 3661 :list-table enhanced name)))
3229
3230 3662
3231 3663
3232;;; SQL mode -- uses SQL interactive mode 3664;;; SQL mode -- uses SQL interactive mode
@@ -3277,6 +3709,8 @@ you must tell Emacs. Here's how to do that in your `~/.emacs' file:
3277 (set (make-local-variable 'paragraph-start) "[\n\f]") 3709 (set (make-local-variable 'paragraph-start) "[\n\f]")
3278 ;; Abbrevs 3710 ;; Abbrevs
3279 (setq abbrev-all-caps 1) 3711 (setq abbrev-all-caps 1)
3712 ;; Contains the name of database objects
3713 (set (make-local-variable 'sql-contains-names) t)
3280 ;; Catch changes to sql-product and highlight accordingly 3714 ;; Catch changes to sql-product and highlight accordingly
3281 (add-hook 'hack-local-variables-hook 'sql-highlight-product t t)) 3715 (add-hook 'hack-local-variables-hook 'sql-highlight-product t t))
3282 3716
@@ -3362,7 +3796,7 @@ you entered, right above the output it created.
3362 sql-product)) 3796 sql-product))
3363 3797
3364 ;; Setup the mode. 3798 ;; Setup the mode.
3365 (setq major-mode 'sql-interactive-mode) ;FIXME: Use define-derived-mode. 3799 (setq major-mode 'sql-interactive-mode)
3366 (setq mode-name 3800 (setq mode-name
3367 (concat "SQLi[" (or (sql-get-product-feature sql-product :name) 3801 (concat "SQLi[" (or (sql-get-product-feature sql-product :name)
3368 (symbol-name sql-product)) "]")) 3802 (symbol-name sql-product)) "]"))
@@ -3385,9 +3819,18 @@ you entered, right above the output it created.
3385 (setq abbrev-all-caps 1) 3819 (setq abbrev-all-caps 1)
3386 ;; Exiting the process will call sql-stop. 3820 ;; Exiting the process will call sql-stop.
3387 (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop) 3821 (set-process-sentinel (get-buffer-process (current-buffer)) 'sql-stop)
3388 ;; Save the connection name 3822 ;; Save the connection and login params
3389 (make-local-variable 'sql-connection) 3823 (set (make-local-variable 'sql-user) sql-user)
3390 ;; Create a usefull name for renaming this buffer later. 3824 (set (make-local-variable 'sql-database) sql-database)
3825 (set (make-local-variable 'sql-server) sql-server)
3826 (set (make-local-variable 'sql-port) sql-port)
3827 (set (make-local-variable 'sql-connection) sql-connection)
3828 ;; Contains the name of database objects
3829 (set (make-local-variable 'sql-contains-names) t)
3830 ;; Keep track of existing object names
3831 (set (make-local-variable 'sql-completion-object) nil)
3832 (set (make-local-variable 'sql-completion-column) nil)
3833 ;; Create a useful name for renaming this buffer later.
3391 (set (make-local-variable 'sql-alternate-buffer-name) 3834 (set (make-local-variable 'sql-alternate-buffer-name)
3392 (sql-make-alternate-buffer-name)) 3835 (sql-make-alternate-buffer-name))
3393 ;; User stuff. Initialize before the hook. 3836 ;; User stuff. Initialize before the hook.
@@ -3398,6 +3841,7 @@ you entered, right above the output it created.
3398 (set (make-local-variable 'sql-prompt-cont-regexp) 3841 (set (make-local-variable 'sql-prompt-cont-regexp)
3399 (sql-get-product-feature sql-product :prompt-cont-regexp)) 3842 (sql-get-product-feature sql-product :prompt-cont-regexp))
3400 (make-local-variable 'sql-output-newline-count) 3843 (make-local-variable 'sql-output-newline-count)
3844 (make-local-variable 'sql-preoutput-hold)
3401 (make-local-variable 'sql-output-by-send) 3845 (make-local-variable 'sql-output-by-send)
3402 (add-hook 'comint-preoutput-filter-functions 3846 (add-hook 'comint-preoutput-filter-functions
3403 'sql-interactive-remove-continuation-prompt nil t) 3847 'sql-interactive-remove-continuation-prompt nil t)
@@ -3450,7 +3894,7 @@ Sentinels will always get the two parameters PROCESS and EVENT."
3450 nil t initial 'sql-connection-history default))) 3894 nil t initial 'sql-connection-history default)))
3451 3895
3452;;;###autoload 3896;;;###autoload
3453(defun sql-connect (connection) 3897(defun sql-connect (connection &optional new-name)
3454 "Connect to an interactive session using CONNECTION settings. 3898 "Connect to an interactive session using CONNECTION settings.
3455 3899
3456See `sql-connection-alist' to see how to define connections and 3900See `sql-connection-alist' to see how to define connections and
@@ -3462,7 +3906,8 @@ is specified in the connection settings."
3462 ;; Prompt for the connection from those defined in the alist 3906 ;; Prompt for the connection from those defined in the alist
3463 (interactive 3907 (interactive
3464 (if sql-connection-alist 3908 (if sql-connection-alist
3465 (list (sql-read-connection "Connection: " nil '(nil))) 3909 (list (sql-read-connection "Connection: " nil '(nil))
3910 current-prefix-arg)
3466 nil)) 3911 nil))
3467 3912
3468 ;; Are there connections defined 3913 ;; Are there connections defined
@@ -3500,14 +3945,15 @@ is specified in the connection settings."
3500 (unless (member token set-params) 3945 (unless (member token set-params)
3501 (if plist 3946 (if plist
3502 (cons token plist) 3947 (cons token plist)
3503 token))))) 3948 token))))))
3504 ;; Remember the connection
3505 (sql-connection connection))
3506 3949
3507 ;; Set the remaining parameters and start the 3950 ;; Set the remaining parameters and start the
3508 ;; interactive session 3951 ;; interactive session
3509 (eval `(let ((,param-var ',rem-params)) 3952 (eval `(let ((sql-connection ,connection)
3510 (sql-product-interactive sql-product))))) 3953 (,param-var ',rem-params))
3954 (sql-product-interactive sql-product
3955 new-name)))))
3956
3511 (message "SQL Connection <%s> does not exist" connection) 3957 (message "SQL Connection <%s> does not exist" connection)
3512 nil))) 3958 nil)))
3513 (message "No SQL Connections defined") 3959 (message "No SQL Connections defined")
@@ -3521,39 +3967,51 @@ optionally is saved to the user's init file."
3521 3967
3522 (interactive "sNew connection name: ") 3968 (interactive "sNew connection name: ")
3523 3969
3524 (if sql-connection 3970 (unless (derived-mode-p 'sql-interactive-mode)
3525 (message "This session was started by a connection; it's already been saved.") 3971 (error "Not in a SQL interactive mode!"))
3526 3972
3527 (let ((login (sql-get-product-feature sql-product :sqli-login)) 3973 ;; Capture the buffer local settings
3528 (alist sql-connection-alist) 3974 (let* ((buf (current-buffer))
3529 connect) 3975 (connection (buffer-local-value 'sql-connection buf))
3530 3976 (product (buffer-local-value 'sql-product buf))
3531 ;; Remove the existing connection if the user says so 3977 (user (buffer-local-value 'sql-user buf))
3532 (when (and (assoc name alist) 3978 (database (buffer-local-value 'sql-database buf))
3533 (yes-or-no-p (format "Replace connection definition <%s>? " name))) 3979 (server (buffer-local-value 'sql-server buf))
3534 (setq alist (assq-delete-all name alist))) 3980 (port (buffer-local-value 'sql-port buf)))
3535 3981
3536 ;; Add the new connection if it doesn't exist 3982 (if connection
3537 (if (assoc name alist) 3983 (message "This session was started by a connection; it's already been saved.")
3538 (message "Connection <%s> already exists" name) 3984
3539 (setq connect 3985 (let ((login (sql-get-product-feature product :sqli-login))
3540 (append (list name) 3986 (alist sql-connection-alist)
3541 (sql-for-each-login 3987 connect)
3542 `(product ,@login) 3988
3543 (lambda (token _plist) 3989 ;; Remove the existing connection if the user says so
3544 (cond 3990 (when (and (assoc name alist)
3545 ((eq token 'product) `(sql-product ',sql-product)) 3991 (yes-or-no-p (format "Replace connection definition <%s>? " name)))
3546 ((eq token 'user) `(sql-user ,sql-user)) 3992 (setq alist (assq-delete-all name alist)))
3547 ((eq token 'database) `(sql-database ,sql-database)) 3993
3548 ((eq token 'server) `(sql-server ,sql-server)) 3994 ;; Add the new connection if it doesn't exist
3549 ((eq token 'port) `(sql-port ,sql-port))))))) 3995 (if (assoc name alist)
3550 3996 (message "Connection <%s> already exists" name)
3551 (setq alist (append alist (list connect))) 3997 (setq connect
3552 3998 (append (list name)
3553 ;; confirm whether we want to save the connections 3999 (sql-for-each-login
3554 (if (yes-or-no-p "Save the connections for future sessions? ") 4000 `(product ,@login)
3555 (customize-save-variable 'sql-connection-alist alist) 4001 (lambda (token _plist)
3556 (customize-set-variable 'sql-connection-alist alist)))))) 4002 (cond
4003 ((eq token 'product) `(sql-product ',product))
4004 ((eq token 'user) `(sql-user ,user))
4005 ((eq token 'database) `(sql-database ,database))
4006 ((eq token 'server) `(sql-server ,server))
4007 ((eq token 'port) `(sql-port ,port)))))))
4008
4009 (setq alist (append alist (list connect)))
4010
4011 ;; confirm whether we want to save the connections
4012 (if (yes-or-no-p "Save the connections for future sessions? ")
4013 (customize-save-variable 'sql-connection-alist alist)
4014 (customize-set-variable 'sql-connection-alist alist)))))))
3557 4015
3558(defun sql-connection-menu-filter (tail) 4016(defun sql-connection-menu-filter (tail)
3559 "Generates menu entries for using each connection." 4017 "Generates menu entries for using each connection."
@@ -3561,7 +4019,10 @@ optionally is saved to the user's init file."
3561 (mapcar 4019 (mapcar
3562 (lambda (conn) 4020 (lambda (conn)
3563 (vector 4021 (vector
3564 (format "Connection <%s>" (car conn)) 4022 (format "Connection <%s>\t%s" (car conn)
4023 (let ((sql-user "") (sql-database "")
4024 (sql-server "") (sql-port 0))
4025 (eval `(let ,(cdr conn) (sql-make-alternate-buffer-name)))))
3565 (list 'sql-connect (car conn)) 4026 (list 'sql-connect (car conn))
3566 t)) 4027 t))
3567 sql-connection-alist) 4028 sql-connection-alist)
@@ -3599,10 +4060,10 @@ the call to \\[sql-product-interactive] with
3599 ;; Get the value of product that we need 4060 ;; Get the value of product that we need
3600 (setq product 4061 (setq product
3601 (cond 4062 (cond
3602 ((and product ; Product specified
3603 (symbolp product)) product)
3604 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product 4063 ((= (prefix-numeric-value product) 4) ; C-u, prompt for product
3605 (sql-read-product "SQL product: " sql-product)) 4064 (sql-read-product "SQL product: " sql-product))
4065 ((and product ; Product specified
4066 (symbolp product)) product)
3606 (t sql-product))) ; Default to sql-product 4067 (t sql-product))) ; Default to sql-product
3607 4068
3608 ;; If we have a product and it has a interactive mode 4069 ;; If we have a product and it has a interactive mode
@@ -3610,7 +4071,7 @@ the call to \\[sql-product-interactive] with
3610 (when (sql-get-product-feature product :sqli-comint-func) 4071 (when (sql-get-product-feature product :sqli-comint-func)
3611 ;; If no new name specified, try to pop to an active SQL 4072 ;; If no new name specified, try to pop to an active SQL
3612 ;; interactive for the same product 4073 ;; interactive for the same product
3613 (let ((buf (sql-find-sqli-buffer product))) 4074 (let ((buf (sql-find-sqli-buffer product sql-connection)))
3614 (if (and (not new-name) buf) 4075 (if (and (not new-name) buf)
3615 (pop-to-buffer buf) 4076 (pop-to-buffer buf)
3616 4077
@@ -3629,23 +4090,24 @@ the call to \\[sql-product-interactive] with
3629 (sql-get-product-feature product :sqli-options)) 4090 (sql-get-product-feature product :sqli-options))
3630 4091
3631 ;; Set SQLi mode. 4092 ;; Set SQLi mode.
3632 (setq new-sqli-buffer (current-buffer))
3633 (let ((sql-interactive-product product)) 4093 (let ((sql-interactive-product product))
3634 (sql-interactive-mode)) 4094 (sql-interactive-mode))
3635 4095
3636 ;; Set the new buffer name 4096 ;; Set the new buffer name
4097 (setq new-sqli-buffer (current-buffer))
3637 (when new-name 4098 (when new-name
3638 (sql-rename-buffer new-name)) 4099 (sql-rename-buffer new-name))
3639
3640 ;; Set `sql-buffer' in the new buffer and the start buffer
3641 (setq sql-buffer (buffer-name new-sqli-buffer)) 4100 (setq sql-buffer (buffer-name new-sqli-buffer))
4101
4102 ;; Set `sql-buffer' in the start buffer
3642 (with-current-buffer start-buffer 4103 (with-current-buffer start-buffer
3643 (setq sql-buffer (buffer-name new-sqli-buffer)) 4104 (when (derived-mode-p 'sql-mode)
3644 (run-hooks 'sql-set-sqli-hook)) 4105 (setq sql-buffer (buffer-name new-sqli-buffer))
4106 (run-hooks 'sql-set-sqli-hook)))
3645 4107
3646 ;; All done. 4108 ;; All done.
3647 (message "Login...done") 4109 (message "Login...done")
3648 (pop-to-buffer sql-buffer))))) 4110 (pop-to-buffer new-sqli-buffer)))))
3649 (message "No default SQL product defined. Set `sql-product'."))) 4111 (message "No default SQL product defined. Set `sql-product'.")))
3650 4112
3651(defun sql-comint (product params) 4113(defun sql-comint (product params)
@@ -3720,6 +4182,157 @@ The default comes from `process-coding-system-alist' and
3720 (setq parameter options)) 4182 (setq parameter options))
3721 (sql-comint product parameter))) 4183 (sql-comint product parameter)))
3722 4184
4185(defun sql-oracle-save-settings (sqlbuf)
4186 "Saves most SQL*Plus settings so they may be reset by \\[sql-redirect]."
4187 ;; Note: does not capture the following settings:
4188 ;;
4189 ;; APPINFO
4190 ;; BTITLE
4191 ;; COMPATIBILITY
4192 ;; COPYTYPECHECK
4193 ;; MARKUP
4194 ;; RELEASE
4195 ;; REPFOOTER
4196 ;; REPHEADER
4197 ;; SQLPLUSCOMPATIBILITY
4198 ;; TTITLE
4199 ;; USER
4200 ;;
4201
4202 (append
4203 ;; (apply 'concat (append
4204 ;; '("SET")
4205
4206 ;; option value...
4207 (sql-redirect-value
4208 sqlbuf
4209 (concat "SHOW ARRAYSIZE AUTOCOMMIT AUTOPRINT AUTORECOVERY AUTOTRACE"
4210 " CMDSEP COLSEP COPYCOMMIT DESCRIBE ECHO EDITFILE EMBEDDED"
4211 " ESCAPE FLAGGER FLUSH HEADING INSTANCE LINESIZE LNO LOBOFFSET"
4212 " LOGSOURCE LONG LONGCHUNKSIZE NEWPAGE NULL NUMFORMAT NUMWIDTH"
4213 " PAGESIZE PAUSE PNO RECSEP SERVEROUTPUT SHIFTINOUT SHOWMODE"
4214 " SPOOL SQLBLANKLINES SQLCASE SQLCODE SQLCONTINUE SQLNUMBER"
4215 " SQLPROMPT SUFFIX TAB TERMOUT TIMING TRIMOUT TRIMSPOOL VERIFY")
4216 "^.+$"
4217 "SET \\&")
4218
4219 ;; option "c" (hex xx)
4220 (sql-redirect-value
4221 sqlbuf
4222 (concat "SHOW BLOCKTERMINATOR CONCAT DEFINE SQLPREFIX SQLTERMINATOR"
4223 " UNDERLINE HEADSEP RECSEPCHAR")
4224 "^\\(.+\\) (hex ..)$"
4225 "SET \\1")
4226
4227 ;; FEDDBACK ON for 99 or more rows
4228 ;; feedback OFF
4229 (sql-redirect-value
4230 sqlbuf
4231 "SHOW FEEDBACK"
4232 "^\\(?:FEEDBACK ON for \\([[:digit:]]+\\) or more rows\\|feedback \\(OFF\\)\\)"
4233 "SET FEEDBACK \\1\\2")
4234
4235 ;; wrap : lines will be wrapped
4236 ;; wrap : lines will be truncated
4237 (list (concat "SET WRAP "
4238 (if (string=
4239 (car (sql-redirect-value
4240 sqlbuf
4241 "SHOW WRAP"
4242 "^wrap : lines will be \\(wrapped\\|truncated\\)" 1))
4243 "wrapped")
4244 "ON" "OFF")))))
4245
4246(defun sql-oracle-restore-settings (sqlbuf saved-settings)
4247 "Restore the SQL*Plus settings in SAVED-SETTINGS."
4248
4249 ;; Remove any settings that haven't changed
4250 (mapc
4251 (lambda (one-cur-setting)
4252 (setq saved-settings (delete one-cur-setting saved-settings)))
4253 (sql-oracle-save-settings sqlbuf))
4254
4255 ;; Restore the changed settings
4256 (sql-redirect sqlbuf saved-settings))
4257
4258(defun sql-oracle-list-all (sqlbuf outbuf enhanced table-name)
4259 ;; Query from USER_OBJECTS or ALL_OBJECTS
4260 (let ((settings (sql-oracle-save-settings sqlbuf))
4261 (simple-sql
4262 (concat
4263 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4264 ", x.object_name AS SQL_EL_NAME "
4265 "FROM user_objects x "
4266 "WHERE x.object_type NOT LIKE '%% BODY' "
4267 "ORDER BY 2, 1;"))
4268 (enhanced-sql
4269 (concat
4270 "SELECT INITCAP(x.object_type) AS SQL_EL_TYPE "
4271 ", x.owner ||'.'|| x.object_name AS SQL_EL_NAME "
4272 "FROM all_objects x "
4273 "WHERE x.object_type NOT LIKE '%% BODY' "
4274 "AND x.owner <> 'SYS' "
4275 "ORDER BY 2, 1;")))
4276
4277 (sql-redirect sqlbuf
4278 (concat "SET LINESIZE 80 PAGESIZE 50000 TRIMOUT ON"
4279 " TAB OFF TIMING OFF FEEDBACK OFF"))
4280
4281 (sql-redirect sqlbuf
4282 (list "COLUMN SQL_EL_TYPE HEADING \"Type\" FORMAT A19"
4283 "COLUMN SQL_EL_NAME HEADING \"Name\""
4284 (format "COLUMN SQL_EL_NAME FORMAT A%d"
4285 (if enhanced 60 35))))
4286
4287 (sql-redirect sqlbuf
4288 (if enhanced enhanced-sql simple-sql)
4289 outbuf)
4290
4291 (sql-redirect sqlbuf
4292 '("COLUMN SQL_EL_NAME CLEAR"
4293 "COLUMN SQL_EL_TYPE CLEAR"))
4294
4295 (sql-oracle-restore-settings sqlbuf settings)))
4296
4297(defun sql-oracle-list-table (sqlbuf outbuf enhanced table-name)
4298 "Implements :list-table under Oracle."
4299 (let ((settings (sql-oracle-save-settings sqlbuf)))
4300
4301 (sql-redirect sqlbuf
4302 (format
4303 (concat "SET LINESIZE %d PAGESIZE 50000"
4304 " DESCRIBE DEPTH 1 LINENUM OFF INDENT ON")
4305 (max 65 (min 120 (window-width)))))
4306
4307 (sql-redirect sqlbuf (format "DESCRIBE %s" table-name)
4308 outbuf)
4309
4310 (sql-oracle-restore-settings sqlbuf settings)))
4311
4312(defcustom sql-oracle-completion-types '("FUNCTION" "PACKAGE" "PROCEDURE"
4313 "SEQUENCE" "SYNONYM" "TABLE" "TRIGGER"
4314 "TYPE" "VIEW")
4315 "List of object types to include for completion under Oracle.
4316
4317See the distinct values in ALL_OBJECTS.OBJECT_TYPE for possible values."
4318 :version "24.1"
4319 :type '(repeat string)
4320 :group 'SQL)
4321
4322(defun sql-oracle-completion-object (sqlbuf schema)
4323 (sql-redirect-value
4324 sqlbuf
4325 (concat
4326 "SELECT CHR(1)||"
4327 (if schema
4328 (format "owner||'.'||object_name AS o FROM all_objects WHERE owner = %s AND "
4329 (sql-str-literal (upcase schema)))
4330 "object_name AS o FROM user_objects WHERE ")
4331 "temporary = 'N' AND generated = 'N' AND secondary = 'N' AND "
4332 "object_type IN ("
4333 (mapconcat (function sql-str-literal) sql-oracle-completion-types ",")
4334 ");")
4335 "^[\001]\\(.+\\)$" 1))
3723 4336
3724 4337
3725;;;###autoload 4338;;;###autoload
@@ -3858,6 +4471,9 @@ The default comes from `process-coding-system-alist' and
3858 (setq params (append options params)) 4471 (setq params (append options params))
3859 (sql-comint product params))) 4472 (sql-comint product params)))
3860 4473
4474(defun sql-sqlite-completion-object (sqlbuf schema)
4475 (sql-redirect-value sqlbuf ".tables" "\\sw\\(?:\\sw\\|\\s_\\)*" 0))
4476
3861 4477
3862 4478
3863;;;###autoload 4479;;;###autoload
@@ -4112,6 +4728,33 @@ Try to set `comint-output-filter-functions' like this:
4112 (setq params (append (list "-p" sql-port) params))) 4728 (setq params (append (list "-p" sql-port) params)))
4113 (sql-comint product params))) 4729 (sql-comint product params)))
4114 4730
4731(defun sql-postgres-completion-object (sqlbuf schema)
4732 (let (cl re fs a r)
4733 (sql-redirect sqlbuf "\\t on")
4734 (setq a (car (sql-redirect-value sqlbuf "\\a" "Output format is \\(.*\\)[.]$" 1)))
4735 (when (string= a "aligned")
4736 (sql-redirect sqlbuf "\\a"))
4737 (setq fs (or (car (sql-redirect-value sqlbuf "\\f" "Field separator is \"\\(.\\)[.]$" 1)) "|"))
4738
4739 (setq re (concat "^\\([^" fs "]*\\)" fs "\\([^" fs "]*\\)" fs "[^" fs "]*" fs "[^" fs "]*$"))
4740 (setq cl (if (not schema)
4741 (sql-redirect-value sqlbuf "\\d" re '(1 2))
4742 (append (sql-redirect-value sqlbuf (format "\\dt %s.*" schema) re '(1 2))
4743 (sql-redirect-value sqlbuf (format "\\dv %s.*" schema) re '(1 2))
4744 (sql-redirect-value sqlbuf (format "\\ds %s.*" schema) re '(1 2)))))
4745
4746 ;; Restore tuples and alignment to what they were
4747 (sql-redirect sqlbuf "\\t off")
4748 (when (not (string= a "aligned"))
4749 (sql-redirect sqlbuf "\\a"))
4750
4751 ;; Return the list of table names (public schema name can be omitted)
4752 (mapcar (lambda (tbl)
4753 (if (string= (car tbl) "public")
4754 (cadr tbl)
4755 (format "%s.%s" (car tbl) (cadr tbl))))
4756 cl)))
4757
4115 4758
4116 4759
4117;;;###autoload 4760;;;###autoload
@@ -4199,8 +4842,7 @@ The default comes from `process-coding-system-alist' and
4199 "Create comint buffer and connect to DB2." 4842 "Create comint buffer and connect to DB2."
4200 ;; Put all parameters to the program (if defined) in a list and call 4843 ;; Put all parameters to the program (if defined) in a list and call
4201 ;; make-comint. 4844 ;; make-comint.
4202 (sql-comint product options) 4845 (sql-comint product options))
4203)
4204 4846
4205;;;###autoload 4847;;;###autoload
4206(defun sql-linter (&optional buffer) 4848(defun sql-linter (&optional buffer)
@@ -4257,3 +4899,6 @@ buffer.
4257(provide 'sql) 4899(provide 'sql)
4258 4900
4259;;; sql.el ends here 4901;;; sql.el ends here
4902
4903; LocalWords: sql SQL SQLite sqlite Sybase Informix MySQL
4904; LocalWords: Postgres SQLServer SQLi
diff --git a/lisp/progmodes/which-func.el b/lisp/progmodes/which-func.el
index 4e4d7b15053..97e188139e9 100644
--- a/lisp/progmodes/which-func.el
+++ b/lisp/progmodes/which-func.el
@@ -206,7 +206,8 @@ It creates the Imenu index for the buffer, if necessary."
206 (setq imenu--index-alist 206 (setq imenu--index-alist
207 (save-excursion (funcall imenu-create-index-function)))) 207 (save-excursion (funcall imenu-create-index-function))))
208 (error 208 (error
209 (message "which-func-ff-hook error: %S" err) 209 (unless (equal err '(error "This buffer cannot use `imenu-default-create-index-function'"))
210 (message "which-func-ff-hook error: %S" err))
210 (setq which-func-mode nil)))) 211 (setq which-func-mode nil))))
211 212
212(defun which-func-update () 213(defun which-func-update ()