diff options
| author | Joakim Verona | 2011-07-15 04:39:29 +0200 |
|---|---|---|
| committer | Joakim Verona | 2011-07-15 04:39:29 +0200 |
| commit | 4f616a2e7ed1db28da98df90266e9751a8ae9ee1 (patch) | |
| tree | 74a9dcbe13e945e712ae04a4a94c2202ca720591 /lisp/progmodes | |
| parent | ff2be00005c3aeda6e11d7ed264ce86f02b60958 (diff) | |
| parent | ec2bc542a4d0127425625e8cb458684bd825675a (diff) | |
| download | emacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.tar.gz emacs-4f616a2e7ed1db28da98df90266e9751a8ae9ee1.zip | |
merge from upstream
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/cc-engine.el | 29 | ||||
| -rw-r--r-- | lisp/progmodes/cc-guess.el | 574 | ||||
| -rw-r--r-- | lisp/progmodes/cc-langs.el | 13 | ||||
| -rw-r--r-- | lisp/progmodes/cc-mode.el | 10 | ||||
| -rw-r--r-- | lisp/progmodes/cc-styles.el | 9 | ||||
| -rw-r--r-- | lisp/progmodes/cc-vars.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/cfengine.el | 268 | ||||
| -rw-r--r-- | lisp/progmodes/compile.el | 11 | ||||
| -rw-r--r-- | lisp/progmodes/cperl-mode.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/etags.el | 6 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 11 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-mi.el | 1058 | ||||
| -rw-r--r-- | lisp/progmodes/grep.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/gud.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/js.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/sql.el | 1155 | ||||
| -rw-r--r-- | lisp/progmodes/which-func.el | 3 |
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. | ||
| 84 | Discard an examined offset if its absolute value is greater than this. | ||
| 85 | |||
| 86 | The 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'. | ||
| 93 | It takes a long time to examine indent information from a large region; | ||
| 94 | this 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 | |||
| 135 | The style is given a name based on the file's absolute file name. | ||
| 136 | |||
| 137 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 138 | non-nil) then the previous guess is extended, otherwise a new guess is | ||
| 139 | made 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 | |||
| 150 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 151 | non-nil) then the previous guess is extended, otherwise a new guess is | ||
| 152 | made 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 | |||
| 163 | The style is given a name based on the file's absolute file name. | ||
| 164 | |||
| 165 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 166 | non-nil) then the previous guess is extended, otherwise a new guess is | ||
| 167 | made 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 | |||
| 177 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 178 | non-nil) then the previous guess is extended, otherwise a new guess is | ||
| 179 | made 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 | |||
| 189 | The style is given a name based on the file's absolute file name. | ||
| 190 | |||
| 191 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 192 | non-nil) then the previous guess is extended, otherwise a new guess is | ||
| 193 | made 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 | |||
| 207 | Every line of code in the region is examined and values for the following two | ||
| 208 | variables are guessed: | ||
| 209 | |||
| 210 | * `c-basic-offset', and | ||
| 211 | * the indentation values of the various syntactic symbols in | ||
| 212 | `c-offsets-alist'. | ||
| 213 | |||
| 214 | The guessed values are put into `c-guess-guessed-basic-offset' and | ||
| 215 | `c-guess-guessed-offsets-alist'. | ||
| 216 | |||
| 217 | Frequencies of use are taken into account when guessing, so minor | ||
| 218 | inconsistencies in the indentation style shouldn't produce wrong guesses. | ||
| 219 | |||
| 220 | If given a prefix argument (or if the optional argument ACCUMULATE is | ||
| 221 | non-nil) then the previous examination is extended, otherwise a new | ||
| 222 | guess is made from scratch. | ||
| 223 | |||
| 224 | Note that the larger the region to guess in, the slower the guessing. | ||
| 225 | So 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 | |||
| 427 | The 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 | ||
| 429 | the 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, | ||
| 467 | PRINTER is used instead. If PRINTER is not `nil', it | ||
| 468 | is 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. | ||
| 531 | So you can put the code into .emacs if you prefer the | ||
| 532 | guessed code. | ||
| 533 | \"STYLE NAME HERE\" is used as the name for the style in the | ||
| 534 | emitted code. If WITH-NAME is given, it is used instead. | ||
| 535 | WITH-NAME is expected as a string but if this function | ||
| 536 | called interactively with prefix argument, the value for | ||
| 537 | WITH-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. | ||
| 655 | DEFAULT-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. |
| 66 | This includes those for cfservd as well as cfagent.")) | 74 | This 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. | ||
| 255 | Treats 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. | ||
| 265 | Treats 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. | ||
| 274 | Intended 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. | ||
| 421 | There are no special keybindings by default. | ||
| 422 | |||
| 423 | Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves | ||
| 424 | to 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 | ||
| 205 | Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves | 443 | Action blocks are treated as defuns, i.e. \\[beginning-of-defun] moves |
| 206 | to the action header." | 444 | to 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." | |||
| 1860 | Stops when a match is found. | 1860 | Stops when a match is found. |
| 1861 | To continue searching for next match, use command \\[tags-loop-continue]. | 1861 | To continue searching for next match, use command \\[tags-loop-continue]. |
| 1862 | 1862 | ||
| 1863 | See documentation of variable `tags-file-name'." | 1863 | If `file-list-form' is non-nil, it should be a form that, when |
| 1864 | evaluated, will return a list of file names. The search will be | ||
| 1865 | restricted to these files. | ||
| 1866 | |||
| 1867 | Aleso 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. |
| 193 | Each element has the form (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS HAS_MORE FP) | 194 | Each element has the form |
| 195 | (VARNUM EXPRESSION NUMCHILD TYPE VALUE STATUS HAS_MORE FP) | ||
| 194 | where STATUS is nil (`unchanged'), `changed' or `out-of-scope', FP the frame | 196 | where STATUS is nil (`unchanged'), `changed' or `out-of-scope', FP the frame |
| 195 | address for root variables.") | 197 | address 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 | ||
| 2315 | TRIGGER-NAME trigger is defined to send GDB-COMMAND. See | 2328 | TRIGGER-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 |
| 2732 | on the current line." | 2749 | on 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 | |||
| 3806 | already, in which case that window is splitted first." | 3837 | already, 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 | ||
| 3966 | When IGNORE-DEDICATED is non-nil, buffer is set even if selected | 3999 | When IGNORE-DEDICATED is non-nil, buffer is set even if selected |
| 3967 | window is dedicated." | 4000 | window 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 | |||
| 4022 | With arg, display additional buffers iff arg is positive." | 4056 | With 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. |
| 4038 | This arrangement depends on the value of `gdb-many-windows'." | 4072 | This 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 |
| 4100 | PUTSTRING." | 4133 | PUTSTRING." |
| 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 | |||
| 574 | settings.") | 608 | settings.") |
| 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 | |||
| 723 | Globally 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 | |||
| 823 | All products share this list; products should define a regexp to | ||
| 824 | identify additional keywords in a variable defined by | ||
| 825 | the :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 | ||
| 801 | When non-nil, Emacs will scan text sent to sqlplus and prompt | 858 | When non-nil, Emacs will scan text sent to sqlplus and prompt |
| 802 | for replacement text for & placeholders as sqlplus does. This | 859 | for replacement text for & placeholders as sqlplus does. This |
| 803 | is needed on Windows where sqlplus output is buffered and the | 860 | is needed on Windows where SQL*Plus output is buffered and the |
| 804 | prompts are not shown until after the text is entered. | 861 | prompts are not shown until after the text is entered. |
| 805 | 862 | ||
| 806 | You will probably want to issue the following command in sqlplus | 863 | You need to issue the following command in SQL*Plus to be safe: |
| 807 | to be safe: | 864 | |
| 865 | SET DEFINE OFF | ||
| 808 | 866 | ||
| 809 | SET SCAN OFF" | 867 | In 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 | ||
| 1086 | Used by `sql-rename-buffer'.") | 1144 | Used 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 | ||
| 1091 | BUFFER can be a buffer object or a buffer name. The buffer must | 1149 | BUFFER can be a buffer object or a buffer name. The buffer must |
| 1092 | be a live buffer, have an running process attached to it, be in | 1150 | be 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." | 1152 | specified, 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 | |||
| 1414 | you define your own `sql-mode-ansi-font-lock-keywords'. You may want | 1506 | you define your own `sql-mode-ansi-font-lock-keywords'. You may want |
| 1415 | to add functions and PL/SQL keywords.") | 1507 | to 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. |
| 2421 | The prompt is assumed to be any text at the beginning of the line matching | 2655 | The prompt is assumed to be any text at the beginning of the line |
| 2422 | the regular expression `comint-prompt-regexp', a buffer local variable." | 2656 | matching the regular expression `comint-prompt-regexp', a buffer |
| 2657 | local 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 | ||
| 2459 | List products with :free-softare attribute set to FREEP. Indent | 2759 | List products with :free-software attribute set to FREEP. Indent |
| 2460 | each line with INDENT." | 2760 | each 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. |
| 2654 | In order to qualify, the SQLi buffer must be alive, be in | 2954 | In 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 | |||
| 2722 | This is the buffer SQL strings are sent to. It is stored in the | 3022 | This is the buffer SQL strings are sent to. It is stored in the |
| 2723 | variable `sql-buffer'. See `sql-help' on how to create such a buffer." | 3023 | variable `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 | ||
| 2938 | Added to the `comint-preoutput-filter-functions' hook in a SQL | 3241 | Added to the `comint-preoutput-filter-functions' hook in a SQL |
| 2939 | interactive buffer. If `sql-outut-newline-count' is greater than | 3242 | interactive buffer. If `sql-output-newline-count' is greater than |
| 2940 | zero, then an output line matching the continuation prompt is filtered | 3243 | zero, then an output line matching the continuation prompt is filtered |
| 2941 | out. If the count is one, then the prompt is replaced with a newline | 3244 | out. If the count is zero, then a newline is inserted into the output |
| 2942 | to force the output from the query to appear on a new line." | 3245 | to 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 | 3247 | The complication to this filter is that the continuation prompts |
| 2945 | (numberp sql-output-newline-count) | 3248 | may arrive in multiple chunks. If they do, then the function |
| 2946 | (>= sql-output-newline-count 1)) | 3249 | saves any unfiltered output in a buffer and prepends that buffer |
| 2947 | (progn | 3250 | to the next chunk to properly match the broken-up prompt. |
| 2948 | (while (and oline | 3251 | |
| 2949 | sql-output-newline-count | 3252 | If the filter gets confused, it should reset and stop filtering |
| 2950 | (> sql-output-newline-count 0) | 3253 | to 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 | ||
| 3072 | COMBUF must be an active SQL interactive buffer. OUTBUF may be | 3400 | SQLBUF must be an active SQL interactive buffer. OUTBUF may be |
| 3073 | an existing buffer, or the name of a non-existing buffer. If | 3401 | an existing buffer, or the name of a non-existing buffer. If |
| 3074 | omitted the output is sent to a temporary buffer which will be | 3402 | omitted the output is sent to a temporary buffer which will be |
| 3075 | killed after the command completes. COMMAND should be a string | 3403 | killed after the command completes. COMMAND should be a string |
| 3076 | of commands accepted by the SQLi program." | 3404 | of commands accepted by the SQLi program. COMMAND may also be a |
| 3077 | 3405 | list 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 | ||
| 3115 | COMBUF must be an active SQL interactive buffer. COMMAND should | 3461 | SQLBUF must be an active SQL interactive buffer. COMMAND should |
| 3116 | be a string of commands accepted by the SQLi program. From the | 3462 | be a string of commands accepted by the SQLi program. From the |
| 3117 | output, the REGEXP is repeatedly matched and the list of | 3463 | output, the REGEXP is repeatedly matched and the list of |
| 3118 | REGEXP-GROUPS submatches is returned. This behaves much like | 3464 | REGEXP-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 | ||
| 3160 | The commands are run in SQLBUF and the output saved in OUTBUF. | 3511 | The commands are run in SQLBUF and the output saved in OUTBUF. |
| 3161 | COMMAND must be a string, a function or a list of such elements. | 3512 | COMMAND 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 | |||
| 3556 | The list is maintained in SQL interactive buffers.") | ||
| 3557 | |||
| 3558 | (defvar sql-completion-column nil | ||
| 3559 | "A list of column names used for completion. | ||
| 3560 | |||
| 3561 | The 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 | ||
| 3456 | See `sql-connection-alist' to see how to define connections and | 3900 | See `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 | |||
| 4317 | See 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 () |