aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Mauger2010-09-13 16:05:23 -0400
committerMichael Mauger2010-09-13 16:05:23 -0400
commita386ac70117a661ee2159e87499fa003b67d18ea (patch)
treee350e718739e1f669a7ef5e0befcc132086a6586
parent74f891be2a66d735558e52101358ecd117e682b1 (diff)
downloademacs-a386ac70117a661ee2159e87499fa003b67d18ea.tar.gz
emacs-a386ac70117a661ee2159e87499fa003b67d18ea.zip
SQL Mode 2.7: Code cleanup and primatives for SQL redirection
* progmodes/sql.el: Version 2.7. (sql-buffer-live-p): Improve detection. (sql-find-sqli-buffer, sql-set-sqli-buffer-generally) (sql-set-sqli-buffer): Use it. (sql-product-interactive): Run `sql-set-sqli-hook'. (sql-rename-buffer): Code cleanup. (sql-redirect, sql-redirect-value): New functions. More to come.
-rw-r--r--lisp/ChangeLog10
-rw-r--r--lisp/progmodes/sql.el192
2 files changed, 151 insertions, 51 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 0d7e47e9ca0..31de63c630e 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,13 @@
12010-09-13 Michael R. Mauger <mmaug@yahoo.com>
2
3 * progmodes/sql.el: Version 2.7.
4 (sql-buffer-live-p): Improve detection.
5 (sql-find-sqli-buffer, sql-set-sqli-buffer-generally)
6 (sql-set-sqli-buffer): Use it.
7 (sql-product-interactive): Run `sql-set-sqli-hook'.
8 (sql-rename-buffer): Code cleanup.
9 (sql-redirect, sql-redirect-value): New functions. More to come.
10
12010-09-13 Juanma Barranquero <lekktu@gmail.com> 112010-09-13 Juanma Barranquero <lekktu@gmail.com>
2 12
3 Port tramp-related Makefile changes of 2010-09-08T14:42:54Z!michael.albinus@gmx.de, 2010-09-13T15:17:01Z!michael.albinus@gmx.de to Windows. 13 Port tramp-related Makefile changes of 2010-09-08T14:42:54Z!michael.albinus@gmx.de, 2010-09-13T15:17:01Z!michael.albinus@gmx.de to Windows.
diff --git a/lisp/progmodes/sql.el b/lisp/progmodes/sql.el
index a80a555c13f..e9860c5fa71 100644
--- a/lisp/progmodes/sql.el
+++ b/lisp/progmodes/sql.el
@@ -5,7 +5,7 @@
5 5
6;; Author: Alex Schroeder <alex@gnu.org> 6;; Author: Alex Schroeder <alex@gnu.org>
7;; Maintainer: Michael Mauger <mmaug@yahoo.com> 7;; Maintainer: Michael Mauger <mmaug@yahoo.com>
8;; Version: 2.6 8;; Version: 2.7
9;; Keywords: comm languages processes 9;; Keywords: comm languages processes
10;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el 10;; URL: http://savannah.gnu.org/cgi-bin/viewcvs/emacs/emacs/lisp/progmodes/sql.el
11;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode 11;; URL: http://www.emacswiki.org/cgi-bin/wiki.pl?SqlMode
@@ -1052,11 +1052,24 @@ You can change `sql-prompt-length' on `sql-interactive-mode-hook'.")
1052 1052
1053Used by `sql-rename-buffer'.") 1053Used by `sql-rename-buffer'.")
1054 1054
1055(defun sql-buffer-live-p (buffer) 1055(defun sql-buffer-live-p (buffer &optional product)
1056 "Returns non-nil if the process associated with buffer is live." 1056 "Returns non-nil if the process associated with buffer is live.
1057 (and buffer 1057
1058 (buffer-live-p (get-buffer buffer)) 1058BUFFER can be a buffer object or a buffer name. The buffer must
1059 (get-buffer-process buffer))) 1059be a live buffer, have an running process attached to it, be in
1060`sql-interactive-mode', and, if PRODUCT is specified, it's
1061`sql-product' must match."
1062
1063 (when buffer
1064 (setq buffer (get-buffer buffer))
1065 (and buffer
1066 (buffer-live-p buffer)
1067 (get-buffer-process buffer)
1068 (comint-check-proc buffer)
1069 (with-current-buffer buffer
1070 (and (derived-mode-p 'sql-product-interactive)
1071 (or (not product)
1072 (eq product sql-product)))))))
1060 1073
1061;; Keymap for sql-interactive-mode. 1074;; Keymap for sql-interactive-mode.
1062 1075
@@ -2577,23 +2590,22 @@ function like this: (sql-get-login 'user 'password 'database)."
2577 "Returns the name of the current default SQLi buffer or nil. 2590 "Returns the name of the current default SQLi buffer or nil.
2578In order to qualify, the SQLi buffer must be alive, be in 2591In order to qualify, the SQLi buffer must be alive, be in
2579`sql-interactive-mode' and have a process." 2592`sql-interactive-mode' and have a process."
2580 (let ((default-buffer (default-value 'sql-buffer)) 2593 (let ((buf sql-buffer)
2581 (current-product sql-product)) 2594 (prod sql-product))
2582 (if (sql-buffer-live-p default-buffer) 2595 (or
2583 default-buffer 2596 ;; Current sql-buffer, if there is one.
2584 (save-current-buffer 2597 (and (sql-buffer-live-p buf prod)
2585 (let ((buflist (buffer-list)) 2598 buf)
2586 (found)) 2599 ;; Global sql-buffer
2587 (while (not (or (null buflist) 2600 (and (setq buf (default-value 'sql-buffer))
2588 found)) 2601 (sql-buffer-live-p buf prod)
2589 (let ((candidate (car buflist))) 2602 buf)
2590 (set-buffer candidate) 2603 ;; Look thru each buffer
2591 (if (and (sql-buffer-live-p candidate) 2604 (car (apply 'append
2592 (derived-mode-p 'sql-interactive-mode) 2605 (mapcar (lambda (b)
2593 (eq sql-product current-product)) 2606 (and (sql-buffer-live-p b prod)
2594 (setq found (buffer-name candidate))) 2607 (list (buffer-name b))))
2595 (setq buflist (cdr buflist)))) 2608 (buffer-list)))))))
2596 found)))))
2597 2609
2598(defun sql-set-sqli-buffer-generally () 2610(defun sql-set-sqli-buffer-generally ()
2599 "Set SQLi buffer for all SQL buffers that have none. 2611 "Set SQLi buffer for all SQL buffers that have none.
@@ -2611,10 +2623,11 @@ using `sql-find-sqli-buffer'. If `sql-buffer' is set,
2611 (let ((candidate (car buflist))) 2623 (let ((candidate (car buflist)))
2612 (set-buffer candidate) 2624 (set-buffer candidate)
2613 (if (and (derived-mode-p 'sql-mode) 2625 (if (and (derived-mode-p 'sql-mode)
2614 (not (buffer-live-p sql-buffer))) 2626 (not (sql-buffer-live-p sql-buffer)))
2615 (progn 2627 (progn
2616 (setq sql-buffer default-buffer) 2628 (setq sql-buffer default-buffer)
2617 (run-hooks 'sql-set-sqli-hook)))) 2629 (when default-buffer
2630 (run-hooks 'sql-set-sqli-hook)))))
2618 (setq buflist (cdr buflist)))))) 2631 (setq buflist (cdr buflist))))))
2619 2632
2620(defun sql-set-sqli-buffer () 2633(defun sql-set-sqli-buffer ()
@@ -2632,19 +2645,13 @@ If you call it from anywhere else, it sets the global copy of
2632 (interactive) 2645 (interactive)
2633 (let ((default-buffer (sql-find-sqli-buffer))) 2646 (let ((default-buffer (sql-find-sqli-buffer)))
2634 (if (null default-buffer) 2647 (if (null default-buffer)
2635 (error "There is no suitable SQLi buffer")) 2648 (error "There is no suitable SQLi buffer")
2636 (let ((new-buffer 2649 (let ((new-buffer (read-buffer "New SQLi buffer: " default-buffer t)))
2637 (get-buffer 2650 (if (null (sql-buffer-live-p new-buffer))
2638 (read-buffer "New SQLi buffer: " default-buffer t)))) 2651 (error "Buffer %s is not a working SQLi buffer" new-buffer)
2639 (if (null (get-buffer-process new-buffer)) 2652 (when new-buffer
2640 (error "Buffer %s has no process" (buffer-name new-buffer))) 2653 (setq sql-buffer new-buffer)
2641 (if (null (with-current-buffer new-buffer 2654 (run-hooks 'sql-set-sqli-hook)))))))
2642 (derived-mode-p 'sql-interactive-mode)))
2643 (error "Buffer %s is no SQLi buffer" (buffer-name new-buffer)))
2644 (if new-buffer
2645 (progn
2646 (setq sql-buffer (buffer-name new-buffer))
2647 (run-hooks 'sql-set-sqli-hook))))))
2648 2655
2649(defun sql-show-sqli-buffer () 2656(defun sql-show-sqli-buffer ()
2650 "Show the name of current SQLi buffer. 2657 "Show the name of current SQLi buffer.
@@ -2742,13 +2749,13 @@ NEW-NAME is empty, then the buffer name will be \"*SQL*\"."
2742 (if (not (derived-mode-p 'sql-interactive-mode)) 2749 (if (not (derived-mode-p 'sql-interactive-mode))
2743 (message "Current buffer is not a SQL interactive buffer") 2750 (message "Current buffer is not a SQL interactive buffer")
2744 2751
2745 (cond 2752 (setq sql-alternate-buffer-name
2746 ((stringp new-name) 2753 (cond
2747 (setq sql-alternate-buffer-name new-name)) 2754 ((stringp new-name) new-name)
2748 ((listp new-name) 2755 ((consp new-name)
2749 (setq sql-alternate-buffer-name
2750 (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): " 2756 (read-string "Buffer name (\"*SQL: XXX*\"; enter `XXX'): "
2751 sql-alternate-buffer-name)))) 2757 sql-alternate-buffer-name))
2758 (t sql-alternate-buffer-name)))
2752 2759
2753 (rename-buffer (if (string= "" sql-alternate-buffer-name) 2760 (rename-buffer (if (string= "" sql-alternate-buffer-name)
2754 "*SQL*" 2761 "*SQL*"
@@ -2994,6 +3001,91 @@ If given the optional parameter VALUE, sets
2994 3001
2995 3002
2996 3003
3004;;; Redirect output functions
3005
3006(defun sql-redirect (command combuf &optional outbuf save-prior)
3007 "Execute the SQL command and send output to OUTBUF.
3008
3009COMBUF must be an active SQL interactive buffer. OUTBUF may be
3010an existing buffer, or the name of a non-existing buffer. If
3011omitted the output is sent to a temporary buffer which will be
3012killed after the command completes. COMMAND should be a string
3013of commands accepted by the SQLi program."
3014
3015 (with-current-buffer combuf
3016 (let ((buf (get-buffer-create (or outbuf " *SQL-Redirect*")))
3017 (proc (get-buffer-process (current-buffer)))
3018 (comint-prompt-regexp (sql-get-product-feature sql-product
3019 :prompt-regexp))
3020 (start nil))
3021 (with-current-buffer buf
3022 (unless save-prior
3023 (erase-buffer))
3024 (goto-char (point-max))
3025 (setq start (point)))
3026
3027 ;; Run the command
3028 (comint-redirect-send-command-to-process command buf proc nil t)
3029 (while (null comint-redirect-completed)
3030 (accept-process-output nil 1))
3031
3032 ;; Remove echo if there was one
3033 (with-current-buffer buf
3034 (goto-char start)
3035 (when (looking-at (concat "^" (regexp-quote command) "[\\n]"))
3036 (delete-region (match-beginning 0) (match-end 0)))
3037 (goto-char start)))))
3038
3039(defun sql-redirect-value (command combuf regexp &optional regexp-groups)
3040 "Execute the SQL command and return part of result.
3041
3042COMBUF must be an active SQL interactive buffer. COMMAND should
3043be a string of commands accepted by the SQLi program. From the
3044output, the REGEXP is repeatedly matched and the list of
3045REGEXP-GROUPS submatches is returned. This behaves much like
3046\\[comint-redirect-results-list-from-process] but instead of
3047returning a single submatch it returns a list of each submatch
3048for each match."
3049
3050 (let ((outbuf " *SQL-Redirect-values*")
3051 (results nil))
3052 (sql-redirect command combuf outbuf nil)
3053 (with-current-buffer outbuf
3054 (while (re-search-forward regexp nil t)
3055 (push
3056 (cond
3057 ;; no groups-return all of them
3058 ((null regexp-groups)
3059 (let ((i 1)
3060 (r nil))
3061 (while (match-beginning i)
3062 (push (match-string i) r))
3063 (nreverse r)))
3064 ;; one group specified
3065 ((numberp regexp-groups)
3066 (match-string regexp-groups))
3067 ;; (buffer-substring-no-properties
3068 ;; (match-beginning regexp-groups)
3069 ;; (match-end regexp-groups)))
3070 ;; list of numbers; return the specified matches only
3071 ((consp regexp-groups)
3072 (mapcar (lambda (c)
3073 (cond
3074 ((numberp c) (match-string c))
3075 ((stringp c) (match-substitute-replacement c))
3076 (t (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s" c))))
3077 regexp-groups))
3078 ;; String is specified; return replacement string
3079 ((stringp regexp-groups)
3080 (match-substitute-replacement regexp-groups))
3081 (t
3082 (error "sql-redirect-value: unknown REGEXP-GROUPS value - %s"
3083 regexp-groups)))
3084 results)))
3085 (nreverse results)))
3086
3087
3088
2997;;; SQL mode -- uses SQL interactive mode 3089;;; SQL mode -- uses SQL interactive mode
2998 3090
2999;;;###autoload 3091;;;###autoload
@@ -3365,7 +3457,7 @@ the call to \\[sql-product-interactive] with
3365 3457
3366 ;; Handle universal arguments if specified 3458 ;; Handle universal arguments if specified
3367 (when (not (or executing-kbd-macro noninteractive)) 3459 (when (not (or executing-kbd-macro noninteractive))
3368 (when (and (listp product) 3460 (when (and (consp product)
3369 (not (cdr product)) 3461 (not (cdr product))
3370 (numberp (car product))) 3462 (numberp (car product)))
3371 (when (>= (car product) 16) 3463 (when (>= (car product) 16)
@@ -3394,10 +3486,7 @@ the call to \\[sql-product-interactive] with
3394 ;; If no new name specified, fall back on sql-buffer if its for 3486 ;; If no new name specified, fall back on sql-buffer if its for
3395 ;; the same product 3487 ;; the same product
3396 (if (and (not new-name) 3488 (if (and (not new-name)
3397 sql-buffer 3489 (sql-buffer-live-p sql-buffer product))
3398 (sql-buffer-live-p sql-buffer)
3399 (comint-check-proc sql-buffer)
3400 (eq product (with-current-buffer sql-buffer sql-product)))
3401 (pop-to-buffer sql-buffer) 3490 (pop-to-buffer sql-buffer)
3402 3491
3403 ;; We have a new name or sql-buffer doesn't exist or match 3492 ;; We have a new name or sql-buffer doesn't exist or match
@@ -3423,10 +3512,11 @@ the call to \\[sql-product-interactive] with
3423 (when new-name 3512 (when new-name
3424 (sql-rename-buffer new-name)) 3513 (sql-rename-buffer new-name))
3425 3514
3426 ;; Set `sql-buffer' in the start buffer 3515 ;; Set `sql-buffer' in the new buffer and the start buffer
3427 (setq sql-buffer (buffer-name new-sqli-buffer)) 3516 (setq sql-buffer (buffer-name new-sqli-buffer))
3428 (with-current-buffer start-buffer 3517 (with-current-buffer start-buffer
3429 (setq sql-buffer (buffer-name new-sqli-buffer))) 3518 (setq sql-buffer (buffer-name new-sqli-buffer))
3519 (run-hooks 'sql-set-sqli-hook))
3430 3520
3431 ;; All done. 3521 ;; All done.
3432 (message "Login...done") 3522 (message "Login...done")