diff options
| author | Miles Bader | 2004-06-28 07:56:49 +0000 |
|---|---|---|
| committer | Miles Bader | 2004-06-28 07:56:49 +0000 |
| commit | 327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801 (patch) | |
| tree | 21de188e13b5e41a79bb50040933072ae0235217 /lisp/progmodes | |
| parent | 852f73b7fa7b71910282eacb6263b3ecfd4ee783 (diff) | |
| parent | 376de73927383d6062483db10b8a82448505f52b (diff) | |
| download | emacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.tar.gz emacs-327719ee8a3fcdb36ed6acaf6d8cb5fbdf0bd801.zip | |
Revision: miles@gnu.org--gnu-2004/emacs--unicode--0--patch-15
Merge from emacs--cvs-trunk--0
Patches applied:
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-218
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-220
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-221
Restore deleted tagline in etc/TUTORIAL.ru
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-222
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-228
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-229
Remove TeX output files from the archive
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-230
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-247
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-248
src/lisp.h (CYCLE_CHECK): Macro moved from xfaces.c
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-249
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-256
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-258
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-263
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-264
Update from CVS: lispref/display.texi: emacs -> Emacs.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-265
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-274
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-275
Update from CVS: man/makefile.w32-in: Revert last change
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-276
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-295
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-296
Allow restarting an existing debugger session that's exited
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-297
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-299
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-300
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-327
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-328
Update from CVS: src/.gdbinit (xsymbol): Fix last change.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-329
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-344
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-345
Tweak source regexps so that building in place won't cause problems
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-346
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-351
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-352
Update from CVS: lisp/flymake.el: New file.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-353
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-361
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-362
Support " [...]" style defaults in minibuffer-electric-default-mode
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-363
(read-number): Use canonical format for default in prompt.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-364
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-367
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-368
Improve display-supports-face-attributes-p on non-ttys
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-369
Rewrite face-differs-from-default-p
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-370
Move `display-supports-face-attributes-p' entirely into C code
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-371
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-372
Simplify face-differs-from-default-p; don't consider :stipple.
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-373
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-374
(tty_supports_face_attributes_p): Ensure attributes differ from default
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-375
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-376
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-377
(Fdisplay_supports_face_attributes_p): Work around bootstrapping problem
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-378
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-380
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-381
Face merging cleanups
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-382
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-384
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-385
src/xfaces.c (push_named_merge_point): Return 0 if a cycle is detected
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-386
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-395
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-396
Tweak arch tagging to make build/install-in-place less annoying
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-397
Work around vc-arch problems when building eshell
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-398
Tweak permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-399
Tweak directory permissions
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-400
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-401
More build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-402
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-403
Yet more build-in-place tweaking of arch tagging
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-404
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-409
Update from CVS
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-410
Make sure image types are initialized for lookup too
* miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-411
- miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-416
Update from CVS
Diffstat (limited to 'lisp/progmodes')
| -rw-r--r-- | lisp/progmodes/ada-mode.el | 16 | ||||
| -rw-r--r-- | lisp/progmodes/cc-cmds.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/cfengine.el | 7 | ||||
| -rw-r--r-- | lisp/progmodes/compile.el | 619 | ||||
| -rw-r--r-- | lisp/progmodes/cperl-mode.el | 9 | ||||
| -rw-r--r-- | lisp/progmodes/etags.el | 19 | ||||
| -rw-r--r-- | lisp/progmodes/f90.el | 60 | ||||
| -rw-r--r-- | lisp/progmodes/flymake.el | 2504 | ||||
| -rw-r--r-- | lisp/progmodes/fortran.el | 3 | ||||
| -rw-r--r-- | lisp/progmodes/gdb-ui.el | 520 | ||||
| -rw-r--r-- | lisp/progmodes/grep.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/gud.el | 95 | ||||
| -rw-r--r-- | lisp/progmodes/idlw-shell.el | 4 | ||||
| -rw-r--r-- | lisp/progmodes/python.el | 569 | ||||
| -rw-r--r-- | lisp/progmodes/sh-script.el | 2 | ||||
| -rw-r--r-- | lisp/progmodes/sql.el | 941 |
16 files changed, 4188 insertions, 1186 deletions
diff --git a/lisp/progmodes/ada-mode.el b/lisp/progmodes/ada-mode.el index abc8db6d2c3..f7688e24069 100644 --- a/lisp/progmodes/ada-mode.el +++ b/lisp/progmodes/ada-mode.el | |||
| @@ -1466,8 +1466,8 @@ The standard casing rules will no longer apply to this word." | |||
| 1466 | ;; If the word is already in the list, even with a different casing | 1466 | ;; If the word is already in the list, even with a different casing |
| 1467 | ;; we simply want to replace it. | 1467 | ;; we simply want to replace it. |
| 1468 | (if (and (not (equal ada-case-exception '())) | 1468 | (if (and (not (equal ada-case-exception '())) |
| 1469 | (assoc-ignore-case word ada-case-exception)) | 1469 | (assoc-string word ada-case-exception t)) |
| 1470 | (setcar (assoc-ignore-case word ada-case-exception) word) | 1470 | (setcar (assoc-string word ada-case-exception t) word) |
| 1471 | (add-to-list 'ada-case-exception (cons word t)) | 1471 | (add-to-list 'ada-case-exception (cons word t)) |
| 1472 | ) | 1472 | ) |
| 1473 | 1473 | ||
| @@ -1519,8 +1519,8 @@ word itself has a special casing." | |||
| 1519 | ;; If the word is already in the list, even with a different casing | 1519 | ;; If the word is already in the list, even with a different casing |
| 1520 | ;; we simply want to replace it. | 1520 | ;; we simply want to replace it. |
| 1521 | (if (and (not (equal ada-case-exception-substring '())) | 1521 | (if (and (not (equal ada-case-exception-substring '())) |
| 1522 | (assoc-ignore-case word ada-case-exception-substring)) | 1522 | (assoc-string word ada-case-exception-substring t)) |
| 1523 | (setcar (assoc-ignore-case word ada-case-exception-substring) word) | 1523 | (setcar (assoc-string word ada-case-exception-substring t) word) |
| 1524 | (add-to-list 'ada-case-exception-substring (cons word t)) | 1524 | (add-to-list 'ada-case-exception-substring (cons word t)) |
| 1525 | ) | 1525 | ) |
| 1526 | 1526 | ||
| @@ -1548,9 +1548,9 @@ word itself has a special casing." | |||
| 1548 | (if (char-equal (string-to-char word) ?*) | 1548 | (if (char-equal (string-to-char word) ?*) |
| 1549 | (progn | 1549 | (progn |
| 1550 | (setq word (substring word 1)) | 1550 | (setq word (substring word 1)) |
| 1551 | (unless (assoc-ignore-case word ada-case-exception-substring) | 1551 | (unless (assoc-string word ada-case-exception-substring t) |
| 1552 | (add-to-list 'ada-case-exception-substring (cons word t)))) | 1552 | (add-to-list 'ada-case-exception-substring (cons word t)))) |
| 1553 | (unless (assoc-ignore-case word ada-case-exception) | 1553 | (unless (assoc-string word ada-case-exception t) |
| 1554 | (add-to-list 'ada-case-exception (cons word t))))) | 1554 | (add-to-list 'ada-case-exception (cons word t))))) |
| 1555 | 1555 | ||
| 1556 | (forward-line 1)) | 1556 | (forward-line 1)) |
| @@ -1618,8 +1618,8 @@ the exceptions defined in `ada-case-exception-file'." | |||
| 1618 | (point))) | 1618 | (point))) |
| 1619 | match) | 1619 | match) |
| 1620 | ;; If we have an exception, replace the word by the correct casing | 1620 | ;; If we have an exception, replace the word by the correct casing |
| 1621 | (if (setq match (assoc-ignore-case (buffer-substring start end) | 1621 | (if (setq match (assoc-string (buffer-substring start end) |
| 1622 | ada-case-exception)) | 1622 | ada-case-exception t)) |
| 1623 | 1623 | ||
| 1624 | (progn | 1624 | (progn |
| 1625 | (delete-region start end) | 1625 | (delete-region start end) |
diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index c6f60d3dcc0..a61369004e8 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el | |||
| @@ -1488,7 +1488,7 @@ more \"DWIM:ey\"." | |||
| 1488 | (save-excursion | 1488 | (save-excursion |
| 1489 | (beginning-of-line) | 1489 | (beginning-of-line) |
| 1490 | (or (not (re-search-backward | 1490 | (or (not (re-search-backward |
| 1491 | sentence-end | 1491 | (sentence-end) |
| 1492 | (c-point 'bopl) | 1492 | (c-point 'bopl) |
| 1493 | t)) | 1493 | t)) |
| 1494 | (< (match-end 0) | 1494 | (< (match-end 0) |
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el index 62633fe2940..16064586ee9 100644 --- a/lisp/progmodes/cfengine.el +++ b/lisp/progmodes/cfengine.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; cfengine.el --- mode for editing Cfengine files | 1 | ;;; cfengine.el --- mode for editing Cfengine files |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 2003 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2003, 2004 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Dave Love <fx@gnu.org> | 5 | ;; Author: Dave Love <fx@gnu.org> |
| 6 | ;; Keywords: languages | 6 | ;; Keywords: languages |
| @@ -102,7 +102,8 @@ This includes those for cfservd as well as cfagent.")) | |||
| 102 | (defun cfengine-beginning-of-defun () | 102 | (defun cfengine-beginning-of-defun () |
| 103 | "`beginning-of-defun' function for Cfengine mode. | 103 | "`beginning-of-defun' function for Cfengine mode. |
| 104 | Treats actions as defuns." | 104 | Treats actions as defuns." |
| 105 | (end-of-line) | 105 | (unless (<= (current-column) (current-indentation)) |
| 106 | (end-of-line)) | ||
| 106 | (if (re-search-backward "^[[:alpha:]]+: *$" nil t) | 107 | (if (re-search-backward "^[[:alpha:]]+: *$" nil t) |
| 107 | (beginning-of-line) | 108 | (beginning-of-line) |
| 108 | (goto-char (point-min))) | 109 | (goto-char (point-min))) |
| @@ -113,7 +114,7 @@ Treats actions as defuns." | |||
| 113 | Treats actions as defuns." | 114 | Treats actions as defuns." |
| 114 | (end-of-line) | 115 | (end-of-line) |
| 115 | (if (re-search-forward "^[[:alpha:]]+: *$" nil t) | 116 | (if (re-search-forward "^[[:alpha:]]+: *$" nil t) |
| 116 | (progn (forward-line -1) (end-of-line)) | 117 | (beginning-of-line) |
| 117 | (goto-char (point-max))) | 118 | (goto-char (point-max))) |
| 118 | t) | 119 | t) |
| 119 | 120 | ||
diff --git a/lisp/progmodes/compile.el b/lisp/progmodes/compile.el index ff4256192c4..033ce883e5f 100644 --- a/lisp/progmodes/compile.el +++ b/lisp/progmodes/compile.el | |||
| @@ -100,7 +100,7 @@ in the compilation output, and should return a transformed file name.") | |||
| 100 | ;;;###autoload | 100 | ;;;###autoload |
| 101 | (defvar compilation-process-setup-function nil | 101 | (defvar compilation-process-setup-function nil |
| 102 | "*Function to call to customize the compilation process. | 102 | "*Function to call to customize the compilation process. |
| 103 | This functions is called immediately before the compilation process is | 103 | This function is called immediately before the compilation process is |
| 104 | started. It can be used to set any variables or functions that are used | 104 | started. It can be used to set any variables or functions that are used |
| 105 | while processing the output of the compilation process. The function | 105 | while processing the output of the compilation process. The function |
| 106 | is called with variables `compilation-buffer' and `compilation-window' | 106 | is called with variables `compilation-buffer' and `compilation-window' |
| @@ -125,11 +125,6 @@ describing how the process finished.") | |||
| 125 | Each function is called with two arguments: the compilation buffer, | 125 | Each function is called with two arguments: the compilation buffer, |
| 126 | and a string describing how the process finished.") | 126 | and a string describing how the process finished.") |
| 127 | 127 | ||
| 128 | (defvar compilation-last-buffer nil | ||
| 129 | "The most recent compilation buffer. | ||
| 130 | A buffer becomes most recent when its compilation is started | ||
| 131 | or when it is used with \\[next-error] or \\[compile-goto-error].") | ||
| 132 | |||
| 133 | (defvar compilation-in-progress nil | 128 | (defvar compilation-in-progress nil |
| 134 | "List of compilation processes now running.") | 129 | "List of compilation processes now running.") |
| 135 | (or (assq 'compilation-in-progress minor-mode-alist) | 130 | (or (assq 'compilation-in-progress minor-mode-alist) |
| @@ -176,8 +171,15 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 176 | "^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\ | 171 | "^\"\\([^,\" \n\t]+\\)\", line \\([0-9]+\\)\ |
| 177 | \\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4)) | 172 | \\(?:[(. pos]+\\([0-9]+\\))?\\)?[:.,; (-]\\( warning:\\|[-0-9 ]*(W)\\)?" 1 2 3 (4)) |
| 178 | 173 | ||
| 174 | (edg-1 | ||
| 175 | "^\\([^ \n]+\\)(\\([0-9]+\\)): \\(?:error\\|warnin\\(g\\)\\|remar\\(k\\)\\)" | ||
| 176 | 1 2 nil (3 . 4)) | ||
| 177 | (edg-2 | ||
| 178 | "at line \\([0-9]+\\) of \"\\([^ \n]+\\)\"$" | ||
| 179 | 2 1 nil 0) | ||
| 180 | |||
| 179 | (epc | 181 | (epc |
| 180 | "^Error [0-9]+ at (\\([0-9]*\\):\\([^)\n]+\\))" 2 1) | 182 | "^Error [0-9]+ at (\\([0-9]+\\):\\([^)\n]+\\))" 2 1) |
| 181 | 183 | ||
| 182 | (iar | 184 | (iar |
| 183 | "^\"\\(.*\\)\",\\([0-9]+\\)\\s-+\\(?:Error\\|Warnin\\(g\\)\\)\\[[0-9]+\\]:" | 185 | "^\"\\(.*\\)\",\\([0-9]+\\)\\s-+\\(?:Error\\|Warnin\\(g\\)\\)\\[[0-9]+\\]:" |
| @@ -187,8 +189,9 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 187 | "^\\([^( \n\t]+\\)(\\([0-9]+\\):\\([0-9]+\\)) :\ | 189 | "^\\([^( \n\t]+\\)(\\([0-9]+\\):\\([0-9]+\\)) :\ |
| 188 | \\(?:warnin\\(g\\)\\|informationa\\(l\\)\\)?" 1 2 3 (4 . 5)) | 190 | \\(?:warnin\\(g\\)\\|informationa\\(l\\)\\)?" 1 2 3 (4 . 5)) |
| 189 | 191 | ||
| 192 | ;; fixme: should be `mips' | ||
| 190 | (irix | 193 | (irix |
| 191 | "^[a-z0-9/]+: \\(?:[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*:\ | 194 | "^[-[:alnum:]_/]+: \\(?:[sS]evere\\|[eE]rror\\|[wW]arnin\\(g\\)\\|[iI]nf\\(o\\)\\)[0-9 ]*:\ |
| 192 | \\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2)) | 195 | \\([^,\" \n\t]+\\)\\(?:, line\\|:\\) \\([0-9]+\\):" 3 4 nil (1 . 2)) |
| 193 | 196 | ||
| 194 | (java | 197 | (java |
| @@ -206,8 +209,8 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 206 | \\(.+\\):\\([0-9]+\\)\\(?:\\(:\\)\\|\\(,\\)\\)?" 1 2 nil (3 . 4)) | 209 | \\(.+\\):\\([0-9]+\\)\\(?:\\(:\\)\\|\\(,\\)\\)?" 1 2 nil (3 . 4)) |
| 207 | 210 | ||
| 208 | (gnu | 211 | (gnu |
| 209 | "^\\(?:[a-zA-Z][-a-zA-Z0-9.]+: ?\\)?\ | 212 | "^\\(?:[[:alpha:]][-[:alnum:].]+: ?\\)?\ |
| 210 | \\([/.]*[a-zA-Z]:?[^ \t\n:]*\\): ?\ | 213 | \\([/.]*[a-zA-Z]:?[^ \t\n:]*\\|{standard input}\\): ?\ |
| 211 | \\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\ | 214 | \\([0-9]+\\)\\([.:]?\\)\\([0-9]+\\)?\ |
| 212 | \\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?:\ | 215 | \\(?:-\\(?:\\([0-9]+\\)\\3\\)?\\.?\\([0-9]+\\)?\\)?:\ |
| 213 | \\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\ | 216 | \\(?: *\\(\\(?:Future\\|Runtime\\)?[Ww]arning\\|W:\\)\\|\ |
| @@ -228,6 +231,7 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 228 | (1 (compilation-error-properties 2 3 nil nil nil 0 nil) | 231 | (1 (compilation-error-properties 2 3 nil nil nil 0 nil) |
| 229 | append))) | 232 | append))) |
| 230 | 233 | ||
| 234 | ;; Should be lint-1, lint-2 (SysV lint) | ||
| 231 | (mips-1 | 235 | (mips-1 |
| 232 | " (\\([0-9]+\\)) in \\([^ \n]+\\)" 2 1) | 236 | " (\\([0-9]+\\)) in \\([^ \n]+\\)" 2 1) |
| 233 | (mips-2 | 237 | (mips-2 |
| @@ -238,7 +242,9 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 238 | : \\(?:error\\|warnin\\(g\\)\\) C[0-9]+:" 1 2 nil (3)) | 242 | : \\(?:error\\|warnin\\(g\\)\\) C[0-9]+:" 1 2 nil (3)) |
| 239 | 243 | ||
| 240 | (oracle | 244 | (oracle |
| 241 | "^Semantic error at line \\([0-9]+\\), column \\([0-9]+\\), file \\(.*\\):$" | 245 | "^\\(?:Semantic error\\|Error\\|PCC-[0-9]+:\\).* line \\([0-9]+\\)\ |
| 246 | \\(?:\\(?:,\\| at\\)? column \\([0-9]+\\)\\)?\ | ||
| 247 | \\(?:,\\| in\\| of\\)? file \\(.*?\\):?$" | ||
| 242 | 3 1 2) | 248 | 3 1 2) |
| 243 | 249 | ||
| 244 | (perl | 250 | (perl |
| @@ -261,16 +267,13 @@ of[ \t]+\"?\\([a-zA-Z]?:?[^\":\n]+\\)\"?:" 3 2 nil (1)) | |||
| 261 | nil 1 nil (3) nil (2 (compilation-face '(3)))) | 267 | nil 1 nil (3) nil (2 (compilation-face '(3)))) |
| 262 | 268 | ||
| 263 | (sun | 269 | (sun |
| 264 | ": \\(?:ERROR\\|WARNIN\\(G\\)\\|REMAR\\(K\\)\\) \\(?:[a-zA-Z0-9 ]+, \\)?\ | 270 | ": \\(?:ERROR\\|WARNIN\\(G\\)\\|REMAR\\(K\\)\\) \\(?:[[:alnum:] ]+, \\)?\ |
| 265 | File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?" | 271 | File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?" |
| 266 | 3 4 5 (1 . 2)) | 272 | 3 4 5 (1 . 2)) |
| 267 | 273 | ||
| 268 | (sun-ada | 274 | (sun-ada |
| 269 | "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3) | 275 | "^\\([^, \n\t]+\\), line \\([0-9]+\\), char \\([0-9]+\\)[:., \(-]" 1 2 3) |
| 270 | 276 | ||
| 271 | (ultrix | ||
| 272 | "^\\(?:cfe\\|fort\\): \\(Warning\\)?[^:\n]*: \\([^ \n]*\\), line \\([0-9]+\\):" 2 3 nil (1)) | ||
| 273 | |||
| 274 | (4bsd | 277 | (4bsd |
| 275 | "\\(?:^\\|:: \\|\\S ( \\)\\(/[^ \n\t()]+\\)(\\([0-9]+\\))\ | 278 | "\\(?:^\\|:: \\|\\S ( \\)\\(/[^ \n\t()]+\\)(\\([0-9]+\\))\ |
| 276 | \\(?:: \\(warning:\\)?\\|$\\| ),\\)" 1 2 nil (3))) | 279 | \\(?:: \\(warning:\\)?\\|$\\| ),\\)" 1 2 nil (3))) |
| @@ -279,14 +282,14 @@ File = \\(.+\\), Line = \\([0-9]+\\)\\(?:, Column = \\([0-9]+\\)\\)?" | |||
| 279 | (defcustom compilation-error-regexp-alist | 282 | (defcustom compilation-error-regexp-alist |
| 280 | (mapcar 'car compilation-error-regexp-alist-alist) | 283 | (mapcar 'car compilation-error-regexp-alist-alist) |
| 281 | "Alist that specifies how to match errors in compiler output. | 284 | "Alist that specifies how to match errors in compiler output. |
| 282 | Note that on Unix exerything is a valid filename, so these | 285 | Note that on Unix everything is a valid filename, so these |
| 283 | matchers must make some common sense assumptions, which catch | 286 | matchers must make some common sense assumptions, which catch |
| 284 | normal cases. A shorter list will be lighter on resource usage. | 287 | normal cases. A shorter list will be lighter on resource usage. |
| 285 | 288 | ||
| 286 | Instead of an alist element, you can use a symbol, which is | 289 | Instead of an alist element, you can use a symbol, which is |
| 287 | looked up in `compilation-error-regexp-alist-alist'. You can see | 290 | looked up in `compilation-error-regexp-alist-alist'. You can see |
| 288 | the predefined symbols and their effects in the file | 291 | the predefined symbols and their effects in the file |
| 289 | `etc/compilation.txt' (linked below if your are customizing this). | 292 | `etc/compilation.txt' (linked below if you are customizing this). |
| 290 | 293 | ||
| 291 | Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK | 294 | Each elt has the form (REGEXP FILE [LINE COLUMN TYPE HYPERLINK |
| 292 | HIGHLIGHT...]). If REGEXP matches, the FILE'th subexpression | 295 | HIGHLIGHT...]). If REGEXP matches, the FILE'th subexpression |
| @@ -328,7 +331,7 @@ be added." | |||
| 328 | (list 'const (car elt))) | 331 | (list 'const (car elt))) |
| 329 | compilation-error-regexp-alist-alist)) | 332 | compilation-error-regexp-alist-alist)) |
| 330 | :link `(file-link :tag "example file" | 333 | :link `(file-link :tag "example file" |
| 331 | ,(concat doc-directory "compilation.txt")) | 334 | ,(expand-file-name "compilation.txt" data-directory)) |
| 332 | :group 'compilation) | 335 | :group 'compilation) |
| 333 | 336 | ||
| 334 | (defvar compilation-directory nil | 337 | (defvar compilation-directory nil |
| @@ -357,7 +360,7 @@ you may also want to change `compilation-page-delimiter'.") | |||
| 357 | (1 font-lock-variable-name-face) | 360 | (1 font-lock-variable-name-face) |
| 358 | (2 (compilation-face '(4 . 3)))) | 361 | (2 (compilation-face '(4 . 3)))) |
| 359 | ;; Command output lines. Recognize `make[n]:' lines too. | 362 | ;; Command output lines. Recognize `make[n]:' lines too. |
| 360 | ("^\\([A-Za-z_0-9/.+-]+\\)\\(\\[\\([0-9]+\\)\\]\\)?[ \t]*:" | 363 | ("^\\([[:alnum:]_/.+-]+\\)\\(\\[\\([0-9]+\\)\\]\\)?[ \t]*:" |
| 361 | (1 font-lock-function-name-face) (3 compilation-line-face nil t)) | 364 | (1 font-lock-function-name-face) (3 compilation-line-face nil t)) |
| 362 | (" --?o\\(?:utfile\\|utput\\)?[= ]?\\(\\S +\\)" . 1) | 365 | (" --?o\\(?:utfile\\|utput\\)?[= ]?\\(\\S +\\)" . 1) |
| 363 | ("^Compilation finished" . compilation-info-face) | 366 | ("^Compilation finished" . compilation-info-face) |
| @@ -427,7 +430,7 @@ You might also use mode hooks to specify it in certain modes, like this: | |||
| 427 | (defvar compilation-locs ()) | 430 | (defvar compilation-locs ()) |
| 428 | 431 | ||
| 429 | (defvar compilation-debug nil | 432 | (defvar compilation-debug nil |
| 430 | "*Set this to `t' before creating a *compilation* buffer. | 433 | "*Set this to t before creating a *compilation* buffer. |
| 431 | Then every error line will have a debug text property with the matcher that | 434 | Then every error line will have a debug text property with the matcher that |
| 432 | fit this line and the match data. Use `describe-text-properties'.") | 435 | fit this line and the match data. Use `describe-text-properties'.") |
| 433 | 436 | ||
| @@ -447,17 +450,19 @@ starting the compilation process.") | |||
| 447 | (defvar compile-history nil) | 450 | (defvar compile-history nil) |
| 448 | 451 | ||
| 449 | (defface compilation-warning-face | 452 | (defface compilation-warning-face |
| 450 | '((((type tty) (class color)) (:foreground "cyan" :weight bold)) | 453 | '((((class color) (min-colors 16)) (:foreground "Orange" :weight bold)) |
| 451 | (((class color)) (:foreground "Orange" :weight bold)) | 454 | (((class color)) (:foreground "cyan" :weight bold)) |
| 452 | (t (:weight bold))) | 455 | (t (:weight bold))) |
| 453 | "Face used to highlight compiler warnings." | 456 | "Face used to highlight compiler warnings." |
| 454 | :group 'font-lock-highlighting-faces | 457 | :group 'font-lock-highlighting-faces |
| 455 | :version "21.4") | 458 | :version "21.4") |
| 456 | 459 | ||
| 457 | (defface compilation-info-face | 460 | (defface compilation-info-face |
| 458 | '((((type tty) (class color)) (:foreground "green" :weight bold)) | 461 | '((((class color) (min-colors 16) (background light)) |
| 459 | (((class color) (background light)) (:foreground "Green3" :weight bold)) | 462 | (:foreground "Green3" :weight bold)) |
| 460 | (((class color) (background dark)) (:foreground "Green" :weight bold)) | 463 | (((class color) (min-colors 16) (background dark)) |
| 464 | (:foreground "Green" :weight bold)) | ||
| 465 | (((class color)) (:foreground "green" :weight bold)) | ||
| 461 | (t (:weight bold))) | 466 | (t (:weight bold))) |
| 462 | "Face used to highlight compiler warnings." | 467 | "Face used to highlight compiler warnings." |
| 463 | :group 'font-lock-highlighting-faces | 468 | :group 'font-lock-highlighting-faces |
| @@ -494,7 +499,8 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 494 | 499 | ||
| 495 | 500 | ||
| 496 | ;; Used for compatibility with the old compile.el. | 501 | ;; Used for compatibility with the old compile.el. |
| 497 | (defvar compilation-parsing-end nil) | 502 | (defvaralias 'compilation-last-buffer 'next-error-last-buffer) |
| 503 | (defvar compilation-parsing-end (make-marker)) | ||
| 498 | (defvar compilation-parse-errors-function nil) | 504 | (defvar compilation-parse-errors-function nil) |
| 499 | (defvar compilation-error-list nil) | 505 | (defvar compilation-error-list nil) |
| 500 | (defvar compilation-old-error-list nil) | 506 | (defvar compilation-old-error-list nil) |
| @@ -518,6 +524,7 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 518 | '(nil)) ; nil only isn't a property-change | 524 | '(nil)) ; nil only isn't a property-change |
| 519 | (cons (match-string-no-properties idx) dir)) | 525 | (cons (match-string-no-properties idx) dir)) |
| 520 | mouse-face highlight | 526 | mouse-face highlight |
| 527 | keymap compilation-button-map | ||
| 521 | help-echo "mouse-2: visit current directory"))) | 528 | help-echo "mouse-2: visit current directory"))) |
| 522 | 529 | ||
| 523 | ;; Data type `reverse-ordered-alist' retriever. This function retrieves the | 530 | ;; Data type `reverse-ordered-alist' retriever. This function retrieves the |
| @@ -528,6 +535,7 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 528 | ;; may be nil. The other KEYs are ordered backwards so that growing line | 535 | ;; may be nil. The other KEYs are ordered backwards so that growing line |
| 529 | ;; numbers can be inserted in front and searching can abort after half the | 536 | ;; numbers can be inserted in front and searching can abort after half the |
| 530 | ;; list on average. | 537 | ;; list on average. |
| 538 | (eval-when-compile ;Don't keep it at runtime if not needed. | ||
| 531 | (defmacro compilation-assq (key alist) | 539 | (defmacro compilation-assq (key alist) |
| 532 | `(let* ((l1 ,alist) | 540 | `(let* ((l1 ,alist) |
| 533 | (l2 (cdr l1))) | 541 | (l2 (cdr l1))) |
| @@ -538,7 +546,7 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 538 | l2 (cdr l1))) | 546 | l2 (cdr l1))) |
| 539 | (if l2 (eq ,key (caar l2)))) | 547 | (if l2 (eq ,key (caar l2)))) |
| 540 | l2 | 548 | l2 |
| 541 | (setcdr l1 (cons (list ,key) l2)))))) | 549 | (setcdr l1 (cons (list ,key) l2))))))) |
| 542 | 550 | ||
| 543 | 551 | ||
| 544 | ;; This function is the central driver, called when font-locking to gather | 552 | ;; This function is the central driver, called when font-locking to gather |
| @@ -556,17 +564,13 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 556 | (setq dir (previous-single-property-change (point) 'directory) | 564 | (setq dir (previous-single-property-change (point) 'directory) |
| 557 | dir (if dir (or (get-text-property (1- dir) 'directory) | 565 | dir (if dir (or (get-text-property (1- dir) 'directory) |
| 558 | (get-text-property dir 'directory))))) | 566 | (get-text-property dir 'directory))))) |
| 559 | (setq file (cons file (car dir)) ; top of dir stack is current | 567 | (setq file (cons file (car dir))))) |
| 560 | file (or (gethash file compilation-locs) | ||
| 561 | (puthash file (list file fmt) compilation-locs))))) | ||
| 562 | ;; This message didn't mention one, get it from previous | 568 | ;; This message didn't mention one, get it from previous |
| 563 | (setq file (previous-single-property-change (point) 'message) | 569 | (setq file (previous-single-property-change (point) 'message) |
| 564 | file (or (if file | 570 | file (or (if file |
| 565 | (nth 2 (car (or (get-text-property (1- file) 'message) | 571 | (car (nth 2 (car (or (get-text-property (1- file) 'message) |
| 566 | (get-text-property file 'message))))) | 572 | (get-text-property file 'message)))))) |
| 567 | ;; no previous either -- let font-lock continue | 573 | '("*unknown*")))) |
| 568 | (gethash (setq file '("*unknown*")) compilation-locs) | ||
| 569 | (puthash file (list file fmt) compilation-locs)))) | ||
| 570 | ;; All of these fields are optional, get them only if we have an index, and | 574 | ;; All of these fields are optional, get them only if we have an index, and |
| 571 | ;; it matched some part of the message. | 575 | ;; it matched some part of the message. |
| 572 | (and line | 576 | (and line |
| @@ -579,75 +583,87 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 579 | (setq col (match-string-no-properties col)) | 583 | (setq col (match-string-no-properties col)) |
| 580 | (setq col (- (string-to-number col) compilation-first-column))) | 584 | (setq col (- (string-to-number col) compilation-first-column))) |
| 581 | (if (and end-col (setq end-col (match-string-no-properties end-col))) | 585 | (if (and end-col (setq end-col (match-string-no-properties end-col))) |
| 582 | (setq end-col (- (string-to-number end-col) compilation-first-column)) | 586 | (setq end-col (- (string-to-number end-col) compilation-first-column -1)) |
| 583 | (if end-line (setq end-col -1))) | 587 | (if end-line (setq end-col -1))) |
| 584 | (if (consp type) ; not a preset type, check what it is. | 588 | (if (consp type) ; not a static type, check what it is. |
| 585 | (setq type (or (and (car type) (match-end (car type)) 1) | 589 | (setq type (or (and (car type) (match-end (car type)) 1) |
| 586 | (and (cdr type) (match-end (cdr type)) 0) | 590 | (and (cdr type) (match-end (cdr type)) 0) |
| 587 | 2))) | 591 | 2))) |
| 588 | ;; Get any (first) already existing marker (if any has one, all have one). | 592 | (compilation-internal-error-properties file line end-line col end-col type fmt))) |
| 589 | ;; Do this first, as the next assq`s may create new nodes. | 593 | |
| 590 | (let ((marker (nth 3 (car (cdar (cddr file))))) | 594 | (defun compilation-internal-error-properties (file line end-line col end-col type fmt) |
| 591 | (loc (compilation-assq line (cdr file))) | 595 | "Get the meta-info that will be added as text-properties. |
| 592 | end-loc) | 596 | LINE, END-LINE, COL, END-COL are integers or nil. |
| 593 | (if end-line | 597 | TYPE can be 0, 1, or 2. |
| 594 | (setq end-loc (compilation-assq end-line (cdr file)) | 598 | FILE should be (ABSOLUTE-FILENAME) or (RELATIVE-FILENAME . DIRNAME) or nil." |
| 595 | end-loc (compilation-assq end-col end-loc)) | 599 | (unless file (setq file '("*unknown*"))) |
| 596 | (if end-col ; use same line element | 600 | (setq file (compilation-get-file-structure file fmt)) |
| 597 | (setq end-loc (compilation-assq end-col loc)))) | 601 | ;; Get first already existing marker (if any has one, all have one). |
| 598 | (setq loc (compilation-assq col loc)) | 602 | ;; Do this first, as the compilation-assq`s may create new nodes. |
| 599 | ;; If they are new, make the loc(s) reference the file they point to. | 603 | (let* ((marker-line (car (cddr file))) ; a line structure |
| 600 | (or (cdr loc) (setcdr loc (list line file))) | 604 | (marker (nth 3 (cadr marker-line))) ; its marker |
| 601 | (if end-loc | 605 | (compilation-error-screen-columns compilation-error-screen-columns) |
| 602 | (or (cdr end-loc) (setcdr end-loc (list (or end-line line) file)))) | 606 | end-marker loc end-loc) |
| 603 | ;; If we'd found a marker, ensure that the new locs also get markers | 607 | (if (not (and marker (marker-buffer marker))) |
| 604 | (when (and marker | 608 | (setq marker) ; no valid marker for this file |
| 605 | (not (or (cddr loc) (cddr end-loc))) ; maybe new node w/o marker | 609 | (setq loc (or line 1)) ; normalize no linenumber to line 1 |
| 606 | (marker-buffer marker)) ; other marker still valid | 610 | (catch 'marker ; find nearest loc, at least one exists |
| 607 | (or line (setq line 1)) ; normalize no linenumber to line 1 | 611 | (dolist (x (nthcdr 3 file)) ; loop over remaining lines |
| 608 | (catch 'marker ; find nearest loc, at least one exists | 612 | (if (> (car x) loc) ; still bigger |
| 609 | (dolist (x (cddr file)) | 613 | (setq marker-line x) |
| 610 | (if (> (or (car x) 1) line) | 614 | (if (> (- (or (car marker-line) 1) loc) |
| 611 | (setq marker x) | 615 | (- loc (car x))) ; current line is nearer |
| 612 | (if (eq (or (car x) 1) line) | 616 | (setq marker-line x)) |
| 613 | (if (cdr (cddr x)) ; at least one other column | 617 | (throw 'marker t)))) |
| 614 | (throw 'marker (setq marker x)) | 618 | (setq marker (nth 3 (cadr marker-line)) |
| 615 | (if marker (throw 'marker t))) | 619 | marker-line (or (car marker-line) 1)) |
| 616 | (throw 'marker (or marker (setq marker x))))))) | 620 | (with-current-buffer (marker-buffer marker) |
| 617 | (setq marker (if (eq (car (cddr marker)) col) | 621 | (save-restriction |
| 618 | (nthcdr 3 marker) | 622 | (widen) |
| 619 | (cddr marker)) | 623 | (goto-char (marker-position marker)) |
| 620 | file compilation-error-screen-columns) | 624 | (when (or end-col end-line) |
| 621 | (with-current-buffer (marker-buffer (cddr marker)) | 625 | (beginning-of-line (- (or end-line line) marker-line -1)) |
| 622 | (save-restriction | 626 | (if (< end-col 0) |
| 623 | (widen) | 627 | (end-of-line) |
| 624 | (goto-char (marker-position (cddr marker))) | 628 | (if compilation-error-screen-columns |
| 625 | (beginning-of-line (- line (car (cadr marker)) -1)) | 629 | (move-to-column end-col) |
| 626 | (if file ; original c.-error-screen-columns | 630 | (forward-char end-col))) |
| 627 | (move-to-column (car loc)) | 631 | (setq end-marker (list (point-marker)))) |
| 628 | (forward-char (car loc))) | 632 | (beginning-of-line (if end-line |
| 629 | (setcdr (cdr loc) (point-marker)) | 633 | (- end-line line -1) |
| 630 | (when end-loc | 634 | (- loc marker-line -1))) |
| 631 | (beginning-of-line (- end-line line -1)) | 635 | (if col |
| 632 | (if (< end-col 0) | 636 | (if compilation-error-screen-columns |
| 633 | (end-of-line) | 637 | (move-to-column col) |
| 634 | (if file ; original c.-error-screen-columns | 638 | (forward-char col)) |
| 635 | (move-to-column (car end-loc)) | 639 | (forward-to-indentation 0)) |
| 636 | (forward-char (car end-loc)))) | 640 | (setq marker (list (point-marker)))))) |
| 637 | (setcdr (cdr end-loc) (point-marker)))))) | 641 | |
| 638 | ;; Must start with face | 642 | (setq loc (compilation-assq line (cdr file))) |
| 639 | `(face ,compilation-message-face | 643 | (if end-line |
| 640 | message (,loc ,type ,end-loc) | 644 | (setq end-loc (compilation-assq end-line (cdr file)) |
| 641 | ,@(if compilation-debug | 645 | end-loc (compilation-assq end-col end-loc)) |
| 642 | `(debug (,(assoc (with-no-warnings matcher) font-lock-keywords) | 646 | (if end-col ; use same line element |
| 643 | ,@(match-data)))) | 647 | (setq end-loc (compilation-assq end-col loc)))) |
| 644 | help-echo ,(if col | 648 | (setq loc (compilation-assq col loc)) |
| 645 | "mouse-2: visit this file, line and column" | 649 | ;; If they are new, make the loc(s) reference the file they point to. |
| 646 | (if line | 650 | (or (cdr loc) (setcdr loc `(,line ,file ,@marker))) |
| 647 | "mouse-2: visit this file and line" | 651 | (if end-loc |
| 648 | "mouse-2: visit this file")) | 652 | (or (cdr end-loc) (setcdr end-loc `(,(or end-line line) ,file ,@end-marker)))) |
| 649 | keymap compilation-button-map | 653 | |
| 650 | mouse-face highlight)))) | 654 | ;; Must start with face |
| 655 | `(face ,compilation-message-face | ||
| 656 | message (,loc ,type ,end-loc) | ||
| 657 | ,@(if compilation-debug | ||
| 658 | `(debug (,(assoc (with-no-warnings matcher) font-lock-keywords) | ||
| 659 | ,@(match-data)))) | ||
| 660 | help-echo ,(if col | ||
| 661 | "mouse-2: visit this file, line and column" | ||
| 662 | (if line | ||
| 663 | "mouse-2: visit this file and line" | ||
| 664 | "mouse-2: visit this file")) | ||
| 665 | keymap compilation-button-map | ||
| 666 | mouse-face highlight))) | ||
| 651 | 667 | ||
| 652 | (defun compilation-mode-font-lock-keywords () | 668 | (defun compilation-mode-font-lock-keywords () |
| 653 | "Return expressions to highlight in Compilation mode." | 669 | "Return expressions to highlight in Compilation mode." |
| @@ -686,12 +702,15 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 686 | ;; error location. Let's do our best. | 702 | ;; error location. Let's do our best. |
| 687 | `(,(car item) | 703 | `(,(car item) |
| 688 | (0 (compilation-compat-error-properties | 704 | (0 (compilation-compat-error-properties |
| 689 | (funcall ',line (list* (match-string ,file) | 705 | (funcall ',line (cons (match-string ,file) |
| 690 | default-directory | 706 | (cons default-directory |
| 691 | ',(nthcdr 4 item)) | 707 | ',(nthcdr 4 item))) |
| 692 | ,(if col `(match-string ,col))))) | 708 | ,(if col `(match-string ,col))))) |
| 693 | (,file compilation-error-face t)) | 709 | (,file compilation-error-face t)) |
| 694 | 710 | ||
| 711 | (unless (or (null (nth 5 item)) (integerp (nth 5 item))) | ||
| 712 | (error "HYPERLINK should be an integer: %s" (nth 5 item))) | ||
| 713 | |||
| 695 | `(,(nth 0 item) | 714 | `(,(nth 0 item) |
| 696 | 715 | ||
| 697 | ,@(when (integerp file) | 716 | ,@(when (integerp file) |
| @@ -729,7 +748,7 @@ Faces `compilation-error-face', `compilation-warning-face', | |||
| 729 | Runs COMMAND, a shell command, in a separate process asynchronously | 748 | Runs COMMAND, a shell command, in a separate process asynchronously |
| 730 | with output going to the buffer `*compilation*'. | 749 | with output going to the buffer `*compilation*'. |
| 731 | 750 | ||
| 732 | If optional second arg COMINT is t the buffer will be in comint mode with | 751 | If optional second arg COMINT is t the buffer will be in Comint mode with |
| 733 | `compilation-shell-minor-mode'. | 752 | `compilation-shell-minor-mode'. |
| 734 | 753 | ||
| 735 | You can then use the command \\[next-error] to find the next error message | 754 | You can then use the command \\[next-error] to find the next error message |
| @@ -737,6 +756,8 @@ and move to the source code that caused it. | |||
| 737 | 756 | ||
| 738 | Interactively, prompts for the command if `compilation-read-command' is | 757 | Interactively, prompts for the command if `compilation-read-command' is |
| 739 | non-nil; otherwise uses `compile-command'. With prefix arg, always prompts. | 758 | non-nil; otherwise uses `compile-command'. With prefix arg, always prompts. |
| 759 | Additionally, with universal prefix arg, compilation buffer will be in | ||
| 760 | comint mode, i.e. interactive. | ||
| 740 | 761 | ||
| 741 | To run more than one compilation at once, start one and rename | 762 | To run more than one compilation at once, start one and rename |
| 742 | the \`*compilation*' buffer to some other name with | 763 | the \`*compilation*' buffer to some other name with |
| @@ -748,11 +769,13 @@ The name used for the buffer is actually whatever is returned by | |||
| 748 | the function in `compilation-buffer-name-function', so you can set that | 769 | the function in `compilation-buffer-name-function', so you can set that |
| 749 | to a function that generates a unique name." | 770 | to a function that generates a unique name." |
| 750 | (interactive | 771 | (interactive |
| 751 | (if (or compilation-read-command current-prefix-arg) | 772 | (list |
| 752 | (list (read-from-minibuffer "Compile command: " | 773 | (if (or compilation-read-command current-prefix-arg) |
| 753 | (eval compile-command) nil nil | 774 | (read-from-minibuffer "Compile command: " |
| 754 | '(compile-history . 1))) | 775 | (eval compile-command) nil nil |
| 755 | (list (eval compile-command)))) | 776 | '(compile-history . 1)) |
| 777 | (eval compile-command)) | ||
| 778 | (consp current-prefix-arg))) | ||
| 756 | (unless (equal command (eval compile-command)) | 779 | (unless (equal command (eval compile-command)) |
| 757 | (setq compile-command command)) | 780 | (setq compile-command command)) |
| 758 | (save-some-buffers (not compilation-ask-about-save) nil) | 781 | (save-some-buffers (not compilation-ask-about-save) nil) |
| @@ -762,8 +785,8 @@ to a function that generates a unique name." | |||
| 762 | ;; run compile with the default command line | 785 | ;; run compile with the default command line |
| 763 | (defun recompile () | 786 | (defun recompile () |
| 764 | "Re-compile the program including the current buffer. | 787 | "Re-compile the program including the current buffer. |
| 765 | If this is run in a compilation-mode buffer, re-use the arguments from the | 788 | If this is run in a Compilation mode buffer, re-use the arguments from the |
| 766 | original use. Otherwise, it recompiles using `compile-command'." | 789 | original use. Otherwise, recompile using `compile-command'." |
| 767 | (interactive) | 790 | (interactive) |
| 768 | (save-some-buffers (not compilation-ask-about-save) nil) | 791 | (save-some-buffers (not compilation-ask-about-save) nil) |
| 769 | (let ((default-directory (or compilation-directory default-directory))) | 792 | (let ((default-directory (or compilation-directory default-directory))) |
| @@ -773,9 +796,9 @@ original use. Otherwise, it recompiles using `compile-command'." | |||
| 773 | (defcustom compilation-scroll-output nil | 796 | (defcustom compilation-scroll-output nil |
| 774 | "*Non-nil to scroll the *compilation* buffer window as output appears. | 797 | "*Non-nil to scroll the *compilation* buffer window as output appears. |
| 775 | 798 | ||
| 776 | Setting it causes the compilation-mode commands to put point at the | 799 | Setting it causes the Compilation mode commands to put point at the |
| 777 | end of their output window so that the end of the output is always | 800 | end of their output window so that the end of the output is always |
| 778 | visible rather than the begining." | 801 | visible rather than the beginning." |
| 779 | :type 'boolean | 802 | :type 'boolean |
| 780 | :version "20.3" | 803 | :version "20.3" |
| 781 | :group 'compilation) | 804 | :group 'compilation) |
| @@ -822,11 +845,11 @@ Otherwise, construct a buffer name from MODE-NAME." | |||
| 822 | The rest of the arguments are optional; for them, nil means use the default. | 845 | The rest of the arguments are optional; for them, nil means use the default. |
| 823 | 846 | ||
| 824 | MODE is the major mode to set in the compilation buffer. Mode | 847 | MODE is the major mode to set in the compilation buffer. Mode |
| 825 | may also be `t' meaning `compilation-shell-minor-mode' under `comint-mode'. | 848 | may also be t meaning use `compilation-shell-minor-mode' under `comint-mode'. |
| 826 | NAME-FUNCTION is a function called to name the buffer. | 849 | NAME-FUNCTION is a function called to name the buffer. |
| 827 | 850 | ||
| 828 | If HIGHLIGHT-REGEXP is non-nil, `next-error' will temporarily highlight | 851 | If HIGHLIGHT-REGEXP is non-nil, `next-error' will temporarily highlight |
| 829 | matching section of the visited source line; the default is to use the | 852 | the matching section of the visited source line; the default is to use the |
| 830 | global value of `compilation-highlight-regexp'. | 853 | global value of `compilation-highlight-regexp'. |
| 831 | 854 | ||
| 832 | Returns the compilation buffer created." | 855 | Returns the compilation buffer created." |
| @@ -838,8 +861,8 @@ Returns the compilation buffer created." | |||
| 838 | (process-environment | 861 | (process-environment |
| 839 | (append | 862 | (append |
| 840 | compilation-environment | 863 | compilation-environment |
| 841 | (if (and (boundp 'system-uses-terminfo) | 864 | (if (if (boundp 'system-uses-terminfo) ; `if' for compiler warning |
| 842 | system-uses-terminfo) | 865 | system-uses-terminfo) |
| 843 | (list "TERM=dumb" "TERMCAP=" | 866 | (list "TERM=dumb" "TERMCAP=" |
| 844 | (format "COLUMNS=%d" (window-width))) | 867 | (format "COLUMNS=%d" (window-width))) |
| 845 | (list "TERM=emacs" | 868 | (list "TERM=emacs" |
| @@ -903,7 +926,9 @@ Returns the compilation buffer created." | |||
| 903 | 'compilation-revert-buffer) | 926 | 'compilation-revert-buffer) |
| 904 | (set-window-start outwin (point-min)) | 927 | (set-window-start outwin (point-min)) |
| 905 | (or (eq outwin (selected-window)) | 928 | (or (eq outwin (selected-window)) |
| 906 | (set-window-point outwin (point))) | 929 | (set-window-point outwin (if compilation-scroll-output |
| 930 | (point) | ||
| 931 | (point-min)))) | ||
| 907 | ;; The setup function is called before compilation-set-window-height | 932 | ;; The setup function is called before compilation-set-window-height |
| 908 | ;; so it can set the compilation-window-height buffer locally. | 933 | ;; so it can set the compilation-window-height buffer locally. |
| 909 | (if compilation-process-setup-function | 934 | (if compilation-process-setup-function |
| @@ -930,6 +955,7 @@ Returns the compilation buffer created." | |||
| 930 | ;; Fake modeline display as if `start-process' were run. | 955 | ;; Fake modeline display as if `start-process' were run. |
| 931 | (setq mode-line-process ":run") | 956 | (setq mode-line-process ":run") |
| 932 | (force-mode-line-update) | 957 | (force-mode-line-update) |
| 958 | (sit-for 0) ; Force redisplay | ||
| 933 | (let ((status (call-process shell-file-name nil outbuf nil "-c" | 959 | (let ((status (call-process shell-file-name nil outbuf nil "-c" |
| 934 | command))) | 960 | command))) |
| 935 | (cond ((numberp status) | 961 | (cond ((numberp status) |
| @@ -944,13 +970,17 @@ exited abnormally with code %d\n" | |||
| 944 | (concat status "\n"))) | 970 | (concat status "\n"))) |
| 945 | (t | 971 | (t |
| 946 | (compilation-handle-exit 'bizarre status status)))) | 972 | (compilation-handle-exit 'bizarre status status)))) |
| 973 | ;; Without async subprocesses, the buffer is not yet | ||
| 974 | ;; fontified, so fontify it now. | ||
| 975 | (let ((font-lock-verbose nil)) ; shut up font-lock messages | ||
| 976 | (font-lock-fontify-buffer)) | ||
| 947 | (message "Executing `%s'...done" command))) | 977 | (message "Executing `%s'...done" command))) |
| 948 | (if (buffer-local-value 'compilation-scroll-output outbuf) | 978 | (if (buffer-local-value 'compilation-scroll-output outbuf) |
| 949 | (save-selected-window | 979 | (save-selected-window |
| 950 | (select-window outwin) | 980 | (select-window outwin) |
| 951 | (goto-char (point-max)))) | 981 | (goto-char (point-max)))) |
| 952 | ;; Make it so the next C-x ` will use this buffer. | 982 | ;; Make it so the next C-x ` will use this buffer. |
| 953 | (setq compilation-last-buffer outbuf))) | 983 | (setq next-error-last-buffer outbuf))) |
| 954 | 984 | ||
| 955 | (defun compilation-set-window-height (window) | 985 | (defun compilation-set-window-height (window) |
| 956 | "Set the height of WINDOW according to `compilation-window-height'." | 986 | "Set the height of WINDOW according to `compilation-window-height'." |
| @@ -960,9 +990,8 @@ exited abnormally with code %d\n" | |||
| 960 | ;; If window is alone in its frame, aside from a minibuffer, | 990 | ;; If window is alone in its frame, aside from a minibuffer, |
| 961 | ;; don't change its height. | 991 | ;; don't change its height. |
| 962 | (not (eq window (frame-root-window (window-frame window)))) | 992 | (not (eq window (frame-root-window (window-frame window)))) |
| 963 | ;; This save-current-buffer prevents us from changing the current | 993 | ;; Stef said that doing the saves in this order is safer: |
| 964 | ;; buffer, which might not be the same as the selected window's buffer. | 994 | (save-excursion |
| 965 | (save-current-buffer | ||
| 966 | (save-selected-window | 995 | (save-selected-window |
| 967 | (select-window window) | 996 | (select-window window) |
| 968 | (enlarge-window (- height (window-height)))))))) | 997 | (enlarge-window (- height (window-height)))))))) |
| @@ -1132,20 +1161,30 @@ variable exists." | |||
| 1132 | "Marker to the location from where the next error will be found. | 1161 | "Marker to the location from where the next error will be found. |
| 1133 | The global commands next/previous/first-error/goto-error use this.") | 1162 | The global commands next/previous/first-error/goto-error use this.") |
| 1134 | 1163 | ||
| 1164 | (defvar compilation-messages-start nil | ||
| 1165 | "Buffer position of the beginning of the compilation messages. | ||
| 1166 | If nil, use the beginning of buffer.") | ||
| 1167 | |||
| 1135 | ;; A function name can't be a hook, must be something with a value. | 1168 | ;; A function name can't be a hook, must be something with a value. |
| 1136 | (defconst compilation-turn-on-font-lock 'turn-on-font-lock) | 1169 | (defconst compilation-turn-on-font-lock 'turn-on-font-lock) |
| 1137 | 1170 | ||
| 1138 | (defun compilation-setup (&optional minor) | 1171 | (defun compilation-setup (&optional minor) |
| 1139 | "Prepare the buffer for the compilation parsing commands to work." | 1172 | "Prepare the buffer for the compilation parsing commands to work. |
| 1173 | Optional argument MINOR indicates this is called from | ||
| 1174 | `compilation-minor-mode'." | ||
| 1140 | (make-local-variable 'compilation-current-error) | 1175 | (make-local-variable 'compilation-current-error) |
| 1176 | (make-local-variable 'compilation-messages-start) | ||
| 1141 | (make-local-variable 'compilation-error-screen-columns) | 1177 | (make-local-variable 'compilation-error-screen-columns) |
| 1142 | (make-local-variable 'overlay-arrow-position) | 1178 | (make-local-variable 'overlay-arrow-position) |
| 1143 | (setq compilation-last-buffer (current-buffer)) | 1179 | ;; Note that compilation-next-error-function is for interfacing |
| 1180 | ;; with the next-error function in simple.el, and it's only | ||
| 1181 | ;; coincidentally named similarly to compilation-next-error. | ||
| 1182 | (setq next-error-function 'compilation-next-error-function) | ||
| 1144 | (set (make-local-variable 'font-lock-extra-managed-props) | 1183 | (set (make-local-variable 'font-lock-extra-managed-props) |
| 1145 | '(directory message help-echo mouse-face debug)) | 1184 | '(directory message help-echo mouse-face debug)) |
| 1146 | (set (make-local-variable 'compilation-locs) | 1185 | (set (make-local-variable 'compilation-locs) |
| 1147 | (make-hash-table :test 'equal :weakness 'value)) | 1186 | (make-hash-table :test 'equal :weakness 'value)) |
| 1148 | ;; lazy-lock would never find the message unless it's scrolled to | 1187 | ;; lazy-lock would never find the message unless it's scrolled to. |
| 1149 | ;; jit-lock might fontify some things too late. | 1188 | ;; jit-lock might fontify some things too late. |
| 1150 | (set (make-local-variable 'font-lock-support-mode) nil) | 1189 | (set (make-local-variable 'font-lock-support-mode) nil) |
| 1151 | (set (make-local-variable 'font-lock-maximum-size) nil) | 1190 | (set (make-local-variable 'font-lock-maximum-size) nil) |
| @@ -1193,7 +1232,7 @@ Turning the mode on runs the normal hook `compilation-minor-mode-hook'." | |||
| 1193 | (font-lock-fontify-buffer))) | 1232 | (font-lock-fontify-buffer))) |
| 1194 | 1233 | ||
| 1195 | (defun compilation-handle-exit (process-status exit-status msg) | 1234 | (defun compilation-handle-exit (process-status exit-status msg) |
| 1196 | "Write msg in the current buffer and hack its mode-line-process." | 1235 | "Write MSG in the current buffer and hack its mode-line-process." |
| 1197 | (let ((buffer-read-only nil) | 1236 | (let ((buffer-read-only nil) |
| 1198 | (status (if compilation-exit-message-function | 1237 | (status (if compilation-exit-message-function |
| 1199 | (funcall compilation-exit-message-function | 1238 | (funcall compilation-exit-message-function |
| @@ -1257,8 +1296,16 @@ Just inserts the text, but uses `insert-before-markers'." | |||
| 1257 | (insert-before-markers string) | 1296 | (insert-before-markers string) |
| 1258 | (run-hooks 'compilation-filter-hook)))))) | 1297 | (run-hooks 'compilation-filter-hook)))))) |
| 1259 | 1298 | ||
| 1299 | ;;; test if a buffer is a compilation buffer, assuming we're in the buffer | ||
| 1300 | (defsubst compilation-buffer-internal-p () | ||
| 1301 | "Test if inside a compilation buffer." | ||
| 1302 | (local-variable-p 'compilation-locs)) | ||
| 1303 | |||
| 1304 | ;;; test if a buffer is a compilation buffer, using compilation-buffer-internal-p | ||
| 1260 | (defsubst compilation-buffer-p (buffer) | 1305 | (defsubst compilation-buffer-p (buffer) |
| 1261 | (local-variable-p 'compilation-locs buffer)) | 1306 | "Test if BUFFER is a compilation buffer." |
| 1307 | (with-current-buffer buffer | ||
| 1308 | (compilation-buffer-internal-p))) | ||
| 1262 | 1309 | ||
| 1263 | (defmacro compilation-loop (< property-change 1+ error) | 1310 | (defmacro compilation-loop (< property-change 1+ error) |
| 1264 | `(while (,< n 0) | 1311 | `(while (,< n 0) |
| @@ -1289,7 +1336,6 @@ Does NOT find the source line like \\[next-error]." | |||
| 1289 | (or (compilation-buffer-p (current-buffer)) | 1336 | (or (compilation-buffer-p (current-buffer)) |
| 1290 | (error "Not in a compilation buffer")) | 1337 | (error "Not in a compilation buffer")) |
| 1291 | (or pt (setq pt (point))) | 1338 | (or pt (setq pt (point))) |
| 1292 | (setq compilation-last-buffer (current-buffer)) | ||
| 1293 | (let* ((msg (get-text-property pt 'message)) | 1339 | (let* ((msg (get-text-property pt 'message)) |
| 1294 | (loc (car msg)) | 1340 | (loc (car msg)) |
| 1295 | last) | 1341 | last) |
| @@ -1327,25 +1373,6 @@ Does NOT find the source line like \\[previous-error]." | |||
| 1327 | (interactive "p") | 1373 | (interactive "p") |
| 1328 | (compilation-next-error (- n))) | 1374 | (compilation-next-error (- n))) |
| 1329 | 1375 | ||
| 1330 | (defun next-error-no-select (n) | ||
| 1331 | "Move point to the next error in the compilation buffer and highlight match. | ||
| 1332 | Prefix arg N says how many error messages to move forwards (or | ||
| 1333 | backwards, if negative). | ||
| 1334 | Finds and highlights the source line like \\[next-error], but does not | ||
| 1335 | select the source buffer." | ||
| 1336 | (interactive "p") | ||
| 1337 | (next-error n) | ||
| 1338 | (pop-to-buffer compilation-last-buffer)) | ||
| 1339 | |||
| 1340 | (defun previous-error-no-select (n) | ||
| 1341 | "Move point to the previous error in the compilation buffer and highlight match. | ||
| 1342 | Prefix arg N says how many error messages to move backwards (or | ||
| 1343 | forwards, if negative). | ||
| 1344 | Finds and highlights the source line like \\[previous-error], but does not | ||
| 1345 | select the source buffer." | ||
| 1346 | (interactive "p") | ||
| 1347 | (next-error-no-select (- n))) | ||
| 1348 | |||
| 1349 | (defun compilation-next-file (n) | 1376 | (defun compilation-next-file (n) |
| 1350 | "Move point to the next error for a different file than the current one. | 1377 | "Move point to the next error for a different file than the current one. |
| 1351 | Prefix arg N says how many files to move forwards (or backwards, if negative)." | 1378 | Prefix arg N says how many files to move forwards (or backwards, if negative)." |
| @@ -1383,73 +1410,35 @@ Use this command in a compilation log buffer. Sets the mark at point there." | |||
| 1383 | 1410 | ||
| 1384 | ;; Return a compilation buffer. | 1411 | ;; Return a compilation buffer. |
| 1385 | ;; If the current buffer is a compilation buffer, return it. | 1412 | ;; If the current buffer is a compilation buffer, return it. |
| 1386 | ;; If compilation-last-buffer is set to a live buffer, use that. | ||
| 1387 | ;; Otherwise, look for a compilation buffer and signal an error | 1413 | ;; Otherwise, look for a compilation buffer and signal an error |
| 1388 | ;; if there are none. | 1414 | ;; if there are none. |
| 1389 | (defun compilation-find-buffer (&optional other-buffer) | 1415 | (defun compilation-find-buffer (&optional other-buffer) |
| 1390 | (if (and (not other-buffer) | 1416 | (next-error-find-buffer other-buffer 'compilation-buffer-internal-p)) |
| 1391 | (compilation-buffer-p (current-buffer))) | ||
| 1392 | ;; The current buffer is a compilation buffer. | ||
| 1393 | (current-buffer) | ||
| 1394 | (if (and compilation-last-buffer (buffer-name compilation-last-buffer) | ||
| 1395 | (compilation-buffer-p compilation-last-buffer) | ||
| 1396 | (or (not other-buffer) (not (eq compilation-last-buffer | ||
| 1397 | (current-buffer))))) | ||
| 1398 | compilation-last-buffer | ||
| 1399 | (let ((buffers (buffer-list))) | ||
| 1400 | (while (and buffers (or (not (compilation-buffer-p (car buffers))) | ||
| 1401 | (and other-buffer | ||
| 1402 | (eq (car buffers) (current-buffer))))) | ||
| 1403 | (setq buffers (cdr buffers))) | ||
| 1404 | (if buffers | ||
| 1405 | (car buffers) | ||
| 1406 | (or (and other-buffer | ||
| 1407 | (compilation-buffer-p (current-buffer)) | ||
| 1408 | ;; The current buffer is a compilation buffer. | ||
| 1409 | (progn | ||
| 1410 | (if other-buffer | ||
| 1411 | (message "This is the only compilation buffer.")) | ||
| 1412 | (current-buffer))) | ||
| 1413 | (error "No compilation started!"))))))) | ||
| 1414 | 1417 | ||
| 1415 | ;;;###autoload | 1418 | ;;;###autoload |
| 1416 | (defun next-error (&optional n) | 1419 | (defun compilation-next-error-function (n &optional reset) |
| 1417 | "Visit next compilation error message and corresponding source code. | ||
| 1418 | Prefix arg N says how many error messages to move forwards (or | ||
| 1419 | backwards, if negative). | ||
| 1420 | |||
| 1421 | \\[next-error] normally uses the most recently started compilation or | ||
| 1422 | grep buffer. However, it can operate on any buffer with output from | ||
| 1423 | the \\[compile] and \\[grep] commands, or, more generally, on any | ||
| 1424 | buffer in Compilation mode or with Compilation Minor mode enabled. To | ||
| 1425 | specify use of a particular buffer for error messages, type | ||
| 1426 | \\[next-error] in that buffer. | ||
| 1427 | |||
| 1428 | Once \\[next-error] has chosen the buffer for error messages, | ||
| 1429 | it stays with that buffer until you use it in some other buffer which | ||
| 1430 | uses Compilation mode or Compilation Minor mode. | ||
| 1431 | |||
| 1432 | See variable `compilation-error-regexp-alist' for customization ideas." | ||
| 1433 | (interactive "p") | 1420 | (interactive "p") |
| 1434 | (set-buffer (setq compilation-last-buffer (compilation-find-buffer))) | 1421 | (set-buffer (compilation-find-buffer)) |
| 1422 | (when reset | ||
| 1423 | (setq compilation-current-error nil)) | ||
| 1435 | (let* ((columns compilation-error-screen-columns) ; buffer's local value | 1424 | (let* ((columns compilation-error-screen-columns) ; buffer's local value |
| 1436 | (last 1) | 1425 | (last 1) |
| 1437 | (loc (compilation-next-error (or n 1) nil | 1426 | (loc (compilation-next-error (or n 1) nil |
| 1438 | (or compilation-current-error (point-min)))) | 1427 | (or compilation-current-error |
| 1428 | compilation-messages-start | ||
| 1429 | (point-min)))) | ||
| 1439 | (end-loc (nth 2 loc)) | 1430 | (end-loc (nth 2 loc)) |
| 1440 | (marker (point-marker))) | 1431 | (marker (point-marker))) |
| 1441 | (setq compilation-current-error (point-marker) | 1432 | (setq compilation-current-error (point-marker) |
| 1442 | overlay-arrow-position | 1433 | overlay-arrow-position |
| 1443 | (if (bolp) | 1434 | (if (bolp) |
| 1444 | compilation-current-error | 1435 | compilation-current-error |
| 1445 | (save-excursion | 1436 | (copy-marker (line-beginning-position))) |
| 1446 | (beginning-of-line) | ||
| 1447 | (point-marker))) | ||
| 1448 | loc (car loc)) | 1437 | loc (car loc)) |
| 1449 | ;; If loc contains no marker, no error in that file has been visited. If | 1438 | ;; If loc contains no marker, no error in that file has been visited. If |
| 1450 | ;; the marker is invalid the buffer has been killed. So, recalculate all | 1439 | ;; the marker is invalid the buffer has been killed. So, recalculate all |
| 1451 | ;; markers for that file. | 1440 | ;; markers for that file. |
| 1452 | (unless (and (nthcdr 3 loc) (marker-buffer (nth 3 loc))) | 1441 | (unless (and (nth 3 loc) (marker-buffer (nth 3 loc))) |
| 1453 | (with-current-buffer (compilation-find-file marker (caar (nth 2 loc)) | 1442 | (with-current-buffer (compilation-find-file marker (caar (nth 2 loc)) |
| 1454 | (or (cdar (nth 2 loc)) | 1443 | (or (cdar (nth 2 loc)) |
| 1455 | default-directory)) | 1444 | default-directory)) |
| @@ -1472,50 +1461,66 @@ See variable `compilation-error-regexp-alist' for customization ideas." | |||
| 1472 | (forward-char (car col)))) | 1461 | (forward-char (car col)))) |
| 1473 | (beginning-of-line) | 1462 | (beginning-of-line) |
| 1474 | (skip-chars-forward " \t")) | 1463 | (skip-chars-forward " \t")) |
| 1475 | (if (nthcdr 3 col) | 1464 | (if (nth 3 col) |
| 1476 | (set-marker (nth 3 col) (point)) | 1465 | (set-marker (nth 3 col) (point)) |
| 1477 | (setcdr (nthcdr 2 col) `(,(point-marker))))))))) | 1466 | (setcdr (nthcdr 2 col) `(,(point-marker))))))))) |
| 1478 | (compilation-goto-locus marker (nth 3 loc) (nth 3 end-loc)) | 1467 | (compilation-goto-locus marker (nth 3 loc) (nth 3 end-loc)) |
| 1479 | (setcdr (nthcdr 3 loc) t))) ; Set this one as visited. | 1468 | (setcdr (nthcdr 3 loc) t))) ; Set this one as visited. |
| 1480 | 1469 | ||
| 1481 | ;;;###autoload (define-key ctl-x-map "`" 'next-error) | 1470 | (defvar compilation-gcpro nil |
| 1482 | 1471 | "Internal variable used to keep some values from being GC'd.") | |
| 1483 | (defun previous-error (n) | 1472 | (make-variable-buffer-local 'compilation-gcpro) |
| 1484 | "Visit previous compilation error message and corresponding source code. | 1473 | |
| 1485 | Prefix arg N says how many error messages to move backwards (or | 1474 | (defun compilation-fake-loc (marker file &optional line col) |
| 1486 | forwards, if negative). | 1475 | "Preassociate MARKER with FILE. |
| 1487 | 1476 | FILE should be ABSOLUTE-FILENAME or (RELATIVE-FILENAME . DIRNAME). | |
| 1488 | This operates on the output from the \\[compile] and \\[grep] commands." | 1477 | This is useful when you compile temporary files, but want |
| 1489 | (interactive "p") | 1478 | automatic translation of the messages to the real buffer from |
| 1490 | (next-error (- n))) | 1479 | which the temporary file came. This only works if done before a |
| 1491 | 1480 | message about FILE appears! | |
| 1492 | (defun first-error (n) | 1481 | |
| 1493 | "Restart at the first error. | 1482 | Optional args LINE and COL default to 1 and beginning of |
| 1494 | Visit corresponding source code. | 1483 | indentation respectively. The marker is expected to reflect |
| 1495 | With prefix arg N, visit the source code of the Nth error. | 1484 | this. In the simplest case the marker points to the first line |
| 1496 | This operates on the output from the \\[compile] command." | 1485 | of the region that was saved to the temp file. |
| 1497 | (interactive "p") | 1486 | |
| 1498 | (set-buffer (setq compilation-last-buffer (compilation-find-buffer))) | 1487 | If you concatenate several regions into the temp file (e.g. a |
| 1499 | (setq compilation-current-error nil) | 1488 | header with variable assignments and a code region), you must |
| 1500 | (next-error n)) | 1489 | call this several times, once each for the last line of one |
| 1501 | 1490 | region and the first line of the next region." | |
| 1502 | (defcustom compilation-context-lines next-screen-context-lines | 1491 | (or (consp file) (setq file (list file))) |
| 1503 | "*Display this many lines of leading context before message." | 1492 | (setq file (compilation-get-file-structure file)) |
| 1504 | :type 'integer | 1493 | ;; Between the current call to compilation-fake-loc and the first occurrence |
| 1494 | ;; of an error message referring to `file', the data is only kept is the | ||
| 1495 | ;; weak hash-table compilation-locs, so we need to prevent this entry | ||
| 1496 | ;; in compilation-locs from being GC'd away. --Stef | ||
| 1497 | (push file compilation-gcpro) | ||
| 1498 | (let ((loc (compilation-assq (or line 1) (cdr file)))) | ||
| 1499 | (setq loc (compilation-assq col loc)) | ||
| 1500 | (if (cdr loc) | ||
| 1501 | (setcdr (cddr loc) (list marker)) | ||
| 1502 | (setcdr loc (list line file marker))) | ||
| 1503 | loc)) | ||
| 1504 | |||
| 1505 | (defcustom compilation-context-lines 0 | ||
| 1506 | "*Display this many lines of leading context before message. | ||
| 1507 | If nil, don't scroll the compilation output window." | ||
| 1508 | :type '(choice integer (const :tag "No window scrolling" nil)) | ||
| 1505 | :group 'compilation | 1509 | :group 'compilation |
| 1506 | :version "21.4") | 1510 | :version "21.4") |
| 1507 | 1511 | ||
| 1508 | (defsubst compilation-set-window (w mk) | 1512 | (defsubst compilation-set-window (w mk) |
| 1509 | ;; Align the compilation output window W with marker MK near top. | 1513 | "Align the compilation output window W with marker MK near top." |
| 1510 | (set-window-start w (save-excursion | 1514 | (if (integerp compilation-context-lines) |
| 1511 | (goto-char mk) | 1515 | (set-window-start w (save-excursion |
| 1512 | (beginning-of-line (- 1 compilation-context-lines)) | 1516 | (goto-char mk) |
| 1513 | (point))) | 1517 | (beginning-of-line (- 1 compilation-context-lines)) |
| 1518 | (point)))) | ||
| 1514 | (set-window-point w mk)) | 1519 | (set-window-point w mk)) |
| 1515 | 1520 | ||
| 1516 | (defun compilation-goto-locus (msg mk end-mk) | 1521 | (defun compilation-goto-locus (msg mk end-mk) |
| 1517 | "Jump to an error MESSAGE and SOURCE. | 1522 | "Jump to an error corresponding to MSG at MK. |
| 1518 | All arguments are markers. If SOURCE-END is non nil, mark is set there." | 1523 | All arguments are markers. If END-MK is non nil, mark is set there." |
| 1519 | (if (eq (window-buffer (selected-window)) | 1524 | (if (eq (window-buffer (selected-window)) |
| 1520 | (marker-buffer msg)) | 1525 | (marker-buffer msg)) |
| 1521 | ;; If the compilation buffer window is selected, | 1526 | ;; If the compilation buffer window is selected, |
| @@ -1622,67 +1627,58 @@ Pop up the buffer containing MARKER and scroll to MARKER if we ask the user." | |||
| 1622 | (overlays-in (point-min) (point-max))) | 1627 | (overlays-in (point-min) (point-max))) |
| 1623 | buffer))) | 1628 | buffer))) |
| 1624 | 1629 | ||
| 1625 | (defun compilation-normalize-filename (filename) | 1630 | (defun compilation-get-file-structure (file &optional fmt) |
| 1626 | "Convert a filename string found in an error message to make it usable." | 1631 | "Retrieve FILE's file-structure or create a new one. |
| 1627 | 1632 | FILE should be (ABSOLUTE-FILENAME) or (RELATIVE-FILENAME . DIRNAME)." | |
| 1628 | ;; Check for a comint-file-name-prefix and prepend it if | 1633 | |
| 1629 | ;; appropriate. (This is very useful for | 1634 | (or (gethash file compilation-locs) |
| 1630 | ;; compilation-minor-mode in an rlogin-mode buffer.) | 1635 | ;; File was not previously encountered, at least not in the form passed. |
| 1631 | (and (boundp 'comint-file-name-prefix) | 1636 | ;; Let's normalize it and look again. |
| 1632 | ;; If file name is relative, default-directory will | 1637 | (let ((filename (car file)) |
| 1633 | ;; already contain the comint-file-name-prefix (done | 1638 | (default-directory (if (cdr file) |
| 1634 | ;; by compile-abbreviate-directory). | 1639 | (file-truename (cdr file)) |
| 1635 | (file-name-absolute-p filename) | 1640 | default-directory))) |
| 1636 | (setq filename | 1641 | |
| 1637 | (concat (with-no-warnings 'comint-file-name-prefix) filename))) | 1642 | ;; Check for a comint-file-name-prefix and prepend it if appropriate. |
| 1638 | 1643 | ;; (This is very useful for compilation-minor-mode in an rlogin-mode | |
| 1639 | ;; If compilation-parse-errors-filename-function is | 1644 | ;; buffer.) |
| 1640 | ;; defined, use it to process the filename. | 1645 | (if (boundp 'comint-file-name-prefix) |
| 1641 | (when compilation-parse-errors-filename-function | 1646 | (if (file-name-absolute-p filename) |
| 1642 | (setq filename | 1647 | (setq filename |
| 1643 | (funcall compilation-parse-errors-filename-function | 1648 | (concat (with-no-warnings comint-file-name-prefix) filename)) |
| 1644 | filename))) | 1649 | (setq default-directory |
| 1645 | 1650 | (file-truename | |
| 1646 | ;; Some compilers (e.g. Sun's java compiler, reportedly) | 1651 | (concat (with-no-warnings comint-file-name-prefix) default-directory))))) |
| 1647 | ;; produce bogus file names like "./bar//foo.c" for file | 1652 | |
| 1648 | ;; "bar/foo.c"; expand-file-name will collapse these into | 1653 | ;; If compilation-parse-errors-filename-function is |
| 1649 | ;; "/foo.c" and fail to find the appropriate file. So we | 1654 | ;; defined, use it to process the filename. |
| 1650 | ;; look for doubled slashes in the file name and fix them | 1655 | (when compilation-parse-errors-filename-function |
| 1651 | ;; up in the buffer. | 1656 | (setq filename |
| 1652 | (setq filename (command-line-normalize-file-name filename))) | 1657 | (funcall compilation-parse-errors-filename-function |
| 1653 | 1658 | filename))) | |
| 1654 | 1659 | ||
| 1655 | ;; If directory DIR is a subdir of ORIG or of ORIG's parent, | 1660 | ;; Some compilers (e.g. Sun's java compiler, reportedly) produce bogus |
| 1656 | ;; return a relative name for it starting from ORIG or its parent. | 1661 | ;; file names like "./bar//foo.c" for file "bar/foo.c"; |
| 1657 | ;; ORIG-EXPANDED is an expanded version of ORIG. | 1662 | ;; expand-file-name will collapse these into "/foo.c" and fail to find |
| 1658 | ;; PARENT-EXPANDED is an expanded version of ORIG's parent. | 1663 | ;; the appropriate file. So we look for doubled slashes in the file |
| 1659 | ;; Those two args could be computed here, but we run faster by | 1664 | ;; name and fix them. |
| 1660 | ;; having the caller compute them just once. | 1665 | (setq filename (command-line-normalize-file-name filename)) |
| 1661 | (defun compile-abbreviate-directory (dir orig orig-expanded parent-expanded) | 1666 | |
| 1662 | ;; Apply canonical abbreviations to DIR first thing. | 1667 | ;; Now eliminate any "..", because find-file would get them wrong. |
| 1663 | ;; Those abbreviations are already done in the other arguments passed. | 1668 | ;; Make relative and absolute filenames, with or without links, the |
| 1664 | (setq dir (abbreviate-file-name dir)) | 1669 | ;; same. |
| 1665 | 1670 | (setq filename | |
| 1666 | ;; Check for a comint-file-name-prefix and prepend it if appropriate. | 1671 | (list (abbreviate-file-name |
| 1667 | ;; (This is very useful for compilation-minor-mode in an rlogin-mode | 1672 | (file-truename (if (cdr file) |
| 1668 | ;; buffer.) | 1673 | (expand-file-name filename) |
| 1669 | (if (boundp 'comint-file-name-prefix) | 1674 | filename))))) |
| 1670 | (setq dir (concat comint-file-name-prefix dir))) | 1675 | |
| 1671 | 1676 | ;; Store it for the possibly unnormalized name | |
| 1672 | (if (and (> (length dir) (length orig-expanded)) | 1677 | (puthash file |
| 1673 | (string= orig-expanded | 1678 | ;; Retrieve or create file-structure for normalized name |
| 1674 | (substring dir 0 (length orig-expanded)))) | 1679 | (or (gethash filename compilation-locs) |
| 1675 | (setq dir | 1680 | (puthash filename (list filename fmt) compilation-locs)) |
| 1676 | (concat orig | 1681 | compilation-locs)))) |
| 1677 | (substring dir (length orig-expanded))))) | ||
| 1678 | (if (and (> (length dir) (length parent-expanded)) | ||
| 1679 | (string= parent-expanded | ||
| 1680 | (substring dir 0 (length parent-expanded)))) | ||
| 1681 | (setq dir | ||
| 1682 | (concat (file-name-directory | ||
| 1683 | (directory-file-name orig)) | ||
| 1684 | (substring dir (length parent-expanded))))) | ||
| 1685 | dir) | ||
| 1686 | 1682 | ||
| 1687 | (add-to-list 'debug-ignored-errors "^No more [-a-z ]+s yet$") | 1683 | (add-to-list 'debug-ignored-errors "^No more [-a-z ]+s yet$") |
| 1688 | 1684 | ||
| @@ -1691,17 +1687,26 @@ Pop up the buffer containing MARKER and scroll to MARKER if we ask the user." | |||
| 1691 | (defun compile-buffer-substring (n) (if n (match-string n))) | 1687 | (defun compile-buffer-substring (n) (if n (match-string n))) |
| 1692 | 1688 | ||
| 1693 | (defun compilation-compat-error-properties (err) | 1689 | (defun compilation-compat-error-properties (err) |
| 1694 | ;; Map old-style ERROR to new-style MESSAGE. | 1690 | "Map old-style error ERR to new-style message." |
| 1695 | (let* ((dst (cdr err)) | 1691 | ;; Old-style structure is (MARKER (FILE DIR) LINE COL) or |
| 1696 | (loc (cond ((markerp dst) (list nil nil nil dst)) | 1692 | ;; (MARKER . MARKER). |
| 1697 | ((consp dst) | 1693 | (let ((dst (cdr err))) |
| 1698 | (list (nth 2 dst) (nth 1 dst) | 1694 | (if (markerp dst) |
| 1699 | (cons (cdar dst) (caar dst))))))) | 1695 | ;; Must start with a face, for font-lock. |
| 1700 | ;; Must start with a face, for font-lock. | 1696 | `(face nil |
| 1701 | `(face nil | 1697 | message ,(list (list nil nil nil dst) 2) |
| 1702 | message ,(list loc 2) | 1698 | help-echo "mouse-2: visit the source location" |
| 1703 | help-echo "mouse-2: visit the source location" | 1699 | keymap compilation-button-map |
| 1704 | mouse-face highlight))) | 1700 | mouse-face highlight) |
| 1701 | ;; Too difficult to do it by hand: dispatch to the normal code. | ||
| 1702 | (let* ((file (pop dst)) | ||
| 1703 | (line (pop dst)) | ||
| 1704 | (col (pop dst)) | ||
| 1705 | (filename (pop file)) | ||
| 1706 | (dirname (pop file)) | ||
| 1707 | (fmt (pop file))) | ||
| 1708 | (compilation-internal-error-properties | ||
| 1709 | (cons filename dirname) line nil col nil 2 fmt))))) | ||
| 1705 | 1710 | ||
| 1706 | (defun compilation-compat-parse-errors (limit) | 1711 | (defun compilation-compat-parse-errors (limit) |
| 1707 | (when compilation-parse-errors-function | 1712 | (when compilation-parse-errors-function |
| @@ -1739,10 +1744,12 @@ Pop up the buffer containing MARKER and scroll to MARKER if we ask the user." | |||
| 1739 | (goto-char limit) | 1744 | (goto-char limit) |
| 1740 | nil) | 1745 | nil) |
| 1741 | 1746 | ||
| 1747 | ;; Beware: this is not only compatiblity code. New code stil uses it. --Stef | ||
| 1742 | (defun compilation-forget-errors () | 1748 | (defun compilation-forget-errors () |
| 1743 | ;; In case we hit the same file/line specs, we want to recompute a new | 1749 | ;; In case we hit the same file/line specs, we want to recompute a new |
| 1744 | ;; marker for them, so flush our cache. | 1750 | ;; marker for them, so flush our cache. |
| 1745 | (setq compilation-locs (make-hash-table :test 'equal :weakness 'value)) | 1751 | (setq compilation-locs (make-hash-table :test 'equal :weakness 'value)) |
| 1752 | (setq compilation-gcpro nil) | ||
| 1746 | ;; FIXME: the old code reset the directory-stack, so maybe we should | 1753 | ;; FIXME: the old code reset the directory-stack, so maybe we should |
| 1747 | ;; put a `directory change' marker of some sort, but where? -stef | 1754 | ;; put a `directory change' marker of some sort, but where? -stef |
| 1748 | ;; | 1755 | ;; |
| @@ -1754,9 +1761,19 @@ Pop up the buffer containing MARKER and scroll to MARKER if we ask the user." | |||
| 1754 | ;; something equivalent to point-max. So we speculatively move | 1761 | ;; something equivalent to point-max. So we speculatively move |
| 1755 | ;; compilation-current-error to point-max (since the external package | 1762 | ;; compilation-current-error to point-max (since the external package |
| 1756 | ;; won't know that it should do it). --stef | 1763 | ;; won't know that it should do it). --stef |
| 1757 | (setq compilation-current-error (point-max))) | 1764 | (setq compilation-current-error nil) |
| 1765 | (let* ((proc (get-buffer-process (current-buffer))) | ||
| 1766 | (mark (if proc (process-mark proc))) | ||
| 1767 | (pos (or mark (point-max)))) | ||
| 1768 | (setq compilation-messages-start | ||
| 1769 | ;; In the future, ignore the text already present in the buffer. | ||
| 1770 | ;; Since many process filter functions insert before markers, | ||
| 1771 | ;; we need to put ours just before the insertion point rather | ||
| 1772 | ;; than at the insertion point. If that's not possible, then | ||
| 1773 | ;; don't use a marker. --Stef | ||
| 1774 | (if (> pos (point-min)) (copy-marker (1- pos)) pos)))) | ||
| 1758 | 1775 | ||
| 1759 | (provide 'compile) | 1776 | (provide 'compile) |
| 1760 | 1777 | ||
| 1761 | ;;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c | 1778 | ;; arch-tag: 12465727-7382-4f72-b234-79855a00dd8c |
| 1762 | ;;; compile.el ends here | 1779 | ;;; compile.el ends here |
diff --git a/lisp/progmodes/cperl-mode.el b/lisp/progmodes/cperl-mode.el index e13198fb240..c651e06b899 100644 --- a/lisp/progmodes/cperl-mode.el +++ b/lisp/progmodes/cperl-mode.el | |||
| @@ -926,12 +926,9 @@ the faces: please specify bold, italic, underline, shadow and box.) | |||
| 926 | (defun cperl-putback-char (c) ; Emacs 19 | 926 | (defun cperl-putback-char (c) ; Emacs 19 |
| 927 | (set 'unread-command-events (list c))) ; Avoid undefined warning | 927 | (set 'unread-command-events (list c))) ; Avoid undefined warning |
| 928 | 928 | ||
| 929 | (if (boundp 'unread-command-events) | 929 | (if cperl-xemacs-p |
| 930 | (if cperl-xemacs-p | 930 | (defun cperl-putback-char (c) ; XEmacs >= 19.12 |
| 931 | (defun cperl-putback-char (c) ; XEmacs >= 19.12 | 931 | (setq unread-command-events (list (eval '(character-to-event c)))))) |
| 932 | (setq unread-command-events (list (eval '(character-to-event c)))))) | ||
| 933 | (defun cperl-putback-char (c) ; XEmacs <= 19.11 | ||
| 934 | (set 'unread-command-event (eval '(character-to-event c))))) ; Avoid warnings | ||
| 935 | 932 | ||
| 936 | (or (fboundp 'uncomment-region) | 933 | (or (fboundp 'uncomment-region) |
| 937 | (defun uncomment-region (beg end) | 934 | (defun uncomment-region (beg end) |
diff --git a/lisp/progmodes/etags.el b/lisp/progmodes/etags.el index ef5d1eba998..184077f6a3a 100644 --- a/lisp/progmodes/etags.el +++ b/lisp/progmodes/etags.el | |||
| @@ -1248,7 +1248,11 @@ where they were found." | |||
| 1248 | 1248 | ||
| 1249 | 1249 | ||
| 1250 | (defun etags-tags-completion-table () | 1250 | (defun etags-tags-completion-table () |
| 1251 | (let ((table (make-vector 511 0))) | 1251 | (let ((table (make-vector 511 0)) |
| 1252 | (point-max (/ (float (point-max)) 100.0)) | ||
| 1253 | (msg-fmt (format | ||
| 1254 | "Making tags completion table for %s...%%d%%%%" | ||
| 1255 | buffer-file-name))) | ||
| 1252 | (save-excursion | 1256 | (save-excursion |
| 1253 | (goto-char (point-min)) | 1257 | (goto-char (point-min)) |
| 1254 | ;; This monster regexp matches an etags tag line. | 1258 | ;; This monster regexp matches an etags tag line. |
| @@ -1264,11 +1268,12 @@ where they were found." | |||
| 1264 | \\([-a-zA-Z0-9_+*$?:]+\\)[^-a-zA-Z0-9_+*$?:\177]*\\)\177\ | 1268 | \\([-a-zA-Z0-9_+*$?:]+\\)[^-a-zA-Z0-9_+*$?:\177]*\\)\177\ |
| 1265 | \\(\\([^\n\001]+\\)\001\\)?\\([0-9]+\\)?,\\([0-9]+\\)?\n" | 1269 | \\(\\([^\n\001]+\\)\001\\)?\\([0-9]+\\)?,\\([0-9]+\\)?\n" |
| 1266 | nil t) | 1270 | nil t) |
| 1267 | (intern (if (match-beginning 5) | 1271 | (intern (prog1 (if (match-beginning 5) |
| 1268 | ;; There is an explicit tag name. | 1272 | ;; There is an explicit tag name. |
| 1269 | (buffer-substring (match-beginning 5) (match-end 5)) | 1273 | (buffer-substring (match-beginning 5) (match-end 5)) |
| 1270 | ;; No explicit tag name. Best guess. | 1274 | ;; No explicit tag name. Best guess. |
| 1271 | (buffer-substring (match-beginning 3) (match-end 3))) | 1275 | (buffer-substring (match-beginning 3) (match-end 3))) |
| 1276 | (message msg-fmt (/ (point) point-max))) | ||
| 1272 | table))) | 1277 | table))) |
| 1273 | table)) | 1278 | table)) |
| 1274 | 1279 | ||
| @@ -1866,6 +1871,7 @@ directory specification." | |||
| 1866 | (or gotany | 1871 | (or gotany |
| 1867 | (error "File %s not in current tags tables" file))))) | 1872 | (error "File %s not in current tags tables" file))))) |
| 1868 | (with-current-buffer "*Tags List*" | 1873 | (with-current-buffer "*Tags List*" |
| 1874 | (require 'apropos) | ||
| 1869 | (apropos-mode) | 1875 | (apropos-mode) |
| 1870 | (setq buffer-read-only t))) | 1876 | (setq buffer-read-only t))) |
| 1871 | 1877 | ||
| @@ -1884,6 +1890,7 @@ directory specification." | |||
| 1884 | (funcall tags-apropos-function regexp)))) | 1890 | (funcall tags-apropos-function regexp)))) |
| 1885 | (etags-tags-apropos-additional regexp)) | 1891 | (etags-tags-apropos-additional regexp)) |
| 1886 | (with-current-buffer "*Tags List*" | 1892 | (with-current-buffer "*Tags List*" |
| 1893 | (require 'apropos) | ||
| 1887 | (apropos-mode) | 1894 | (apropos-mode) |
| 1888 | ;; apropos-mode is derived from fundamental-mode and it kills | 1895 | ;; apropos-mode is derived from fundamental-mode and it kills |
| 1889 | ;; all local variables. | 1896 | ;; all local variables. |
diff --git a/lisp/progmodes/f90.el b/lisp/progmodes/f90.el index 11553a1fdb6..53165fbecb7 100644 --- a/lisp/progmodes/f90.el +++ b/lisp/progmodes/f90.el | |||
| @@ -153,7 +153,7 @@ | |||
| 153 | ;;; Code: | 153 | ;;; Code: |
| 154 | 154 | ||
| 155 | ;; TODO | 155 | ;; TODO |
| 156 | ;; Support for hideshow, align. | 156 | ;; Support for align. |
| 157 | ;; OpenMP, preprocessor highlighting. | 157 | ;; OpenMP, preprocessor highlighting. |
| 158 | 158 | ||
| 159 | (defvar comment-auto-fill-only-comments) | 159 | (defvar comment-auto-fill-only-comments) |
| @@ -589,6 +589,53 @@ characters long.") | |||
| 589 | (make-variable-buffer-local 'f90-cache-position) | 589 | (make-variable-buffer-local 'f90-cache-position) |
| 590 | 590 | ||
| 591 | 591 | ||
| 592 | ;; Hideshow support. | ||
| 593 | (defconst f90-end-block-re | ||
| 594 | (concat "^[ \t0-9]*\\<end\\>[ \t]*" | ||
| 595 | (regexp-opt '("do" "if" "forall" "function" "interface" | ||
| 596 | "module" "program" "select" "subroutine" | ||
| 597 | "type" "where" ) t) | ||
| 598 | "[ \t]*\\sw*") | ||
| 599 | "Regexp matching the end of a \"block\" of F90 code. | ||
| 600 | Used in the F90 entry in `hs-special-modes-alist'.") | ||
| 601 | |||
| 602 | ;; Ignore the fact that FUNCTION, SUBROUTINE, WHERE, FORALL have a | ||
| 603 | ;; following "(". DO, CASE, IF can have labels; IF must be | ||
| 604 | ;; accompanied by THEN. | ||
| 605 | ;; A big problem is that many of these statements can be broken over | ||
| 606 | ;; lines, even with embedded comments. We only try to handle this for | ||
| 607 | ;; IF ... THEN statements, assuming and hoping it will be less common | ||
| 608 | ;; for other constructs. We match up to one new-line, provided ") | ||
| 609 | ;; THEN" appears on one line. Matching on just ") THEN" is no good, | ||
| 610 | ;; since that includes ELSE branches. | ||
| 611 | ;; For a fully accurate solution, hideshow would probably have to be | ||
| 612 | ;; modified to allow functions as well as regexps to be used to | ||
| 613 | ;; specify block start and end positions. | ||
| 614 | (defconst f90-start-block-re | ||
| 615 | (concat | ||
| 616 | "^[ \t0-9]*" ; statement number | ||
| 617 | "\\(\\(" | ||
| 618 | "\\(\\sw+[ \t]*:[ \t]*\\)?" ; structure label | ||
| 619 | "\\(do\\|select[ \t]*case\\|if[ \t]*(.*\n?.*)[ \t]*then\\|" | ||
| 620 | ;; Distinguish WHERE block from isolated WHERE. | ||
| 621 | "\\(where\\|forall\\)[ \t]*(.*)[ \t]*\\(!\\|$\\)\\)\\)" | ||
| 622 | "\\|" | ||
| 623 | "program\\|interface\\|module\\|type\\|function\\|subroutine" | ||
| 624 | ;; ") THEN" at line end. Problem - also does ELSE. | ||
| 625 | ;;; "\\|.*)[ \t]*then[ \t]*\\($\\|!\\)" | ||
| 626 | "\\)" | ||
| 627 | "[ \t]*") | ||
| 628 | "Regexp matching the start of a \"block\" of F90 code. | ||
| 629 | A simple regexp cannot do this in fully correct fashion, so this | ||
| 630 | tries to strike a compromise between complexity and flexibility. | ||
| 631 | Used in the F90 entry in `hs-special-modes-alist'.") | ||
| 632 | |||
| 633 | ;; hs-special-modes-alist is autoloaded. | ||
| 634 | (add-to-list 'hs-special-modes-alist | ||
| 635 | `(f90-mode ,f90-start-block-re ,f90-end-block-re | ||
| 636 | "!" f90-end-of-block nil)) | ||
| 637 | |||
| 638 | |||
| 592 | ;; Imenu support. | 639 | ;; Imenu support. |
| 593 | (defvar f90-imenu-generic-expression | 640 | (defvar f90-imenu-generic-expression |
| 594 | (let ((good-char "[^!\"\&\n \t]") (not-e "[^e!\n\"\& \t]") | 641 | (let ((good-char "[^!\"\&\n \t]") (not-e "[^e!\n\"\& \t]") |
| @@ -850,14 +897,16 @@ line-number before indenting." | |||
| 850 | 897 | ||
| 851 | (defsubst f90-get-present-comment-type () | 898 | (defsubst f90-get-present-comment-type () |
| 852 | "If point lies within a comment, return the string starting the comment. | 899 | "If point lies within a comment, return the string starting the comment. |
| 853 | For example, \"!\" or \"!!\"." | 900 | For example, \"!\" or \"!!\", followed by the appropriate amount of |
| 901 | whitespace, if any." | ||
| 902 | ;; Include the whitespace for consistent auto-filling of comment blocks. | ||
| 854 | (save-excursion | 903 | (save-excursion |
| 855 | (when (f90-in-comment) | 904 | (when (f90-in-comment) |
| 856 | (beginning-of-line) | 905 | (beginning-of-line) |
| 857 | (re-search-forward "!+" (line-end-position)) | 906 | (re-search-forward "!+[ \t]*" (line-end-position)) |
| 858 | (while (f90-in-string) | 907 | (while (f90-in-string) |
| 859 | (re-search-forward "!+" (line-end-position))) | 908 | (re-search-forward "!+[ \t]*" (line-end-position))) |
| 860 | (match-string 0)))) | 909 | (match-string-no-properties 0)))) |
| 861 | 910 | ||
| 862 | (defsubst f90-equal-symbols (a b) | 911 | (defsubst f90-equal-symbols (a b) |
| 863 | "Compare strings A and B neglecting case and allowing for nil value." | 912 | "Compare strings A and B neglecting case and allowing for nil value." |
| @@ -1519,6 +1568,7 @@ is non-nil, call `f90-update-line' after inserting the continuation marker." | |||
| 1519 | (cond ((f90-in-string) | 1568 | (cond ((f90-in-string) |
| 1520 | (insert "&\n&")) | 1569 | (insert "&\n&")) |
| 1521 | ((f90-in-comment) | 1570 | ((f90-in-comment) |
| 1571 | (delete-horizontal-space 'backwards) ; remove trailing whitespace | ||
| 1522 | (insert "\n" (f90-get-present-comment-type))) | 1572 | (insert "\n" (f90-get-present-comment-type))) |
| 1523 | (t (insert "&") | 1573 | (t (insert "&") |
| 1524 | (or no-update (f90-update-line)) | 1574 | (or no-update (f90-update-line)) |
diff --git a/lisp/progmodes/flymake.el b/lisp/progmodes/flymake.el new file mode 100644 index 00000000000..2cd62eeecee --- /dev/null +++ b/lisp/progmodes/flymake.el | |||
| @@ -0,0 +1,2504 @@ | |||
| 1 | ;;; flymake.el -- a universal on-the-fly syntax checker | ||
| 2 | |||
| 3 | ;; Copyright (C) 2003 Free Software Foundation | ||
| 4 | |||
| 5 | ;; Author: Pavel Kobiakov <pk_at_work@yahoo.com> | ||
| 6 | ;; Maintainer: Pavel Kobiakov <pk_at_work@yahoo.com> | ||
| 7 | ;; Version: 0.3 | ||
| 8 | ;; Keywords: c languages tools | ||
| 9 | |||
| 10 | ;; This file is part of GNU Emacs. | ||
| 11 | |||
| 12 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 13 | ;; it under the terms of the GNU General Public License as published by | ||
| 14 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 15 | ;; any later version. | ||
| 16 | |||
| 17 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 18 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 19 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 20 | ;; GNU General Public License for more details. | ||
| 21 | |||
| 22 | ;; You should have received a copy of the GNU General Public License | ||
| 23 | ;; along with GNU Emacs; see the file COPYING. If not, write to the | ||
| 24 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
| 25 | ;; Boston, MA 02111-1307, USA. | ||
| 26 | |||
| 27 | ;;; Commentary: | ||
| 28 | ;; | ||
| 29 | ;; Flymake is a minor Emacs mode performing on-the-fly syntax | ||
| 30 | ;; checks using the external syntax check tool (for C/C++ this | ||
| 31 | ;; is usually the compiler) | ||
| 32 | |||
| 33 | ;;; Code: | ||
| 34 | |||
| 35 | ;;;_* Provide | ||
| 36 | (provide 'flymake) | ||
| 37 | |||
| 38 | ;;;; [[ Overlay compatibility | ||
| 39 | (autoload 'make-overlay "overlay" "Overlay compatibility kit." t) | ||
| 40 | (autoload 'overlayp "overlay" "Overlay compatibility kit." t) | ||
| 41 | (autoload 'overlays-in "overlay" "Overlay compatibility kit." t) | ||
| 42 | (autoload 'delete-overlay "overlay" "Overlay compatibility kit." t) | ||
| 43 | (autoload 'overlay-put "overlay" "Overlay compatibility kit." t) | ||
| 44 | (autoload 'overlay-get "overlay" "Overlay compatibility kit." t) | ||
| 45 | ;;;; ]] | ||
| 46 | |||
| 47 | ;;;; [[ cross-emacs compatibility routines | ||
| 48 | (defvar flymake-emacs | ||
| 49 | (cond | ||
| 50 | ((string-match "XEmacs" emacs-version) 'xemacs) | ||
| 51 | (t 'emacs) | ||
| 52 | ) | ||
| 53 | "Currently used emacs flavor" | ||
| 54 | ) | ||
| 55 | |||
| 56 | (defun flymake-makehash(&optional test) | ||
| 57 | (cond | ||
| 58 | ((equal flymake-emacs 'xemacs) (if test (make-hash-table :test test) (make-hash-table))) | ||
| 59 | (t (makehash test)) | ||
| 60 | ) | ||
| 61 | ) | ||
| 62 | |||
| 63 | (defun flymake-time-to-float(&optional tm) | ||
| 64 | "Convert `current-time` to a float number of seconds." | ||
| 65 | (multiple-value-bind (s0 s1 s2) (or tm (current-time)) | ||
| 66 | (+ (* (float (ash 1 16)) s0) (float s1) (* 0.0000001 s2))) | ||
| 67 | ) | ||
| 68 | (defun flymake-float-time() | ||
| 69 | (cond | ||
| 70 | ((equal flymake-emacs 'xemacs) (flymake-time-to-float (current-time))) | ||
| 71 | (t (float-time)) | ||
| 72 | ) | ||
| 73 | ) | ||
| 74 | |||
| 75 | (defun flymake-replace-regexp-in-string(regexp rep str) | ||
| 76 | (cond | ||
| 77 | ((equal flymake-emacs 'xemacs) (replace-in-string str regexp rep)) | ||
| 78 | (t (replace-regexp-in-string regexp rep str)) | ||
| 79 | ) | ||
| 80 | ) | ||
| 81 | |||
| 82 | (defun flymake-split-string-remove-empty-edges(str pattern) | ||
| 83 | "split, then remove first and/or last in case it's empty" | ||
| 84 | (let* ((splitted (split-string str pattern))) | ||
| 85 | (if (and (> (length splitted) 0) (= 0 (length (elt splitted 0)))) | ||
| 86 | (setq splitted (cdr splitted)) | ||
| 87 | ) | ||
| 88 | (if (and (> (length splitted) 0) (= 0 (length (elt splitted (1- (length splitted)))))) | ||
| 89 | (setq splitted (reverse (cdr (reverse splitted)))) | ||
| 90 | ) | ||
| 91 | splitted | ||
| 92 | ) | ||
| 93 | ) | ||
| 94 | (defun flymake-split-string(str pattern) | ||
| 95 | (cond | ||
| 96 | ((equal flymake-emacs 'xemacs) (flymake-split-string-remove-empty-edges str pattern)) | ||
| 97 | (t (split-string str pattern)) | ||
| 98 | ) | ||
| 99 | ) | ||
| 100 | |||
| 101 | (defun flymake-get-temp-dir() | ||
| 102 | (cond | ||
| 103 | ((equal flymake-emacs 'xemacs) (temp-directory)) | ||
| 104 | (t temporary-file-directory) | ||
| 105 | ) | ||
| 106 | ) | ||
| 107 | |||
| 108 | (defun flymake-line-beginning-position() | ||
| 109 | (save-excursion | ||
| 110 | (beginning-of-line) | ||
| 111 | (point) | ||
| 112 | ) | ||
| 113 | ) | ||
| 114 | |||
| 115 | (defun flymake-line-end-position() | ||
| 116 | (save-excursion | ||
| 117 | (end-of-line) | ||
| 118 | (point) | ||
| 119 | ) | ||
| 120 | ) | ||
| 121 | |||
| 122 | (defun flymake-popup-menu(pos menu-data) | ||
| 123 | (cond | ||
| 124 | ((equal flymake-emacs 'xemacs) | ||
| 125 | (let* ((x-pos (nth 0 (nth 0 pos))) | ||
| 126 | (y-pos (nth 1 (nth 0 pos))) | ||
| 127 | (fake-event-props '(button 1 x 1 y 1))) | ||
| 128 | (setq fake-event-props (plist-put fake-event-props 'x x-pos)) | ||
| 129 | (setq fake-event-props (plist-put fake-event-props 'y y-pos)) | ||
| 130 | (popup-menu (flymake-make-xemacs-menu menu-data) (make-event 'button-press fake-event-props)) | ||
| 131 | ) | ||
| 132 | ) | ||
| 133 | (t (x-popup-menu pos (flymake-make-emacs-menu menu-data))) | ||
| 134 | ) | ||
| 135 | ) | ||
| 136 | |||
| 137 | (defun flymake-make-emacs-menu(menu-data) | ||
| 138 | (let* ((menu-title (nth 0 menu-data)) | ||
| 139 | (menu-items (nth 1 menu-data)) | ||
| 140 | (menu-commands nil)) | ||
| 141 | |||
| 142 | (setq menu-commands (mapcar (lambda (foo) | ||
| 143 | (cons (nth 0 foo) (nth 1 foo))) | ||
| 144 | menu-items)) | ||
| 145 | (list menu-title (cons "" menu-commands)) | ||
| 146 | ) | ||
| 147 | ) | ||
| 148 | |||
| 149 | (defun flymake-nop() | ||
| 150 | ) | ||
| 151 | |||
| 152 | (defun flymake-make-xemacs-menu(menu-data) | ||
| 153 | (let* ((menu-title (nth 0 menu-data)) | ||
| 154 | (menu-items (nth 1 menu-data)) | ||
| 155 | (menu-commands nil)) | ||
| 156 | (setq menu-commands (mapcar (lambda (foo) | ||
| 157 | (vector (nth 0 foo) (or (nth 1 foo) '(flymake-nop)) t)) | ||
| 158 | menu-items)) | ||
| 159 | (cons menu-title menu-commands) | ||
| 160 | ) | ||
| 161 | ) | ||
| 162 | |||
| 163 | (defun flymake-xemacs-window-edges(&optional window) | ||
| 164 | (let ((edges (window-pixel-edges window)) | ||
| 165 | tmp) | ||
| 166 | (setq tmp edges) | ||
| 167 | (setcar tmp (/ (car tmp) (face-width 'default))) | ||
| 168 | (setq tmp (cdr tmp)) | ||
| 169 | (setcar tmp (/ (car tmp) (face-height 'default))) | ||
| 170 | (setq tmp (cdr tmp)) | ||
| 171 | (setcar tmp (/ (car tmp) (face-width 'default))) | ||
| 172 | (setq tmp (cdr tmp)) | ||
| 173 | (setcar tmp (/ (car tmp) (face-height 'default))) | ||
| 174 | edges | ||
| 175 | ) | ||
| 176 | ) | ||
| 177 | |||
| 178 | (defun flymake-current-row() | ||
| 179 | "return current row in current frame" | ||
| 180 | (cond | ||
| 181 | ((equal flymake-emacs 'xemacs) (count-lines (window-start) (point))) | ||
| 182 | (t (+ (car (cdr (window-edges))) (count-lines (window-start) (point)))) | ||
| 183 | ) | ||
| 184 | ) | ||
| 185 | |||
| 186 | (defun flymake-selected-frame() | ||
| 187 | (cond | ||
| 188 | ((equal flymake-emacs 'xemacs) (selected-window)) | ||
| 189 | (t (selected-frame)) | ||
| 190 | ) | ||
| 191 | ) | ||
| 192 | |||
| 193 | ;;;; ]] | ||
| 194 | |||
| 195 | (defcustom flymake-log-level -1 | ||
| 196 | "Logging level, only messages with level > flymake-log-level will not be logged | ||
| 197 | -1 = NONE, 0 = ERROR, 1 = WARNING, 2 = INFO, 3 = DEBUG" | ||
| 198 | :group 'flymake | ||
| 199 | :type 'integer | ||
| 200 | ) | ||
| 201 | |||
| 202 | (defun flymake-log(level text &rest args) | ||
| 203 | "Log a message with optional arguments" | ||
| 204 | (if (<= level flymake-log-level) | ||
| 205 | (let* ((msg (apply 'format text args))) | ||
| 206 | (message msg) | ||
| 207 | ;(with-temp-buffer | ||
| 208 | ; (insert msg) | ||
| 209 | ; (insert "\n") | ||
| 210 | ; (flymake-save-buffer-in-file (current-buffer) "d:/flymake.log" t) ; make log file name customizable | ||
| 211 | ;) | ||
| 212 | ) | ||
| 213 | ) | ||
| 214 | ) | ||
| 215 | |||
| 216 | (defun flymake-ins-after(list pos val) | ||
| 217 | "insert val into list after position pos" | ||
| 218 | (let ((tmp (copy-sequence list))) ; (???) | ||
| 219 | (setcdr (nthcdr pos tmp) (cons val (nthcdr (1+ pos) tmp))) | ||
| 220 | tmp | ||
| 221 | ) | ||
| 222 | ) | ||
| 223 | |||
| 224 | (defun flymake-set-at(list pos val) | ||
| 225 | "set val at position pos in list" | ||
| 226 | (let ((tmp (copy-sequence list))) ; (???) | ||
| 227 | (setcar (nthcdr pos tmp) val) | ||
| 228 | tmp | ||
| 229 | ) | ||
| 230 | ) | ||
| 231 | |||
| 232 | (defvar flymake-pid-to-names(flymake-makehash) | ||
| 233 | "pid -> source buffer name, output file name mapping" | ||
| 234 | ) | ||
| 235 | |||
| 236 | (defun flymake-reg-names(pid source-buffer-name) | ||
| 237 | "Save into in pid map" | ||
| 238 | (unless (stringp source-buffer-name) | ||
| 239 | (error "invalid buffer name") | ||
| 240 | ) | ||
| 241 | (puthash pid (list source-buffer-name) flymake-pid-to-names) | ||
| 242 | ) | ||
| 243 | |||
| 244 | (defun flymake-get-source-buffer-name(pid) | ||
| 245 | "Return buffer name stored in pid map" | ||
| 246 | (nth 0 (gethash pid flymake-pid-to-names)) | ||
| 247 | ) | ||
| 248 | |||
| 249 | (defun flymake-unreg-names(pid) | ||
| 250 | "Delete pid->buffer name mapping" | ||
| 251 | (remhash pid flymake-pid-to-names) | ||
| 252 | ) | ||
| 253 | |||
| 254 | (defun flymake-get-buffer-var(buffer var-name) | ||
| 255 | "switch to buffer if necessary and return local variable var" | ||
| 256 | (unless (bufferp buffer) | ||
| 257 | (error "invalid buffer") | ||
| 258 | ) | ||
| 259 | |||
| 260 | (if (eq buffer (current-buffer)) | ||
| 261 | (symbol-value var-name) | ||
| 262 | ;else | ||
| 263 | (save-excursion | ||
| 264 | (set-buffer buffer) | ||
| 265 | (symbol-value var-name) | ||
| 266 | ) | ||
| 267 | ) | ||
| 268 | ) | ||
| 269 | |||
| 270 | (defun flymake-set-buffer-var(buffer var-name var-value) | ||
| 271 | "switch to buffer if necessary and set local variable var-name to var-value" | ||
| 272 | (unless (bufferp buffer) | ||
| 273 | (error "invalid buffer") | ||
| 274 | ) | ||
| 275 | |||
| 276 | (if (eq buffer (current-buffer)) | ||
| 277 | (set var-name var-value) | ||
| 278 | ;else | ||
| 279 | (save-excursion | ||
| 280 | (set-buffer buffer) | ||
| 281 | (set var-name var-value) | ||
| 282 | ) | ||
| 283 | ) | ||
| 284 | ) | ||
| 285 | |||
| 286 | (defvar flymake-buffer-data(flymake-makehash) | ||
| 287 | "data specific to syntax check tool, in name-value pairs" | ||
| 288 | ) | ||
| 289 | (make-variable-buffer-local 'flymake-buffer-data) | ||
| 290 | (defun flymake-get-buffer-data(buffer) | ||
| 291 | (flymake-get-buffer-var buffer 'flymake-buffer-data) | ||
| 292 | ) | ||
| 293 | (defun flymake-set-buffer-data(buffer data) | ||
| 294 | (flymake-set-buffer-var buffer 'flymake-buffer-data data) | ||
| 295 | ) | ||
| 296 | (defun flymake-get-buffer-value(buffer name) | ||
| 297 | (gethash name (flymake-get-buffer-data buffer)) | ||
| 298 | ) | ||
| 299 | (defun flymake-set-buffer-value(buffer name value) | ||
| 300 | (puthash name value (flymake-get-buffer-data buffer)) | ||
| 301 | ) | ||
| 302 | |||
| 303 | (defvar flymake-output-residual nil | ||
| 304 | "" | ||
| 305 | ) | ||
| 306 | (make-variable-buffer-local 'flymake-output-residual) | ||
| 307 | (defun flymake-get-buffer-output-residual(buffer) | ||
| 308 | (flymake-get-buffer-var buffer 'flymake-output-residual) | ||
| 309 | ) | ||
| 310 | (defun flymake-set-buffer-output-residual(buffer residual) | ||
| 311 | (flymake-set-buffer-var buffer 'flymake-output-residual residual) | ||
| 312 | ) | ||
| 313 | |||
| 314 | (defcustom flymake-allowed-file-name-masks '((".+\\.c$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 315 | (".+\\.cpp$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 316 | (".+\\.xml$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 317 | (".+\\.html?$" flymake-xml-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 318 | (".+\\.cs$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 319 | (".+\\.pl$" flymake-perl-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 320 | (".+\\.h$" flymake-master-make-header-init flymake-master-cleanup flymake-get-real-file-name) | ||
| 321 | (".+\\.java$" flymake-simple-make-java-init flymake-simple-java-cleanup flymake-get-real-file-name) | ||
| 322 | (".+[0-9]+\\.tex$" flymake-master-tex-init flymake-master-cleanup flymake-get-real-file-name) | ||
| 323 | (".+\\.tex$" flymake-simple-tex-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 324 | (".+\\.idl$" flymake-simple-make-init flymake-simple-cleanup flymake-get-real-file-name) | ||
| 325 | ; (".+\\.cpp$" 1) | ||
| 326 | ; (".+\\.java$" 3) | ||
| 327 | ; (".+\\.h$" 2 (".+\\.cpp$" ".+\\.c$") | ||
| 328 | ; ("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) | ||
| 329 | ; (".+\\.idl$" 1) | ||
| 330 | ; (".+\\.odl$" 1) | ||
| 331 | ; (".+[0-9]+\\.tex$" 2 (".+\\.tex$") | ||
| 332 | ; ("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2 )) | ||
| 333 | ; (".+\\.tex$" 1) | ||
| 334 | ) | ||
| 335 | "*Files syntax checking is allowed for" | ||
| 336 | :group 'flymake | ||
| 337 | :type '(repeat (string symbol symbol symbol)) | ||
| 338 | ) | ||
| 339 | |||
| 340 | (defun flymake-get-file-name-mode-and-masks(file-name) | ||
| 341 | "return the corresponding entry from flymake-allowed-file-name-masks" | ||
| 342 | (unless (stringp file-name) | ||
| 343 | (error "invalid file-name") | ||
| 344 | ) | ||
| 345 | (let ((count (length flymake-allowed-file-name-masks)) | ||
| 346 | (idx 0) | ||
| 347 | (mode-and-masks nil)) | ||
| 348 | (while (and (not mode-and-masks) (< idx count)) | ||
| 349 | (if (string-match (nth 0 (nth idx flymake-allowed-file-name-masks)) file-name) | ||
| 350 | (setq mode-and-masks (cdr (nth idx flymake-allowed-file-name-masks))) | ||
| 351 | ) | ||
| 352 | (setq idx (1+ idx)) | ||
| 353 | ) | ||
| 354 | (flymake-log 3 "file %s, init=%s" file-name (car mode-and-masks)) | ||
| 355 | mode-and-masks | ||
| 356 | ) | ||
| 357 | ) | ||
| 358 | |||
| 359 | (defun flymake-can-syntax-check-file(file-name) | ||
| 360 | "Determine whether we can syntax check file-name: nil if cannot, non-nil if can" | ||
| 361 | (if (flymake-get-init-function file-name) | ||
| 362 | t | ||
| 363 | ;else | ||
| 364 | nil | ||
| 365 | ) | ||
| 366 | ) | ||
| 367 | |||
| 368 | (defun flymake-get-init-function(file-name) | ||
| 369 | "return init function to be used for the file" | ||
| 370 | (let* ((init-f (nth 0 (flymake-get-file-name-mode-and-masks file-name)))) | ||
| 371 | ;(flymake-log 0 "calling %s" init-f) | ||
| 372 | ;(funcall init-f (current-buffer)) | ||
| 373 | ) | ||
| 374 | (nth 0 (flymake-get-file-name-mode-and-masks file-name)) | ||
| 375 | ) | ||
| 376 | |||
| 377 | (defun flymake-get-cleanup-function(file-name) | ||
| 378 | "return cleanup function to be used for the file" | ||
| 379 | (nth 1 (flymake-get-file-name-mode-and-masks file-name)) | ||
| 380 | ) | ||
| 381 | |||
| 382 | (defun flymake-get-real-file-name-function(file-name) | ||
| 383 | "" | ||
| 384 | (or (nth 2 (flymake-get-file-name-mode-and-masks file-name)) 'flymake-get-real-file-name) | ||
| 385 | ) | ||
| 386 | |||
| 387 | (defcustom flymake-buildfile-dirs '("." ".." "../.." "../../.." "../../../.." "../../../../.." "../../../../../.." "../../../../../../.." "../../../../../../../.." "../../../../../../../../.." "../../../../../../../../../.." "../../../../../../../../../../..") | ||
| 388 | "dirs to look for buildfile" | ||
| 389 | :group 'flymake | ||
| 390 | :type '(repeat (string)) | ||
| 391 | ) | ||
| 392 | |||
| 393 | (defvar flymake-find-buildfile-cache (flymake-makehash 'equal)) | ||
| 394 | (defun flymake-get-buildfile-from-cache(dir-name) | ||
| 395 | (gethash dir-name flymake-find-buildfile-cache) | ||
| 396 | ) | ||
| 397 | (defun flymake-add-buildfile-to-cache(dir-name buildfile) | ||
| 398 | (puthash dir-name buildfile flymake-find-buildfile-cache) | ||
| 399 | ) | ||
| 400 | (defun flymake-clear-buildfile-cache() | ||
| 401 | (clrhash flymake-find-buildfile-cache) | ||
| 402 | ) | ||
| 403 | |||
| 404 | (defun flymake-find-buildfile(buildfile-name source-dir-name dirs) | ||
| 405 | "find buildfile (i.e. Makefile, build.xml, etc.) starting from current directory. Return its path or nil if not found" | ||
| 406 | (if (flymake-get-buildfile-from-cache source-dir-name) | ||
| 407 | (progn | ||
| 408 | (flymake-get-buildfile-from-cache source-dir-name) | ||
| 409 | ) | ||
| 410 | ;else | ||
| 411 | (let* ((buildfile-dir nil) | ||
| 412 | (buildfile nil) | ||
| 413 | (dir-count (length dirs)) | ||
| 414 | (dir-idx 0) | ||
| 415 | (found nil)) | ||
| 416 | |||
| 417 | (while (and (not found) (< dir-idx dir-count)) | ||
| 418 | |||
| 419 | (setq buildfile-dir (concat source-dir-name (nth dir-idx dirs))) | ||
| 420 | (setq buildfile (concat buildfile-dir "/" buildfile-name)) | ||
| 421 | |||
| 422 | (when (file-exists-p buildfile) | ||
| 423 | (setq found t) | ||
| 424 | ) | ||
| 425 | |||
| 426 | (setq dir-idx (1+ dir-idx)) | ||
| 427 | ) | ||
| 428 | (if found | ||
| 429 | (progn | ||
| 430 | (flymake-log 3 "found buildfile at %s/%s" buildfile-dir buildfile-name) | ||
| 431 | (flymake-add-buildfile-to-cache source-dir-name buildfile-dir) | ||
| 432 | buildfile-dir | ||
| 433 | ) | ||
| 434 | ;else | ||
| 435 | (progn | ||
| 436 | (flymake-log 3 "buildfile for %s not found" source-dir-name) | ||
| 437 | nil | ||
| 438 | ) | ||
| 439 | ) | ||
| 440 | ) | ||
| 441 | ) | ||
| 442 | ) | ||
| 443 | |||
| 444 | (defun flymake-fix-path-name(name) | ||
| 445 | "replace all occurences of '\' with '/'" | ||
| 446 | (when name | ||
| 447 | (let* ((new-name (flymake-replace-regexp-in-string "[\\]" "/" (expand-file-name name))) | ||
| 448 | (last-char (elt new-name (1- (length new-name))))) | ||
| 449 | (setq new-name (flymake-replace-regexp-in-string "\\./" "" new-name)) | ||
| 450 | (if (equal "/" (char-to-string last-char)) | ||
| 451 | (setq new-name (substring new-name 0 (1- (length new-name)))) | ||
| 452 | ) | ||
| 453 | new-name | ||
| 454 | ) | ||
| 455 | ) | ||
| 456 | ) | ||
| 457 | |||
| 458 | (defun flymake-same-files(file-name-one file-name-two) | ||
| 459 | "t if file-name-one and file-name-two actually point to the same file" | ||
| 460 | (equal (flymake-fix-path-name file-name-one) (flymake-fix-path-name file-name-two)) | ||
| 461 | ) | ||
| 462 | |||
| 463 | (defun flymake-ensure-ends-with-slash(path) | ||
| 464 | (if (not (= (elt path (1- (length path))) (string-to-char "/"))) | ||
| 465 | (concat path "/") | ||
| 466 | ;else | ||
| 467 | path | ||
| 468 | ) | ||
| 469 | ) | ||
| 470 | |||
| 471 | (defun flymake-get-common-path-prefix(string-one string-two) | ||
| 472 | "return common prefix for two paths" | ||
| 473 | (when (and string-one string-two) | ||
| 474 | (let* ((slash-pos-one -1) | ||
| 475 | (slash-pos-two -1) | ||
| 476 | (done nil) | ||
| 477 | (prefix nil)) | ||
| 478 | |||
| 479 | (setq string-one (flymake-ensure-ends-with-slash string-one)) | ||
| 480 | (setq string-two (flymake-ensure-ends-with-slash string-two)) | ||
| 481 | |||
| 482 | (while (not done) | ||
| 483 | (setq slash-pos-one (string-match "/" string-one (1+ slash-pos-one))) | ||
| 484 | (setq slash-pos-two (string-match "/" string-two (1+ slash-pos-two))) | ||
| 485 | |||
| 486 | (if (and slash-pos-one slash-pos-two | ||
| 487 | (= slash-pos-one slash-pos-two) | ||
| 488 | (string= (substring string-one 0 slash-pos-one) (substring string-two 0 slash-pos-two))) | ||
| 489 | (progn | ||
| 490 | (setq prefix (substring string-one 0 (1+ slash-pos-one))) | ||
| 491 | ) | ||
| 492 | ;else | ||
| 493 | (setq done t) | ||
| 494 | ) | ||
| 495 | ) | ||
| 496 | prefix | ||
| 497 | ) | ||
| 498 | ) | ||
| 499 | ) | ||
| 500 | |||
| 501 | (defun flymake-build-relative-path(from-dir to-dir) | ||
| 502 | "return rel: from-dir/rel == to-dir" | ||
| 503 | (if (not (equal (elt from-dir 0) (elt to-dir 0))) | ||
| 504 | (error "first chars in paths %s, %s must be equal (same drive)" from-dir to-dir) | ||
| 505 | ;else | ||
| 506 | (let* ((from (flymake-ensure-ends-with-slash (flymake-fix-path-name from-dir))) | ||
| 507 | (to (flymake-ensure-ends-with-slash (flymake-fix-path-name to-dir))) | ||
| 508 | (prefix (flymake-get-common-path-prefix from to)) | ||
| 509 | (from-suffix (substring from (length prefix))) | ||
| 510 | (up-count (length (flymake-split-string from-suffix "[/]"))) | ||
| 511 | (to-suffix (substring to (length prefix))) | ||
| 512 | (idx 0) | ||
| 513 | (rel nil)) | ||
| 514 | |||
| 515 | (if (and (> (length to-suffix) 0) (equal "/" (char-to-string (elt to-suffix 0)))) | ||
| 516 | (setq to-suffix (substring to-suffix 1)) | ||
| 517 | ) | ||
| 518 | |||
| 519 | (while (< idx up-count) | ||
| 520 | (if (> (length rel) 0) | ||
| 521 | (setq rel (concat rel "/")) | ||
| 522 | ) | ||
| 523 | (setq rel (concat rel "..")) | ||
| 524 | (setq idx (1+ idx)) | ||
| 525 | ) | ||
| 526 | (if (> (length rel) 0) | ||
| 527 | (setq rel (concat rel "/")) | ||
| 528 | ) | ||
| 529 | (if (> (length to-suffix) 0) | ||
| 530 | (setq rel (concat rel to-suffix)) | ||
| 531 | ) | ||
| 532 | |||
| 533 | (or rel "./") | ||
| 534 | ) | ||
| 535 | ) | ||
| 536 | ) | ||
| 537 | |||
| 538 | (defcustom flymake-master-file-dirs '("." "./src" "./UnitTest") | ||
| 539 | "dirs where to llok for master files" | ||
| 540 | :group 'flymake | ||
| 541 | :type '(repeat (string)) | ||
| 542 | ) | ||
| 543 | |||
| 544 | (defcustom flymake-master-file-count-limit 32 | ||
| 545 | "max number of master files to check" | ||
| 546 | :group 'flymake | ||
| 547 | :type 'integer | ||
| 548 | ) | ||
| 549 | |||
| 550 | (defun flymake-find-possible-master-files(file-name master-file-dirs masks) | ||
| 551 | "find (by name and location) all posible master files, which are .cpp and .c for and .h. | ||
| 552 | Files are searched for starting from the .h directory and max max-level parent dirs. | ||
| 553 | File contents are not checked." | ||
| 554 | (let* ((dir-idx 0) | ||
| 555 | (dir-count (length master-file-dirs)) | ||
| 556 | (files nil) | ||
| 557 | (done nil) | ||
| 558 | (masks-count (length masks))) | ||
| 559 | |||
| 560 | (while (and (not done) (< dir-idx dir-count)) | ||
| 561 | (let* ((dir (concat (flymake-fix-path-name (file-name-directory file-name)) "/" (nth dir-idx master-file-dirs))) | ||
| 562 | (masks-idx 0)) | ||
| 563 | (while (and (file-exists-p dir) (not done) (< masks-idx masks-count)) | ||
| 564 | (let* ((mask (nth masks-idx masks)) | ||
| 565 | (dir-files (directory-files dir t mask)) | ||
| 566 | (file-count (length dir-files)) | ||
| 567 | (file-idx 0)) | ||
| 568 | |||
| 569 | (flymake-log 3 "dir %s, %d file(s) for mask %s" dir file-count mask) | ||
| 570 | (while (and (not done) (< file-idx file-count)) | ||
| 571 | (when (not (file-directory-p (nth file-idx dir-files))) | ||
| 572 | (setq files (cons (nth file-idx dir-files) files)) | ||
| 573 | (when (>= (length files) flymake-master-file-count-limit) | ||
| 574 | (flymake-log 3 "master file count limit (%d) reached" flymake-master-file-count-limit) | ||
| 575 | (setq done t) | ||
| 576 | ) | ||
| 577 | ) | ||
| 578 | (setq file-idx (1+ file-idx)) | ||
| 579 | ) | ||
| 580 | ) | ||
| 581 | (setq masks-idx (1+ masks-idx)) | ||
| 582 | ) | ||
| 583 | ) | ||
| 584 | (setq dir-idx (1+ dir-idx)) | ||
| 585 | ) | ||
| 586 | (when files | ||
| 587 | (setq flymake-included-file-name (file-name-nondirectory file-name)) | ||
| 588 | (setq files (sort files 'flymake-master-file-compare)) | ||
| 589 | (setq flymake-included-file-name nil) | ||
| 590 | ) | ||
| 591 | (flymake-log 3 "found %d possible master file(s)" (length files)) | ||
| 592 | files | ||
| 593 | ) | ||
| 594 | ) | ||
| 595 | |||
| 596 | (defvar flymake-included-file-name nil ; this is used to pass a parameter to a sort predicate below | ||
| 597 | "" | ||
| 598 | ) | ||
| 599 | |||
| 600 | (defun flymake-master-file-compare(file-one file-two) | ||
| 601 | "used in sort to move most possible file names to the beginning of the list (File.h -> File.cpp moved to top" | ||
| 602 | (and (equal (file-name-sans-extension flymake-included-file-name) | ||
| 603 | (file-name-sans-extension (file-name-nondirectory file-one))) | ||
| 604 | (not (equal file-one file-two)) | ||
| 605 | ) | ||
| 606 | ) | ||
| 607 | |||
| 608 | (defcustom flymake-check-file-limit 8192 | ||
| 609 | "max number of chars to look at when checking possible master file" | ||
| 610 | :group 'flymake | ||
| 611 | :type 'integer | ||
| 612 | ) | ||
| 613 | |||
| 614 | (defun flymake-check-patch-master-file-buffer(master-file-temp-buffer | ||
| 615 | master-file-name patched-master-file-name | ||
| 616 | source-file-name patched-source-file-name | ||
| 617 | include-dirs regexp-list) | ||
| 618 | "check whether master-file-name is indeed a master file for source-file-name. | ||
| 619 | For .cpp master file this means it includes source-file-name (.h). | ||
| 620 | If yes, patch a copy of master-file-name to include patched-source-file-name instead of source-file-name. | ||
| 621 | Whenether a buffer for master-file-name exists, use it as a source instead of reading master file from disk" | ||
| 622 | (let* ((found nil) | ||
| 623 | (regexp (format (nth 0 regexp-list) ; "[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" | ||
| 624 | (file-name-nondirectory source-file-name))) | ||
| 625 | (path-idx (nth 1 regexp-list)) | ||
| 626 | (name-idx (nth 2 regexp-list)) | ||
| 627 | (inc-path nil) | ||
| 628 | (inc-name nil) | ||
| 629 | (search-limit flymake-check-file-limit)) | ||
| 630 | (save-excursion | ||
| 631 | (unwind-protect | ||
| 632 | (progn | ||
| 633 | (set-buffer master-file-temp-buffer) | ||
| 634 | (when (> search-limit (point-max)) | ||
| 635 | (setq search-limit (point-max)) | ||
| 636 | ) | ||
| 637 | (flymake-log 3 "checking %s against regexp %s" master-file-name regexp) | ||
| 638 | (goto-char (point-min)) | ||
| 639 | (while (and (< (point) search-limit) (re-search-forward regexp search-limit t)) | ||
| 640 | (let* ((match-beg (match-beginning name-idx)) | ||
| 641 | (match-end (match-end name-idx))) | ||
| 642 | |||
| 643 | (flymake-log 3 "found possible match for %s" (file-name-nondirectory source-file-name)) | ||
| 644 | (setq inc-path (match-string path-idx)) | ||
| 645 | (setq inc-name (match-string name-idx)) | ||
| 646 | (when (string= inc-name (file-name-nondirectory source-file-name)) | ||
| 647 | (flymake-log 3 "inc-path=%s inc-name=%s" inc-path inc-name) | ||
| 648 | (when (flymake-check-include source-file-name inc-path inc-name include-dirs) | ||
| 649 | (setq found t) | ||
| 650 | ; replace-match is not used here as it fails in xemacs with | ||
| 651 | ; 'last match not a buffer' error as check-includes calls replace-in-string | ||
| 652 | (flymake-replace-region (current-buffer) match-beg match-end | ||
| 653 | (file-name-nondirectory patched-source-file-name)) | ||
| 654 | ) | ||
| 655 | ) | ||
| 656 | (forward-line 1) | ||
| 657 | ) | ||
| 658 | ) | ||
| 659 | (when found | ||
| 660 | (flymake-save-buffer-in-file (current-buffer) patched-master-file-name) | ||
| 661 | ) | ||
| 662 | ) | ||
| 663 | ;+(flymake-log 3 "killing buffer %s" (buffer-name master-file-temp-buffer)) | ||
| 664 | (kill-buffer master-file-temp-buffer) | ||
| 665 | ) | ||
| 666 | ) | ||
| 667 | ;+(flymake-log 3 "check-patch master file %s: %s" master-file-name found) | ||
| 668 | (when found | ||
| 669 | (flymake-log 2 "found master file %s" master-file-name) | ||
| 670 | ) | ||
| 671 | found | ||
| 672 | ) | ||
| 673 | ) | ||
| 674 | |||
| 675 | (defun flymake-replace-region(buffer beg end rep) | ||
| 676 | "replace text in buffer in region (beg; end) with rep" | ||
| 677 | (save-excursion | ||
| 678 | (delete-region beg end) | ||
| 679 | (goto-char beg) | ||
| 680 | (insert rep) | ||
| 681 | ) | ||
| 682 | ) | ||
| 683 | |||
| 684 | (defun flymake-read-file-to-temp-buffer(file-name) | ||
| 685 | "isert contents of file-name into newly created temp buffer" | ||
| 686 | (let* ((temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (file-name-nondirectory file-name)))))) | ||
| 687 | (save-excursion | ||
| 688 | (set-buffer temp-buffer) | ||
| 689 | (insert-file-contents file-name) | ||
| 690 | ) | ||
| 691 | temp-buffer | ||
| 692 | ) | ||
| 693 | ) | ||
| 694 | |||
| 695 | (defun flymake-copy-buffer-to-temp-buffer(buffer) | ||
| 696 | "copy contents of buffer into newly created temp buffer" | ||
| 697 | (let ((contents nil) | ||
| 698 | (temp-buffer nil)) | ||
| 699 | (save-excursion | ||
| 700 | (set-buffer buffer) | ||
| 701 | (setq contents (buffer-string)) | ||
| 702 | |||
| 703 | (setq temp-buffer (get-buffer-create (generate-new-buffer-name (concat "flymake:" (buffer-name buffer))))) | ||
| 704 | (set-buffer temp-buffer) | ||
| 705 | (insert contents) | ||
| 706 | ) | ||
| 707 | temp-buffer | ||
| 708 | ) | ||
| 709 | ) | ||
| 710 | |||
| 711 | (defun flymake-check-include(source-file-name inc-path inc-name include-dirs) | ||
| 712 | "t if source-file-name is the one found via include dirs using inc-path and inc-name" | ||
| 713 | (if (file-name-absolute-p inc-path) | ||
| 714 | (flymake-same-files source-file-name (concat inc-path "/" inc-name)) | ||
| 715 | ;else | ||
| 716 | (let* ((count (length include-dirs)) | ||
| 717 | (idx 0) | ||
| 718 | (file-name nil) | ||
| 719 | (found nil)) | ||
| 720 | (while (and (not found) (< idx count)) | ||
| 721 | (setq file-name (concat (file-name-directory source-file-name) "/" (nth idx include-dirs))) | ||
| 722 | (if (> (length inc-path) 0) | ||
| 723 | (setq file-name (concat file-name "/" inc-path)) | ||
| 724 | ) | ||
| 725 | (setq file-name (concat file-name "/" inc-name)) | ||
| 726 | (when (flymake-same-files source-file-name file-name) | ||
| 727 | (setq found t) | ||
| 728 | ) | ||
| 729 | (setq idx (1+ idx)) | ||
| 730 | ) | ||
| 731 | found | ||
| 732 | ) | ||
| 733 | ) | ||
| 734 | ) | ||
| 735 | |||
| 736 | (defun flymake-find-buffer-for-file(file-name) | ||
| 737 | "buffer if there exists a buffer visiting file-name, nil otherwise" | ||
| 738 | (let ((buffer-name (get-file-buffer file-name))) | ||
| 739 | (if buffer-name | ||
| 740 | (get-buffer buffer-name) | ||
| 741 | ) | ||
| 742 | ) | ||
| 743 | ) | ||
| 744 | |||
| 745 | (defun flymake-create-master-file(source-file-name patched-source-file-name get-incl-dirs-f create-temp-f masks include-regexp-list) | ||
| 746 | "save source-file-name with a different name, find master file, patch it and save it to." | ||
| 747 | (let* ((possible-master-files (flymake-find-possible-master-files source-file-name flymake-master-file-dirs masks)) | ||
| 748 | (master-file-count (length possible-master-files)) | ||
| 749 | (idx 0) | ||
| 750 | (temp-buffer nil) | ||
| 751 | (master-file-name nil) | ||
| 752 | (patched-master-file-name nil) | ||
| 753 | (found nil)) | ||
| 754 | |||
| 755 | (while (and (not found) (< idx master-file-count)) | ||
| 756 | (setq master-file-name (nth idx possible-master-files)) | ||
| 757 | (setq patched-master-file-name (funcall create-temp-f master-file-name "flymake_master")) | ||
| 758 | (if (flymake-find-buffer-for-file master-file-name) | ||
| 759 | (setq temp-buffer (flymake-copy-buffer-to-temp-buffer (flymake-find-buffer-for-file master-file-name))) | ||
| 760 | ;else | ||
| 761 | (setq temp-buffer (flymake-read-file-to-temp-buffer master-file-name)) | ||
| 762 | ) | ||
| 763 | (setq found | ||
| 764 | (flymake-check-patch-master-file-buffer | ||
| 765 | temp-buffer | ||
| 766 | master-file-name | ||
| 767 | patched-master-file-name | ||
| 768 | source-file-name | ||
| 769 | patched-source-file-name | ||
| 770 | (funcall get-incl-dirs-f (file-name-directory master-file-name)) | ||
| 771 | include-regexp-list)) | ||
| 772 | (setq idx (1+ idx)) | ||
| 773 | ) | ||
| 774 | (if found | ||
| 775 | (list master-file-name patched-master-file-name) | ||
| 776 | ;else | ||
| 777 | (progn | ||
| 778 | (flymake-log 3 "none of %d master file(s) checked includes %s" master-file-count | ||
| 779 | (file-name-nondirectory source-file-name)) | ||
| 780 | nil | ||
| 781 | ) | ||
| 782 | ) | ||
| 783 | ) | ||
| 784 | ) | ||
| 785 | |||
| 786 | (defun flymake-save-buffer-in-file(buffer file-name) | ||
| 787 | (or buffer | ||
| 788 | (error "invalid buffer") | ||
| 789 | ) | ||
| 790 | (save-excursion | ||
| 791 | (save-restriction | ||
| 792 | (set-buffer buffer) | ||
| 793 | (widen) | ||
| 794 | (make-directory (file-name-directory file-name) 1) | ||
| 795 | (write-region (point-min) (point-max) file-name nil 566) | ||
| 796 | ) | ||
| 797 | ) | ||
| 798 | (flymake-log 3 "saved buffer %s in file %s" (buffer-name buffer) file-name) | ||
| 799 | ) | ||
| 800 | |||
| 801 | (defun flymake-save-string-to-file(file-name data) | ||
| 802 | "save string data to file file-name" | ||
| 803 | (write-region data nil file-name nil 566) | ||
| 804 | ) | ||
| 805 | |||
| 806 | (defun flymake-read-file-to-string(file-name) | ||
| 807 | "read file contents and return them as a string" | ||
| 808 | (with-temp-buffer | ||
| 809 | (insert-file-contents file-name) | ||
| 810 | (buffer-substring (point-min) (point-max)) | ||
| 811 | ) | ||
| 812 | ) | ||
| 813 | |||
| 814 | (defun flymake-process-filter(process output) | ||
| 815 | "flymake process filter: parse output, highlight err lines" | ||
| 816 | (let* ((pid (process-id process)) | ||
| 817 | (source-buffer (get-buffer (flymake-get-source-buffer-name pid)))) | ||
| 818 | |||
| 819 | (flymake-log 3 "received %d byte(s) of output from process %d" (length output) pid) | ||
| 820 | (when source-buffer | ||
| 821 | (flymake-parse-output-and-residual source-buffer output) | ||
| 822 | ) | ||
| 823 | ) | ||
| 824 | ) | ||
| 825 | |||
| 826 | (defun flymake-process-sentinel(process event) | ||
| 827 | "Sentinel for syntax check buffers" | ||
| 828 | (if (memq (process-status process) '(signal exit)) | ||
| 829 | (let*((exit-status (process-exit-status process)) | ||
| 830 | (command (process-command process)) | ||
| 831 | (pid (process-id process)) | ||
| 832 | (source-buffer (get-buffer (flymake-get-source-buffer-name pid))) | ||
| 833 | (cleanup-f (flymake-get-cleanup-function (buffer-file-name source-buffer)))) | ||
| 834 | |||
| 835 | (flymake-log 2 "process %d exited with code %d" pid exit-status) | ||
| 836 | (condition-case err | ||
| 837 | (progn | ||
| 838 | (flymake-log 3 "cleaning up using %s" cleanup-f) | ||
| 839 | (funcall cleanup-f source-buffer) | ||
| 840 | |||
| 841 | (flymake-unreg-names pid) | ||
| 842 | (delete-process process) | ||
| 843 | |||
| 844 | (when source-buffer | ||
| 845 | (save-excursion | ||
| 846 | (set-buffer source-buffer) | ||
| 847 | |||
| 848 | (flymake-parse-residual source-buffer) | ||
| 849 | (flymake-post-syntax-check source-buffer) | ||
| 850 | (flymake-set-buffer-is-running source-buffer nil) | ||
| 851 | ) | ||
| 852 | ) | ||
| 853 | ) | ||
| 854 | (error | ||
| 855 | (let ((err-str (format "Error in process sentinel for buffer %s: %s" | ||
| 856 | source-buffer (error-message-string err)))) | ||
| 857 | (flymake-log 0 err-str) | ||
| 858 | (flymake-set-buffer-is-running source-buffer nil) | ||
| 859 | ) | ||
| 860 | ) | ||
| 861 | ) | ||
| 862 | ) | ||
| 863 | ) | ||
| 864 | ) | ||
| 865 | |||
| 866 | (defun flymake-post-syntax-check(source-buffer) | ||
| 867 | "" | ||
| 868 | (flymake-set-buffer-err-info source-buffer (flymake-get-buffer-new-err-info source-buffer)) | ||
| 869 | (flymake-set-buffer-new-err-info source-buffer nil) | ||
| 870 | |||
| 871 | (flymake-set-buffer-err-info source-buffer (flymake-fix-line-numbers | ||
| 872 | (flymake-get-buffer-err-info source-buffer) | ||
| 873 | 1 | ||
| 874 | (flymake-count-lines source-buffer))) | ||
| 875 | (flymake-delete-own-overlays source-buffer) | ||
| 876 | (flymake-highlight-err-lines source-buffer (flymake-get-buffer-err-info source-buffer)) | ||
| 877 | |||
| 878 | (let ((err-count (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "e")) | ||
| 879 | (warn-count (flymake-get-err-count (flymake-get-buffer-err-info source-buffer) "w"))) | ||
| 880 | |||
| 881 | (flymake-log 2 "%s: %d error(s), %d warning(s) in %.2f second(s)" | ||
| 882 | (buffer-name source-buffer) err-count warn-count | ||
| 883 | (- (flymake-float-time) (flymake-get-buffer-check-start-time source-buffer))) | ||
| 884 | (flymake-set-buffer-check-start-time source-buffer nil) | ||
| 885 | (if (and (equal 0 err-count) (equal 0 warn-count)) | ||
| 886 | (if (equal 0 exit-status) | ||
| 887 | (flymake-report-status source-buffer "" "") ; PASSED | ||
| 888 | ;else | ||
| 889 | (if (not (flymake-get-buffer-check-was-interrupted source-buffer)) | ||
| 890 | (flymake-report-fatal-status (current-buffer) "CFGERR" | ||
| 891 | (format "Configuration error has occured while running %s" command)) | ||
| 892 | ;else | ||
| 893 | (flymake-report-status source-buffer nil "") ; "STOPPED" | ||
| 894 | ) | ||
| 895 | ) | ||
| 896 | ;else | ||
| 897 | (flymake-report-status source-buffer (format "%d/%d" err-count warn-count) "") | ||
| 898 | ) | ||
| 899 | ) | ||
| 900 | ) | ||
| 901 | |||
| 902 | (defun flymake-parse-output-and-residual(source-buffer output) | ||
| 903 | "split output into lines, merge in residual if necessary" | ||
| 904 | (save-excursion | ||
| 905 | (set-buffer source-buffer) | ||
| 906 | (let* ((buffer-residual (flymake-get-buffer-output-residual source-buffer)) | ||
| 907 | (total-output (if buffer-residual (concat buffer-residual output) output)) | ||
| 908 | (lines-and-residual (flymake-split-output total-output)) | ||
| 909 | (lines (nth 0 lines-and-residual)) | ||
| 910 | (new-residual (nth 1 lines-and-residual))) | ||
| 911 | |||
| 912 | (flymake-set-buffer-output-residual source-buffer new-residual) | ||
| 913 | (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines | ||
| 914 | (flymake-get-buffer-new-err-info source-buffer) | ||
| 915 | source-buffer lines)) | ||
| 916 | ) | ||
| 917 | ) | ||
| 918 | ) | ||
| 919 | |||
| 920 | (defun flymake-parse-residual(source-buffer) | ||
| 921 | "parse residual if it's non empty" | ||
| 922 | (save-excursion | ||
| 923 | (set-buffer source-buffer) | ||
| 924 | (when (flymake-get-buffer-output-residual source-buffer) | ||
| 925 | (flymake-set-buffer-new-err-info source-buffer (flymake-parse-err-lines | ||
| 926 | (flymake-get-buffer-new-err-info source-buffer) | ||
| 927 | source-buffer | ||
| 928 | (list (flymake-get-buffer-output-residual source-buffer)))) | ||
| 929 | (flymake-set-buffer-output-residual source-buffer nil) | ||
| 930 | ) | ||
| 931 | ) | ||
| 932 | ) | ||
| 933 | |||
| 934 | (defvar flymake-err-info nil | ||
| 935 | "sorted list of line numbers and lists of err info in the form (file, err-text)." | ||
| 936 | ) | ||
| 937 | (make-variable-buffer-local 'flymake-err-info) | ||
| 938 | (defun flymake-get-buffer-err-info(buffer) | ||
| 939 | (flymake-get-buffer-var buffer 'flymake-err-info) | ||
| 940 | ) | ||
| 941 | (defun flymake-set-buffer-err-info(buffer err-info) | ||
| 942 | (flymake-set-buffer-var buffer 'flymake-err-info err-info) | ||
| 943 | ) | ||
| 944 | (defun flymake-er-make-er(line-no line-err-info-list) | ||
| 945 | (list line-no line-err-info-list) | ||
| 946 | ) | ||
| 947 | (defun flymake-er-get-line(err-info) | ||
| 948 | (nth 0 err-info) | ||
| 949 | ) | ||
| 950 | (defun flymake-er-get-line-err-info-list(err-info) | ||
| 951 | (nth 1 err-info) | ||
| 952 | ) | ||
| 953 | |||
| 954 | (defvar flymake-new-err-info nil | ||
| 955 | "the same as flymake -err-info, effective when a syntax check is in progress" | ||
| 956 | ) | ||
| 957 | (make-variable-buffer-local 'flymake-new-err-info) | ||
| 958 | (defun flymake-get-buffer-new-err-info(buffer) | ||
| 959 | (flymake-get-buffer-var buffer 'flymake-new-err-info) | ||
| 960 | ) | ||
| 961 | (defun flymake-set-buffer-new-err-info(buffer new-err-info) | ||
| 962 | (flymake-set-buffer-var buffer 'flymake-new-err-info new-err-info) | ||
| 963 | ) | ||
| 964 | |||
| 965 | ;; getters/setters for line-err-info: (file, line, type, text). | ||
| 966 | (defun flymake-ler-make-ler(file line type text &optional full-file) | ||
| 967 | (list file line type text full-file) | ||
| 968 | ) | ||
| 969 | (defun flymake-ler-get-file(line-err-info) | ||
| 970 | (nth 0 line-err-info) | ||
| 971 | ) | ||
| 972 | (defun flymake-ler-get-line(line-err-info) | ||
| 973 | (nth 1 line-err-info) | ||
| 974 | ) | ||
| 975 | (defun flymake-ler-get-type(line-err-info) | ||
| 976 | (nth 2 line-err-info) | ||
| 977 | ) | ||
| 978 | (defun flymake-ler-get-text(line-err-info) | ||
| 979 | (nth 3 line-err-info) | ||
| 980 | ) | ||
| 981 | (defun flymake-ler-get-full-file(line-err-info) | ||
| 982 | (nth 4 line-err-info) | ||
| 983 | ) | ||
| 984 | (defun flymake-ler-set-file(line-err-info file) | ||
| 985 | (flymake-ler-make-ler file | ||
| 986 | (flymake-ler-get-line line-err-info) | ||
| 987 | (flymake-ler-get-type line-err-info) | ||
| 988 | (flymake-ler-get-text line-err-info) | ||
| 989 | (flymake-ler-get-full-file line-err-info)) | ||
| 990 | ) | ||
| 991 | (defun flymake-ler-set-full-file(line-err-info full-file) | ||
| 992 | (flymake-ler-make-ler (flymake-ler-get-file line-err-info) | ||
| 993 | (flymake-ler-get-line line-err-info) | ||
| 994 | (flymake-ler-get-type line-err-info) | ||
| 995 | (flymake-ler-get-text line-err-info) | ||
| 996 | full-file) | ||
| 997 | ) | ||
| 998 | (defun flymake-ler-set-line(line-err-info line) | ||
| 999 | (flymake-ler-make-ler (flymake-ler-get-file line-err-info) | ||
| 1000 | line | ||
| 1001 | (flymake-ler-get-type line-err-info) | ||
| 1002 | (flymake-ler-get-text line-err-info) | ||
| 1003 | (flymake-ler-get-full-file line-err-info)) | ||
| 1004 | ) | ||
| 1005 | |||
| 1006 | (defun flymake-get-line-err-count(line-err-info-list type) | ||
| 1007 | "return number of errors of specified type - e or w" | ||
| 1008 | (let* ((idx 0) | ||
| 1009 | (count (length line-err-info-list)) | ||
| 1010 | (err-count 0)) | ||
| 1011 | |||
| 1012 | (while (< idx count) | ||
| 1013 | (when (equal type (flymake-ler-get-type (nth idx line-err-info-list))) | ||
| 1014 | (setq err-count (1+ err-count)) | ||
| 1015 | ) | ||
| 1016 | (setq idx (1+ idx)) | ||
| 1017 | ) | ||
| 1018 | err-count | ||
| 1019 | ) | ||
| 1020 | ) | ||
| 1021 | |||
| 1022 | (defun flymake-get-err-count(err-info-list type) | ||
| 1023 | "return number of errors of specified type for the err-info-list" | ||
| 1024 | (let* ((idx 0) | ||
| 1025 | (count (length err-info-list)) | ||
| 1026 | (err-count 0)) | ||
| 1027 | (while (< idx count) | ||
| 1028 | (setq err-count (+ err-count (flymake-get-line-err-count (nth 1 (nth idx err-info-list)) type))) | ||
| 1029 | (setq idx (1+ idx)) | ||
| 1030 | ) | ||
| 1031 | err-count | ||
| 1032 | ) | ||
| 1033 | ) | ||
| 1034 | |||
| 1035 | (defun flymake-fix-line-numbers(err-info-list min-line max-line) | ||
| 1036 | "replace line-numbers < min-line with min-line and > max-line with max-line - as some compilers might report line number outside the file being compiled" | ||
| 1037 | (let* ((count (length err-info-list)) | ||
| 1038 | (err-info nil) | ||
| 1039 | (line 0)) | ||
| 1040 | (while (> count 0) | ||
| 1041 | (setq err-info (nth (1- count) err-info-list)) | ||
| 1042 | (setq line (flymake-er-get-line err-info)) | ||
| 1043 | (when (or (< line min-line) (> line max-line)) | ||
| 1044 | (setq line (if (< line min-line) min-line max-line)) | ||
| 1045 | (setq err-info-list (flymake-set-at err-info-list (1- count) | ||
| 1046 | (flymake-er-make-er line | ||
| 1047 | (flymake-er-get-line-err-info-list err-info)))) | ||
| 1048 | ) | ||
| 1049 | (setq count (1- count)) | ||
| 1050 | ) | ||
| 1051 | ) | ||
| 1052 | err-info-list | ||
| 1053 | ) | ||
| 1054 | |||
| 1055 | (defun flymake-highlight-err-lines(buffer err-info-list) | ||
| 1056 | "highlight err-lines in buffer using info from err-info-list" | ||
| 1057 | (save-excursion | ||
| 1058 | (set-buffer buffer) | ||
| 1059 | (let* ((idx 0) | ||
| 1060 | (count (length err-info-list))) | ||
| 1061 | (while (< idx count) | ||
| 1062 | (flymake-highlight-line (car (nth idx err-info-list)) (nth 1 (nth idx err-info-list))) | ||
| 1063 | (setq idx (1+ idx)) | ||
| 1064 | ) | ||
| 1065 | ) | ||
| 1066 | ) | ||
| 1067 | ) | ||
| 1068 | |||
| 1069 | (defun flymake-overlay-p(ov) | ||
| 1070 | "Determine whether overlay was created by flymake" | ||
| 1071 | (and (overlayp ov) (overlay-get ov 'flymake-overlay)) | ||
| 1072 | ) | ||
| 1073 | |||
| 1074 | (defun flymake-make-overlay(beg end tooltip-text face mouse-face) | ||
| 1075 | "Allocate a flymake overlay in range beg end" | ||
| 1076 | (when (not (flymake-region-has-flymake-overlays beg end)) | ||
| 1077 | (let ((ov (make-overlay beg end nil t t))) | ||
| 1078 | (overlay-put ov 'face face) | ||
| 1079 | (overlay-put ov 'mouse-face mouse-face) | ||
| 1080 | (overlay-put ov 'help-echo tooltip-text) | ||
| 1081 | (overlay-put ov 'flymake-overlay t) | ||
| 1082 | (overlay-put ov 'priority 100) | ||
| 1083 | ;+(flymake-log 3 "created overlay %s" ov) | ||
| 1084 | ov | ||
| 1085 | ) | ||
| 1086 | (flymake-log 3 "created an overlay at (%d-%d)" beg end) | ||
| 1087 | ) | ||
| 1088 | ) | ||
| 1089 | |||
| 1090 | (defun flymake-delete-own-overlays(buffer) | ||
| 1091 | "Delete all flymake overlays in buffer" | ||
| 1092 | (save-excursion | ||
| 1093 | (set-buffer buffer) | ||
| 1094 | (let ((ov (overlays-in (point-min) (point-max)))) | ||
| 1095 | (while (consp ov) | ||
| 1096 | (when (flymake-overlay-p (car ov)) | ||
| 1097 | (delete-overlay (car ov)) | ||
| 1098 | ;+(flymake-log 3 "deleted overlay %s" ov) | ||
| 1099 | ) | ||
| 1100 | (setq ov (cdr ov)) | ||
| 1101 | ) | ||
| 1102 | ) | ||
| 1103 | ) | ||
| 1104 | ) | ||
| 1105 | |||
| 1106 | (defun flymake-region-has-flymake-overlays(beg end) | ||
| 1107 | "t if specified regions has at least one flymake overlay, nil otrherwise" | ||
| 1108 | (let ((ov (overlays-in beg end)) | ||
| 1109 | (has-flymake-overlays nil)) | ||
| 1110 | (while (consp ov) | ||
| 1111 | (when (flymake-overlay-p (car ov)) | ||
| 1112 | (setq has-flymake-overlays t) | ||
| 1113 | ) | ||
| 1114 | (setq ov (cdr ov)) | ||
| 1115 | ) | ||
| 1116 | ) | ||
| 1117 | ) | ||
| 1118 | |||
| 1119 | (defface flymake-errline-face | ||
| 1120 | ;+ '((((class color)) (:foreground "OrangeRed" :bold t :underline t)) | ||
| 1121 | ;+ '((((class color)) (:underline "OrangeRed")) | ||
| 1122 | '((((class color)) (:background "LightPink")) | ||
| 1123 | (t (:bold t))) | ||
| 1124 | "Face used for marking error lines" | ||
| 1125 | :group 'flymake | ||
| 1126 | ) | ||
| 1127 | |||
| 1128 | (defface flymake-warnline-face | ||
| 1129 | '((((class color)) (:background "LightBlue2")) | ||
| 1130 | (t (:bold t))) | ||
| 1131 | "Face used for marking warning lines" | ||
| 1132 | :group 'flymake | ||
| 1133 | ) | ||
| 1134 | |||
| 1135 | |||
| 1136 | (defun flymake-highlight-line(line-no line-err-info-list) | ||
| 1137 | "highlight line line-no in current buffer, perhaps use text from line-err-info-list to enhance highlighting" | ||
| 1138 | (goto-line line-no) | ||
| 1139 | (let* ((line-beg (flymake-line-beginning-position)) | ||
| 1140 | (line-end (flymake-line-end-position)) | ||
| 1141 | (beg line-beg) | ||
| 1142 | (end line-end) | ||
| 1143 | (tooltip-text (flymake-ler-get-text (nth 0 line-err-info-list))) | ||
| 1144 | (face nil)) | ||
| 1145 | |||
| 1146 | (goto-char line-beg) | ||
| 1147 | (while (looking-at "[ \t]") | ||
| 1148 | (forward-char) | ||
| 1149 | ) | ||
| 1150 | |||
| 1151 | (setq beg (point)) | ||
| 1152 | |||
| 1153 | (goto-char line-end) | ||
| 1154 | (while (and (looking-at "[ \t\r\n]") (> (point) 1)) | ||
| 1155 | (backward-char) | ||
| 1156 | ) | ||
| 1157 | |||
| 1158 | (setq end (1+ (point))) | ||
| 1159 | |||
| 1160 | (when (<= end beg) | ||
| 1161 | (setq beg line-beg) | ||
| 1162 | (setq end line-end) | ||
| 1163 | ) | ||
| 1164 | (when (= end beg) | ||
| 1165 | (goto-char end) | ||
| 1166 | (forward-line) | ||
| 1167 | (setq end (point)) | ||
| 1168 | ) | ||
| 1169 | (if (> (flymake-get-line-err-count line-err-info-list "e") 0) | ||
| 1170 | (setq face 'flymake-errline-face) | ||
| 1171 | ;else | ||
| 1172 | (setq face 'flymake-warnline-face) | ||
| 1173 | ) | ||
| 1174 | (flymake-make-overlay beg end tooltip-text face nil) | ||
| 1175 | ) | ||
| 1176 | ) | ||
| 1177 | |||
| 1178 | (defun flymake-parse-err-lines(err-info-list source-buffer lines) | ||
| 1179 | "parse err lines, store info in err-info-list" | ||
| 1180 | (let* ((count (length lines)) | ||
| 1181 | (idx 0) | ||
| 1182 | (line-err-info nil) | ||
| 1183 | (real-file-name nil) | ||
| 1184 | (source-file-name (buffer-file-name source-buffer)) | ||
| 1185 | (get-real-file-name-f (flymake-get-real-file-name-function source-file-name))) | ||
| 1186 | |||
| 1187 | (while (< idx count) | ||
| 1188 | (setq line-err-info (flymake-parse-line (nth idx lines))) | ||
| 1189 | (when line-err-info | ||
| 1190 | (setq real-file-name (funcall get-real-file-name-f source-buffer (flymake-ler-get-file line-err-info))) | ||
| 1191 | (setq line-err-info (flymake-ler-set-full-file line-err-info real-file-name)) | ||
| 1192 | |||
| 1193 | (if (flymake-same-files real-file-name source-file-name) | ||
| 1194 | (setq line-err-info (flymake-ler-set-file line-err-info nil)) | ||
| 1195 | ;else | ||
| 1196 | (setq line-err-info (flymake-ler-set-file line-err-info (file-name-nondirectory real-file-name))) | ||
| 1197 | ) | ||
| 1198 | |||
| 1199 | (setq err-info-list (flymake-add-err-info err-info-list line-err-info)) | ||
| 1200 | ) | ||
| 1201 | (flymake-log 3 "parsed '%s', %s line-err-info" (nth idx lines) (if line-err-info "got" "no")) | ||
| 1202 | (setq idx (1+ idx)) | ||
| 1203 | ) | ||
| 1204 | err-info-list | ||
| 1205 | ) | ||
| 1206 | ) | ||
| 1207 | |||
| 1208 | (defun flymake-split-output(output) | ||
| 1209 | "split output into lines, return last one as residual if it does not end with newline char. Returns ((lines) residual)" | ||
| 1210 | (when (and output (> (length output) 0)) | ||
| 1211 | (let* ((lines (flymake-split-string output "[\n\r]+")) | ||
| 1212 | (complete (equal "\n" (char-to-string (aref output (1- (length output)))))) | ||
| 1213 | (residual nil)) | ||
| 1214 | (when (not complete) | ||
| 1215 | (setq residual (car (last lines))) | ||
| 1216 | (setq lines (butlast lines)) | ||
| 1217 | ) | ||
| 1218 | (list lines residual) | ||
| 1219 | ) | ||
| 1220 | ) | ||
| 1221 | ) | ||
| 1222 | |||
| 1223 | (eval-when-compile (require 'compile)) | ||
| 1224 | (defvar flymake-err-line-patterns ; regexp file-idx line-idx col-idx (optional) text-idx(optional), match-end to end of string is error text | ||
| 1225 | (append | ||
| 1226 | '( | ||
| 1227 | ; MS Visual C++ 6.0 | ||
| 1228 | ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | ||
| 1229 | 1 3 nil 4) | ||
| 1230 | ; jikes | ||
| 1231 | ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\|Semantic Error\\):[ \t\n]*\\(.+\\)\\)" | ||
| 1232 | 1 3 nil 4) | ||
| 1233 | ; MS midl | ||
| 1234 | ("midl[ ]*:[ ]*\\(command line error .*\\)" | ||
| 1235 | nil nil nil 1) | ||
| 1236 | ; MS C# | ||
| 1237 | ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\),[0-9]+)\: \\(\\(error\\|warning\\|fatal error\\) \\(CS[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | ||
| 1238 | 1 3 nil 4) | ||
| 1239 | ; perl | ||
| 1240 | ("\\(.*\\) at \\([^ \n]+\\) line \\([0-9]+\\)[,.\n]" 2 3 nil 1) | ||
| 1241 | ; LaTeX warnings (fileless) ("\\(LaTeX \\(Warning\\|Error\\): .*\\) on input line \\([0-9]+\\)" 20 3 nil 1) | ||
| 1242 | ; ant/javac | ||
| 1243 | (" *\\(\\[javac\\]\\)? *\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[ \t\n]*\\(.+\\)" | ||
| 1244 | 2 4 nil 5) | ||
| 1245 | ) | ||
| 1246 | compilation-error-regexp-alist) | ||
| 1247 | "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx)" | ||
| 1248 | ) | ||
| 1249 | ;(defcustom flymake-err-line-patterns | ||
| 1250 | ; '( | ||
| 1251 | ; ; MS Visual C++ 6.0 | ||
| 1252 | ; ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)(\\([0-9]+\\)) \: \\(\\(error\\|warning\\|fatal error\\) \\(C[0-9]+\\):[ \t\n]*\\(.+\\)\\)" | ||
| 1253 | ; 1 3 4) | ||
| 1254 | ; ; jikes | ||
| 1255 | ; ("\\(\\([a-zA-Z]:\\)?[^:(\t\n]+\\)\:\\([0-9]+\\)\:[0-9]+\:[0-9]+\:[0-9]+\: \\(\\(Error\\|Warning\\|Caution\\):[ \t\n]*\\(.+\\)\\)" | ||
| 1256 | ; 1 3 4)) | ||
| 1257 | ; "patterns for matching error/warning lines, (regexp file-idx line-idx err-text-idx)" | ||
| 1258 | ; :group 'flymake | ||
| 1259 | ; :type '(repeat (string number number number)) | ||
| 1260 | ;) | ||
| 1261 | |||
| 1262 | (defun flymake-parse-line(line) | ||
| 1263 | "parse line to see whether it's an error of warning, return it's components or nil for no match" | ||
| 1264 | (let ((raw-file-name nil) | ||
| 1265 | (line-no 0) | ||
| 1266 | (err-type "e") | ||
| 1267 | (err-text nil) | ||
| 1268 | (count (length flymake-err-line-patterns)) | ||
| 1269 | (idx 0) | ||
| 1270 | (matched nil)) | ||
| 1271 | (while (and (< idx count) (not matched)) | ||
| 1272 | (when (string-match (car (nth idx flymake-err-line-patterns)) line) | ||
| 1273 | (let* ((file-idx (nth 1 (nth idx flymake-err-line-patterns))) | ||
| 1274 | (line-idx (nth 2 (nth idx flymake-err-line-patterns)))) | ||
| 1275 | |||
| 1276 | (setq raw-file-name (if file-idx (match-string file-idx line) nil)) | ||
| 1277 | (setq line-no (if line-idx (string-to-int (match-string line-idx line)) 0)) | ||
| 1278 | (setq err-text (if (> (length (nth idx flymake-err-line-patterns)) 4) | ||
| 1279 | (match-string (nth 4 (nth idx flymake-err-line-patterns)) line) | ||
| 1280 | (flymake-patch-err-text (substring line (match-end 0))))) | ||
| 1281 | (or err-text (setq err-text "<no error text>")) | ||
| 1282 | (if (and err-text (string-match "^[wW]arning" err-text)) | ||
| 1283 | (setq err-type "w") | ||
| 1284 | ) | ||
| 1285 | (flymake-log 3 "parse line: file-idx=%s line-idx=%s file=%s line=%s text=%s" file-idx line-idx | ||
| 1286 | raw-file-name line-no err-text) | ||
| 1287 | (setq matched t) | ||
| 1288 | ) | ||
| 1289 | ) | ||
| 1290 | (setq idx (1+ idx)) | ||
| 1291 | ) | ||
| 1292 | (if matched | ||
| 1293 | (flymake-ler-make-ler raw-file-name line-no err-type err-text) | ||
| 1294 | ; else | ||
| 1295 | () | ||
| 1296 | ) | ||
| 1297 | ) | ||
| 1298 | ) | ||
| 1299 | |||
| 1300 | (defun flymake-find-err-info(err-info-list line-no) | ||
| 1301 | "find (line-err-info-list pos) for specified line-no" | ||
| 1302 | (if err-info-list | ||
| 1303 | (let* ((line-err-info-list nil) | ||
| 1304 | (pos 0) | ||
| 1305 | (count (length err-info-list))) | ||
| 1306 | |||
| 1307 | (while (and (< pos count) (< (car (nth pos err-info-list)) line-no)) | ||
| 1308 | (setq pos (1+ pos)) | ||
| 1309 | ) | ||
| 1310 | (when (and (< pos count) (equal (car (nth pos err-info-list)) line-no)) | ||
| 1311 | (setq line-err-info-list (flymake-er-get-line-err-info-list (nth pos err-info-list))) | ||
| 1312 | ) | ||
| 1313 | (list line-err-info-list pos) | ||
| 1314 | ) | ||
| 1315 | ;else | ||
| 1316 | '(nil 0) | ||
| 1317 | ) | ||
| 1318 | ) | ||
| 1319 | |||
| 1320 | (defun flymake-line-err-info-is-less-or-equal(line-one line-two) | ||
| 1321 | (or (string< (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | ||
| 1322 | (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | ||
| 1323 | (not (flymake-ler-get-file line-one)) (flymake-ler-get-file line-two) | ||
| 1324 | ) | ||
| 1325 | (and (string= (flymake-ler-get-type line-one) (flymake-ler-get-type line-two)) | ||
| 1326 | (or (and (flymake-ler-get-file line-one) (flymake-ler-get-file line-two)) | ||
| 1327 | (and (not (flymake-ler-get-file line-one)) (not (flymake-ler-get-file line-two))) | ||
| 1328 | ) | ||
| 1329 | ) | ||
| 1330 | ) | ||
| 1331 | ) | ||
| 1332 | |||
| 1333 | (defun flymake-add-line-err-info(line-err-info-list line-err-info) | ||
| 1334 | "insert new err info favoring sorting: err-type e/w, filename nil/non-nill" | ||
| 1335 | (if (not line-err-info-list) | ||
| 1336 | (list line-err-info) | ||
| 1337 | ;else | ||
| 1338 | (let* ((count (length line-err-info-list)) | ||
| 1339 | (idx 0)) | ||
| 1340 | (while (and (< idx count) (flymake-line-err-info-is-less-or-equal (nth idx line-err-info-list) line-err-info)) | ||
| 1341 | (setq idx (1+ idx)) | ||
| 1342 | ) | ||
| 1343 | (cond ((equal 0 idx) (setq line-err-info-list (cons line-err-info line-err-info-list))) | ||
| 1344 | (t (setq line-err-info-list (flymake-ins-after line-err-info-list (1- idx) line-err-info))) | ||
| 1345 | ) | ||
| 1346 | line-err-info-list | ||
| 1347 | ) | ||
| 1348 | ) | ||
| 1349 | ) | ||
| 1350 | |||
| 1351 | (defun flymake-add-err-info(err-info-list line-err-info) | ||
| 1352 | "add error info (file line type text) to err info list preserving sort order" | ||
| 1353 | (let* ((count (length err-info-list)) | ||
| 1354 | (line-no (if (flymake-ler-get-file line-err-info) 1 (flymake-ler-get-line line-err-info))) | ||
| 1355 | (info-and-pos (flymake-find-err-info err-info-list line-no)) | ||
| 1356 | (exists (car info-and-pos)) | ||
| 1357 | (pos (nth 1 info-and-pos)) | ||
| 1358 | (line-err-info-list nil) | ||
| 1359 | (err-info nil)) | ||
| 1360 | |||
| 1361 | (if exists | ||
| 1362 | (setq line-err-info-list (flymake-er-get-line-err-info-list (car (nthcdr pos err-info-list)))) | ||
| 1363 | ) | ||
| 1364 | (setq line-err-info-list (flymake-add-line-err-info line-err-info-list line-err-info)) | ||
| 1365 | |||
| 1366 | (setq err-info (flymake-er-make-er line-no line-err-info-list)) | ||
| 1367 | (cond (exists (setq err-info-list (flymake-set-at err-info-list pos err-info))) | ||
| 1368 | ((equal 0 pos) (setq err-info-list (cons err-info err-info-list))) | ||
| 1369 | (t (setq err-info-list (flymake-ins-after err-info-list (1- pos) err-info))) | ||
| 1370 | ) | ||
| 1371 | err-info-list | ||
| 1372 | ) | ||
| 1373 | ) | ||
| 1374 | |||
| 1375 | (defun flymake-get-project-include-dirs-imp(basedir) | ||
| 1376 | "include dirs for the project current file belongs to" | ||
| 1377 | (if (flymake-get-project-include-dirs-from-cache basedir) | ||
| 1378 | (progn | ||
| 1379 | (flymake-get-project-include-dirs-from-cache basedir) | ||
| 1380 | ) | ||
| 1381 | ;else | ||
| 1382 | (let* ((command-line (concat "make -C\"" basedir "\" DUMPVARS=INCLUDE_DIRS dumpvars")) | ||
| 1383 | (output (shell-command-to-string command-line)) | ||
| 1384 | (lines (flymake-split-string output "\n")) | ||
| 1385 | (count (length lines)) | ||
| 1386 | (idx 0) | ||
| 1387 | (inc-dirs nil)) | ||
| 1388 | (while (and (< idx count) (not (string-match "^INCLUDE_DIRS=.*" (nth idx lines)))) | ||
| 1389 | (setq idx (1+ idx)) | ||
| 1390 | ) | ||
| 1391 | (when (< idx count) | ||
| 1392 | (let* ((inc-lines (flymake-split-string (nth idx lines) " *-I")) | ||
| 1393 | (inc-count (length inc-lines))) | ||
| 1394 | (while (> inc-count 0) | ||
| 1395 | (when (not (string-match "^INCLUDE_DIRS=.*" (nth (1- inc-count) inc-lines))) | ||
| 1396 | (setq inc-dirs (cons (flymake-replace-regexp-in-string "\"" "" (nth (1- inc-count) inc-lines)) inc-dirs)) | ||
| 1397 | ) | ||
| 1398 | (setq inc-count (1- inc-count)) | ||
| 1399 | ) | ||
| 1400 | ) | ||
| 1401 | ) | ||
| 1402 | (flymake-add-project-include-dirs-to-cache basedir inc-dirs) | ||
| 1403 | inc-dirs | ||
| 1404 | ) | ||
| 1405 | ) | ||
| 1406 | ) | ||
| 1407 | |||
| 1408 | (defcustom flymake-get-project-include-dirs-function 'flymake-get-project-include-dirs-imp | ||
| 1409 | "function used to get project inc dirs, one paramater: basedir name" | ||
| 1410 | :group 'flymake | ||
| 1411 | :type 'function | ||
| 1412 | ) | ||
| 1413 | |||
| 1414 | (defun flymake-get-project-include-dirs(basedir) | ||
| 1415 | (funcall flymake-get-project-include-dirs-function basedir) | ||
| 1416 | ) | ||
| 1417 | |||
| 1418 | (defun flymake-get-system-include-dirs() | ||
| 1419 | "system include dirs - from the 'INCLUDE' env setting" | ||
| 1420 | (let* ((includes (getenv "INCLUDE"))) | ||
| 1421 | (if includes (flymake-split-string includes path-separator) nil) | ||
| 1422 | ) | ||
| 1423 | ) | ||
| 1424 | |||
| 1425 | (defvar flymake-project-include-dirs-cache (flymake-makehash 'equal)) | ||
| 1426 | (defun flymake-get-project-include-dirs-from-cache(base-dir) | ||
| 1427 | (gethash base-dir flymake-project-include-dirs-cache) | ||
| 1428 | ) | ||
| 1429 | (defun flymake-add-project-include-dirs-to-cache(base-dir include-dirs) | ||
| 1430 | (puthash base-dir include-dirs flymake-project-include-dirs-cache) | ||
| 1431 | ) | ||
| 1432 | (defun flymake-clear-project-include-dirs-cache() | ||
| 1433 | (clrhash flymake-project-include-dirs-cache) | ||
| 1434 | ) | ||
| 1435 | |||
| 1436 | (defun flymake-get-include-dirs(base-dir) | ||
| 1437 | "dirs to use when resolving local filenames" | ||
| 1438 | (let* ((include-dirs (append '(".") (flymake-get-project-include-dirs base-dir) (flymake-get-system-include-dirs)))) | ||
| 1439 | include-dirs | ||
| 1440 | ) | ||
| 1441 | ) | ||
| 1442 | |||
| 1443 | (defun flymake-find-file(rel-file-name include-dirs) | ||
| 1444 | "iterate through include-dirs, return first 'include-dir/rel-file-name' that exists, or just rel-file-name if not" | ||
| 1445 | (let* ((count (length include-dirs)) | ||
| 1446 | (idx 0) | ||
| 1447 | (found nil) | ||
| 1448 | (full-file-name rel-file-name)) | ||
| 1449 | |||
| 1450 | (while (and (not found) (< idx count)) | ||
| 1451 | (let* ((dir (nth idx include-dirs))) | ||
| 1452 | (setq full-file-name (concat dir "/" rel-file-name)) | ||
| 1453 | (when (file-exists-p full-file-name) | ||
| 1454 | (setq done t) | ||
| 1455 | ) | ||
| 1456 | ) | ||
| 1457 | (setq idx (1+ idx)) | ||
| 1458 | ) | ||
| 1459 | (if found | ||
| 1460 | full-file-name | ||
| 1461 | ;else | ||
| 1462 | rel-file-name | ||
| 1463 | ) | ||
| 1464 | ) | ||
| 1465 | ) | ||
| 1466 | |||
| 1467 | (defun flymake-restore-formatting(source-buffer) | ||
| 1468 | "Remove any formatting made by flymake" | ||
| 1469 | ) | ||
| 1470 | |||
| 1471 | (defun flymake-get-program-dir(buffer) | ||
| 1472 | "dir to start profram in" | ||
| 1473 | (unless (bufferp buffer) | ||
| 1474 | (error "invlid buffer") | ||
| 1475 | ) | ||
| 1476 | (save-excursion | ||
| 1477 | (set-buffer buffer) | ||
| 1478 | default-directory | ||
| 1479 | ) | ||
| 1480 | ) | ||
| 1481 | |||
| 1482 | (defun flymake-safe-delete-file(file-name) | ||
| 1483 | (when (and file-name (file-exists-p file-name)) | ||
| 1484 | (delete-file file-name) | ||
| 1485 | (flymake-log 1 "deleted file %s" file-name) | ||
| 1486 | ) | ||
| 1487 | ) | ||
| 1488 | |||
| 1489 | (defun flymake-safe-delete-directory(dir-name) | ||
| 1490 | (condition-case err | ||
| 1491 | (progn | ||
| 1492 | (delete-directory dir-name) | ||
| 1493 | (flymake-log 1 "deleted dir %s" dir-name) | ||
| 1494 | ) | ||
| 1495 | (error | ||
| 1496 | (flymake-log 1 "failed to delete dir %s, error ignored" dir-name) | ||
| 1497 | ) | ||
| 1498 | ) | ||
| 1499 | ) | ||
| 1500 | |||
| 1501 | (defcustom flymake-compilation-prevents-syntax-check t | ||
| 1502 | "if non-nil, syntax check won't be started in case compilation is running" | ||
| 1503 | :group 'flymake | ||
| 1504 | :type 'boolean | ||
| 1505 | ) | ||
| 1506 | |||
| 1507 | (defun flymake-start-syntax-check(buffer) | ||
| 1508 | "start syntax checking for buffer" | ||
| 1509 | (unless (bufferp buffer) | ||
| 1510 | (error "expected a buffer") | ||
| 1511 | ) | ||
| 1512 | (save-excursion | ||
| 1513 | (set-buffer buffer) | ||
| 1514 | (flymake-log 3 "flymake is running: %s" (flymake-get-buffer-is-running buffer)) | ||
| 1515 | (when (and (not (flymake-get-buffer-is-running buffer)) | ||
| 1516 | (flymake-can-syntax-check-file (buffer-file-name buffer))) | ||
| 1517 | (when (or (not flymake-compilation-prevents-syntax-check) | ||
| 1518 | (not (flymake-compilation-is-running))) ;+ (flymake-rep-ort-status buffer "COMP") | ||
| 1519 | (flymake-clear-buildfile-cache) | ||
| 1520 | (flymake-clear-project-include-dirs-cache) | ||
| 1521 | |||
| 1522 | (flymake-set-buffer-check-was-interrupted buffer nil) | ||
| 1523 | (flymake-set-buffer-data buffer (flymake-makehash 'equal)) | ||
| 1524 | |||
| 1525 | (let* ((source-file-name (buffer-file-name buffer)) | ||
| 1526 | (init-f (flymake-get-init-function source-file-name)) | ||
| 1527 | (cleanup-f (flymake-get-cleanup-function source-file-name)) | ||
| 1528 | (cmd-and-args (funcall init-f buffer)) | ||
| 1529 | (cmd (nth 0 cmd-and-args)) | ||
| 1530 | (args (nth 1 cmd-and-args)) | ||
| 1531 | (dir (nth 2 cmd-and-args))) | ||
| 1532 | (if (not cmd-and-args) | ||
| 1533 | (progn | ||
| 1534 | (flymake-log 0 "init function %s for %s failed, cleaning up" init-f source-file-name) | ||
| 1535 | (funcall cleanup-f buffer) | ||
| 1536 | ) | ||
| 1537 | ;else | ||
| 1538 | (progn | ||
| 1539 | (flymake-set-buffer-last-change-time buffer nil) | ||
| 1540 | (flymake-start-syntax-check-process buffer cmd args dir) | ||
| 1541 | ) | ||
| 1542 | ) | ||
| 1543 | ) | ||
| 1544 | ) | ||
| 1545 | ) | ||
| 1546 | ) | ||
| 1547 | ) | ||
| 1548 | |||
| 1549 | (defun flymake-start-syntax-check-process(buffer cmd args dir) | ||
| 1550 | "start syntax check-process" | ||
| 1551 | |||
| 1552 | (let* ((process nil)) | ||
| 1553 | (condition-case err | ||
| 1554 | (progn | ||
| 1555 | (when dir | ||
| 1556 | (let ((default-directory dir)) | ||
| 1557 | (flymake-log 3 "starting process on dir %s" default-directory) | ||
| 1558 | ) | ||
| 1559 | ) | ||
| 1560 | (setq process (get-process (apply 'start-process "flymake-proc" nil cmd args))) | ||
| 1561 | (set-process-sentinel process 'flymake-process-sentinel) | ||
| 1562 | (set-process-filter process 'flymake-process-filter) | ||
| 1563 | |||
| 1564 | (flymake-reg-names (process-id process) (buffer-name buffer)) | ||
| 1565 | |||
| 1566 | (flymake-set-buffer-is-running buffer t) | ||
| 1567 | (flymake-set-buffer-last-change-time buffer nil) | ||
| 1568 | (flymake-set-buffer-check-start-time buffer (flymake-float-time)) | ||
| 1569 | |||
| 1570 | (flymake-report-status buffer nil "*") | ||
| 1571 | (flymake-log 2 "started process %d, command=%s, dir=%s" | ||
| 1572 | (process-id process) (process-command process) default-directory) | ||
| 1573 | process | ||
| 1574 | ) | ||
| 1575 | (error | ||
| 1576 | (let ((err-str (format "Failed to launch syntax check process '%s' with args %s: %s" | ||
| 1577 | cmd args (error-message-string err))) | ||
| 1578 | (source-file-name (buffer-file-name buffer)) | ||
| 1579 | (cleanup-f (flymake-get-cleanup-function source-file-name))) | ||
| 1580 | (flymake-log 0 err-str) | ||
| 1581 | (funcall cleanup-f buffer) | ||
| 1582 | (flymake-report-fatal-status buffer "PROCERR" err-str) | ||
| 1583 | ) | ||
| 1584 | ) | ||
| 1585 | ) | ||
| 1586 | ) | ||
| 1587 | ) | ||
| 1588 | |||
| 1589 | (defun flymake-kill-process(pid &optional rest) | ||
| 1590 | "kill process pid" | ||
| 1591 | (signal-process pid 9) | ||
| 1592 | (let* ((buffer-name (flymake-get-source-buffer-name pid))) | ||
| 1593 | (when (and buffer-name (get-buffer buffer-name)) | ||
| 1594 | (flymake-set-buffer-check-was-interrupted (get-buffer buffer-name) t) | ||
| 1595 | ) | ||
| 1596 | ) | ||
| 1597 | (flymake-log 1 "killed process %d" pid) | ||
| 1598 | ) | ||
| 1599 | |||
| 1600 | (defun flymake-stop-all-syntax-checks() | ||
| 1601 | "kill all syntax check processes" | ||
| 1602 | (interactive) | ||
| 1603 | (let ((pids (copy-hash-table flymake-pid-to-names))) | ||
| 1604 | (maphash 'flymake-kill-process pids) | ||
| 1605 | ) | ||
| 1606 | ) | ||
| 1607 | |||
| 1608 | (defun flymake-compilation-is-running() | ||
| 1609 | (and (boundp 'compilation-in-progress) | ||
| 1610 | compilation-in-progress) | ||
| 1611 | ) | ||
| 1612 | |||
| 1613 | (defun flymake-compile() | ||
| 1614 | "kill all flymake syntax checks, start compilation" | ||
| 1615 | (interactive) | ||
| 1616 | (flymake-stop-all-syntax-checks) | ||
| 1617 | (call-interactively 'compile) | ||
| 1618 | ) | ||
| 1619 | |||
| 1620 | (defvar flymake-is-running nil | ||
| 1621 | "t if flymake syntax check process is running for the current buffer" | ||
| 1622 | ) | ||
| 1623 | (make-variable-buffer-local 'flymake-is-running) | ||
| 1624 | (defun flymake-get-buffer-is-running(buffer) | ||
| 1625 | (flymake-get-buffer-var buffer 'flymake-is-running) | ||
| 1626 | ) | ||
| 1627 | (defun flymake-set-buffer-is-running(buffer is-running) | ||
| 1628 | (flymake-set-buffer-var buffer 'flymake-is-running is-running) | ||
| 1629 | ) | ||
| 1630 | |||
| 1631 | (defvar flymake-timer nil | ||
| 1632 | "timer for starting syntax checks" | ||
| 1633 | ) | ||
| 1634 | (make-variable-buffer-local 'flymake-timer) | ||
| 1635 | (defun flymake-get-buffer-timer(buffer) | ||
| 1636 | (flymake-get-buffer-var buffer 'flymake-timer) | ||
| 1637 | ) | ||
| 1638 | (defun flymake-set-buffer-timer(buffer timer) | ||
| 1639 | (flymake-set-buffer-var buffer 'flymake-timer timer) | ||
| 1640 | ) | ||
| 1641 | |||
| 1642 | (defvar flymake-last-change-time nil | ||
| 1643 | "time of last buffer change" | ||
| 1644 | ) | ||
| 1645 | (make-variable-buffer-local 'flymake-last-change-time) | ||
| 1646 | (defun flymake-get-buffer-last-change-time(buffer) | ||
| 1647 | (flymake-get-buffer-var buffer 'flymake-last-change-time) | ||
| 1648 | ) | ||
| 1649 | (defun flymake-set-buffer-last-change-time(buffer change-time) | ||
| 1650 | (flymake-set-buffer-var buffer 'flymake-last-change-time change-time) | ||
| 1651 | ) | ||
| 1652 | |||
| 1653 | (defvar flymake-check-start-time nil | ||
| 1654 | "time at which syntax check was started") | ||
| 1655 | (make-variable-buffer-local 'flymake-check-start-time) | ||
| 1656 | (defun flymake-get-buffer-check-start-time(buffer) | ||
| 1657 | (flymake-get-buffer-var buffer 'flymake-check-start-time) | ||
| 1658 | ) | ||
| 1659 | (defun flymake-set-buffer-check-start-time(buffer check-start-time) | ||
| 1660 | (flymake-set-buffer-var buffer 'flymake-check-start-time check-start-time) | ||
| 1661 | ) | ||
| 1662 | |||
| 1663 | (defvar flymake-check-was-interrupted nil | ||
| 1664 | "t if syntax check was killed by flymake-compile" | ||
| 1665 | ) | ||
| 1666 | (make-variable-buffer-local 'flymake-check-was-interrupted) | ||
| 1667 | (defun flymake-get-buffer-check-was-interrupted(buffer) | ||
| 1668 | (flymake-get-buffer-var buffer 'flymake-check-was-interrupted) | ||
| 1669 | ) | ||
| 1670 | (defun flymake-set-buffer-check-was-interrupted(buffer interrupted) | ||
| 1671 | (flymake-set-buffer-var buffer 'flymake-check-was-interrupted interrupted) | ||
| 1672 | ) | ||
| 1673 | |||
| 1674 | (defcustom flymake-no-changes-timeout 0.5 | ||
| 1675 | "time to wait after last change before starting compilation" | ||
| 1676 | :group 'flymake | ||
| 1677 | :type 'number | ||
| 1678 | ) | ||
| 1679 | |||
| 1680 | (defun flymake-on-timer-event(buffer) | ||
| 1681 | "start a syntax check for buffer if necessary" | ||
| 1682 | ;+(flymake-log 3 "timer: running=%s, time=%s, cur-time=%s" (flymake-get-buffer-is-running buffer) (flymake-get-buffer-last-change-time buffer) (flymake-float-time)) | ||
| 1683 | |||
| 1684 | (when (and (bufferp buffer) (not (flymake-get-buffer-is-running buffer))) | ||
| 1685 | (save-excursion | ||
| 1686 | (set-buffer buffer) | ||
| 1687 | (when (and (flymake-get-buffer-last-change-time buffer) | ||
| 1688 | (> (flymake-float-time) (+ flymake-no-changes-timeout (flymake-get-buffer-last-change-time buffer)))) | ||
| 1689 | (flymake-set-buffer-last-change-time buffer nil) | ||
| 1690 | (flymake-log 3 "starting syntax check as more than 1 second passed since last change") | ||
| 1691 | (flymake-start-syntax-check buffer) | ||
| 1692 | ) | ||
| 1693 | ) | ||
| 1694 | ) | ||
| 1695 | ) | ||
| 1696 | |||
| 1697 | (defun flymake-start-syntax-check-for-current-buffer() | ||
| 1698 | "run flymake-start-syntax-check for current buffer if it isn't already running" | ||
| 1699 | (interactive) | ||
| 1700 | (flymake-start-syntax-check (current-buffer)) | ||
| 1701 | ) | ||
| 1702 | |||
| 1703 | (defun flymake-current-line-no() | ||
| 1704 | "return number of current line in current buffer" | ||
| 1705 | (interactive) | ||
| 1706 | (let ((beg (point-min)) | ||
| 1707 | (end (if (= (point) (point-max)) (point) (1+ (point))))) | ||
| 1708 | (count-lines beg end) | ||
| 1709 | ) | ||
| 1710 | ) | ||
| 1711 | |||
| 1712 | (defun flymake-get-line-count(buffer) | ||
| 1713 | "return number of lines in buffer" | ||
| 1714 | (unless (bufferp buffer) | ||
| 1715 | (error "invalid buffer") | ||
| 1716 | ) | ||
| 1717 | (save-excursion | ||
| 1718 | (set-buffer buffer) | ||
| 1719 | (count-lines (point-min) (point-max)) | ||
| 1720 | ) | ||
| 1721 | ) | ||
| 1722 | |||
| 1723 | (defun flymake-count-lines(buffer) | ||
| 1724 | "return number of lines in buffer" | ||
| 1725 | (save-excursion | ||
| 1726 | (set-buffer buffer) | ||
| 1727 | (count-lines (point-min) (point-max)) | ||
| 1728 | ) | ||
| 1729 | ) | ||
| 1730 | |||
| 1731 | (defun flymake-get-point-pixel-pos() | ||
| 1732 | "return point position in pixels: (x, y)" | ||
| 1733 | (let ((mouse-pos (mouse-position)) | ||
| 1734 | (pixel-pos nil) | ||
| 1735 | (ret nil)) | ||
| 1736 | (if (car (cdr mouse-pos)) | ||
| 1737 | (progn | ||
| 1738 | (set-mouse-position (flymake-selected-frame) (current-column) (flymake-current-row)) | ||
| 1739 | (setq pixel-pos (mouse-pixel-position)) | ||
| 1740 | (set-mouse-position (car mouse-pos) (car (cdr mouse-pos)) (cdr (cdr mouse-pos))) | ||
| 1741 | (setq ret (list (car (cdr pixel-pos)) (cdr (cdr pixel-pos)))) | ||
| 1742 | ) | ||
| 1743 | ;else | ||
| 1744 | (progn | ||
| 1745 | (setq ret '(0 0)) | ||
| 1746 | ) | ||
| 1747 | ) | ||
| 1748 | (flymake-log 3 "mouse pos is %s" ret) | ||
| 1749 | ret | ||
| 1750 | ) | ||
| 1751 | ) | ||
| 1752 | |||
| 1753 | (defun flymake-display-err-menu-for-current-line() | ||
| 1754 | "Display a menu with errors/warnings for current line if it has errors and/or warnings" | ||
| 1755 | (interactive) | ||
| 1756 | (let* ((line-no (flymake-current-line-no)) | ||
| 1757 | (line-err-info-list (nth 0 (flymake-find-err-info (flymake-get-buffer-err-info (current-buffer)) line-no))) | ||
| 1758 | (menu-data (flymake-make-err-menu-data line-no line-err-info-list)) | ||
| 1759 | (choice nil) | ||
| 1760 | (mouse-pos (flymake-get-point-pixel-pos)) | ||
| 1761 | (moved-mouse-pos (list (car mouse-pos) (+ 10 (car (cdr mouse-pos))))) | ||
| 1762 | (menu-pos (list (flymake-get-point-pixel-pos) (selected-window)))) | ||
| 1763 | (if menu-data | ||
| 1764 | (progn | ||
| 1765 | (setq choice (flymake-popup-menu menu-pos menu-data)) | ||
| 1766 | (flymake-log 3 "choice=%s" choice) | ||
| 1767 | (when choice | ||
| 1768 | (eval choice) | ||
| 1769 | ) | ||
| 1770 | ) | ||
| 1771 | ;else | ||
| 1772 | (flymake-log 1 "no errors for line %d" line-no) | ||
| 1773 | ) | ||
| 1774 | ) | ||
| 1775 | ) | ||
| 1776 | |||
| 1777 | (defun flymake-make-err-menu-data(line-no line-err-info-list) | ||
| 1778 | "Make a (menu-title (item-title item-action)*) list with errors/warnings from line-err-info" | ||
| 1779 | (let* ((menu-items nil)) | ||
| 1780 | (when line-err-info-list | ||
| 1781 | (let* ((count (length line-err-info-list)) | ||
| 1782 | (menu-item-text nil)) | ||
| 1783 | (while (> count 0) | ||
| 1784 | (setq menu-item-text (flymake-ler-get-text (nth (1- count) line-err-info-list))) | ||
| 1785 | (let* ((file (flymake-ler-get-file (nth (1- count) line-err-info-list))) | ||
| 1786 | (full-file (flymake-ler-get-full-file (nth (1- count) line-err-info-list))) | ||
| 1787 | (line (flymake-ler-get-line (nth (1- count) line-err-info-list)))) | ||
| 1788 | (if file | ||
| 1789 | (setq menu-item-text (concat menu-item-text " - " file "(" (format "%d" line) ")")) | ||
| 1790 | ) | ||
| 1791 | (setq menu-items (cons (list menu-item-text | ||
| 1792 | (if file (list 'flymake-goto-file-and-line full-file line) nil)) | ||
| 1793 | menu-items)) | ||
| 1794 | ) | ||
| 1795 | (setq count (1- count)) | ||
| 1796 | ) | ||
| 1797 | (flymake-log 3 "created menu-items with %d item(s)" (length menu-items)) | ||
| 1798 | ) | ||
| 1799 | ) | ||
| 1800 | (if menu-items | ||
| 1801 | (let* ((menu-title (format "Line %d: %d error(s), %d warning(s)" line-no | ||
| 1802 | (flymake-get-line-err-count line-err-info-list "e") | ||
| 1803 | (flymake-get-line-err-count line-err-info-list "w")))) | ||
| 1804 | (list menu-title menu-items) | ||
| 1805 | ) | ||
| 1806 | ;else | ||
| 1807 | nil | ||
| 1808 | ) | ||
| 1809 | ) | ||
| 1810 | ) | ||
| 1811 | |||
| 1812 | (defun flymake-goto-file-and-line(file line) | ||
| 1813 | "try to get buffer for file and goto line line in it" | ||
| 1814 | (if (not (file-exists-p file)) | ||
| 1815 | (flymake-log 1 "file %s does not exists" file) | ||
| 1816 | ;else | ||
| 1817 | (progn | ||
| 1818 | (find-file file) | ||
| 1819 | (goto-line line) | ||
| 1820 | ) | ||
| 1821 | ) | ||
| 1822 | ) | ||
| 1823 | ;; flymake minor mode declarations | ||
| 1824 | |||
| 1825 | (defvar flymake-mode nil) | ||
| 1826 | (make-variable-buffer-local 'flymake-mode) | ||
| 1827 | |||
| 1828 | (defvar flymake-mode-line nil | ||
| 1829 | "" | ||
| 1830 | ) | ||
| 1831 | (make-variable-buffer-local 'flymake-mode-line) | ||
| 1832 | (defun flymake-get-buffer-mode-line(buffer) | ||
| 1833 | (flymake-get-buffer-var buffer 'flymake-mode-line) | ||
| 1834 | ) | ||
| 1835 | (defun flymake-set-buffer-mode-line(buffer mode-line-string) | ||
| 1836 | (flymake-set-buffer-var buffer 'flymake-mode-line mode-line-string) | ||
| 1837 | ) | ||
| 1838 | |||
| 1839 | (defvar flymake-mode-line-e-w nil) | ||
| 1840 | (make-variable-buffer-local 'flymake-mode-line-e-w) | ||
| 1841 | (defun flymake-get-buffer-mode-line-e-w(buffer) | ||
| 1842 | (flymake-get-buffer-var buffer 'flymake-mode-line-e-w) | ||
| 1843 | ) | ||
| 1844 | (defun flymake-set-buffer-mode-line-e-w(buffer e-w) | ||
| 1845 | (flymake-set-buffer-var buffer 'flymake-mode-line-e-w e-w) | ||
| 1846 | ) | ||
| 1847 | |||
| 1848 | (defvar flymake-mode-line-status nil) | ||
| 1849 | (make-variable-buffer-local 'flymake-mode-line-status) | ||
| 1850 | (defun flymake-get-buffer-mode-line-status(buffer) | ||
| 1851 | (flymake-get-buffer-var buffer 'flymake-mode-line-status) | ||
| 1852 | ) | ||
| 1853 | (defun flymake-set-buffer-mode-line-status(buffer status) | ||
| 1854 | (flymake-set-buffer-var buffer 'flymake-mode-line-status status) | ||
| 1855 | ) | ||
| 1856 | |||
| 1857 | (defun flymake-report-status(buffer e-w &optional status) | ||
| 1858 | "show status in the mode line" | ||
| 1859 | (when (bufferp buffer) | ||
| 1860 | (save-excursion | ||
| 1861 | (set-buffer buffer) | ||
| 1862 | (when e-w | ||
| 1863 | (flymake-set-buffer-mode-line-e-w buffer e-w) | ||
| 1864 | ) | ||
| 1865 | (when status | ||
| 1866 | (flymake-set-buffer-mode-line-status buffer status) | ||
| 1867 | ) | ||
| 1868 | (let* ((mode-line " Flymake")) | ||
| 1869 | (when (> (length (flymake-get-buffer-mode-line-e-w buffer)) 0) | ||
| 1870 | (setq mode-line (concat mode-line ":" (flymake-get-buffer-mode-line-e-w buffer))) | ||
| 1871 | ) | ||
| 1872 | (setq mode-line (concat mode-line (flymake-get-buffer-mode-line-status buffer))) | ||
| 1873 | (flymake-set-buffer-mode-line buffer mode-line) | ||
| 1874 | (force-mode-line-update) | ||
| 1875 | ) | ||
| 1876 | ) | ||
| 1877 | ) | ||
| 1878 | ) | ||
| 1879 | |||
| 1880 | (defun flymake-display-warning(warning) | ||
| 1881 | "display a warning to the user" | ||
| 1882 | (message-box warning) | ||
| 1883 | ) | ||
| 1884 | |||
| 1885 | (defcustom flymake-gui-warnings-enabled t | ||
| 1886 | "enables/disables gui warnings" | ||
| 1887 | :group 'flymake | ||
| 1888 | :type 'boolean | ||
| 1889 | ) | ||
| 1890 | |||
| 1891 | (defun flymake-report-fatal-status(buffer status warning) | ||
| 1892 | "display a warning and switch flymake mode OFF" | ||
| 1893 | (when flymake-gui-warnings-enabled | ||
| 1894 | (flymake-display-warning (format "Flymake: %s. Flymake will be switched OFF" warning)) | ||
| 1895 | ) | ||
| 1896 | (save-excursion | ||
| 1897 | (set-buffer buffer) | ||
| 1898 | (flymake-mode 0) | ||
| 1899 | (flymake-log 0 "switched OFF Flymake mode for buffer %s due to fatal status %s, warning %s" | ||
| 1900 | (buffer-name buffer) status warning) | ||
| 1901 | ) | ||
| 1902 | ) | ||
| 1903 | |||
| 1904 | (defun flymake-mode(&optional arg) | ||
| 1905 | "toggle flymake-mode" | ||
| 1906 | (interactive) | ||
| 1907 | (let ((old-flymake-mode flymake-mode)) | ||
| 1908 | |||
| 1909 | (setq turn-on | ||
| 1910 | (if (null arg) | ||
| 1911 | (not flymake-mode) | ||
| 1912 | ;else | ||
| 1913 | (> (prefix-numeric-value arg) 0)) | ||
| 1914 | ) | ||
| 1915 | |||
| 1916 | (if turn-on | ||
| 1917 | (if (flymake-can-syntax-check-file (buffer-file-name)) | ||
| 1918 | (flymake-mode-on) | ||
| 1919 | ;else | ||
| 1920 | (flymake-log 2 "flymake cannot check syntax in buffer %s" (buffer-name)) | ||
| 1921 | ) | ||
| 1922 | ;else | ||
| 1923 | (flymake-mode-off) | ||
| 1924 | ) | ||
| 1925 | (force-mode-line-update) | ||
| 1926 | ) | ||
| 1927 | ) | ||
| 1928 | |||
| 1929 | ;;;###autoload | ||
| 1930 | (unless (assq 'flymake-mode minor-mode-alist) | ||
| 1931 | (setq minor-mode-alist (cons '(flymake-mode flymake-mode-line) minor-mode-alist)) | ||
| 1932 | ) | ||
| 1933 | |||
| 1934 | ;;;###autoload | ||
| 1935 | (defun flymake-mode-on() | ||
| 1936 | "turn flymake mode on" | ||
| 1937 | (when (not flymake-mode) | ||
| 1938 | (make-local-variable 'after-change-functions) | ||
| 1939 | (setq after-change-functions (cons 'flymake-after-change-function after-change-functions)) | ||
| 1940 | (add-hook 'after-save-hook 'flymake-after-save-hook) | ||
| 1941 | (add-hook 'kill-buffer-hook 'flymake-kill-buffer-hook) | ||
| 1942 | ;+(add-hook 'find-file-hooks 'flymake-find-file-hook) | ||
| 1943 | |||
| 1944 | (flymake-report-status (current-buffer) "" "") | ||
| 1945 | |||
| 1946 | (flymake-set-buffer-timer (current-buffer) (run-at-time nil 1 'flymake-on-timer-event (current-buffer))) | ||
| 1947 | |||
| 1948 | (setq flymake-mode t) | ||
| 1949 | (flymake-log 1 "flymake mode turned ON for buffer %s" (buffer-name (current-buffer))) | ||
| 1950 | (when flymake-start-syntax-check-on-find-file | ||
| 1951 | (flymake-start-syntax-check-for-current-buffer) ; will be started by on-load hook | ||
| 1952 | ) | ||
| 1953 | ) | ||
| 1954 | ) | ||
| 1955 | |||
| 1956 | ;;;###autoload | ||
| 1957 | (defun flymake-mode-off() | ||
| 1958 | "turn flymake mode off" | ||
| 1959 | (when flymake-mode | ||
| 1960 | (setq after-change-functions (delq 'flymake-after-change-function after-change-functions)) | ||
| 1961 | (remove-hook 'after-save-hook (function flymake-after-save-hook) t) | ||
| 1962 | (remove-hook 'kill-buffer-hook (function flymake-kill-buffer-hook) t) | ||
| 1963 | ;+(remove-hook 'find-file-hooks (function flymake-find-file-hook) t) | ||
| 1964 | |||
| 1965 | (flymake-delete-own-overlays (current-buffer)) | ||
| 1966 | |||
| 1967 | (when (flymake-get-buffer-timer (current-buffer)) | ||
| 1968 | (cancel-timer (flymake-get-buffer-timer (current-buffer))) | ||
| 1969 | (flymake-set-buffer-timer (current-buffer) nil) | ||
| 1970 | ) | ||
| 1971 | |||
| 1972 | (flymake-set-buffer-is-running (current-buffer) nil) | ||
| 1973 | |||
| 1974 | (setq flymake-mode nil) | ||
| 1975 | (flymake-log 1 "flymake mode turned OFF for buffer %s" (buffer-name (current-buffer))) | ||
| 1976 | ) | ||
| 1977 | ) | ||
| 1978 | |||
| 1979 | (defcustom flymake-start-syntax-check-on-newline t | ||
| 1980 | "start syntax check if newline char was added/removed from the buffer" | ||
| 1981 | :group 'flymake | ||
| 1982 | :type 'boolean | ||
| 1983 | ) | ||
| 1984 | |||
| 1985 | (defun flymake-after-change-function(start stop len) | ||
| 1986 | "Start syntax check for current buffer if it isn't already running" | ||
| 1987 | ;+(flymake-log 0 "setting change time to %s" (flymake-float-time)) | ||
| 1988 | (let((new-text (buffer-substring start stop))) | ||
| 1989 | (when (and flymake-start-syntax-check-on-newline (equal new-text "\n")) | ||
| 1990 | (flymake-log 3 "starting syntax check as new-line has been seen") | ||
| 1991 | (flymake-start-syntax-check-for-current-buffer) | ||
| 1992 | ) | ||
| 1993 | (flymake-set-buffer-last-change-time (current-buffer) (flymake-float-time)) | ||
| 1994 | ) | ||
| 1995 | ) | ||
| 1996 | |||
| 1997 | (defun flymake-after-save-hook() | ||
| 1998 | (if (local-variable-p 'flymake-mode (current-buffer)) ; (???) other way to determine whether flymake is active in buffer being saved? | ||
| 1999 | (progn | ||
| 2000 | (flymake-log 3 "starting syntax check as buffer was saved") | ||
| 2001 | (flymake-start-syntax-check-for-current-buffer) ; no more mode 3. cannot start check if mode 3 (to temp copies) is active - (???) | ||
| 2002 | ) | ||
| 2003 | ) | ||
| 2004 | ) | ||
| 2005 | |||
| 2006 | (defun flymake-kill-buffer-hook() | ||
| 2007 | (when (flymake-get-buffer-timer (current-buffer)) | ||
| 2008 | (cancel-timer (flymake-get-buffer-timer (current-buffer))) | ||
| 2009 | (flymake-set-buffer-timer (current-buffer) nil) | ||
| 2010 | ) | ||
| 2011 | ) | ||
| 2012 | |||
| 2013 | (defcustom flymake-start-syntax-check-on-find-file t | ||
| 2014 | "statr syntax check on find file" | ||
| 2015 | :group 'flymake | ||
| 2016 | :type 'boolean | ||
| 2017 | ) | ||
| 2018 | |||
| 2019 | (defun flymake-find-file-hook() | ||
| 2020 | ;+(when flymake-start-syntax-check-on-find-file | ||
| 2021 | ;+ (flymake-log 3 "starting syntax check on file open") | ||
| 2022 | ;+ (flymake-start-syntax-check-for-current-buffer) | ||
| 2023 | ;+) | ||
| 2024 | (when (and (not (local-variable-p 'flymake-mode (current-buffer))) | ||
| 2025 | (flymake-can-syntax-check-file (buffer-file-name (current-buffer)))) | ||
| 2026 | (flymake-mode) | ||
| 2027 | (flymake-log 3 "automatically turned ON flymake mode") | ||
| 2028 | ) | ||
| 2029 | ) | ||
| 2030 | |||
| 2031 | (defun flymake-get-first-err-line-no(err-info-list) | ||
| 2032 | "return first line-no with error" | ||
| 2033 | (when err-info-list | ||
| 2034 | (flymake-er-get-line (car err-info-list)) | ||
| 2035 | ) | ||
| 2036 | ) | ||
| 2037 | |||
| 2038 | (defun flymake-get-last-err-line-no(err-info-list) | ||
| 2039 | "return last line-no with error" | ||
| 2040 | (when err-info-list | ||
| 2041 | (flymake-er-get-line (nth (1- (length err-info-list)) err-info-list)) | ||
| 2042 | ) | ||
| 2043 | ) | ||
| 2044 | |||
| 2045 | (defun flymake-get-next-err-line-no(err-info-list line-no) | ||
| 2046 | "return next line with erroe" | ||
| 2047 | (when err-info-list | ||
| 2048 | (let* ((count (length err-info-list)) | ||
| 2049 | (idx 0)) | ||
| 2050 | (while (and (< idx count) (>= line-no (flymake-er-get-line (nth idx err-info-list)))) | ||
| 2051 | (setq idx (1+ idx)) | ||
| 2052 | ) | ||
| 2053 | (if (< idx count) | ||
| 2054 | (flymake-er-get-line (nth idx err-info-list)) | ||
| 2055 | ) | ||
| 2056 | ) | ||
| 2057 | ) | ||
| 2058 | ) | ||
| 2059 | |||
| 2060 | (defun flymake-get-prev-err-line-no(err-info-list line-no) | ||
| 2061 | "return prev line with error" | ||
| 2062 | (when err-info-list | ||
| 2063 | (let* ((count (length err-info-list))) | ||
| 2064 | (while (and (> count 0) (<= line-no (flymake-er-get-line (nth (1- count) err-info-list)))) | ||
| 2065 | (setq count (1- count)) | ||
| 2066 | ) | ||
| 2067 | (if (> count 0) | ||
| 2068 | (flymake-er-get-line (nth (1- count) err-info-list)) | ||
| 2069 | ) | ||
| 2070 | ) | ||
| 2071 | ) | ||
| 2072 | ) | ||
| 2073 | |||
| 2074 | (defun flymake-skip-whitespace() | ||
| 2075 | "move forward until nonwhitespace is reached" | ||
| 2076 | (while (looking-at "[ \t]") | ||
| 2077 | (forward-char) | ||
| 2078 | ) | ||
| 2079 | ) | ||
| 2080 | |||
| 2081 | (defun flymake-goto-line(line-no) | ||
| 2082 | "goto-line, then skip whitespace" | ||
| 2083 | (goto-line line-no) | ||
| 2084 | (flymake-skip-whitespace) | ||
| 2085 | ) | ||
| 2086 | |||
| 2087 | (defun flymake-goto-next-error() | ||
| 2088 | "go to next error in err ring" | ||
| 2089 | (interactive) | ||
| 2090 | (let ((line-no (flymake-get-next-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no)))) | ||
| 2091 | (when (not line-no) | ||
| 2092 | (setq line-no (flymake-get-first-err-line-no (flymake-get-buffer-err-info (current-buffer)))) | ||
| 2093 | (flymake-log 1 "passed end of file") | ||
| 2094 | ) | ||
| 2095 | (if line-no | ||
| 2096 | (flymake-goto-line line-no) | ||
| 2097 | ;else | ||
| 2098 | (flymake-log 1 "no errors in current buffer") | ||
| 2099 | ) | ||
| 2100 | ) | ||
| 2101 | ) | ||
| 2102 | |||
| 2103 | (defun flymake-goto-prev-error() | ||
| 2104 | "go to prev error in err ring" | ||
| 2105 | (interactive) | ||
| 2106 | (let ((line-no (flymake-get-prev-err-line-no (flymake-get-buffer-err-info (current-buffer)) (flymake-current-line-no)))) | ||
| 2107 | (when (not line-no) | ||
| 2108 | (setq line-no (flymake-get-last-err-line-no (flymake-get-buffer-err-info (current-buffer)))) | ||
| 2109 | (flymake-log 1 "passed beginning of file") | ||
| 2110 | ) | ||
| 2111 | (if line-no | ||
| 2112 | (flymake-goto-line line-no) | ||
| 2113 | ;else | ||
| 2114 | (flymake-log 1 "no errors in current buffer") | ||
| 2115 | ) | ||
| 2116 | ) | ||
| 2117 | ) | ||
| 2118 | |||
| 2119 | (defun flymake-patch-err-text(string) | ||
| 2120 | (if (string-match "^[\n\t :0-9]*\\(.*\\)$" string) | ||
| 2121 | (match-string 1 string) | ||
| 2122 | ;else | ||
| 2123 | string | ||
| 2124 | ) | ||
| 2125 | ) | ||
| 2126 | |||
| 2127 | ;;;; general init-cleanup and helper routines | ||
| 2128 | |||
| 2129 | (defun flymake-create-temp-inplace(file-name prefix) | ||
| 2130 | (unless (stringp file-name) | ||
| 2131 | (error "invalid file-name") | ||
| 2132 | ) | ||
| 2133 | (or prefix | ||
| 2134 | (setq prefix "flymake") | ||
| 2135 | ) | ||
| 2136 | (let* ((temp-name (concat (file-name-sans-extension file-name) | ||
| 2137 | "_" prefix | ||
| 2138 | (and (file-name-extension file-name) | ||
| 2139 | (concat "." (file-name-extension file-name)))))) | ||
| 2140 | (flymake-log 3 "create-temp-inplace: file=%s temp=%s" file-name temp-name) | ||
| 2141 | temp-name | ||
| 2142 | ) | ||
| 2143 | ) | ||
| 2144 | |||
| 2145 | (defun flymake-create-temp-with-folder-structure(file-name prefix) | ||
| 2146 | (unless (stringp file-name) | ||
| 2147 | (error "invalid file-name") | ||
| 2148 | ) | ||
| 2149 | |||
| 2150 | (let* ((dir (file-name-directory file-name)) | ||
| 2151 | (slash-pos (string-match "/" dir)) | ||
| 2152 | (temp-dir (concat (flymake-ensure-ends-with-slash (flymake-get-temp-dir)) (substring dir (1+ slash-pos))))) | ||
| 2153 | |||
| 2154 | (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) | ||
| 2155 | (file-name-nondirectory file-name))) | ||
| 2156 | ) | ||
| 2157 | ) | ||
| 2158 | |||
| 2159 | (defun flymake-strrchr(str ch) | ||
| 2160 | (let* ((count (length str)) | ||
| 2161 | (pos nil)) | ||
| 2162 | (while (and (not pos) (> count 0)) | ||
| 2163 | (if (= ch (elt str (1- count))) | ||
| 2164 | (setq pos (1- count)) | ||
| 2165 | ) | ||
| 2166 | (setq count (1- count)) | ||
| 2167 | ) | ||
| 2168 | pos | ||
| 2169 | ) | ||
| 2170 | ) | ||
| 2171 | |||
| 2172 | (defun flymake-delete-temp-directory(dir-name) | ||
| 2173 | "attempt to delete temp dir created by flymake-create-temp-with-folder-structure, do not fail on error" | ||
| 2174 | (let* ((temp-dir (flymake-get-temp-dir)) | ||
| 2175 | (suffix (substring dir-name (1+ (length temp-dir)))) | ||
| 2176 | (slash-pos nil)) | ||
| 2177 | |||
| 2178 | (while (> (length suffix) 0) | ||
| 2179 | ;+(flymake-log 0 "suffix=%s" suffix) | ||
| 2180 | (flymake-safe-delete-directory (file-truename (concat (flymake-ensure-ends-with-slash temp-dir) suffix))) | ||
| 2181 | (setq slash-pos (flymake-strrchr suffix (string-to-char "/"))) | ||
| 2182 | (if slash-pos | ||
| 2183 | (setq suffix (substring suffix 0 slash-pos)) | ||
| 2184 | ;else | ||
| 2185 | (setq suffix "") | ||
| 2186 | ) | ||
| 2187 | ) | ||
| 2188 | ) | ||
| 2189 | ) | ||
| 2190 | |||
| 2191 | (defun flymake-init-create-temp-buffer-copy(buffer create-temp-f) | ||
| 2192 | "make a temporary copy of the current buffer, save its name in buffer data and return the name" | ||
| 2193 | (let* ((source-file-name (buffer-file-name buffer)) | ||
| 2194 | (temp-source-file-name (funcall create-temp-f source-file-name "flymake"))) | ||
| 2195 | |||
| 2196 | (flymake-save-buffer-in-file buffer temp-source-file-name) | ||
| 2197 | (flymake-set-buffer-value buffer "temp-source-file-name" temp-source-file-name) | ||
| 2198 | |||
| 2199 | temp-source-file-name | ||
| 2200 | ) | ||
| 2201 | ) | ||
| 2202 | |||
| 2203 | (defun flymake-simple-cleanup(buffer) | ||
| 2204 | "cleanup after flymake-init-create-temp-buffer-copy -- delete temp file" | ||
| 2205 | (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) | ||
| 2206 | (flymake-safe-delete-file temp-source-file-name) | ||
| 2207 | (flymake-set-buffer-last-change-time buffer nil) | ||
| 2208 | ) | ||
| 2209 | ) | ||
| 2210 | |||
| 2211 | (defun flymake-get-real-file-name(buffer file-name-from-err-msg) | ||
| 2212 | "Translate file name from error message to `real' file name. Return full-name. Names are real, not patched" | ||
| 2213 | (let* ((real-name nil) | ||
| 2214 | (source-file-name (buffer-file-name buffer)) | ||
| 2215 | (master-file-name (flymake-get-buffer-value buffer "master-file-name")) | ||
| 2216 | (temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name")) | ||
| 2217 | (temp-master-file-name (flymake-get-buffer-value buffer "temp-master-file-name")) | ||
| 2218 | (base-dirs (list (flymake-get-buffer-value buffer "base-dir") | ||
| 2219 | (file-name-directory source-file-name) | ||
| 2220 | (if master-file-name (file-name-directory master-file-name) nil))) | ||
| 2221 | (files (list (list source-file-name source-file-name) | ||
| 2222 | (list temp-source-file-name source-file-name) | ||
| 2223 | (list master-file-name master-file-name) | ||
| 2224 | (list temp-master-file-name master-file-name)))) | ||
| 2225 | |||
| 2226 | (when (equal 0 (length file-name-from-err-msg)) | ||
| 2227 | (setq file-name-from-err-msg source-file-name) | ||
| 2228 | ) | ||
| 2229 | |||
| 2230 | (setq real-name (flymake-get-full-patched-file-name file-name-from-err-msg base-dirs files)) | ||
| 2231 | ; if real-name is nil, than file name from err msg is none of the files we've patched | ||
| 2232 | (if (not real-name) | ||
| 2233 | (setq real-name (flymake-get-full-nonpatched-file-name file-name-from-err-msg base-dirs)) | ||
| 2234 | ) | ||
| 2235 | (if (not real-name) | ||
| 2236 | (setq real-name file-name-from-err-msg) | ||
| 2237 | ) | ||
| 2238 | (setq real-name (flymake-fix-path-name real-name)) | ||
| 2239 | (flymake-log 3 "get-real-file-name: file-name=%s real-name=%s" file-name-from-err-msg real-name) | ||
| 2240 | real-name | ||
| 2241 | ) | ||
| 2242 | ) | ||
| 2243 | |||
| 2244 | (defun flymake-get-full-patched-file-name(file-name-from-err-msg base-dirs files) | ||
| 2245 | (let* ((base-dirs-count (length base-dirs)) | ||
| 2246 | (file-count (length files)) | ||
| 2247 | (real-name nil)) | ||
| 2248 | |||
| 2249 | (while (and (not real-name) (> base-dirs-count 0)) | ||
| 2250 | (setq file-count (length files)) | ||
| 2251 | (while (and (not real-name) (> file-count 0)) | ||
| 2252 | (let* ((this-dir (nth (1- base-dirs-count) base-dirs)) | ||
| 2253 | (this-file (nth 0 (nth (1- file-count) files))) | ||
| 2254 | (this-real-name (nth 1 (nth (1- file-count) files)))) | ||
| 2255 | ;+(flymake-log 0 "this-dir=%s this-file=%s this-real=%s msg-file=%s" this-dir this-file this-real-name file-name-from-err-msg) | ||
| 2256 | (when (and this-dir this-file (flymake-same-files | ||
| 2257 | (flymake-get-absolute-file-name-basedir file-name-from-err-msg this-dir) | ||
| 2258 | this-file)) | ||
| 2259 | (setq real-name this-real-name) | ||
| 2260 | ) | ||
| 2261 | ) | ||
| 2262 | (setq file-count (1- file-count)) | ||
| 2263 | ) | ||
| 2264 | (setq base-dirs-count (1- base-dirs-count)) | ||
| 2265 | ) | ||
| 2266 | real-name | ||
| 2267 | ) | ||
| 2268 | ) | ||
| 2269 | |||
| 2270 | (defun flymake-get-full-nonpatched-file-name(file-name-from-err-msg base-dirs) | ||
| 2271 | (let* ((real-name nil)) | ||
| 2272 | (if (file-name-absolute-p file-name-from-err-msg) | ||
| 2273 | (setq real-name file-name-from-err-msg) | ||
| 2274 | ;else | ||
| 2275 | (let* ((base-dirs-count (length base-dirs))) | ||
| 2276 | (while (and (not real-name) (> base-dirs-count 0)) | ||
| 2277 | (let* ((full-name (flymake-get-absolute-file-name-basedir file-name-from-err-msg | ||
| 2278 | (nth (1- base-dirs-count) base-dirs)))) | ||
| 2279 | (if (file-exists-p full-name) | ||
| 2280 | (setq real-name full-name) | ||
| 2281 | ) | ||
| 2282 | (setq base-dirs-count (1- base-dirs-count)) | ||
| 2283 | ) | ||
| 2284 | ) | ||
| 2285 | ) | ||
| 2286 | ) | ||
| 2287 | real-name | ||
| 2288 | ) | ||
| 2289 | ) | ||
| 2290 | |||
| 2291 | (defun flymake-get-absolute-file-name-basedir(file-name dir-name) | ||
| 2292 | (if (file-name-absolute-p file-name) | ||
| 2293 | file-name | ||
| 2294 | ;else | ||
| 2295 | (concat dir-name "/" file-name) | ||
| 2296 | ) | ||
| 2297 | ) | ||
| 2298 | |||
| 2299 | (defun flymake-init-find-buildfile-dir(buffer source-file-name buildfile-name) | ||
| 2300 | "find buildfile, store its dir in buffer data and return its dir, if found" | ||
| 2301 | (let* ((buildfile-dir (flymake-find-buildfile buildfile-name | ||
| 2302 | (file-name-directory source-file-name) | ||
| 2303 | flymake-buildfile-dirs))) | ||
| 2304 | (if (not buildfile-dir) | ||
| 2305 | (progn | ||
| 2306 | (flymake-log 1 "no buildfile (%s) for %s" buildfile-name source-file-name) | ||
| 2307 | (flymake-report-fatal-status buffer "NOMK" (format "No buildfile (%s) found for %s" buildfile-name source-file-name)) | ||
| 2308 | ) | ||
| 2309 | ;else | ||
| 2310 | (progn | ||
| 2311 | (flymake-set-buffer-value buffer "base-dir" buildfile-dir) | ||
| 2312 | ) | ||
| 2313 | ) | ||
| 2314 | buildfile-dir | ||
| 2315 | ) | ||
| 2316 | ) | ||
| 2317 | |||
| 2318 | (defun flymake-init-create-temp-source-and-master-buffer-copy(buffer get-incl-dirs-f create-temp-f master-file-masks include-regexp-list) | ||
| 2319 | "find master file (or buffer), create it's copy along with a copy of the source file" | ||
| 2320 | (let* ((source-file-name (buffer-file-name buffer)) | ||
| 2321 | (temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f)) | ||
| 2322 | (master-file-name nil) | ||
| 2323 | (temp-master-file-name nil) | ||
| 2324 | (master-and-temp-master (flymake-create-master-file | ||
| 2325 | source-file-name temp-source-file-name | ||
| 2326 | get-incl-dirs-f create-temp-f | ||
| 2327 | master-file-masks include-regexp-list))) | ||
| 2328 | |||
| 2329 | (if (not master-and-temp-master) | ||
| 2330 | (progn | ||
| 2331 | (flymake-log 1 "cannot find master file for %s" source-file-name) | ||
| 2332 | (flymake-report-status buffer "!" "") ; NOMASTER | ||
| 2333 | ) | ||
| 2334 | ;else | ||
| 2335 | (progn | ||
| 2336 | (setq master-file-name (nth 0 master-and-temp-master)) | ||
| 2337 | (setq temp-master-file-name (nth 1 master-and-temp-master)) | ||
| 2338 | (flymake-set-buffer-value buffer "master-file-name" master-file-name) | ||
| 2339 | (flymake-set-buffer-value buffer "temp-master-file-name" temp-master-file-name) | ||
| 2340 | ) | ||
| 2341 | ) | ||
| 2342 | temp-master-file-name | ||
| 2343 | ) | ||
| 2344 | ) | ||
| 2345 | |||
| 2346 | (defun flymake-master-cleanup(buffer) | ||
| 2347 | (flymake-simple-cleanup buffer) | ||
| 2348 | (flymake-safe-delete-file (flymake-get-buffer-value buffer "temp-master-file-name")) | ||
| 2349 | ) | ||
| 2350 | |||
| 2351 | ;;;; make-specific init-cleanup routines | ||
| 2352 | |||
| 2353 | (defun flymake-get-syntax-check-program-args(source-file-name base-dir use-relative-base-dir use-relative-source get-cmd-line-f) | ||
| 2354 | "create a command line for the syntax check command, using get-cmd-line-f" | ||
| 2355 | (let* ((my-base-dir base-dir) | ||
| 2356 | (my-source source-file-name)) | ||
| 2357 | |||
| 2358 | (when use-relative-base-dir | ||
| 2359 | (setq my-base-dir (flymake-build-relative-path (file-name-directory source-file-name) base-dir)) | ||
| 2360 | ) | ||
| 2361 | |||
| 2362 | (when use-relative-source | ||
| 2363 | (setq my-source (concat (flymake-build-relative-path base-dir (file-name-directory source-file-name)) | ||
| 2364 | (file-name-nondirectory source-file-name))) | ||
| 2365 | ) | ||
| 2366 | |||
| 2367 | (funcall get-cmd-line-f my-source my-base-dir) | ||
| 2368 | ) | ||
| 2369 | ) | ||
| 2370 | |||
| 2371 | (defun flymake-get-make-cmdline(source base-dir) | ||
| 2372 | (list "make" | ||
| 2373 | (list "-s" | ||
| 2374 | "-C" | ||
| 2375 | base-dir | ||
| 2376 | (concat "CHK_SOURCES=" source) | ||
| 2377 | "SYNTAX_CHECK_MODE=1" | ||
| 2378 | "check-syntax")) | ||
| 2379 | ) | ||
| 2380 | |||
| 2381 | (defun flymake-get-ant-cmdline(source base-dir) | ||
| 2382 | (list "ant" | ||
| 2383 | (list "-buildfile" | ||
| 2384 | (concat base-dir "/" "build.xml") | ||
| 2385 | (concat "-DCHK_SOURCES=" source) | ||
| 2386 | "check-syntax")) | ||
| 2387 | ) | ||
| 2388 | |||
| 2389 | (defun flymake-simple-make-init-impl(buffer create-temp-f use-relative-base-dir use-relative-source build-file-name get-cmdline-f) | ||
| 2390 | "create syntax check command line for a directly checked source file, use create-temp-f for creating temp copy" | ||
| 2391 | (let* ((args nil) | ||
| 2392 | (source-file-name (buffer-file-name buffer)) | ||
| 2393 | (buildfile-dir (flymake-init-find-buildfile-dir buffer source-file-name build-file-name))) | ||
| 2394 | (if buildfile-dir | ||
| 2395 | (let* ((temp-source-file-name (flymake-init-create-temp-buffer-copy buffer create-temp-f))) | ||
| 2396 | (setq args (flymake-get-syntax-check-program-args temp-source-file-name buildfile-dir | ||
| 2397 | use-relative-base-dir use-relative-source | ||
| 2398 | get-cmdline-f)) | ||
| 2399 | ) | ||
| 2400 | ) | ||
| 2401 | |||
| 2402 | args | ||
| 2403 | ) | ||
| 2404 | ) | ||
| 2405 | |||
| 2406 | (defun flymake-simple-make-init(buffer) | ||
| 2407 | (flymake-simple-make-init-impl buffer 'flymake-create-temp-inplace t t "Makefile" 'flymake-get-make-cmdline) | ||
| 2408 | ) | ||
| 2409 | |||
| 2410 | (defun flymake-master-make-init(buffer get-incl-dirs-f master-file-masks include-regexp-list) | ||
| 2411 | "create make command line for a source file checked via master file compilation" | ||
| 2412 | (let* ((make-args nil) | ||
| 2413 | (temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy | ||
| 2414 | buffer get-incl-dirs-f 'flymake-create-temp-inplace | ||
| 2415 | master-file-masks include-regexp-list))) | ||
| 2416 | (when temp-master-file-name | ||
| 2417 | (let* ((buildfile-dir (flymake-init-find-buildfile-dir buffer temp-master-file-name "Makefile"))) | ||
| 2418 | (if buildfile-dir | ||
| 2419 | (setq make-args (flymake-get-syntax-check-program-args | ||
| 2420 | temp-master-file-name buildfile-dir nil nil 'flymake-get-make-cmdline)) | ||
| 2421 | ) | ||
| 2422 | ) | ||
| 2423 | ) | ||
| 2424 | |||
| 2425 | make-args | ||
| 2426 | ) | ||
| 2427 | ) | ||
| 2428 | |||
| 2429 | (defun flymake-find-make-buildfile(source-dir) | ||
| 2430 | (flymake-find-buildfile "Makefile" source-dir flymake-buildfile-dirs) | ||
| 2431 | ) | ||
| 2432 | |||
| 2433 | ;;;; .h/make specific | ||
| 2434 | (defun flymake-master-make-header-init(buffer) | ||
| 2435 | (flymake-master-make-init buffer | ||
| 2436 | 'flymake-get-include-dirs | ||
| 2437 | '(".+\\.cpp$" ".+\\.c$") | ||
| 2438 | '("[ \t]*#[ \t]*include[ \t]*\"\\([\w0-9/\\_\.]*[/\\]*\\)\\(%s\\)\"" 1 2)) | ||
| 2439 | ) | ||
| 2440 | |||
| 2441 | ;;;; .java/make specific | ||
| 2442 | (defun flymake-simple-make-java-init(buffer) | ||
| 2443 | (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "Makefile" 'flymake-get-make-cmdline) | ||
| 2444 | ) | ||
| 2445 | |||
| 2446 | (defun flymake-simple-ant-java-init(buffer) | ||
| 2447 | (flymake-simple-make-init-impl buffer 'flymake-create-temp-with-folder-structure nil nil "build.xml" 'flymake-get-ant-cmdline) | ||
| 2448 | ) | ||
| 2449 | |||
| 2450 | (defun flymake-simple-java-cleanup(buffer) | ||
| 2451 | "cleanup after flymake-simple-make-java-init -- delete temp file and dirs" | ||
| 2452 | (let* ((temp-source-file-name (flymake-get-buffer-value buffer "temp-source-file-name"))) | ||
| 2453 | (flymake-safe-delete-file temp-source-file-name) | ||
| 2454 | (when temp-source-file-name | ||
| 2455 | (flymake-delete-temp-directory (file-name-directory temp-source-file-name)) | ||
| 2456 | ) | ||
| 2457 | ) | ||
| 2458 | ) | ||
| 2459 | |||
| 2460 | ;;;; perl-specific init-cleanup routines | ||
| 2461 | |||
| 2462 | (defun flymake-perl-init(buffer) | ||
| 2463 | (let* ((temp-file (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)) | ||
| 2464 | (local-file (concat (flymake-build-relative-path (file-name-directory (buffer-file-name (current-buffer))) | ||
| 2465 | (file-name-directory temp-file)) | ||
| 2466 | (file-name-nondirectory temp-file)))) | ||
| 2467 | (list "perl" (list "-wc " local-file)) | ||
| 2468 | ) | ||
| 2469 | ) | ||
| 2470 | |||
| 2471 | ;;;; tex-specific init-cleanup routines | ||
| 2472 | |||
| 2473 | (defun flymake-get-tex-args(file-name) | ||
| 2474 | ;(list "latex" (list "-c-style-errors" file-name)) | ||
| 2475 | (list "texify" (list "--pdf" "--tex-option=-c-style-errors" file-name)) | ||
| 2476 | ) | ||
| 2477 | |||
| 2478 | (defun flymake-simple-tex-init(buffer) | ||
| 2479 | (flymake-get-tex-args (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace)) | ||
| 2480 | ) | ||
| 2481 | |||
| 2482 | (defun flymake-master-tex-init(buffer) | ||
| 2483 | (let* ((temp-master-file-name (flymake-init-create-temp-source-and-master-buffer-copy | ||
| 2484 | buffer 'flymake-get-include-dirs-dot 'flymake-create-temp-inplace | ||
| 2485 | '(".+\\.tex$") | ||
| 2486 | '("[ \t]*\\input[ \t]*{\\(.*\\)\\(%s\\)}" 1 2)))) | ||
| 2487 | (when temp-master-file-name | ||
| 2488 | (flymake-get-tex-args temp-master-file-name) | ||
| 2489 | ) | ||
| 2490 | ) | ||
| 2491 | ) | ||
| 2492 | |||
| 2493 | (defun flymake-get-include-dirs-dot(base-dir) | ||
| 2494 | '(".") | ||
| 2495 | ) | ||
| 2496 | |||
| 2497 | ;;;; xml-specific init-cleanup routines | ||
| 2498 | |||
| 2499 | (defun flymake-xml-init(buffer) | ||
| 2500 | (list "xml" (list "val" (flymake-init-create-temp-buffer-copy buffer 'flymake-create-temp-inplace))) | ||
| 2501 | ) | ||
| 2502 | |||
| 2503 | ;;; arch-tag: 8f0d6090-061d-4cac-8862-7c151c4a02dd | ||
| 2504 | ;;; flymake.el ends here | ||
diff --git a/lisp/progmodes/fortran.el b/lisp/progmodes/fortran.el index f23eabe6e9c..88d41650c07 100644 --- a/lisp/progmodes/fortran.el +++ b/lisp/progmodes/fortran.el | |||
| @@ -1700,8 +1700,7 @@ If ALL is nil, only match comments that start in column > 0." | |||
| 1700 | (while repeat | 1700 | (while repeat |
| 1701 | (setq repeat nil) | 1701 | (setq repeat nil) |
| 1702 | ;; Adapted from f90-find-breakpoint. | 1702 | ;; Adapted from f90-find-breakpoint. |
| 1703 | (re-search-backward fortran-break-delimiters-re | 1703 | (re-search-backward fortran-break-delimiters-re bol) |
| 1704 | (line-beginning-position)) | ||
| 1705 | (if (not fortran-break-before-delimiters) | 1704 | (if (not fortran-break-before-delimiters) |
| 1706 | (if (looking-at fortran-no-break-re) | 1705 | (if (looking-at fortran-no-break-re) |
| 1707 | ;; Deal with cases such as "**" split over | 1706 | ;; Deal with cases such as "**" split over |
diff --git a/lisp/progmodes/gdb-ui.el b/lisp/progmodes/gdb-ui.el index 5163471f47a..2f267787707 100644 --- a/lisp/progmodes/gdb-ui.el +++ b/lisp/progmodes/gdb-ui.el | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | ;;; gdb-ui.el --- User Interface for running GDB | 1 | ;;; gdb-ui.el --- User Interface for running GDB |
| 2 | 2 | ||
| 3 | ;; Author: Nick Roberts <nick@nick.uklinux.net> | 3 | ;; Author: Nick Roberts <nickrob@gnu.org> |
| 4 | ;; Maintainer: FSF | 4 | ;; Maintainer: FSF |
| 5 | ;; Keywords: unix, tools | 5 | ;; Keywords: unix, tools |
| 6 | 6 | ||
| @@ -40,8 +40,15 @@ | |||
| 40 | ;; Kingdon and uses GDB's annotation interface. You don't need to know about | 40 | ;; Kingdon and uses GDB's annotation interface. You don't need to know about |
| 41 | ;; annotations to use this mode as a debugger, but if you are interested | 41 | ;; annotations to use this mode as a debugger, but if you are interested |
| 42 | ;; developing the mode itself, then see the Annotations section in the GDB | 42 | ;; developing the mode itself, then see the Annotations section in the GDB |
| 43 | ;; info manual. Some GDB/MI commands are also used through th CLI command | 43 | ;; info manual. |
| 44 | ;; 'interpreter mi <mi-command>'. | 44 | ;; |
| 45 | ;; GDB developers plan to make the annotation interface obsolete. A new | ||
| 46 | ;; interface called GDB/MI (machine interface) has been designed to replace | ||
| 47 | ;; it. Some GDB/MI commands are used in this file through the CLI command | ||
| 48 | ;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included in the | ||
| 49 | ;; GDB repository for future releases (6.2 onwards) that uses GDB/MI as the | ||
| 50 | ;; primary interface to GDB. It is still under development and is part of a | ||
| 51 | ;; process to migrate Emacs from annotations to GDB/MI. | ||
| 45 | ;; | 52 | ;; |
| 46 | ;; Known Bugs: | 53 | ;; Known Bugs: |
| 47 | ;; | 54 | ;; |
| @@ -53,7 +60,7 @@ | |||
| 53 | (defvar gdb-current-address "main" "Initialisation for Assembler buffer.") | 60 | (defvar gdb-current-address "main" "Initialisation for Assembler buffer.") |
| 54 | (defvar gdb-previous-address nil) | 61 | (defvar gdb-previous-address nil) |
| 55 | (defvar gdb-previous-frame nil) | 62 | (defvar gdb-previous-frame nil) |
| 56 | (defvar gdb-current-frame "main") | 63 | (defvar gdb-current-frame nil) |
| 57 | (defvar gdb-current-language nil) | 64 | (defvar gdb-current-language nil) |
| 58 | (defvar gdb-view-source t "Non-nil means that source code can be viewed.") | 65 | (defvar gdb-view-source t "Non-nil means that source code can be viewed.") |
| 59 | (defvar gdb-selected-view 'source "Code type that user wishes to view.") | 66 | (defvar gdb-selected-view 'source "Code type that user wishes to view.") |
| @@ -63,7 +70,8 @@ | |||
| 63 | (defvar gdb-overlay-arrow-position nil) | 70 | (defvar gdb-overlay-arrow-position nil) |
| 64 | (defvar gdb-variables '() | 71 | (defvar gdb-variables '() |
| 65 | "A list of variables that are local to the GUD buffer.") | 72 | "A list of variables that are local to the GUD buffer.") |
| 66 | 73 | (defvar gdb-server-prefix nil) | |
| 74 | |||
| 67 | ;;;###autoload | 75 | ;;;###autoload |
| 68 | (defun gdba (command-line) | 76 | (defun gdba (command-line) |
| 69 | "Run gdb on program FILE in buffer *gud-FILE*. | 77 | "Run gdb on program FILE in buffer *gud-FILE*. |
| @@ -73,23 +81,34 @@ and source-file directory for your debugger. | |||
| 73 | If `gdb-many-windows' is nil (the default value) then gdb just | 81 | If `gdb-many-windows' is nil (the default value) then gdb just |
| 74 | pops up the GUD buffer unless `gdb-show-main' is t. In this case | 82 | pops up the GUD buffer unless `gdb-show-main' is t. In this case |
| 75 | it starts with two windows: one displaying the GUD buffer and the | 83 | it starts with two windows: one displaying the GUD buffer and the |
| 76 | other with the source file with the main routine of the debugee. | 84 | other with the source file with the main routine of the inferior. |
| 77 | 85 | ||
| 78 | If `gdb-many-windows' is t the layout below will appear | 86 | If `gdb-many-windows' is t, regardless of the value of |
| 79 | regardless of the value of `gdb-show-main' unless | 87 | `gdb-show-main', the layout below will appear unless |
| 80 | `gdb-use-inferior-io-buffer' is nil when the source buffer | 88 | `gdb-use-inferior-io-buffer' is nil when the source buffer |
| 81 | occupies the full width of the frame. Keybindings are given in | 89 | occupies the full width of the frame. Keybindings are given in |
| 82 | relevant buffer. | 90 | relevant buffer. |
| 83 | 91 | ||
| 92 | Watch expressions appear in the speedbar/slowbar. | ||
| 93 | |||
| 94 | The following interactive lisp functions help control operation : | ||
| 95 | |||
| 96 | `gdb-many-windows' - Toggle the number of windows gdb uses. | ||
| 97 | `gdb-restore-windows' - To restore the window layout. | ||
| 98 | |||
| 99 | See Info node `(emacs)GDB Graphical Interface' for a more | ||
| 100 | detailed description of this mode. | ||
| 101 | |||
| 102 | |||
| 84 | --------------------------------------------------------------------- | 103 | --------------------------------------------------------------------- |
| 85 | GDB Toolbar | 104 | GDB Toolbar |
| 86 | --------------------------------------------------------------------- | 105 | --------------------------------------------------------------------- |
| 87 | GUD buffer (I/O of GDB) | Locals buffer | 106 | GUD buffer (I/O of GDB) | Locals buffer |
| 88 | | | 107 | | |
| 89 | | | 108 | | |
| 90 | | | 109 | | |
| 91 | --------------------------------------------------------------------- | 110 | --------------------------------------------------------------------- |
| 92 | Source buffer | Input/Output (of debugee) buffer | 111 | Source buffer | Input/Output (of inferior) buffer |
| 93 | | (comint-mode) | 112 | | (comint-mode) |
| 94 | | | 113 | | |
| 95 | | | 114 | | |
| @@ -98,28 +117,12 @@ Source buffer | Input/Output (of debugee) buffer | |||
| 98 | | | 117 | | |
| 99 | | | 118 | | |
| 100 | --------------------------------------------------------------------- | 119 | --------------------------------------------------------------------- |
| 101 | Stack buffer | Breakpoints buffer | 120 | Stack buffer | Breakpoints buffer |
| 102 | RET gdb-frames-select | SPC gdb-toggle-breakpoint | 121 | RET gdb-frames-select | SPC gdb-toggle-breakpoint |
| 103 | | RET gdb-goto-breakpoint | 122 | | RET gdb-goto-breakpoint |
| 104 | | d gdb-delete-breakpoint | 123 | | d gdb-delete-breakpoint |
| 105 | --------------------------------------------------------------------- | 124 | --------------------------------------------------------------------- |
| 106 | 125 | " | |
| 107 | All the buffers share the toolbar and source should always display in the same | ||
| 108 | window e.g after typing g on a breakpoint in the breakpoints buffer. Breakpoint | ||
| 109 | icons are displayed both by setting a break with gud-break and by typing break | ||
| 110 | in the GUD buffer. | ||
| 111 | |||
| 112 | This works best (depending on the size of your monitor) using most of the | ||
| 113 | screen. | ||
| 114 | |||
| 115 | Displayed expressions appear in separate frames. Arrays may be displayed | ||
| 116 | as slices and visualised using the graph program from plotutils if installed. | ||
| 117 | Pointers in structures may be followed in a tree-like fashion. | ||
| 118 | |||
| 119 | The following interactive lisp functions help control operation : | ||
| 120 | |||
| 121 | `gdb-many-windows' - Toggle the number of windows gdb uses. | ||
| 122 | `gdb-restore-windows' - To restore the window layout." | ||
| 123 | ;; | 126 | ;; |
| 124 | (interactive (list (gud-query-cmdline 'gdba))) | 127 | (interactive (list (gud-query-cmdline 'gdba))) |
| 125 | ;; | 128 | ;; |
| @@ -179,12 +182,17 @@ The following interactive lisp functions help control operation : | |||
| 179 | (setq gdb-current-address "main") | 182 | (setq gdb-current-address "main") |
| 180 | (setq gdb-previous-address nil) | 183 | (setq gdb-previous-address nil) |
| 181 | (setq gdb-previous-frame nil) | 184 | (setq gdb-previous-frame nil) |
| 182 | (setq gdb-current-frame "main") | 185 | (setq gdb-current-frame nil) |
| 183 | (setq gdb-view-source t) | 186 | (setq gdb-view-source t) |
| 184 | (setq gdb-selected-view 'source) | 187 | (setq gdb-selected-view 'source) |
| 185 | (setq gdb-var-list nil) | 188 | (setq gdb-var-list nil) |
| 186 | (setq gdb-var-changed nil) | 189 | (setq gdb-var-changed nil) |
| 187 | (setq gdb-first-prompt nil) | 190 | (setq gdb-first-prompt nil) |
| 191 | (setq gdb-prompting nil) | ||
| 192 | (setq gdb-current-item nil) | ||
| 193 | (setq gdb-pending-triggers nil) | ||
| 194 | (setq gdb-output-sink 'user) | ||
| 195 | (setq gdb-server-prefix "server ") | ||
| 188 | ;; | 196 | ;; |
| 189 | (mapc 'make-local-variable gdb-variables) | 197 | (mapc 'make-local-variable gdb-variables) |
| 190 | (setq gdb-buffer-type 'gdba) | 198 | (setq gdb-buffer-type 'gdba) |
| @@ -213,16 +221,26 @@ speedbar." | |||
| 213 | (require 'tooltip) | 221 | (require 'tooltip) |
| 214 | (let ((expr (tooltip-identifier-from-point (point)))) | 222 | (let ((expr (tooltip-identifier-from-point (point)))) |
| 215 | (if (and (string-equal gdb-current-language "c") | 223 | (if (and (string-equal gdb-current-language "c") |
| 216 | gdb-use-colon-colon-notation) | 224 | gdb-use-colon-colon-notation gdb-current-frame) |
| 217 | (setq expr (concat gdb-current-frame "::" expr))) | 225 | (setq expr (concat gdb-current-frame "::" expr))) |
| 218 | (catch 'already-watched | 226 | (catch 'already-watched |
| 219 | (dolist (var gdb-var-list) | 227 | (dolist (var gdb-var-list) |
| 220 | (if (string-equal expr (car var)) (throw 'already-watched nil))) | 228 | (if (string-equal expr (car var)) (throw 'already-watched nil))) |
| 221 | (set-text-properties 0 (length expr) nil expr) | 229 | (set-text-properties 0 (length expr) nil expr) |
| 222 | (gdb-enqueue-input | 230 | (gdb-enqueue-input |
| 223 | (list (concat "server interpreter mi \"-var-create - * " expr "\"\n") | 231 | (list |
| 232 | (if (eq gud-minor-mode 'gdba) | ||
| 233 | (concat "server interpreter mi \"-var-create - * " expr "\"\n") | ||
| 234 | (concat"-var-create - * " expr "\n")) | ||
| 224 | `(lambda () (gdb-var-create-handler ,expr)))))) | 235 | `(lambda () (gdb-var-create-handler ,expr)))))) |
| 225 | (select-window (get-buffer-window gud-comint-buffer))) | 236 | (select-window (get-buffer-window gud-comint-buffer 'visible))) |
| 237 | |||
| 238 | (defun gdb-goto-info () | ||
| 239 | "Go to Emacs info node: GDB Graphical Interface." | ||
| 240 | (interactive) | ||
| 241 | (select-frame (make-frame)) | ||
| 242 | (require 'info) | ||
| 243 | (Info-goto-node "(emacs)GDB Graphical Interface")) | ||
| 226 | 244 | ||
| 227 | (defconst gdb-var-create-regexp | 245 | (defconst gdb-var-create-regexp |
| 228 | "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"") | 246 | "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"") |
| @@ -306,12 +324,15 @@ speedbar." | |||
| 306 | (setq gdb-var-list (nreverse var-list)))))) | 324 | (setq gdb-var-list (nreverse var-list)))))) |
| 307 | 325 | ||
| 308 | (defun gdb-var-update () | 326 | (defun gdb-var-update () |
| 309 | (if (not (member 'gdb-var-update (gdb-get-pending-triggers))) | 327 | (if (not (member 'gdb-var-update gdb-pending-triggers)) |
| 310 | (progn | 328 | (progn |
| 311 | (gdb-enqueue-input (list "server interpreter mi \"-var-update *\"\n" | 329 | (gdb-enqueue-input |
| 330 | (list | ||
| 331 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) | ||
| 332 | "server interpreter mi \"-var-update *\"\n" | ||
| 333 | "-var-update *\n") | ||
| 312 | 'gdb-var-update-handler)) | 334 | 'gdb-var-update-handler)) |
| 313 | (gdb-set-pending-triggers (cons 'gdb-var-update | 335 | (push 'gdb-var-update gdb-pending-triggers)))) |
| 314 | (gdb-get-pending-triggers)))))) | ||
| 315 | 336 | ||
| 316 | (defconst gdb-var-update-regexp "name=\"\\(.*?\\)\"") | 337 | (defconst gdb-var-update-regexp "name=\"\\(.*?\\)\"") |
| 317 | 338 | ||
| @@ -321,12 +342,15 @@ speedbar." | |||
| 321 | (while (re-search-forward gdb-var-update-regexp nil t) | 342 | (while (re-search-forward gdb-var-update-regexp nil t) |
| 322 | (let ((varnum (match-string 1))) | 343 | (let ((varnum (match-string 1))) |
| 323 | (gdb-enqueue-input | 344 | (gdb-enqueue-input |
| 324 | (list (concat "server interpreter mi \"-var-evaluate-expression " | 345 | (list |
| 325 | varnum "\"\n") | 346 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) |
| 347 | (concat "server interpreter mi \"-var-evaluate-expression " | ||
| 348 | varnum "\"\n") | ||
| 349 | (concat "-var-evaluate-expression " varnum "\n")) | ||
| 326 | `(lambda () (gdb-var-evaluate-expression-handler | 350 | `(lambda () (gdb-var-evaluate-expression-handler |
| 327 | ,varnum t))))))) | 351 | ,varnum t))))))) |
| 328 | (gdb-set-pending-triggers | 352 | (setq gdb-pending-triggers |
| 329 | (delq 'gdb-var-update (gdb-get-pending-triggers)))) | 353 | (delq 'gdb-var-update gdb-pending-triggers))) |
| 330 | 354 | ||
| 331 | (defun gdb-var-delete () | 355 | (defun gdb-var-delete () |
| 332 | "Delete watched expression from the speedbar." | 356 | "Delete watched expression from the speedbar." |
| @@ -339,8 +363,11 @@ speedbar." | |||
| 339 | (varnum (cadr var))) | 363 | (varnum (cadr var))) |
| 340 | (unless (string-match "\\." varnum) | 364 | (unless (string-match "\\." varnum) |
| 341 | (gdb-enqueue-input | 365 | (gdb-enqueue-input |
| 342 | (list (concat "server interpreter mi \"-var-delete " | 366 | (list |
| 343 | varnum "\"\n") | 367 | (if (with-current-buffer gud-comint-buffer |
| 368 | (eq gud-minor-mode 'gdba)) | ||
| 369 | (concat "server interpreter mi \"-var-delete " varnum "\"\n") | ||
| 370 | (concat "-var-delete " varnum "\n")) | ||
| 344 | 'ignore)) | 371 | 'ignore)) |
| 345 | (setq gdb-var-list (delq var gdb-var-list)) | 372 | (setq gdb-var-list (delq var gdb-var-list)) |
| 346 | (dolist (varchild gdb-var-list) | 373 | (dolist (varchild gdb-var-list) |
| @@ -354,8 +381,11 @@ speedbar." | |||
| 354 | (varnum (cadr var)) (value)) | 381 | (varnum (cadr var)) (value)) |
| 355 | (setq value (read-string "New value: ")) | 382 | (setq value (read-string "New value: ")) |
| 356 | (gdb-enqueue-input | 383 | (gdb-enqueue-input |
| 357 | (list (concat "server interpreter mi \"-var-assign " | 384 | (list |
| 358 | varnum " " value "\"\n") | 385 | (if (with-current-buffer gud-comint-buffer |
| 386 | (eq gud-minor-mode 'gdba)) | ||
| 387 | (concat "server interpreter mi \"-var-assign " varnum " " value "\"\n") | ||
| 388 | (concat "-var-assign " varnum " " value "\n")) | ||
| 359 | 'ignore)))) | 389 | 'ignore)))) |
| 360 | 390 | ||
| 361 | (defcustom gdb-show-changed-values t | 391 | (defcustom gdb-show-changed-values t |
| @@ -370,49 +400,25 @@ TEXT is the text of the button we clicked on, a + or - item. | |||
| 370 | TOKEN is data related to this node. | 400 | TOKEN is data related to this node. |
| 371 | INDENT is the current indentation depth." | 401 | INDENT is the current indentation depth." |
| 372 | (cond ((string-match "+" text) ;expand this node | 402 | (cond ((string-match "+" text) ;expand this node |
| 373 | (gdb-var-list-children token)) | 403 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) |
| 404 | (gdb-var-list-children token) | ||
| 405 | (gdbmi-var-list-children token))) | ||
| 374 | ((string-match "-" text) ;contract this node | 406 | ((string-match "-" text) ;contract this node |
| 375 | (dolist (var gdb-var-list) | 407 | (dolist (var gdb-var-list) |
| 376 | (if (string-match (concat token "\\.") (nth 1 var)) | 408 | (if (string-match (concat token "\\.") (nth 1 var)) |
| 377 | (setq gdb-var-list (delq var gdb-var-list)))) | 409 | (setq gdb-var-list (delq var gdb-var-list)))) |
| 378 | (setq gdb-var-changed t)))) | 410 | (setq gdb-var-changed t)))) |
| 379 | |||
| 380 | 411 | ||
| 381 | ;; ====================================================================== | 412 | (defvar gdb-buffer-type nil |
| 382 | ;; | ||
| 383 | ;; In this world, there are gdb variables (of unspecified | ||
| 384 | ;; representation) and buffers associated with those objects. | ||
| 385 | ;; The list of variables is built up by the expansions of | ||
| 386 | ;; def-gdb-variable | ||
| 387 | |||
| 388 | (defmacro def-gdb-var (root-symbol &optional default doc) | ||
| 389 | (let* ((root (symbol-name root-symbol)) | ||
| 390 | (accessor (intern (concat "gdb-get-" root))) | ||
| 391 | (setter (intern (concat "gdb-set-" root))) | ||
| 392 | (name (intern (concat "gdb-" root)))) | ||
| 393 | `(progn | ||
| 394 | (defvar ,name ,default ,doc) | ||
| 395 | (if (not (memq ',name gdb-variables)) | ||
| 396 | (push ',name gdb-variables)) | ||
| 397 | (defun ,accessor () | ||
| 398 | (buffer-local-value ',name gud-comint-buffer)) | ||
| 399 | (defun ,setter (val) | ||
| 400 | (with-current-buffer gud-comint-buffer | ||
| 401 | (setq ,name val)))))) | ||
| 402 | |||
| 403 | (def-gdb-var buffer-type nil | ||
| 404 | "One of the symbols bound in `gdb-buffer-rules'.") | 413 | "One of the symbols bound in `gdb-buffer-rules'.") |
| 405 | 414 | ||
| 406 | (def-gdb-var burst "" | 415 | (defvar gdb-input-queue () |
| 407 | "A string of characters from gdb that have not yet been processed.") | ||
| 408 | |||
| 409 | (def-gdb-var input-queue () | ||
| 410 | "A list of gdb command objects.") | 416 | "A list of gdb command objects.") |
| 411 | 417 | ||
| 412 | (def-gdb-var prompting nil | 418 | (defvar gdb-prompting nil |
| 413 | "True when gdb is idle with no pending input.") | 419 | "True when gdb is idle with no pending input.") |
| 414 | 420 | ||
| 415 | (def-gdb-var output-sink 'user | 421 | (defvar gdb-output-sink 'user |
| 416 | "The disposition of the output of the current gdb command. | 422 | "The disposition of the output of the current gdb command. |
| 417 | Possible values are these symbols: | 423 | Possible values are these symbols: |
| 418 | 424 | ||
| @@ -430,12 +436,14 @@ Possible values are these symbols: | |||
| 430 | gdb mode sends to gdb on its own behalf. | 436 | gdb mode sends to gdb on its own behalf. |
| 431 | post-emacs -- ignore output until the prompt annotation is | 437 | post-emacs -- ignore output until the prompt annotation is |
| 432 | received, then go to USER disposition. | 438 | received, then go to USER disposition. |
| 433 | ") | ||
| 434 | 439 | ||
| 435 | (def-gdb-var current-item nil | 440 | gdba (gdb-ui.el) uses all five values, gdbmi (gdb-mi.el) only two |
| 441 | (user and emacs).") | ||
| 442 | |||
| 443 | (defvar gdb-current-item nil | ||
| 436 | "The most recent command item sent to gdb.") | 444 | "The most recent command item sent to gdb.") |
| 437 | 445 | ||
| 438 | (def-gdb-var pending-triggers '() | 446 | (defvar gdb-pending-triggers '() |
| 439 | "A list of trigger functions that have run later than their output | 447 | "A list of trigger functions that have run later than their output |
| 440 | handlers.") | 448 | handlers.") |
| 441 | 449 | ||
| @@ -479,8 +487,8 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'." | |||
| 479 | (set (make-local-variable 'gdb-buffer-type) key) | 487 | (set (make-local-variable 'gdb-buffer-type) key) |
| 480 | (if (cdr (cdr rules)) | 488 | (if (cdr (cdr rules)) |
| 481 | (funcall (car (cdr (cdr rules))))) | 489 | (funcall (car (cdr (cdr rules))))) |
| 482 | (set (make-local-variable 'gud-comint-buffer) gud-comint-buffer) | 490 | (set (make-local-variable 'gud-minor-mode) |
| 483 | (set (make-local-variable 'gud-minor-mode) 'gdba) | 491 | (with-current-buffer gud-comint-buffer gud-minor-mode)) |
| 484 | (set (make-local-variable 'tool-bar-map) gud-tool-bar-map) | 492 | (set (make-local-variable 'tool-bar-map) gud-tool-bar-map) |
| 485 | new)))) | 493 | new)))) |
| 486 | 494 | ||
| @@ -548,7 +556,7 @@ The key should be one of the cars in `gdb-buffer-rules-assoc'." | |||
| 548 | (define-key map "\C-c\C-d" 'gdb-inferior-io-eof) | 556 | (define-key map "\C-c\C-d" 'gdb-inferior-io-eof) |
| 549 | map)) | 557 | map)) |
| 550 | 558 | ||
| 551 | (define-derived-mode gdb-inferior-io-mode comint-mode "Debuggee I/O" | 559 | (define-derived-mode gdb-inferior-io-mode comint-mode "Inferior I/O" |
| 552 | "Major mode for gdb inferior-io." | 560 | "Major mode for gdb inferior-io." |
| 553 | :syntax-table nil :abbrev-table nil | 561 | :syntax-table nil :abbrev-table nil |
| 554 | ;; We want to use comint because it has various nifty and familiar | 562 | ;; We want to use comint because it has various nifty and familiar |
| @@ -620,20 +628,18 @@ This filter may simply queue output for a later time." | |||
| 620 | ;; is a query, or other non-top-level prompt. | 628 | ;; is a query, or other non-top-level prompt. |
| 621 | 629 | ||
| 622 | (defun gdb-enqueue-input (item) | 630 | (defun gdb-enqueue-input (item) |
| 623 | (if (gdb-get-prompting) | 631 | (if gdb-prompting |
| 624 | (progn | 632 | (progn |
| 625 | (gdb-send-item item) | 633 | (gdb-send-item item) |
| 626 | (gdb-set-prompting nil)) | 634 | (setq gdb-prompting nil)) |
| 627 | (gdb-set-input-queue | 635 | (push item gdb-input-queue))) |
| 628 | (cons item (gdb-get-input-queue))))) | ||
| 629 | 636 | ||
| 630 | (defun gdb-dequeue-input () | 637 | (defun gdb-dequeue-input () |
| 631 | (let ((queue (gdb-get-input-queue))) | 638 | (let ((queue gdb-input-queue)) |
| 632 | (and queue | 639 | (and queue |
| 633 | (let ((last (car (last queue)))) | 640 | (let ((last (car (last queue)))) |
| 634 | (unless (nbutlast queue) (gdb-set-input-queue '())) | 641 | (unless (nbutlast queue) (setq gdb-input-queue '())) |
| 635 | last)))) | 642 | last)))) |
| 636 | |||
| 637 | 643 | ||
| 638 | ;; | 644 | ;; |
| 639 | ;; output -- things gdb prints to emacs | 645 | ;; output -- things gdb prints to emacs |
| @@ -662,6 +668,8 @@ This filter may simply queue output for a later time." | |||
| 662 | ("commands" gdb-subprompt) | 668 | ("commands" gdb-subprompt) |
| 663 | ("overload-choice" gdb-subprompt) | 669 | ("overload-choice" gdb-subprompt) |
| 664 | ("query" gdb-subprompt) | 670 | ("query" gdb-subprompt) |
| 671 | ;; Need this prompt for GDB 6.1 | ||
| 672 | ("nquery" gdb-subprompt) | ||
| 665 | ("prompt-for-continue" gdb-subprompt) | 673 | ("prompt-for-continue" gdb-subprompt) |
| 666 | ("post-prompt" gdb-post-prompt) | 674 | ("post-prompt" gdb-post-prompt) |
| 667 | ("source" gdb-source) | 675 | ("source" gdb-source) |
| @@ -688,89 +696,97 @@ This filter may simply queue output for a later time." | |||
| 688 | (string-to-int (match-string 2 args)))) | 696 | (string-to-int (match-string 2 args)))) |
| 689 | (setq gdb-current-address (match-string 3 args)) | 697 | (setq gdb-current-address (match-string 3 args)) |
| 690 | (setq gdb-view-source t) | 698 | (setq gdb-view-source t) |
| 691 | ;; cover for auto-display output which comes *before* | 699 | ;; cover for auto-display output which comes *before* |
| 692 | ;; stopped annotation | 700 | ;; stopped annotation |
| 693 | (if (eq (gdb-get-output-sink) 'inferior) (gdb-set-output-sink 'user))) | 701 | (if (eq gdb-output-sink 'inferior) (setq gdb-output-sink 'user))) |
| 694 | 702 | ||
| 695 | (defun gdb-send-item (item) | 703 | (defun gdb-send-item (item) |
| 696 | (if gdb-enable-debug-log (push (cons 'send item) gdb-debug-log)) | 704 | (if gdb-enable-debug-log (push (cons 'send item) gdb-debug-log)) |
| 697 | (gdb-set-current-item item) | 705 | (setq gdb-current-item item) |
| 698 | (if (stringp item) | 706 | (with-current-buffer gud-comint-buffer |
| 699 | (progn | 707 | (if (eq gud-minor-mode 'gdba) |
| 700 | (gdb-set-output-sink 'user) | 708 | (progn |
| 701 | (process-send-string (get-buffer-process gud-comint-buffer) item)) | 709 | (if (stringp item) |
| 702 | (progn | 710 | (progn |
| 711 | (setq gdb-output-sink 'user) | ||
| 712 | (process-send-string (get-buffer-process gud-comint-buffer) item)) | ||
| 713 | (progn | ||
| 714 | (gdb-clear-partial-output) | ||
| 715 | (setq gdb-output-sink 'pre-emacs) | ||
| 716 | (process-send-string (get-buffer-process gud-comint-buffer) | ||
| 717 | (car item))))) | ||
| 718 | ; case: eq gud-minor-mode 'gdbmi | ||
| 703 | (gdb-clear-partial-output) | 719 | (gdb-clear-partial-output) |
| 704 | (gdb-set-output-sink 'pre-emacs) | 720 | (setq gdb-output-sink 'emacs) |
| 705 | (process-send-string (get-buffer-process gud-comint-buffer) | 721 | (process-send-string (get-buffer-process gud-comint-buffer) |
| 706 | (car item))))) | 722 | (car item))))) |
| 707 | 723 | ||
| 708 | (defun gdb-pre-prompt (ignored) | 724 | (defun gdb-pre-prompt (ignored) |
| 709 | "An annotation handler for `pre-prompt'. This terminates the collection of | 725 | "An annotation handler for `pre-prompt'. This terminates the collection of |
| 710 | output from a previous command if that happens to be in effect." | 726 | output from a previous command if that happens to be in effect." |
| 711 | (let ((sink (gdb-get-output-sink))) | 727 | (let ((sink gdb-output-sink)) |
| 712 | (cond | 728 | (cond |
| 713 | ((eq sink 'user) t) | 729 | ((eq sink 'user) t) |
| 714 | ((eq sink 'emacs) | 730 | ((eq sink 'emacs) |
| 715 | (gdb-set-output-sink 'post-emacs)) | 731 | (setq gdb-output-sink 'post-emacs)) |
| 716 | (t | 732 | (t |
| 717 | (gdb-set-output-sink 'user) | 733 | (setq gdb-output-sink 'user) |
| 718 | (error "Phase error in gdb-pre-prompt (got %s)" sink))))) | 734 | (error "Phase error in gdb-pre-prompt (got %s)" sink))))) |
| 719 | 735 | ||
| 720 | (defun gdb-prompt (ignored) | 736 | (defun gdb-prompt (ignored) |
| 721 | "An annotation handler for `prompt'. | 737 | "An annotation handler for `prompt'. |
| 722 | This sends the next command (if any) to gdb." | 738 | This sends the next command (if any) to gdb." |
| 723 | (when gdb-first-prompt (gdb-ann3)) | 739 | (when gdb-first-prompt (gdb-ann3)) |
| 724 | (let ((sink (gdb-get-output-sink))) | 740 | (let ((sink gdb-output-sink)) |
| 725 | (cond | 741 | (cond |
| 726 | ((eq sink 'user) t) | 742 | ((eq sink 'user) t) |
| 727 | ((eq sink 'post-emacs) | 743 | ((eq sink 'post-emacs) |
| 728 | (gdb-set-output-sink 'user) | 744 | (setq gdb-output-sink 'user) |
| 729 | (let ((handler | 745 | (let ((handler |
| 730 | (car (cdr (gdb-get-current-item))))) | 746 | (car (cdr gdb-current-item)))) |
| 731 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) | 747 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) |
| 732 | (funcall handler)))) | 748 | (funcall handler)))) |
| 733 | (t | 749 | (t |
| 734 | (gdb-set-output-sink 'user) | 750 | (setq gdb-output-sink 'user) |
| 735 | (error "Phase error in gdb-prompt (got %s)" sink)))) | 751 | (error "Phase error in gdb-prompt (got %s)" sink)))) |
| 736 | (let ((input (gdb-dequeue-input))) | 752 | (let ((input (gdb-dequeue-input))) |
| 737 | (if input | 753 | (if input |
| 738 | (gdb-send-item input) | 754 | (gdb-send-item input) |
| 739 | (progn | 755 | (progn |
| 740 | (gdb-set-prompting t) | 756 | (setq gdb-prompting t) |
| 741 | (gud-display-frame))))) | 757 | (gud-display-frame))))) |
| 742 | 758 | ||
| 743 | (defun gdb-subprompt (ignored) | 759 | (defun gdb-subprompt (ignored) |
| 744 | "An annotation handler for non-top-level prompts." | 760 | "An annotation handler for non-top-level prompts." |
| 745 | (gdb-set-prompting t)) | 761 | (setq gdb-prompting t)) |
| 746 | 762 | ||
| 747 | (defun gdb-starting (ignored) | 763 | (defun gdb-starting (ignored) |
| 748 | "An annotation handler for `starting'. This says that I/O for the | 764 | "An annotation handler for `starting'. This says that I/O for the |
| 749 | subprocess is now the program being debugged, not GDB." | 765 | subprocess is now the program being debugged, not GDB." |
| 750 | (let ((sink (gdb-get-output-sink))) | 766 | (let ((sink gdb-output-sink)) |
| 751 | (cond | 767 | (cond |
| 752 | ((eq sink 'user) | 768 | ((eq sink 'user) |
| 753 | (progn | 769 | (progn |
| 754 | (setq gud-running t) | 770 | (setq gud-running t) |
| 755 | (if gdb-use-inferior-io-buffer | 771 | (if gdb-use-inferior-io-buffer |
| 756 | (gdb-set-output-sink 'inferior)))) | 772 | (setq gdb-output-sink 'inferior)))) |
| 757 | (t (error "Unexpected `starting' annotation"))))) | 773 | (t (error "Unexpected `starting' annotation"))))) |
| 758 | 774 | ||
| 759 | (defun gdb-stopping (ignored) | 775 | (defun gdb-stopping (ignored) |
| 760 | "An annotation handler for `exited' and other annotations which say that I/O | 776 | "An annotation handler for `exited' and other annotations which say that I/O |
| 761 | for the subprocess is now GDB, not the program being debugged." | 777 | for the subprocess is now GDB, not the program being debugged." |
| 762 | (if gdb-use-inferior-io-buffer | 778 | (if gdb-use-inferior-io-buffer |
| 763 | (let ((sink (gdb-get-output-sink))) | 779 | (let ((sink gdb-output-sink)) |
| 764 | (cond | 780 | (cond |
| 765 | ((eq sink 'inferior) | 781 | ((eq sink 'inferior) |
| 766 | (gdb-set-output-sink 'user)) | 782 | (setq gdb-output-sink 'user)) |
| 767 | (t (error "Unexpected stopping annotation")))))) | 783 | (t (error "Unexpected stopping annotation")))))) |
| 768 | 784 | ||
| 769 | (defun gdb-frame-begin (ignored) | 785 | (defun gdb-frame-begin (ignored) |
| 770 | (let ((sink (gdb-get-output-sink))) | 786 | (let ((sink gdb-output-sink)) |
| 771 | (cond | 787 | (cond |
| 772 | ((eq sink 'inferior) | 788 | ((eq sink 'inferior) |
| 773 | (gdb-set-output-sink 'user)) | 789 | (setq gdb-output-sink 'user)) |
| 774 | ((eq sink 'user) t) | 790 | ((eq sink 'user) t) |
| 775 | ((eq sink 'emacs) t) | 791 | ((eq sink 'emacs) t) |
| 776 | (t (error "Unexpected frame-begin annotation (%S)" sink))))) | 792 | (t (error "Unexpected frame-begin annotation (%S)" sink))))) |
| @@ -779,17 +795,17 @@ for the subprocess is now GDB, not the program being debugged." | |||
| 779 | "An annotation handler for `stopped'. It is just like gdb-stopping, except | 795 | "An annotation handler for `stopped'. It is just like gdb-stopping, except |
| 780 | that if we already set the output sink to 'user in gdb-stopping, that is fine." | 796 | that if we already set the output sink to 'user in gdb-stopping, that is fine." |
| 781 | (setq gud-running nil) | 797 | (setq gud-running nil) |
| 782 | (let ((sink (gdb-get-output-sink))) | 798 | (let ((sink gdb-output-sink)) |
| 783 | (cond | 799 | (cond |
| 784 | ((eq sink 'inferior) | 800 | ((eq sink 'inferior) |
| 785 | (gdb-set-output-sink 'user)) | 801 | (setq gdb-output-sink 'user)) |
| 786 | ((eq sink 'user) t) | 802 | ((eq sink 'user) t) |
| 787 | (t (error "Unexpected stopped annotation"))))) | 803 | (t (error "Unexpected stopped annotation"))))) |
| 788 | 804 | ||
| 789 | (defun gdb-post-prompt (ignored) | 805 | (defun gdb-post-prompt (ignored) |
| 790 | "An annotation handler for `post-prompt'. This begins the collection of | 806 | "An annotation handler for `post-prompt'. This begins the collection of |
| 791 | output from the current command if that happens to be appropriate." | 807 | output from the current command if that happens to be appropriate." |
| 792 | (if (not (gdb-get-pending-triggers)) | 808 | (if (not gdb-pending-triggers) |
| 793 | (progn | 809 | (progn |
| 794 | (gdb-get-current-frame) | 810 | (gdb-get-current-frame) |
| 795 | (gdb-invalidate-frames) | 811 | (gdb-invalidate-frames) |
| @@ -806,13 +822,13 @@ output from the current command if that happens to be appropriate." | |||
| 806 | (dolist (var gdb-var-list) | 822 | (dolist (var gdb-var-list) |
| 807 | (setcar (nthcdr 5 var) nil)))) | 823 | (setcar (nthcdr 5 var) nil)))) |
| 808 | (gdb-var-update)))) | 824 | (gdb-var-update)))) |
| 809 | (let ((sink (gdb-get-output-sink))) | 825 | (let ((sink gdb-output-sink)) |
| 810 | (cond | 826 | (cond |
| 811 | ((eq sink 'user) t) | 827 | ((eq sink 'user) t) |
| 812 | ((eq sink 'pre-emacs) | 828 | ((eq sink 'pre-emacs) |
| 813 | (gdb-set-output-sink 'emacs)) | 829 | (setq gdb-output-sink 'emacs)) |
| 814 | (t | 830 | (t |
| 815 | (gdb-set-output-sink 'user) | 831 | (setq gdb-output-sink 'user) |
| 816 | (error "Phase error in gdb-post-prompt (got %s)" sink))))) | 832 | (error "Phase error in gdb-post-prompt (got %s)" sink))))) |
| 817 | 833 | ||
| 818 | (defun gud-gdba-marker-filter (string) | 834 | (defun gud-gdba-marker-filter (string) |
| @@ -874,7 +890,7 @@ output from the current command if that happens to be appropriate." | |||
| 874 | output)) | 890 | output)) |
| 875 | 891 | ||
| 876 | (defun gdb-concat-output (so-far new) | 892 | (defun gdb-concat-output (so-far new) |
| 877 | (let ((sink (gdb-get-output-sink ))) | 893 | (let ((sink gdb-output-sink)) |
| 878 | (cond | 894 | (cond |
| 879 | ((eq sink 'user) (concat so-far new)) | 895 | ((eq sink 'user) (concat so-far new)) |
| 880 | ((or (eq sink 'pre-emacs) (eq sink 'post-emacs)) so-far) | 896 | ((or (eq sink 'pre-emacs) (eq sink 'post-emacs)) so-far) |
| @@ -936,19 +952,17 @@ output from the current command if that happens to be appropriate." | |||
| 936 | `(defun ,name (&optional ignored) | 952 | `(defun ,name (&optional ignored) |
| 937 | (if (and (,demand-predicate) | 953 | (if (and (,demand-predicate) |
| 938 | (not (member ',name | 954 | (not (member ',name |
| 939 | (gdb-get-pending-triggers)))) | 955 | gdb-pending-triggers))) |
| 940 | (progn | 956 | (progn |
| 941 | (gdb-enqueue-input | 957 | (gdb-enqueue-input |
| 942 | (list ,gdb-command ',output-handler)) | 958 | (list ,gdb-command ',output-handler)) |
| 943 | (gdb-set-pending-triggers | 959 | (push ',name gdb-pending-triggers))))) |
| 944 | (cons ',name | ||
| 945 | (gdb-get-pending-triggers))))))) | ||
| 946 | 960 | ||
| 947 | (defmacro def-gdb-auto-update-handler (name trigger buf-key custom-defun) | 961 | (defmacro def-gdb-auto-update-handler (name trigger buf-key custom-defun) |
| 948 | `(defun ,name () | 962 | `(defun ,name () |
| 949 | (gdb-set-pending-triggers | 963 | (setq gdb-pending-triggers |
| 950 | (delq ',trigger | 964 | (delq ',trigger |
| 951 | (gdb-get-pending-triggers))) | 965 | gdb-pending-triggers)) |
| 952 | (let ((buf (gdb-get-buffer ',buf-key))) | 966 | (let ((buf (gdb-get-buffer ',buf-key))) |
| 953 | (and buf | 967 | (and buf |
| 954 | (with-current-buffer buf | 968 | (with-current-buffer buf |
| @@ -1080,7 +1094,7 @@ static char *magick[] = { | |||
| 1080 | (dolist (buffer (buffer-list)) | 1094 | (dolist (buffer (buffer-list)) |
| 1081 | (with-current-buffer buffer | 1095 | (with-current-buffer buffer |
| 1082 | (if (and (eq gud-minor-mode 'gdba) | 1096 | (if (and (eq gud-minor-mode 'gdba) |
| 1083 | (not (string-match "^\*" (buffer-name)))) | 1097 | (not (string-match "\\`\\*.+\\*\\'" (buffer-name)))) |
| 1084 | (gdb-remove-breakpoint-icons (point-min) (point-max))))) | 1098 | (gdb-remove-breakpoint-icons (point-min) (point-max))))) |
| 1085 | (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer) | 1099 | (with-current-buffer (gdb-get-buffer 'gdb-breakpoints-buffer) |
| 1086 | (save-excursion | 1100 | (save-excursion |
| @@ -1112,10 +1126,11 @@ static char *magick[] = { | |||
| 1112 | (save-excursion | 1126 | (save-excursion |
| 1113 | (goto-line (string-to-number line)) | 1127 | (goto-line (string-to-number line)) |
| 1114 | (gdb-put-breakpoint-icon (eq flag ?y))))))))) | 1128 | (gdb-put-breakpoint-icon (eq flag ?y))))))))) |
| 1115 | (end-of-line)))))) | 1129 | (end-of-line))))) |
| 1130 | (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) | ||
| 1116 | 1131 | ||
| 1117 | (defun gdb-mouse-toggle-breakpoint (event) | 1132 | (defun gdb-mouse-toggle-breakpoint (event) |
| 1118 | "Toggle breakpoint with mouse click in left margin." | 1133 | "Toggle breakpoint in left fringe/margin with mouse click" |
| 1119 | (interactive "e") | 1134 | (interactive "e") |
| 1120 | (mouse-minibuffer-check event) | 1135 | (mouse-minibuffer-check event) |
| 1121 | (let ((posn (event-end event))) | 1136 | (let ((posn (event-end event))) |
| @@ -1135,14 +1150,24 @@ static char *magick[] = { | |||
| 1135 | (concat "*breakpoints of " (gdb-get-target-string) "*"))) | 1150 | (concat "*breakpoints of " (gdb-get-target-string) "*"))) |
| 1136 | 1151 | ||
| 1137 | (defun gdb-display-breakpoints-buffer () | 1152 | (defun gdb-display-breakpoints-buffer () |
| 1153 | "Display status of user-settable breakpoints." | ||
| 1138 | (interactive) | 1154 | (interactive) |
| 1139 | (gdb-display-buffer | 1155 | (gdb-display-buffer |
| 1140 | (gdb-get-create-buffer 'gdb-breakpoints-buffer))) | 1156 | (gdb-get-create-buffer 'gdb-breakpoints-buffer))) |
| 1141 | 1157 | ||
| 1158 | (defconst gdb-frame-parameters | ||
| 1159 | '((height . 12) (width . 60) | ||
| 1160 | (unsplittable . t) | ||
| 1161 | (tool-bar-lines . nil) | ||
| 1162 | (menu-bar-lines . nil) | ||
| 1163 | (minibuffer . nil))) | ||
| 1164 | |||
| 1142 | (defun gdb-frame-breakpoints-buffer () | 1165 | (defun gdb-frame-breakpoints-buffer () |
| 1166 | "Display status of user-settable breakpoints in a new frame." | ||
| 1143 | (interactive) | 1167 | (interactive) |
| 1144 | (switch-to-buffer-other-frame | 1168 | (select-frame (make-frame gdb-frame-parameters)) |
| 1145 | (gdb-get-create-buffer 'gdb-breakpoints-buffer))) | 1169 | (switch-to-buffer (gdb-get-create-buffer 'gdb-breakpoints-buffer)) |
| 1170 | (set-window-dedicated-p (selected-window) t)) | ||
| 1146 | 1171 | ||
| 1147 | (defvar gdb-breakpoints-mode-map | 1172 | (defvar gdb-breakpoints-mode-map |
| 1148 | (let ((map (make-sparse-keymap)) | 1173 | (let ((map (make-sparse-keymap)) |
| @@ -1167,7 +1192,9 @@ static char *magick[] = { | |||
| 1167 | (setq mode-name "Breakpoints") | 1192 | (setq mode-name "Breakpoints") |
| 1168 | (use-local-map gdb-breakpoints-mode-map) | 1193 | (use-local-map gdb-breakpoints-mode-map) |
| 1169 | (setq buffer-read-only t) | 1194 | (setq buffer-read-only t) |
| 1170 | (gdb-invalidate-breakpoints)) | 1195 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) |
| 1196 | (gdb-invalidate-breakpoints) | ||
| 1197 | (gdbmi-invalidate-breakpoints))) | ||
| 1171 | 1198 | ||
| 1172 | (defun gdb-toggle-breakpoint () | 1199 | (defun gdb-toggle-breakpoint () |
| 1173 | "Enable/disable the breakpoint at current line." | 1200 | "Enable/disable the breakpoint at current line." |
| @@ -1180,8 +1207,8 @@ static char *magick[] = { | |||
| 1180 | (list | 1207 | (list |
| 1181 | (concat | 1208 | (concat |
| 1182 | (if (eq ?y (char-after (match-beginning 2))) | 1209 | (if (eq ?y (char-after (match-beginning 2))) |
| 1183 | "server disable " | 1210 | gdb-server-prefix "disable " |
| 1184 | "server enable ") | 1211 | gdb-server-prefix "enable ") |
| 1185 | (match-string 1) "\n") | 1212 | (match-string 1) "\n") |
| 1186 | 'ignore))))) | 1213 | 'ignore))))) |
| 1187 | 1214 | ||
| @@ -1192,28 +1219,31 @@ static char *magick[] = { | |||
| 1192 | (if (not (looking-at "\\([0-9]+\\).*point\\s-*\\S-*\\s-*\\(.\\)")) | 1219 | (if (not (looking-at "\\([0-9]+\\).*point\\s-*\\S-*\\s-*\\(.\\)")) |
| 1193 | (error "Not recognized as break/watchpoint line") | 1220 | (error "Not recognized as break/watchpoint line") |
| 1194 | (gdb-enqueue-input | 1221 | (gdb-enqueue-input |
| 1195 | (list (concat "server delete " (match-string 1) "\n") 'ignore)))) | 1222 | (list (concat gdb-server-prefix "delete " (match-string 1) "\n") 'ignore)))) |
| 1196 | 1223 | ||
| 1197 | (defun gdb-goto-breakpoint () | 1224 | (defun gdb-goto-breakpoint () |
| 1198 | "Display the file in the source buffer at the breakpoint specified on the | 1225 | "Display the breakpoint location specified at current line." |
| 1199 | current line." | ||
| 1200 | (interactive) | 1226 | (interactive) |
| 1201 | (save-excursion | 1227 | (save-excursion |
| 1202 | (beginning-of-line 1) | 1228 | (beginning-of-line 1) |
| 1203 | (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) | 1229 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdbmi)) |
| 1204 | (looking-at "\\(\\S-*\\):\\([0-9]+\\)")) | 1230 | (looking-at "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*.\\s-*\\S-*\\s-*\\(\\S-*\\):\\([0-9]+\\)") |
| 1231 | (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) | ||
| 1232 | (looking-at "\\(\\S-*\\):\\([0-9]+\\)"))) | ||
| 1205 | (if (match-string 2) | 1233 | (if (match-string 2) |
| 1206 | (let ((line (match-string 2)) | 1234 | (let ((line (match-string 2)) |
| 1207 | (file (match-string 1))) | 1235 | (file (match-string 1))) |
| 1208 | (save-selected-window | 1236 | (save-selected-window |
| 1209 | (gdb-display-buffer (find-file-noselect | 1237 | (let* ((buf (find-file-noselect (if (file-exists-p file) |
| 1210 | (if (file-exists-p file) | 1238 | file |
| 1211 | file | 1239 | (expand-file-name file gdb-cdir)))) |
| 1212 | (expand-file-name file gdb-cdir)))) | 1240 | (window (gdb-display-buffer buf))) |
| 1213 | (goto-line (string-to-number line)))))) | 1241 | (with-current-buffer buf |
| 1242 | (goto-line (string-to-number line)) | ||
| 1243 | (set-window-point window (point)))))))) | ||
| 1214 | 1244 | ||
| 1215 | (defun gdb-mouse-goto-breakpoint (event) | 1245 | (defun gdb-mouse-goto-breakpoint (event) |
| 1216 | "Display the file in the source buffer at the selected breakpoint." | 1246 | "Display the breakpoint location that you click on." |
| 1217 | (interactive "e") | 1247 | (interactive "e") |
| 1218 | (mouse-set-point event) | 1248 | (mouse-set-point event) |
| 1219 | (gdb-goto-breakpoint)) | 1249 | (gdb-goto-breakpoint)) |
| @@ -1256,14 +1286,17 @@ current line." | |||
| 1256 | (concat "*stack frames of " (gdb-get-target-string) "*"))) | 1286 | (concat "*stack frames of " (gdb-get-target-string) "*"))) |
| 1257 | 1287 | ||
| 1258 | (defun gdb-display-stack-buffer () | 1288 | (defun gdb-display-stack-buffer () |
| 1289 | "Display backtrace of current stack." | ||
| 1259 | (interactive) | 1290 | (interactive) |
| 1260 | (gdb-display-buffer | 1291 | (gdb-display-buffer |
| 1261 | (gdb-get-create-buffer 'gdb-stack-buffer))) | 1292 | (gdb-get-create-buffer 'gdb-stack-buffer))) |
| 1262 | 1293 | ||
| 1263 | (defun gdb-frame-stack-buffer () | 1294 | (defun gdb-frame-stack-buffer () |
| 1295 | "Display backtrace of current stack in a new frame." | ||
| 1264 | (interactive) | 1296 | (interactive) |
| 1265 | (switch-to-buffer-other-frame | 1297 | (select-frame (make-frame gdb-frame-parameters)) |
| 1266 | (gdb-get-create-buffer 'gdb-stack-buffer))) | 1298 | (switch-to-buffer (gdb-get-create-buffer 'gdb-stack-buffer)) |
| 1299 | (set-window-dedicated-p (selected-window) t)) | ||
| 1267 | 1300 | ||
| 1268 | (defvar gdb-frames-mode-map | 1301 | (defvar gdb-frames-mode-map |
| 1269 | (let ((map (make-sparse-keymap))) | 1302 | (let ((map (make-sparse-keymap))) |
| @@ -1281,25 +1314,25 @@ current line." | |||
| 1281 | (setq buffer-read-only t) | 1314 | (setq buffer-read-only t) |
| 1282 | (use-local-map gdb-frames-mode-map) | 1315 | (use-local-map gdb-frames-mode-map) |
| 1283 | (font-lock-mode -1) | 1316 | (font-lock-mode -1) |
| 1284 | (gdb-invalidate-frames)) | 1317 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) |
| 1318 | (gdb-invalidate-frames) | ||
| 1319 | (gdbmi-invalidate-frames))) | ||
| 1285 | 1320 | ||
| 1286 | (defun gdb-get-frame-number () | 1321 | (defun gdb-get-frame-number () |
| 1287 | (save-excursion | 1322 | (save-excursion |
| 1288 | (let* ((pos (re-search-backward "^#\\([0-9]*\\)" nil t)) | 1323 | (let* ((pos (re-search-backward "^#*\\([0-9]*\\)" nil t)) |
| 1289 | (n (or (and pos (match-string-no-properties 1)) "0"))) | 1324 | (n (or (and pos (match-string-no-properties 1)) "0"))) |
| 1290 | n))) | 1325 | n))) |
| 1291 | 1326 | ||
| 1292 | (defun gdb-frames-select () | 1327 | (defun gdb-frames-select () |
| 1293 | "Make the frame on the current line become the current frame and display the | 1328 | "Select the frame and display the relevant source." |
| 1294 | source in the source buffer." | ||
| 1295 | (interactive) | 1329 | (interactive) |
| 1296 | (gdb-enqueue-input | 1330 | (gdb-enqueue-input |
| 1297 | (list (concat "server frame " (gdb-get-frame-number) "\n") 'ignore)) | 1331 | (list (concat gdb-server-prefix "frame " (gdb-get-frame-number) "\n") 'ignore)) |
| 1298 | (gud-display-frame)) | 1332 | (gud-display-frame)) |
| 1299 | 1333 | ||
| 1300 | (defun gdb-frames-mouse-select (event) | 1334 | (defun gdb-frames-mouse-select (event) |
| 1301 | "Make the selected frame become the current frame and display the source in | 1335 | "Select the frame you click on and display the relevant source." |
| 1302 | the source buffer." | ||
| 1303 | (interactive "e") | 1336 | (interactive "e") |
| 1304 | (mouse-set-point event) | 1337 | (mouse-set-point event) |
| 1305 | (gdb-frames-select)) | 1338 | (gdb-frames-select)) |
| @@ -1313,7 +1346,7 @@ the source buffer." | |||
| 1313 | 1346 | ||
| 1314 | (def-gdb-auto-updated-buffer gdb-threads-buffer | 1347 | (def-gdb-auto-updated-buffer gdb-threads-buffer |
| 1315 | gdb-invalidate-threads | 1348 | gdb-invalidate-threads |
| 1316 | "server info threads\n" | 1349 | (concat gdb-server-prefix "info threads\n") |
| 1317 | gdb-info-threads-handler | 1350 | gdb-info-threads-handler |
| 1318 | gdb-info-threads-custom) | 1351 | gdb-info-threads-custom) |
| 1319 | 1352 | ||
| @@ -1332,14 +1365,17 @@ the source buffer." | |||
| 1332 | (concat "*threads of " (gdb-get-target-string) "*"))) | 1365 | (concat "*threads of " (gdb-get-target-string) "*"))) |
| 1333 | 1366 | ||
| 1334 | (defun gdb-display-threads-buffer () | 1367 | (defun gdb-display-threads-buffer () |
| 1368 | "Display IDs of currently known threads." | ||
| 1335 | (interactive) | 1369 | (interactive) |
| 1336 | (gdb-display-buffer | 1370 | (gdb-display-buffer |
| 1337 | (gdb-get-create-buffer 'gdb-threads-buffer))) | 1371 | (gdb-get-create-buffer 'gdb-threads-buffer))) |
| 1338 | 1372 | ||
| 1339 | (defun gdb-frame-threads-buffer () | 1373 | (defun gdb-frame-threads-buffer () |
| 1374 | "Display IDs of currently known threads in a new frame." | ||
| 1340 | (interactive) | 1375 | (interactive) |
| 1341 | (switch-to-buffer-other-frame | 1376 | (select-frame (make-frame gdb-frame-parameters)) |
| 1342 | (gdb-get-create-buffer 'gdb-threads-buffer))) | 1377 | (switch-to-buffer (gdb-get-create-buffer 'gdb-threads-buffer)) |
| 1378 | (set-window-dedicated-p (selected-window) t)) | ||
| 1343 | 1379 | ||
| 1344 | (defvar gdb-threads-mode-map | 1380 | (defvar gdb-threads-mode-map |
| 1345 | (let ((map (make-sparse-keymap))) | 1381 | (let ((map (make-sparse-keymap))) |
| @@ -1351,7 +1387,7 @@ the source buffer." | |||
| 1351 | (defun gdb-threads-mode () | 1387 | (defun gdb-threads-mode () |
| 1352 | "Major mode for gdb frames. | 1388 | "Major mode for gdb frames. |
| 1353 | 1389 | ||
| 1354 | \\{gdb-frames-mode-map}" | 1390 | \\{gdb-threads-mode-map}" |
| 1355 | (setq major-mode 'gdb-threads-mode) | 1391 | (setq major-mode 'gdb-threads-mode) |
| 1356 | (setq mode-name "Threads") | 1392 | (setq mode-name "Threads") |
| 1357 | (setq buffer-read-only t) | 1393 | (setq buffer-read-only t) |
| @@ -1364,16 +1400,14 @@ the source buffer." | |||
| 1364 | (match-string-no-properties 1))) | 1400 | (match-string-no-properties 1))) |
| 1365 | 1401 | ||
| 1366 | (defun gdb-threads-select () | 1402 | (defun gdb-threads-select () |
| 1367 | "Make the thread on the current line become the current thread and display the | 1403 | "Select the thread and display the relevant source." |
| 1368 | source in the source buffer." | ||
| 1369 | (interactive) | 1404 | (interactive) |
| 1370 | (gdb-enqueue-input | 1405 | (gdb-enqueue-input |
| 1371 | (list (concat "thread " (gdb-get-thread-number) "\n") 'ignore)) | 1406 | (list (concat "thread " (gdb-get-thread-number) "\n") 'ignore)) |
| 1372 | (gud-display-frame)) | 1407 | (gud-display-frame)) |
| 1373 | 1408 | ||
| 1374 | (defun gdb-threads-mouse-select (event) | 1409 | (defun gdb-threads-mouse-select (event) |
| 1375 | "Make the selected frame become the current frame and display the source in | 1410 | "Select the thread you click on and display the relevant source." |
| 1376 | the source buffer." | ||
| 1377 | (interactive "e") | 1411 | (interactive "e") |
| 1378 | (mouse-set-point event) | 1412 | (mouse-set-point event) |
| 1379 | (gdb-threads-select)) | 1413 | (gdb-threads-select)) |
| @@ -1387,7 +1421,7 @@ the source buffer." | |||
| 1387 | 1421 | ||
| 1388 | (def-gdb-auto-updated-buffer gdb-registers-buffer | 1422 | (def-gdb-auto-updated-buffer gdb-registers-buffer |
| 1389 | gdb-invalidate-registers | 1423 | gdb-invalidate-registers |
| 1390 | "server info registers\n" | 1424 | (concat gdb-server-prefix "info registers\n") |
| 1391 | gdb-info-registers-handler | 1425 | gdb-info-registers-handler |
| 1392 | gdb-info-registers-custom) | 1426 | gdb-info-registers-custom) |
| 1393 | 1427 | ||
| @@ -1413,14 +1447,17 @@ the source buffer." | |||
| 1413 | (concat "*registers of " (gdb-get-target-string) "*"))) | 1447 | (concat "*registers of " (gdb-get-target-string) "*"))) |
| 1414 | 1448 | ||
| 1415 | (defun gdb-display-registers-buffer () | 1449 | (defun gdb-display-registers-buffer () |
| 1450 | "Display integer register contents." | ||
| 1416 | (interactive) | 1451 | (interactive) |
| 1417 | (gdb-display-buffer | 1452 | (gdb-display-buffer |
| 1418 | (gdb-get-create-buffer 'gdb-registers-buffer))) | 1453 | (gdb-get-create-buffer 'gdb-registers-buffer))) |
| 1419 | 1454 | ||
| 1420 | (defun gdb-frame-registers-buffer () | 1455 | (defun gdb-frame-registers-buffer () |
| 1456 | "Display integer register contents in a new frame." | ||
| 1421 | (interactive) | 1457 | (interactive) |
| 1422 | (switch-to-buffer-other-frame | 1458 | (select-frame (make-frame gdb-frame-parameters)) |
| 1423 | (gdb-get-create-buffer 'gdb-registers-buffer))) | 1459 | (switch-to-buffer (gdb-get-create-buffer 'gdb-registers-buffer)) |
| 1460 | (set-window-dedicated-p (selected-window) t)) | ||
| 1424 | 1461 | ||
| 1425 | ;; | 1462 | ;; |
| 1426 | ;; Locals buffer. | 1463 | ;; Locals buffer. |
| @@ -1438,8 +1475,8 @@ the source buffer." | |||
| 1438 | ;; Abbreviate for arrays and structures. | 1475 | ;; Abbreviate for arrays and structures. |
| 1439 | ;; These can be expanded using gud-display. | 1476 | ;; These can be expanded using gud-display. |
| 1440 | (defun gdb-info-locals-handler nil | 1477 | (defun gdb-info-locals-handler nil |
| 1441 | (gdb-set-pending-triggers (delq 'gdb-invalidate-locals | 1478 | (setq gdb-pending-triggers (delq 'gdb-invalidate-locals |
| 1442 | (gdb-get-pending-triggers))) | 1479 | gdb-pending-triggers)) |
| 1443 | (let ((buf (gdb-get-buffer 'gdb-partial-output-buffer))) | 1480 | (let ((buf (gdb-get-buffer 'gdb-partial-output-buffer))) |
| 1444 | (with-current-buffer buf | 1481 | (with-current-buffer buf |
| 1445 | (goto-char (point-min)) | 1482 | (goto-char (point-min)) |
| @@ -1474,24 +1511,29 @@ the source buffer." | |||
| 1474 | 1511 | ||
| 1475 | \\{gdb-locals-mode-map}" | 1512 | \\{gdb-locals-mode-map}" |
| 1476 | (setq major-mode 'gdb-locals-mode) | 1513 | (setq major-mode 'gdb-locals-mode) |
| 1477 | (setq mode-name "Locals") | 1514 | (setq mode-name (concat "Locals:" gdb-current-frame)) |
| 1478 | (setq buffer-read-only t) | 1515 | (setq buffer-read-only t) |
| 1479 | (use-local-map gdb-locals-mode-map) | 1516 | (use-local-map gdb-locals-mode-map) |
| 1480 | (gdb-invalidate-locals)) | 1517 | (if (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba)) |
| 1518 | (gdb-invalidate-locals) | ||
| 1519 | (gdbmi-invalidate-locals))) | ||
| 1481 | 1520 | ||
| 1482 | (defun gdb-locals-buffer-name () | 1521 | (defun gdb-locals-buffer-name () |
| 1483 | (with-current-buffer gud-comint-buffer | 1522 | (with-current-buffer gud-comint-buffer |
| 1484 | (concat "*locals of " (gdb-get-target-string) "*"))) | 1523 | (concat "*locals of " (gdb-get-target-string) "*"))) |
| 1485 | 1524 | ||
| 1486 | (defun gdb-display-locals-buffer () | 1525 | (defun gdb-display-locals-buffer () |
| 1526 | "Display local variables of current stack and their values." | ||
| 1487 | (interactive) | 1527 | (interactive) |
| 1488 | (gdb-display-buffer | 1528 | (gdb-display-buffer |
| 1489 | (gdb-get-create-buffer 'gdb-locals-buffer))) | 1529 | (gdb-get-create-buffer 'gdb-locals-buffer))) |
| 1490 | 1530 | ||
| 1491 | (defun gdb-frame-locals-buffer () | 1531 | (defun gdb-frame-locals-buffer () |
| 1532 | "Display local variables of current stack and their values in a new frame." | ||
| 1492 | (interactive) | 1533 | (interactive) |
| 1493 | (switch-to-buffer-other-frame | 1534 | (select-frame (make-frame gdb-frame-parameters)) |
| 1494 | (gdb-get-create-buffer 'gdb-locals-buffer))) | 1535 | (switch-to-buffer (gdb-get-create-buffer 'gdb-locals-buffer)) |
| 1536 | (set-window-dedicated-p (selected-window) t)) | ||
| 1495 | 1537 | ||
| 1496 | 1538 | ||
| 1497 | ;;;; Window management | 1539 | ;;;; Window management |
| @@ -1510,9 +1552,9 @@ the source buffer." | |||
| 1510 | #'(lambda (win) | 1552 | #'(lambda (win) |
| 1511 | (if (eq gud-comint-buffer (window-buffer win)) | 1553 | (if (eq gud-comint-buffer (window-buffer win)) |
| 1512 | (set-window-dedicated-p win t)))) | 1554 | (set-window-dedicated-p win t)))) |
| 1513 | (setq answer (get-buffer-window buf)) | 1555 | (setq answer (get-buffer-window buf 'visible)) |
| 1514 | (if (not answer) | 1556 | (if (not answer) |
| 1515 | (let ((window (get-lru-window))) | 1557 | (let ((window (get-lru-window 'visible))) |
| 1516 | (if window | 1558 | (if window |
| 1517 | (progn | 1559 | (progn |
| 1518 | (set-window-buffer window buf) | 1560 | (set-window-buffer window buf) |
| @@ -1523,7 +1565,7 @@ the source buffer." | |||
| 1523 | (if (eq gud-comint-buffer (window-buffer win)) | 1565 | (if (eq gud-comint-buffer (window-buffer win)) |
| 1524 | (set-window-dedicated-p win nil))))) | 1566 | (set-window-dedicated-p win nil))))) |
| 1525 | (if must-split | 1567 | (if must-split |
| 1526 | (let* ((largest (get-largest-window)) | 1568 | (let* ((largest (get-largest-window 'visible)) |
| 1527 | (cur-size (window-height largest)) | 1569 | (cur-size (window-height largest)) |
| 1528 | (new-size (and size (< size cur-size) (- cur-size size)))) | 1570 | (new-size (and size (< size cur-size) (- cur-size size)))) |
| 1529 | (setq answer (split-window largest new-size)) | 1571 | (setq answer (split-window largest new-size)) |
| @@ -1532,11 +1574,9 @@ the source buffer." | |||
| 1532 | 1574 | ||
| 1533 | (defun gdb-display-source-buffer (buffer) | 1575 | (defun gdb-display-source-buffer (buffer) |
| 1534 | (if (eq gdb-selected-view 'source) | 1576 | (if (eq gdb-selected-view 'source) |
| 1535 | (progn | ||
| 1536 | (gdb-display-buffer buffer) | 1577 | (gdb-display-buffer buffer) |
| 1537 | (get-buffer-window buffer)) | 1578 | (gdb-display-buffer (gdb-get-buffer 'gdb-assembler-buffer))) |
| 1538 | (gdb-display-buffer (gdb-get-buffer 'gdb-assembler-buffer)) | 1579 | (get-buffer-window buffer 'visible)) |
| 1539 | nil)) | ||
| 1540 | 1580 | ||
| 1541 | 1581 | ||
| 1542 | ;;; Shared keymap initialization: | 1582 | ;;; Shared keymap initialization: |
| @@ -1545,25 +1585,23 @@ the source buffer." | |||
| 1545 | (define-key gud-menu-map [frames] | 1585 | (define-key gud-menu-map [frames] |
| 1546 | `(menu-item "GDB-Frames" ,menu :visible (eq gud-minor-mode 'gdba))) | 1586 | `(menu-item "GDB-Frames" ,menu :visible (eq gud-minor-mode 'gdba))) |
| 1547 | (define-key menu [gdb] '("Gdb" . gdb-frame-gdb-buffer)) | 1587 | (define-key menu [gdb] '("Gdb" . gdb-frame-gdb-buffer)) |
| 1548 | (define-key menu [locals] '("Locals" . gdb-frame-locals-buffer)) | 1588 | (define-key menu [threads] '("Threads" . gdb-frame-threads-buffer)) |
| 1589 | (define-key menu [assembler] '("Machine" . gdb-frame-assembler-buffer)) | ||
| 1549 | (define-key menu [registers] '("Registers" . gdb-frame-registers-buffer)) | 1590 | (define-key menu [registers] '("Registers" . gdb-frame-registers-buffer)) |
| 1591 | (define-key menu [locals] '("Locals" . gdb-frame-locals-buffer)) | ||
| 1550 | (define-key menu [frames] '("Stack" . gdb-frame-stack-buffer)) | 1592 | (define-key menu [frames] '("Stack" . gdb-frame-stack-buffer)) |
| 1551 | (define-key menu [breakpoints] '("Breakpoints" . gdb-frame-breakpoints-buffer)) | 1593 | (define-key menu [breakpoints] '("Breakpoints" . gdb-frame-breakpoints-buffer))) |
| 1552 | (define-key menu [threads] '("Threads" . gdb-frame-threads-buffer)) | ||
| 1553 | ; (define-key menu [assembler] '("Machine" . gdb-frame-assembler-buffer)) | ||
| 1554 | ) | ||
| 1555 | 1594 | ||
| 1556 | (let ((menu (make-sparse-keymap "GDB-Windows"))) | 1595 | (let ((menu (make-sparse-keymap "GDB-Windows"))) |
| 1557 | (define-key gud-menu-map [displays] | 1596 | (define-key gud-menu-map [displays] |
| 1558 | `(menu-item "GDB-Windows" ,menu :visible (eq gud-minor-mode 'gdba))) | 1597 | `(menu-item "GDB-Windows" ,menu :visible (eq gud-minor-mode 'gdba))) |
| 1559 | (define-key menu [gdb] '("Gdb" . gdb-display-gdb-buffer)) | 1598 | (define-key menu [gdb] '("Gdb" . gdb-display-gdb-buffer)) |
| 1560 | (define-key menu [locals] '("Locals" . gdb-display-locals-buffer)) | 1599 | (define-key menu [assembler] '("Machine" . gdb-display-assembler-buffer)) |
| 1600 | (define-key menu [threads] '("Threads" . gdb-display-threads-buffer)) | ||
| 1561 | (define-key menu [registers] '("Registers" . gdb-display-registers-buffer)) | 1601 | (define-key menu [registers] '("Registers" . gdb-display-registers-buffer)) |
| 1602 | (define-key menu [locals] '("Locals" . gdb-display-locals-buffer)) | ||
| 1562 | (define-key menu [frames] '("Stack" . gdb-display-stack-buffer)) | 1603 | (define-key menu [frames] '("Stack" . gdb-display-stack-buffer)) |
| 1563 | (define-key menu [breakpoints] '("Breakpoints" . gdb-display-breakpoints-buffer)) | 1604 | (define-key menu [breakpoints] '("Breakpoints" . gdb-display-breakpoints-buffer))) |
| 1564 | (define-key menu [threads] '("Threads" . gdb-display-threads-buffer)) | ||
| 1565 | ; (define-key menu [assembler] '("Machine" . gdb-display-assembler-buffer)) | ||
| 1566 | ) | ||
| 1567 | 1605 | ||
| 1568 | (let ((menu (make-sparse-keymap "View"))) | 1606 | (let ((menu (make-sparse-keymap "View"))) |
| 1569 | (define-key gud-menu-map [view] | 1607 | (define-key gud-menu-map [view] |
| @@ -1589,11 +1627,14 @@ the source buffer." | |||
| 1589 | "Display locals, stack and breakpoint information"))) | 1627 | "Display locals, stack and breakpoint information"))) |
| 1590 | 1628 | ||
| 1591 | (defun gdb-frame-gdb-buffer () | 1629 | (defun gdb-frame-gdb-buffer () |
| 1630 | "Display GUD buffer in a new frame." | ||
| 1592 | (interactive) | 1631 | (interactive) |
| 1593 | (switch-to-buffer-other-frame | 1632 | (select-frame (make-frame gdb-frame-parameters)) |
| 1594 | (gdb-get-create-buffer 'gdba))) | 1633 | (switch-to-buffer (gdb-get-create-buffer 'gdba)) |
| 1634 | (set-window-dedicated-p (selected-window) t)) | ||
| 1595 | 1635 | ||
| 1596 | (defun gdb-display-gdb-buffer () | 1636 | (defun gdb-display-gdb-buffer () |
| 1637 | "Display GUD buffer." | ||
| 1597 | (interactive) | 1638 | (interactive) |
| 1598 | (gdb-display-buffer | 1639 | (gdb-display-buffer |
| 1599 | (gdb-get-create-buffer 'gdba))) | 1640 | (gdb-get-create-buffer 'gdba))) |
| @@ -1601,6 +1642,7 @@ the source buffer." | |||
| 1601 | (defvar gdb-main-file nil "Source file from which program execution begins.") | 1642 | (defvar gdb-main-file nil "Source file from which program execution begins.") |
| 1602 | 1643 | ||
| 1603 | (defun gdb-view-source-function () | 1644 | (defun gdb-view-source-function () |
| 1645 | "Select source view." | ||
| 1604 | (interactive) | 1646 | (interactive) |
| 1605 | (if gdb-view-source | 1647 | (if gdb-view-source |
| 1606 | (gdb-display-buffer | 1648 | (gdb-display-buffer |
| @@ -1610,8 +1652,10 @@ the source buffer." | |||
| 1610 | (setq gdb-selected-view 'source)) | 1652 | (setq gdb-selected-view 'source)) |
| 1611 | 1653 | ||
| 1612 | (defun gdb-view-assembler() | 1654 | (defun gdb-view-assembler() |
| 1655 | "Select disassembly view." | ||
| 1613 | (interactive) | 1656 | (interactive) |
| 1614 | (gdb-display-buffer (gdb-get-create-buffer 'gdb-assembler-buffer)) | 1657 | (gdb-display-buffer (gdb-get-create-buffer 'gdb-assembler-buffer)) |
| 1658 | (gdb-invalidate-assembler) | ||
| 1615 | (setq gdb-selected-view 'assembler)) | 1659 | (setq gdb-selected-view 'assembler)) |
| 1616 | 1660 | ||
| 1617 | ;(defun gdb-view-both() | 1661 | ;(defun gdb-view-both() |
| @@ -1656,10 +1700,10 @@ the source buffer." | |||
| 1656 | (other-window 1)) | 1700 | (other-window 1)) |
| 1657 | 1701 | ||
| 1658 | (defcustom gdb-many-windows nil | 1702 | (defcustom gdb-many-windows nil |
| 1659 | "Nil (the default value) means just pops up the GUD buffer | 1703 | "Nil (the default value) means just pop up the GUD buffer |
| 1660 | unless `gdb-show-main' is t. In this case it starts with two | 1704 | unless `gdb-show-main' is t. In this case it starts with two |
| 1661 | windows: one displaying the GUD buffer and the other with the | 1705 | windows: one displaying the GUD buffer and the other with the |
| 1662 | source file with the main routine of the debugee. Non-nil means | 1706 | source file with the main routine of the inferior. Non-nil means |
| 1663 | display the layout shown for `gdba'." | 1707 | display the layout shown for `gdba'." |
| 1664 | :type 'boolean | 1708 | :type 'boolean |
| 1665 | :group 'gud) | 1709 | :group 'gud) |
| @@ -1701,15 +1745,15 @@ This arrangement depends on the value of `gdb-many-windows'." | |||
| 1701 | "Exit a debugging session cleanly by killing the gdb buffers and resetting | 1745 | "Exit a debugging session cleanly by killing the gdb buffers and resetting |
| 1702 | the source buffers." | 1746 | the source buffers." |
| 1703 | (dolist (buffer (buffer-list)) | 1747 | (dolist (buffer (buffer-list)) |
| 1704 | (if (not (eq buffer gud-comint-buffer)) | 1748 | (unless (eq buffer gud-comint-buffer) |
| 1705 | (with-current-buffer buffer | 1749 | (with-current-buffer buffer |
| 1706 | (if (memq gud-minor-mode '(gdba pdb)) | 1750 | (if (memq gud-minor-mode '(gdbmi gdba)) |
| 1707 | (if (string-match "^\*.+*$" (buffer-name)) | 1751 | (if (string-match "\\`\\*.+\\*\\'" (buffer-name)) |
| 1708 | (kill-buffer nil) | 1752 | (kill-buffer nil) |
| 1709 | (gdb-remove-breakpoint-icons (point-min) (point-max) t) | 1753 | (gdb-remove-breakpoint-icons (point-min) (point-max) t) |
| 1710 | (setq gud-minor-mode nil) | 1754 | (setq gud-minor-mode nil) |
| 1711 | (kill-local-variable 'tool-bar-map) | 1755 | (kill-local-variable 'tool-bar-map) |
| 1712 | (setq gud-running nil)))))) | 1756 | (setq gud-running nil)))))) |
| 1713 | (when (markerp gdb-overlay-arrow-position) | 1757 | (when (markerp gdb-overlay-arrow-position) |
| 1714 | (move-marker gdb-overlay-arrow-position nil) | 1758 | (move-marker gdb-overlay-arrow-position nil) |
| 1715 | (setq gdb-overlay-arrow-position nil)) | 1759 | (setq gdb-overlay-arrow-position nil)) |
| @@ -1791,11 +1835,10 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1791 | (when (< left-margin-width 2) | 1835 | (when (< left-margin-width 2) |
| 1792 | (save-current-buffer | 1836 | (save-current-buffer |
| 1793 | (setq left-margin-width 2) | 1837 | (setq left-margin-width 2) |
| 1794 | (if (get-buffer-window (current-buffer)) | 1838 | (if (get-buffer-window (current-buffer) 'visible) |
| 1795 | (set-window-margins (get-buffer-window | 1839 | (set-window-margins |
| 1796 | (current-buffer)) | 1840 | (get-buffer-window (current-buffer) 'visible) |
| 1797 | left-margin-width | 1841 | left-margin-width right-margin-width)))) |
| 1798 | right-margin-width)))) | ||
| 1799 | (put-image | 1842 | (put-image |
| 1800 | (if enabled | 1843 | (if enabled |
| 1801 | (or breakpoint-enabled-icon | 1844 | (or breakpoint-enabled-icon |
| @@ -1819,11 +1862,10 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1819 | (when (< left-margin-width 2) | 1862 | (when (< left-margin-width 2) |
| 1820 | (save-current-buffer | 1863 | (save-current-buffer |
| 1821 | (setq left-margin-width 2) | 1864 | (setq left-margin-width 2) |
| 1822 | (if (get-buffer-window (current-buffer)) | 1865 | (if (get-buffer-window (current-buffer) 'visible) |
| 1823 | (set-window-margins (get-buffer-window | 1866 | (set-window-margins |
| 1824 | (current-buffer)) | 1867 | (get-buffer-window (current-buffer) 'visible) |
| 1825 | left-margin-width | 1868 | left-margin-width right-margin-width)))) |
| 1826 | right-margin-width)))) | ||
| 1827 | (gdb-put-string (if enabled "B" "b") (1+ start))))) | 1869 | (gdb-put-string (if enabled "B" "b") (1+ start))))) |
| 1828 | 1870 | ||
| 1829 | (defun gdb-remove-breakpoint-icons (start end &optional remove-margin) | 1871 | (defun gdb-remove-breakpoint-icons (start end &optional remove-margin) |
| @@ -1832,11 +1874,10 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1832 | (remove-images start end)) | 1874 | (remove-images start end)) |
| 1833 | (when remove-margin | 1875 | (when remove-margin |
| 1834 | (setq left-margin-width 0) | 1876 | (setq left-margin-width 0) |
| 1835 | (if (get-buffer-window (current-buffer)) | 1877 | (if (get-buffer-window (current-buffer) 'visible) |
| 1836 | (set-window-margins (get-buffer-window | 1878 | (set-window-margins |
| 1837 | (current-buffer)) | 1879 | (get-buffer-window (current-buffer) 'visible) |
| 1838 | left-margin-width | 1880 | left-margin-width right-margin-width)))) |
| 1839 | right-margin-width)))) | ||
| 1840 | 1881 | ||
| 1841 | 1882 | ||
| 1842 | ;; | 1883 | ;; |
| @@ -1848,7 +1889,7 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1848 | 1889 | ||
| 1849 | (def-gdb-auto-updated-buffer gdb-assembler-buffer | 1890 | (def-gdb-auto-updated-buffer gdb-assembler-buffer |
| 1850 | gdb-invalidate-assembler | 1891 | gdb-invalidate-assembler |
| 1851 | (concat "server disassemble " gdb-current-address "\n") | 1892 | (concat gdb-server-prefix "disassemble " gdb-current-address "\n") |
| 1852 | gdb-assembler-handler | 1893 | gdb-assembler-handler |
| 1853 | gdb-assembler-custom) | 1894 | gdb-assembler-custom) |
| 1854 | 1895 | ||
| @@ -1887,7 +1928,7 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1887 | (if (re-search-forward address nil t) | 1928 | (if (re-search-forward address nil t) |
| 1888 | (gdb-put-breakpoint-icon (eq flag ?y)))))))) | 1929 | (gdb-put-breakpoint-icon (eq flag ?y)))))))) |
| 1889 | (if (not (equal gdb-current-address "main")) | 1930 | (if (not (equal gdb-current-address "main")) |
| 1890 | (set-window-point (get-buffer-window buffer) pos)))) | 1931 | (set-window-point (get-buffer-window buffer 'visible) pos)))) |
| 1891 | 1932 | ||
| 1892 | (defvar gdb-assembler-mode-map | 1933 | (defvar gdb-assembler-mode-map |
| 1893 | (let ((map (make-sparse-keymap))) | 1934 | (let ((map (make-sparse-keymap))) |
| @@ -1913,14 +1954,17 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1913 | (concat "*Machine Code " (gdb-get-target-string) "*"))) | 1954 | (concat "*Machine Code " (gdb-get-target-string) "*"))) |
| 1914 | 1955 | ||
| 1915 | (defun gdb-display-assembler-buffer () | 1956 | (defun gdb-display-assembler-buffer () |
| 1957 | "Display disassembly view." | ||
| 1916 | (interactive) | 1958 | (interactive) |
| 1917 | (gdb-display-buffer | 1959 | (gdb-display-buffer |
| 1918 | (gdb-get-create-buffer 'gdb-assembler-buffer))) | 1960 | (gdb-get-create-buffer 'gdb-assembler-buffer))) |
| 1919 | 1961 | ||
| 1920 | (defun gdb-frame-assembler-buffer () | 1962 | (defun gdb-frame-assembler-buffer () |
| 1963 | "Display disassembly view in a new frame." | ||
| 1921 | (interactive) | 1964 | (interactive) |
| 1922 | (switch-to-buffer-other-frame | 1965 | (select-frame (make-frame gdb-frame-parameters)) |
| 1923 | (gdb-get-create-buffer 'gdb-assembler-buffer))) | 1966 | (switch-to-buffer (gdb-get-create-buffer 'gdb-assembler-buffer)) |
| 1967 | (set-window-dedicated-p (selected-window) t)) | ||
| 1924 | 1968 | ||
| 1925 | ;; modified because if gdb-current-address has changed value a new command | 1969 | ;; modified because if gdb-current-address has changed value a new command |
| 1926 | ;; must be enqueued to update the buffer with the new output | 1970 | ;; must be enqueued to update the buffer with the new output |
| @@ -1929,44 +1973,44 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1929 | (progn | 1973 | (progn |
| 1930 | (unless (string-equal gdb-current-frame gdb-previous-frame) | 1974 | (unless (string-equal gdb-current-frame gdb-previous-frame) |
| 1931 | (if (or (not (member 'gdb-invalidate-assembler | 1975 | (if (or (not (member 'gdb-invalidate-assembler |
| 1932 | (gdb-get-pending-triggers))) | 1976 | gdb-pending-triggers)) |
| 1933 | (not (string-equal gdb-current-address | 1977 | (not (string-equal gdb-current-address |
| 1934 | gdb-previous-address))) | 1978 | gdb-previous-address))) |
| 1935 | (progn | 1979 | (progn |
| 1936 | ;; take previous disassemble command off the queue | 1980 | ;; take previous disassemble command off the queue |
| 1937 | (with-current-buffer gud-comint-buffer | 1981 | (with-current-buffer gud-comint-buffer |
| 1938 | (let ((queue (gdb-get-input-queue)) (item)) | 1982 | (let ((queue gdb-input-queue) (item)) |
| 1939 | (dolist (item queue) | 1983 | (dolist (item queue) |
| 1940 | (if (equal (cdr item) '(gdb-assembler-handler)) | 1984 | (if (equal (cdr item) '(gdb-assembler-handler)) |
| 1941 | (gdb-set-input-queue | 1985 | (setq gdb-input-queue |
| 1942 | (delete item (gdb-get-input-queue))))))) | 1986 | (delete item gdb-input-queue)))))) |
| 1943 | (gdb-enqueue-input | 1987 | (gdb-enqueue-input |
| 1944 | (list (concat "server disassemble " gdb-current-address "\n") | 1988 | (list (concat gdb-server-prefix "disassemble " gdb-current-address "\n") |
| 1945 | 'gdb-assembler-handler)) | 1989 | 'gdb-assembler-handler)) |
| 1946 | (gdb-set-pending-triggers | 1990 | (push 'gdb-invalidate-assembler gdb-pending-triggers) |
| 1947 | (cons 'gdb-invalidate-assembler | ||
| 1948 | (gdb-get-pending-triggers))) | ||
| 1949 | (setq gdb-previous-address gdb-current-address) | 1991 | (setq gdb-previous-address gdb-current-address) |
| 1950 | (setq gdb-previous-frame gdb-current-frame))))))) | 1992 | (setq gdb-previous-frame gdb-current-frame))))))) |
| 1951 | 1993 | ||
| 1952 | (defun gdb-get-current-frame () | 1994 | (defun gdb-get-current-frame () |
| 1953 | (if (not (member 'gdb-get-current-frame (gdb-get-pending-triggers))) | 1995 | (if (not (member 'gdb-get-current-frame gdb-pending-triggers)) |
| 1954 | (progn | 1996 | (progn |
| 1955 | (gdb-enqueue-input | 1997 | (gdb-enqueue-input |
| 1956 | (list (concat "server info frame\n") 'gdb-frame-handler)) | 1998 | (list (concat gdb-server-prefix "info frame\n") 'gdb-frame-handler)) |
| 1957 | (gdb-set-pending-triggers | 1999 | (push 'gdb-get-current-frame |
| 1958 | (cons 'gdb-get-current-frame | 2000 | gdb-pending-triggers)))) |
| 1959 | (gdb-get-pending-triggers)))))) | ||
| 1960 | 2001 | ||
| 1961 | (defun gdb-frame-handler () | 2002 | (defun gdb-frame-handler () |
| 1962 | (gdb-set-pending-triggers | 2003 | (setq gdb-pending-triggers |
| 1963 | (delq 'gdb-get-current-frame (gdb-get-pending-triggers))) | 2004 | (delq 'gdb-get-current-frame gdb-pending-triggers)) |
| 1964 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) | 2005 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) |
| 1965 | (goto-char (point-min)) | 2006 | (goto-char (point-min)) |
| 1966 | (forward-line) | 2007 | (forward-line) |
| 1967 | (if (looking-at ".*=\\s-+0x\\(\\S-*\\)\\s-+in\\s-+\\(\\S-*\\)") | 2008 | (if (looking-at ".*=\\s-+0x\\(\\S-*\\)\\s-+in\\s-+\\(\\S-*?\\);? ") |
| 1968 | (progn | 2009 | (progn |
| 1969 | (setq gdb-current-frame (match-string 2)) | 2010 | (setq gdb-current-frame (match-string 2)) |
| 2011 | (if (gdb-get-buffer 'gdb-locals-buffer) | ||
| 2012 | (with-current-buffer (gdb-get-buffer 'gdb-locals-buffer) | ||
| 2013 | (setq mode-name (concat "Locals:" gdb-current-frame)))) | ||
| 1970 | (let ((address (match-string 1))) | 2014 | (let ((address (match-string 1))) |
| 1971 | ;; remove leading 0s from output of info frame command. | 2015 | ;; remove leading 0s from output of info frame command. |
| 1972 | (if (string-match "^0+\\(.*\\)" address) | 2016 | (if (string-match "^0+\\(.*\\)" address) |
| @@ -1986,5 +2030,5 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1986 | 2030 | ||
| 1987 | (provide 'gdb-ui) | 2031 | (provide 'gdb-ui) |
| 1988 | 2032 | ||
| 1989 | ;;; arch-tag: e9fb00c5-74ef-469f-a088-37384caae352 | 2033 | ;; arch-tag: e9fb00c5-74ef-469f-a088-37384caae352 |
| 1990 | ;;; gdb-ui.el ends here | 2034 | ;;; gdb-ui.el ends here |
diff --git a/lisp/progmodes/grep.el b/lisp/progmodes/grep.el index 94937ba1e87..aa9a50a2580 100644 --- a/lisp/progmodes/grep.el +++ b/lisp/progmodes/grep.el | |||
| @@ -216,7 +216,7 @@ Notice that using \\[next-error] or \\[compile-goto-error] modifies | |||
| 216 | `complation-last-buffer' rather than `grep-last-buffer'.") | 216 | `complation-last-buffer' rather than `grep-last-buffer'.") |
| 217 | 217 | ||
| 218 | (defvar grep-regexp-alist | 218 | (defvar grep-regexp-alist |
| 219 | '(("^\\(.+?\\)[:( \t]+\\([0-9]+\\)[:) \t]" 1 2) | 219 | '(("^\\(.+?\\)[:( \t]+\\([0-9]+\\)\\([:) \t]\\)\\(?:\\([0-9]+\\)\\(?:-\\([0-9]+\\)\\)?\\3\\)?" 1 2 (4 . 5)) |
| 220 | ("^Binary file \\(.+\\) matches$" 1 nil nil 1)) | 220 | ("^Binary file \\(.+\\) matches$" 1 nil nil 1)) |
| 221 | "Regexp used to match grep hits. See `compilation-error-regexp-alist'.") | 221 | "Regexp used to match grep hits. See `compilation-error-regexp-alist'.") |
| 222 | 222 | ||
| @@ -555,7 +555,7 @@ those sub directories of DIR." | |||
| 555 | nil) ;; we change default-directory to dir | 555 | nil) ;; we change default-directory to dir |
| 556 | (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ") | 556 | (and grep-tree-ignore-CVS-directories "-path '*/CVS' -prune -o ") |
| 557 | grep-tree-ignore-case)) | 557 | grep-tree-ignore-case)) |
| 558 | (default-directory dir) | 558 | (default-directory (file-name-as-directory (expand-file-name dir))) |
| 559 | (null-device nil)) ; see grep | 559 | (null-device nil)) ; see grep |
| 560 | (grep command-args regexp))) | 560 | (grep command-args regexp))) |
| 561 | 561 | ||
diff --git a/lisp/progmodes/gud.el b/lisp/progmodes/gud.el index a34b0bb2d48..4ea4fcb6ea2 100644 --- a/lisp/progmodes/gud.el +++ b/lisp/progmodes/gud.el | |||
| @@ -4,7 +4,7 @@ | |||
| 4 | ;; Maintainer: FSF | 4 | ;; Maintainer: FSF |
| 5 | ;; Keywords: unix, tools | 5 | ;; Keywords: unix, tools |
| 6 | 6 | ||
| 7 | ;; Copyright (C) 1992,93,94,95,96,1998,2000,02,2003 Free Software Foundation, Inc. | 7 | ;; Copyright (C) 1992,93,94,95,96,1998,2000,02,03,04 Free Software Foundation, Inc. |
| 8 | 8 | ||
| 9 | ;; This file is part of GNU Emacs. | 9 | ;; This file is part of GNU Emacs. |
| 10 | 10 | ||
| @@ -92,44 +92,44 @@ If SOFT is non-nil, returns nil if the symbol doesn't already exist." | |||
| 92 | Used to grey out relevant toolbar icons.") | 92 | Used to grey out relevant toolbar icons.") |
| 93 | 93 | ||
| 94 | (easy-mmode-defmap gud-menu-map | 94 | (easy-mmode-defmap gud-menu-map |
| 95 | '(([refresh] "Refresh" . gud-refresh) | 95 | '(([help] menu-item "Help" gdb-goto-info |
| 96 | :enable (memq gud-minor-mode '(gdbmi gdba))) | ||
| 97 | ([refresh] "Refresh" . gud-refresh) | ||
| 96 | ([run] menu-item "Run" gud-run | 98 | ([run] menu-item "Run" gud-run |
| 97 | :enable (and (not gud-running) | 99 | :enable (and (not gud-running) |
| 98 | (memq gud-minor-mode '(gdba gdb dbx jdb)))) | 100 | (memq gud-minor-mode '(gdbmi gdba gdb dbx jdb)))) |
| 99 | ([until] menu-item "Continue to selection" gud-until | 101 | ([until] menu-item "Continue to selection" gud-until |
| 100 | :enable (and (not gud-running) | 102 | :enable (and (not gud-running) |
| 101 | (memq gud-minor-mode '(gdba gdb perldb)))) | 103 | (memq gud-minor-mode '(gdbmi gdba gdb perldb)))) |
| 102 | ([remove] menu-item "Remove Breakpoint" gud-remove | 104 | ([remove] menu-item "Remove Breakpoint" gud-remove |
| 103 | :enable (not gud-running)) | 105 | :enable (not gud-running)) |
| 104 | ([tbreak] menu-item "Temporary Breakpoint" gud-tbreak | 106 | ([tbreak] menu-item "Temporary Breakpoint" gud-tbreak |
| 105 | :enable (memq gud-minor-mode '(gdba gdb sdb xdb bashdb))) | 107 | :enable (memq gud-minor-mode '(gdbmi gdba gdb sdb xdb bashdb))) |
| 106 | ([break] menu-item "Set Breakpoint" gud-break | 108 | ([break] menu-item "Set Breakpoint" gud-break |
| 107 | :enable (not gud-running)) | 109 | :enable (not gud-running)) |
| 108 | ([up] menu-item "Up Stack" gud-up | 110 | ([up] menu-item "Up Stack" gud-up |
| 109 | :enable (and (not gud-running) | 111 | :enable (and (not gud-running) |
| 110 | (memq gud-minor-mode | 112 | (memq gud-minor-mode |
| 111 | '(gdba gdb dbx xdb jdb pdb bashdb)))) | 113 | '(gdbmi gdba gdb dbx xdb jdb pdb bashdb)))) |
| 112 | ([down] menu-item "Down Stack" gud-down | 114 | ([down] menu-item "Down Stack" gud-down |
| 113 | :enable (and (not gud-running) | 115 | :enable (and (not gud-running) |
| 114 | (memq gud-minor-mode | 116 | (memq gud-minor-mode |
| 115 | '(gdba gdb dbx xdb jdb pdb bashdb)))) | 117 | '(gdbmi gdba gdb dbx xdb jdb pdb bashdb)))) |
| 116 | ([print] menu-item "Print Expression" gud-print | 118 | ([print] menu-item "Print Expression" gud-print |
| 117 | :enable (not gud-running)) | 119 | :enable (not gud-running)) |
| 118 | ([watch] menu-item "Watch Expression" gud-watch | 120 | ([watch] menu-item "Watch Expression" gud-watch |
| 119 | :enable (and (not gud-running) | 121 | :enable (and (not gud-running) |
| 120 | (eq gud-minor-mode 'gdba))) | 122 | (memq gud-minor-mode '(gdbmi gdba)))) |
| 121 | ([finish] menu-item "Finish Function" gud-finish | 123 | ([finish] menu-item "Finish Function" gud-finish |
| 122 | :enable (and (not gud-running) | 124 | :enable (and (not gud-running) |
| 123 | (memq gud-minor-mode | 125 | (memq gud-minor-mode |
| 124 | '(gdba gdb xdb jdb pdb bashdb)))) | 126 | '(gdbmi gdba gdb xdb jdb pdb bashdb)))) |
| 125 | ([stepi] menu-item "Step Instruction" gud-stepi | 127 | ([stepi] menu-item "Step Instruction" gud-stepi |
| 126 | :enable (and (not gud-running) | 128 | :enable (and (not gud-running) |
| 127 | (memq gud-minor-mode | 129 | (memq gud-minor-mode '(gdbmi gdba gdb dbx)))) |
| 128 | '(gdba gdb dbx)))) | ||
| 129 | ([nexti] menu-item "Next Instruction" gud-nexti | 130 | ([nexti] menu-item "Next Instruction" gud-nexti |
| 130 | :enable (and (not gud-running) | 131 | :enable (and (not gud-running) |
| 131 | (memq gud-minor-mode | 132 | (memq gud-minor-mode '(gdbmi gdba gdb dbx)))) |
| 132 | '(gdba gdb dbx)))) | ||
| 133 | ([step] menu-item "Step Line" gud-step | 133 | ([step] menu-item "Step Line" gud-step |
| 134 | :enable (not gud-running)) | 134 | :enable (not gud-running)) |
| 135 | ([next] menu-item "Next Line" gud-next | 135 | ([next] menu-item "Next Line" gud-next |
| @@ -171,7 +171,8 @@ Used to grey out relevant toolbar icons.") | |||
| 171 | (gud-stepi . "gud-si") | 171 | (gud-stepi . "gud-si") |
| 172 | (gud-nexti . "gud-ni") | 172 | (gud-nexti . "gud-ni") |
| 173 | (gud-up . "gud-up") | 173 | (gud-up . "gud-up") |
| 174 | (gud-down . "gud-down")) | 174 | (gud-down . "gud-down") |
| 175 | (gdb-goto-info . "help")) | ||
| 175 | map) | 176 | map) |
| 176 | (tool-bar-local-item-from-menu | 177 | (tool-bar-local-item-from-menu |
| 177 | (car x) (cdr x) map gud-minor-mode-map))))) | 178 | (car x) (cdr x) map gud-minor-mode-map))))) |
| @@ -312,11 +313,14 @@ t means that there is no stack, and we are in display-file mode.") | |||
| 312 | (defvar gud-speedbar-menu-items | 313 | (defvar gud-speedbar-menu-items |
| 313 | ;; Note to self. Add expand, and turn off items when not available. | 314 | ;; Note to self. Add expand, and turn off items when not available. |
| 314 | '(["Jump to stack frame" speedbar-edit-line | 315 | '(["Jump to stack frame" speedbar-edit-line |
| 315 | (with-current-buffer gud-comint-buffer (not (eq gud-minor-mode 'gdba)))] | 316 | (with-current-buffer gud-comint-buffer |
| 317 | (not (memq gud-minor-mode '(gdbmi gdba))))] | ||
| 316 | ["Edit value" speedbar-edit-line | 318 | ["Edit value" speedbar-edit-line |
| 317 | (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba))] | 319 | (with-current-buffer gud-comint-buffer |
| 320 | (not (memq gud-minor-mode '(gdbmi gdba))))] | ||
| 318 | ["Delete expression" gdb-var-delete | 321 | ["Delete expression" gdb-var-delete |
| 319 | (with-current-buffer gud-comint-buffer (eq gud-minor-mode 'gdba))]) | 322 | (with-current-buffer gud-comint-buffer |
| 323 | (not (memq gud-minor-mode '(gdbmi gdba))))]) | ||
| 320 | "Additional menu items to add to the speedbar frame.") | 324 | "Additional menu items to add to the speedbar frame.") |
| 321 | 325 | ||
| 322 | ;; Make sure our special speedbar mode is loaded | 326 | ;; Make sure our special speedbar mode is loaded |
| @@ -330,7 +334,7 @@ If the GUD BUFFER is not running a supported debugger, then turn | |||
| 330 | off the specialized speedbar mode." | 334 | off the specialized speedbar mode." |
| 331 | (let ((minor-mode (with-current-buffer buffer gud-minor-mode))) | 335 | (let ((minor-mode (with-current-buffer buffer gud-minor-mode))) |
| 332 | (cond | 336 | (cond |
| 333 | ((eq minor-mode 'gdba) | 337 | ((memq minor-mode '(gdbmi gdba)) |
| 334 | (when (or gdb-var-changed | 338 | (when (or gdb-var-changed |
| 335 | (not (save-excursion | 339 | (not (save-excursion |
| 336 | (goto-char (point-min)) | 340 | (goto-char (point-min)) |
| @@ -397,7 +401,7 @@ off the specialized speedbar mode." | |||
| 397 | (speedbar-insert-button (car frame) | 401 | (speedbar-insert-button (car frame) |
| 398 | 'speedbar-file-face | 402 | 'speedbar-file-face |
| 399 | 'speedbar-highlight-face | 403 | 'speedbar-highlight-face |
| 400 | (cond ((memq minor-mode '(gdba gdb)) | 404 | (cond ((memq minor-mode '(gdbmi gdba gdb)) |
| 401 | 'gud-gdb-goto-stackframe) | 405 | 'gud-gdb-goto-stackframe) |
| 402 | (t (error "Should never be here"))) | 406 | (t (error "Should never be here"))) |
| 403 | frame t))) | 407 | frame t))) |
| @@ -1401,7 +1405,7 @@ and source-file directory for your debugger." | |||
| 1401 | 1405 | ||
| 1402 | output)) | 1406 | output)) |
| 1403 | 1407 | ||
| 1404 | (defcustom gud-pdb-command-name "pdb" | 1408 | (defcustom gud-pdb-command-name "pydb" |
| 1405 | "File name for executing the Python debugger. | 1409 | "File name for executing the Python debugger. |
| 1406 | This should be an executable on your path, or an absolute file name." | 1410 | This should be an executable on your path, or an absolute file name." |
| 1407 | :type 'string | 1411 | :type 'string |
| @@ -2339,7 +2343,8 @@ comint mode, which see." | |||
| 2339 | ;; Don't put repeated commands in command history many times. | 2343 | ;; Don't put repeated commands in command history many times. |
| 2340 | (set (make-local-variable 'comint-input-ignoredups) t) | 2344 | (set (make-local-variable 'comint-input-ignoredups) t) |
| 2341 | (make-local-variable 'paragraph-start) | 2345 | (make-local-variable 'paragraph-start) |
| 2342 | (set (make-local-variable 'gud-delete-prompt-marker) (make-marker))) | 2346 | (set (make-local-variable 'gud-delete-prompt-marker) (make-marker)) |
| 2347 | (add-hook 'kill-buffer-hook 'gud-kill-buffer-hook nil t)) | ||
| 2343 | 2348 | ||
| 2344 | ;; Cause our buffers to be displayed, by default, | 2349 | ;; Cause our buffers to be displayed, by default, |
| 2345 | ;; in the selected window. | 2350 | ;; in the selected window. |
| @@ -2384,8 +2389,11 @@ comint mode, which see." | |||
| 2384 | (if (file-name-directory file-subst) | 2389 | (if (file-name-directory file-subst) |
| 2385 | (expand-file-name file-subst) | 2390 | (expand-file-name file-subst) |
| 2386 | file-subst))) | 2391 | file-subst))) |
| 2387 | (filepart (and file-word (concat "-" (file-name-nondirectory file))))) | 2392 | (filepart (and file-word (concat "-" (file-name-nondirectory file)))) |
| 2393 | (existing-buffer (get-buffer (concat "*gud" filepart "*")))) | ||
| 2388 | (pop-to-buffer (concat "*gud" filepart "*")) | 2394 | (pop-to-buffer (concat "*gud" filepart "*")) |
| 2395 | (when (and existing-buffer (get-buffer-process existing-buffer)) | ||
| 2396 | (error "This program is already running under gdb")) | ||
| 2389 | ;; Set the dir, in case the buffer already existed with a different dir. | 2397 | ;; Set the dir, in case the buffer already existed with a different dir. |
| 2390 | (setq default-directory dir) | 2398 | (setq default-directory dir) |
| 2391 | ;; Set default-directory to the file's directory. | 2399 | ;; Set default-directory to the file's directory. |
| @@ -2507,14 +2515,14 @@ It is saved for when this flag is not set.") | |||
| 2507 | ;; Stop displaying an arrow in a source file. | 2515 | ;; Stop displaying an arrow in a source file. |
| 2508 | (setq overlay-arrow-position nil) | 2516 | (setq overlay-arrow-position nil) |
| 2509 | (set-process-buffer proc nil) | 2517 | (set-process-buffer proc nil) |
| 2510 | (if (eq gud-minor-mode-type 'gdba) | 2518 | (if (memq gud-minor-mode-type '(gdbmi gdba)) |
| 2511 | (gdb-reset) | 2519 | (gdb-reset) |
| 2512 | (gud-reset))) | 2520 | (gud-reset))) |
| 2513 | ((memq (process-status proc) '(signal exit)) | 2521 | ((memq (process-status proc) '(signal exit)) |
| 2514 | ;; Stop displaying an arrow in a source file. | 2522 | ;; Stop displaying an arrow in a source file. |
| 2515 | (setq overlay-arrow-position nil) | 2523 | (setq overlay-arrow-position nil) |
| 2516 | (with-current-buffer gud-comint-buffer | 2524 | (with-current-buffer gud-comint-buffer |
| 2517 | (if (eq gud-minor-mode 'gdba) | 2525 | (if (memq gud-minor-mode-type '(gdbmi gdba)) |
| 2518 | (gdb-reset) | 2526 | (gdb-reset) |
| 2519 | (gud-reset))) | 2527 | (gud-reset))) |
| 2520 | (let* ((obuf (current-buffer))) | 2528 | (let* ((obuf (current-buffer))) |
| @@ -2543,19 +2551,18 @@ It is saved for when this flag is not set.") | |||
| 2543 | (set-buffer obuf)))))) | 2551 | (set-buffer obuf)))))) |
| 2544 | 2552 | ||
| 2545 | (defun gud-kill-buffer-hook () | 2553 | (defun gud-kill-buffer-hook () |
| 2546 | (if gud-minor-mode | 2554 | (setq gud-minor-mode-type gud-minor-mode) |
| 2547 | (setq gud-minor-mode-type gud-minor-mode))) | 2555 | (condition-case nil |
| 2548 | 2556 | (kill-process (get-buffer-process gud-comint-buffer)) | |
| 2549 | (add-hook 'kill-buffer-hook 'gud-kill-buffer-hook) | 2557 | (error nil))) |
| 2550 | 2558 | ||
| 2551 | (defun gud-reset () | 2559 | (defun gud-reset () |
| 2552 | (dolist (buffer (buffer-list)) | 2560 | (dolist (buffer (buffer-list)) |
| 2553 | (if (not (eq buffer gud-comint-buffer)) | 2561 | (unless (eq buffer gud-comint-buffer) |
| 2554 | (save-excursion | 2562 | (with-current-buffer buffer |
| 2555 | (set-buffer buffer) | 2563 | (when gud-minor-mode |
| 2556 | (when gud-minor-mode | 2564 | (setq gud-minor-mode nil) |
| 2557 | (setq gud-minor-mode nil) | 2565 | (kill-local-variable 'tool-bar-map)))))) |
| 2558 | (kill-local-variable 'tool-bar-map)))))) | ||
| 2559 | 2566 | ||
| 2560 | (defun gud-display-frame () | 2567 | (defun gud-display-frame () |
| 2561 | "Find and obey the last filename-and-line marker from the debugger. | 2568 | "Find and obey the last filename-and-line marker from the debugger. |
| @@ -2580,7 +2587,7 @@ Obeying it means displaying in another window the specified file and line." | |||
| 2580 | (with-current-buffer gud-comint-buffer | 2587 | (with-current-buffer gud-comint-buffer |
| 2581 | (gud-find-file true-file))) | 2588 | (gud-find-file true-file))) |
| 2582 | (window (and buffer (or (get-buffer-window buffer) | 2589 | (window (and buffer (or (get-buffer-window buffer) |
| 2583 | (if (eq gud-minor-mode 'gdba) | 2590 | (if (memq gud-minor-mode '(gdbmi gdba)) |
| 2584 | (gdb-display-source-buffer buffer) | 2591 | (gdb-display-source-buffer buffer) |
| 2585 | (display-buffer buffer))))) | 2592 | (display-buffer buffer))))) |
| 2586 | (pos)) | 2593 | (pos)) |
| @@ -2704,7 +2711,7 @@ Obeying it means displaying in another window the specified file and line." | |||
| 2704 | (forward-line 0) | 2711 | (forward-line 0) |
| 2705 | (if (looking-at comint-prompt-regexp) | 2712 | (if (looking-at comint-prompt-regexp) |
| 2706 | (set-marker gud-delete-prompt-marker (point))) | 2713 | (set-marker gud-delete-prompt-marker (point))) |
| 2707 | (if (eq gud-minor-mode 'gdba) | 2714 | (if (memq gud-minor-mode '(gdbmi gdba)) |
| 2708 | (apply comint-input-sender (list proc command)) | 2715 | (apply comint-input-sender (list proc command)) |
| 2709 | (process-send-string proc (concat command "\n"))))))) | 2716 | (process-send-string proc (concat command "\n"))))))) |
| 2710 | 2717 | ||
diff --git a/lisp/progmodes/idlw-shell.el b/lisp/progmodes/idlw-shell.el index a600939ef71..ae0c43c2730 100644 --- a/lisp/progmodes/idlw-shell.el +++ b/lisp/progmodes/idlw-shell.el | |||
| @@ -1823,8 +1823,8 @@ Change the default directory for the process buffer to concur." | |||
| 1823 | 'hide 'wait) | 1823 | 'hide 'wait) |
| 1824 | ;; If we don't know anything about the class, update shell routines | 1824 | ;; If we don't know anything about the class, update shell routines |
| 1825 | (if (and idlwave-shell-get-object-class | 1825 | (if (and idlwave-shell-get-object-class |
| 1826 | (not (assoc-ignore-case idlwave-shell-get-object-class | 1826 | (not (assoc-string idlwave-shell-get-object-class |
| 1827 | (idlwave-class-alist)))) | 1827 | (idlwave-class-alist) t))) |
| 1828 | (idlwave-shell-maybe-update-routine-info)) | 1828 | (idlwave-shell-maybe-update-routine-info)) |
| 1829 | idlwave-shell-get-object-class))) | 1829 | idlwave-shell-get-object-class))) |
| 1830 | 1830 | ||
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index bfa507b851a..274480a36de 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -3,6 +3,7 @@ | |||
| 3 | ;; Copyright (C) 2003, 04 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 2003, 04 Free Software Foundation, Inc. |
| 4 | 4 | ||
| 5 | ;; Author: Dave Love <fx@gnu.org> | 5 | ;; Author: Dave Love <fx@gnu.org> |
| 6 | ;; Maintainer: FSF | ||
| 6 | ;; Created: Nov 2003 | 7 | ;; Created: Nov 2003 |
| 7 | ;; Keywords: languages | 8 | ;; Keywords: languages |
| 8 | 9 | ||
| @@ -45,19 +46,18 @@ | |||
| 45 | ;; I've installed a minor mode to do the job properly in Emacs 22. | 46 | ;; I've installed a minor mode to do the job properly in Emacs 22. |
| 46 | ;; Other things seem more natural or canonical here, e.g. the | 47 | ;; Other things seem more natural or canonical here, e.g. the |
| 47 | ;; {beginning,end}-of-defun implementation dealing with nested | 48 | ;; {beginning,end}-of-defun implementation dealing with nested |
| 48 | ;; definitions, and the inferior mode following `cmuscheme'. (The | 49 | ;; definitions, and the inferior mode following `cmuscheme'. The |
| 49 | ;; inferior mode should be able to find the source of errors from | 50 | ;; inferior mode can find the source of errors from |
| 50 | ;; `python-send-region' & al via `compilation-minor-mode', but I can't | 51 | ;; `python-send-region' & al via `compilation-minor-mode'. Successive |
| 51 | ;; make that work with the current (March '04) compile.el.) | 52 | ;; TABs cycle between possible indentations for the line. There is |
| 52 | ;; Successive TABs cycle between possible indentations for the line. | 53 | ;; symbol completion using lookup in Python. |
| 53 | 54 | ||
| 54 | ;; Even where it has similar facilities, this is incompatible with | 55 | ;; Even where it has similar facilities, this is incompatible with |
| 55 | ;; python-mode.el in various respects. For instance, various key | 56 | ;; python-mode.el in various respects. For instance, various key |
| 56 | ;; bindings are changed to obey Emacs conventions, and things like | 57 | ;; bindings are changed to obey Emacs conventions, and things like |
| 57 | ;; marking blocks and `beginning-of-defun' behave differently. | 58 | ;; marking blocks and `beginning-of-defun' behave differently. |
| 58 | 59 | ||
| 59 | ;; TODO: See various Fixmes below. It should be possible to arrange | 60 | ;; TODO: See various Fixmes below. |
| 60 | ;; some sort of completion using the inferior interpreter. | ||
| 61 | 61 | ||
| 62 | ;;; Code: | 62 | ;;; Code: |
| 63 | 63 | ||
| @@ -66,10 +66,8 @@ | |||
| 66 | (require 'comint) | 66 | (require 'comint) |
| 67 | (eval-when-compile | 67 | (eval-when-compile |
| 68 | (require 'compile) | 68 | (require 'compile) |
| 69 | (autoload 'Info-last "info") | ||
| 70 | (autoload 'Info-exit "info") | ||
| 71 | (autoload 'info-lookup-maybe-add-help "info-look")) | 69 | (autoload 'info-lookup-maybe-add-help "info-look")) |
| 72 | (autoload 'compilation-start "compile") ; spurious compiler warning anyway | 70 | (autoload 'compilation-start "compile") |
| 73 | 71 | ||
| 74 | (defgroup python nil | 72 | (defgroup python nil |
| 75 | "Silly walks in the Python language" | 73 | "Silly walks in the Python language" |
| @@ -204,6 +202,8 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 204 | (define-key map "\C-c\C-z" 'python-switch-to-python) | 202 | (define-key map "\C-c\C-z" 'python-switch-to-python) |
| 205 | (define-key map "\C-c\C-m" 'python-load-file) | 203 | (define-key map "\C-c\C-m" 'python-load-file) |
| 206 | (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme | 204 | (define-key map "\C-c\C-l" 'python-load-file) ; a la cmuscheme |
| 205 | (substitute-key-definition 'complete-symbol 'python-complete-symbol | ||
| 206 | map global-map) | ||
| 207 | ;; Fixme: Add :help to menu. | 207 | ;; Fixme: Add :help to menu. |
| 208 | (easy-menu-define python-menu map "Python Mode menu" | 208 | (easy-menu-define python-menu map "Python Mode menu" |
| 209 | '("Python" | 209 | '("Python" |
| @@ -262,9 +262,7 @@ Used for syntactic keywords. N is the match number (1, 2 or 3)." | |||
| 262 | ;;;; Utility stuff | 262 | ;;;; Utility stuff |
| 263 | 263 | ||
| 264 | (defsubst python-in-string/comment () | 264 | (defsubst python-in-string/comment () |
| 265 | "Return non-nil if point is in a Python literal (a comment or string). | 265 | "Return non-nil if point is in a Python literal (a comment or string)." |
| 266 | Optional argument LIM indicates the beginning of the containing form, | ||
| 267 | i.e. the limit on how far back to scan." | ||
| 268 | (syntax-ppss-context (syntax-ppss))) | 266 | (syntax-ppss-context (syntax-ppss))) |
| 269 | 267 | ||
| 270 | (defconst python-space-backslash-table | 268 | (defconst python-space-backslash-table |
| @@ -299,16 +297,18 @@ comments and strings, or that the bracket/paren nesting depth is nonzero." | |||
| 299 | (syntax-ppss (line-beginning-position))))))) | 297 | (syntax-ppss (line-beginning-position))))))) |
| 300 | 298 | ||
| 301 | (defun python-comment-line-p () | 299 | (defun python-comment-line-p () |
| 302 | "Return non-nil if current line has only a comment or is blank." | 300 | "Return non-nil iff current line has only a comment." |
| 303 | (save-excursion | 301 | (save-excursion |
| 304 | (back-to-indentation) | 302 | (end-of-line) |
| 305 | (looking-at (rx (or (syntax comment-start) line-end))))) | 303 | (when (eq 'comment (syntax-ppss-context (syntax-ppss))) |
| 304 | (back-to-indentation) | ||
| 305 | (looking-at (rx (or (syntax comment-start) line-end)))))) | ||
| 306 | 306 | ||
| 307 | (defun python-beginning-of-string () | 307 | (defun python-beginning-of-string () |
| 308 | "Go to beginning of string around point. | 308 | "Go to beginning of string around point. |
| 309 | Do nothing if not in string." | 309 | Do nothing if not in string." |
| 310 | (let ((state (syntax-ppss))) | 310 | (let ((state (syntax-ppss))) |
| 311 | (when (nth 3 state) | 311 | (when (eq 'string (syntax-ppss-context state)) |
| 312 | (goto-char (nth 8 state))))) | 312 | (goto-char (nth 8 state))))) |
| 313 | 313 | ||
| 314 | (defun python-open-block-statement-p (&optional bos) | 314 | (defun python-open-block-statement-p (&optional bos) |
| @@ -323,7 +323,8 @@ BOS non-nil means point is known to be at beginning of statement." | |||
| 323 | line-end)) | 323 | line-end)) |
| 324 | (save-excursion (python-end-of-statement)) | 324 | (save-excursion (python-end-of-statement)) |
| 325 | t) | 325 | t) |
| 326 | (not (python-in-string/comment))))) | 326 | (not (progn (goto-char (match-beginning 0)) |
| 327 | (python-in-string/comment)))))) | ||
| 327 | 328 | ||
| 328 | (defun python-close-block-statement-p (&optional bos) | 329 | (defun python-close-block-statement-p (&optional bos) |
| 329 | "Return non-nil if current line is a statement closing a block. | 330 | "Return non-nil if current line is a statement closing a block. |
| @@ -384,7 +385,8 @@ Otherwise indent them to column zero." | |||
| 384 | (defcustom python-honour-comment-indentation nil | 385 | (defcustom python-honour-comment-indentation nil |
| 385 | "Non-nil means indent relative to preceding comment line. | 386 | "Non-nil means indent relative to preceding comment line. |
| 386 | Only do this for comments where the leading comment character is followed | 387 | Only do this for comments where the leading comment character is followed |
| 387 | by space." | 388 | by space. This doesn't apply to comment lines, which are always indented |
| 389 | in lines with preceding comments." | ||
| 388 | :type 'boolean | 390 | :type 'boolean |
| 389 | :group 'python) | 391 | :group 'python) |
| 390 | 392 | ||
| @@ -514,6 +516,16 @@ Set `python-indent' locally to the value guessed." | |||
| 514 | (- python-indent))) | 516 | (- python-indent))) |
| 515 | 0))))))))) | 517 | 0))))))))) |
| 516 | 518 | ||
| 519 | (defun python-comment-indent () | ||
| 520 | "`comment-indent-function' for Python." | ||
| 521 | ;; If previous non-blank line was a comment, use its indentation. | ||
| 522 | ;; FIXME: This seems unnecessary since the default code delegates to | ||
| 523 | ;; indent-according-to-mode. --Stef | ||
| 524 | (unless (bobp) | ||
| 525 | (save-excursion | ||
| 526 | (forward-comment -1) | ||
| 527 | (if (eq ?# (char-after)) (current-column))))) | ||
| 528 | |||
| 517 | ;;;; Cycling through the possible indentations with successive TABs. | 529 | ;;;; Cycling through the possible indentations with successive TABs. |
| 518 | 530 | ||
| 519 | ;; These don't need to be buffer-local since they're only relevant | 531 | ;; These don't need to be buffer-local since they're only relevant |
| @@ -538,11 +550,17 @@ Set `python-indent' locally to the value guessed." | |||
| 538 | (point)))) | 550 | (point)))) |
| 539 | 551 | ||
| 540 | (defun python-indentation-levels () | 552 | (defun python-indentation-levels () |
| 541 | "Return a list of possible indentations for this statement. | 553 | "Return a list of possible indentations for this line. |
| 542 | Includes the default indentation and those which would close all | 554 | Includes the default indentation and those which would close all |
| 543 | enclosing blocks." | 555 | enclosing blocks. Assumes the line has already been indented per |
| 556 | `python-indent-line'. Elements of the list are actually pairs: | ||
| 557 | \(INDENTATION . TEXT), where TEXT is the initial text of the | ||
| 558 | corresponding block opening (or nil)." | ||
| 544 | (save-excursion | 559 | (save-excursion |
| 545 | (let ((levels (list (cons (current-indentation) nil)))) | 560 | (let ((levels (list (cons (current-indentation) |
| 561 | (save-excursion | ||
| 562 | (if (python-beginning-of-block) | ||
| 563 | (python-initial-text))))))) | ||
| 546 | ;; Only one possibility if we immediately follow a block open or | 564 | ;; Only one possibility if we immediately follow a block open or |
| 547 | ;; are in a continuation line. | 565 | ;; are in a continuation line. |
| 548 | (unless (or (python-continuation-line-p) | 566 | (unless (or (python-continuation-line-p) |
| @@ -568,8 +586,7 @@ enclosing blocks." | |||
| 568 | (if (> (- (point-max) pos) (point)) | 586 | (if (> (- (point-max) pos) (point)) |
| 569 | (goto-char (- (point-max) pos)))))) | 587 | (goto-char (- (point-max) pos)))))) |
| 570 | 588 | ||
| 571 | ;; Fixme: Is the arg necessary? | 589 | (defun python-indent-line () |
| 572 | (defun python-indent-line (&optional arg) | ||
| 573 | "Indent current line as Python code. | 590 | "Indent current line as Python code. |
| 574 | When invoked via `indent-for-tab-command', cycle through possible | 591 | When invoked via `indent-for-tab-command', cycle through possible |
| 575 | indentations for current line. The cycle is broken by a command different | 592 | indentations for current line. The cycle is broken by a command different |
| @@ -586,13 +603,30 @@ from `indent-for-tab-command', i.e. successive TABs do the cycling." | |||
| 586 | (beginning-of-line) | 603 | (beginning-of-line) |
| 587 | (delete-horizontal-space) | 604 | (delete-horizontal-space) |
| 588 | (indent-to (car (nth python-indent-index python-indent-list))) | 605 | (indent-to (car (nth python-indent-index python-indent-list))) |
| 589 | (let ((text (cdr (nth python-indent-index | 606 | (if (python-block-end-p) |
| 590 | python-indent-list)))) | 607 | (let ((text (cdr (nth python-indent-index |
| 591 | (if text (message "Closes: %s" text))))) | 608 | python-indent-list)))) |
| 609 | (if text | ||
| 610 | (message "Closes: %s" text)))))) | ||
| 592 | (python-indent-line-1) | 611 | (python-indent-line-1) |
| 593 | (setq python-indent-list (python-indentation-levels) | 612 | (setq python-indent-list (python-indentation-levels) |
| 594 | python-indent-list-length (length python-indent-list) | 613 | python-indent-list-length (length python-indent-list) |
| 595 | python-indent-index (1- python-indent-list-length))))) | 614 | python-indent-index (1- python-indent-list-length))))) |
| 615 | |||
| 616 | (defun python-block-end-p () | ||
| 617 | "Non-nil if this is a line in a statement closing a block, | ||
| 618 | or a blank line indented to where it would close a block." | ||
| 619 | (and (not (python-comment-line-p)) | ||
| 620 | (or (python-close-block-statement-p t) | ||
| 621 | (< (current-indentation) | ||
| 622 | (save-excursion | ||
| 623 | (python-previous-statement) | ||
| 624 | (current-indentation)))))) | ||
| 625 | |||
| 626 | ;; Fixme: Define an indent-region-function. It should probably leave | ||
| 627 | ;; lines alone if the indentation is already at one of the allowed | ||
| 628 | ;; levels. Otherwise, M-C-\ typically keeps indenting more deeply | ||
| 629 | ;; down a function. | ||
| 596 | 630 | ||
| 597 | ;;;; Movement. | 631 | ;;;; Movement. |
| 598 | 632 | ||
| @@ -629,8 +663,7 @@ start of buffer." | |||
| 629 | "`end-of-defun-function' for Python. | 663 | "`end-of-defun-function' for Python. |
| 630 | Finds end of innermost nested class or method definition." | 664 | Finds end of innermost nested class or method definition." |
| 631 | (let ((orig (point)) | 665 | (let ((orig (point)) |
| 632 | (pattern (rx (and line-start (0+ space) | 666 | (pattern (rx (and line-start (0+ space) (or "def" "class") space)))) |
| 633 | (or "def" "class") space)))) | ||
| 634 | ;; Go to start of current block and check whether it's at top | 667 | ;; Go to start of current block and check whether it's at top |
| 635 | ;; level. If it is, and not a block start, look forward for | 668 | ;; level. If it is, and not a block start, look forward for |
| 636 | ;; definition statement. | 669 | ;; definition statement. |
| @@ -829,7 +862,8 @@ move and return nil. Otherwise return t." | |||
| 829 | Makes nested Imenu menus from nested `class' and `def' statements. | 862 | Makes nested Imenu menus from nested `class' and `def' statements. |
| 830 | The nested menus are headed by an item referencing the outer | 863 | The nested menus are headed by an item referencing the outer |
| 831 | definition; it has a space prepended to the name so that it sorts | 864 | definition; it has a space prepended to the name so that it sorts |
| 832 | first with `imenu--sort-by-name'." | 865 | first with `imenu--sort-by-name' (though, unfortunately, sub-menus |
| 866 | precede it)." | ||
| 833 | (unless (boundp 'python-recursing) ; dynamically bound below | 867 | (unless (boundp 'python-recursing) ; dynamically bound below |
| 834 | (goto-char (point-min))) ; normal call from Imenu | 868 | (goto-char (point-min))) ; normal call from Imenu |
| 835 | (let (index-alist ; accumulated value to return | 869 | (let (index-alist ; accumulated value to return |
| @@ -914,13 +948,20 @@ See `python-check-command' for the default." | |||
| 914 | (file-name-nondirectory name)))))))) | 948 | (file-name-nondirectory name)))))))) |
| 915 | (setq python-saved-check-command command) | 949 | (setq python-saved-check-command command) |
| 916 | (save-some-buffers (not compilation-ask-about-save) nil) | 950 | (save-some-buffers (not compilation-ask-about-save) nil) |
| 917 | (compilation-start command)) | 951 | (let ((compilation-error-regexp-alist |
| 952 | (cons '("(\\([^,]+\\), line \\([0-9]+\\))" 1 2) | ||
| 953 | compilation-error-regexp-alist))) | ||
| 954 | (compilation-start command))) | ||
| 918 | 955 | ||
| 919 | ;;;; Inferior mode stuff (following cmuscheme). | 956 | ;;;; Inferior mode stuff (following cmuscheme). |
| 920 | 957 | ||
| 958 | ;; Fixme: Make sure we can work with IPython. | ||
| 959 | |||
| 921 | (defcustom python-python-command "python" | 960 | (defcustom python-python-command "python" |
| 922 | "*Shell command to run Python interpreter. | 961 | "*Shell command to run Python interpreter. |
| 923 | Any arguments can't contain whitespace." | 962 | Any arguments can't contain whitespace. |
| 963 | Note that IPython may not work properly; it must at least be used with the | ||
| 964 | `-cl' flag, i.e. use `ipython -cl'." | ||
| 924 | :group 'python | 965 | :group 'python |
| 925 | :type 'string) | 966 | :type 'string) |
| 926 | 967 | ||
| @@ -937,40 +978,66 @@ Additional arguments are added when the command is used by `run-python' | |||
| 937 | et al.") | 978 | et al.") |
| 938 | 979 | ||
| 939 | (defvar python-buffer nil | 980 | (defvar python-buffer nil |
| 940 | "*The current python process buffer. | 981 | "The current python process buffer." |
| 941 | To run multiple Python processes, start the first with \\[run-python]. | 982 | ;; Fixme: a single process is currently assumed, so that this doc |
| 942 | It will be in a buffer named *Python*. Rename that with | 983 | ;; is misleading. |
| 943 | \\[rename-buffer]. Now start a new process with \\[run-python]. It | 984 | |
| 944 | will be in a new buffer, named *Python*. Switch between the different | 985 | ;; "*The current python process buffer. |
| 945 | process buffers with \\[switch-to-buffer]. | 986 | ;; To run multiple Python processes, start the first with \\[run-python]. |
| 946 | 987 | ;; It will be in a buffer named *Python*. Rename that with | |
| 947 | Commands that send text from source buffers to Python processes have | 988 | ;; \\[rename-buffer]. Now start a new process with \\[run-python]. It |
| 948 | to choose a process to send to. This is determined by global variable | 989 | ;; will be in a new buffer, named *Python*. Switch between the different |
| 949 | `python-buffer'. Suppose you have three inferior Pythons running: | 990 | ;; process buffers with \\[switch-to-buffer]. |
| 950 | Buffer Process | 991 | |
| 951 | foo python | 992 | ;; Commands that send text from source buffers to Python processes have |
| 952 | bar python<2> | 993 | ;; to choose a process to send to. This is determined by global variable |
| 953 | *Python* python<3> | 994 | ;; `python-buffer'. Suppose you have three inferior Pythons running: |
| 954 | If you do a \\[python-send-region-and-go] command on some Python source | 995 | ;; Buffer Process |
| 955 | code, what process does it go to? | 996 | ;; foo python |
| 956 | 997 | ;; bar python<2> | |
| 957 | - In a process buffer (foo, bar, or *Python*), send it to that process. | 998 | ;; *Python* python<3> |
| 958 | - In some other buffer (e.g. a source file), send it to the process | 999 | ;; If you do a \\[python-send-region-and-go] command on some Python source |
| 959 | attached to `python-buffer'. | 1000 | ;; code, what process does it go to? |
| 960 | Process selection is done by function `python-proc'. | 1001 | |
| 961 | 1002 | ;; - In a process buffer (foo, bar, or *Python*), send it to that process. | |
| 962 | Whenever \\[run-python] starts a new process, it resets `python-buffer' | 1003 | ;; - In some other buffer (e.g. a source file), send it to the process |
| 963 | to be the new process's buffer. If you only run one process, this will | 1004 | ;; attached to `python-buffer'. |
| 964 | do the right thing. If you run multiple processes, you can change | 1005 | ;; Process selection is done by function `python-proc'. |
| 965 | `python-buffer' to another process buffer with \\[set-variable].") | 1006 | |
| 1007 | ;; Whenever \\[run-python] starts a new process, it resets `python-buffer' | ||
| 1008 | ;; to be the new process's buffer. If you only run one process, this will | ||
| 1009 | ;; do the right thing. If you run multiple processes, you can change | ||
| 1010 | ;; `python-buffer' to another process buffer with \\[set-variable]." | ||
| 1011 | ) | ||
| 966 | 1012 | ||
| 967 | (defconst python-compilation-regexp-alist | 1013 | (defconst python-compilation-regexp-alist |
| 1014 | ;; FIXME: maybe these should move to compilation-error-regexp-alist-alist. | ||
| 968 | `((,(rx (and line-start (1+ (any " \t")) "File \"" | 1015 | `((,(rx (and line-start (1+ (any " \t")) "File \"" |
| 969 | (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c | 1016 | (group (1+ (not (any "\"<")))) ; avoid `<stdin>' &c |
| 970 | "\", line " (group (1+ digit)))) | 1017 | "\", line " (group (1+ digit)))) |
| 971 | 1 python-compilation-line-number)) | 1018 | 1 2) |
| 1019 | (,(rx (and " in file " (group (1+ not-newline)) " on line " | ||
| 1020 | (group (1+ digit)))) | ||
| 1021 | 1 2)) | ||
| 972 | "`compilation-error-regexp-alist' for inferior Python.") | 1022 | "`compilation-error-regexp-alist' for inferior Python.") |
| 973 | 1023 | ||
| 1024 | (defvar inferior-python-mode-map | ||
| 1025 | (let ((map (make-sparse-keymap))) | ||
| 1026 | ;; This will inherit from comint-mode-map. | ||
| 1027 | (define-key map "\C-c\C-l" 'python-load-file) | ||
| 1028 | (define-key map "\C-c\C-v" 'python-check) | ||
| 1029 | ;; Note that we _can_ still use these commands which send to the | ||
| 1030 | ;; Python process even at the prompt iff we have a normal prompt, | ||
| 1031 | ;; i.e. '>>> ' and not '... '. See the comment before | ||
| 1032 | ;; python-send-region. Fixme: uncomment these if we address that. | ||
| 1033 | |||
| 1034 | ;; (define-key map [(meta ?\t)] 'python-complete-symbol) | ||
| 1035 | ;; (define-key map "\C-c\C-f" 'python-describe-symbol) | ||
| 1036 | map)) | ||
| 1037 | |||
| 1038 | ;; Fixme: This should inherit some stuff from python-mode, but I'm not | ||
| 1039 | ;; sure how much: at least some keybindings, like C-c C-f; syntax?; | ||
| 1040 | ;; font-locking, e.g. for triple-quoted strings? | ||
| 974 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" | 1041 | (define-derived-mode inferior-python-mode comint-mode "Inferior Python" |
| 975 | "Major mode for interacting with an inferior Python process. | 1042 | "Major mode for interacting with an inferior Python process. |
| 976 | A Python process can be started with \\[run-python]. | 1043 | A Python process can be started with \\[run-python]. |
| @@ -991,14 +1058,13 @@ For running multiple processes in multiple buffers, see `python-buffer'. | |||
| 991 | :group 'python | 1058 | :group 'python |
| 992 | (set-syntax-table python-mode-syntax-table) | 1059 | (set-syntax-table python-mode-syntax-table) |
| 993 | (setq mode-line-process '(":%s")) | 1060 | (setq mode-line-process '(":%s")) |
| 994 | ;; Fixme: Maybe install some python-mode bindings too. | 1061 | (set (make-local-variable 'comint-input-filter) 'python-input-filter) |
| 995 | (define-key inferior-python-mode-map "\C-c\C-l" 'python-load-file) | ||
| 996 | (define-key inferior-python-mode-map "\C-c\C-z" 'python-switch-to-python) | ||
| 997 | (add-hook 'comint-input-filter-functions 'python-input-filter nil t) | ||
| 998 | (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter | 1062 | (add-hook 'comint-preoutput-filter-functions #'python-preoutput-filter |
| 999 | nil t) | 1063 | nil t) |
| 1000 | ;; Still required by `comint-redirect-send-command', for instance: | 1064 | ;; Still required by `comint-redirect-send-command', for instance |
| 1001 | (set (make-local-variable 'comint-prompt-regexp) "^\\([>.]\\{3\\} \\)+") | 1065 | ;; (and we need to match things like `>>> ... >>> '): |
| 1066 | (set (make-local-variable 'comint-prompt-regexp) | ||
| 1067 | (rx (and line-start (1+ (and (repeat 3 (any ">.")) ?\ ))))) | ||
| 1002 | (set (make-local-variable 'compilation-error-regexp-alist) | 1068 | (set (make-local-variable 'compilation-error-regexp-alist) |
| 1003 | python-compilation-regexp-alist) | 1069 | python-compilation-regexp-alist) |
| 1004 | (compilation-shell-minor-mode 1)) | 1070 | (compilation-shell-minor-mode 1)) |
| @@ -1009,15 +1075,9 @@ Default ignores all inputs of 0, 1, or 2 non-blank characters." | |||
| 1009 | :type 'regexp | 1075 | :type 'regexp |
| 1010 | :group 'python) | 1076 | :group 'python) |
| 1011 | 1077 | ||
| 1012 | (defvar python-orig-start nil | ||
| 1013 | "Marker to the start of the region passed to the inferior Python. | ||
| 1014 | It can also be a filename.") | ||
| 1015 | |||
| 1016 | (defun python-input-filter (str) | 1078 | (defun python-input-filter (str) |
| 1017 | "`comint-input-filter' function for inferior Python. | 1079 | "`comint-input-filter' function for inferior Python. |
| 1018 | Don't save anything for STR matching `inferior-python-filter-regexp'. | 1080 | Don't save anything for STR matching `inferior-python-filter-regexp'." |
| 1019 | Also resets variables for adjusting error messages." | ||
| 1020 | (setq python-orig-start nil) | ||
| 1021 | (not (string-match inferior-python-filter-regexp str))) | 1081 | (not (string-match inferior-python-filter-regexp str))) |
| 1022 | 1082 | ||
| 1023 | ;; Fixme: Loses with quoted whitespace. | 1083 | ;; Fixme: Loses with quoted whitespace. |
| @@ -1030,21 +1090,8 @@ Also resets variables for adjusting error messages." | |||
| 1030 | (t (let ((pos (string-match "[^ \t]" string))) | 1090 | (t (let ((pos (string-match "[^ \t]" string))) |
| 1031 | (if pos (python-args-to-list (substring string pos)))))))) | 1091 | (if pos (python-args-to-list (substring string pos)))))))) |
| 1032 | 1092 | ||
| 1033 | (defun python-compilation-line-number (file col) | ||
| 1034 | "Return error descriptor of error found for FILE, column COL. | ||
| 1035 | Used as line-number hook function in `python-compilation-regexp-alist'." | ||
| 1036 | (let ((line (string-to-number (match-string 2)))) | ||
| 1037 | (cons (point-marker) | ||
| 1038 | (if (and (markerp python-orig-start) | ||
| 1039 | (marker-buffer python-orig-start)) | ||
| 1040 | (with-current-buffer (marker-buffer python-orig-start) | ||
| 1041 | (goto-char python-orig-start) | ||
| 1042 | (forward-line (1- line))) | ||
| 1043 | (list (if (stringp python-orig-start) python-orig-start file) | ||
| 1044 | line nil))))) | ||
| 1045 | |||
| 1046 | (defvar python-preoutput-result nil | 1093 | (defvar python-preoutput-result nil |
| 1047 | "Data from output line last `_emacs_out' line seen by the preoutput filter.") | 1094 | "Data from last `_emacs_out' line seen by the preoutput filter.") |
| 1048 | 1095 | ||
| 1049 | (defvar python-preoutput-continuation nil | 1096 | (defvar python-preoutput-continuation nil |
| 1050 | "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") | 1097 | "If non-nil, funcall this when `python-preoutput-filter' sees `_emacs_ok'.") |
| @@ -1055,7 +1102,9 @@ Used as line-number hook function in `python-compilation-regexp-alist'." | |||
| 1055 | ;; `python-preoutput-continuation' if we get it. | 1102 | ;; `python-preoutput-continuation' if we get it. |
| 1056 | (defun python-preoutput-filter (s) | 1103 | (defun python-preoutput-filter (s) |
| 1057 | "`comint-preoutput-filter-functions' function: ignore prompts not at bol." | 1104 | "`comint-preoutput-filter-functions' function: ignore prompts not at bol." |
| 1058 | (cond ((and (string-match "\\`[.>]\\{3\\} \\'" s) | 1105 | (cond ((and (string-match (rx (and string-start (repeat 3 (any ".>")) |
| 1106 | " " string-end)) | ||
| 1107 | s) | ||
| 1059 | (/= (let ((inhibit-field-text-motion t)) | 1108 | (/= (let ((inhibit-field-text-motion t)) |
| 1060 | (line-beginning-position)) | 1109 | (line-beginning-position)) |
| 1061 | (point))) | 1110 | (point))) |
| @@ -1076,10 +1125,10 @@ Used as line-number hook function in `python-compilation-regexp-alist'." | |||
| 1076 | CMD is the Python command to run. NOSHOW non-nil means don't show the | 1125 | CMD is the Python command to run. NOSHOW non-nil means don't show the |
| 1077 | buffer automatically. | 1126 | buffer automatically. |
| 1078 | If there is a process already running in `*Python*', switch to | 1127 | If there is a process already running in `*Python*', switch to |
| 1079 | that buffer. Interactively a prefix arg, allows you to edit the initial | 1128 | that buffer. Interactively, a prefix arg allows you to edit the initial |
| 1080 | command line (default is the value of `python-command'); `-i' etc. args | 1129 | command line (default is `python-command'); `-i' etc. args will be added |
| 1081 | will be added to this as appropriate. Runs the hooks | 1130 | to this as appropriate. Runs the hook `inferior-python-mode-hook' |
| 1082 | `inferior-python-mode-hook' (after the `comint-mode-hook' is run). | 1131 | \(after the `comint-mode-hook' is run). |
| 1083 | \(Type \\[describe-mode] in the process buffer for a list of commands.)" | 1132 | \(Type \\[describe-mode] in the process buffer for a list of commands.)" |
| 1084 | (interactive (list (if current-prefix-arg | 1133 | (interactive (list (if current-prefix-arg |
| 1085 | (read-string "Run Python: " python-command) | 1134 | (read-string "Run Python: " python-command) |
| @@ -1089,82 +1138,78 @@ will be added to this as appropriate. Runs the hooks | |||
| 1089 | ;; Fixme: Consider making `python-buffer' buffer-local as a buffer | 1138 | ;; Fixme: Consider making `python-buffer' buffer-local as a buffer |
| 1090 | ;; (not a name) in Python buffers from which `run-python' &c is | 1139 | ;; (not a name) in Python buffers from which `run-python' &c is |
| 1091 | ;; invoked. Would support multiple processes better. | 1140 | ;; invoked. Would support multiple processes better. |
| 1092 | (unless (comint-check-proc "*Python*") | 1141 | (unless (comint-check-proc python-buffer) |
| 1093 | (let ((cmdlist (append (python-args-to-list cmd) '("-i")))) | 1142 | (let* ((cmdlist (append (python-args-to-list cmd) '("-i"))) |
| 1143 | (path (getenv "PYTHONPATH")) | ||
| 1144 | (process-environment ; to import emacs.py | ||
| 1145 | (push (concat "PYTHONPATH=" data-directory | ||
| 1146 | (if path (concat ":" path))) | ||
| 1147 | process-environment))) | ||
| 1094 | (set-buffer (apply 'make-comint "Python" (car cmdlist) nil | 1148 | (set-buffer (apply 'make-comint "Python" (car cmdlist) nil |
| 1095 | (cdr cmdlist)))) | 1149 | (cdr cmdlist))) |
| 1150 | (setq python-buffer "*Python*")) | ||
| 1096 | (inferior-python-mode) | 1151 | (inferior-python-mode) |
| 1097 | ;; Load function defintions we need. | 1152 | ;; Load function defintions we need. |
| 1098 | ;; Before the preoutput function was used, this was done via -c in | 1153 | ;; Before the preoutput function was used, this was done via -c in |
| 1099 | ;; cmdlist, but that loses the banner and doesn't run the startup | 1154 | ;; cmdlist, but that loses the banner and doesn't run the startup |
| 1100 | ;; file. | 1155 | ;; file. The code might be inline here, but there's enough that it |
| 1101 | (python-send-string "\ | 1156 | ;; seems worth putting in a separate file, and it's probably cleaner |
| 1102 | def _emacs_execfile (file): # execute file and remove it | 1157 | ;; to put it in a module. |
| 1103 | from os import remove | 1158 | (python-send-string "import emacs")) |
| 1104 | try: execfile (file, globals (), globals ()) | 1159 | (unless noshow (pop-to-buffer python-buffer))) |
| 1105 | finally: remove (file) | 1160 | |
| 1106 | 1161 | ;; Fixme: We typically lose if the inferior isn't in the normal REPL, | |
| 1107 | def _emacs_args (name): # get arglist of name for eldoc &c | 1162 | ;; e.g. prompt is `help> '. Probably raise an error if the form of |
| 1108 | import inspect | 1163 | ;; the prompt is unexpected; actually, it needs to be `>>> ', not |
| 1109 | parts = name.split ('.') | 1164 | ;; `... ', i.e. we're not inputting a block &c. However, this may not |
| 1110 | if len (parts) > 1: | 1165 | ;; be the place to do it, e.g. we might actually want to send commands |
| 1111 | try: exec 'import ' + parts[0] | 1166 | ;; having set up such a state. |
| 1112 | except: return None | 1167 | |
| 1113 | try: exec 'func='+name # lose if name is keyword or undefined | 1168 | (defun python-send-command (command) |
| 1114 | except: return None | 1169 | "Like `python-send-string' but resets `compilation-minor-mode'." |
| 1115 | if inspect.isbuiltin (func): | 1170 | (goto-char (point-max)) |
| 1116 | doc = func.__doc__ | 1171 | (let ((end (marker-position (process-mark (python-proc))))) |
| 1117 | if doc.find (' ->') != -1: | 1172 | (compilation-forget-errors) |
| 1118 | print '_emacs_out', doc.split (' ->')[0] | 1173 | (python-send-string command) |
| 1119 | elif doc.find ('\\n') != -1: | 1174 | (set-marker compilation-parsing-end end) |
| 1120 | print '_emacs_out', doc.split ('\\n')[0] | 1175 | (setq compilation-last-buffer (current-buffer)))) |
| 1121 | return None | ||
| 1122 | if inspect.ismethod (func): func = func.im_func | ||
| 1123 | if not inspect.isfunction (func): | ||
| 1124 | return None | ||
| 1125 | (args, varargs, varkw, defaults) = inspect.getargspec (func) | ||
| 1126 | print '_emacs_out', func.__name__+inspect.formatargspec (args, varargs, varkw, defaults) | ||
| 1127 | |||
| 1128 | print '_emacs_ok'")) | ||
| 1129 | (unless noshow (pop-to-buffer (setq python-buffer "*Python*")))) | ||
| 1130 | 1176 | ||
| 1131 | (defun python-send-region (start end) | 1177 | (defun python-send-region (start end) |
| 1132 | "Send the region to the inferior Python process." | 1178 | "Send the region to the inferior Python process." |
| 1133 | ;; The region is evaluated from a temporary file. This avoids | 1179 | ;; The region is evaluated from a temporary file. This avoids |
| 1134 | ;; problems with blank lines, which have different semantics | 1180 | ;; problems with blank lines, which have different semantics |
| 1135 | ;; interactively and in files. It also saves the inferior process | 1181 | ;; interactively and in files. It also saves the inferior process |
| 1136 | ;; buffer filling up with interpreter prompts. We need a function | 1182 | ;; buffer filling up with interpreter prompts. We need a Python |
| 1137 | ;; to remove the temporary file when it has been evaluated, which | 1183 | ;; function to remove the temporary file when it has been evaluated |
| 1138 | ;; unfortunately means using a not-quite pristine interpreter | 1184 | ;; (though we could probably do it in Lisp with a Comint output |
| 1139 | ;; initially. Unfortunately we also get tracebacks which look like: | 1185 | ;; filter). This function also catches exceptions and truncates |
| 1140 | ;; | 1186 | ;; tracebacks not to mention the frame of the function itself. |
| 1141 | ;; >>> Traceback (most recent call last): | ||
| 1142 | ;; File "<stdin>", line 1, in ? | ||
| 1143 | ;; File "<string>", line 4, in _emacs_execfile | ||
| 1144 | ;; File "/tmp/py7734RSB", line 11 | ||
| 1145 | ;; | 1187 | ;; |
| 1146 | ;; The compilation-minor-mode parsing takes care of relating the | 1188 | ;; The compilation-minor-mode parsing takes care of relating the |
| 1147 | ;; reference to the temporary file to the source. Fixme: | 1189 | ;; reference to the temporary file to the source. |
| 1148 | ;; comint-filter the first two lines of the traceback? | 1190 | ;; |
| 1191 | ;; Fixme: Write a `coding' header to the temp file if the region is | ||
| 1192 | ;; non-ASCII. | ||
| 1149 | (interactive "r") | 1193 | (interactive "r") |
| 1150 | (let* ((f (make-temp-file "py")) | 1194 | (let* ((f (make-temp-file "py")) |
| 1151 | (command (format "_emacs_execfile(%S)" f)) | 1195 | (command (format "emacs.eexecfile(%S)" f)) |
| 1152 | (orig-start (copy-marker start))) | 1196 | (orig-start (copy-marker start))) |
| 1153 | (if (save-excursion | 1197 | (when (save-excursion |
| 1154 | (goto-char start) | 1198 | (goto-char start) |
| 1155 | (/= 0 (current-indentation))) ; need dummy block | 1199 | (/= 0 (current-indentation))) ; need dummy block |
| 1156 | (write-region "if True:\n" nil f nil 'nomsg)) | 1200 | (save-excursion |
| 1201 | (goto-char orig-start) | ||
| 1202 | ;; Wrong if we had indented code at buffer start. | ||
| 1203 | (set-marker orig-start (line-beginning-position 0))) | ||
| 1204 | (write-region "if True:\n" nil f nil 'nomsg)) | ||
| 1157 | (write-region start end f t 'nomsg) | 1205 | (write-region start end f t 'nomsg) |
| 1158 | (when python-buffer | 1206 | (let ((proc (python-proc))) ;Make sure we're running a process. |
| 1159 | (with-current-buffer python-buffer | 1207 | (with-current-buffer python-buffer |
| 1160 | (let ((end (marker-position (process-mark (python-proc))))) | 1208 | (python-send-command command) |
| 1161 | (set (make-local-variable 'python-orig-start) orig-start) | 1209 | ;; Tell compile.el to redirect error locations in file `f' to |
| 1162 | (set (make-local-variable 'compilation-error-list) nil) | 1210 | ;; positions past marker `orig-start'. It has to be done *after* |
| 1163 | (let ((comint-input-filter-functions | 1211 | ;; python-send-command's call to compilation-forget-errors. |
| 1164 | (delete 'python-input-filter comint-input-filter-functions))) | 1212 | (compilation-fake-loc orig-start f))))) |
| 1165 | (python-send-string command)) | ||
| 1166 | (set-marker compilation-parsing-end end) | ||
| 1167 | (setq compilation-last-buffer (current-buffer))))))) | ||
| 1168 | 1213 | ||
| 1169 | (defun python-send-string (string) | 1214 | (defun python-send-string (string) |
| 1170 | "Evaluate STRING in inferior Python process." | 1215 | "Evaluate STRING in inferior Python process." |
| @@ -1177,6 +1222,8 @@ print '_emacs_ok'")) | |||
| 1177 | (interactive) | 1222 | (interactive) |
| 1178 | (python-send-region (point-min) (point-max))) | 1223 | (python-send-region (point-min) (point-max))) |
| 1179 | 1224 | ||
| 1225 | ;; Fixme: Try to define the function or class within the relevant | ||
| 1226 | ;; module, not just at top level. | ||
| 1180 | (defun python-send-defun () | 1227 | (defun python-send-defun () |
| 1181 | "Send the current defun (class or method) to the inferior Python process." | 1228 | "Send the current defun (class or method) to the inferior Python process." |
| 1182 | (interactive) | 1229 | (interactive) |
| @@ -1223,39 +1270,33 @@ function location information for debugging, and supports users of | |||
| 1223 | module-qualified names." | 1270 | module-qualified names." |
| 1224 | (interactive (comint-get-source "Load Python file: " python-prev-dir/file | 1271 | (interactive (comint-get-source "Load Python file: " python-prev-dir/file |
| 1225 | python-source-modes | 1272 | python-source-modes |
| 1226 | t)) ; because execfile needs exact name | 1273 | t)) ; because execfile needs exact name |
| 1227 | (comint-check-source file-name) ; Check to see if buffer needs saved. | 1274 | (comint-check-source file-name) ; Check to see if buffer needs saving. |
| 1228 | (setq python-prev-dir/file (cons (file-name-directory file-name) | 1275 | (setq python-prev-dir/file (cons (file-name-directory file-name) |
| 1229 | (file-name-nondirectory file-name))) | 1276 | (file-name-nondirectory file-name))) |
| 1230 | (when python-buffer | 1277 | (let ((proc (python-proc))) ;Make sure we have a process. |
| 1231 | (with-current-buffer python-buffer | 1278 | (with-current-buffer python-buffer |
| 1232 | (let ((end (marker-position (process-mark (python-proc))))) | 1279 | ;; Fixme: I'm not convinced by this logic from python-mode.el. |
| 1233 | (set (make-local-variable 'compilation-error-list) nil) | 1280 | (python-send-command |
| 1234 | ;; (set (make-local-variable 'compilation-old-error-list) nil) | 1281 | (if (string-match "\\.py\\'" file-name) |
| 1235 | (let ((comint-input-filter-functions | 1282 | (let ((module (file-name-sans-extension |
| 1236 | (delete 'python-input-filter comint-input-filter-functions))) | 1283 | (file-name-nondirectory file-name)))) |
| 1237 | (python-send-string | 1284 | (format "emacs.eimport(%S,%S)" |
| 1238 | (if (string-match "\\.py\\'" file-name) | 1285 | module (file-name-directory file-name))) |
| 1239 | ;; Fixme: make sure the directory is in the path list | 1286 | (format "execfile(%S)" file-name))) |
| 1240 | (let ((module (file-name-sans-extension | 1287 | (message "%s loaded" file-name)))) |
| 1241 | (file-name-nondirectory file-name)))) | 1288 | |
| 1242 | (set (make-local-variable 'python-orig-start) nil) | 1289 | ;; Fixme: If we need to start the process, wait until we've got the OK |
| 1243 | (format "\ | 1290 | ;; from the startup. |
| 1244 | if globals().has_key(%S): reload(%s) | ||
| 1245 | else: import %s | ||
| 1246 | " module module module)) | ||
| 1247 | (set (make-local-variable 'python-orig-start) file-name) | ||
| 1248 | (format "execfile('%s')" file-name)))) | ||
| 1249 | (set-marker compilation-parsing-end end) | ||
| 1250 | (setq compilation-last-buffer (current-buffer)))))) | ||
| 1251 | |||
| 1252 | ;; Fixme: Should this start a process if there isn't one? (Unlike cmuscheme.) | ||
| 1253 | (defun python-proc () | 1291 | (defun python-proc () |
| 1254 | "Return the current Python process. See variable `python-buffer'." | 1292 | "Return the current Python process. |
| 1255 | (let ((proc (get-buffer-process (if (eq major-mode 'inferior-python-mode) | 1293 | See variable `python-buffer'. Starts a new process if necessary." |
| 1256 | (current-buffer) | 1294 | (or (if python-buffer |
| 1257 | python-buffer)))) | 1295 | (get-buffer-process (if (eq major-mode 'inferior-python-mode) |
| 1258 | (or proc (error "No current process. See variable `python-buffer'")))) | 1296 | (current-buffer) |
| 1297 | python-buffer))) | ||
| 1298 | (progn (run-python nil t) | ||
| 1299 | (python-proc)))) | ||
| 1259 | 1300 | ||
| 1260 | ;;;; Context-sensitive help. | 1301 | ;;;; Context-sensitive help. |
| 1261 | 1302 | ||
| @@ -1267,33 +1308,47 @@ else: import %s | |||
| 1267 | "Syntax table giving `.' symbol syntax. | 1308 | "Syntax table giving `.' symbol syntax. |
| 1268 | Otherwise inherits from `python-mode-syntax-table'.") | 1309 | Otherwise inherits from `python-mode-syntax-table'.") |
| 1269 | 1310 | ||
| 1311 | (defvar view-return-to-alist) | ||
| 1312 | (eval-when-compile (autoload 'help-buffer "help-fns")) | ||
| 1313 | |||
| 1270 | ;; Fixme: Should this actually be used instead of info-look, i.e. be | 1314 | ;; Fixme: Should this actually be used instead of info-look, i.e. be |
| 1271 | ;; bound to C-h S? | 1315 | ;; bound to C-h S? Can we use other pydoc stuff before python 2.2? |
| 1272 | (defun python-describe-symbol (symbol) | 1316 | (defun python-describe-symbol (symbol) |
| 1273 | "Get help on SYMBOL using `pydoc'. | 1317 | "Get help on SYMBOL using `help'. |
| 1274 | Interactively, prompt for symbol." | 1318 | Interactively, prompt for symbol. |
| 1275 | ;; Note that we do this in the inferior process, not a separate one to | 1319 | |
| 1320 | Symbol may be anything recognized by the interpreter's `help' command -- | ||
| 1321 | e.g. `CALLS' -- not just variables in scope. | ||
| 1322 | This only works for Python version 2.2 or newer since earlier interpreters | ||
| 1323 | don't support `help'." | ||
| 1324 | ;; Note that we do this in the inferior process, not a separate one, to | ||
| 1276 | ;; ensure the environment is appropriate. | 1325 | ;; ensure the environment is appropriate. |
| 1277 | (interactive | 1326 | (interactive |
| 1278 | (let ((symbol (with-syntax-table python-dotty-syntax-table | 1327 | (let ((symbol (with-syntax-table python-dotty-syntax-table |
| 1279 | (current-word))) | 1328 | (current-word))) |
| 1280 | (enable-recursive-minibuffers t) | 1329 | (enable-recursive-minibuffers t)) |
| 1281 | val) | 1330 | (list (read-string (if symbol |
| 1282 | (setq val (read-string (if symbol | 1331 | (format "Describe symbol (default %s): " symbol) |
| 1283 | (format "Describe symbol (default %s): " | 1332 | "Describe symbol: ") |
| 1284 | symbol) | 1333 | nil nil symbol)))) |
| 1285 | "Describe symbol: ") | ||
| 1286 | nil nil symbol)) | ||
| 1287 | (list (or val symbol)))) | ||
| 1288 | (if (equal symbol "") (error "No symbol")) | 1334 | (if (equal symbol "") (error "No symbol")) |
| 1289 | (let* ((func `(lambda () | 1335 | (let* ((func `(lambda () |
| 1290 | (comint-redirect-send-command (format "help(%S)\n" ,symbol) | 1336 | (comint-redirect-send-command (format "emacs.ehelp(%S)\n" |
| 1337 | ,symbol) | ||
| 1291 | "*Help*" nil)))) | 1338 | "*Help*" nil)))) |
| 1292 | ;; Ensure we have a suitable help buffer. | 1339 | ;; Ensure we have a suitable help buffer. |
| 1293 | (let (temp-buffer-show-hook) ; avoid xref stuff | 1340 | ;; Fixme: Maybe process `Related help topics' a la help xrefs and |
| 1294 | (with-output-to-temp-buffer "*Help*" | 1341 | ;; allow C-c C-f in help buffer. |
| 1342 | (let ((temp-buffer-show-hook ; avoid xref stuff | ||
| 1343 | (lambda () | ||
| 1344 | (toggle-read-only 1) | ||
| 1345 | (setq view-return-to-alist | ||
| 1346 | (list (cons (selected-window) help-return-method)))))) | ||
| 1347 | (help-setup-xref (list 'python-describe-symbol symbol) (interactive-p)) | ||
| 1348 | (with-output-to-temp-buffer (help-buffer) | ||
| 1295 | (with-current-buffer standard-output | 1349 | (with-current-buffer standard-output |
| 1296 | (set (make-local-variable 'comint-redirect-subvert-readonly) t)))) | 1350 | (set (make-local-variable 'comint-redirect-subvert-readonly) t) |
| 1351 | (print-help-return-message)))) | ||
| 1297 | (if (and python-buffer (get-buffer python-buffer)) | 1352 | (if (and python-buffer (get-buffer python-buffer)) |
| 1298 | (with-current-buffer python-buffer | 1353 | (with-current-buffer python-buffer |
| 1299 | (funcall func)) | 1354 | (funcall func)) |
| @@ -1302,6 +1357,15 @@ Interactively, prompt for symbol." | |||
| 1302 | 1357 | ||
| 1303 | (add-to-list 'debug-ignored-errors "^No symbol") | 1358 | (add-to-list 'debug-ignored-errors "^No symbol") |
| 1304 | 1359 | ||
| 1360 | (defun python-send-receive (string) | ||
| 1361 | "Send STRING to inferior Python (if any) and return result. | ||
| 1362 | The result is what follows `_emacs_out' in the output (or nil)." | ||
| 1363 | (let ((proc (python-proc))) | ||
| 1364 | (python-send-string string) | ||
| 1365 | (setq python-preoutput-result nil) | ||
| 1366 | (accept-process-output proc 5) | ||
| 1367 | python-preoutput-result)) | ||
| 1368 | |||
| 1305 | ;; Fixme: try to make it work with point in the arglist. Also, is | 1369 | ;; Fixme: try to make it work with point in the arglist. Also, is |
| 1306 | ;; there anything reasonable we can do with random methods? | 1370 | ;; there anything reasonable we can do with random methods? |
| 1307 | ;; (Currently only works with functions.) | 1371 | ;; (Currently only works with functions.) |
| @@ -1310,14 +1374,9 @@ Interactively, prompt for symbol." | |||
| 1310 | Only works when point is in a function name, not its arglist, for instance. | 1374 | Only works when point is in a function name, not its arglist, for instance. |
| 1311 | Assumes an inferior Python is running." | 1375 | Assumes an inferior Python is running." |
| 1312 | (let ((symbol (with-syntax-table python-dotty-syntax-table | 1376 | (let ((symbol (with-syntax-table python-dotty-syntax-table |
| 1313 | (current-word))) | 1377 | (current-word)))) |
| 1314 | (proc (and python-buffer (python-proc)))) | 1378 | (when symbol |
| 1315 | (when (and proc symbol) | 1379 | (python-send-receive (format "emacs.eargs(%S)" symbol))))) |
| 1316 | (python-send-string | ||
| 1317 | (format "_emacs_args(%S)" symbol)) | ||
| 1318 | (setq python-preoutput-result nil) | ||
| 1319 | (accept-process-output proc 1) | ||
| 1320 | python-preoutput-result))) | ||
| 1321 | 1380 | ||
| 1322 | ;;;; Info-look functionality. | 1381 | ;;;; Info-look functionality. |
| 1323 | 1382 | ||
| @@ -1331,11 +1390,13 @@ Used with `eval-after-load'." | |||
| 1331 | ;; Whether info files have a Python version suffix, e.g. in Debian. | 1390 | ;; Whether info files have a Python version suffix, e.g. in Debian. |
| 1332 | (versioned | 1391 | (versioned |
| 1333 | (with-temp-buffer | 1392 | (with-temp-buffer |
| 1334 | (Info-mode) | 1393 | (with-no-warnings (Info-mode)) |
| 1335 | (condition-case () | 1394 | (condition-case () |
| 1336 | ;; Don't use `info' because it would pop-up a *info* buffer. | 1395 | ;; Don't use `info' because it would pop-up a *info* buffer. |
| 1337 | (Info-goto-node (format "(python%s-lib)Miscellaneous Index" | 1396 | (with-no-warnings |
| 1338 | version)) | 1397 | (Info-goto-node (format "(python%s-lib)Miscellaneous Index" |
| 1398 | version)) | ||
| 1399 | t) | ||
| 1339 | (error nil))))) | 1400 | (error nil))))) |
| 1340 | (info-lookup-maybe-add-help | 1401 | (info-lookup-maybe-add-help |
| 1341 | :mode 'python-mode | 1402 | :mode 'python-mode |
| @@ -1401,7 +1462,7 @@ The criterion is either a match for `jython-mode' via | |||
| 1401 | (while (re-search-forward | 1462 | (while (re-search-forward |
| 1402 | (rx (and line-start (or "import" "from") (1+ space) | 1463 | (rx (and line-start (or "import" "from") (1+ space) |
| 1403 | (group (1+ (not (any " \t\n.")))))) | 1464 | (group (1+ (not (any " \t\n.")))))) |
| 1404 | 10000 ; Probably not worth customizing. | 1465 | (+ (point-min) 10000) ; Probably not worth customizing. |
| 1405 | t) | 1466 | t) |
| 1406 | (if (member (match-string 1) python-jython-packages) | 1467 | (if (member (match-string 1) python-jython-packages) |
| 1407 | (throw 'done t)))) | 1468 | (throw 'done t)))) |
| @@ -1519,11 +1580,97 @@ Uses `python-beginning-of-block', `python-end-of-block'." | |||
| 1519 | (python-end-of-block) | 1580 | (python-end-of-block) |
| 1520 | (exchange-point-and-mark)) | 1581 | (exchange-point-and-mark)) |
| 1521 | 1582 | ||
| 1583 | ;;;; Completion. | ||
| 1584 | |||
| 1585 | (defun python-symbol-completions (symbol) | ||
| 1586 | "Return a list of completions of the string SYMBOL from Python process. | ||
| 1587 | The list is sorted." | ||
| 1588 | (when symbol | ||
| 1589 | (let ((completions | ||
| 1590 | (condition-case () | ||
| 1591 | (car (read-from-string (python-send-receive | ||
| 1592 | (format "emacs.complete(%S)" symbol)))) | ||
| 1593 | (error nil)))) | ||
| 1594 | (sort | ||
| 1595 | ;; We can get duplicates from the above -- don't know why. | ||
| 1596 | (delete-dups completions) | ||
| 1597 | #'string<)))) | ||
| 1598 | |||
| 1599 | (defun python-partial-symbol () | ||
| 1600 | "Return the partial symbol before point (for completion)." | ||
| 1601 | (let ((end (point)) | ||
| 1602 | (start (save-excursion | ||
| 1603 | (and (re-search-backward | ||
| 1604 | (rx (and (or buffer-start (regexp "[^[:alnum:]._]")) | ||
| 1605 | (group (1+ (regexp "[[:alnum:]._]"))) | ||
| 1606 | point)) | ||
| 1607 | nil t) | ||
| 1608 | (match-beginning 1))))) | ||
| 1609 | (if start (buffer-substring-no-properties start end)))) | ||
| 1610 | |||
| 1611 | ;; Fixme: We should have an abstraction of this sort of thing in the | ||
| 1612 | ;; core. | ||
| 1613 | (defun python-complete-symbol () | ||
| 1614 | "Perform completion on the Python symbol preceding point. | ||
| 1615 | Repeating the command scrolls the completion window." | ||
| 1616 | (interactive) | ||
| 1617 | (let ((window (get-buffer-window "*Completions*"))) | ||
| 1618 | (if (and (eq last-command this-command) | ||
| 1619 | window (window-live-p window) (window-buffer window) | ||
| 1620 | (buffer-name (window-buffer window))) | ||
| 1621 | (with-current-buffer (window-buffer window) | ||
| 1622 | (if (pos-visible-in-window-p (point-max) window) | ||
| 1623 | (set-window-start window (point-min)) | ||
| 1624 | (save-selected-window | ||
| 1625 | (select-window window) | ||
| 1626 | (scroll-up)))) | ||
| 1627 | ;; Do completion. | ||
| 1628 | (let* ((end (point)) | ||
| 1629 | (symbol (python-partial-symbol)) | ||
| 1630 | (completions (python-symbol-completions symbol)) | ||
| 1631 | (completion (if completions | ||
| 1632 | (try-completion symbol completions)))) | ||
| 1633 | (when symbol | ||
| 1634 | (cond ((eq completion t)) | ||
| 1635 | ((null completion) | ||
| 1636 | (message "Can't find completion for \"%s\"" symbol) | ||
| 1637 | (ding)) | ||
| 1638 | ((not (string= symbol completion)) | ||
| 1639 | (delete-region (- end (length symbol)) end) | ||
| 1640 | (insert completion)) | ||
| 1641 | (t | ||
| 1642 | (message "Making completion list...") | ||
| 1643 | (with-output-to-temp-buffer "*Completions*" | ||
| 1644 | (display-completion-list completions)) | ||
| 1645 | (message "Making completion list...%s" "done")))))))) | ||
| 1646 | |||
| 1647 | (eval-when-compile (require 'hippie-exp)) | ||
| 1648 | |||
| 1649 | (defun python-try-complete (old) | ||
| 1650 | "Completion function for Python for use with `hippie-expand'." | ||
| 1651 | (when (eq major-mode 'python-mode) ; though we only add it locally | ||
| 1652 | (unless old | ||
| 1653 | (let ((symbol (python-partial-symbol))) | ||
| 1654 | (he-init-string (- (point) (length symbol)) (point)) | ||
| 1655 | (if (not (he-string-member he-search-string he-tried-table)) | ||
| 1656 | (push he-search-string he-tried-table)) | ||
| 1657 | (setq he-expand-list | ||
| 1658 | (and symbol (python-symbol-completions symbol))))) | ||
| 1659 | (while (and he-expand-list | ||
| 1660 | (he-string-member (car he-expand-list) he-tried-table)) | ||
| 1661 | (pop he-expand-list)) | ||
| 1662 | (if he-expand-list | ||
| 1663 | (progn | ||
| 1664 | (he-substitute-string (pop he-expand-list)) | ||
| 1665 | t) | ||
| 1666 | (if old (he-reset-string)) | ||
| 1667 | nil))) | ||
| 1668 | |||
| 1522 | ;;;; Modes. | 1669 | ;;;; Modes. |
| 1523 | 1670 | ||
| 1524 | (defvar outline-heading-end-regexp) | 1671 | (defvar outline-heading-end-regexp) |
| 1525 | (defvar eldoc-print-current-symbol-info-function) | 1672 | (defvar eldoc-print-current-symbol-info-function) |
| 1526 | (defvar python-mode-running) | 1673 | |
| 1527 | ;;;###autoload | 1674 | ;;;###autoload |
| 1528 | (define-derived-mode python-mode fundamental-mode "Python" | 1675 | (define-derived-mode python-mode fundamental-mode "Python" |
| 1529 | "Major mode for editing Python files. | 1676 | "Major mode for editing Python files. |
| @@ -1565,11 +1712,10 @@ lines count as headers. | |||
| 1565 | )) | 1712 | )) |
| 1566 | (set (make-local-variable 'parse-sexp-lookup-properties) t) | 1713 | (set (make-local-variable 'parse-sexp-lookup-properties) t) |
| 1567 | (set (make-local-variable 'comment-start) "# ") | 1714 | (set (make-local-variable 'comment-start) "# ") |
| 1568 | ;; Fixme: define a comment-indent-function? | 1715 | (set (make-local-variable 'comment-indent-function) #'python-comment-indent) |
| 1569 | (set (make-local-variable 'indent-line-function) #'python-indent-line) | 1716 | (set (make-local-variable 'indent-line-function) #'python-indent-line) |
| 1570 | (set (make-local-variable 'paragraph-start) "\\s-*$") | 1717 | (set (make-local-variable 'paragraph-start) "\\s-*$") |
| 1571 | (set (make-local-variable 'fill-paragraph-function) | 1718 | (set (make-local-variable 'fill-paragraph-function) 'python-fill-paragraph) |
| 1572 | 'python-fill-paragraph) | ||
| 1573 | (set (make-local-variable 'require-final-newline) t) | 1719 | (set (make-local-variable 'require-final-newline) t) |
| 1574 | (set (make-local-variable 'add-log-current-defun-function) | 1720 | (set (make-local-variable 'add-log-current-defun-function) |
| 1575 | #'python-current-defun) | 1721 | #'python-current-defun) |
| @@ -1587,6 +1733,9 @@ lines count as headers. | |||
| 1587 | #'python-eldoc-function) | 1733 | #'python-eldoc-function) |
| 1588 | (add-hook 'eldoc-mode-hook | 1734 | (add-hook 'eldoc-mode-hook |
| 1589 | '(lambda () (run-python 0 t)) nil t) ; need it running | 1735 | '(lambda () (run-python 0 t)) nil t) ; need it running |
| 1736 | (if (featurep 'hippie-exp) | ||
| 1737 | (set (make-local-variable 'hippie-expand-try-functions-list) | ||
| 1738 | (cons 'python-try-complete hippie-expand-try-functions-list))) | ||
| 1590 | (unless font-lock-mode (font-lock-mode 1)) | 1739 | (unless font-lock-mode (font-lock-mode 1)) |
| 1591 | (when python-guess-indent (python-guess-indent)) | 1740 | (when python-guess-indent (python-guess-indent)) |
| 1592 | (set (make-local-variable 'python-command) python-python-command) | 1741 | (set (make-local-variable 'python-command) python-python-command) |
diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index df2bf6803da..adb5f7b402a 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el | |||
| @@ -648,7 +648,7 @@ implemented as aliases. See `sh-feature'." | |||
| 648 | 648 | ||
| 649 | (rc "else") | 649 | (rc "else") |
| 650 | 650 | ||
| 651 | (sh "do" "elif" "else" "if" "then" "trap" "type" "until" "while")) | 651 | (sh "!" "do" "elif" "else" "if" "then" "trap" "type" "until" "while")) |
| 652 | "*List of keywords that may be immediately followed by a builtin or keyword. | 652 | "*List of keywords that may be immediately followed by a builtin or keyword. |
| 653 | Given some confusion between keywords and builtins depending on shell and | 653 | Given some confusion between keywords and builtins depending on shell and |
| 654 | system, the distinction here has been based on whether they influence the | 654 | system, the distinction here has been based on whether they influence the |
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el index 1a9251599ce..0e0d89b07e1 100644 --- a/lisp/progmodes/sql.el +++ b/lisp/progmodes/sql.el | |||
| @@ -1,11 +1,12 @@ | |||
| 1 | ;;; sql.el --- specialized comint.el for SQL interpreters | 1 | ;;; sql.el --- specialized comint.el for SQL interpreters |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1998,99,2000,01,02,03,04 Free Software Foundation, Inc. |
| 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: 1.8.0 | 7 | ;; Version: 2.0.1 |
| 8 | ;; Keywords: comm languages processes | 8 | ;; Keywords: comm languages processes |
| 9 | ;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el | ||
| 9 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode | 10 | ;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode |
| 10 | 11 | ||
| 11 | ;; This file is part of GNU Emacs. | 12 | ;; This file is part of GNU Emacs. |
| @@ -101,7 +102,7 @@ | |||
| 101 | 102 | ||
| 102 | ;; (const :tag "XyzDB" xyz) | 103 | ;; (const :tag "XyzDB" xyz) |
| 103 | 104 | ||
| 104 | ;; 2) Add an entry to the `sql-product-support' list. | 105 | ;; 2) Add an entry to the `sql-product-alist' list. |
| 105 | 106 | ||
| 106 | ;; (xyz | 107 | ;; (xyz |
| 107 | ;; :font-lock sql-mode-xyz-font-lock-keywords | 108 | ;; :font-lock sql-mode-xyz-font-lock-keywords |
| @@ -136,7 +137,7 @@ | |||
| 136 | ;; using ANSI keywords. See sql-mode-oracle-font-lock-keywords for | 137 | ;; using ANSI keywords. See sql-mode-oracle-font-lock-keywords for |
| 137 | ;; a more complex example. | 138 | ;; a more complex example. |
| 138 | 139 | ||
| 139 | ;; (defvar sql-mode-xyz-font-lock-keywords sql-mode-ansi-font-lock-keywords | 140 | ;; (defvar sql-mode-xyz-font-lock-keywords nil |
| 140 | ;; "XyzDB SQL keywords used by font-lock.") | 141 | ;; "XyzDB SQL keywords used by font-lock.") |
| 141 | 142 | ||
| 142 | ;; 6) Add a product highlighting function. | 143 | ;; 6) Add a product highlighting function. |
| @@ -192,13 +193,18 @@ | |||
| 192 | 193 | ||
| 193 | ;;; Thanks to all the people who helped me out: | 194 | ;;; Thanks to all the people who helped me out: |
| 194 | 195 | ||
| 196 | ;; Alex Schroeder <alex@gnu.org> | ||
| 195 | ;; Kai Blauberg <kai.blauberg@metla.fi> | 197 | ;; Kai Blauberg <kai.blauberg@metla.fi> |
| 196 | ;; <ibalaban@dalet.com> | 198 | ;; <ibalaban@dalet.com> |
| 197 | ;; Yair Friedman <yfriedma@JohnBryce.Co.Il> | 199 | ;; Yair Friedman <yfriedma@JohnBryce.Co.Il> |
| 198 | ;; Gregor Zych <zych@pool.informatik.rwth-aachen.de> | 200 | ;; Gregor Zych <zych@pool.informatik.rwth-aachen.de> |
| 199 | ;; nino <nino@inform.dk> | 201 | ;; nino <nino@inform.dk> |
| 200 | ;; Berend de Boer <berend@pobox.com> | 202 | ;; Berend de Boer <berend@pobox.com> |
| 201 | ;; Michael Mauger <mmaug@yahoo.com> | 203 | ;; Adam Jenkins <adam@thejenkins.org> |
| 204 | ;; Michael Mauger <mmaug@yahoo.com> -- improved product support | ||
| 205 | ;; Drew Adams <drew.adams@oracle.com> -- Emacs 20 support | ||
| 206 | ;; Harald Maier <maierh@myself.com> -- sql-send-string | ||
| 207 | ;; Stefan Monnier <monnier@iro.umontreal.ca> -- font-lock corrections | ||
| 202 | 208 | ||
| 203 | 209 | ||
| 204 | 210 | ||
| @@ -209,6 +215,8 @@ | |||
| 209 | (eval-when-compile | 215 | (eval-when-compile |
| 210 | (require 'regexp-opt)) | 216 | (require 'regexp-opt)) |
| 211 | (require 'custom) | 217 | (require 'custom) |
| 218 | (eval-when-compile ;; needed in Emacs 19, 20 | ||
| 219 | (setq max-specpdl-size 2000)) | ||
| 212 | 220 | ||
| 213 | ;;; Allow customization | 221 | ;;; Allow customization |
| 214 | 222 | ||
| @@ -264,7 +272,7 @@ highlighted properly when you open them." | |||
| 264 | (defvar sql-interactive-product nil | 272 | (defvar sql-interactive-product nil |
| 265 | "Product under `sql-interactive-mode'.") | 273 | "Product under `sql-interactive-mode'.") |
| 266 | 274 | ||
| 267 | (defvar sql-product-support | 275 | (defvar sql-product-alist |
| 268 | '((ansi | 276 | '((ansi |
| 269 | :font-lock sql-mode-ansi-font-lock-keywords) | 277 | :font-lock sql-mode-ansi-font-lock-keywords) |
| 270 | (db2 | 278 | (db2 |
| @@ -319,9 +327,9 @@ highlighted properly when you open them." | |||
| 319 | :syntax-alist ((?$ . "w") (?# . "w"))) | 327 | :syntax-alist ((?$ . "w") (?# . "w"))) |
| 320 | (postgres | 328 | (postgres |
| 321 | :font-lock sql-mode-postgres-font-lock-keywords | 329 | :font-lock sql-mode-postgres-font-lock-keywords |
| 322 | :sqli-login (database server) | 330 | :sqli-login (user database server) |
| 323 | :sqli-connect sql-connect-postgres | 331 | :sqli-connect sql-connect-postgres |
| 324 | :sqli-prompt-regexp "^.*> *" | 332 | :sqli-prompt-regexp "^.*[#>] *" |
| 325 | :sqli-prompt-length 5) | 333 | :sqli-prompt-length 5) |
| 326 | (solid | 334 | (solid |
| 327 | :font-lock sql-mode-solid-font-lock-keywords | 335 | :font-lock sql-mode-solid-font-lock-keywords |
| @@ -372,10 +380,12 @@ following: | |||
| 372 | database. Do product specific | 380 | database. Do product specific |
| 373 | configuration of comint in this function. | 381 | configuration of comint in this function. |
| 374 | 382 | ||
| 375 | :sqli-prompt-regexp a regular expression string that matches the | 383 | :sqli-prompt-regexp a regular expression string that matches |
| 376 | prompt issued by the product interpreter. | 384 | the prompt issued by the product |
| 385 | interpreter. (Not needed in 21.3+) | ||
| 377 | 386 | ||
| 378 | :sqli-prompt-length the length of the prompt on the line. | 387 | :sqli-prompt-length the length of the prompt on the line.(Not |
| 388 | needed in 21.3+) | ||
| 379 | 389 | ||
| 380 | :syntax-alist an alist of syntax table entries to enable | 390 | :syntax-alist an alist of syntax table entries to enable |
| 381 | special character treatment by font-lock and | 391 | special character treatment by font-lock and |
| @@ -412,14 +422,14 @@ buffer is shown using `display-buffer'." | |||
| 412 | 422 | ||
| 413 | (defvar sql-imenu-generic-expression | 423 | (defvar sql-imenu-generic-expression |
| 414 | ;; Items are in reverse order because they are rendered in reverse. | 424 | ;; Items are in reverse order because they are rendered in reverse. |
| 415 | '(("Rules/Defaults" "^\\s-*create\\s-+\\(rule\\|default\\)\\s-+\\(\\w+\\)" 2) | 425 | '(("Rules/Defaults" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(rule\\|default\\)\\s-+\\(\\w+\\)" 3) |
| 416 | ("Sequences" "^\\s-*create\\s-+sequence\\s-+\\(\\w+\\)" 1) | 426 | ("Sequences" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*sequence\\s-+\\(\\w+\\)" 2) |
| 417 | ("Triggers" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?trigger\\s-+\\(\\w+\\)" 3) | 427 | ("Triggers" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*trigger\\s-+\\(\\w+\\)" 2) |
| 418 | ("Functions" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?function\\s-+\\(\\w+\\)" 3) | 428 | ("Functions" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?function\\s-+\\(\\w+\\)" 3) |
| 419 | ("Procedures" "^\\s-*\\(create\\s-+\\(or\\s-+replace\\s-+\\)?\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4) | 429 | ("Procedures" "^\\s-*\\(create\\s-+\\(\\w+\\s-+\\)*\\)?proc\\(edure\\)?\\s-+\\(\\w+\\)" 4) |
| 420 | ("Packages" "^\\s-*create\\s-+\\(or\\s-+replace\\s-+\\)?package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3) | 430 | ("Packages" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*package\\s-+\\(body\\s-+\\)?\\(\\w+\\)" 3) |
| 421 | ("Indexes" "^\\s-*create\\s-+index\\s-+\\(\\w+\\)" 1) | 431 | ("Indexes" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*index\\s-+\\(\\w+\\)" 2) |
| 422 | ("Tables/Views" "^\\s-*create\\s-+\\(\\(global\\s-+\\)?\\(temporary\\s-+\\)?table\\|view\\)\\s-+\\(\\w+\\)" 4)) | 432 | ("Tables/Views" "^\\s-*create\\s-+\\(\\w+\\s-+\\)*\\(table\\|view\\)\\s-+\\(\\w+\\)" 3)) |
| 423 | "Define interesting points in the SQL buffer for `imenu'. | 433 | "Define interesting points in the SQL buffer for `imenu'. |
| 424 | 434 | ||
| 425 | This is used to set `imenu-generic-expression' when SQL mode is | 435 | This is used to set `imenu-generic-expression' when SQL mode is |
| @@ -745,6 +755,7 @@ Based on `comint-mode-map'.") | |||
| 745 | (let ((map (make-sparse-keymap))) | 755 | (let ((map (make-sparse-keymap))) |
| 746 | (define-key map (kbd "C-c C-c") 'sql-send-paragraph) | 756 | (define-key map (kbd "C-c C-c") 'sql-send-paragraph) |
| 747 | (define-key map (kbd "C-c C-r") 'sql-send-region) | 757 | (define-key map (kbd "C-c C-r") 'sql-send-region) |
| 758 | (define-key map (kbd "C-c C-s") 'sql-send-string) | ||
| 748 | (define-key map (kbd "C-c C-b") 'sql-send-buffer) | 759 | (define-key map (kbd "C-c C-b") 'sql-send-buffer) |
| 749 | map) | 760 | map) |
| 750 | "Mode map used for `sql-mode'.") | 761 | "Mode map used for `sql-mode'.") |
| @@ -764,6 +775,7 @@ Based on `comint-mode-map'.") | |||
| 764 | (get-buffer-process sql-buffer))] | 775 | (get-buffer-process sql-buffer))] |
| 765 | ["Send Buffer" sql-send-buffer (and (buffer-live-p sql-buffer) | 776 | ["Send Buffer" sql-send-buffer (and (buffer-live-p sql-buffer) |
| 766 | (get-buffer-process sql-buffer))] | 777 | (get-buffer-process sql-buffer))] |
| 778 | ["Send String" sql-send-string t] | ||
| 767 | ["--" nil nil] | 779 | ["--" nil nil] |
| 768 | ["Start SQLi session" sql-product-interactive (sql-product-feature :sqli-connect)] | 780 | ["Start SQLi session" sql-product-interactive (sql-product-feature :sqli-connect)] |
| 769 | ["Show SQLi buffer" sql-show-sqli-buffer t] | 781 | ["Show SQLi buffer" sql-show-sqli-buffer t] |
| @@ -792,7 +804,7 @@ Based on `comint-mode-map'.") | |||
| 792 | ["Linter" sql-highlight-linter-keywords | 804 | ["Linter" sql-highlight-linter-keywords |
| 793 | :style radio | 805 | :style radio |
| 794 | :selected (eq sql-product 'linter)] | 806 | :selected (eq sql-product 'linter)] |
| 795 | ["Microsoft" sql-highlight-ms-keywords | 807 | ["MS SQLServer" sql-highlight-ms-keywords |
| 796 | :style radio | 808 | :style radio |
| 797 | :selected (eq sql-product 'ms)] | 809 | :selected (eq sql-product 'ms)] |
| 798 | ["MySQL" sql-highlight-mysql-keywords | 810 | ["MySQL" sql-highlight-mysql-keywords |
| @@ -828,24 +840,24 @@ Based on `comint-mode-map'.") | |||
| 828 | 840 | ||
| 829 | (defvar sql-mode-abbrev-table nil | 841 | (defvar sql-mode-abbrev-table nil |
| 830 | "Abbrev table used in `sql-mode' and `sql-interactive-mode'.") | 842 | "Abbrev table used in `sql-mode' and `sql-interactive-mode'.") |
| 831 | (if sql-mode-abbrev-table | 843 | (unless sql-mode-abbrev-table |
| 832 | () | 844 | (define-abbrev-table 'sql-mode-abbrev-table nil) |
| 833 | (let ((nargs (cdr (subr-arity (symbol-function 'define-abbrev)))) | 845 | (mapcar |
| 834 | d-a) | ||
| 835 | ;; In Emacs 21.3+, provide SYSTEM-FLAG to define-abbrev. | 846 | ;; In Emacs 21.3+, provide SYSTEM-FLAG to define-abbrev. |
| 836 | (setq d-a | 847 | '(lambda (abbrev) |
| 837 | (if (>= nargs 6) | 848 | (let ((name (car abbrev)) |
| 838 | '(lambda (name expansion) (define-abbrev sql-mode-abbrev-table name expansion nil 0 t)) | 849 | (expansion (cdr abbrev))) |
| 839 | '(lambda (name expansion) (define-abbrev sql-mode-abbrev-table name expansion)))) | 850 | (condition-case nil |
| 840 | 851 | (define-abbrev sql-mode-abbrev-table name expansion nil 0 t) | |
| 841 | (define-abbrev-table 'sql-mode-abbrev-table nil) | 852 | (error |
| 842 | (funcall d-a "ins" "insert") | 853 | (define-abbrev sql-mode-abbrev-table name expansion))))) |
| 843 | (funcall d-a "upd" "update") | 854 | '(("ins" "insert") |
| 844 | (funcall d-a "del" "delete") | 855 | ("upd" "update") |
| 845 | (funcall d-a "sel" "select") | 856 | ("del" "delete") |
| 846 | (funcall d-a "proc" "procedure") | 857 | ("sel" "select") |
| 847 | (funcall d-a "func" "function") | 858 | ("proc" "procedure") |
| 848 | (funcall d-a "cr" "create"))) | 859 | ("func" "function") |
| 860 | ("cr" "create")))) | ||
| 849 | 861 | ||
| 850 | ;; Syntax Table | 862 | ;; Syntax Table |
| 851 | 863 | ||
| @@ -855,9 +867,7 @@ Based on `comint-mode-map'.") | |||
| 855 | (modify-syntax-entry ?/ ". 14" table) | 867 | (modify-syntax-entry ?/ ". 14" table) |
| 856 | (modify-syntax-entry ?* ". 23" table) | 868 | (modify-syntax-entry ?* ". 23" table) |
| 857 | ;; double-dash starts comment | 869 | ;; double-dash starts comment |
| 858 | (if (string-match "XEmacs\\|Lucid" emacs-version) | 870 | (modify-syntax-entry ?- ". 12b" table) |
| 859 | (modify-syntax-entry ?- ". 56" table) | ||
| 860 | (modify-syntax-entry ?- ". 12b" table)) | ||
| 861 | ;; newline and formfeed end coments | 871 | ;; newline and formfeed end coments |
| 862 | (modify-syntax-entry ?\n "> b" table) | 872 | (modify-syntax-entry ?\n "> b" table) |
| 863 | (modify-syntax-entry ?\f "> b" table) | 873 | (modify-syntax-entry ?\f "> b" table) |
| @@ -871,55 +881,117 @@ Based on `comint-mode-map'.") | |||
| 871 | ;; Font lock support | 881 | ;; Font lock support |
| 872 | 882 | ||
| 873 | (defvar sql-mode-font-lock-object-name | 883 | (defvar sql-mode-font-lock-object-name |
| 874 | (list (concat "^\\s-*\\(create\\(\\s-+or\\s-+replace\\)?\\|drop\\|alter\\)?\\s-+" | 884 | (list (concat "^\\s-*\\(create\\|drop\\|alter\\)\\s-+" ;; lead off with CREATE, DROP or ALTER |
| 875 | "\\(\\(global\\s-+\\)?\\(temporary\\s-+\\)?table\\|view\\|package\\(\\s-+body\\)?\\|" | 885 | "\\(\\w+\\s-+\\)*" ;; optional intervening keywords |
| 876 | "proc\\(edure\\)?\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+\\(\\w+\\)") | 886 | "\\(table\\|view\\|package\\(\\s-+body\\)?\\|proc\\(edure\\)?" |
| 877 | 8 'font-lock-function-name-face) | 887 | "\\|function\\|trigger\\|sequence\\|rule\\|default\\)\\s-+" |
| 878 | 888 | "\\(\\w+\\)") | |
| 879 | "Pattern to match the names of top-level objects in a CREATE, | 889 | 6 'font-lock-function-name-face) |
| 880 | DROP or ALTER statement. | 890 | |
| 881 | 891 | "Pattern to match the names of top-level objects. | |
| 882 | The format of variable should be a valid `font-lock-keywords' | 892 | |
| 883 | entry.") | 893 | The pattern matches the name in a CREATE, DROP or ALTER |
| 894 | statement. The format of variable should be a valid | ||
| 895 | `font-lock-keywords' entry.") | ||
| 896 | |||
| 897 | (defmacro sql-keywords-re (&rest keywords) | ||
| 898 | "Compile-time generation of regexp matching any one of KEYWORDS." | ||
| 899 | `(eval-when-compile | ||
| 900 | (concat "\\b" | ||
| 901 | (regexp-opt ',keywords t) | ||
| 902 | "\\b"))) | ||
| 884 | 903 | ||
| 885 | (defvar sql-mode-ansi-font-lock-keywords | 904 | (defvar sql-mode-ansi-font-lock-keywords |
| 886 | (let ((ansi-keywords (eval-when-compile | 905 | (let ((ansi-funcs (sql-keywords-re |
| 887 | (concat "\\b" | 906 | "abs" "avg" "bit_length" "cardinality" "cast" "char_length" |
| 888 | (regexp-opt '( | 907 | "character_length" "coalesce" "convert" "count" "current_date" |
| 889 | 908 | "current_path" "current_role" "current_time" "current_timestamp" | |
| 890 | "authorization" "avg" "begin" "close" "cobol" "commit" | 909 | "current_user" "extract" "localtime" "localtimestamp" "lower" "max" |
| 891 | "continue" "count" "declare" "double" "end" "escape" | 910 | "min" "mod" "nullif" "octet_length" "overlay" "placing" "session_user" |
| 892 | "exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator" | 911 | "substring" "sum" "system_user" "translate" "treat" "trim" "upper" |
| 893 | "key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli" | 912 | "user" |
| 894 | "precision" "primary" "procedure" "references" "rollback" | 913 | )) |
| 895 | "schema" "section" "some" "sqlcode" "sqlerror" "sum" "work" | 914 | |
| 896 | 915 | (ansi-non-reserved (sql-keywords-re | |
| 897 | ) t) "\\b"))) | 916 | "ada" "asensitive" "assignment" "asymmetric" "atomic" "between" |
| 898 | (ansi-reserved-words (eval-when-compile | 917 | "bitvar" "called" "catalog_name" "chain" "character_set_catalog" |
| 899 | (concat "\\b" | 918 | "character_set_name" "character_set_schema" "checked" "class_origin" |
| 900 | (regexp-opt '( | 919 | "cobol" "collation_catalog" "collation_name" "collation_schema" |
| 901 | 920 | "column_name" "command_function" "command_function_code" "committed" | |
| 902 | "all" "and" "any" "as" "asc" "between" "by" "check" "create" | 921 | "condition_number" "connection_name" "constraint_catalog" |
| 903 | "current" "default" "delete" "desc" "distinct" "exists" "float" "for" | 922 | "constraint_name" "constraint_schema" "contains" "cursor_name" |
| 904 | "from" "grant" "group" "having" "in" "insert" "into" "is" | 923 | "datetime_interval_code" "datetime_interval_precision" "defined" |
| 905 | "like" "not" "null" "of" "on" "option" "or" "order" "privileges" | 924 | "definer" "dispatch" "dynamic_function" "dynamic_function_code" |
| 906 | "public" "select" "set" "table" "to" "union" "unique" | 925 | "existing" "exists" "final" "fortran" "generated" "granted" |
| 907 | "update" "user" "values" "view" "where" "with" | 926 | "hierarchy" "hold" "implementation" "infix" "insensitive" "instance" |
| 908 | 927 | "instantiable" "invoker" "key_member" "key_type" "length" "m" | |
| 909 | ) t) "\\b"))) | 928 | "message_length" "message_octet_length" "message_text" "method" "more" |
| 910 | (ansi-types (eval-when-compile | 929 | "mumps" "name" "nullable" "number" "options" "overlaps" "overriding" |
| 911 | (concat "\\b" | 930 | "parameter_mode" "parameter_name" "parameter_ordinal_position" |
| 912 | (regexp-opt '( | 931 | "parameter_specific_catalog" "parameter_specific_name" |
| 913 | 932 | "parameter_specific_schema" "pascal" "pli" "position" "repeatable" | |
| 914 | ;; ANSI Keywords that look like types | 933 | "returned_length" "returned_octet_length" "returned_sqlstate" |
| 915 | "character" "cursor" "dec" "int" "real" | 934 | "routine_catalog" "routine_name" "routine_schema" "row_count" "scale" |
| 916 | ;; ANSI Reserved Word that look like types | 935 | "schema_name" "security" "self" "sensitive" "serializable" |
| 917 | "char" "integer" "smallint" | 936 | "server_name" "similar" "simple" "source" "specific_name" "style" |
| 918 | 937 | "subclass_origin" "sublist" "symmetric" "system" "table_name" | |
| 919 | ) t) "\\b")))) | 938 | "transaction_active" "transactions_committed" |
| 920 | (list (cons ansi-keywords 'font-lock-keyword-face) | 939 | "transactions_rolled_back" "transform" "transforms" "trigger_catalog" |
| 921 | (cons ansi-reserved-words 'font-lock-keyword-face) | 940 | "trigger_name" "trigger_schema" "type" "uncommitted" "unnamed" |
| 922 | (cons ansi-types 'font-lock-type-face))) | 941 | "user_defined_type_catalog" "user_defined_type_name" |
| 942 | "user_defined_type_schema" | ||
| 943 | )) | ||
| 944 | |||
| 945 | (ansi-reserved (sql-keywords-re | ||
| 946 | "absolute" "action" "add" "admin" "after" "aggregate" "alias" "all" | ||
| 947 | "allocate" "alter" "and" "any" "are" "as" "asc" "assertion" "at" | ||
| 948 | "authorization" "before" "begin" "both" "breadth" "by" "call" | ||
| 949 | "cascade" "cascaded" "case" "catalog" "check" "class" "close" | ||
| 950 | "collate" "collation" "column" "commit" "completion" "connect" | ||
| 951 | "connection" "constraint" "constraints" "constructor" "continue" | ||
| 952 | "corresponding" "create" "cross" "cube" "current" "cursor" "cycle" | ||
| 953 | "data" "day" "deallocate" "declare" "default" "deferrable" "deferred" | ||
| 954 | "delete" "depth" "deref" "desc" "describe" "descriptor" "destroy" | ||
| 955 | "destructor" "deterministic" "diagnostics" "dictionary" "disconnect" | ||
| 956 | "distinct" "domain" "drop" "dynamic" "each" "else" "end" "equals" | ||
| 957 | "escape" "every" "except" "exception" "exec" "execute" "external" | ||
| 958 | "false" "fetch" "first" "for" "foreign" "found" "free" "from" "full" | ||
| 959 | "function" "general" "get" "global" "go" "goto" "grant" "group" | ||
| 960 | "grouping" "having" "host" "hour" "identity" "ignore" "immediate" "in" | ||
| 961 | "indicator" "initialize" "initially" "inner" "inout" "input" "insert" | ||
| 962 | "intersect" "into" "is" "isolation" "iterate" "join" "key" "language" | ||
| 963 | "last" "lateral" "leading" "left" "less" "level" "like" "limit" | ||
| 964 | "local" "locator" "map" "match" "minute" "modifies" "modify" "module" | ||
| 965 | "month" "names" "natural" "new" "next" "no" "none" "not" "null" "of" | ||
| 966 | "off" "old" "on" "only" "open" "operation" "option" "or" "order" | ||
| 967 | "ordinality" "out" "outer" "output" "pad" "parameter" "parameters" | ||
| 968 | "partial" "path" "postfix" "prefix" "preorder" "prepare" "preserve" | ||
| 969 | "primary" "prior" "privileges" "procedure" "public" "read" "reads" | ||
| 970 | "recursive" "references" "referencing" "relative" "restrict" "result" | ||
| 971 | "return" "returns" "revoke" "right" "role" "rollback" "rollup" | ||
| 972 | "routine" "rows" "savepoint" "schema" "scroll" "search" "second" | ||
| 973 | "section" "select" "sequence" "session" "set" "sets" "size" "some" | ||
| 974 | "space" "specific" "specifictype" "sql" "sqlexception" "sqlstate" | ||
| 975 | "sqlwarning" "start" "state" "statement" "static" "structure" "table" | ||
| 976 | "temporary" "terminate" "than" "then" "timezone_hour" | ||
| 977 | "timezone_minute" "to" "trailing" "transaction" "translation" | ||
| 978 | "trigger" "true" "under" "union" "unique" "unknown" "unnest" "update" | ||
| 979 | "usage" "using" "value" "values" "variable" "view" "when" "whenever" | ||
| 980 | "where" "with" "without" "work" "write" "year" | ||
| 981 | )) | ||
| 982 | |||
| 983 | (ansi-types (sql-keywords-re | ||
| 984 | "array" "binary" "bit" "blob" "boolean" "char" "character" "clob" | ||
| 985 | "date" "dec" "decimal" "double" "float" "int" "integer" "interval" | ||
| 986 | "large" "national" "nchar" "nclob" "numeric" "object" "precision" | ||
| 987 | "real" "ref" "row" "scope" "smallint" "time" "timestamp" "varchar" | ||
| 988 | "varying" "zone" | ||
| 989 | ))) | ||
| 990 | |||
| 991 | `((,ansi-non-reserved . font-lock-keyword-face) | ||
| 992 | (,ansi-reserved . font-lock-keyword-face) | ||
| 993 | (,ansi-funcs . font-lock-builtin-face) | ||
| 994 | (,ansi-types . font-lock-type-face))) | ||
| 923 | 995 | ||
| 924 | "ANSI SQL keywords used by font-lock. | 996 | "ANSI SQL keywords used by font-lock. |
| 925 | 997 | ||
| @@ -930,66 +1002,156 @@ you define your own sql-mode-ansi-font-lock-keywords. You may want to | |||
| 930 | add functions and PL/SQL keywords.") | 1002 | add functions and PL/SQL keywords.") |
| 931 | 1003 | ||
| 932 | (defvar sql-mode-oracle-font-lock-keywords | 1004 | (defvar sql-mode-oracle-font-lock-keywords |
| 933 | (let ((oracle-keywords (eval-when-compile | 1005 | (let ((oracle-functions (sql-keywords-re |
| 934 | (concat "\\b" | 1006 | "abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2" |
| 935 | (regexp-opt '( | 1007 | "avg" "bfilename" "bin_to_num" "bitand" "cast" "ceil" "chartorowid" |
| 936 | ;; Oracle (+ANSI) SQL keywords | 1008 | "chr" "coalesce" "compose" "concat" "convert" "corr" "cos" "cosh" |
| 937 | 1009 | "count" "covar_pop" "covar_samp" "cume_dist" "current_date" | |
| 938 | ; ANSI keywords | 1010 | "current_timestamp" "current_user" "dbtimezone" "decode" "decompose" |
| 939 | "authorization" "avg" "begin" "close" "cobol" "commit" | 1011 | "dense_rank" "depth" "deref" "dump" "empty_clob" "existsnode" "exp" |
| 940 | "continue" "count" "declare" "double" "end" "escape" | 1012 | "extract" "extractvalue" "first" "first_value" "floor" "following" |
| 941 | "exec" "fetch" "foreign" "fortran" "found" "go" "goto" "indicator" | 1013 | "from_tz" "greatest" "group_id" "grouping_id" "hextoraw" "initcap" |
| 942 | "key" "language" "max" "min" "module" "numeric" "open" "pascal" "pli" | 1014 | "instr" "lag" "last" "last_day" "last_value" "lead" "least" "length" |
| 943 | "precision" "primary" "procedure" "references" "rollback" | 1015 | "ln" "localtimestamp" "lower" "lpad" "ltrim" "make_ref" "max" "min" |
| 944 | "schema" "section" "some" "sqlcode" "sqlerror" "sum" "work" | 1016 | "mod" "months_between" "new_time" "next_day" "nls_charset_decl_len" |
| 945 | 1017 | "nls_charset_id" "nls_charset_name" "nls_initcap" "nls_lower" | |
| 946 | ; ANSI reserved words | 1018 | "nls_upper" "nlssort" "ntile" "nullif" "numtodsinterval" |
| 947 | "all" "and" "any" "as" "asc" "between" "by" "check" "create" | 1019 | "numtoyminterval" "nvl" "nvl2" "over" "path" "percent_rank" |
| 948 | "current" "default" "delete" "desc" "distinct" "exists" "float" "for" | 1020 | "percentile_cont" "percentile_disc" "power" "preceding" "rank" |
| 949 | "from" "grant" "group" "having" "in" "insert" "into" "is" | 1021 | "ratio_to_report" "rawtohex" "rawtonhex" "reftohex" "regr_" |
| 950 | "like" "not" "null" "of" "on" "option" "or" "order" "privileges" | 1022 | "regr_avgx" "regr_avgy" "regr_count" "regr_intercept" "regr_r2" |
| 951 | "public" "select" "set" "table" "to" "union" "unique" | 1023 | "regr_slope" "regr_sxx" "regr_sxy" "regr_syy" "replace" "round" |
| 952 | "update" "user" "values" "view" "where" "with" | 1024 | "row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim" |
| 953 | 1025 | "sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev" | |
| 954 | "access" "add" "admin" "after" "allocate" "alter" "analyze" "archive" | 1026 | "stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path" |
| 955 | "archivelog" "audit" "authid" "backup" "become" "before" "block" | 1027 | "sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" |
| 956 | "body" "cache" "cancel" "cascade" "change" "checkpoint" "cluster" | 1028 | "sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh" |
| 957 | "comment" "compile" "compress" "compute" "connect" "constraint" | 1029 | "to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" |
| 958 | "constraints" "contents" "controlfile" "cross" "currval" "cycle" | 1030 | "to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" |
| 959 | "database" "datafile" "dba" "deterministic" "disable" "dismount" | 1031 | "to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" |
| 960 | "drop" "dump" "each" "else" "else" "elsif" "enable" "events" "except" | 1032 | "tz_offset" "uid" "unbounded" "unistr" "updatexml" "upper" "user" |
| 961 | "exceptions" "exclusive" "execute" "exit" "explain" "extent" | 1033 | "userenv" "var_pop" "var_samp" "variance" "vsize" "width_bucket" "xml" |
| 962 | "externally" "false" "file" "flush" "force" "freelist" "freelists" | 1034 | "xmlagg" "xmlattribute" "xmlcolattval" "xmlconcat" "xmlelement" |
| 963 | "full" "function" "global" "grant" "groups" "identified" "if" | 1035 | "xmlforest" "xmlsequence" "xmltransform" |
| 964 | "immediate" "including" "increment" "index" "initial" "initrans" | 1036 | )) |
| 965 | "inner" "instance" "intersect" "join" "layer" "left" "level" "link" | 1037 | |
| 966 | "lists" "lock" "logfile" "long" "loop" "manage" "manual" | 1038 | (oracle-keywords (sql-keywords-re |
| 967 | "maxdatafiles" "maxextents" "maxinistances" "maxlogfiles" | 1039 | "abort" "access" "accessed" "account" "activate" "add" "admin" |
| 968 | "maxloghistory" "maxlogmembers" "maxtrans" "maxvalue" "merge" | 1040 | "advise" "after" "agent" "aggregate" "all" "allocate" "allow" "alter" |
| 969 | "minextents" "minus" "minvalue" "mode" "modify" "mount" "natural" | 1041 | "always" "analyze" "ancillary" "and" "any" "apply" "archive" |
| 970 | "new" "next" "nextval" "noarchivelog" "noaudit" "nocache" "nocompress" | 1042 | "archivelog" "array" "as" "asc" "associate" "at" "attribute" |
| 971 | "nocycle" "nomaxvalue" "nominvalue" "none" "noorder" "noresetlogs" | 1043 | "attributes" "audit" "authenticated" "authid" "authorization" "auto" |
| 972 | "normal" "nosort" "nowait" "off" "offline" "old" "online" "only" | 1044 | "autoallocate" "automatic" "availability" "backup" "before" "begin" |
| 973 | "optimal" "others" "out" "outer" "over" "own" "package" "parallel" | 1045 | "behalf" "between" "binding" "bitmap" "block" "blocksize" "body" |
| 974 | "parallel_enable" "pctfree" "pctincrease" "pctused" "plan" "pragma" | 1046 | "both" "buffer_pool" "build" "by" "cache" "call" "cancel" |
| 975 | "preserve" "prior" "private" "profile" "quota" "raise" "raw" "read" | 1047 | "cascade" "case" "category" "certificate" "chained" "change" "check" |
| 976 | "recover" "referencing" "rename" "replace" "resetlogs" "resource" | 1048 | "checkpoint" "child" "chunk" "class" "clear" "clone" "close" "cluster" |
| 977 | "restrict_references" "restricted" "return" "returning" "reuse" | 1049 | "column" "column_value" "columns" "comment" "commit" "committed" |
| 978 | "revoke" "right" "rnds" "rnps" "role" "roles" "row" "rowlabel" | 1050 | "compatibility" "compile" "complete" "composite_limit" "compress" |
| 979 | "rownum" "rows" "savepoint" "scn" "segment" "sequence" "session" | 1051 | "compute" "connect" "connect_time" "consider" "consistent" |
| 980 | "share" "shared" "size" "snapshot" "sort" "statement_id" "statistics" | 1052 | "constraint" "constraints" "constructor" "contents" "context" |
| 981 | "stop" "storage" "subtype" "successful" "switch" "synonym" "sysdate" | 1053 | "continue" "controlfile" "corruption" "cost" "cpu_per_call" |
| 982 | "system" "tables" "tablespace" "temporary" "then" "thread" "tracing" | 1054 | "cpu_per_session" "create" "cross" "cube" "current" "currval" "cycle" |
| 983 | "transaction" "trigger" "triggers" "true" "truncate" "type" "uid" | 1055 | "dangling" "data" "database" "datafile" "datafiles" "day" "ddl" |
| 984 | "under" "unlimited" "until" "use" "using" "validate" "when" "while" | 1056 | "deallocate" "debug" "default" "deferrable" "deferred" "definer" |
| 985 | "wnds" "wnps" "write" | 1057 | "delay" "delete" "demand" "desc" "determines" "deterministic" |
| 986 | 1058 | "dictionary" "dimension" "directory" "disable" "disassociate" | |
| 987 | ) t) "\\b"))) | 1059 | "disconnect" "distinct" "distinguished" "distributed" "dml" "drop" |
| 988 | (oracle-warning-words (eval-when-compile | 1060 | "each" "element" "else" "enable" "end" "equals_path" "escape" |
| 989 | (concat "\\b" | 1061 | "estimate" "except" "exceptions" "exchange" "excluding" "exists" |
| 990 | (regexp-opt '( | 1062 | "expire" "explain" "extent" "external" "externally" |
| 991 | ;; PLSQL defined exceptions | 1063 | "failed_login_attempts" "fast" "file" "final" "finish" "flush" "for" |
| 992 | 1064 | "force" "foreign" "freelist" "freelists" "freepools" "fresh" "from" | |
| 1065 | "full" "function" "functions" "generated" "global" "global_name" | ||
| 1066 | "globally" "grant" "group" "grouping" "groups" "guard" "hash" | ||
| 1067 | "hashkeys" "having" "heap" "hierarchy" "id" "identified" "identifier" | ||
| 1068 | "idle_time" "immediate" "in" "including" "increment" "index" "indexed" | ||
| 1069 | "indexes" "indextype" "indextypes" "indicator" "initial" "initialized" | ||
| 1070 | "initially" "initrans" "inner" "insert" "instance" "instantiable" | ||
| 1071 | "instead" "intersect" "into" "invalidate" "is" "isolation" "java" | ||
| 1072 | "join" "keep" "key" "kill" "language" "left" "less" "level" | ||
| 1073 | "levels" "library" "like" "like2" "like4" "likec" "limit" "link" | ||
| 1074 | "list" "lob" "local" "location" "locator" "lock" "log" "logfile" | ||
| 1075 | "logging" "logical" "logical_reads_per_call" | ||
| 1076 | "logical_reads_per_session" "managed" "management" "manual" "map" | ||
| 1077 | "mapping" "master" "matched" "materialized" "maxdatafiles" | ||
| 1078 | "maxextents" "maximize" "maxinstances" "maxlogfiles" "maxloghistory" | ||
| 1079 | "maxlogmembers" "maxsize" "maxtrans" "maxvalue" "member" "memory" | ||
| 1080 | "merge" "migrate" "minextents" "minimize" "minimum" "minus" "minvalue" | ||
| 1081 | "mode" "modify" "monitoring" "month" "mount" "move" "movement" "name" | ||
| 1082 | "named" "natural" "nested" "never" "new" "next" "nextval" "no" | ||
| 1083 | "noarchivelog" "noaudit" "nocache" "nocompress" "nocopy" "nocycle" | ||
| 1084 | "nodelay" "noforce" "nologging" "nomapping" "nomaxvalue" "nominimize" | ||
| 1085 | "nominvalue" "nomonitoring" "none" "noorder" "noparallel" "norely" | ||
| 1086 | "noresetlogs" "noreverse" "normal" "norowdependencies" "nosort" | ||
| 1087 | "noswitch" "not" "nothing" "notimeout" "novalidate" "nowait" "null" | ||
| 1088 | "nulls" "object" "of" "off" "offline" "oidindex" "old" "on" "online" | ||
| 1089 | "only" "open" "operator" "optimal" "option" "or" "order" | ||
| 1090 | "organization" "out" "outer" "outline" "overflow" "overriding" | ||
| 1091 | "package" "packages" "parallel" "parallel_enable" "parameters" | ||
| 1092 | "parent" "partition" "partitions" "password" "password_grace_time" | ||
| 1093 | "password_life_time" "password_lock_time" "password_reuse_max" | ||
| 1094 | "password_reuse_time" "password_verify_function" "pctfree" | ||
| 1095 | "pctincrease" "pctthreshold" "pctused" "pctversion" "percent" | ||
| 1096 | "performance" "permanent" "pfile" "physical" "pipelined" "plan" | ||
| 1097 | "post_transaction" "pragma" "prebuilt" "preserve" "primary" "private" | ||
| 1098 | "private_sga" "privileges" "procedure" "profile" "protection" "public" | ||
| 1099 | "purge" "query" "quiesce" "quota" "range" "read" "reads" "rebuild" | ||
| 1100 | "records_per_block" "recover" "recovery" "recycle" "reduced" "ref" | ||
| 1101 | "references" "referencing" "refresh" "register" "reject" "relational" | ||
| 1102 | "rely" "rename" "reset" "resetlogs" "resize" "resolve" "resolver" | ||
| 1103 | "resource" "restrict" "restrict_references" "restricted" "result" | ||
| 1104 | "resumable" "resume" "retention" "return" "returning" "reuse" | ||
| 1105 | "reverse" "revoke" "rewrite" "right" "rnds" "rnps" "role" "roles" | ||
| 1106 | "rollback" "rollup" "row" "rowdependencies" "rownum" "rows" "sample" | ||
| 1107 | "savepoint" "scan" "schema" "scn" "scope" "segment" "select" | ||
| 1108 | "selectivity" "self" "sequence" "serializable" "session" | ||
| 1109 | "sessions_per_user" "set" "sets" "settings" "shared" "shared_pool" | ||
| 1110 | "shrink" "shutdown" "siblings" "sid" "single" "size" "skip" "some" | ||
| 1111 | "sort" "source" "space" "specification" "spfile" "split" "standby" | ||
| 1112 | "start" "statement_id" "static" "statistics" "stop" "storage" "store" | ||
| 1113 | "structure" "subpartition" "subpartitions" "substitutable" | ||
| 1114 | "successful" "supplemental" "suspend" "switch" "switchover" "synonym" | ||
| 1115 | "sys" "system" "table" "tables" "tablespace" "tempfile" "template" | ||
| 1116 | "temporary" "test" "than" "then" "thread" "through" "time_zone" | ||
| 1117 | "timeout" "to" "trace" "transaction" "trigger" "triggers" "truncate" | ||
| 1118 | "trust" "type" "types" "unarchived" "under" "under_path" "undo" | ||
| 1119 | "uniform" "union" "unique" "unlimited" "unlock" "unquiesce" | ||
| 1120 | "unrecoverable" "until" "unusable" "unused" "update" "upgrade" "usage" | ||
| 1121 | "use" "using" "validate" "validation" "value" "values" "variable" | ||
| 1122 | "varray" "version" "view" "wait" "when" "whenever" "where" "with" | ||
| 1123 | "without" "wnds" "wnps" "work" "write" "xmldata" "xmlschema" "xmltype" | ||
| 1124 | )) | ||
| 1125 | |||
| 1126 | (oracle-types (sql-keywords-re | ||
| 1127 | "bfile" "blob" "byte" "char" "character" "clob" "date" "dec" "decimal" | ||
| 1128 | "double" "float" "int" "integer" "interval" "long" "national" "nchar" | ||
| 1129 | "nclob" "number" "numeric" "nvarchar2" "precision" "raw" "real" | ||
| 1130 | "rowid" "second" "smallint" "time" "timestamp" "urowid" "varchar" | ||
| 1131 | "varchar2" "varying" "year" "zone" | ||
| 1132 | )) | ||
| 1133 | |||
| 1134 | (plsql-functions (sql-keywords-re | ||
| 1135 | "%bulk_rowcount" "%found" "%isopen" "%notfound" "%rowcount" "%rowtype" | ||
| 1136 | "%type" "extend" "prior" | ||
| 1137 | )) | ||
| 1138 | |||
| 1139 | (plsql-keywords (sql-keywords-re | ||
| 1140 | "autonomous_transaction" "bulk" "char_base" "collect" "constant" | ||
| 1141 | "cursor" "declare" "do" "elsif" "exception_init" "execute" "exit" | ||
| 1142 | "extends" "false" "fetch" "forall" "goto" "hour" "if" "interface" | ||
| 1143 | "loop" "minute" "number_base" "ocirowid" "opaque" "others" "rowtype" | ||
| 1144 | "separate" "serially_reusable" "sql" "sqlcode" "sqlerrm" "subtype" | ||
| 1145 | "the" "timezone_abbr" "timezone_hour" "timezone_minute" | ||
| 1146 | "timezone_region" "true" "varrying" "while" | ||
| 1147 | )) | ||
| 1148 | |||
| 1149 | (plsql-type (sql-keywords-re | ||
| 1150 | "binary_integer" "boolean" "naturaln" "pls_integer" "positive" | ||
| 1151 | "positiven" "record" "signtype" "string" | ||
| 1152 | )) | ||
| 1153 | |||
| 1154 | (plsql-warning (sql-keywords-re | ||
| 993 | "access_into_null" "case_not_found" "collection_is_null" | 1155 | "access_into_null" "case_not_found" "collection_is_null" |
| 994 | "cursor_already_open" "dup_val_on_index" "invalid_cursor" | 1156 | "cursor_already_open" "dup_val_on_index" "invalid_cursor" |
| 995 | "invalid_number" "login_denied" "no_data_found" "not_logged_on" | 1157 | "invalid_number" "login_denied" "no_data_found" "not_logged_on" |
| @@ -997,15 +1159,11 @@ add functions and PL/SQL keywords.") | |||
| 997 | "subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid" | 1159 | "subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid" |
| 998 | "timeout_on_resource" "too_many_rows" "value_error" "zero_divide" | 1160 | "timeout_on_resource" "too_many_rows" "value_error" "zero_divide" |
| 999 | "exception" "notfound" | 1161 | "exception" "notfound" |
| 1162 | )) | ||
| 1000 | 1163 | ||
| 1001 | ) t) "\\b"))) | 1164 | (sqlplus-commands |
| 1002 | 1165 | (eval-when-compile (concat "^\\(\\(" | |
| 1003 | (oracle-sqlplus-commands | 1166 | (regexp-opt '( |
| 1004 | (eval-when-compile | ||
| 1005 | (concat "^\\(\\(" | ||
| 1006 | (regexp-opt '( | ||
| 1007 | ;; SQL*Plus commands | ||
| 1008 | |||
| 1009 | "@" "@@" "accept" "append" "archive" "attribute" "break" | 1167 | "@" "@@" "accept" "append" "archive" "attribute" "break" |
| 1010 | "btitle" "change" "clear" "column" "connect" "copy" "define" | 1168 | "btitle" "change" "clear" "column" "connect" "copy" "define" |
| 1011 | "del" "describe" "disconnect" "edit" "execute" "exit" "get" "help" | 1169 | "del" "describe" "disconnect" "edit" "execute" "exit" "get" "help" |
| @@ -1040,73 +1198,16 @@ add functions and PL/SQL keywords.") | |||
| 1040 | "timi\\(ng\\)?\\|trim\\(out\\)?\\|trims\\(pool\\)?\\|" | 1198 | "timi\\(ng\\)?\\|trim\\(out\\)?\\|trims\\(pool\\)?\\|" |
| 1041 | "und\\(erline\\)?\\|ver\\(ify\\)?\\|wra\\(p\\)?\\)\\)\\)" | 1199 | "und\\(erline\\)?\\|ver\\(ify\\)?\\|wra\\(p\\)?\\)\\)\\)" |
| 1042 | "\\b.*$" | 1200 | "\\b.*$" |
| 1043 | ))) | 1201 | )))) |
| 1044 | 1202 | ||
| 1045 | (oracle-types | 1203 | `((,sqlplus-commands . font-lock-doc-face) |
| 1046 | (eval-when-compile | 1204 | (,oracle-functions . font-lock-builtin-face) |
| 1047 | (concat "\\b" | 1205 | (,oracle-keywords . font-lock-keyword-face) |
| 1048 | (regexp-opt '( | 1206 | (,oracle-types . font-lock-type-face) |
| 1049 | ;; Oracle Keywords that look like types | 1207 | (,plsql-functions . font-lock-builtin-face) |
| 1050 | ;; Oracle Reserved Words that look like types | 1208 | (,plsql-keywords . font-lock-keyword-face) |
| 1051 | 1209 | (,plsql-type . font-lock-type-face) | |
| 1052 | "bfile" "binary_integer" "blob" "boolean" "byte" "char" "character" | 1210 | (,plsql-warning . font-lock-warning-face))) |
| 1053 | "clob" "date" "day" "dec" "decimal" "double" "float" "int" "integer" | ||
| 1054 | "interval" "local" "long" "month" "natural" "naturaln" "nchar" "nclob" | ||
| 1055 | "number" "numeric" "nvarchar2" "pls_integer" "positive" "positiven" | ||
| 1056 | "precision" "raw" "real" "rowid" "second" "signtype" "smallint" | ||
| 1057 | "string" "time" "timestamp" "urowid" "varchar" "varchar2" "year" | ||
| 1058 | "zone" | ||
| 1059 | |||
| 1060 | ) t) "\\b"))) | ||
| 1061 | (oracle-builtin-functions (eval-when-compile | ||
| 1062 | (concat "\\b" | ||
| 1063 | (regexp-opt '( | ||
| 1064 | ;; Misc Oracle builtin functions | ||
| 1065 | |||
| 1066 | "abs" "acos" "add_months" "ascii" "asciistr" "asin" "atan" "atan2" | ||
| 1067 | "avg" "bfilename" "bin_to_num" "bitand" "case" "cast" "ceil" | ||
| 1068 | "chartorowid" "chr" "coalesce" "compose" "concat" "convert" "corr" | ||
| 1069 | "cos" "cosh" "count" "covar_pop" "covar_samp" "cume_dist" | ||
| 1070 | "current_date" "current_timestamp" "current_user" "dbtimezone" | ||
| 1071 | "decode" "decompose" "dense_rank" "depth" "deref" "dump" "empty_blob" | ||
| 1072 | "empty_clob" "existsnode" "exp" "extract" "extractvalue" "first" | ||
| 1073 | "first_value" "floor" "from_tz" "greatest" "group_id" "grouping" | ||
| 1074 | "grouping_id" "hextoraw" "initcap" "instr" "lag" "last" "last_day" | ||
| 1075 | "last_value" "lead" "least" "length" "ln" "localtimestamp" "log" | ||
| 1076 | "lower" "lpad" "ltrim" "make_ref" "max" "min" "mod" "months_between" | ||
| 1077 | "nchr" "new_time" "next_day" "nls_charset_decl_len" "nls_charset_id" | ||
| 1078 | "nls_charset_name" "nls_initcap" "nls_lower" "nlssort" "nls_upper" | ||
| 1079 | "ntile" "nullif" "numtodsinterval" "numtoyminterval" "nvl" "nvl2" | ||
| 1080 | "path" "percent_rank" "percentile_cont" "percentile_disc" "power" | ||
| 1081 | "rank" "ratio_to_report" "rawtohex" "rawtonhex" "ref" "reftohex" | ||
| 1082 | "regr_slope" "regr_intercept" "regr_count" "regr_r2" "regr_avgx" | ||
| 1083 | "regr_avgy" "regr_sxx" "regr_syy" "regr_sxy" "round" | ||
| 1084 | "row_number" "rowidtochar" "rowidtonchar" "rpad" "rtrim" | ||
| 1085 | "sessiontimezone" "sign" "sin" "sinh" "soundex" "sqrt" "stddev" | ||
| 1086 | "stddev_pop" "stddev_samp" "substr" "sum" "sys_connect_by_path" | ||
| 1087 | "sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" | ||
| 1088 | "sys_xmlagg" "sys_xmlgen" "sysdate" "systimestamp" "tan" "tanh" | ||
| 1089 | "to_char" "to_clob" "to_date" "to_dsinterval" "to_lob" "to_multi_byte" | ||
| 1090 | "to_nchar" "to_nclob" "to_number" "to_single_byte" "to_timestamp" | ||
| 1091 | "to_timestamp_tz" "to_yminterval" "translate" "treat" "trim" "trunc" | ||
| 1092 | "tz_offset" "uid" "unistr" "updatexml" "upper" "user" "userenv" | ||
| 1093 | "value" "var_pop" "var_samp" "variance" "vsize" "width_bucket" | ||
| 1094 | "xmlagg" "xmlcolattval" "xmlconcat" "xmlelement" "xmlforest" | ||
| 1095 | "xmlsequence" "xmltransform" | ||
| 1096 | |||
| 1097 | ) t) "\\b")))) | ||
| 1098 | (list (cons oracle-sqlplus-commands 'font-lock-doc-face) | ||
| 1099 | (cons oracle-keywords 'font-lock-keyword-face) | ||
| 1100 | (cons oracle-warning-words 'font-lock-warning-face) | ||
| 1101 | ;; XEmacs doesn't have font-lock-builtin-face | ||
| 1102 | (if (string-match "XEmacs\\|Lucid" emacs-version) | ||
| 1103 | (cons oracle-builtin-functions 'font-lock-preprocessor-face) | ||
| 1104 | ;; GNU Emacs 19 doesn't have it either | ||
| 1105 | (if (string-match "GNU Emacs 19" emacs-version) | ||
| 1106 | (cons oracle-builtin-functions 'font-lock-keyword-face) | ||
| 1107 | ;; Emacs | ||
| 1108 | (cons oracle-builtin-functions 'font-lock-builtin-face))) | ||
| 1109 | (cons oracle-types 'font-lock-type-face))) | ||
| 1110 | 1211 | ||
| 1111 | "Oracle SQL keywords used by font-lock. | 1212 | "Oracle SQL keywords used by font-lock. |
| 1112 | 1213 | ||
| @@ -1117,42 +1218,84 @@ you define your own sql-mode-oracle-font-lock-keywords. You may want | |||
| 1117 | to add functions and PL/SQL keywords.") | 1218 | to add functions and PL/SQL keywords.") |
| 1118 | 1219 | ||
| 1119 | (defvar sql-mode-postgres-font-lock-keywords | 1220 | (defvar sql-mode-postgres-font-lock-keywords |
| 1120 | (let ((postgres-reserved-words (eval-when-compile | 1221 | (let ((pg-funcs (sql-keywords-re |
| 1121 | (concat "\\b" | 1222 | "abbrev" "abs" "acos" "age" "area" "ascii" "asin" "atab2" "atan" |
| 1122 | (regexp-opt '( | 1223 | "atan2" "avg" "bit_length" "both" "broadcast" "btrim" "cbrt" "ceil" |
| 1123 | "language" | 1224 | "center" "char_length" "chr" "coalesce" "col_description" "convert" |
| 1124 | ) t) "\\b"))) | 1225 | "cos" "cot" "count" "current_database" "current_date" "current_schema" |
| 1125 | (postgres-types (eval-when-compile | 1226 | "current_schemas" "current_setting" "current_time" "current_timestamp" |
| 1126 | (concat "\\b" | 1227 | "current_user" "currval" "date_part" "date_trunc" "decode" "degrees" |
| 1127 | (regexp-opt '( | 1228 | "diameter" "encode" "exp" "extract" "floor" "get_bit" "get_byte" |
| 1128 | 1229 | "has_database_privilege" "has_function_privilege" | |
| 1129 | "bool" "box" "circle" "char" "char2" "char4" "char8" "char16" "date" | 1230 | "has_language_privilege" "has_schema_privilege" "has_table_privilege" |
| 1130 | "float4" "float8" "int2" "int4" "int8" "line" "lseg" "money" "path" | 1231 | "height" "host" "initcap" "isclosed" "isfinite" "isopen" "leading" |
| 1131 | "point" "polygon" "serial" "text" "time" "timespan" "timestamp" "varchar" | 1232 | "length" "ln" "localtime" "localtimestamp" "log" "lower" "lpad" |
| 1132 | 1233 | "ltrim" "masklen" "max" "min" "mod" "netmask" "network" "nextval" | |
| 1133 | ) t)"\\b"))) | 1234 | "now" "npoints" "nullif" "obj_description" "octet_length" "overlay" |
| 1134 | (postgres-builtin-functions (eval-when-compile | 1235 | "pclose" "pg_client_encoding" "pg_function_is_visible" |
| 1135 | (concat "\\b" | 1236 | "pg_get_constraintdef" "pg_get_indexdef" "pg_get_ruledef" |
| 1136 | (regexp-opt '( | 1237 | "pg_get_userbyid" "pg_get_viewdef" "pg_opclass_is_visible" |
| 1137 | ;; Misc Postgres builtin functions | 1238 | "pg_operator_is_visible" "pg_table_is_visible" "pg_type_is_visible" |
| 1138 | 1239 | "pi" "popen" "position" "pow" "quote_ident" "quote_literal" "radians" | |
| 1139 | "abstime" "age" "area" "box" "center" "date_part" "date_trunc" | 1240 | "radius" "random" "repeat" "replace" "round" "rpad" "rtrim" |
| 1140 | "datetime" "dexp" "diameter" "dpow" "float" "float4" "height" | 1241 | "session_user" "set_bit" "set_byte" "set_config" "set_masklen" |
| 1141 | "initcap" "integer" "isclosed" "isfinite" "isoldpath" "isopen" | 1242 | "setval" "sign" "sin" "split_part" "sqrt" "stddev" "strpos" "substr" |
| 1142 | "length" "lower" "lpad" "ltrim" "pclose" "point" "points" "popen" | 1243 | "substring" "sum" "tan" "timeofday" "to_ascii" "to_char" "to_date" |
| 1143 | "position" "radius" "reltime" "revertpoly" "rpad" "rtrim" "substr" | 1244 | "to_hex" "to_number" "to_timestamp" "trailing" "translate" "trim" |
| 1144 | "substring" "text" "timespan" "translate" "trim" "upgradepath" | 1245 | "trunc" "upper" "variance" "version" "width" |
| 1145 | "upgradepoly" "upper" "varchar" "width" | 1246 | )) |
| 1146 | 1247 | ||
| 1147 | ) t) "\\b")))) | 1248 | (pg-reserved (sql-keywords-re |
| 1148 | (append sql-mode-ansi-font-lock-keywords | 1249 | "abort" "access" "add" "after" "aggregate" "alignment" "all" "alter" |
| 1149 | (list (cons postgres-reserved-words 'font-lock-keyword-face) | 1250 | "analyze" "and" "any" "as" "asc" "assignment" "authorization" |
| 1150 | ;; XEmacs doesn't have 'font-lock-builtin-face | 1251 | "backward" "basetype" "before" "begin" "between" "binary" "by" "cache" |
| 1151 | (if (string-match "XEmacs\\|Lucid" emacs-version) | 1252 | "called" "cascade" "case" "cast" "characteristics" "check" |
| 1152 | (cons postgres-builtin-functions 'font-lock-preprocessor-face) | 1253 | "checkpoint" "class" "close" "cluster" "column" "comment" "commit" |
| 1153 | ;; Emacs | 1254 | "committed" "commutator" "constraint" "constraints" "conversion" |
| 1154 | (cons postgres-builtin-functions 'font-lock-builtin-face)) | 1255 | "copy" "create" "createdb" "createuser" "cursor" "cycle" "database" |
| 1155 | (cons postgres-types 'font-lock-type-face)))) | 1256 | "deallocate" "declare" "default" "deferrable" "deferred" "definer" |
| 1257 | "delete" "delimiter" "desc" "distinct" "do" "domain" "drop" "each" | ||
| 1258 | "element" "else" "encoding" "encrypted" "end" "escape" "except" | ||
| 1259 | "exclusive" "execute" "exists" "explain" "extended" "external" "false" | ||
| 1260 | "fetch" "finalfunc" "for" "force" "foreign" "forward" "freeze" "from" | ||
| 1261 | "full" "function" "grant" "group" "gtcmp" "handler" "hashes" "having" | ||
| 1262 | "immediate" "immutable" "implicit" "in" "increment" "index" "inherits" | ||
| 1263 | "initcond" "initially" "input" "insensitive" "insert" "instead" | ||
| 1264 | "internallength" "intersect" "into" "invoker" "is" "isnull" | ||
| 1265 | "isolation" "join" "key" "language" "leftarg" "level" "like" "limit" | ||
| 1266 | "listen" "load" "local" "location" "lock" "ltcmp" "main" "match" | ||
| 1267 | "maxvalue" "merges" "minvalue" "mode" "move" "natural" "negator" | ||
| 1268 | "next" "nocreatedb" "nocreateuser" "none" "not" "nothing" "notify" | ||
| 1269 | "notnull" "null" "of" "offset" "oids" "on" "only" "operator" "or" | ||
| 1270 | "order" "output" "owner" "partial" "passedbyvalue" "password" "plain" | ||
| 1271 | "prepare" "primary" "prior" "privileges" "procedural" "procedure" | ||
| 1272 | "public" "read" "recheck" "references" "reindex" "relative" "rename" | ||
| 1273 | "reset" "restrict" "returns" "revoke" "rightarg" "rollback" "row" | ||
| 1274 | "rule" "schema" "scroll" "security" "select" "sequence" "serializable" | ||
| 1275 | "session" "set" "sfunc" "share" "show" "similar" "some" "sort1" | ||
| 1276 | "sort2" "stable" "start" "statement" "statistics" "storage" "strict" | ||
| 1277 | "stype" "sysid" "table" "temp" "template" "temporary" "then" "to" | ||
| 1278 | "transaction" "trigger" "true" "truncate" "trusted" "type" | ||
| 1279 | "unencrypted" "union" "unique" "unknown" "unlisten" "until" "update" | ||
| 1280 | "usage" "user" "using" "vacuum" "valid" "validator" "values" | ||
| 1281 | "variable" "verbose" "view" "volatile" "when" "where" "with" "without" | ||
| 1282 | "work" | ||
| 1283 | )) | ||
| 1284 | |||
| 1285 | (pg-types (sql-keywords-re | ||
| 1286 | "anyarray" "bigint" "bigserial" "bit" "boolean" "box" "bytea" "char" | ||
| 1287 | "character" "cidr" "circle" "cstring" "date" "decimal" "double" | ||
| 1288 | "float4" "float8" "inet" "int2" "int4" "int8" "integer" "internal" | ||
| 1289 | "interval" "language_handler" "line" "lseg" "macaddr" "money" | ||
| 1290 | "numeric" "oid" "opaque" "path" "point" "polygon" "precision" "real" | ||
| 1291 | "record" "regclass" "regoper" "regoperator" "regproc" "regprocedure" | ||
| 1292 | "regtype" "serial" "serial4" "serial8" "smallint" "text" "time" | ||
| 1293 | "timestamp" "varchar" "varying" "void" "zone" | ||
| 1294 | ))) | ||
| 1295 | |||
| 1296 | `((,pg-funcs . font-lock-builtin-face) | ||
| 1297 | (,pg-reserved . font-lock-keyword-face) | ||
| 1298 | (,pg-types . font-lock-type-face))) | ||
| 1156 | 1299 | ||
| 1157 | "Postgres SQL keywords used by font-lock. | 1300 | "Postgres SQL keywords used by font-lock. |
| 1158 | 1301 | ||
| @@ -1162,10 +1305,7 @@ function `regexp-opt'. Therefore, take a look at the source before | |||
| 1162 | you define your own sql-mode-postgres-font-lock-keywords.") | 1305 | you define your own sql-mode-postgres-font-lock-keywords.") |
| 1163 | 1306 | ||
| 1164 | (defvar sql-mode-linter-font-lock-keywords | 1307 | (defvar sql-mode-linter-font-lock-keywords |
| 1165 | (let ((linter-keywords (eval-when-compile | 1308 | (let ((linter-keywords (sql-keywords-re |
| 1166 | (concat "\\b" | ||
| 1167 | (regexp-opt '( | ||
| 1168 | |||
| 1169 | "autocommit" "autoinc" "autorowid" "cancel" "cascade" "channel" | 1309 | "autocommit" "autoinc" "autorowid" "cancel" "cascade" "channel" |
| 1170 | "committed" "count" "countblob" "cross" "current" "data" "database" | 1310 | "committed" "count" "countblob" "cross" "current" "data" "database" |
| 1171 | "datafile" "datafiles" "datesplit" "dba" "dbname" "default" "deferred" | 1311 | "datafile" "datafiles" "datesplit" "dba" "dbname" "default" "deferred" |
| @@ -1190,12 +1330,9 @@ you define your own sql-mode-postgres-font-lock-keywords.") | |||
| 1190 | "trigger_info_size" "true" "trunc" "uncommitted" "unicode" "unknown" | 1330 | "trigger_info_size" "true" "trunc" "uncommitted" "unicode" "unknown" |
| 1191 | "unlimited" "unlisted" "user" "utf8" "value" "varying" "volumes" | 1331 | "unlimited" "unlisted" "user" "utf8" "value" "varying" "volumes" |
| 1192 | "wait" "windows_code" "workspace" "write" "xml" | 1332 | "wait" "windows_code" "workspace" "write" "xml" |
| 1333 | )) | ||
| 1193 | 1334 | ||
| 1194 | ) t) "\\b"))) | 1335 | (linter-reserved (sql-keywords-re |
| 1195 | (linter-reserved-words (eval-when-compile | ||
| 1196 | (concat "\\b" | ||
| 1197 | (regexp-opt '( | ||
| 1198 | |||
| 1199 | "access" "action" "add" "address" "after" "all" "alter" "always" "and" | 1336 | "access" "action" "add" "address" "after" "all" "alter" "always" "and" |
| 1200 | "any" "append" "as" "asc" "ascic" "async" "at_begin" "at_end" "audit" | 1337 | "any" "append" "as" "asc" "ascic" "async" "at_begin" "at_end" "audit" |
| 1201 | "aud_obj_name_len" "backup" "base" "before" "between" "blobfile" | 1338 | "aud_obj_name_len" "backup" "base" "before" "between" "blobfile" |
| @@ -1213,22 +1350,16 @@ you define your own sql-mode-postgres-font-lock-keywords.") | |||
| 1213 | "start" "stop" "sync" "synchronize" "synonym" "sysdate" "table" "then" | 1350 | "start" "stop" "sync" "synchronize" "synonym" "sysdate" "table" "then" |
| 1214 | "to" "union" "unique" "unlock" "until" "update" "using" "values" | 1351 | "to" "union" "unique" "unlock" "until" "update" "using" "values" |
| 1215 | "view" "when" "where" "with" "without" | 1352 | "view" "when" "where" "with" "without" |
| 1353 | )) | ||
| 1216 | 1354 | ||
| 1217 | ) t) "\\b"))) | 1355 | (linter-types (sql-keywords-re |
| 1218 | (linter-types (eval-when-compile | ||
| 1219 | (concat "\\b" | ||
| 1220 | (regexp-opt '( | ||
| 1221 | |||
| 1222 | "bigint" "bitmap" "blob" "boolean" "char" "character" "date" | 1356 | "bigint" "bitmap" "blob" "boolean" "char" "character" "date" |
| 1223 | "datetime" "dec" "decimal" "double" "float" "int" "integer" "nchar" | 1357 | "datetime" "dec" "decimal" "double" "float" "int" "integer" "nchar" |
| 1224 | "number" "numeric" "real" "smallint" "varbyte" "varchar" "byte" | 1358 | "number" "numeric" "real" "smallint" "varbyte" "varchar" "byte" |
| 1225 | "cursor" "long" | 1359 | "cursor" "long" |
| 1360 | )) | ||
| 1226 | 1361 | ||
| 1227 | ) t) "\\b"))) | 1362 | (linter-functions (sql-keywords-re |
| 1228 | (linter-builtin-functions (eval-when-compile | ||
| 1229 | (concat "\\b" | ||
| 1230 | (regexp-opt '( | ||
| 1231 | |||
| 1232 | "abs" "acos" "asin" "atan" "atan2" "avg" "ceil" "cos" "cosh" "divtime" | 1363 | "abs" "acos" "asin" "atan" "atan2" "avg" "ceil" "cos" "cosh" "divtime" |
| 1233 | "exp" "floor" "getbits" "getblob" "getbyte" "getlong" "getraw" | 1364 | "exp" "floor" "getbits" "getblob" "getbyte" "getlong" "getraw" |
| 1234 | "getstr" "gettext" "getword" "hextoraw" "lenblob" "length" "log" | 1365 | "getstr" "gettext" "getword" "hextoraw" "lenblob" "length" "log" |
| @@ -1239,20 +1370,12 @@ you define your own sql-mode-postgres-font-lock-keywords.") | |||
| 1239 | "to_gmtime" "to_localtime" "to_number" "trim" "upper" "decode" | 1370 | "to_gmtime" "to_localtime" "to_number" "trim" "upper" "decode" |
| 1240 | "substr" "substring" "chr" "dayname" "days" "greatest" "hex" "initcap" | 1371 | "substr" "substring" "chr" "dayname" "days" "greatest" "hex" "initcap" |
| 1241 | "instr" "least" "multime" "replace" "width" | 1372 | "instr" "least" "multime" "replace" "width" |
| 1373 | ))) | ||
| 1242 | 1374 | ||
| 1243 | ) t) "\\b")))) | 1375 | `((,linter-keywords . font-lock-keyword-face) |
| 1244 | (append sql-mode-ansi-font-lock-keywords | 1376 | (,linter-reserved . font-lock-keyword-face) |
| 1245 | (list (cons linter-keywords 'font-lock-keywords-face) | 1377 | (,linter-functions . font-lock-builtin-face) |
| 1246 | (cons linter-reserved-words 'font-lock-keyword-face) | 1378 | (,linter-types . font-lock-type-face))) |
| 1247 | ;; XEmacs doesn't have font-lock-builtin-face | ||
| 1248 | (if (string-match "XEmacs\\|Lucid" emacs-version) | ||
| 1249 | (cons linter-builtin-functions 'font-lock-preprocessor-face) | ||
| 1250 | ;; GNU Emacs 19 doesn't have it either | ||
| 1251 | (if (string-match "GNU Emacs 19" emacs-version) | ||
| 1252 | (cons linter-builtin-functions 'font-lock-keywords-face) | ||
| 1253 | ;; Emacs | ||
| 1254 | (cons linter-builtin-functions 'font-lock-builtin-face))) | ||
| 1255 | (cons linter-types 'font-lock-type-face)))) | ||
| 1256 | 1379 | ||
| 1257 | "Linter SQL keywords used by font-lock. | 1380 | "Linter SQL keywords used by font-lock. |
| 1258 | 1381 | ||
| @@ -1261,21 +1384,18 @@ regular expressions are created during compilation by calling the | |||
| 1261 | function `regexp-opt'.") | 1384 | function `regexp-opt'.") |
| 1262 | 1385 | ||
| 1263 | (defvar sql-mode-ms-font-lock-keywords | 1386 | (defvar sql-mode-ms-font-lock-keywords |
| 1264 | (let ((ms-reserved-words (eval-when-compile | 1387 | (let ((ms-reserved (sql-keywords-re |
| 1265 | (concat "\\b" | ||
| 1266 | (regexp-opt '( | ||
| 1267 | |||
| 1268 | "absolute" "add" "all" "alter" "and" "any" "as" "asc" "authorization" | 1388 | "absolute" "add" "all" "alter" "and" "any" "as" "asc" "authorization" |
| 1269 | "avg" "backup" "begin" "between" "break" "browse" "bulk" "by" | 1389 | "avg" "backup" "begin" "between" "break" "browse" "bulk" "by" |
| 1270 | "cascade" "case" "check" "checkpoint" "close" "clustered" "coalesce" | 1390 | "cascade" "case" "check" "checkpoint" "close" "clustered" "coalesce" |
| 1271 | "column" "commit" "committed" "compute" "confirm" "constraint" | 1391 | "column" "commit" "committed" "compute" "confirm" "constraint" |
| 1272 | "contains" "containstable" "continue" "controlrow" "convert" "count" | 1392 | "contains" "containstable" "continue" "controlrow" "convert" "count" |
| 1273 | "create" "cross" "current" "current_date" "current_time" | 1393 | "create" "cross" "current" "current_date" "current_time" |
| 1274 | "current_timestamp" "current_user" "database" "deallocate" | 1394 | "current_timestamp" "current_user" "database" "deallocate" "declare" |
| 1275 | "declare" "default" "delete" "deny" "desc" "disk" "distinct" | 1395 | "default" "delete" "deny" "desc" "disk" "distinct" "distributed" |
| 1276 | "distributed" "double" "drop" "dummy" "dump" "else" "end" "errlvl" | 1396 | "double" "drop" "dummy" "dump" "else" "end" "errlvl" "errorexit" |
| 1277 | "errorexit" "escape" "except" "exec" "execute" "exists" "exit" "fetch" | 1397 | "escape" "except" "exec" "execute" "exists" "exit" "fetch" "file" |
| 1278 | "file" "fillfactor" "first" "floppy" "for" "foreign" "freetext" | 1398 | "fillfactor" "first" "floppy" "for" "foreign" "freetext" |
| 1279 | "freetexttable" "from" "full" "goto" "grant" "group" "having" | 1399 | "freetexttable" "from" "full" "goto" "grant" "group" "having" |
| 1280 | "holdlock" "identity" "identity_insert" "identitycol" "if" "in" | 1400 | "holdlock" "identity" "identity_insert" "identitycol" "if" "in" |
| 1281 | "index" "inner" "insert" "intersect" "into" "is" "isolation" "join" | 1401 | "index" "inner" "insert" "intersect" "into" "is" "isolation" "join" |
| @@ -1295,29 +1415,21 @@ function `regexp-opt'.") | |||
| 1295 | "textsize" "then" "to" "top" "tran" "transaction" "trigger" "truncate" | 1415 | "textsize" "then" "to" "top" "tran" "transaction" "trigger" "truncate" |
| 1296 | "tsequal" "uncommitted" "union" "unique" "update" "updatetext" | 1416 | "tsequal" "uncommitted" "union" "unique" "update" "updatetext" |
| 1297 | "updlock" "use" "user" "values" "view" "waitfor" "when" "where" | 1417 | "updlock" "use" "user" "values" "view" "waitfor" "when" "where" |
| 1298 | "while" "with" "work" "writetext" | 1418 | "while" "with" "work" "writetext" "collate" "function" "openxml" |
| 1299 | "collate" "function" "openxml" "returns" | 1419 | "returns" |
| 1300 | 1420 | )) | |
| 1301 | ) t) "\\b"))) | ||
| 1302 | (ms-types (eval-when-compile | ||
| 1303 | (concat "\\b" | ||
| 1304 | (regexp-opt '( | ||
| 1305 | 1421 | ||
| 1422 | (ms-types (sql-keywords-re | ||
| 1306 | "binary" "bit" "char" "character" "cursor" "datetime" "dec" "decimal" | 1423 | "binary" "bit" "char" "character" "cursor" "datetime" "dec" "decimal" |
| 1307 | "double" "float" "image" "int" "integer" "money" "national" "nchar" | 1424 | "double" "float" "image" "int" "integer" "money" "national" "nchar" |
| 1308 | "ntext" "numeric" "numeric" "nvarchar" "precision" "real" | 1425 | "ntext" "numeric" "numeric" "nvarchar" "precision" "real" |
| 1309 | "smalldatetime" "smallint" "smallmoney" "text" "timestamp" "tinyint" | 1426 | "smalldatetime" "smallint" "smallmoney" "text" "timestamp" "tinyint" |
| 1310 | "uniqueidentifier" "varbinary" "varchar" "varying" | 1427 | "uniqueidentifier" "varbinary" "varchar" "varying" |
| 1311 | 1428 | )) | |
| 1312 | ) t) "\\b"))) | ||
| 1313 | 1429 | ||
| 1314 | (ms-vars "\\b@[a-zA-Z0-9_]*\\b") | 1430 | (ms-vars "\\b@[a-zA-Z0-9_]*\\b") |
| 1315 | 1431 | ||
| 1316 | (ms-builtin-functions (eval-when-compile | 1432 | (ms-functions (sql-keywords-re |
| 1317 | (concat "\\b" | ||
| 1318 | (regexp-opt '( | ||
| 1319 | ;; Misc MS builtin functions | ||
| 1320 | |||
| 1321 | "@@connections" "@@cpu_busy" "@@cursor_rows" "@@datefirst" "@@dbts" | 1433 | "@@connections" "@@cpu_busy" "@@cursor_rows" "@@datefirst" "@@dbts" |
| 1322 | "@@error" "@@fetch_status" "@@identity" "@@idle" "@@io_busy" | 1434 | "@@error" "@@fetch_status" "@@identity" "@@idle" "@@io_busy" |
| 1323 | "@@langid" "@@language" "@@lock_timeout" "@@max_connections" | 1435 | "@@langid" "@@language" "@@lock_timeout" "@@max_connections" |
| @@ -1346,14 +1458,12 @@ function `regexp-opt'.") | |||
| 1346 | "suser_id" "suser_name" "suser_sid" "suser_sname" "system_user" "tan" | 1458 | "suser_id" "suser_name" "suser_sid" "suser_sname" "system_user" "tan" |
| 1347 | "textptr" "textvalid" "typeproperty" "unicode" "upper" "user" | 1459 | "textptr" "textvalid" "typeproperty" "unicode" "upper" "user" |
| 1348 | "user_id" "user_name" "var" "varp" "year" | 1460 | "user_id" "user_name" "var" "varp" "year" |
| 1461 | )) | ||
| 1349 | 1462 | ||
| 1350 | ) t) "\\b"))) | 1463 | (ms-commands |
| 1351 | |||
| 1352 | (ms-config-commands | ||
| 1353 | (eval-when-compile | 1464 | (eval-when-compile |
| 1354 | (concat "^\\(\\(set\\s-+\\(" | 1465 | (concat "^\\(\\(set\\s-+\\(" |
| 1355 | (regexp-opt '( | 1466 | (regexp-opt '( |
| 1356 | |||
| 1357 | "datefirst" "dateformat" "deadlock_priority" "lock_timeout" | 1467 | "datefirst" "dateformat" "deadlock_priority" "lock_timeout" |
| 1358 | "concat_null_yields_null" "cursor_close_on_commit" | 1468 | "concat_null_yields_null" "cursor_close_on_commit" |
| 1359 | "disable_def_cnst_chk" "fips_flagger" "identity_insert" "language" | 1469 | "disable_def_cnst_chk" "fips_flagger" "identity_insert" "language" |
| @@ -1364,19 +1474,14 @@ function `regexp-opt'.") | |||
| 1364 | "ansi_warnings" "forceplan" "showplan_all" "showplan_text" | 1474 | "ansi_warnings" "forceplan" "showplan_all" "showplan_text" |
| 1365 | "statistics" "implicit_transactions" "remote_proc_transactions" | 1475 | "statistics" "implicit_transactions" "remote_proc_transactions" |
| 1366 | "transaction" "xact_abort" | 1476 | "transaction" "xact_abort" |
| 1367 | |||
| 1368 | ) t) | 1477 | ) t) |
| 1369 | "\\)\\)\\|go\\s-*\\|use\\s-+\\|setuser\\s-+\\|dbcc\\s-+\\).*$")))) | 1478 | "\\)\\)\\|go\\s-*\\|use\\s-+\\|setuser\\s-+\\|dbcc\\s-+\\).*$")))) |
| 1370 | 1479 | ||
| 1371 | (list (cons ms-config-commands 'font-lock-doc-face) | 1480 | `((,ms-commands . font-lock-doc-face) |
| 1372 | (cons ms-reserved-words 'font-lock-keyword-face) | 1481 | (,ms-reserved . font-lock-keyword-face) |
| 1373 | ;; XEmacs doesn't have 'font-lock-builtin-face | 1482 | (,ms-functions . font-lock-builtin-face) |
| 1374 | (if (string-match "XEmacs\\|Lucid" emacs-version) | 1483 | (,ms-vars . font-lock-variable-name-face) |
| 1375 | (cons ms-builtin-functions 'font-lock-preprocessor-face) | 1484 | (,ms-types . font-lock-type-face))) |
| 1376 | ;; Emacs | ||
| 1377 | (cons ms-builtin-functions 'font-lock-builtin-face)) | ||
| 1378 | (cons ms-vars 'font-lock-variable-name-face) | ||
| 1379 | (cons ms-types 'font-lock-type-face))) | ||
| 1380 | 1485 | ||
| 1381 | "Microsoft SQLServer SQL keywords used by font-lock. | 1486 | "Microsoft SQLServer SQL keywords used by font-lock. |
| 1382 | 1487 | ||
| @@ -1385,7 +1490,7 @@ regular expressions are created during compilation by calling the | |||
| 1385 | function `regexp-opt'. Therefore, take a look at the source before | 1490 | function `regexp-opt'. Therefore, take a look at the source before |
| 1386 | you define your own sql-mode-ms-font-lock-keywords.") | 1491 | you define your own sql-mode-ms-font-lock-keywords.") |
| 1387 | 1492 | ||
| 1388 | (defvar sql-mode-sybase-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1493 | (defvar sql-mode-sybase-font-lock-keywords nil |
| 1389 | "Sybase SQL keywords used by font-lock. | 1494 | "Sybase SQL keywords used by font-lock. |
| 1390 | 1495 | ||
| 1391 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1496 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1393,7 +1498,7 @@ regular expressions are created during compilation by calling the | |||
| 1393 | function `regexp-opt'. Therefore, take a look at the source before | 1498 | function `regexp-opt'. Therefore, take a look at the source before |
| 1394 | you define your own sql-mode-sybase-font-lock-keywords.") | 1499 | you define your own sql-mode-sybase-font-lock-keywords.") |
| 1395 | 1500 | ||
| 1396 | (defvar sql-mode-informix-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1501 | (defvar sql-mode-informix-font-lock-keywords nil |
| 1397 | "Informix SQL keywords used by font-lock. | 1502 | "Informix SQL keywords used by font-lock. |
| 1398 | 1503 | ||
| 1399 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1504 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1401,7 +1506,7 @@ regular expressions are created during compilation by calling the | |||
| 1401 | function `regexp-opt'. Therefore, take a look at the source before | 1506 | function `regexp-opt'. Therefore, take a look at the source before |
| 1402 | you define your own sql-mode-informix-font-lock-keywords.") | 1507 | you define your own sql-mode-informix-font-lock-keywords.") |
| 1403 | 1508 | ||
| 1404 | (defvar sql-mode-interbase-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1509 | (defvar sql-mode-interbase-font-lock-keywords nil |
| 1405 | "Interbase SQL keywords used by font-lock. | 1510 | "Interbase SQL keywords used by font-lock. |
| 1406 | 1511 | ||
| 1407 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1512 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1409,7 +1514,7 @@ regular expressions are created during compilation by calling the | |||
| 1409 | function `regexp-opt'. Therefore, take a look at the source before | 1514 | function `regexp-opt'. Therefore, take a look at the source before |
| 1410 | you define your own sql-mode-interbase-font-lock-keywords.") | 1515 | you define your own sql-mode-interbase-font-lock-keywords.") |
| 1411 | 1516 | ||
| 1412 | (defvar sql-mode-ingres-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1517 | (defvar sql-mode-ingres-font-lock-keywords nil |
| 1413 | "Ingres SQL keywords used by font-lock. | 1518 | "Ingres SQL keywords used by font-lock. |
| 1414 | 1519 | ||
| 1415 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1520 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1417,7 +1522,7 @@ regular expressions are created during compilation by calling the | |||
| 1417 | function `regexp-opt'. Therefore, take a look at the source before | 1522 | function `regexp-opt'. Therefore, take a look at the source before |
| 1418 | you define your own sql-mode-interbase-font-lock-keywords.") | 1523 | you define your own sql-mode-interbase-font-lock-keywords.") |
| 1419 | 1524 | ||
| 1420 | (defvar sql-mode-solid-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1525 | (defvar sql-mode-solid-font-lock-keywords nil |
| 1421 | "Solid SQL keywords used by font-lock. | 1526 | "Solid SQL keywords used by font-lock. |
| 1422 | 1527 | ||
| 1423 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1528 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1425,7 +1530,76 @@ regular expressions are created during compilation by calling the | |||
| 1425 | function `regexp-opt'. Therefore, take a look at the source before | 1530 | function `regexp-opt'. Therefore, take a look at the source before |
| 1426 | you define your own sql-mode-solid-font-lock-keywords.") | 1531 | you define your own sql-mode-solid-font-lock-keywords.") |
| 1427 | 1532 | ||
| 1428 | (defvar sql-mode-mysql-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1533 | (defvar sql-mode-mysql-font-lock-keywords |
| 1534 | (let ((mysql-funcs (sql-keywords-re | ||
| 1535 | "ascii" "avg" "bdmpolyfromtext" "bdmpolyfromwkb" "bdpolyfromtext" | ||
| 1536 | "bdpolyfromwkb" "benchmark" "bin" "bit_and" "bit_length" "bit_or" | ||
| 1537 | "bit_xor" "both" "cast" "char_length" "character_length" "coalesce" | ||
| 1538 | "concat" "concat_ws" "connection_id" "conv" "convert" "count" | ||
| 1539 | "curdate" "current_date" "current_time" "current_timestamp" "curtime" | ||
| 1540 | "elt" "encrypt" "export_set" "field" "find_in_set" "found_rows" "from" | ||
| 1541 | "geomcollfromtext" "geomcollfromwkb" "geometrycollectionfromtext" | ||
| 1542 | "geometrycollectionfromwkb" "geometryfromtext" "geometryfromwkb" | ||
| 1543 | "geomfromtext" "geomfromwkb" "get_lock" "group_concat" "hex" "ifnull" | ||
| 1544 | "instr" "interval" "isnull" "last_insert_id" "lcase" "leading" | ||
| 1545 | "length" "linefromtext" "linefromwkb" "linestringfromtext" | ||
| 1546 | "linestringfromwkb" "load_file" "locate" "lower" "lpad" "ltrim" | ||
| 1547 | "make_set" "master_pos_wait" "max" "mid" "min" "mlinefromtext" | ||
| 1548 | "mlinefromwkb" "mpointfromtext" "mpointfromwkb" "mpolyfromtext" | ||
| 1549 | "mpolyfromwkb" "multilinestringfromtext" "multilinestringfromwkb" | ||
| 1550 | "multipointfromtext" "multipointfromwkb" "multipolygonfromtext" | ||
| 1551 | "multipolygonfromwkb" "now" "nullif" "oct" "octet_length" "ord" | ||
| 1552 | "pointfromtext" "pointfromwkb" "polyfromtext" "polyfromwkb" | ||
| 1553 | "polygonfromtext" "polygonfromwkb" "position" "quote" "rand" | ||
| 1554 | "release_lock" "repeat" "replace" "reverse" "rpad" "rtrim" "soundex" | ||
| 1555 | "space" "std" "stddev" "substring" "substring_index" "sum" "sysdate" | ||
| 1556 | "trailing" "trim" "ucase" "unix_timestamp" "upper" "user" "variance" | ||
| 1557 | )) | ||
| 1558 | |||
| 1559 | (mysql-keywords (sql-keywords-re | ||
| 1560 | "action" "add" "after" "against" "all" "alter" "and" "as" "asc" | ||
| 1561 | "auto_increment" "avg_row_length" "bdb" "between" "by" "cascade" | ||
| 1562 | "case" "change" "character" "check" "checksum" "close" "collate" | ||
| 1563 | "collation" "column" "columns" "comment" "committed" "concurrent" | ||
| 1564 | "constraint" "create" "cross" "data" "database" "default" | ||
| 1565 | "delay_key_write" "delayed" "delete" "desc" "directory" "disable" | ||
| 1566 | "distinct" "distinctrow" "do" "drop" "dumpfile" "duplicate" "else" | ||
| 1567 | "enable" "enclosed" "end" "escaped" "exists" "fields" "first" "for" | ||
| 1568 | "force" "foreign" "from" "full" "fulltext" "global" "group" "handler" | ||
| 1569 | "having" "heap" "high_priority" "if" "ignore" "in" "index" "infile" | ||
| 1570 | "inner" "insert" "insert_method" "into" "is" "isam" "isolation" "join" | ||
| 1571 | "key" "keys" "last" "left" "level" "like" "limit" "lines" "load" | ||
| 1572 | "local" "lock" "low_priority" "match" "max_rows" "merge" "min_rows" | ||
| 1573 | "mode" "modify" "mrg_myisam" "myisam" "natural" "next" "no" "not" | ||
| 1574 | "null" "offset" "oj" "on" "open" "optionally" "or" "order" "outer" | ||
| 1575 | "outfile" "pack_keys" "partial" "password" "prev" "primary" | ||
| 1576 | "procedure" "quick" "raid0" "raid_type" "read" "references" "rename" | ||
| 1577 | "repeatable" "restrict" "right" "rollback" "rollup" "row_format" | ||
| 1578 | "savepoint" "select" "separator" "serializable" "session" "set" | ||
| 1579 | "share" "show" "sql_big_result" "sql_buffer_result" "sql_cache" | ||
| 1580 | "sql_calc_found_rows" "sql_no_cache" "sql_small_result" "starting" | ||
| 1581 | "straight_join" "striped" "table" "tables" "temporary" "terminated" | ||
| 1582 | "then" "to" "transaction" "truncate" "type" "uncommitted" "union" | ||
| 1583 | "unique" "unlock" "update" "use" "using" "values" "when" "where" | ||
| 1584 | "with" "write" "xor" | ||
| 1585 | )) | ||
| 1586 | |||
| 1587 | (mysql-types (sql-keywords-re | ||
| 1588 | "bigint" "binary" "bit" "blob" "bool" "boolean" "char" "curve" "date" | ||
| 1589 | "datetime" "dec" "decimal" "double" "enum" "fixed" "float" "geometry" | ||
| 1590 | "geometrycollection" "int" "integer" "line" "linearring" "linestring" | ||
| 1591 | "longblob" "longtext" "mediumblob" "mediumint" "mediumtext" | ||
| 1592 | "multicurve" "multilinestring" "multipoint" "multipolygon" | ||
| 1593 | "multisurface" "national" "numeric" "point" "polygon" "precision" | ||
| 1594 | "real" "smallint" "surface" "text" "time" "timestamp" "tinyblob" | ||
| 1595 | "tinyint" "tinytext" "unsigned" "varchar" "year" "year2" "year4" | ||
| 1596 | "zerofill" | ||
| 1597 | ))) | ||
| 1598 | |||
| 1599 | `((,mysql-funcs . font-lock-builtin-face) | ||
| 1600 | (,mysql-keywords . font-lock-keyword-face) | ||
| 1601 | (,mysql-types . font-lock-type-face))) | ||
| 1602 | |||
| 1429 | "MySQL SQL keywords used by font-lock. | 1603 | "MySQL SQL keywords used by font-lock. |
| 1430 | 1604 | ||
| 1431 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1605 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1433,7 +1607,7 @@ regular expressions are created during compilation by calling the | |||
| 1433 | function `regexp-opt'. Therefore, take a look at the source before | 1607 | function `regexp-opt'. Therefore, take a look at the source before |
| 1434 | you define your own sql-mode-mysql-font-lock-keywords.") | 1608 | you define your own sql-mode-mysql-font-lock-keywords.") |
| 1435 | 1609 | ||
| 1436 | (defvar sql-mode-sqlite-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1610 | (defvar sql-mode-sqlite-font-lock-keywords nil |
| 1437 | "SQLite SQL keywords used by font-lock. | 1611 | "SQLite SQL keywords used by font-lock. |
| 1438 | 1612 | ||
| 1439 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1613 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1441,7 +1615,7 @@ regular expressions are created during compilation by calling the | |||
| 1441 | function `regexp-opt'. Therefore, take a look at the source before | 1615 | function `regexp-opt'. Therefore, take a look at the source before |
| 1442 | you define your own sql-mode-sqlite-font-lock-keywords.") | 1616 | you define your own sql-mode-sqlite-font-lock-keywords.") |
| 1443 | 1617 | ||
| 1444 | (defvar sql-mode-db2-font-lock-keywords sql-mode-ansi-font-lock-keywords | 1618 | (defvar sql-mode-db2-font-lock-keywords nil |
| 1445 | "DB2 SQL keywords used by font-lock. | 1619 | "DB2 SQL keywords used by font-lock. |
| 1446 | 1620 | ||
| 1447 | This variable is used by `sql-mode' and `sql-interactive-mode'. The | 1621 | This variable is used by `sql-mode' and `sql-interactive-mode'. The |
| @@ -1463,16 +1637,16 @@ highlighting rules in sql-mode.") | |||
| 1463 | (defun sql-product-feature (feature &optional product) | 1637 | (defun sql-product-feature (feature &optional product) |
| 1464 | "Lookup `feature' needed to support the current SQL product. | 1638 | "Lookup `feature' needed to support the current SQL product. |
| 1465 | 1639 | ||
| 1466 | See \[sql-product-support] for a list of products and supported features." | 1640 | See \[sql-product-alist] for a list of products and supported features." |
| 1467 | (cadr | 1641 | (plist-get |
| 1468 | (memq feature | 1642 | (cdr (assoc (or product sql-product) |
| 1469 | (assoc (or product sql-product) | 1643 | sql-product-alist)) |
| 1470 | sql-product-support)))) | 1644 | feature)) |
| 1471 | 1645 | ||
| 1472 | (defun sql-product-font-lock (keywords-only imenu) | 1646 | (defun sql-product-font-lock (keywords-only imenu) |
| 1473 | "Sets `font-lock-defaults' and `font-lock-keywords' based on | 1647 | "Sets `font-lock-defaults' and `font-lock-keywords' based on |
| 1474 | the product-specific keywords and syntax-alists defined in | 1648 | the product-specific keywords and syntax-alists defined in |
| 1475 | `sql-product-support'." | 1649 | `sql-product-alist'." |
| 1476 | (let | 1650 | (let |
| 1477 | ;; Get the product-specific syntax-alist. | 1651 | ;; Get the product-specific syntax-alist. |
| 1478 | ((syntax-alist | 1652 | ((syntax-alist |
| @@ -1483,27 +1657,69 @@ the product-specific keywords and syntax-alists defined in | |||
| 1483 | ;; Get the product-specific keywords. | 1657 | ;; Get the product-specific keywords. |
| 1484 | (setq sql-mode-font-lock-keywords | 1658 | (setq sql-mode-font-lock-keywords |
| 1485 | (append | 1659 | (append |
| 1486 | (eval (sql-product-feature :font-lock)) | 1660 | (unless (eq sql-product 'ansi) |
| 1661 | (eval (sql-product-feature :font-lock))) | ||
| 1662 | ;; Always highlight ANSI keywords | ||
| 1663 | (eval (sql-product-feature :font-lock 'ansi)) | ||
| 1664 | ;; Fontify object names in CREATE, DROP and ALTER DDL | ||
| 1665 | ;; statements | ||
| 1487 | (list sql-mode-font-lock-object-name))) | 1666 | (list sql-mode-font-lock-object-name))) |
| 1488 | 1667 | ||
| 1489 | ;; Setup font-lock. (What is the minimum we should have to do | 1668 | ;; Setup font-lock. Force re-parsing of `font-lock-defaults'. |
| 1490 | ;; here?) | 1669 | (set (make-local-variable 'font-lock-set-defaults) nil) |
| 1491 | (setq font-lock-set-defaults nil | 1670 | (setq font-lock-defaults (list 'sql-mode-font-lock-keywords |
| 1492 | font-lock-keywords sql-mode-font-lock-keywords | ||
| 1493 | font-lock-defaults (list 'sql-mode-font-lock-keywords | ||
| 1494 | keywords-only t syntax-alist)) | 1671 | keywords-only t syntax-alist)) |
| 1495 | 1672 | ||
| 1673 | ;; Force font lock to reinitialize if it is already on | ||
| 1674 | ;; Otherwise, we can wait until it can be started. | ||
| 1675 | (when (and (fboundp 'font-lock-mode) | ||
| 1676 | font-lock-mode) | ||
| 1677 | (font-lock-mode-internal nil) | ||
| 1678 | (font-lock-mode-internal t)) | ||
| 1679 | |||
| 1680 | (add-hook 'font-lock-mode-hook | ||
| 1681 | (lambda () | ||
| 1682 | ;; Provide defaults for new font-lock faces. | ||
| 1683 | (defvar font-lock-builtin-face | ||
| 1684 | (if (boundp 'font-lock-preprocessor-face) | ||
| 1685 | font-lock-preprocessor-face | ||
| 1686 | font-lock-keyword-face)) | ||
| 1687 | (defvar font-lock-doc-face font-lock-string-face)) | ||
| 1688 | nil t) | ||
| 1689 | |||
| 1496 | ;; Setup imenu; it needs the same syntax-alist. | 1690 | ;; Setup imenu; it needs the same syntax-alist. |
| 1497 | (when imenu | 1691 | (when imenu |
| 1498 | (setq imenu-syntax-alist syntax-alist)))) | 1692 | (setq imenu-syntax-alist syntax-alist)))) |
| 1499 | 1693 | ||
| 1500 | ;;;###autoload | 1694 | ;;;###autoload |
| 1501 | (defun sql-add-product-keywords (product keywords) | 1695 | (defun sql-add-product-keywords (product keywords &optional append) |
| 1502 | "Append a `font-lock-keywords' entry to the existing entries defined | 1696 | "Add highlighting KEYWORDS for SQL PRODUCT. |
| 1503 | for the specified `product'." | 1697 | |
| 1504 | 1698 | PRODUCT should be a symbol, the name of a sql product, such as | |
| 1505 | (let ((font-lock (sql-product-feature :font-lock product))) | 1699 | `oracle'. KEYWORDS should be a list; see the variable |
| 1506 | (set font-lock (append (eval font-lock) (list keywords))))) | 1700 | `font-lock-keywords'. By default they are added at the beginning |
| 1701 | of the current highlighting list. If optional argument APPEND is | ||
| 1702 | `set', they are used to replace the current highlighting list. | ||
| 1703 | If APPEND is any other non-nil value, they are added at the end | ||
| 1704 | of the current highlighting list. | ||
| 1705 | |||
| 1706 | For example: | ||
| 1707 | |||
| 1708 | (sql-add-product-keywords 'ms | ||
| 1709 | '((\"\\\\b\\\\w+_t\\\\b\" . font-lock-type-face))) | ||
| 1710 | |||
| 1711 | adds a fontification pattern to fontify identifiers ending in | ||
| 1712 | `_t' as data types." | ||
| 1713 | |||
| 1714 | (let ((font-lock (sql-product-feature :font-lock product)) | ||
| 1715 | old) | ||
| 1716 | (setq old (eval font-lock)) | ||
| 1717 | (set font-lock | ||
| 1718 | (if (eq append 'set) | ||
| 1719 | keywords | ||
| 1720 | (if append | ||
| 1721 | (append old keywords) | ||
| 1722 | (append keywords old)))))) | ||
| 1507 | 1723 | ||
| 1508 | 1724 | ||
| 1509 | 1725 | ||
| @@ -1517,10 +1733,6 @@ selected." | |||
| 1517 | ;; Setup font-lock | 1733 | ;; Setup font-lock |
| 1518 | (sql-product-font-lock nil t) | 1734 | (sql-product-font-lock nil t) |
| 1519 | 1735 | ||
| 1520 | ;; Force fontification, if its enabled. | ||
| 1521 | (if font-lock-mode | ||
| 1522 | (font-lock-fontify-buffer)) | ||
| 1523 | |||
| 1524 | ;; Set the mode name to include the product. | 1736 | ;; Set the mode name to include the product. |
| 1525 | (setq mode-name (concat "SQL[" (prin1-to-string sql-product) "]")))) | 1737 | (setq mode-name (concat "SQL[" (prin1-to-string sql-product) "]")))) |
| 1526 | 1738 | ||
| @@ -1528,7 +1740,7 @@ selected." | |||
| 1528 | "Set `sql-product' to product and enable appropriate | 1740 | "Set `sql-product' to product and enable appropriate |
| 1529 | highlighting." | 1741 | highlighting." |
| 1530 | (interactive "SEnter SQL product: ") | 1742 | (interactive "SEnter SQL product: ") |
| 1531 | (when (not (assoc product sql-product-support)) | 1743 | (when (not (assoc product sql-product-alist)) |
| 1532 | (error "SQL product %s is not supported; treated as ANSI" product) | 1744 | (error "SQL product %s is not supported; treated as ANSI" product) |
| 1533 | (setq product 'ansi)) | 1745 | (setq product 'ansi)) |
| 1534 | 1746 | ||
| @@ -1952,6 +2164,19 @@ Every newline in STRING will be preceded with a space and a backslash." | |||
| 1952 | (interactive) | 2164 | (interactive) |
| 1953 | (sql-send-region (point-min) (point-max))) | 2165 | (sql-send-region (point-min) (point-max))) |
| 1954 | 2166 | ||
| 2167 | (defun sql-send-string (str) | ||
| 2168 | "Send a string to the SQL process." | ||
| 2169 | (interactive "sSQL Text: ") | ||
| 2170 | (if (buffer-live-p sql-buffer) | ||
| 2171 | (save-excursion | ||
| 2172 | (comint-send-string sql-buffer str) | ||
| 2173 | (comint-send-string sql-buffer "\n") | ||
| 2174 | (message "Sent string to buffer %s." (buffer-name sql-buffer)) | ||
| 2175 | (if sql-pop-to-buffer-after-send-region | ||
| 2176 | (pop-to-buffer sql-buffer) | ||
| 2177 | (display-buffer sql-buffer))) | ||
| 2178 | (message "No SQL process started."))) | ||
| 2179 | |||
| 1955 | (defun sql-toggle-pop-to-buffer-after-send-region (&optional value) | 2180 | (defun sql-toggle-pop-to-buffer-after-send-region (&optional value) |
| 1956 | "Toggle `sql-pop-to-buffer-after-send-region'. | 2181 | "Toggle `sql-pop-to-buffer-after-send-region'. |
| 1957 | 2182 | ||
| @@ -2611,6 +2836,8 @@ parameters and command options." | |||
| 2611 | (setq params (append params (list sql-database)))) | 2836 | (setq params (append params (list sql-database)))) |
| 2612 | (if (not (string= "" sql-server)) | 2837 | (if (not (string= "" sql-server)) |
| 2613 | (setq params (append (list "-h" sql-server) params))) | 2838 | (setq params (append (list "-h" sql-server) params))) |
| 2839 | (if (not (string= "" sql-user)) | ||
| 2840 | (setq params (append (list "-U" sql-user) params))) | ||
| 2614 | (set-buffer (apply 'make-comint "SQL" sql-postgres-program | 2841 | (set-buffer (apply 'make-comint "SQL" sql-postgres-program |
| 2615 | nil params)))) | 2842 | nil params)))) |
| 2616 | 2843 | ||