diff options
author | 2010-10-05 11:32:29 +0200 | |
---|---|---|
committer | 2010-10-05 11:32:29 +0200 | |
commit | bd1b8554c2b98cc211e9714fbb4d3b9c5e57526b (patch) | |
tree | 1b824e34130619033df5d0fa07ff0ec08507c2a2 /dotemacs/.emacs.d/sqlplus.el | |
parent | 59da8f9c06b615834e31d1838f39eafa4de02eb3 (diff) | |
parent | da733711d47de1a34d591268d821a3687cbdbd07 (diff) | |
download | dotfiles-bd1b8554c2b98cc211e9714fbb4d3b9c5e57526b.tar.gz dotfiles-bd1b8554c2b98cc211e9714fbb4d3b9c5e57526b.zip |
Merge branch 'fix-dotemacs'
Diffstat (limited to 'dotemacs/.emacs.d/sqlplus.el')
-rw-r--r-- | dotemacs/.emacs.d/sqlplus.el | 5151 |
1 files changed, 0 insertions, 5151 deletions
diff --git a/dotemacs/.emacs.d/sqlplus.el b/dotemacs/.emacs.d/sqlplus.el deleted file mode 100644 index 4d5e7d7..0000000 --- a/dotemacs/.emacs.d/sqlplus.el +++ /dev/null @@ -1,5151 +0,0 @@ -;;; sqlplus.el --- User friendly interface to SQL*Plus and support for PL/SQL compilation - -;; Copyright (C) 2007, 2008 Peter Karpiuk, Scott Tiger S.A. - -;; Author: Peter Karpiuk <piotr.karpiuk (at) gmail (dot) com> -;; Maintainer: Peter Karpiuk <piotr.karpiuk (at) gmail (dot) com> -;; Created: 25 Nov 2007 -;; Version 0.9.0 -;; Keywords: sql sqlplus oracle plsql - -;; GNU Emacs is free software; you can redistribute it and/or modify -;; it under the terms of the GNU General Public License as published -;; by the Free Software Foundation; either version 2, or (at your -;; option) any later version. - -;; GNU Emacs is distributed in the hope that it will be useful, but -;; WITHOUT ANY WARRANTY; without even the implied warranty of -;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -;; General Public License for more details. - -;; You should have received a copy of the GNU General Public License -;; along with GNU Emacs; see the file COPYING. If not, write to the -;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -;;; Commentary: - -;; Facilitates interaction with Oracle via SQL*Plus (GNU Emacs only). -;; Moreover, this package complements plsql.el (Kahlil Hodgson) -;; upon convenient compilation of PL/SQL source files. -;; -;; This package was inspired by sqlplus-mode.el (Rob Riepel, Peter -;; D. Pezaris, Martin Schwenke), but offers more features: -;; - tables are parsed, formatted and rendered with colors, like in -;; many GUI programs; you can see raw SQL*Plus output also, -;; if you wish -;; - table will be cutted if you try to fetch too many rows -;; (SELECT * FROM MY_MILLION_ROWS_TABLE); current SQL*Plus command -;; will be automatically interrupted under the hood in such cases -;; - you can use many SQL*Plus processes simultaneously, -;; - font locking (especially if you use Emacs>=22), with database -;; object names highlighting, -;; - history (log) of executed commands - see` sqlplus-history-dir` -;; variable, -;; - commands for fetching any database object definition -;; (package, table/index/sequence script) -;; - query result can be shown in HTML, -;; - input buffer for each connection can be saved into file on -;; disconnect and automatically restored on next connect (see -;; 'sqlplus-session-cache-dir' variable); if you place some -;; SQL*Plus commands between '/* init */' and '/* end */' -;; comments in saved input buffer, they will be automatically -;; executed on every connect -;; - if you use plsql.el for editing PL/SQL files, you can compile -;; such sources everytime with C-cC-c; error messages will be -;; parsed and displayed for easy source navigation -;; - M-. or C-mouse-1 on database object name will go to definition -;; in filesystem (use arrow button on toolbar to go back) -;; -;; The following commands should be added to a global initialization -;; file or to any user's .emacs file to conveniently use -;; sqlplus-mode: -;; -;; (require 'sqlplus) -;; (add-to-list 'auto-mode-alist '("\\.sqp\\'" . sqlplus-mode)) -;; -;; If you want PL/SQL support also, try something like this: -;; -;; (require 'plsql) -;; (setq auto-mode-alist -;; (append '(("\\.pls\\'" . plsql-mode) ("\\.pkg\\'" . plsql-mode) -;; ("\\.pks\\'" . plsql-mode) ("\\.pkb\\'" . plsql-mode) -;; ("\\.sql\\'" . plsql-mode) ("\\.PLS\\'" . plsql-mode) -;; ("\\.PKG\\'" . plsql-mode) ("\\.PKS\\'" . plsql-mode) -;; ("\\.PKB\\'" . plsql-mode) ("\\.SQL\\'" . plsql-mode) -;; ("\\.prc\\'" . plsql-mode) ("\\.fnc\\'" . plsql-mode) -;; ("\\.trg\\'" . plsql-mode) ("\\.vw\\'" . plsql-mode) -;; ("\\.PRC\\'" . plsql-mode) ("\\.FNC\\'" . plsql-mode) -;; ("\\.TRG\\'" . plsql-mode) ("\\.VW\\'" . plsql-mode)) -;; auto-mode-alist )) -;; -;; M-x sqlplus will start new SQL*Plus session. -;; -;; C-RET execute command under point -;; S-C-RET execute command under point and show result table in HTML -;; buffer -;; M-RET explain execution plan for command under point -;; M-. or C-mouse-1: find database object definition (table, view -;; index, synonym, trigger, procedure, function, package) -;; in filesystem -;; C-cC-s show database object definition (retrieved from database) -;; -;; Use describe-mode while in sqlplus-mode for further instructions. -;; -;; Many useful commands are defined in orcl-mode minor mode, which is -;; common for input and otput SQL*Plus buffers, as well as PL/SQL -;; buffers. -;; -;; For twiddling, see 'sqlplus' customization group. -;; -;; If you find this package useful, send me a postcard to address: -;; -;; Peter Karpiuk -;; Scott Tiger S.A. -;; ul. Gawinskiego 8 -;; 01-645 Warsaw -;; Poland - -;;; Known bugs: - -;; 1. Result of SQL select command can be messed up if some columns -;; has newline characters. To avoid this, execute SQL*Plus command -;; column <colname> truncated -;; before such select - -;;; Code: - -(require 'recentf) -(require 'font-lock) -(require 'cl) -(require 'sql) -(require 'tabify) -(require 'skeleton) - -(defconst sqlplus-revision "$Revision: 1.7 $") - -;;; Variables - - -(defgroup sqlplus nil - "SQL*Plus" - :group 'tools - :version 21) - -(defcustom plsql-auto-parse-errors-flag t - "Non nil means parse PL/SQL compilation results and show them in the compilation buffer." - :group 'sqlplus - :type '(boolean)) - -(defcustom sqlplus-init-sequence-start-regexp "/\\* init \\*/" - "SQL*Plus start of session init command sequence." - :group 'sqlplus - :type '(regexp)) - -(defcustom sqlplus-init-sequence-end-regexp "/\\* end \\*/" - "SQL*Plus end of session init command sequence." - :group 'sqlplus - :type '(regexp)) - -(defcustom sqlplus-explain-plan-warning-regexps '("TABLE ACCESS FULL" "INDEX FULL SCAN") - "SQL*Plus explain plan warning regexps" - :group 'sqlplus - :type '(repeat regexp)) - -(defcustom sqlplus-syntax-faces - '((schema font-lock-type-face nil) - (table font-lock-type-face ("dual")) - (synonym font-lock-type-face nil) - (view font-lock-type-face nil) - (column font-lock-constant-face nil) - (sequence font-lock-type-face nil) - (package font-lock-type-face nil) - (trigger font-lock-type-face nil) - (index font-lock-type-face) nil) - "Font lock configuration for database object names in current schema. -This is alist, and each element looks like (SYMBOL FACE LIST) -where SYMBOL is one of: schema, table, synonym, view, column, -sequence, package, trigger, index. Database objects means only -objects from current schema, so if you want syntax highlighting -for other objects (eg. 'dual' table name), you can explicitly -enumerate them in LIST as strings." - :group 'sqlplus - :tag "Oracle SQL Syntax Faces" - :type '(repeat (list symbol face (repeat string)))) - -(defcustom sqlplus-output-buffer-max-size (* 50 1000 1000) - "Maximum size of SQL*Plus output buffer. -After exceeding oldest results are deleted." - :group 'sqlplus - :tag "SQL*Plus Output Buffer Max Size" - :type '(integer)) - -(defcustom sqlplus-select-result-max-col-width nil - "Maximum width of column in displayed database table, or nil if there is no limit. -If any cell value is longer, it will be cutted and terminated with ellipsis ('...')." - :group 'sqlplus - :tag "SQL*Plus Select Result Max Column Width" - :type '(choice integer (const nil))) - -(defcustom sqlplus-format-output-tables-flag t - "Non-nil means format result if it looks like database table." - :group 'sqlplus - :tag "SQL*Plus Format Output Table" - :type '(boolean)) - -(defcustom sqlplus-kill-processes-without-query-on-exit-flag t - "Non-nil means silently kill all SQL*Plus processes on Emacs exit." - :group 'sqlplus - :tag "SQL*Plus Kill Processes Without Query On Exit" - :type '(boolean)) - -(defcustom sqlplus-multi-output-tables-default-flag t - "Non-nil means render database table as set of adjacent tables so that they occupy all width of output window. -For screen space saving and user comfort." - :group 'sqlplus - :tag "SQL*Plus Multiple Tables In Output by Default" - :type '(boolean)) - -(defcustom sqlplus-source-buffer-readonly-by-default-flag t - "Non-nil means show database sources in read-only buffer." - :group 'sqlplus - :tag "SQL*Plus Source Buffer Read Only By Default" - :type '(boolean)) - -(defcustom sqlplus-command "sqlplus" - "SQL*Plus interpreter program." - :group 'sqlplus - :tag "SQL*Plus Command" - :type '(string)) - -(defcustom sqlplus-history-dir nil - "Directory of SQL*Plus command history (log) files, or nil (dont generate log files). -History file name has format '<connect-string>-history.txt'." - :group 'sqlplus - :tag "SQL*Plus History Dir" - :type '(choice directory (const nil))) - -(defvar sqlplus-session-file-extension "sqp") - -(defcustom sqlplus-session-cache-dir nil - "Directory of SQL*Plus input buffer files, or nil (dont save user session). -Session file name has format '<connect-string>.sqp'" - :group 'sqlplus - :tag "SQL*Plus History Dir" - :type '(choice directory (const nil))) - -(defcustom sqlplus-save-passwords nil - "Non-nil means save passwords between Emacs sessions. (Not implemented yet)." - :group 'sqlplus - :tag "SQL*Plus Save Passwords" - :type '(boolean)) - -(defcustom sqlplus-pagesize 200 - "Approximate number of records in query results. -If result has more rows, it will be cutted and terminated with '. . .' line." - :group 'sqlplus - :tag "SQL*Plus Max Rows Count" - :type '(integer)) - -(defvar sqlplus-default-wrap "on") - -(defcustom sqlplus-initial-strings - (list "set sqlnumber off" - "set tab off" - "set linesize 4000" - "set echo off" - "set newpage 1" - "set space 1" - "set feedback 6" - "set heading on" - "set trimspool off" - (format "set wrap %s" sqlplus-default-wrap) - "set timing on" - "set feedback on") - "Initial commands to send to interpreter. -Customizing this variable is dangerous." - :group 'sqlplus - :tag "SQL*Plus Initial Strings" - :type '(repeat string)) - -(defcustom sqlplus-table-col-separator " | " - "Database table column separator (text-only terminals)." - :group 'sqlplus - :tag "SQL*Plus Table Col Separator" - :type '(string)) - -(defcustom sqlplus-table-col-head-separator "-+-" - "Database table header-column separator (text-only terminals)." - :group 'sqlplus - :tag "SQL*Plus Table Col Separator" - :type '(string)) - -(defcustom sqlplus-html-output-file-name "$HOME/sqlplus_report.html" - "Output file for HTML result." - :group 'sqlplus - :tag "SQL*Plus HTML Output File Name" - :type '(file)) - -(defcustom sqlplus-html-output-encoding "iso-8859-1" - "Encoding for SQL*Plus HTML output." - :group 'sqlplus - :tag "SQL*Plus HTML Output Encoding" - :type '(string)) - -(defcustom sqlplus-html-output-sql t - "Non-nil means put SQL*Plus command in head of HTML result." - :group 'sqlplus - :tag "SQL*Plus HTML Output Encoding" - :type '(choice (const :tag "Elegant" 'elegant) - (const :tag "Simple" t) - (const :tag "No" nil))) - -(defcustom sqlplus-html-output-header (concat (current-time-string) "<br><br>") - "HTML header sexp (result must be string)." - :group 'sqlplus - :tag "SQL*Plus HTML Output Header" - :type '(sexp)) - -(defcustom sqlplus-command-highlighting-percentage 7 - "SQL*Plus command highlighting percentage (0-100), only if sqlplus-command-highlighting-style is set." - :group 'sqlplus - :tag "SQL*Plus command highlighting percentage" - :type '(integer)) - -(defcustom sqlplus-command-highlighting-style nil - "How to highlight current command in sqlplus buffer." - :group 'sqlplus - :tag "SQL*Plud command highlighting style" - :type '(choice (const :tag "Fringe" fringe) - (const :tag "Background" background) - (const :tag "Fringe and background" fringe-and-background) - (const :tag "None" nil))) - -(defvar sqlplus-elegant-style window-system) - -(defvar sqlplus-cs nil) - -(defun sqlplus-shine-color (color percent) - (when (equal color "unspecified-bg") - (setq color (if (< percent 0) "white" "black"))) - (apply 'format "#%02x%02x%02x" - (mapcar (lambda (value) - (min 65535 (max 0 (* (+ (/ value 650) percent) 650)))) - (color-values color)))) - -(defvar sqlplus-table-head-face 'sqlplus-table-head-face) -(defface sqlplus-table-head-face - (list - (list '((class mono)) - '(:inherit default :weight bold :inverse-video t)) - (list '((background light)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) -70) :foreground (face-background 'default)) - (when (and sqlplus-elegant-style (>= emacs-major-version 22)) '(:box (:style released-button))))) - (list '((background dark)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) +70) :foreground (face-background 'default)) - (when (and sqlplus-elegant-style (>= emacs-major-version 22)) '(:box (:style released-button))))) - '(t (:inherit default))) - "Face for table header" - :group 'sqlplus) - -(defvar sqlplus-table-even-rows-face 'sqlplus-table-even-rows-face) -(defface sqlplus-table-even-rows-face - (list - (list '((class mono)) '()) - (list '((type tty)) '()) - (list '((background light)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) -20) :overline (face-background 'default)))) - (list '((background dark)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) +20) :overline (face-background 'default)))) - '(t ())) - "Face for table even rows" - :group 'sqlplus) - -(defvar sqlplus-table-odd-rows-face 'sqlplus-table-odd-rows-face) -(defface sqlplus-table-odd-rows-face - (list - (list '((class mono)) '(:inherit default)) - (list '((background light)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) -30) :overline (face-background 'default)))) - (list '((background dark)) - (append (list :inherit 'default :background (sqlplus-shine-color (face-background 'default) +30) :overline (face-background 'default)))) - '(t (:inherit default))) - "Face for table even rows" - :group 'sqlplus) - -(defvar sqlplus-command-highlight-face 'sqlplus-command-highlight-face) -(defface sqlplus-command-highlight-face - (list - '(((class mono)) ()) - '(((type tty)) ()) - (list '((background light)) - (append (list :background (sqlplus-shine-color (face-background 'default) (- sqlplus-command-highlighting-percentage))))) - (list '((background dark)) - (append (list :background (sqlplus-shine-color (face-background 'default) sqlplus-command-highlighting-percentage)))) - '(t ())) - "Face for highlighting command under point" - :group 'sqlplus) - -(defvar sqlplus-plsql-compilation-results-buffer-name "*PL/SQL Compilation*") - -(defvar sqlplus-fan "|" - "Local in input buffers") -(make-variable-buffer-local 'sqlplus-fan) - -(defvar orcl-mode-map nil - "Keymap used in Orcl mode.") - -(define-minor-mode orcl-mode - "Mode for executing SQL*Plus commands and scrolling results. - -Mode Specific Bindings: - -\\{orcl-mode-map}" - nil ; init value - (" " (:eval sqlplus-fan) " " (:eval (connect-string-to-string))) ; mode indicator - orcl-mode-map ; keymap - ;; body - (setq sqlplus-fan "|") - (unless (assq 'orcl-mode minor-mode-map-alist) - (push (cons 'orcl-mode orcl-mode-map) minor-mode-map-alist))) - -(defvar sqlplus-user-variables (makehash 'equal)) - -(defvar sqlplus-user-variables-history nil) - -(defvar sqlplus-get-source-history nil) - -(defvar sqlplus-process-p nil - "Non-nil (connect string) if current buffer is SQL*Plus process buffer. -Local in process buffer.") -(make-variable-buffer-local 'sqlplus-process-p) - -(defvar sqlplus-command-seq 0 - "Sequence for command id within SQL*Plus connection. -Local in process buffer.") -(make-variable-buffer-local 'sqlplus-command-seq) - -;;; :id - unique command identifier (from sequence, for session) -;;; :sql - content of command -;;; :dont-parse-result - process data online as it comes from sqlplus, with sqlplus-result-online or with :result-function function -;;; :result-function - function for processing sqlplus data; must have signature (context connect-string begin end interrupted); -;;; if nil then it is sqlplus-result-online for :dont-parse-result set to non-nil and sqlplus-process-command-output for :dont-parse-result set to nil -;;; :current-command-input-buffer-name - buffer name from which command was initialized -(defvar sqlplus-command-contexts nil - "Command options list, for current and enqueued commands, in chronological order. -Local in process buffer.") -(make-variable-buffer-local 'sqlplus-command-contexts) - -(defvar sqlplus-connect-string nil - "Local variable with connect-string for current buffer (input buffers, output buffer).") -(make-variable-buffer-local 'sqlplus-connect-string) - -(defvar sqlplus-connect-strings-alist nil - "Connect strings in format (CS . PASSWD), where PASSWD can be nil.") - -(defvar sqlplus-connect-string-history nil) - -(defvar sqlplus-prompt-prefix "SQL[") -(defvar sqlplus-prompt-suffix "]# ") - -(defvar sqlplus-page-separator "@!%#!") - -(defvar sqlplus-repfooter "##%@!") - -(defvar sqlplus-mode-map nil - "Keymap used in SQL*Plus mode.") - -(defvar sqlplus-output-separator "@--" - "String printed between sets of SQL*Plus command output.") - -;;; Markers - - -(defvar sqlplus-buffer-mark (make-marker) - "Marks the current SQL command in the SQL*Plus output buffer. -Local in output buffer.") -(make-variable-buffer-local 'sqlplus-buffer-mark) - -(defvar sqlplus-region-beginning-pos nil - "Marks the beginning of the region to sent to the SQL*Plus process. -Local in input buffer with sqlplus-mode.") -(make-variable-buffer-local 'sqlplus-region-beginning-pos) - -(defvar sqlplus-region-end-pos nil - "Marks the end of the region to sent to the SQL*Plus process. -Local in input buffer with sqlplus-mode.") -(make-variable-buffer-local 'sqlplus-region-end-pos) - -(defvar sqlplus-connections-menu - '("SQL*Plus" - :filter sqlplus-connections-menu) - "Menu for database connections") - -(defconst sqlplus-kill-xpm "\ -/* XPM */ -static char * reload_page_xpm[] = { -\"24 24 100 2\", -\" c None\", -\". c #000000\", -\"+ c #2A5695\", -\"@ c #30609E\", -\"# c #3363A2\", -\"$ c #3969A6\", -\"% c #3D6BA6\", -\"& c #3C68A3\", -\"* c #35619C\", -\"= c #244F8D\", -\"- c #3364A3\", -\"; c #3162A1\", -\"> c #3867A4\", -\", c #3F6DA8\", -\"' c #4672AC\", -\") c #4B76AE\", -\"! c #4E78AF\", -\"~ c #537CB1\", -\"{ c #547DB0\", -\"] c #446BA1\", -\"^ c #2E5D9C\", -\"/ c #234F8C\", -\"( c #214C89\", -\"_ c #244E8C\", -\": c #3A649D\", -\"< c #517BB0\", -\"[ c #517BB1\", -\"} c #4874AD\", -\"| c #6086B7\", -\"1 c #5F84B4\", -\"2 c #4B71A6\", -\"3 c #7B9BC4\", -\"4 c #224C89\", -\"5 c #3865A2\", -\"6 c #406FAB\", -\"7 c #436BA3\", -\"8 c #648ABA\", -\"9 c #4D78AF\", -\"0 c #4B77AE\", -\"a c #6E91BE\", -\"b c #809EC6\", -\"c c #204A87\", -\"d c #4974AF\", -\"e c #2B5590\", -\"f c #6487B5\", -\"g c #678CBB\", -\"h c #3465A4\", -\"i c #84A1C8\", -\"j c #6D8FBA\", -\"k c #4F7AB0\", -\"l c #8BA7CB\", -\"m c #7E9DC5\", -\"n c #83A1C7\", -\"o c #91ACCE\", -\"p c #89A4C9\", -\"q c #8FA9CB\", -\"r c #85A2C7\", -\"s c #90ABCC\", -\"t c #3E6CA8\", -\"u c #87A3C8\", -\"v c #4B6DA1\", -\"w c #91ABCD\", -\"x c #3768A5\", -\"y c #8AA5C9\", -\"z c #2D5690\", -\"A c #204A86\", -\"B c #93ADCE\", -\"C c #7294BF\", -\"D c #6288B9\", -\"E c #86A3C8\", -\"F c #466EA3\", -\"G c #3864A1\", -\"H c #285390\", -\"I c #234E8C\", -\"J c #95AECF\", -\"K c #7493BC\", -\"L c #86A2C7\", -\"M c #7999C3\", -\"N c #5B82B5\", -\"O c #6C8EBB\", -\"P c #4B71A5\", -\"Q c #26508B\", -\"R c #2B5792\", -\"S c #305E9B\", -\"T c #31619F\", -\"U c #7895BD\", -\"V c #819DC3\", -\"W c #688DBB\", -\"X c #6288B8\", -\"Y c #5880B4\", -\"Z c #577FB3\", -\"` c #547DB2\", -\" . c #416FAA\", -\".. c #3564A2\", -\"+. c #577AAB\", -\"@. c #6286B6\", -\"#. c #668BBA\", -\"$. c #507AB0\", -\"%. c #426EA8\", -\"&. c #2F5B97\", -\" \", -\" \", -\" \", -\" . . . . . . . . \", -\" . . + @ # $ % & * . . . . \", -\" . = - ; @ > , ' ) ! ~ { . . . ] . \", -\" . ^ / ( _ . . . : < [ } | 1 2 3 . \", -\" . _ 4 5 6 . . . 7 8 9 0 a b . \", -\" . c d . . . e f g h i . \", -\" . . . . . j k h l . \", -\" . . f m n l o . \", -\" . . . . . . . . \", -\" . . . . . . . . \", -\" . p q q q r . . \", -\" . s , t u v . . . . \", -\" . w x | y z . . . . A . \", -\" . B C 9 D E F . . . G H I . \", -\" . J K L M N C O P . . . Q R S T . \", -\" . U . . . V W X | Y Z ` ) .... \", -\" . . . . +.@.#.N $.%.&.. . \", -\" . . . . . . . . \", -\" \", -\" \", -\" \"}; -" - "XPM format image used as Kill icon") - -(defconst sqlplus-cancel-xpm "\ -/* XPM */ -static char * process_stop_xpm[] = { -\"24 24 197 2\", -\" c None\", -\". c #000000\", -\"+ c #C92B1E\", -\"@ c #DA432F\", -\"# c #E95941\", -\"$ c #F26B50\", -\"% c #ED6047\", -\"& c #DF4A35\", -\"* c #CE3324\", -\"= c #BF1D13\", -\"- c #EA5942\", -\"; c #EF563A\", -\"> c #F14D2C\", -\", c #F1431F\", -\"' c #F23A12\", -\") c #F2421C\", -\"! c #F24D2A\", -\"~ c #F15737\", -\"{ c #F0644A\", -\"] c #CF3121\", -\"^ c #D83828\", -\"/ c #ED5840\", -\"( c #EC3B1C\", -\"_ c #EE310B\", -\": c #F1350C\", -\"< c #F4380D\", -\"[ c #F53A0D\", -\"} c #F53B0D\", -\"| c #F4390D\", -\"1 c #F2360C\", -\"2 c #EF3A15\", -\"3 c #F05A3D\", -\"4 c #E44D37\", -\"5 c #CD2B1E\", -\"6 c #EA4D35\", -\"7 c #E92D0C\", -\"8 c #ED2F0B\", -\"9 c #F0330C\", -\"0 c #F3380D\", -\"a c #F63C0E\", -\"b c #F93F0F\", -\"c c #F9400F\", -\"d c #F73D0E\", -\"e c #F1340C\", -\"f c #EE300B\", -\"g c #EC482C\", -\"h c #E04532\", -\"i c #E84E3A\", -\"j c #E62A0E\", -\"k c #EA2B0A\", -\"l c #F83F0E\", -\"m c #FC4310\", -\"n c #FC4410\", -\"o c #F63B0E\", -\"p c #EB2C0A\", -\"q c #EB5139\", -\"r c #C8251A\", -\"s c #DD3D2E\", -\"t c #E5341D\", -\"u c #E62508\", -\"v c #F9BEB2\", -\"w c #FBCFC5\", -\"x c #F54C23\", -\"y c #F95125\", -\"z c #FDD4CB\", -\"A c #FABFB2\", -\"B c #E83013\", -\"C c #E84F3B\", -\"D c #E54737\", -\"E c #E22007\", -\"F c #E92A09\", -\"G c #FBD2CA\", -\"H c #FFFFFF\", -\"I c #FDDFD9\", -\"J c #F64E24\", -\"K c #FDE0D9\", -\"L c #E72609\", -\"M c #E7452F\", -\"N c #E33D2D\", -\"O c #E11E07\", -\"P c #E52308\", -\"Q c #E82809\", -\"R c #EC3F21\", -\"S c #FCDED8\", -\"T c #F55C37\", -\"U c #FCDFD8\", -\"V c #F04521\", -\"W c #EC2E0A\", -\"X c #E92909\", -\"Y c #E62408\", -\"Z c #E53823\", -\"` c #CE2B1F\", -\" . c #C62018\", -\".. c #E03120\", -\"+. c #E01C06\", -\"@. c #E32107\", -\"#. c #ED4121\", -\"$. c #FEF9F8\", -\"%. c #E72709\", -\"&. c #E42208\", -\"*. c #E32D17\", -\"=. c #D83729\", -\"-. c #CB231B\", -\";. c #DE2A1B\", -\">. c #DE1A06\", -\",. c #EE5135\", -\"'. c #EF5335\", -\"). c #EC2D0A\", -\"!. c #E82709\", -\"~. c #E21F07\", -\"{. c #E02511\", -\"]. c #DC392C\", -\"^. c #BE1612\", -\"/. c #DD2E21\", -\"(. c #DC1705\", -\"_. c #DF1B06\", -\":. c #E42308\", -\"<. c #E93A20\", -\"[. c #FBDDD8\", -\"}. c #EB3D20\", -\"|. c #DF2A18\", -\"1. c #D02A1F\", -\"2. c #DC3328\", -\"3. c #DA1404\", -\"4. c #DD1805\", -\"5. c #E3331E\", -\"6. c #FADCD8\", -\"7. c #FBDCD8\", -\"8. c #EB4C34\", -\"9. c #E6361F\", -\"0. c #DD1905\", -\"a. c #DF2F21\", -\"b. c #C21A14\", -\"c. c #DA3128\", -\"d. c #D81408\", -\"e. c #F7C9C4\", -\"f. c #FADBD8\", -\"g. c #E5341E\", -\"h. c #E5351E\", -\"i. c #F8CEC9\", -\"j. c #DB1505\", -\"k. c #DD3429\", -\"l. c #C31613\", -\"m. c #D9281F\", -\"n. c #D71003\", -\"o. c #D91304\", -\"p. c #F3B5B0\", -\"q. c #F7CDC9\", -\"r. c #E12F1D\", -\"s. c #DF1C06\", -\"t. c #E2301D\", -\"u. c #F4B6B0\", -\"v. c #DC1605\", -\"w. c #DB2317\", -\"x. c #D2271F\", -\"y. c #D1231D\", -\"z. c #D61A10\", -\"A. c #D60F03\", -\"B. c #D81104\", -\"C. c #DB1605\", -\"D. c #D81204\", -\"E. c #D81509\", -\"F. c #DA2F26\", -\"G. c #D52620\", -\"H. c #D51A12\", -\"I. c #D50D03\", -\"J. c #D60E03\", -\"K. c #D6170D\", -\"L. c #D92B23\", -\"M. c #BD100D\", -\"N. c #AB0404\", -\"O. c #CE1D19\", -\"P. c #D6231C\", -\"Q. c #D41008\", -\"R. c #D40B02\", -\"S. c #D40C02\", -\"T. c #D50C03\", -\"U. c #D40E05\", -\"V. c #D62018\", -\"W. c #D4251F\", -\"X. c #B30A09\", -\"Y. c #A20000\", -\"Z. c #BC0F0E\", -\"`. c #D2211E\", -\" + c #D52520\", -\".+ c #D5201A\", -\"++ c #D41A14\", -\"@+ c #D51F19\", -\"#+ c #D62620\", -\"$+ c #D52420\", -\"%+ c #C51614\", -\"&+ c #A30101\", -\"*+ c #A30303\", -\"=+ c #AE0909\", -\"-+ c #BD0E0E\", -\";+ c #B30B0B\", -\">+ c #A30404\", -\" \", -\" . . . . . . . \", -\" . . + @ # $ % & * . . \", -\" . = - ; > , ' ) ! ~ { ] . \", -\" . ^ / ( _ : < [ } | 1 2 3 4 . \", -\" . 5 6 7 8 9 0 a b c d | e f g h . \", -\" . i j k f : [ l m n c o 1 _ p q r . \", -\" . s t u k v w x l m n y z A _ p B C . \", -\" . D E u F G H I J b y K H w f k L M . \", -\" . N O P Q R S H I T K H U V W X Y Z ` . \", -\" . ...+.@.u F #.S H $.H U V 8 k %.&.*.=.. \", -\" . -.;.>.O &.L F ,.$.H $.'.).k !.P ~.{.].. \", -\" . ^./.(._.~.:.<.[.H $.H [.}.L P E +.|.1.. \", -\" . 2.3.4._.5.6.H 7.8.7.H 6.9.~.+.0.a.b.. \", -\" . c.d.3.(.e.H f.g.@.h.6.H i._.4.j.k.. \", -\" . l.m.n.o.p.q.r._.s.s.t.e.u.v.3.w.x.. \", -\" . y.z.A.B.o.j.C.(.(.v.j.3.D.E.F.. \", -\" . G.H.I.J.n.B.B.B.B.n.A.K.L.M.. \", -\" . N.O.P.Q.R.S.T.T.S.U.V.W.X.. \", -\" . Y.Z.`. +.+++@+#+$+%+&+. \", -\" . . . *+=+-+;+>+Y.. . \", -\" . . . . . . \", -\" \", -\" \"}; -" - "XPM format image used as Cancel icon") - -(defconst sqlplus-rollback-xpm "\ -/* XPM */ -static char * rollback_xpm[] = { -\"24 24 228 2\", -\" c None\", -\". c #000000\", -\"+ c #F8F080\", -\"@ c #FEF57B\", -\"# c #FFF571\", -\"$ c #FFF164\", -\"% c #FFED58\", -\"& c #FFE748\", -\"* c #FEDE39\", -\"= c #F8F897\", -\"- c #FFFE96\", -\"; c #FFFA8A\", -\"> c #FFF67C\", -\", c #FFF16E\", -\"' c #FFEC62\", -\") c #FFE956\", -\"! c #FFE448\", -\"~ c #FFE03C\", -\"{ c #FFDD30\", -\"] c #FED821\", -\"^ c #F1CB15\", -\"/ c #FFFC92\", -\"( c #FFFC91\", -\"_ c #FFFC90\", -\": c #FFFB8D\", -\"< c #FFF67D\", -\"[ c #FFEB5E\", -\"} c #FFEA5B\", -\"| c #FFE958\", -\"1 c #FFE855\", -\"2 c #FFE752\", -\"3 c #FDD41C\", -\"4 c #FDD319\", -\"5 c #FDD416\", -\"6 c #FFFF9D\", -\"7 c #FFFF99\", -\"8 c #FFFD94\", -\"9 c #FFFA89\", -\"0 c #FFDC2F\", -\"a c #FED315\", -\"b c #FFD808\", -\"c c #FFFC9F\", -\"d c #FFFE99\", -\"e c #FFDF3B\", -\"f c #F7C909\", -\"g c #F8EA86\", -\"h c #FEFCB7\", -\"i c #FFFDA6\", -\"j c #FFFA91\", -\"k c #FFF681\", -\"l c #FFF171\", -\"m c #FFED64\", -\"n c #FFE44A\", -\"o c #FFE03D\", -\"p c #FEDB2F\", -\"q c #F9D21E\", -\"r c #E9BC0F\", -\"s c #CE9C02\", -\"t c #F3E36A\", -\"u c #FCF899\", -\"v c #FFFCA3\", -\"w c #FEF694\", -\"x c #FFF284\", -\"y c #FFEE71\", -\"z c #FFEA62\", -\"A c #FDDC40\", -\"B c #F8D22F\", -\"C c #F1C61B\", -\"D c #DDAD0A\", -\"E c #CC9A02\", -\"F c #C89500\", -\"G c #F4EA77\", -\"H c #F7EF7F\", -\"I c #FFF16A\", -\"J c #FFEF68\", -\"K c #FFEE66\", -\"L c #FED622\", -\"M c #FED51E\", -\"N c #FED419\", -\"O c #E9B90E\", -\"P c #E7B509\", -\"Q c #D4A202\", -\"R c #CA9700\", -\"S c #F6E67C\", -\"T c #F3E67F\", -\"U c #FCEE7A\", -\"V c #FDEB66\", -\"W c #FEE44E\", -\"X c #FED313\", -\"Y c #FDCA03\", -\"Z c #F2BE01\", -\"` c #D4A60D\", -\" . c #D4A206\", -\".. c #D19C00\", -\"+. c #CF9800\", -\"@. c #E3AF02\", -\"#. c #F9EB81\", -\"$. c #FBF096\", -\"%. c #F9E67C\", -\"&. c #F8DC5F\", -\"*. c #F8D548\", -\"=. c #F9D02D\", -\"-. c #F9C915\", -\";. c #F7C104\", -\">. c #EEB606\", -\",. c #E9B704\", -\"'. c #DEAE08\", -\"). c #414D7B\", -\"!. c #3C5CA2\", -\"~. c #3A65B3\", -\"{. c #3668BB\", -\"]. c #325EAF\", -\"^. c #F3E46E\", -\"/. c #FCFA9B\", -\"(. c #FFF89C\", -\"_. c #FDEC81\", -\":. c #FCE668\", -\"<. c #FDDF4E\", -\"[. c #FCDA3C\", -\"}. c #FCD52E\", -\"|. c #FAD026\", -\"1. c #4662A2\", -\"2. c #465A8D\", -\"3. c #3F6CBA\", -\"4. c #3A68B7\", -\"5. c #2E529E\", -\"6. c #2655AC\", -\"7. c #F0DC69\", -\"8. c #FBF78C\", -\"9. c #FFF880\", -\"0. c #FFF06B\", -\"a. c #FFE03E\", -\"b. c #FFD828\", -\"c. c #FED015\", -\"d. c #F5C40A\", -\"e. c #4B70B4\", -\"f. c #4870B7\", -\"g. c #3C5CA1\", -\"h. c #4070BF\", -\"i. c #3759A0\", -\"j. c #1D469C\", -\"k. c #214493\", -\"l. c #F2DD6C\", -\"m. c #F8EB7E\", -\"n. c #FBEE7A\", -\"o. c #FBE461\", -\"p. c #FADB48\", -\"q. c #FBD631\", -\"r. c #FED10F\", -\"s. c #FECD07\", -\"t. c #F1BD00\", -\"u. c #456AAE\", -\"v. c #4C7ECA\", -\"w. c #487AC8\", -\"x. c #35528F\", -\"y. c #1B4294\", -\"z. c #1B4193\", -\"A. c #F9EA83\", -\"B. c #FCF08E\", -\"C. c #F6E16E\", -\"D. c #F4D559\", -\"E. c #F5CF45\", -\"F. c #F6CB2E\", -\"G. c #F8C611\", -\"H. c #F6C005\", -\"I. c #E8B300\", -\"J. c #4268AE\", -\"K. c #4375C4\", -\"L. c #3F71C1\", -\"M. c #33569B\", -\"N. c #173F94\", -\"O. c #183A8B\", -\"P. c #F3E36E\", -\"Q. c #FCF7A1\", -\"R. c #FEF9A1\", -\"S. c #FEEE7D\", -\"T. c #FCE360\", -\"U. c #FAD946\", -\"V. c #F9D132\", -\"W. c #F8CD26\", -\"X. c #F7CA20\", -\"Y. c #3B589A\", -\"Z. c #395FA9\", -\"`. c #3359A5\", -\" + c #3056A3\", -\".+ c #2B468D\", -\"++ c #0A3897\", -\"@+ c #E6D465\", -\"#+ c #FDFA90\", -\"$+ c #FFF885\", -\"%+ c #FFF074\", -\"&+ c #FFEA60\", -\"*+ c #FFE246\", -\"=+ c #FFDC31\", -\"-+ c #FED51F\", -\";+ c #F7CB14\", -\">+ c #173788\", -\",+ c #063494\", -\"'+ c #E8DE7B\", -\")+ c #FFFA86\", -\"!+ c #FFF26A\", -\"~+ c #FFE84F\", -\"{+ c #FFD415\", -\"]+ c #FDCC04\", -\"^+ c #F3C001\", -\"/+ c #EBB600\", -\"(+ c #E3AF01\", -\"_+ c #D7A100\", -\":+ c #2D3E7F\", -\"<+ c #033396\", -\"[+ c #CFB954\", -\"}+ c #DBC347\", -\"|+ c #DEBF2C\", -\"1+ c #DFB718\", -\"2+ c #DFB206\", -\"3+ c #D6A505\", -\"4+ c #C6970A\", -\"5+ c #B48413\", -\"6+ c #374682\", -\"7+ c #023398\", -\"8+ c #0E3287\", -\"9+ c #253775\", -\"0+ c #05318F\", -\"a+ c #10358B\", -\"b+ c #183888\", -\"c+ c #053495\", -\"d+ c #0E348D\", -\"e+ c #183585\", -\" . . . . . . . \", -\" . . + @ # $ % & * . . . \", -\" . = - ; > , ' ) ! ~ { ] ^ . \", -\". / ( _ : ; < [ } | 1 2 3 4 5 . \", -\". 6 7 8 9 > , ' ) ! ~ 0 ] a b . \", -\". c d 8 9 > , ' ) ! e 0 ] a f . \", -\". g h i j k l m | n o p q r s . \", -\". t u v w x y z 2 A B C D E F . \", -\". G H I J K L M N O P Q R F F . \", -\". S T U V W p X Y Z ` ...+.@.. . . . . \", -\". #.$.%.&.*.=.-.;.>.. . ,.'.. ).!.~.{.].. \", -\". ^./.(._.:.<.[.}.|.. 1.. . 2.3.4.. . 5.6.. \", -\". 7.8.9.0.) a.b.c.d.. e.f.g.h.i.. . j.k.. \", -\". l.m.n.o.p.q.r.s.t.. u.v.w.x.. . y.z.. \", -\". A.B.C.D.E.F.G.H.I.. J.K.L.M.. . N.O.. \", -\". P.Q.R.S.T.U.V.W.X.. Y.Z.`. +.+. . ++. \", -\". @+#+$+%+&+*+=+-+;+. . . . . . . . >+,+. \", -\" . '+)+!+~+{ {+]+^+/+(+_+. . :+<+. \", -\" . . [+}+|+1+2+3+4+5+. . 6+7+8+. \", -\" . . . . . . . . . 9+0+a+. \", -\" . b+c+d+. \", -\" . e+. . \", -\" . \", -\" \"}; -" - "XPM format image used as Rollback icon") - -(defconst sqlplus-commit-xpm "\ -/* XPM */ -static char * commit_xpm[] = { -\"24 24 276 2\", -\" c None\", -\". c #000000\", -\"+ c #FDF57D\", -\"@ c #FFF676\", -\"# c #FFF36C\", -\"$ c #FFF05D\", -\"% c #FFEB51\", -\"& c #FFE445\", -\"* c #FDDC35\", -\"= c #EFEA85\", -\"- c #FBF68D\", -\"; c #FCF482\", -\"> c #FCF178\", -\", c #FCEE6E\", -\"' c #FCEB66\", -\") c #FCE85B\", -\"! c #FCE551\", -\"~ c #FDE147\", -\"{ c #FDDF3D\", -\"] c #FEDD2D\", -\"^ c #FCD621\", -\"/ c #E5BF16\", -\"( c #D8D479\", -\"_ c #FCF587\", -\": c #FAEF78\", -\"< c #FAEA6B\", -\"[ c #FAEA6A\", -\"} c #FAE968\", -\"| c #FAE967\", -\"1 c #FAE865\", -\"2 c #FAE864\", -\"3 c #FDDD3C\", -\"4 c #FED621\", -\"5 c #FFD51D\", -\"6 c #FFD51B\", -\"7 c #FFD519\", -\"8 c #D8B82B\", -\"9 c #FCF790\", -\"0 c #FBF587\", -\"a c #F8EF7D\", -\"b c #F8EC75\", -\"c c #F7E86B\", -\"d c #F8E868\", -\"e c #F9E663\", -\"f c #F9E45A\", -\"g c #F9E253\", -\"h c #F9E04C\", -\"i c #FBDD40\", -\"j c #FBDB38\", -\"k c #FAD933\", -\"l c #FAD529\", -\"m c #FDD810\", -\"n c #FFFD9E\", -\"o c #FFFF9A\", -\"p c #FFFE96\", -\"q c #FFFB8C\", -\"r c #FFF781\", -\"s c #FFF375\", -\"t c #FFEF69\", -\"u c #FFEA5B\", -\"v c #FFE750\", -\"w c #FFE345\", -\"x c #FFDF38\", -\"y c #FFDB2B\", -\"z c #FFD81F\", -\"A c #FFD313\", -\"B c #FBD007\", -\"C c #FBF090\", -\"D c #FFFDAE\", -\"E c #FFFEA2\", -\"F c #FFFA8C\", -\"G c #FFF780\", -\"H c #F6CA11\", -\"I c #E1AF03\", -\"J c #F4E36D\", -\"K c #FCF7A4\", -\"L c #FFFEBB\", -\"M c #FEFAA6\", -\"N c #FFF990\", -\"O c #FFF57E\", -\"P c #FFEE6F\", -\"Q c #FFEB61\", -\"R c #FFE856\", -\"S c #FFE34A\", -\"T c #FBDD44\", -\"U c #F7D535\", -\"V c #EBBF13\", -\"W c #D5A406\", -\"X c #C99500\", -\"Y c #F0DC5F\", -\"Z c #F3E772\", -\"` c #F7EC76\", -\" . c #F6E56D\", -\".. c #F6E369\", -\"+. c #F6E264\", -\"@. c #F5DF5C\", -\"#. c #F3DB53\", -\"$. c #F3D849\", -\"%. c #EFD245\", -\"&. c #ECCE3F\", -\"*. c #E3B91F\", -\"=. c #D3A40B\", -\"-. c #C99600\", -\";. c #C69200\", -\">. c #EED95E\", -\",. c #EDDA60\", -\"'. c #F1DF64\", -\"). c #F2DF5E\", -\"!. c #F2DD57\", -\"~. c #F2D94E\", -\"{. c #F2D644\", -\"]. c #EFD038\", -\"^. c #ECCB34\", -\"/. c #E6C430\", -\"(. c #DFB71F\", -\"_. c #D9AD17\", -\":. c #CC9907\", -\"<. c #C69000\", -\"[. c #D39E00\", -\"}. c #BB1503\", -\"|. c #F9EA7D\", -\"1. c #F6E57A\", -\"2. c #F5E370\", -\"3. c #F5DE62\", -\"4. c #F9DF52\", -\"5. c #FBDB3E\", -\"6. c #FCD526\", -\"7. c #FCCE0F\", -\"8. c #F7C50A\", -\"9. c #EEBA08\", -\"0. c #E2AB03\", -\"a. c #D7A000\", -\"b. c #D59D00\", -\"c. c #DFA901\", -\"d. c #E7B402\", -\"e. c #C91800\", -\"f. c #F6E676\", -\"g. c #FCF4A1\", -\"h. c #FDF096\", -\"i. c #FAE167\", -\"j. c #F7D64F\", -\"k. c #F7CF38\", -\"l. c #F7CB26\", -\"m. c #F6BF0C\", -\"n. c #F1B905\", -\"o. c #ECB309\", -\"p. c #EBB60A\", -\"q. c #F0BF0B\", -\"r. c #F3C206\", -\"s. c #E5B201\", -\"t. c #CF9C01\", -\"u. c #C21602\", -\"v. c #C21703\", -\"w. c #F2E067\", -\"x. c #FBF78F\", -\"y. c #FEF28A\", -\"z. c #FEED74\", -\"A. c #FFE85F\", -\"B. c #FFE24D\", -\"C. c #FFDE3A\", -\"D. c #FED92F\", -\"E. c #FCD325\", -\"F. c #F8CD1A\", -\"G. c #EDBD0A\", -\"H. c #D9A701\", -\"I. c #C79200\", -\"J. c #D11D00\", -\"K. c #EFDA64\", -\"L. c #F7EF7F\", -\"M. c #FCF47F\", -\"N. c #FDEE6C\", -\"O. c #FDE85B\", -\"P. c #FDE249\", -\"Q. c #FDDC36\", -\"R. c #FCD423\", -\"S. c #F9CC14\", -\"T. c #F0C10E\", -\"U. c #E6B507\", -\"V. c #DCA900\", -\"W. c #D29F00\", -\"X. c #C69400\", -\"Y. c #C99200\", -\"Z. c #CC1B02\", -\"`. c #C61A04\", -\" + c #E1CF5F\", -\".+ c #EAD862\", -\"++ c #ECDB63\", -\"@+ c #EFDC5E\", -\"#+ c #EFD955\", -\"$+ c #EFD74D\", -\"%+ c #EFD444\", -\"&+ c #F0D23E\", -\"*+ c #EECE37\", -\"=+ c #E8C731\", -\"-+ c #E0B922\", -\";+ c #D09E03\", -\">+ c #CB9700\", -\",+ c #C39100\", -\"'+ c #C99400\", -\")+ c #E12400\", -\"!+ c #F2E47C\", -\"~+ c #F8ED8C\", -\"{+ c #F4E171\", -\"]+ c #F0D65B\", -\"^+ c #F0D24F\", -\"/+ c #F1CF43\", -\"(+ c #F2CD34\", -\"_+ c #F2C824\", -\":+ c #EEC527\", -\"<+ c #E7BD23\", -\"[+ c #DFAC12\", -\"}+ c #DAA203\", -\"|+ c #E5B202\", -\"1+ c #EDBA01\", -\"2+ c #D69F00\", -\"3+ c #D21E01\", -\"4+ c #D01C00\", -\"5+ c #F2E16A\", -\"6+ c #FBF59D\", -\"7+ c #FEFBAA\", -\"8+ c #FEF084\", -\"9+ c #FCE567\", -\"0+ c #FBDD50\", -\"a+ c #F8D23B\", -\"b+ c #F8CD28\", -\"c+ c #EEB51C\", -\"d+ c #DA8A13\", -\"e+ c #E29A16\", -\"f+ c #EDB111\", -\"g+ c #E5AE08\", -\"h+ c #D19C01\", -\"i+ c #C79400\", -\"j+ c #BF1603\", -\"k+ c #DD2300\", -\"l+ c #E6D261\", -\"m+ c #FCF88C\", -\"n+ c #FFF27A\", -\"o+ c #FFEC6A\", -\"p+ c #FFE655\", -\"q+ c #FFE041\", -\"r+ c #FFDA2B\", -\"s+ c #E49D14\", -\"t+ c #BA4F02\", -\"u+ c #BB6A00\", -\"v+ c #B37102\", -\"w+ c #DD2200\", -\"x+ c #CA1B02\", -\"y+ c #E6DB78\", -\"z+ c #FEFB8B\", -\"A+ c #FFF470\", -\"B+ c #FFEA56\", -\"C+ c #FFE13E\", -\"D+ c #FFDA24\", -\"E+ c #FECF0A\", -\"F+ c #F5BE01\", -\"G+ c #D37800\", -\"H+ c #D72000\", -\"I+ c #C61802\", -\"J+ c #EBD55C\", -\"K+ c #FCE353\", -\"L+ c #FFE33E\", -\"M+ c #FFDB26\", -\"N+ c #FFD20B\", -\"O+ c #FCCB01\", -\"P+ c #F0B900\", -\"Q+ c #D47D00\", -\"R+ c #E42500\", -\"S+ c #EB2900\", -\"T+ c #DF2301\", -\"U+ c #E82700\", -\"V+ c #D31F04\", -\"W+ c #C71F01\", -\"X+ c #EA2800\", -\"Y+ c #E92800\", -\"Z+ c #DD2301\", -\"`+ c #E22501\", -\" . . . . . . . \", -\" . . . + @ # $ % & * . . . \", -\" . = - ; > , ' ) ! ~ { ] ^ / . \", -\". ( _ : < [ } | 1 2 3 4 5 6 7 8 . \", -\". 9 0 a b c d e f g h i j k l m . \", -\". n o p q r s t u v w x y z A B . \", -\". C D E F G s t u v w x y z H I . \", -\". J K L M N O P Q R S T U V W X . \", -\". Y Z ` ...+.@.#.$.%.&.*.=.-.;.. . . \", -\". >.,.'.).!.~.{.].^./.(._.:.<.[.. . }.. \", -\". |.1.2.3.4.5.6.7.8.9.0.a.b.c.d.. . e.. \", -\". f.g.h.i.j.k.l.m.n.o.p.q.r.s.t.. . u.v.. \", -\". w.x.n y.z.A.B.C.D.E.F.G.H.-.I.. . J.. \", -\". K.L.M.N.O.P.Q.R.S.T.U.V.W.X.Y.. . Z.`.. \", -\". +.+++@+#+$+%+&+*+=+-+;+>+,+'+. . )+. \", -\". !+~+{+]+^+/+(+_+:+<+[+}+|+1+2+. . 3+4+. \", -\". 5+6+7+8+9+0+a+b+c+d+e+f+g+h+i+. j+k+. \", -\". l+m+q n+o+p+q+r+s+. . . t+u+v+. w+x+. \", -\" . y+z+A+B+C+D+E+F+G+. H+. . . I+)+. \", -\" . . J+K+L+M+N+O+P+Q+. R+S+T+U+V+. \", -\" . . . . . . . . . . W+X+Y+. \", -\" . Z+`+. \", -\" . . \", -\" . \"}; -" - "XPM format image used as Commit icon") - -(defconst plsql-prev-mark-xpm "\ -/* XPM */ -static char * go_previous_xpm[] = { -\"24 24 59 1\", -\" c None\", -\". c #000000\", -\"+ c #355D96\", -\"@ c #3C639B\", -\"# c #6E92BF\", -\"$ c #41679D\", -\"% c #6990BE\", -\"& c #6D94C2\", -\"* c #456DA2\", -\"= c #628BBC\", -\"- c #4D7BB4\", -\"; c #6991C0\", -\"> c #4971A6\", -\", c #5D87BA\", -\"' c #4B7BB3\", -\") c #4979B3\", -\"! c #5884B9\", -\"~ c #638CBC\", -\"{ c #638BBC\", -\"] c #6089BA\", -\"^ c #4B73A9\", -\"/ c #5883B8\", -\"( c #4A7AB3\", -\"_ c #618ABB\", -\": c #4C74AB\", -\"< c #547FB5\", -\"[ c #4972A9\", -\"} c #4D79B1\", -\"| c #4171AD\", -\"1 c #4071AD\", -\"2 c #4070AD\", -\"3 c #4171AC\", -\"4 c #4071AC\", -\"5 c #4070AC\", -\"6 c #3F70AC\", -\"7 c #3F70AB\", -\"8 c #406FAC\", -\"9 c #5781B5\", -\"0 c #4A74AC\", -\"a c #3E6CA8\", -\"b c #3465A4\", -\"c c #4E78AF\", -\"d c #446FA8\", -\"e c #4A75AD\", -\"f c #3F6CA6\", -\"g c #3C6BA7\", -\"h c #3B6BA7\", -\"i c #4471AB\", -\"j c #4572AB\", -\"k c #4672AC\", -\"l c #4571AB\", -\"m c #3A68A3\", -\"n c #3B6AA7\", -\"o c #406EA9\", -\"p c #3564A0\", -\"q c #3868A6\", -\"r c #305E9D\", -\"s c #3767A5\", -\"t c #2E5D9B\", -\" \", -\" \", -\" \", -\" .. \", -\" .+. \", -\" .@#. \", -\" .$%&. \", -\" .*=-;......... \", -\" .>,')!~{{{{{~]. \", -\" .^/()))(((((('_. \", -\" .:<)))))))))))),. \", -\" .[}|1123455567589. \", -\" .0abbbbbbbbbbbbc. \", -\" .dabbbbbbbbbbbe. \", -\" .fgbbhijjjjjkl. \", -\" .mnbo......... \", -\" .pqh. \", -\" .rs. \", -\" .t. \", -\" .. \", -\" . \", -\" \", -\" \", -\" \"}; -" - "XPM format image used as Previous Mark icon") - -(defconst plsql-next-mark-xpm "\ -/* XPM */ -static char * go_next_xpm[] = { -\"24 24 63 1\", -\" c None\", -\". c #000000\", -\"+ c #365F97\", -\"@ c #6B8FBE\", -\"# c #41689E\", -\"$ c #6990BF\", -\"% c #466EA4\", -\"& c #678EBD\", -\"* c #4E7DB5\", -\"= c #638CBC\", -\"- c #4B72A7\", -\"; c #5B83B5\", -\"> c #628BBB\", -\", c #5A86BA\", -\"' c #4979B3\", -\") c #4B7AB3\", -\"! c #5E87B9\", -\"~ c #4E76AA\", -\"{ c #5B84B8\", -\"] c #4E7CB5\", -\"^ c #4A7AB3\", -\"/ c #5883B7\", -\"( c #5178AD\", -\"_ c #5982B6\", -\": c #4C7BB4\", -\"< c #537FB5\", -\"[ c #5079AE\", -\"} c #507BB0\", -\"| c #4272AD\", -\"1 c #4070AC\", -\"2 c #3F70AB\", -\"3 c #3F70AC\", -\"4 c #4071AC\", -\"5 c #4171AC\", -\"6 c #4070AD\", -\"7 c #4071AD\", -\"8 c #4171AD\", -\"9 c #4D79B1\", -\"0 c #4E76AD\", -\"a c #4872AA\", -\"b c #3767A5\", -\"c c #3465A4\", -\"d c #3D6CA8\", -\"e c #4C76AD\", -\"f c #2B548E\", -\"g c #446FA8\", -\"h c #3C6BA7\", -\"i c #4772AA\", -\"j c #29528E\", -\"k c #3F6CA6\", -\"l c #4471AB\", -\"m c #4371AB\", -\"n c #3B6BA7\", -\"o c #416EA8\", -\"p c #3F6CA7\", -\"q c #3A69A6\", -\"r c #3C6AA5\", -\"s c #3B6AA5\", -\"t c #3868A6\", -\"u c #3765A2\", -\"v c #3666A3\", -\"w c #32619F\", -\"x c #2F5D9B\", -\" \", -\" \", -\" \", -\" .. \", -\" .+. \", -\" .@#. \", -\" .$$%. \", -\" .........&*=-. \", -\" .;>>>>>>=,')!~. \", -\" .{]^^^^^^''''/(. \", -\" ._:'''''''''''<[. \", -\" .}|12311145677890. \", -\" .abcccccccccccde. \", -\" .gbcccccccccchi. \", -\" .klmlllllhccno. \", -\" .........pcqr. \", -\" .stu. \", -\" .vw. \", -\" .x. \", -\" .. \", -\" . \", -\" \", -\" \", -\" \"}; -" - "XPM format image used as Next Mark icon") - -(defconst sqlplus-kill-image - (create-image sqlplus-kill-xpm 'xpm t)) - -(defconst sqlplus-cancel-image - (create-image sqlplus-cancel-xpm 'xpm t)) - -(defconst sqlplus-commit-image - (create-image sqlplus-commit-xpm 'xpm t)) - -(defconst sqlplus-rollback-image - (create-image sqlplus-rollback-xpm 'xpm t)) - -(defconst plsql-prev-mark-image - (create-image plsql-prev-mark-xpm 'xpm t)) - -(defconst plsql-next-mark-image - (create-image plsql-next-mark-xpm 'xpm t)) - -(defvar sqlplus-mode-syntax-table nil - "Syntax table used while in sqlplus-mode.") - -(defvar sqlplus-suppress-show-output-buffer nil) - -;; Local in input buffers -(defvar sqlplus-font-lock-keywords-1 nil) -(make-variable-buffer-local 'sqlplus-font-lock-keywords-1) -(defvar sqlplus-font-lock-keywords-2 nil) -(make-variable-buffer-local 'sqlplus-font-lock-keywords-2) -(defvar sqlplus-font-lock-keywords-3 nil) -(make-variable-buffer-local 'sqlplus-font-lock-keywords-3) - -(defvar sqlplus-font-lock-defaults '((sqlplus-font-lock-keywords-1 sqlplus-font-lock-keywords-2 sqlplus-font-lock-keywords-3) nil t nil nil)) - -(defvar sqlplus-oracle-extra-builtin-functions-re - (concat "\\b" - (regexp-opt '("acos" "asciistr" "asin" "atan" "atan2" "bfilename" "bin_to_num" "bitand" "cardinality" "cast" "coalesce" "collect" - "compose" "corr" "corr_s" "corr_k" "covar_pop" "covar_samp" "cume_dist" "current_date" "current_timestamp" "cv" - "dbtimezone" "decompose" "dense_rank" "depth" "deref" "empty_blob, empty_clob" "existsnode" "extract" - "extractvalue" "first" "first_value" "from_tz" "group_id" "grouping" "grouping_id" "iteration_number" - "lag" "last" "last_value" "lead" "lnnvl" "localtimestamp" "make_ref" "median" "nanvl" "nchr" "nls_charset_decl_len" - "nls_charset_id" "nls_charset_name" "ntile" "nullif" "numtodsinterval" "numtoyminterval" "nvl2" "ora_hash" "path" - "percent_rank" "percentile_cont" "percentile_disc" "powermultiset" "powermultiset_by_cardinality" "presentnnv" - "presentv" "previous" "rank" "ratio_to_report" "rawtonhex" "ref" "reftohex" "regexp_instr" "regexp_replace" - "regexp_substr" "regr_slope" "regr_intercept" "regr_count" "regr_r2" "regr_avgx" "regr_avgy" "regr_sxx" "regr_syy" - "regr_sxy" "remainder" "row_number" "rowidtonchar" "scn_to_timestamp" "sessiontimezone" "stats_binomial_test" - "stats_crosstab" "stats_f_test" "stats_ks_test" "stats_mode" "stats_mw_test" "stats_one_way_anova" "stats_t_test_one" - "stats_t_test_paired" "stats_t_test_indep" "stats_t_test_indepu" "stats_wsr_test" "stddev_pop" "stddev_samp" - "sys_connect_by_path" "sys_context" "sys_dburigen" "sys_extract_utc" "sys_guid" "sys_typeid" "sys_xmlagg" "sys_xmlgen" - "systimestamp" "timestamp_to_scn" "to_binary_double" "to_binary_float" "to_clob" "to_dsinterval" "to_lob" "to_nchar" - "to_nclob" "to_timestamp" "to_timestamp_tz" "to_yminterval" "treat" "tz_offset" "unistr" "updatexml" "value" "var_pop" - "var_samp" "width_bucket" "xmlagg" "xmlcolattval" "xmlconcat" "xmlelement" "xmlforest" "xmlsequence" "xmltransform") t) - "\\b")) -(defvar sqlplus-oracle-extra-warning-words-re - (concat "\\b" - (regexp-opt '("access_into_null" "case_not_found" "collection_is_null" "rowtype_mismatch" - "self_is_null" "subscript_beyond_count" "subscript_outside_limit" "sys_invalid_rowid") t) - "\\b")) -(defvar sqlplus-oracle-extra-keywords-re - (concat "\\b\\(" - "\\(at\\s-+local\\|at\\s-+time\\s-+zone\\|to\\s-+second\\|to\\s-+month\\|is\\s-+present\\|a\\s-+set\\)\\|" - (regexp-opt '("case" "nan" "infinite" "equals_path" "empty" "likec" "like2" "like4" "member" - "regexp_like" "submultiset" "under_path" "mlslabel") t) - "\\)\\b")) -(defvar sqlplus-oracle-extra-pseudocolumns-re - (concat "\\b" - (regexp-opt '("connect_by_iscycle" "connect_by_isleaf" "versions_starttime" "versions_startscn" - "versions_endtime" "versions_endscn" "versions_xid" "versions_operation" "object_id" "object_value" "ora_rowscn" - "xmldata") t) - "\\b")) -(defvar sqlplus-oracle-plsql-extra-reserved-words-re - (concat "\\b" - (regexp-opt '("array" "at" "authid" "bulk" "char_base" "day" "do" "extends" "forall" "heap" "hour" - "interface" "isolation" "java" "limited" "minute" "mlslabel" "month" "natural" "naturaln" "nocopy" "number_base" - "ocirowid" "opaque" "operator" "organization" "pls_integer" "positive" "positiven" "range" "record" "release" "reverse" - "rowtype" "second" "separate" "space" "sql" "timezone_region" "timezone_abbr" "timezone_minute" "timezone_hour" "year" - "zone") t) - "\\b")) -(defvar sqlplus-oracle-extra-types-re - (concat "\\b" - (regexp-opt '("nvarchar2" "binary_float" "binary_double" "timestamp" "interval" "interval_day" "urowid" "nchar" "clob" "nclob" "bfile") t) - "\\b")) - -(defvar sqlplus-commands-regexp-1 nil) -(defvar sqlplus-commands-regexp-23 nil) -(defvar sqlplus-system-variables-regexp-1 nil) -(defvar sqlplus-system-variables-regexp-23 nil) -(defvar sqlplus-v22-commands-font-lock-keywords-1 nil) -(defvar sqlplus-v22-commands-font-lock-keywords-23 nil) -(defvar font-lock-sqlplus-face nil) - -(defvar sqlplus-output-buffer-keymap nil - "Local in output buffer.") -(make-variable-buffer-local 'sqlplus-output-buffer-keymap) - -(defvar sqlplus-kill-function-inhibitor nil) - -(defvar sqlplus-slip-separator-width 2 - "Only for classic table style.") - -(defvar sqlplus-user-string-history nil) - -(defvar sqlplus-object-types '( "CONSUMER GROUP" "SEQUENCE" "SCHEDULE" "PROCEDURE" "OPERATOR" "WINDOW" - "PACKAGE" "LIBRARY" "PROGRAM" "PACKAGE BODY" "JAVA RESOURCE" "XML SCHEMA" - "JOB CLASS" "TRIGGER" "TABLE" "SYNONYM" "VIEW" "FUNCTION" "WINDOW GROUP" - "JAVA CLASS" "INDEXTYPE" "INDEX" "TYPE" "EVALUATION CONTEXT" )) - -(defvar sqlplus-end-of-source-sentinel "%%@@end-of-source-sentinel@@%%") - -(defconst sqlplus-system-variables - '("appi[nfo]" "array[size]" "auto[commit]" "autop[rint]" "autorecovery" "autot[race]" "blo[ckterminator]" "cmds[ep]" - "colsep" "com[patibility]" "con[cat]" "copyc[ommit]" "copytypecheck" "def[ine]" "describe" "echo" "editf[ile]" - "emb[edded]" "esc[ape]" "feed[back]" "flagger" "flu[sh]" "hea[ding]" "heads[ep]" "instance" "lin[esize]" - "lobof[fset]" "logsource" "long" "longc[hunksize]" "mark[up]" "newp[age]" "null" "numf[ormat]" "num[width]" - "pages[ize]" "pau[se]" "recsep" "recsepchar" "serverout[put]" "shift[inout]" "show[mode]" "sqlbl[anklines]" - "sqlc[ase]" "sqlco[ntinue]" "sqln[umber]" "sqlpluscompat[ibility]" "sqlpre[fix]" "sqlp[rompt]" "sqlt[erminator]" - "suf[fix]" "tab" "term[out]" "ti[me]" "timi[ng]" "trim[out]" "trims[pool]" "und[erline]" "ver[ify]" "wra[p]")) - -(defconst sqlplus-commands - '(("@[@]") - (("/" "r[un]")) - ("acc[ept]" - (font-lock-type-face "num[ber]" "char" "date" "binary_float" "binary_double") - (font-lock-keyword-face "for[mat]" "def[ault]" "[no]prompt" "hide")) - ("a[ppend]") - ("archive log" - (font-lock-keyword-face "list" "stop" "start" "next" "all" "to")) - ("attribute" - (font-lock-keyword-face "ali[as]" "cle[ar]" "for[mat]" "like" "on" "off")) - ("bre[ak]" - (font-lock-keyword-face "on" "row" "report" "ski[p]" "page" "nodup[licates]" "dup[licates]")) - ("bti[tle]" - (font-lock-keyword-face "on" "off") - (font-lock-builtin-face "bold" "ce[nter]" "col" "format" "le[ft]" "r[ight]" "s[kip]" "tab")) - ("c[hange]") - ("cl[ear]" - (font-lock-keyword-face "bre[aks]" "buff[er]" "col[umns]" "comp[utes]" "scr[een]" "sql" "timi[ng]")) - ("col[umn]" - (font-lock-keyword-face "ali[as]" "cle[ar]" "entmap" "on" "off" "fold_a[fter]" "fold_b[efore]" "for[mat]" "hea[ding]" - "jus[tify]" "l[eft]" "c[enter]" "r[ight]" "like" "newl[ine]" "new_v[alue]" "nopri[nt]" "pri[nt]" - "nul[l]" "old_v[alue]" "wra[pped]" "wor[d_wrapped]" "tru[ncated]")) - ("comp[ute]" - (font-lock-keyword-face "lab[el]" "of" "on" "report" "row") - (font-lock-builtin-face "avg" "cou[nt]" "min[imum]" "max[imum]" "num[ber]" "sum" "std" "var[iance]")) - ("conn[ect]" - (font-lock-keyword-face "as" "sysoper" "sysdba")) - ("copy") - ("def[ine]") - ("del" - (font-lock-keyword-face "last")) - ("desc[ribe]") - ("disc[onnect]") - ("ed[it]") - ("exec[ute]") - (("exit" "quit") - (font-lock-keyword-face "success" "failure" "warning" "commit" "rollback")) - ("get" - (font-lock-keyword-face "file" "lis[t]" "nol[ist]")) - ("help") - (("ho[st]" "!" "$")) - ("i[nput]") - ("l[ist]" - (font-lock-keyword-face "last")) - ("passw[ord]") - ("pau[se]") - ("pri[nt]") - ("pro[mpt]") - ("recover" - (font-lock-keyword-face "begin" "end" "backup" "automatic" "from" "logfile" "test" "allow" "corruption" "continue" "default" "cancel" - "standby" "database" "until" "time" "change" "using" "controlfile" "tablespace" "datafile" - "consistent" "with" "[no]parallel" "managed" "disconnect" "session" "[no]timeout" "[no]delay" "next" "no" "expire" - "current" "through" "thread" "sequence" "all" "archivelog" "last" "switchover" "immediate" "[no]wait" - "finish" "skip")) - ("rem[ark]") - ("repf[ooter]" - (font-lock-keyword-face "page" "on" "off") - (font-lock-builtin-face "bold" "ce[nter]" "col" "format" "le[ft]" "r[ight]" "s[kip]" "tab")) - ("reph[eader]" - (font-lock-keyword-face "page" "on" "off") - (font-lock-builtin-face "bold" "ce[nter]" "col" "format" "le[ft]" "r[ight]" "s[kip]" "tab")) - ("sav[e]" - (font-lock-keyword-face "file" "cre[ate]" "rep[lace]" "app[end]")) - ("set" - (font-lock-builtin-face sqlplus-system-variables) - (font-lock-keyword-face "on" "off" "immediate" "trace[only]" "explain" "statistics" "native" "v7" "v8" "all" "linenum" "indent" - "entry" "intermediate" "full" "local" "head" "html" "body" "table" "entmap" "spool" "[pre]format" - "none" "[word_]wrapped" "each" "truncated" "[in]visible" "mixed" "lower" "upper")) - ("sho[w]" - (font-lock-keyword-face "all" "bti[tle]" "err[ors]" "function" "procedure" "package[ body]" "trigger" "view" "type[ body]" - "dimension" "java class" "lno" "parameters" "pno" "recyc[lebin]" "rel[ease]" "repf[ooter]" "reph[eader]" - "sga" "spoo[l]" "sqlcode" "tti[tle]" "user") - (font-lock-builtin-face sqlplus-system-variables)) - ("shutdown" - (font-lock-keyword-face "abort" "immediate" "normal" "transactional" "local")) - ("spo[ol]" - ("cre" "create" "rep" "replace" "app" "append" "off" "out")) - ("sta[rt]") - ("startup" - (font-lock-keyword-face "force" "restrict" "pfile" "quiet" "mount" "open" "nomount" "read" "only" "write" "recover")) - ("store" - (font-lock-keyword-face "set" "cre[ate]" "rep[lace]" "app[end]")) - ("timi[ng]" - (font-lock-keyword-face "start" "show" "stop")) - ("tti[tle]" - (font-lock-keyword-face "tti[tle]" "on" "off") - (font-lock-builtin-face "bold" "ce[nter]" "col" "format" "le[ft]" "r[ight]" "s[kip]" "tab")) - ("undef[ine]") - ("var[iable]" - (font-lock-type-face "number" "[n]char" "byte" "[n]varchar2" "[n]clob" "refcursor" "binary_float" "binary_double")) - ("whenever oserror" - (font-lock-keyword-face "exit" "success" "failure" "commit" "rollback" "continue" "commit" "rollback" "none")) - ("whenever sqlerror" - (font-lock-keyword-face "exit" "success" "failure" "warning" "commit" "rollback" "continue" "none")))) - -(defvar plsql-mode-map nil) - -(defstruct sqlplus-global-struct - font-lock-regexps - objects-alist - side-view-buffer - root-dir -) - -(defvar sqlplus-global-structures (make-hash-table :test 'equal) - "Connect string -> sqlplus-global-struct") - -(defun sqlplus-get-objects-alist (&optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (sqlplus-global-struct-objects-alist struct)))) - -(defun sqlplus-set-objects-alist (objects-alist &optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (setf (sqlplus-global-struct-objects-alist struct) objects-alist)))) - -(defun sqlplus-get-font-lock-regexps (&optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (sqlplus-global-struct-font-lock-regexps struct)))) - -(defun sqlplus-set-font-lock-regexps (font-lock-regexps &optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (setf (sqlplus-global-struct-font-lock-regexps struct) font-lock-regexps)))) - -(defun sqlplus-get-side-view-buffer (&optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (sqlplus-global-struct-side-view-buffer struct)))) - -(defun sqlplus-get-root-dir (&optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (sqlplus-global-struct-root-dir struct)))) - -(defun sqlplus-set-root-dir (root-dir &optional connect-string) - (let ((struct (gethash (car (refine-connect-string (or connect-string sqlplus-connect-string sqlplus-process-p))) - sqlplus-global-structures))) - (when struct - (setf (sqlplus-global-struct-root-dir struct) root-dir)))) - -;;; --- - -(defun sqlplus-initial-strings () - (append sqlplus-initial-strings - (list - (concat "btitle left '" sqlplus-page-separator "'") - (concat "repfooter left '" sqlplus-repfooter "'") - (concat "set pagesize " (number-to-string sqlplus-pagesize))))) - -(defun sqlplus-connect-string-lessp (cs1 cs2) - "Compare two connect strings" - (let ((cs1-pair (split-string cs1 "@")) - (cs2-pair (split-string cs2 "@"))) - (or (string< (cadr cs1-pair) (cadr cs2-pair)) - (and (string= (cadr cs1-pair) (cadr cs2-pair)) - (string< (car cs1-pair) (car cs2-pair)))))) - -(defun sqlplus-divide-connect-strings () - "Returns (active-connect-string-list . inactive-connect-string-list)" - (let* ((active-connect-strings - (sort (delq nil (mapcar (lambda (buffer) - (with-current-buffer buffer - (when (and (eq major-mode 'sqlplus-mode) - sqlplus-connect-string) - (let ((cs (car (refine-connect-string sqlplus-connect-string)))) - (when (and (get-buffer (sqlplus-get-process-buffer-name cs)) - (get-process (sqlplus-get-process-name cs))) - (downcase cs)))))) - (buffer-list))) - 'sqlplus-connect-string-lessp)) - (inactive-connect-strings - (sort (delq nil (mapcar (lambda (pair) - (unless (member (downcase (car pair)) active-connect-strings) (downcase (car pair))) ) - sqlplus-connect-strings-alist)) - 'sqlplus-connect-string-lessp))) - (setq active-connect-strings (remove-duplicates active-connect-strings :test 'equal)) - (setq inactive-connect-strings (remove-duplicates inactive-connect-strings :test 'equal)) - (cons active-connect-strings inactive-connect-strings))) - -(defun sqlplus-connections-menu (menu) - (condition-case err - (let* ((connect-strings-pair (sqlplus-divide-connect-strings)) - (active-connect-strings (car connect-strings-pair)) - (inactive-connect-strings (cdr connect-strings-pair))) - (append - (list ["New connection..." sqlplus t]) - (list ["Tnsnames.ora" sqlplus-find-tnsnames t]) - (list ["Command Line" sqlplus-command-line t]) - (when (eq major-mode 'sqlplus-mode) - (list - "----" - ["Evaluate Statement" sqlplus-send-current sqlplus-connect-string] - ["Explain Statement" sqlplus-explain sqlplus-connect-string] - ["Evaluate Statement (HTML)" sqlplus-send-current-html sqlplus-connect-string] - ["Evaluate Region" sqlplus-send-region (and (mark) sqlplus-connect-string)])) - (when orcl-mode - (list - "----" - ["Send Commit" sqlplus-send-commit sqlplus-connect-string] - ["Send Rollback" sqlplus-send-rollback sqlplus-connect-string] - ["Restart Connection" sqlplus-restart-connection sqlplus-connect-string] - ["Show History" sqlplus-show-history sqlplus-connect-string] - ["Get Source from DB" sqlplus-get-source sqlplus-connect-string] - ["Interrupt Evaluation" sqlplus-send-interrupt sqlplus-connect-string] - ["Compare schema to filesystem" sqlplus-compare-schema-to-filesystem sqlplus-connect-string] - "----" - (list "Output" - ["Show window" sqlplus-buffer-display-window t] - "----" - ["Redisplay" sqlplus-buffer-redisplay-current t] - ["Previous" sqlplus-buffer-prev-command t] - ["Next" sqlplus-buffer-next-command t] - "----" - ["Scroll Right" sqlplus-buffer-scroll-right t] - ["Scroll Left" sqlplus-buffer-scroll-left t] - ["Scroll Down" sqlplus-buffer-scroll-down t] - ["Scroll Up" sqlplus-buffer-scroll-up t] - "----" - ["Bottom" sqlplus-buffer-bottom t] - ["Top" sqlplus-buffer-top t] - "----" - ["Erase" sqlplus-buffer-erase t]) - )) - (when inactive-connect-strings - (append - (list "----") - (list (append (list "Recent Connections") - (mapcar (lambda (connect-string) - (vector connect-string (list 'apply ''sqlplus - (list 'sqlplus-read-connect-string connect-string)) t)) inactive-connect-strings))))) - (when active-connect-strings - (append - (list "----") - (mapcar (lambda (connect-string) - (vector connect-string (list 'apply ''sqlplus - (list 'sqlplus-read-connect-string connect-string)) t)) active-connect-strings))) - )) - (error (message (error-message-string err))))) - -(defun sqlplus-send-commit () - "Send 'commit' command to SQL*Process." - (interactive) - (sqlplus-check-connection) - (sqlplus-execute sqlplus-connect-string "commit;" nil nil)) - -(defun sqlplus-send-rollback () - "Send 'rollback' command to SQL*Process." - (interactive) - (sqlplus-check-connection) - (sqlplus-execute sqlplus-connect-string "rollback;" nil nil)) - -(defun sqlplus-show-history () - "Show command history for current connection." - (interactive) - (sqlplus-check-connection) - (sqlplus-verify-buffer sqlplus-connect-string) - (switch-to-buffer (sqlplus-get-history-buffer sqlplus-connect-string))) - -(defun sqlplus-restart-connection () - "Kill SQL*Plus process and start again." - (interactive) - (sqlplus-check-connection) - (sqlplus-verify-buffer sqlplus-connect-string) - (let ((connect-stringos sqlplus-connect-string)) - (unwind-protect - (progn - (setq sqlplus-kill-function-inhibitor t) - (sqlplus-shutdown connect-stringos t)) - (setq sqlplus-kill-function-inhibitor nil)) - (sqlplus connect-stringos (sqlplus-get-input-buffer-name connect-stringos)))) - -(define-skeleton plsql-begin - "begin..end skeleton" - "" ; interactor - "begin" ?\n - > _ ?\n - "end;" >) - -(define-skeleton plsql-loop - "loop..end loop skeleton" - "" ; interactor - "loop" ?\n - > _ ?\n - "end loop;" >) - -(define-skeleton plsql-if - "if..end if skeleton" - "" ; interactor - "if " _ " then" ?\n - > ?\n - "end if;" >) - -;;; SQLPLUS-mode Keymap - - -(unless orcl-mode-map - (setq orcl-mode-map (make-sparse-keymap)) - (define-key orcl-mode-map "\C-c\C-o" 'sqlplus-buffer-display-window) - (define-key orcl-mode-map "\C-c\C-l" 'sqlplus-buffer-redisplay-current) - (define-key orcl-mode-map "\C-c\C-p" 'sqlplus-buffer-prev-command) - (define-key orcl-mode-map [C-S-up] 'sqlplus-buffer-prev-command) - (define-key orcl-mode-map "\C-c\C-n" 'sqlplus-buffer-next-command) - (define-key orcl-mode-map [C-S-down] 'sqlplus-buffer-next-command) - (define-key orcl-mode-map "\C-c\C-b" 'sqlplus-buffer-scroll-right) - (define-key orcl-mode-map [C-S-left] 'sqlplus-buffer-scroll-right) - (define-key orcl-mode-map "\C-c\C-f" 'sqlplus-buffer-scroll-left) - (define-key orcl-mode-map [C-S-right] 'sqlplus-buffer-scroll-left) - (define-key orcl-mode-map "\C-c\M-v" 'sqlplus-buffer-scroll-down) - (define-key orcl-mode-map "\C-c\C-v" 'sqlplus-buffer-scroll-up) - (define-key orcl-mode-map "\C-c>" 'sqlplus-buffer-bottom) - (define-key orcl-mode-map "\C-c<" 'sqlplus-buffer-top) - (define-key orcl-mode-map "\C-c\C-w" 'sqlplus-buffer-erase) - (define-key orcl-mode-map "\C-c\C-m" 'sqlplus-send-commit) - (define-key orcl-mode-map "\C-c\C-a" 'sqlplus-send-rollback) - (define-key orcl-mode-map "\C-c\C-k" 'sqlplus-restart-connection) - (define-key orcl-mode-map "\C-c\C-t" 'sqlplus-show-history) - (define-key orcl-mode-map "\C-c\C-s" 'sqlplus-get-source) - (define-key orcl-mode-map "\C-c\C-i" 'sqlplus-send-interrupt) - (define-key orcl-mode-map [S-return] 'sqlplus-send-user-string) - (define-key orcl-mode-map [tool-bar sqlplus-restart-connection] - (list 'menu-item "Restart connection" 'sqlplus-restart-connection :image sqlplus-kill-image)) - (define-key orcl-mode-map [tool-bar sqlplus-cancel] - (list 'menu-item "Cancel" 'sqlplus-send-interrupt :image sqlplus-cancel-image)) - (define-key orcl-mode-map [tool-bar sqlplus-rollback] - (list 'menu-item "Rollback" 'sqlplus-send-rollback :image sqlplus-rollback-image)) - (define-key orcl-mode-map [tool-bar sqlplus-commit] - (list 'menu-item "Commit" 'sqlplus-send-commit :image sqlplus-commit-image))) - -(unless sqlplus-mode-map - (setq sqlplus-mode-map (make-sparse-keymap)) - (define-key sqlplus-mode-map "\C-c\C-g" 'plsql-begin) - (define-key sqlplus-mode-map "\C-c\C-q" 'plsql-loop) - (define-key sqlplus-mode-map "\C-c\C-z" 'plsql-if) - (define-key sqlplus-mode-map "\C-c\C-r" 'sqlplus-send-region) - (define-key sqlplus-mode-map [C-return] 'sqlplus-send-current) - (define-key sqlplus-mode-map [M-return] 'sqlplus-explain) - (define-key sqlplus-mode-map "\C-c\C-e" 'sqlplus-send-current) - (define-key sqlplus-mode-map "\C-c\C-j" 'sqlplus-send-current-html) - (define-key sqlplus-mode-map [C-S-return] 'sqlplus-send-current-html) - (define-key sqlplus-mode-map "\M-." 'sqlplus-file-get-source) - (define-key sqlplus-mode-map [C-down-mouse-1] 'sqlplus-mouse-select-identifier) - (define-key sqlplus-mode-map [C-mouse-1] 'sqlplus-file-get-source-mouse) - ) - -(easy-menu-add-item nil nil sqlplus-connections-menu t) - -(unless sqlplus-mode-syntax-table - (setq sqlplus-mode-syntax-table (make-syntax-table)) - (modify-syntax-entry ?/ ". 14" sqlplus-mode-syntax-table) ; comment start - (modify-syntax-entry ?* ". 23" sqlplus-mode-syntax-table) - (modify-syntax-entry ?+ "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?. "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?\" "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?\\ "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?- ". 12b" sqlplus-mode-syntax-table) - (modify-syntax-entry ?\n "> b" sqlplus-mode-syntax-table) - (modify-syntax-entry ?= "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?% "w" sqlplus-mode-syntax-table) - (modify-syntax-entry ?< "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?> "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?& "w" sqlplus-mode-syntax-table) - (modify-syntax-entry ?| "." sqlplus-mode-syntax-table) - (modify-syntax-entry ?_ "w" sqlplus-mode-syntax-table) ; _ is word char - (modify-syntax-entry ?\' "\"" sqlplus-mode-syntax-table)) - -;;; SQL*Plus mode - -(defun connect-string-to-string () - (let ((txt (or (car (refine-connect-string sqlplus-connect-string)) "disconnected")) - (result)) - (if (string-match "^\\(.*?\\)\\(\\w*prod\\w*\\)$" txt) - (if (>= emacs-major-version 22) - (setq result (list (list :propertize (substring txt 0 (match-beginning 2)) 'face '((:foreground "blue"))) - (list :propertize (substring txt (match-beginning 2)) 'face '((:foreground "red")(:weight bold))))) - (setq result (setq txt (propertize txt 'face '((:foreground "blue"))))) - (put-text-property (match-beginning 2) (match-end 2) 'face '((:foreground "red")(:weight bold)) txt)) - (setq result - (if (>= emacs-major-version 22) - (list :propertize txt 'face '((:foreground "blue"))) - (setq txt (propertize txt 'face '((:foreground "blue"))))))) - result)) - -(defun sqlplus-font-lock (type-symbol limit) - (let ((sqlplus-font-lock-regexps (sqlplus-get-font-lock-regexps))) - (when sqlplus-font-lock-regexps - (let ((regexp (gethash type-symbol sqlplus-font-lock-regexps))) - (when regexp - (re-search-forward regexp limit t)))))) - -;; Local in input buffer (sqlplus-mode) -(defvar sqlplus-command-overlay nil) -(make-variable-buffer-local 'sqlplus-command-overlay) -(defvar sqlplus-begin-command-overlay-arrow-position nil) -(make-variable-buffer-local 'sqlplus-begin-command-overlay-arrow-position) -(defvar sqlplus-end-command-overlay-arrow-position nil) -(make-variable-buffer-local 'sqlplus-end-command-overlay-arrow-position) - -(defun sqlplus-highlight-current-sqlplus-command() - (when (and window-system sqlplus-command-highlighting-style) - (let* ((pair (sqlplus-mark-current)) - (begin (and (car pair) (save-excursion (goto-char (car pair)) (skip-chars-forward " \t\n") (point)))) - (end (and (cdr pair) (save-excursion (goto-char (cdr pair)) (skip-chars-backward " \t\n") (beginning-of-line) (point)))) - (point-line-beg (save-excursion (beginning-of-line) (point))) - (overlay-begin begin) - (overlay-end end)) - (when (and begin end) - (when (< end point-line-beg) - (save-excursion (goto-char point-line-beg) (when (eobp) (insert "\n"))) - (setq end point-line-beg) - (setq overlay-end end)) - (when (or (>= begin end) (< (point) begin)) - (when (or (< (point) begin) (> begin end)) - (setq overlay-begin nil - overlay-end nil)) - (setq begin nil - end nil))) - (if (and overlay-begin overlay-end (memq sqlplus-command-highlighting-style '(background fringe-and-background))) - (progn - (setq overlay-end (save-excursion - (goto-char overlay-end) - (beginning-of-line 2) - (point))) - (move-overlay sqlplus-command-overlay overlay-begin overlay-end)) - (move-overlay sqlplus-command-overlay 1 1)) - (if (memq sqlplus-command-highlighting-style '(fringe fringe-and-background)) - (progn - (put 'sqlplus-begin-command-overlay-arrow-position 'overlay-arrow-bitmap 'top-left-angle) - (put 'sqlplus-end-command-overlay-arrow-position 'overlay-arrow-bitmap 'bottom-left-angle) - (set-marker sqlplus-begin-command-overlay-arrow-position begin) - (set-marker sqlplus-end-command-overlay-arrow-position end)) - (set-marker sqlplus-begin-command-overlay-arrow-position nil) - (set-marker sqlplus-end-command-overlay-arrow-position nil))))) - -(defun sqlplus-find-begin-of-sqlplus-command () - (save-excursion - (beginning-of-line) - (while (and (not (bobp)) (save-excursion (end-of-line 0) (skip-chars-backward " \t") (equal (char-before) ?-))) - (beginning-of-line 0)) - (point))) - -(defun sqlplus-find-end-of-sqlplus-command () - (save-excursion - (end-of-line) - (while (progn (skip-chars-backward " \t") (and (not (eobp)) (equal (char-before) ?-))) - (end-of-line 2)) - (point))) - -(defun sqlplus-set-font-lock-emacs-structures-for-level (level mode-symbol) - (let ((result (append sql-mode-oracle-font-lock-keywords - (default-value (cond ((equal level 3) 'sqlplus-font-lock-keywords-3) - ((equal level 2) 'sqlplus-font-lock-keywords-2) - ((equal level 1) 'sqlplus-font-lock-keywords-1) - (t nil)))))) - (when (featurep 'plsql) - (setq result (append (symbol-value 'plsql-oracle-font-lock-fix-re) result))) - (setq result - (append - ;; Names for schemas, tables, synonyms, views, columns, sequences, packages, triggers and indexes - (when (> level 2) - (mapcar (lambda (pair) - (let ((type-symbol (car pair)) - (face (cadr pair))) - (cons (eval `(lambda (limit) (sqlplus-font-lock ',type-symbol limit))) face))) - sqlplus-syntax-faces)) - ;; SQL*Plus - (when (eq mode-symbol 'sqlplus-mode) - (unless sqlplus-commands-regexp-1 - (flet ((first-form-fun (cmds) (mapcar (lambda (name) (car (sqlplus-full-forms name))) cmds)) - (all-forms-fun (cmds) (mapcan 'sqlplus-full-forms cmds)) - (sqlplus-commands-regexp-fun (form-fun cmds) (concat "^" (regexp-opt (funcall form-fun cmds) t) "\\b")) - (sqlplus-system-variables-fun (form-fun vars) (concat "\\b" (regexp-opt (funcall form-fun vars) t) "\\b"))) - (flet ((sqlplus-v22-commands-font-lock-keywords-fun - (form-fun) - (delq nil - (mapcar - (lambda (command-info) - (let* ((names (car command-info)) - (names-list (if (listp names) names (list names))) - (sublists (cdr command-info))) - (when sublists - (append (list (sqlplus-commands-regexp-fun form-fun names-list)) - (mapcar (lambda (sublist) - (let ((face (car sublist)) - (regexp (concat "\\b" - (regexp-opt (mapcan (lambda (name) (sqlplus-full-forms name)) - (mapcan (lambda (elem) - (if (symbolp elem) - (copy-list (symbol-value elem)) - (list elem))) - (cdr sublist))) - t) - "\\b"))) - (list regexp '(sqlplus-find-end-of-sqlplus-command) nil (list 1 face)))) - sublists) - (list '("\\(\\w+\\)" (sqlplus-find-end-of-sqlplus-command) nil (1 font-lock-sqlplus-face))))))) - sqlplus-commands)))) - (let ((commands (mapcan - (lambda (command-info) (let ((names (car command-info))) (if (listp names) (copy-list names) (list names)))) - sqlplus-commands))) - (setq sqlplus-commands-regexp-1 (sqlplus-commands-regexp-fun 'first-form-fun commands)) - (setq sqlplus-commands-regexp-23 (sqlplus-commands-regexp-fun 'all-forms-fun commands)) - (if (<= emacs-major-version 21) - (setq sqlplus-system-variables-regexp-1 (sqlplus-system-variables-fun 'first-form-fun sqlplus-system-variables) - sqlplus-system-variables-regexp-23 (sqlplus-system-variables-fun 'all-forms-fun sqlplus-system-variables)) - (setq sqlplus-v22-commands-font-lock-keywords-1 (sqlplus-v22-commands-font-lock-keywords-fun 'first-form-fun) - sqlplus-v22-commands-font-lock-keywords-23 (sqlplus-v22-commands-font-lock-keywords-fun 'all-forms-fun))))))) - (append (list - ;; Comments (REM command) - (cons "^\\(rem\\)\\b\\(.*?\\)$" '((1 font-lock-keyword-face nil nil) (2 font-lock-comment-face t nil))) - ;; Predefined SQL*Plus variables - (cons (concat "\\b" - (regexp-opt '("_CONNECT_IDENTIFIER" "_DATE" "_EDITOR" "_O_VERSION" "_O_RELEASE" "_PRIVILEGE" - "_SQLPLUS_RELEASE" "_USER") t) - "\\b") - 'font-lock-builtin-face) - ;; SQL*Plus commands (+ shortcuts if level >= 2) - (cons - (concat (if (>= level 2) sqlplus-commands-regexp-23 sqlplus-commands-regexp-1) "\\|^\\(@@\\|@\\|!\\|/\\|\\$\\)" ) - 'font-lock-keyword-face)) - (if (<= emacs-major-version 21) - ;; SQL*Plus system variables (+ shortcuts if level >= 2) - (list (cons (if (>= level 2) sqlplus-system-variables-regexp-23 sqlplus-system-variables-regexp-1) 'font-lock-builtin-face)) - ;; ver. >= 22 - (if (>= level 2) sqlplus-v22-commands-font-lock-keywords-23 sqlplus-v22-commands-font-lock-keywords-1)))) - ; (cons "\\b\\([a-zA-Z$_#0-9]+\\)\\b\\.\\(\\b[a-zA-Z$_#0-9]+\\b\\)" '((1 font-lock-type-face nil nil)(2 font-lock-variable-name-face nil nil))) - (list - ;; Extra Oracle syntax highlighting, not recognized by sql-mode or plsql-mode - (cons sqlplus-oracle-extra-types-re 'font-lock-type-face) - (cons sqlplus-oracle-extra-warning-words-re 'font-lock-warning-face) - (cons sqlplus-oracle-extra-types-re 'font-lock-type-face) - (cons sqlplus-oracle-extra-keywords-re 'font-lock-keyword-face) - (cons sqlplus-oracle-plsql-extra-reserved-words-re 'font-lock-keyword-face) - (if (string-match "XEmacs\\|Lucid" emacs-version) - (cons sqlplus-oracle-extra-pseudocolumns-re 'font-lock-preprocessor-face) - (cons sqlplus-oracle-extra-pseudocolumns-re 'font-lock-builtin-face)) - (if (string-match "XEmacs\\|Lucid" emacs-version) - (cons sqlplus-oracle-extra-builtin-functions-re 'font-lock-preprocessor-face) - (cons sqlplus-oracle-extra-builtin-functions-re 'font-lock-builtin-face)) - ;; SQL*Plus variable names, like '&name' or '&&name' - (cons "\\(\\b&[&a-zA-Z$_#0-9]+\\b\\)" 'font-lock-variable-name-face)) - result - ;; Function calls - (when (>= level 2) - (list (cons "\\b\\(\\([a-zA-Z$_#0-9]+\\b\\)\\.\\)?\\(\\b[a-zA-Z$_#0-9]+\\b\\)\\s-*(" - '((2 font-lock-type-face nil t) - (3 font-lock-function-name-face nil nil))))))) - result)) - -(defun sqlplus-mode nil - "Mode for editing and executing SQL*Plus commands. Entry into this mode runs the hook -'sqlplus-mode-hook'. - -Use \\[sqlplus] to start the SQL*Plus interpreter. - -Just position the cursor on or near the SQL*Plus statement you -wish to send and press '\\[sqlplus-send-current]' to run it and -display the results. - -Mode Specific Bindings: - -\\{sqlplus-mode-map}" - (interactive) - (run-hooks 'change-major-mode-hook) - (setq major-mode 'sqlplus-mode - mode-name "SQL*Plus") - (use-local-map sqlplus-mode-map) - (set-syntax-table sqlplus-mode-syntax-table) - (make-local-variable 'comment-start) - (make-local-variable 'comment-end) - (setq comment-start "/* " - comment-end " */") - (orcl-mode 1) - (setq sqlplus-font-lock-keywords-1 (sqlplus-set-font-lock-emacs-structures-for-level 1 major-mode) - sqlplus-font-lock-keywords-2 (sqlplus-set-font-lock-emacs-structures-for-level 2 major-mode) - sqlplus-font-lock-keywords-3 (sqlplus-set-font-lock-emacs-structures-for-level 3 major-mode)) - (when (featurep 'plsql) - (set (make-local-variable 'indent-line-function) - (lambda () (interactive) (condition-case err (funcall (symbol-function 'plsql-indent)) (error (message "Error: %S" err))))) - (set (make-local-variable 'indent-region-function) 'plsql-indent-region) - (set (make-local-variable 'align-mode-rules-list) 'plsql-align-rules-list)) - (setq font-lock-defaults sqlplus-font-lock-defaults) - (unless sqlplus-connect-string - (let ((potential-connect-string (sqlplus-get-potential-connect-string (buffer-file-name)))) - (when (and potential-connect-string - (get-process (sqlplus-get-process-name potential-connect-string))) - (setq sqlplus-connect-string potential-connect-string)))) - (set (make-local-variable 'font-lock-extend-after-change-region-function) - (lambda (beg end old-len) - (cons (save-excursion (goto-char beg) (sqlplus-find-begin-of-sqlplus-command)) - (save-excursion (goto-char end) (sqlplus-find-end-of-sqlplus-command))))) - (unless font-lock-sqlplus-face - (copy-face 'default 'font-lock-sqlplus-face) - (setq font-lock-sqlplus-face 'font-lock-sqlplus-face)) - (turn-on-font-lock) - (unless frame-background-mode - (setq frame-background-mode (if (< (sqlplus-color-percentage (face-background 'default)) 50) 'dark 'light))) - (setq imenu-generic-expression '((nil "^--[ ]*\\([^;.\n]*\\)" 1))) - ;; if input buffer has sqlplus-mode then prepare it for command under cursor selection - (when (and (eq major-mode 'sqlplus-mode) (null sqlplus-begin-command-overlay-arrow-position)) - (setq sqlplus-begin-command-overlay-arrow-position (make-marker) - sqlplus-end-command-overlay-arrow-position (make-marker) - sqlplus-command-overlay (make-overlay 1 1)) - (overlay-put sqlplus-command-overlay 'face 'sqlplus-command-highlight-face) - (when (and (>= emacs-major-version 22) (not (memq 'sqlplus-begin-command-overlay-arrow-position overlay-arrow-variable-list))) - (push 'sqlplus-begin-command-overlay-arrow-position overlay-arrow-variable-list)) - (when (and (>= emacs-major-version 22) (not (memq 'sqlplus-end-command-overlay-arrow-position overlay-arrow-variable-list))) - (push 'sqlplus-end-command-overlay-arrow-position overlay-arrow-variable-list)) - (add-hook 'pre-command-hook (lambda () - (set-marker sqlplus-begin-command-overlay-arrow-position nil) - (set-marker sqlplus-end-command-overlay-arrow-position nil)) - nil t) - (add-hook 'post-command-hook (lambda () - (sqlplus-clear-mouse-selection) - (set-marker sqlplus-begin-command-overlay-arrow-position nil) - (set-marker sqlplus-end-command-overlay-arrow-position nil)) - nil t)) - (run-hooks 'sqlplus-mode-hook)) - -(defun sqlplus-color-percentage (color) - (truncate (* (/ (/ (reduce '+ (color-values color)) 3.0) 65535.0) 100.0))) - -(defun sqlplus-get-potential-connect-string (file-path) - (when file-path - (let* ((file-name (file-name-nondirectory file-path)) - (extension (file-name-extension file-name)) - (case-fold-search t)) - (when (and extension - (string-match (concat "^" sqlplus-session-file-extension "$") extension) - (string-match "@" file-name)) - (car (refine-connect-string (file-name-sans-extension file-name))))))) - -(defun sqlplus-check-connection () - (if orcl-mode - (unless sqlplus-connect-string - (let* ((potential-connect-string (sqlplus-get-potential-connect-string (buffer-file-name))) - (connect-string (car (sqlplus-read-connect-string nil (or potential-connect-string - (caar (sqlplus-divide-connect-strings))))))) - (sqlplus connect-string (buffer-name)))) - (error "Current buffer is not determined to communicate with Oracle"))) - -;;; Utilitities - -(defun sqlplus-echo-in-buffer (buffer-name string &optional force-display hide-after-head) - "Displays string in the named buffer, creating the buffer if needed. If force-display is true, the buffer will appear -if not already shown." - (let ((buffer (get-buffer buffer-name))) - (when buffer - (if force-display (display-buffer buffer)) - (with-current-buffer buffer - (while (and (> (buffer-size) sqlplus-output-buffer-max-size) - (progn (goto-char (point-min)) - (unless (eobp) (forward-char)) - (re-search-forward (concat "^" (regexp-quote sqlplus-output-separator)) nil t))) - (delete-region 1 (- (point) (length sqlplus-output-separator)))) - - (goto-char (point-max)) - (let ((start-point (point))) - (insert string) - (when hide-after-head - (let ((from-pos (string-match "\n" string)) - (keymap (make-sparse-keymap)) - overlay) - (when from-pos - (setq overlay (make-overlay (+ start-point from-pos) (- (+ start-point (length string)) 2))) - (when (or (not (consp buffer-invisibility-spec)) - (not (assq 'hide-symbol buffer-invisibility-spec))) - (add-to-invisibility-spec '(hide-symbol . t))) - (overlay-put overlay 'invisible 'hide-symbol) - (put-text-property start-point (- (+ start-point (length string)) 2) 'help-echo string) - (put-text-property start-point (- (+ start-point (length string)) 2) 'mouse-face 'highlight) - (put-text-property start-point (- (+ start-point (length string)) 2) 'keymap sqlplus-output-buffer-keymap))))) - (if force-display - (set-window-point (get-buffer-window buffer-name) (point-max))))))) - -(defun sqlplus-verify-buffer (connect-string) - (let ((output-buffer-name (sqlplus-get-output-buffer-name connect-string)) - (process-buffer-name (sqlplus-get-process-buffer-name connect-string))) - (when (not (get-buffer process-buffer-name)) - (sqlplus-shutdown connect-string) - (error "No SQL*Plus session! Use 'M-x sqlplus' to start the SQL*Plus interpreter")) - (unless (get-buffer-process process-buffer-name) - (sqlplus-shutdown connect-string) - (error "Buffer '%s' is not talking to anybody!" output-buffer-name))) - t) - -(defun sqlplus-get-context (connect-string &optional id) - (let ((process-buffer (sqlplus-get-process-buffer-name connect-string))) - (when process-buffer - (with-current-buffer process-buffer - (when id - (while (and sqlplus-command-contexts - (not (equal (sqlplus-get-context-value (car sqlplus-command-contexts) :id) id))) - (setq sqlplus-command-contexts (cdr sqlplus-command-contexts)))) - (car sqlplus-command-contexts))))) - -(defun sqlplus-get-context-value (context var-symbol) - (cdr (assq var-symbol context))) - -(defun sqlplus-set-context-value (context var-symbol value) - (let ((association (assq var-symbol context))) - (if association - (setcdr association value) - (setcdr context (cons (cons var-symbol value) (cdr context)))) - context)) - -(defun sqlplus-mark-current () - "Marks the current SQL for sending to the SQL*Plus process. Marks are placed around a region defined by empty lines." - (let (begin end empty-line-p empty-line-p next-line-included tail-p) - (save-excursion - (beginning-of-line) - (setq empty-line-p (when (looking-at "^[ \t]*\\(\n\\|\\'\\)") (point))) - (setq next-line-included (and empty-line-p (save-excursion (skip-chars-forward " \t\n") (> (current-column) 0)))) - (setq tail-p (and empty-line-p - (or (bobp) (save-excursion (beginning-of-line 0) (looking-at "^[ \t]*\n")))))) - (unless tail-p - (save-excursion - (end-of-line) - (re-search-backward "\\`\\|\n[\r\t ]*\n[^ \t]" nil t) - (skip-syntax-forward "-") - (setq begin (point))) - (save-excursion - (beginning-of-line) - (re-search-forward "\n[\r\t ]*\n[^ \t]\\|\\'" nil t) - (unless (zerop (length (match-string 0))) - (backward-char 1)) - (skip-syntax-backward "-") - (setq end (or (and (not next-line-included) empty-line-p) (point))))) - (cons begin end))) - -;;; Transmission Commands - -(defun sqlplus-send-current (arg &optional html) - "Send the current SQL command(s) to the SQL*Plus process. With argument, show results in raw form." - (interactive "P") - (sqlplus-check-connection) - (when (buffer-file-name) - (condition-case err - (save-buffer) - (error (message (error-message-string err))))) - (let ((region (sqlplus-mark-current))) - (setq sqlplus-region-beginning-pos (car region) - sqlplus-region-end-pos (cdr region))) - (if (and sqlplus-region-beginning-pos sqlplus-region-end-pos) - (sqlplus-send-region arg sqlplus-region-beginning-pos sqlplus-region-end-pos nil html) - (error "Point doesn't indicate any command to execute"))) - -(defun sqlplus-send-current-html (arg) - (interactive "P") - (sqlplus-send-current arg t)) - - -;;; SQLPLUS-Output Buffer Operations - - -(defun sqlplus--show-buffer (connect-string fcn args) - (let* ((output-buffer-name (sqlplus-get-output-buffer-name connect-string))) - (sqlplus-verify-buffer connect-string) - (if sqlplus-suppress-show-output-buffer - (with-current-buffer (get-buffer output-buffer-name) - (if fcn (condition-case err (apply fcn args) (error (message (error-message-string err)))))) - (if (not (eq (window-buffer (selected-window)) (get-buffer output-buffer-name))) - (switch-to-buffer-other-window output-buffer-name)) - (if fcn (condition-case err (apply fcn args) (error (message (error-message-string err)))))))) - -(defun sqlplus-show-buffer (&optional connect-string fcn &rest args) - "Makes the SQL*Plus output buffer visible in the other window." - (interactive) - (setq connect-string (or connect-string sqlplus-connect-string)) - (unless connect-string - (error "Current buffer is disconnected!")) - (let ((output-buffer-name (sqlplus-get-output-buffer-name connect-string))) - (if (and output-buffer-name - (eq (current-buffer) (get-buffer output-buffer-name))) - (sqlplus--show-buffer connect-string fcn args) - (save-excursion - (save-selected-window - (sqlplus--show-buffer connect-string fcn args)))))) - -(fset 'sqlplus-buffer-display-window 'sqlplus-show-buffer) - -(defun sqlplus-buffer-scroll-up (&optional connect-string) - "Scroll-up in the SQL*Plus output buffer window." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'scroll-up)) - -(defun sqlplus-buffer-scroll-down (&optional connect-string) - "Scroll-down in the SQL*Plus output buffer window." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'scroll-down)) - -(defun sqlplus-scroll-left (num) - (call-interactively 'scroll-left)) - -(defun sqlplus-scroll-right (num) - (call-interactively 'scroll-right)) - -(defun sqlplus-buffer-scroll-left (num &optional connect-string) - "Scroll-left in the SQL*Plus output buffer window." - (interactive "p") - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-scroll-left (* num (/ (window-width) 2)))) - -(defun sqlplus-buffer-scroll-right (num &optional connect-string) - "Scroll-right in the SQL*Plus output buffer window." - (interactive "p") - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-scroll-right (* num (/ (window-width) 2)))) - -(defun sqlplus-buffer-mark-current (&optional connect-string) - "Mark the current position in the SQL*Plus output window." - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-buffer-make-mark)) - -(defun sqlplus-buffer-make-mark (&optional connect-string) - "Set the sqlplus-buffer-marker." - (setq sqlplus-buffer-mark (copy-marker (point)))) - -(defun sqlplus-buffer-redisplay-current (&optional connect-string) - "Go to the current sqlplus-buffer-mark." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-goto-mark)) - -(defun sqlplus-goto-mark () - (goto-char sqlplus-buffer-mark) - (recenter 0)) - -(defun sqlplus-buffer-top (&optional connect-string) - "Goto the top of the SQL*Plus output buffer." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-beginning-of-buffer)) - -(defun sqlplus-beginning-of-buffer nil (goto-char (point-min))) - -(defun sqlplus-buffer-bottom (&optional connect-string) - "Goto the bottom of the SQL*Plus output buffer." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-end-of-buffer)) - -(defun sqlplus-end-of-buffer nil (goto-char (point-max)) (unless sqlplus-suppress-show-output-buffer (recenter -1))) - -(defun sqlplus-buffer-erase (&optional connect-string) - "Clear the SQL output buffer." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'erase-buffer)) - -(defun sqlplus-buffer-next-command (&optional connect-string) - "Search for the next command in the SQL*Plus output buffer." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-next-command)) - -(defun sqlplus-next-command nil - "Search for the next command in the SQL*Plus output buffer." - (cond ((re-search-forward (concat "^" (regexp-quote sqlplus-output-separator)) nil t) - (forward-line 2) - (recenter 0)) - (t (beep) (message "No more commands.")))) - -(defun sqlplus-buffer-prev-command (&optional connect-string) - "Search for the previous command in the SQL*Plus output buffer." - (interactive) - (sqlplus-show-buffer (or connect-string sqlplus-connect-string) 'sqlplus-previous-command)) - -(defun sqlplus-previous-command nil - "Search for the previous command in the SQL*Plus output buffer." - (let ((start (point))) - (re-search-backward (concat "^" (regexp-quote sqlplus-output-separator)) nil t) - (cond ((re-search-backward (concat "^" (regexp-quote sqlplus-output-separator)) nil t) - (forward-line 2) - (recenter 0)) - (t - (message "No more commands.") (beep) - (goto-char start))))) - -(defun sqlplus-send-interrupt nil - "Send an interrupt the the SQL*Plus interpreter process." - (interactive) - (sqlplus-check-connection) - (let ((connect-string sqlplus-connect-string)) - (sqlplus-verify-buffer connect-string) - (interrupt-process (get-process (sqlplus-get-process-name connect-string))))) - - -;;; SQL Interpreter - -(defun refine-connect-string (connect-string &optional no-slash) - "Z connect stringa do SQL*Plusa wycina haslo, tj. np. 'ponaglenia/x@SID' -> ('ponaglenia@SID' . 'x')." - (let (result passwd) - (when connect-string - (setq result - (if (string-match "\\(\\`[^@/]*?\\)/\\([^/@:]*\\)\\(.*?\\'\\)" connect-string) - (progn - (setq passwd (match-string 2 connect-string)) - (concat (match-string 1 connect-string) (match-string 3 connect-string))) - connect-string)) - (when no-slash - (while (string-match "/" result) - (setq result (replace-match "!" nil t result))))) - (cons result passwd))) - -(defun sqlplus-get-output-buffer-name (connect-string) - (concat "*" (car (refine-connect-string connect-string)) "*")) - -(defun sqlplus-get-input-buffer-name (connect-string) - (concat (car (refine-connect-string connect-string)) (concat "." sqlplus-session-file-extension))) - -(defun sqlplus-get-history-buffer-name (connect-string) - (concat " " (car (refine-connect-string connect-string)) "-hist")) - -(defun sqlplus-get-process-buffer-name (connect-string) - (concat " " (car (refine-connect-string connect-string)))) - -(defun sqlplus-get-process-name (connect-string) - (car (refine-connect-string connect-string))) - -(defun sqlplus-read-connect-string (&optional connect-string default-connect-string) - "Ask user for connect string with password, with DEFAULT-CONNECT-STRING proposed. -DEFAULT-CONNECT-STRING nil means first inactive connect-string on sqlplus-connect-strings-alist. -CONNECT-STRING non nil means ask for password only if CONNECT-STRING has no password itself. -Returns (qualified-connect-string refined-connect-string)." - (unless default-connect-string - (let ((inactive-connect-strings (cdr (sqlplus-divide-connect-strings)))) - (setq default-connect-string - (some (lambda (pair) - (when (member (car pair) inactive-connect-strings) (car pair))) - sqlplus-connect-strings-alist)))) - (let* ((cs (downcase (or connect-string - (read-string (format "Connect string%s: " (if default-connect-string (format " [default %s]" default-connect-string) "")) - nil 'sqlplus-connect-string-history default-connect-string)))) - (pair (refine-connect-string cs)) - (refined-cs (car pair)) - (password (cdr pair)) - (was-password password) - (association (assoc refined-cs sqlplus-connect-strings-alist))) - (unless (or password current-prefix-arg) - (setq password (cdr association))) - (unless password - (setq password (read-passwd (format "Password for %s: " cs)))) - (unless was-password - (if (string-match "@" cs) - (setq cs (replace-match (concat "/" password "@") t t cs)) - (setq cs (concat cs "/" password)))) - (list cs refined-cs))) - -(defun sqlplus (connect-string &optional input-buffer-name output-buffer-flag) - "Create SQL*Plus process connected to Oracle according to -CONNECT-STRING, open (or create) input buffer with specified -name (do not create if INPUT-BUFFER-NAME is nil). -OUTPUT-BUFFER-FLAG has meanings: nil or SHOW-OUTPUT-BUFFER - -create output buffer and show it, DONT-SHOW-OUTPUT-BUFFER - -create output buffer but dont show it, DONT-CREATE-OUTPUT-BUFFER -- dont create output buffer" - (interactive (let ((pair (sqlplus-read-connect-string))) - (list (car pair) (concat (cadr pair) (concat "." sqlplus-session-file-extension))))) - (set (make-local-variable 'comment-start-skip) "/\\*+ *\\|--+ *") - (set (make-local-variable 'comment-multi-line) t) - ;; create sqlplus-session-cache-dir if not exists - (when sqlplus-session-cache-dir - (condition-case err - (unless (file-directory-p sqlplus-session-cache-dir) - (make-directory sqlplus-session-cache-dir t)) - (error (message (error-message-string err))))) - (let* ((was-input-buffer (and input-buffer-name (get-buffer input-buffer-name))) - (input-buffer (or was-input-buffer - (when input-buffer-name - (if sqlplus-session-cache-dir - (let ((buf (find-file-noselect - (concat - (file-name-as-directory sqlplus-session-cache-dir) - (car (refine-connect-string connect-string t)) - (concat "." sqlplus-session-file-extension))))) - (condition-case nil - (with-current-buffer buf - (rename-buffer input-buffer-name)) - (error nil)) - buf) - (get-buffer-create input-buffer-name))))) - (output-buffer (or (and (not (eq output-buffer-flag 'dont-create-output-buffer)) - (get-buffer-create (sqlplus-get-output-buffer-name connect-string))) - (get-buffer (sqlplus-get-output-buffer-name connect-string)))) - (process-name (sqlplus-get-process-name connect-string)) - (process-buffer-name (sqlplus-get-process-buffer-name connect-string)) - (was-process (get-process process-name)) - process-created - (process (or was-process - (let (proc) - (puthash (car (refine-connect-string connect-string)) - (make-sqlplus-global-struct :font-lock-regexps (make-hash-table :test 'equal) - :side-view-buffer (when (featurep 'ide-skel) (sqlplus-create-side-view-buffer connect-string))) - sqlplus-global-structures) - ;; push current connect string to the beginning of sqlplus-connect-strings-alist - (let* ((refined-cs (refine-connect-string connect-string))) - (setq sqlplus-connect-strings-alist (delete* (car refined-cs) sqlplus-connect-strings-alist :test 'string= :key 'car)) - (push refined-cs sqlplus-connect-strings-alist)) - (sqlplus-get-history-buffer connect-string) - (when output-buffer - (with-current-buffer output-buffer - (erase-buffer))) - (setq process-created t - proc (start-process process-name process-buffer-name sqlplus-command connect-string)) - (set-process-sentinel proc (lambda (process event) - (let ((proc-buffer (buffer-name (process-buffer process))) - (output-buffer (get-buffer (sqlplus-get-output-buffer-name (process-name process)))) - err-msg - (exited-abnormally (string-match "\\`exited abnormally with code" event))) - (when output-buffer - (with-current-buffer output-buffer - (goto-char (point-max)) - (insert (format "\n%s" event)) - (when exited-abnormally - (setq sqlplus-connect-strings-alist - (delete* (car (refine-connect-string sqlplus-connect-string)) - sqlplus-connect-strings-alist :test 'string= :key 'car)) - (when proc-buffer - (with-current-buffer proc-buffer - (save-excursion - (goto-char (point-min)) - (when (re-search-forward "^ORA-[0-9]+.*$" nil t) - (setq err-msg (match-string 0)))) - (erase-buffer))) - (when err-msg - (insert (concat "\n" err-msg))))))))) - (process-kill-without-query proc (not sqlplus-kill-processes-without-query-on-exit-flag)) - (set-process-filter proc 'sqlplus-process-filter) - (with-current-buffer (get-buffer process-buffer-name) - (setq sqlplus-process-p connect-string)) - proc)))) - (when output-buffer - (with-current-buffer output-buffer - (orcl-mode 1) - (set (make-local-variable 'line-move-ignore-invisible) t) - (setq sqlplus-output-buffer-keymap (make-sparse-keymap) - sqlplus-connect-string connect-string - truncate-lines t) - (define-key sqlplus-output-buffer-keymap "\C-m" (lambda () (interactive) (sqlplus-output-buffer-hide-show))) - (define-key sqlplus-output-buffer-keymap [S-mouse-2] (lambda (event) (interactive "@e") (sqlplus-output-buffer-hide-show))) - (local-set-key [S-return] 'sqlplus-send-user-string))) - (when input-buffer - (with-current-buffer input-buffer - (setq sqlplus-connect-string connect-string))) - ;; if input buffer was created then switch it to sqlplus-mode - (when (and input-buffer (not was-input-buffer)) - (with-current-buffer input-buffer - (unless (eq major-mode 'sqlplus-mode) - (sqlplus-mode))) - (when font-lock-mode (font-lock-mode 1)) - (set-window-buffer (sqlplus-get-workbench-window) input-buffer)) - ;; if process was created then get information for font lock - (when process-created - (sqlplus-execute connect-string nil nil (sqlplus-initial-strings) 'no-echo) - (let ((plsql-font-lock-level (sqlplus-font-lock-value-in-major-mode font-lock-maximum-decoration 'plsql-mode)) - (sqlplus-font-lock-level (sqlplus-font-lock-value-in-major-mode font-lock-maximum-decoration 'sqlplus-mode))) - (when (or (equal plsql-font-lock-level t) (equal sqlplus-font-lock-level t) - (and (numberp plsql-font-lock-level) (>= plsql-font-lock-level 2)) - (and (numberp sqlplus-font-lock-level) (>= sqlplus-font-lock-level 2))) - (sqlplus-hidden-select connect-string - (concat "select distinct column_name, 'COLUMN', ' ' from user_tab_columns where column_name not like 'BIN$%'\n" - "union\n" - "select username, 'SCHEMA', ' ' from all_users where username not like 'BIN$%'\n" - "union\n" - "select object_name, object_type, decode( status, 'INVALID', 'I', ' ' ) from user_objects\n" - "where object_name not like 'BIN$%'\n" - "and object_type in ('VIEW', 'SEQUENCE', 'PACKAGE', 'TRIGGER', 'TABLE', 'SYNONYM', 'INDEX', 'FUNCTION', 'PROCEDURE');") - 'sqlplus-my-handler)))) - (when input-buffer - (save-selected-window - (when (equal (selected-window) (sqlplus-get-side-window)) - (select-window (sqlplus-get-workbench-window))) - (switch-to-buffer input-buffer))) - (let ((saved-window (cons (selected-window) (window-buffer (selected-window)))) - (input-buffer (get-buffer (sqlplus-get-input-buffer-name connect-string)))) - (when (or (eq output-buffer-flag 'show-output-buffer) (null output-buffer-flag)) - (sqlplus-show-buffer connect-string)) - (if (window-live-p (car saved-window)) - (select-window (car saved-window)) - (if (get-buffer-window (cdr saved-window)) - (select-window (get-buffer-window (cdr saved-window))) - (when (and input-buffer - (get-buffer-window input-buffer)) - (select-window (get-buffer-window input-buffer)))))) - ;; executing initial sequence (between /* init */ and /* end */) - (when (and (not was-process) input-buffer) - (with-current-buffer input-buffer - (save-excursion - (goto-char (point-min)) - (when (re-search-forward (concat "^" sqlplus-init-sequence-start-regexp "\\s-*\n\\(\\(.\\|\n\\)*?\\)\n" sqlplus-init-sequence-end-regexp) nil t) - (when (match-string 1) - (sqlplus-send-region nil (match-beginning 1) (match-end 1) t)))))))) - -;; Command under cursor selection mechanism -(when window-system - (run-with-idle-timer 0 t (lambda () (when (eq major-mode 'sqlplus-mode) (sqlplus-highlight-current-sqlplus-command)))) - (run-with-idle-timer 1 t (lambda () - (when (eq major-mode 'sqlplus-mode) - (if (>= (sqlplus-color-percentage (face-background 'default)) 50) - (set-face-attribute 'sqlplus-command-highlight-face nil - :background (sqlplus-shine-color (face-background 'default) (- sqlplus-command-highlighting-percentage))) - (set-face-attribute 'sqlplus-command-highlight-face nil - :background (sqlplus-shine-color (face-background 'default) sqlplus-command-highlighting-percentage))))))) - -(defun sqlplus-output-buffer-hide-show () - (if (and (consp buffer-invisibility-spec) - (assq 'hide-symbol buffer-invisibility-spec)) - (remove-from-invisibility-spec '(hide-symbol . t)) - (add-to-invisibility-spec '(hide-symbol . t))) - (let ((overlay (car (overlays-at (point))))) - (when overlay - (goto-char (overlay-start overlay)) - (beginning-of-line))) - (recenter 0)) - -(defun sqlplus-font-lock-value-in-major-mode (alist mode-symbol) - (if (consp alist) - (cdr (or (assq mode-symbol alist) (assq t alist))) - alist)) - -(defun sqlplus-get-history-buffer (connect-string) - (let* ((history-buffer-name (sqlplus-get-history-buffer-name connect-string)) - (history-buffer (get-buffer history-buffer-name))) - (unless history-buffer - (setq history-buffer (get-buffer-create history-buffer-name)) - (with-current-buffer history-buffer - (setq sqlplus-cs connect-string) - (add-hook 'kill-buffer-hook 'sqlplus-history-buffer-kill-function nil t))) - history-buffer)) - -(defun sqlplus-history-buffer-kill-function () - (when sqlplus-history-dir - (condition-case err - (progn - (unless (file-directory-p sqlplus-history-dir) - (make-directory sqlplus-history-dir t)) - (append-to-file 1 (buffer-size) (concat (file-name-as-directory sqlplus-history-dir) (car (refine-connect-string sqlplus-cs t)) "-hist.txt"))) - (error (message (error-message-string err)))))) - -(defun sqlplus-soft-shutdown (connect-string) - (unless (some (lambda (buffer) - (with-current-buffer buffer - (and sqlplus-connect-string - (equal (car (refine-connect-string sqlplus-connect-string)) - (car (refine-connect-string connect-string)))))) - (buffer-list)) - (sqlplus-shutdown connect-string))) - -(defun sqlplus-shutdown (connect-string &optional dont-kill-input-buffer) - "Kill input, output and process buffer for specified CONNECT-STRING." - (let ((input-buffers (delq nil (mapcar (lambda (buffer) (with-current-buffer buffer - (when (and (eq major-mode 'sqlplus-mode) - (equal (car (refine-connect-string sqlplus-connect-string)) - (car (refine-connect-string connect-string)))) - buffer))) (buffer-list)))) - (output-buffer (get-buffer (sqlplus-get-output-buffer-name connect-string))) - (history-buffer (get-buffer (sqlplus-get-history-buffer-name connect-string))) - (process-buffer (get-buffer (sqlplus-get-process-buffer-name connect-string)))) - (when history-buffer - (kill-buffer history-buffer)) - (when (and process-buffer - (with-current-buffer process-buffer sqlplus-process-p)) - (when (get-process (sqlplus-get-process-name connect-string)) - (delete-process (sqlplus-get-process-name connect-string))) - (kill-buffer process-buffer)) - (when (and output-buffer - (with-current-buffer output-buffer sqlplus-connect-string)) - (when (buffer-file-name output-buffer) - (with-current-buffer output-buffer - (save-buffer))) - (kill-buffer output-buffer)) - (dolist (input-buffer input-buffers) - (when (buffer-file-name input-buffer) - (with-current-buffer input-buffer - (save-buffer))) - (unless dont-kill-input-buffer - (kill-buffer input-buffer))))) - -(defun sqlplus-magic () - (let (bottom-message pos) - (delete-region (point) (progn (beginning-of-line 3) (point))) - (setq bottom-message (buffer-substring (point) (save-excursion (end-of-line) (point)))) - (setq pos (point)) - (when (re-search-forward "^-------" nil t) - (delete-region pos (progn (beginning-of-line 2) (point))) - (while (re-search-forward "|" (save-excursion (end-of-line) (point)) t) - (save-excursion - (backward-char) - (if (or (bolp) (save-excursion (forward-char) (eolp))) - (while (member (char-after) '(?- ?|)) - (delete-char 1) - (sqlplus-next-line)) - (while (member (char-after) '(?- ?|)) - (delete-char 1) - (insert " ") - (backward-char) - (sqlplus-next-line))))) - (beginning-of-line 3) - (re-search-forward "^---" nil t) - (goto-char (match-beginning 0)) - (delete-region (point) (point-max)) - (insert (format "%s\n\n%s\n" sqlplus-repfooter bottom-message)) - ))) - - -(defun sqlplus-process-command-output (context connect-string begin end interrupted) - (let* ((output-buffer-name (sqlplus-get-output-buffer-name connect-string)) - (output-buffer (get-buffer output-buffer-name)) - (process-buffer (sqlplus-get-process-buffer-name connect-string)) - str - error-list show-errors-p - slips-count - (user-function (sqlplus-get-context-value context :user-function)) - (result-function (sqlplus-get-context-value context :result-table-function)) - (last-compiled-file-path (sqlplus-get-context-value context :last-compiled-file-path)) - (compilation-expected (sqlplus-get-context-value context :compilation-expected)) - (columns-count (sqlplus-get-context-value context :columns-count)) - (sql (sqlplus-get-context-value context :sql)) - (original-buffer (current-buffer)) - explain-plan - table-data) - (setq slips-count columns-count) - (with-temp-buffer - (insert-buffer-substring original-buffer begin end) - (goto-char (point-min)) - (while (re-search-forward (concat "\n+" (regexp-quote sqlplus-page-separator) "\n") nil t) - (replace-match "\n")) - (goto-char (point-min)) - (setq str (buffer-string)) - (while (string-match (concat "^" (regexp-quote sqlplus-repfooter) "\n") str) - (setq str (replace-match "" nil t str))) - - ;; compilation errors? - (goto-char (point-min)) - (skip-chars-forward "\n\t ") - (when (and ;;(not (equal (point) (point-max))) - plsql-auto-parse-errors-flag - output-buffer - last-compiled-file-path - (re-search-forward "^\\(LINE/COL\\|\\(SP2\\|CPY\\|ORA\\)-[0-9]\\{4,5\\}:\\|No errors\\|Nie ma b..d.w\\|Keine Fehler\\|No hay errores\\|Identificateur erron\\|Nessun errore\\|N..o h.. erros\\)" nil t)) - (goto-char (point-min)) - (setq error-list (plsql-parse-errors last-compiled-file-path) - show-errors-p compilation-expected)) - - ;; explain? - (let ((case-fold-search t)) - (goto-char (point-min)) - (skip-chars-forward "\n\t ") - (when (and sql - (string-match "^[\n\t ]*explain\\>" sql) - (looking-at "Explained[.]")) - (delete-region (point-min) (point-max)) - (setq str "") - (sqlplus--send connect-string - "select plan_table_output from table(dbms_xplan.display(null, null, 'TYPICAL'));" - nil - 'no-echo - nil))) - - ;; plan table output? - (goto-char (point-min)) - (skip-chars-forward "\n\t ") - (when (and (looking-at "^PLAN_TABLE_OUTPUT\n") - sqlplus-format-output-tables-flag - (not compilation-expected) - (not show-errors-p)) - (sqlplus-magic) ;; TODO - (goto-char (point-min)) - (re-search-forward "^[^\n]+" nil t) - (delete-region (point-min) (progn (beginning-of-line) (point))) - ;; (setq slips-count 1) - (setq explain-plan t) - (setq table-data (save-excursion (sqlplus-parse-output-table interrupted)))) - - ;; query result? - (goto-char (point-min)) - (when (and sqlplus-format-output-tables-flag - (not compilation-expected) - (not table-data) - (not show-errors-p) - (not (re-search-forward "^LINE/COL\\>" nil t))) - (setq table-data (save-excursion (sqlplus-parse-output-table interrupted)))) - (if user-function - (funcall user-function connect-string context (or table-data str)) - (when output-buffer - (with-current-buffer output-buffer - (save-excursion - (goto-char (point-max)) - (cond (show-errors-p - (insert str) - (plsql-display-errors (file-name-directory last-compiled-file-path) error-list) - (let* ((plsql-buf (get-file-buffer last-compiled-file-path)) - (win (when plsql-buf (car (get-buffer-window-list plsql-buf))))) - (when win - (select-window win)))) - ((and table-data - (car table-data)) - (if result-function - (funcall result-function connect-string table-data) - (let ((b (point)) - (warning-regexp (regexp-opt sqlplus-explain-plan-warning-regexps)) - e) - (sqlplus-draw-table table-data slips-count) - (when interrupted (insert ". . .\n")) - (setq e (point)) - (when explain-plan - (save-excursion - (goto-char b) - (while (re-search-forward warning-regexp nil t) - (add-text-properties (match-beginning 0) (match-end 0) - (list 'face (list (cons 'foreground-color "red") (list :weight 'bold) - (get-text-property (match-beginning 0) 'face)))))))))) - (t - (insert str)))))))))) - -(defun sqlplus-result-online (connect-string context string last-chunk) - (let ((output-buffer (sqlplus-get-output-buffer-name connect-string))) - (when output-buffer - (with-current-buffer output-buffer - (save-excursion - (goto-char (point-max)) - (insert string)))))) - -(defvar sqlplus-prompt-regexp (concat "^" (regexp-quote sqlplus-prompt-prefix) "\\([0-9]+\\)" (regexp-quote sqlplus-prompt-suffix))) - -(defvar sqlplus-page-separator-regexp (concat "^" (regexp-quote sqlplus-page-separator))) - -(defun sqlplus-process-filter (process string) - (with-current-buffer (process-buffer process) - (let* ((prompt-safe-len (+ (max (+ (length sqlplus-prompt-prefix) (length sqlplus-prompt-suffix)) (length sqlplus-page-separator)) 10)) - current-context-id filter-input-processed - (connect-string sqlplus-process-p) - (chunk-begin-pos (make-marker)) - (chunk-end-pos (make-marker)) - (prompt-found (make-marker)) - (context (sqlplus-get-context connect-string current-context-id)) - (current-command-input-buffer-name (sqlplus-get-context-value context :current-command-input-buffer-name)) - (current-command-input-buffer-names (when current-command-input-buffer-name (list current-command-input-buffer-name)))) - (set-marker chunk-begin-pos (max 1 (- (point) prompt-safe-len))) - (goto-char (point-max)) - (insert string) - (unless current-command-input-buffer-names - (setq current-command-input-buffer-names - (delq nil (mapcar (lambda (buffer) (with-current-buffer buffer - (when (and (memq major-mode '(sqlplus-mode plsql-mode)) - sqlplus-connect-string - (equal (car (refine-connect-string sqlplus-connect-string)) - (car (refine-connect-string connect-string)))) - buffer))) (buffer-list))))) - ;; fan animation - (dolist (current-command-input-buffer-name current-command-input-buffer-names) - (let ((input-buffer (get-buffer current-command-input-buffer-name))) - (when input-buffer - (with-current-buffer input-buffer - (setq sqlplus-fan - (cond ((equal sqlplus-fan "|") "/") - ((equal sqlplus-fan "/") "-") - ((equal sqlplus-fan "-") "\\") - ((equal sqlplus-fan "\\") "|"))) - (put-text-property 0 (length sqlplus-fan) 'face '((foreground-color . "red")) sqlplus-fan) - (put-text-property 0 (length sqlplus-fan) 'help-echo (sqlplus-get-context-value context :sql) sqlplus-fan) - (force-mode-line-update))))) - (unwind-protect - (while (not filter-input-processed) - (let* ((context (sqlplus-get-context connect-string current-context-id)) - (dont-parse-result (sqlplus-get-context-value context :dont-parse-result)) - (current-command-input-buffer-name (sqlplus-get-context-value context :current-command-input-buffer-name)) - (result-function (sqlplus-get-context-value context :result-function)) - (skip-to-the-end-of-command (sqlplus-get-context-value context :skip-to-the-end-of-command))) - (set-marker prompt-found nil) - (goto-char chunk-begin-pos) - (set-marker chunk-end-pos - (if (or (re-search-forward sqlplus-prompt-regexp nil t) - (re-search-forward "^SQL> " nil t)) - (progn - (set-marker prompt-found (match-end 0)) - (when (match-string 1) - (setq current-context-id (string-to-number (match-string 1)))) - (match-beginning 0)) - (point-max))) - (cond ((and (equal chunk-begin-pos chunk-end-pos) ; at the end of command - (marker-position prompt-found)) - ;; deactivate fan - (dolist (current-command-input-buffer-name current-command-input-buffer-names) - (let ((input-buffer (get-buffer current-command-input-buffer-name))) - (when input-buffer - (with-current-buffer input-buffer - (remove-text-properties 0 (length sqlplus-fan) '(face nil) sqlplus-fan) - (force-mode-line-update))))) - (delete-region 1 prompt-found) - (when dont-parse-result - (funcall (or result-function 'sqlplus-result-online) connect-string context "" t)) - (sqlplus-set-context-value context :skip-to-the-end-of-command nil) - (set-marker chunk-begin-pos 1)) - ((equal chunk-begin-pos chunk-end-pos) - (when dont-parse-result - (delete-region 1 (point-max))) - (setq filter-input-processed t)) - (dont-parse-result - (funcall (or result-function 'sqlplus-result-online) - connect-string - context - (buffer-substring chunk-begin-pos chunk-end-pos) - (marker-position prompt-found)) - (set-marker chunk-begin-pos chunk-end-pos)) - (t - (when (not skip-to-the-end-of-command) - (goto-char (max 1 (- chunk-begin-pos 4010))) - (let ((page-separator-found - (save-excursion (let ((pos (re-search-forward (concat sqlplus-page-separator-regexp "[^-]*\\(^-\\|^<th\\b\\)") nil t))) - (when (and pos - (or (not (marker-position prompt-found)) - (< pos prompt-found))) - (match-beginning 0)))))) - (when (or (marker-position prompt-found) page-separator-found) - (goto-char (or page-separator-found chunk-end-pos)) - (let ((end-pos (point)) - (cur-msg (or (current-message) ""))) - (sqlplus-set-context-value context :skip-to-the-end-of-command page-separator-found) - (when page-separator-found - (interrupt-process) - (save-excursion - (re-search-backward "[^ \t\n]\n" nil t) - (setq end-pos (match-end 0)))) - (if result-function - (save-excursion (funcall result-function context connect-string 1 end-pos page-separator-found)) - (with-temp-message "Formatting output..." - (save-excursion (sqlplus-process-command-output context connect-string 1 end-pos page-separator-found))) - (message "%s" cur-msg)) - (when page-separator-found - (delete-region 1 (+ page-separator-found (length sqlplus-page-separator))) - (set-marker chunk-end-pos 1)))))) - (set-marker chunk-begin-pos chunk-end-pos))))) - (goto-char (point-max)) - (set-marker chunk-begin-pos nil) - (set-marker chunk-end-pos nil) - (set-marker prompt-found nil))))) - -(defadvice switch-to-buffer (around switch-to-buffer-around-advice (buffer-or-name &optional norecord)) - ad-do-it - (when (and sqlplus-connect-string - (eq major-mode 'sqlplus-mode)) - (let ((side-window (sqlplus-get-side-window)) - (output-buffer (get-buffer (sqlplus-get-output-buffer-name sqlplus-connect-string)))) - (when (and side-window - (not (eq (window-buffer) output-buffer))) - (save-selected-window - (switch-to-buffer-other-window output-buffer)))))) -(ad-activate 'switch-to-buffer) - -(defun sqlplus-kill-function () - (unless sqlplus-kill-function-inhibitor - ;; shutdown connection if it is SQL*Plus output buffer or SQL*Plus process buffer - (if (or (and sqlplus-connect-string (equal (buffer-name) (sqlplus-get-output-buffer-name sqlplus-connect-string))) - sqlplus-process-p) - (sqlplus--enqueue-task 'sqlplus-shutdown (or sqlplus-connect-string sqlplus-process-p)) - ;; input buffer or another buffer connected to SQL*Plus - possibly shutdown - (when sqlplus-connect-string - (let ((counter 0) - (scs sqlplus-connect-string)) - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (when (equal sqlplus-connect-string scs) (incf counter)))) - (when (<= counter 2) - (let* ((process (get-process (sqlplus-get-process-name sqlplus-connect-string)))) - (when (or (not process) - (memq (process-status process) '(exit signal)) - (y-or-n-p (format "Kill SQL*Plus process %s " (car (refine-connect-string sqlplus-connect-string))))) - (sqlplus--enqueue-task 'sqlplus-shutdown sqlplus-connect-string))))))))) - -(defun sqlplus-emacs-kill-function () - ;; save and kill all sqlplus-mode buffers - (let (buffers-to-kill) - (dolist (buffer (buffer-list)) - (with-current-buffer buffer - (when (and sqlplus-connect-string - (eq major-mode 'sqlplus-mode)) - (when (buffer-file-name) - (save-buffer)) - (push buffer buffers-to-kill)))) - (setq sqlplus-kill-function-inhibitor t) - (condition-case nil - (unwind-protect - (dolist (buffer buffers-to-kill) - (kill-buffer buffer)) - (setq sqlplus-kill-function-inhibitor nil)) - (error nil)) - t)) - -(push 'sqlplus-emacs-kill-function kill-emacs-query-functions) - -(add-hook 'kill-buffer-hook 'sqlplus-kill-function) - -;; kill all history buffers so that they can save themselves -(add-hook 'kill-emacs-hook (lambda () - (dolist (buf (copy-list (buffer-list))) - (when (and (string-match "@.*-hist" (buffer-name buf)) - (with-current-buffer buf sqlplus-cs)) - (kill-buffer buf))))) - -(defun sqlplus-find-output-table (interrupted) - "Search for table in last SQL*Plus command result, and return -list (BEGIN END MSG) for first and last table char, or nil if -table is not found." - (let (begin end) - (goto-char (point-min)) - (when (re-search-forward "^[^\n]+\n\\( \\)?-" nil t) - (let (msg - (indent (when (match-string 1) -1))) ; result of 'describe' sqlplus command - (forward-line -1) - ;; (untabify (point) (buffer-size)) - (setq begin (point)) - (when indent - (indent-rigidly begin (point-max) indent) - (goto-char begin)) - (if indent - (progn - (goto-char (point-max)) - (skip-chars-backward "\n\t ") - (setq end (point)) - (goto-char (point-max))) - (or (re-search-forward (concat "^" (regexp-quote sqlplus-repfooter) "\n[\n\t ]*") nil t) - (when interrupted (re-search-forward "\\'" nil t))) ; \\' means end of buffer - (setq end (match-beginning 0)) - (setq msg (buffer-substring (match-end 0) (point-max)))) - (list begin end msg))))) - -(defstruct col-desc - id ; from 0 - name ; column name - start-pos ; char column number - end-pos ; char column number - max-width ; max. column width - preferred-width ; preferred column width - min-prefix-len ; min. prefix (spaces only) - numeric ; y if column is numeric, n if is not, nil if don't know - has-eol ; temporary value for processing current row -) - -(defun sqlplus-previous-line () - (let ((col (current-column))) - (forward-line -1) - (move-to-column col t))) - -(defun sqlplus-next-line () - (let ((col (current-column))) - (forward-line 1) - (move-to-column col t))) - -(defun sqlplus--correct-column-name (max-col-no) - (let ((counter 0) - (big (1- (save-excursion (beginning-of-line) (point))))) - (skip-chars-forward " ") - (when (re-search-forward " [^ \n]" (+ big max-col-no) t) - (backward-char) - (while (< (point) (+ big max-col-no)) - (setq counter (1+ counter)) - (insert " "))) - counter)) - -(defun sqlplus-parse-output-table (interrupted) - "Parse table and return list (COLUMN-INFOS ROWS MSG) where -COLUMN-INFOS is a col-desc structures list, ROWS is a table of -records (record is a list of strings). Return nil if table is -not detected." - (let ((region (sqlplus-find-output-table interrupted))) - (when region - (let ((begin (car region)) - (end (cadr region)) - (last-msg (caddr region)) - (col-counter 0) - column-infos rows - (record-lines 1) - finish) - ;; (message "'%s'\n'%s'" (buffer-substring begin end) last-msg) - (goto-char begin) - ;; we are at the first char of column name - ;; move to the first char of '-----' column separator - (beginning-of-line 2) - (while (not finish) - (if (equal (char-after) ?-) - ;; at the first column separator char - (let* ((beg (point)) - (col-begin (current-column)) - (col-max-width (skip-chars-forward "-")) - ;; after last column separator char - (ed (point)) - (col-end (+ col-begin col-max-width)) - (col-name (let* ((b (progn - (goto-char beg) - (sqlplus-previous-line) - (save-excursion - (let ((counter (sqlplus--correct-column-name (1+ col-end)))) - (setq beg (+ beg counter)) - (setq ed (+ ed counter)))) - (point))) - (e (+ b col-max-width))) - (skip-chars-forward " \t") - (setq b (point)) - (goto-char (min (save-excursion (end-of-line) (point)) e)) - (skip-chars-backward " \t") - (setq e (point)) - (if (> e b) - (buffer-substring b e) - ""))) - (col-preferred-width (string-width col-name))) - ;; (put-text-property 0 (length col-name) 'face '(bold) col-name) - (push (make-col-desc :id col-counter :name col-name :start-pos col-begin - :end-pos col-end :max-width col-max-width :preferred-width col-preferred-width :min-prefix-len col-max-width) - column-infos) - (incf col-counter) - (goto-char ed) - (if (equal (char-after) ?\n) - (progn - (beginning-of-line 3) - (incf record-lines)) - (forward-char))) - (setq finish t))) - (decf record-lines) - (setq column-infos (nreverse column-infos)) - (forward-line -1) - - ;; at the first char of first data cell. - ;; table parsing... - (while (< (point) end) - (let (record last-start-pos) - (dolist (column-info column-infos) - (let ((start-pos (col-desc-start-pos column-info)) - (end-pos (col-desc-end-pos column-info)) - width len value b e l) - (when (and last-start-pos - (<= start-pos last-start-pos)) - (forward-line)) - (setq last-start-pos start-pos) - (move-to-column start-pos) - (setq b (point)) - (move-to-column end-pos) - (setq e (point)) - (move-to-column start-pos) - (setq l (skip-chars-forward " " e)) - (when (and (col-desc-min-prefix-len column-info) - (< l (- e b)) - (< l (col-desc-min-prefix-len column-info))) - (setf (col-desc-min-prefix-len column-info) - (if (looking-at "[0-9]") l nil))) - (move-to-column end-pos) - (skip-chars-backward " " b) - (setq value (if (> (point) b) (buffer-substring b (point)) "")) - (setq len (length value) - width (string-width value)) - (when (and sqlplus-select-result-max-col-width - (> len sqlplus-select-result-max-col-width)) - (setq value (concat (substring value 0 sqlplus-select-result-max-col-width) "...") - len (length value) - width (string-width value))) - (when (> width (col-desc-preferred-width column-info)) - (setf (col-desc-preferred-width column-info) width)) - (when (and (< l (- e b)) - (memq (col-desc-numeric column-info) '(nil y))) - (setf (col-desc-numeric column-info) - (if (string-match "\\` *[-+0-9Ee.,$]+\\'" value) 'y 'n))) - (push value record))) - (forward-line) - (when (> record-lines 1) - (forward-line)) - (setq last-start-pos nil - record (nreverse record)) - (push record rows))) - (setq rows (nreverse rows)) - (list column-infos rows last-msg))))) - -(defun sqlplus-draw-table (lst &optional slips-count) - "SLIPS-COUNT (nil means compute automatically)." - ;; current buffer: SQL*Plus output buffer - (when window-system - (if (>= (sqlplus-color-percentage (face-background 'default)) 50) - (progn - (set-face-attribute 'sqlplus-table-head-face nil - :background (sqlplus-shine-color (face-background 'default) -70) :foreground (face-background 'default)) - (set-face-attribute 'sqlplus-table-even-rows-face nil - :background (sqlplus-shine-color (face-background 'default) -20) :overline (face-background 'default)) - (set-face-attribute 'sqlplus-table-odd-rows-face nil - :background (sqlplus-shine-color (face-background 'default) -30) :overline (face-background 'default))) - (set-face-attribute 'sqlplus-table-head-face nil - :background (sqlplus-shine-color (face-background 'default) +70) :foreground (face-background 'default)) - (set-face-attribute 'sqlplus-table-even-rows-face nil - :background (sqlplus-shine-color (face-background 'default) +20) :overline (face-background 'default)) - (set-face-attribute 'sqlplus-table-odd-rows-face nil - :background (sqlplus-shine-color (face-background 'default) +30) :overline (face-background 'default)))) - (let* ((column-infos (car lst)) - (rows (cadr lst)) - (slip-width 0) - (table-header-height 1) - (table-area-width (1- (let ((side-window (sqlplus-get-side-window))) (if side-window (window-width side-window) (frame-width))))) - ;; may be nil, which means no limit - (table-area-height (let ((side-window (sqlplus-get-side-window))) - (when side-window - (- (window-height side-window) 2 (if mode-line-format 1 0) (if header-line-format 1 0))))) - (column-separator-width (if sqlplus-elegant-style 1.2 (max (length sqlplus-table-col-separator) (length sqlplus-table-col-head-separator)))) - rows-per-slip ;; data rows per slip - (slip-separator-width (if sqlplus-elegant-style 1.5 sqlplus-slip-separator-width)) - (slip-separator (make-string (max 0 (if sqlplus-elegant-style 1 sqlplus-slip-separator-width)) ?\ )) - (last-msg (caddr lst))) - (when sqlplus-elegant-style - (put-text-property 0 1 'display (cons 'space (list :width slip-separator-width)) slip-separator)) - (when (<= table-area-height table-header-height) - (setq table-area-height nil)) - (when (and window-system sqlplus-elegant-style table-area-height (> table-area-height 3)) - ;; overline makes glyph higher... - (setq table-area-height (- table-area-height (round (/ (* 20.0 (- table-area-height 3)) (face-attribute 'default :height)))))) - (when column-infos - (goto-char (point-max)) - (beginning-of-line) - ;; slip width (without separator between slips) - (dolist (col-info column-infos) - (when (col-desc-min-prefix-len col-info) - (setf (col-desc-preferred-width col-info) (max (string-width (col-desc-name col-info)) - (- (col-desc-preferred-width col-info) (col-desc-min-prefix-len col-info))))) - (incf slip-width (+ (col-desc-preferred-width col-info) column-separator-width))) - (when (> slip-width 0) - (setq slip-width (+ (- slip-width column-separator-width) (if sqlplus-elegant-style 1.0 0)))) - ;; computing slip count if not known yet - (unless slips-count - (setq slips-count - (if table-area-height (min (ceiling (/ (float (length rows)) (max 1 (- table-area-height table-header-height 2)))) - (max 1 (floor (/ (float table-area-width) (+ slip-width slip-separator-width))))) - 1))) - (setq slips-count (max 1 (min slips-count (length rows)))) ; slip count <= data rows - (setq rows-per-slip (ceiling (/ (float (length rows)) slips-count))) - (when (> rows-per-slip 0) - (setq slips-count (max 1 (min (ceiling (/ (float (length rows)) rows-per-slip)) slips-count)))) - - (let ((table-begin-point (point))) - (dotimes (slip-no slips-count) - (let ((row-no 0) - (slip-begin-point (point)) - (rows-processed 0)) - ;; column names - (dolist (col-info column-infos) - (let* ((col-name (col-desc-name col-info)) - (spaces (max 0 (- (col-desc-preferred-width col-info) (string-width col-name)))) - (last-col-p (>= (1+ (col-desc-id col-info)) (length column-infos))) - (val (format (if sqlplus-elegant-style " %s%s %s" "%s%s%s") - col-name - (make-string spaces ?\ ) - (if last-col-p "" (if sqlplus-elegant-style " " sqlplus-table-col-separator))))) - (put-text-property 0 (if (or (not sqlplus-elegant-style) last-col-p) (length val) (1- (length val))) - 'face 'sqlplus-table-head-face val) - (when sqlplus-elegant-style - (put-text-property 0 1 'display '(space . (:width 0.5)) val) - (put-text-property (- (length val) (if last-col-p 1 2)) (- (length val) (if last-col-p 0 1)) 'display '(space . (:width 0.5)) val) - (unless last-col-p - (put-text-property (- (length val) 1) (length val) 'display '(space . (:width 0.2)) val))) - (insert val))) - (insert slip-separator) - (insert "\n") - ;; data rows - (while (and (< rows-processed rows-per-slip) - rows) - (let ((row (car rows))) - (setq rows (cdr rows)) - (incf rows-processed) - (let ((col-infos column-infos)) - (dolist (value row) - (let* ((col-info (car col-infos)) - (numeric-p (eq (col-desc-numeric col-info) 'y)) - (min-prefix (col-desc-min-prefix-len col-info))) - (when (and min-prefix - value - (>= (length value) min-prefix)) - (setq value (substring value min-prefix))) - (let* ((spaces (max 0 (- (col-desc-preferred-width col-info) (string-width value)))) - (val (if numeric-p - (format (if sqlplus-elegant-style " %s%s %s" "%s%s%s") - (make-string spaces ?\ ) - value - (if (cdr col-infos) (if sqlplus-elegant-style " " sqlplus-table-col-separator) "")) - (format (if sqlplus-elegant-style " %s%s %s" "%s%s%s") - value - (make-string spaces ?\ ) - (if (cdr col-infos) (if sqlplus-elegant-style " " sqlplus-table-col-separator) ""))))) - (put-text-property 0 (if (and sqlplus-elegant-style (cdr col-infos)) (- (length val) 1) (length val)) - 'face (if (evenp row-no) - 'sqlplus-table-even-rows-face - 'sqlplus-table-odd-rows-face) val) - (when sqlplus-elegant-style - (put-text-property 0 1 'display '(space . (:width 0.5)) val) - (put-text-property (- (length val) (if (cdr col-infos) 2 1)) - (- (length val) (if (cdr col-infos) 1 0)) - 'display '(space . (:width 0.5)) val) - (when (cdr col-infos) - (put-text-property (- (length val) 1) (length val) 'display '(space . (:width 0.2)) val))) - (setq col-infos (cdr col-infos)) - (insert val)))) - (incf row-no) - (insert slip-separator) - (insert "\n")))) - (when (> slip-no 0) - (delete-backward-char 1) - (let ((slip-end-point (point))) - (kill-rectangle slip-begin-point slip-end-point) - (delete-region slip-begin-point (point-max)) - (goto-char table-begin-point) - (end-of-line) - (yank-rectangle) - (goto-char (point-max)) - )))) - (goto-char (point-max)) - (when (and last-msg (> (length last-msg) 0)) - (unless sqlplus-elegant-style (insert "\n")) - (let ((s (format "%s\n\n" (replace-regexp-in-string "\n+" " " last-msg)))) - (when sqlplus-elegant-style - (put-text-property (- (length s) 2) (1- (length s)) 'display '(space . (:height 1.5)) s)) - (insert s))))))) - -(defun sqlplus-send-user-string (str) - (interactive (progn (sqlplus-check-connection) - (if sqlplus-connect-string - (list (read-string "Send to process: " nil 'sqlplus-user-string-history "")) - (error "Works only in SQL*Plus buffer")))) - (let ((connect-string sqlplus-connect-string)) - (sqlplus-verify-buffer connect-string) - (let* ((process (get-process (sqlplus-get-process-name connect-string))) - (output-buffer-name (sqlplus-get-output-buffer-name connect-string))) - (sqlplus-echo-in-buffer output-buffer-name (concat str "\n")) - (send-string process (concat str "\n"))))) - -(defun sqlplus-prepare-update-alist (table-data) - (let ((column-infos (car table-data)) - (rows (cadr table-data)) - (msg (caddr table-data)) - alist) - (dolist (row rows) - (let* ((object-name (car row)) - (object-type (intern (downcase (cadr row)))) - (status (caddr row)) - (regexp-list (cdr (assq object-type alist))) - (pair (cons object-name (equal status "I")))) - (if regexp-list - (setcdr regexp-list (cons pair (cdr regexp-list))) - (setq regexp-list (list pair)) - (setq alist (cons (cons object-type regexp-list) alist))))) - alist)) - -(defun sqlplus-my-update-handler (connect-string table-data) - (let ((alist (sqlplus-prepare-update-alist table-data))) - (when (featurep 'ide-skel) - (funcall 'sqlplus-side-view-update-data connect-string alist)))) - -(defun sqlplus-my-handler (connect-string table-data) - (let ((alist (sqlplus-prepare-update-alist table-data)) - (sqlplus-font-lock-regexps (sqlplus-get-font-lock-regexps connect-string))) - (sqlplus-set-objects-alist alist connect-string) - (when (featurep 'ide-skel) - (funcall 'sqlplus-side-view-update-data connect-string alist)) - (clrhash sqlplus-font-lock-regexps) - (dolist (lst sqlplus-syntax-faces) - (let* ((object-type (car lst)) - (regexp-list (append (caddr lst) (mapcar 'car (cdr (assq object-type alist)))))) - (when regexp-list - (puthash object-type (concat "\\b" (regexp-opt regexp-list t) "\\b") sqlplus-font-lock-regexps)))) - (let ((map sqlplus-font-lock-regexps)) - (mapc (lambda (buffer) - (with-current-buffer buffer - (when (and (memq major-mode '(sqlplus-mode plsql-mode)) - (equal sqlplus-connect-string connect-string)) - (when font-lock-mode (font-lock-mode 1))))) - (buffer-list))))) - -(defun sqlplus-get-source-function (connect-string context string last-chunk) - (let* ((source-text (sqlplus-get-context-value context :source-text)) - (source-type (sqlplus-get-context-value context :source-type)) - (source-name (sqlplus-get-context-value context :source-name)) - (source-extension (sqlplus-get-context-value context :source-extension)) - (name (concat (upcase source-name) "." source-extension)) - finish) - (unless (sqlplus-get-context-value context :finished) - (setq source-text (concat source-text string)) - (sqlplus-set-context-value context :source-text source-text) - (when last-chunk - (if (string-match (regexp-quote sqlplus-end-of-source-sentinel) source-text) - (when (< (length source-text) (+ (length sqlplus-end-of-source-sentinel) 5)) - (setq last-chunk nil - finish "There is no such database object")) - (setq last-chunk nil))) - (when last-chunk - (setq finish t)) - (when finish - (sqlplus-set-context-value context :finished t) - (if (stringp finish) - (message finish) - (with-temp-buffer - (insert source-text) - (goto-char (point-min)) - (re-search-forward (regexp-quote sqlplus-end-of-source-sentinel) nil t) - (replace-match "") - (goto-char (point-max)) - (forward-comment (- (buffer-size))) - (when (equal source-type "TABLE") - (goto-char (point-min)) - (insert (format "table %s\n(\n" source-name)) - (goto-char (point-max)) - (delete-region (re-search-backward "," nil t) (point-max)) - (insert "\n);")) - (insert "\n/\n") - (unless (member source-type '("SEQUENCE" "TABLE" "SYNONYM" "INDEX")) - (insert "show err\n")) - (goto-char (point-min)) - (insert "create " (if (member source-type '("INDEX" "SEQUENCE" "TABLE")) "" "or replace ")) - (setq source-text (buffer-string))) - (with-current-buffer (get-buffer-create name) - (setq buffer-read-only nil) - (erase-buffer) - (insert source-text) - (goto-char (point-min)) - (set-visited-file-name (concat (file-name-as-directory temporary-file-directory) - (concat (make-temp-name (sqlplus-canonize-file-name (concat (upcase source-name) "_") "[$]")) "." source-extension))) - (rename-buffer name) - (condition-case err - (funcall (symbol-function 'plsql-mode)) - (error nil)) - (setq sqlplus-connect-string connect-string - buffer-read-only sqlplus-source-buffer-readonly-by-default-flag) - (save-buffer) - (save-selected-window - (let ((win (selected-window))) - (when (or (equal win (sqlplus-get-side-window)) - (and (fboundp 'ide-skel-side-view-window-p) - (funcall 'ide-skel-side-view-window-p win))) - (setq win (sqlplus-get-workbench-window))) - (set-window-buffer win (current-buffer)))))))))) - -(defun sqlplus-get-source (connect-string name type &optional schema-name) - "Fetch source for database object NAME in current or specified SCHEMA-NAME, and show the source in new buffer. -Possible TYPE values are in 'sqlplus-object-types'." - (interactive (let* ((thing (thing-at-point 'symbol)) - (obj-raw-name (read-string (concat "Object name" (if thing (concat " [default " thing "]") "") ": ") - nil - 'sqlplus-get-source-history (when thing thing))) - (completion-ignore-case t) - (type (completing-read "Object type: " (mapcar (lambda (type) (cons type nil)) sqlplus-object-types) nil t))) - (string-match "^\\(\\([^.]+\\)[.]\\)?\\(.*\\)$" obj-raw-name) - (list sqlplus-connect-string (match-string 3 obj-raw-name) type (match-string 2 obj-raw-name)))) - (setq type (upcase type)) - (let* ((sql - (cond ((equal type "SEQUENCE") - (format (concat "select 'sequence %s' || sequence_name || " - "decode( increment_by, 1, '', ' increment by ' || increment_by ) || " - "case when increment_by > 0 and max_value >= (1.0000E+27)-1 or increment_by < 0 and max_value = -1 then '' " - "else decode( max_value, null, ' nomaxvalue', ' maxvalue ' || max_value) end || " - "case when increment_by > 0 and min_value = 1 or increment_by < 0 and min_value <= (-1.0000E+26)+1 then '' " - "else decode( min_value, null, ' nominvalue', ' minvalue ' || min_value) end || " - "decode( cycle_flag, 'Y', ' cycle', '' ) || " - "decode( cache_size, 20, '', 0, ' nocache', ' cache ' || cache_size ) || " - "decode( order_flag, 'Y', ' order', '' ) " - "from %s where sequence_name = '%s'%s;") - (if schema-name (concat (upcase schema-name) ".") "") - (if schema-name "all_sequences" "user_sequences") - (upcase name) - (if schema-name (format " and sequence_owner = '%s'" (upcase schema-name)) ""))) - ((equal type "TABLE") - (format (concat "select ' ' || column_name || ' ' || data_type || " - "decode( data_type," - " 'VARCHAR2', '(' || to_char( data_length, 'fm9999' ) || ')'," - " 'NUMBER', decode( data_precision," - " null, ''," - " '(' || to_char( data_precision, 'fm9999' ) || decode( data_scale," - " null, ''," - " 0, ''," - " ',' || data_scale ) || ')' )," - " '') || " - "decode( nullable, 'Y', ' not null', '') || ','" - "from all_tab_columns " - "where owner = %s and table_name = '%s' " - "order by column_id;") - (if schema-name (concat "'" (upcase schema-name) "'") "user") - (upcase name))) - ((equal type "SYNONYM") - (format (concat "select " - "decode( owner, 'PUBLIC', 'public ', '' ) || 'synonym ' || " - "decode( owner, 'PUBLIC', '', user, '', owner || '.' ) || synonym_name || ' for ' || " - "decode( table_owner, user, '', table_owner || '.' ) || table_name || " - "decode( db_link, null, '', '@' || db_link ) " - "from all_synonyms where (owner = 'PUBLIC' or owner = %s) and synonym_name = '%s';") - (if schema-name (concat "'" (upcase schema-name) "'") "user") - (upcase name))) - ((equal type "VIEW") - (if schema-name (format "select 'view %s.' || view_name || ' as ', text from all_views where owner = '%s' and view_name = '%s';" - (upcase schema-name) (upcase schema-name) (upcase name)) - (format "select 'view ' || view_name || ' as ', text from user_views where view_name = '%s';" (upcase name)))) - ((or (equal type "PROCEDURE") - (equal type "FUNCTION")) - (if schema-name (format "select text from all_source where owner = '%s' and name = '%s' and type in ('PROCEDURE', 'FUNCTION') order by line;" - (upcase schema-name) (upcase name)) - (format "select text from user_source where name = '%s' and type in ('PROCEDURE', 'FUNCTION') order by line;" - (upcase name)))) - (t - (if schema-name (format "select text from all_source where owner = '%s' and name = '%s' and type = '%s' order by line;" - (upcase schema-name) (upcase name) (upcase type)) - (format "select text from user_source where name = '%s' and type = '%s' order by line;" - (upcase name) (upcase type)))))) - (prolog-commands (list "set echo off" - "set newpage 0" - "set space 0" - "set pagesize 0" - "set feedback off" - "set long 4000" - "set longchunksize 4000" - "set wrap on" - "set heading off" - "set trimspool on" - "set linesize 4000" - "set timing off")) - (extension (if (equal (downcase type) "package") "pks" "sql")) - (source-buffer-name (concat " " (upcase name) "." extension)) - (context-options (list (cons :dont-parse-result 'dont-parse) - (cons :source-text nil) - (cons :source-type type) - (cons :source-name name) - (cons :source-extension extension) - (cons :result-function 'sqlplus-get-source-function)))) - (sqlplus-execute connect-string sql context-options prolog-commands t t) - (sqlplus-execute connect-string (format "select '%s' from dual;" sqlplus-end-of-source-sentinel) context-options prolog-commands t t))) - -(defun sqlplus-canonize-file-name (file-name regexp) - (while (string-match regexp file-name) - (setq file-name (replace-match "!" nil t file-name))) - file-name) - -(defun sqlplus-define-user-variables (string) - (when string - (let (variables-list - define-commands - (index 0)) - (while (setq index (string-match "&+\\(\\(\\sw\\|\\s_\\)+\\)" string index)) - (let ((var-name (match-string 1 string))) - (setq index (+ 2 index)) - (unless (member var-name variables-list) - (push var-name variables-list)))) - (dolist (var-name (reverse variables-list)) - (let* ((default-value (gethash var-name sqlplus-user-variables nil)) - (value (read-string (format (concat "Variable value for %s" (if default-value (format " [default: %s]" default-value) "") ": ") var-name) - nil 'sqlplus-user-variables-history default-value))) - (unless value - (error "There is no value for %s defined" var-name)) - (setq define-commands (cons (format "define %s=%s" var-name value) define-commands)) - (puthash var-name value sqlplus-user-variables))) - define-commands))) - -(defun sqlplus-parse-region (start end) - (let ((sql (buffer-substring start end))) - (save-excursion - ;; Strip whitespace from beginning and end, just to be neat. - (if (string-match "\\`[ \t\n]+" sql) - (setq sql (substring sql (match-end 0)))) - (if (string-match "[ \t\n]+\\'" sql) - (setq sql (substring sql 0 (match-beginning 0)))) - (setq sql (replace-regexp-in-string "^[ \t]*--.*[\n]?" "" sql)) - (when (zerop (length sql)) - (error "Nothing to send")) - ;; Now the string should end with an sqlplus-terminator. - (if (not (string-match "\\(;\\|/\\|[.]\\)\\'" sql)) - (setq sql (concat sql ";")))) - sql)) - -(defun sqlplus-show-html-fun (context connect-string begin end interrupted) - (let ((output-file (expand-file-name (substitute-in-file-name sqlplus-html-output-file-name))) - (sql (sqlplus-get-context-value context :htmlized-html-command)) - (html (buffer-substring begin end)) - (header-html (eval sqlplus-html-output-header))) - (let ((case-fold-search t)) - (while (and (string-match "\\`[ \t\n]*\\(<br>\\|<p>\\)?" html) (match-string 0 html) (> (length (match-string 0 html)) 0)) - (setq html (replace-match "" nil t html))) - (when (> (length html) 0) - (sqlplus-execute connect-string "" nil '("set markup html off") 'no-echo 'dont-show-output-buffer) - (find-file output-file) - (erase-buffer) - (insert (concat "<html>\n" - "<head>\n" - " <meta http-equiv=\"content-type\" content=\"text/html; charset=" sqlplus-html-output-encoding "\">\n" - (sqlplus-get-context-value context :head) "\n" - "</head>\n" - "<body " (sqlplus-get-context-value context :body) ">\n" - (if header-html header-html "") - (if sqlplus-html-output-sql sql "") - "<p>" - html "\n" - "</body>\n" - "</html>")) - (goto-char (point-min)) - (save-buffer))))) - -(defun sqlplus-refine-html (html remove-entities) - (string-match "\\`\"?\\(\\(.\\|\n\\)*?\\)\"?[ \t\n]*\\'" html) - (setq html (match-string 1 html)) - (if remove-entities - (progn - (while (string-match """ html) (setq html (replace-match "\"" nil t html))) - (while (string-match "<" html) (setq html (replace-match "<" nil t html))) - (while (string-match ">" html) (setq html (replace-match ">" nil t html))) - (while (string-match "&" html) (setq html (replace-match "&" nil t html)))) - (while (string-match "&" html) (setq html (replace-match "&" nil t html))) - (while (string-match ">" html) (setq html (replace-match ">" nil t html))) - (while (string-match "<" html) (setq html (replace-match "<" nil t html))) - (while (string-match "\"" html) (setq html (replace-match """ nil t html)))) - (string-match "\\`\"?\\(\\(.\\|\n\\)*?\\)\"?[ \t\n]*\\'" html) - (setq html (match-string 1 html)) - html) - -(defun sqlplus-show-markup-fun (context connect-string begin end interrupted) - (goto-char begin) - (let ((head "") - (body "") - preformat) - (when (re-search-forward (concat "\\bHEAD\\b[ \t\n]*\\(\\(.\\|\n\\)*\\)[ \t\n]*" - "\\bBODY\\b[ \t\n]*\\(\\(.\\|\n\\)*\\)[ \t\n]*" - "\\bTABLE\\b\\(.\\|\n\\)*PREFORMAT[ \t\n]+\\(ON\\|OFF\\)\\b") nil t) - (setq head (match-string 1) - body (match-string 3) - preformat (string= (downcase (match-string 6)) "on")) - (setq head (sqlplus-refine-html head t) - body (sqlplus-refine-html body t)) - (let ((context-options (list (cons :result-function 'sqlplus-show-html-fun) - (cons :current-command-input-buffer-name (sqlplus-get-context-value context :current-command-input-buffer-name)) - (cons :html-command (sqlplus-get-context-value context :html-command)) - (cons :htmlized-html-command (sqlplus-get-context-value context :htmlized-html-command)) - (cons :head head) - (cons :body body))) - (prolog-commands (list "set wrap on" - (format "set linesize %S" (if preformat (1- (frame-width)) 4000)) - "set pagesize 50000" - "btitle off" - "repfooter off" - "set markup html on"))) - (sqlplus-execute connect-string (sqlplus-get-context-value context :html-command) context-options prolog-commands 'no-echo 'dont-show-output-buffer))))) - -(defun sqlplus-htmlize (begin end) - (let (result) - (when (featurep 'htmlize) - (let* ((htmlize-output-type 'font) - (buffer (funcall (symbol-function 'htmlize-region) begin end))) - (with-current-buffer buffer - (goto-char 1) - (re-search-forward "<pre>[ \t\n]*\\(\\(.\\|\n\\)*?\\)[ \t\n]*</pre>" nil t) - (setq result (concat "<pre>" (match-string 1) "</pre>"))) - (kill-buffer buffer))) - (unless result - (setq result (sqlplus-refine-html (buffer-substring begin end) nil))) - result)) - -(defun sqlplus--send (connect-string sql &optional arg no-echo html start end) - (if html - (let* ((context-options (list (cons :result-function 'sqlplus-show-markup-fun) - (cons :current-command-input-buffer-name (buffer-name)) - (cons :html-command sql) - (cons :htmlized-html-command (if (and (eq sqlplus-html-output-sql 'elegant) (featurep 'htmlize)) - (sqlplus-htmlize start end) - (sqlplus-refine-html sql nil)))))) - (sqlplus-execute connect-string "show markup\n" context-options nil 'no-echo 'dont-show-output-buffer)) - (let* ((no-parse (consp arg)) - (context-options (list (cons :dont-parse-result (consp arg)) - (cons :columns-count (if (integerp arg) - (if (zerop arg) nil arg) - (if sqlplus-multi-output-tables-default-flag nil 1))) - (cons :current-command-input-buffer-name (buffer-name)))) - (prolog-commands (list (format "set wrap %s" (if no-parse "on" sqlplus-default-wrap)) - (format "set linesize %s" (if (consp arg) (1- (frame-width)) 4000)) - (format "set pagesize %S" (if no-parse 50000 sqlplus-pagesize)) - (format "btitle %s" - (if no-parse "off" (concat "left '" sqlplus-page-separator "'"))) - (format "repfooter %s" - (if no-parse "off" (concat "left '" sqlplus-repfooter "'")))))) - (sqlplus-execute connect-string sql context-options prolog-commands no-echo)))) - -(defun sqlplus-explain () - (interactive) - (sqlplus-check-connection) - (when (buffer-file-name) - (condition-case err - (save-buffer) - (error (message (error-message-string err))))) - (let* ((region (sqlplus-mark-current))) - (setq sqlplus-region-beginning-pos (car region) - sqlplus-region-end-pos (cdr region)) - (if (and sqlplus-region-beginning-pos sqlplus-region-end-pos) - (let ((sql (sqlplus-parse-region (car region) (cdr region))) - (case-fold-search t)) - (if (string-match "^[\n\t ]*explain[\n\t ]+plan[\t\t ]+for\\>" sql) - (sqlplus--send sqlplus-connect-string sql nil nil nil) - (setq sql (concat (sqlplus-fontify-string sqlplus-connect-string "explain plan for ") sql)) - (sqlplus--send sqlplus-connect-string sql nil nil nil))) - (error "Point doesn't indicate any command to execute")))) - -(defun sqlplus-send-region (arg start end &optional no-echo html) - "Send a region to the SQL*Plus process." - (interactive "P\nr") - (sqlplus-check-connection) - (sqlplus--send sqlplus-connect-string (sqlplus-parse-region start end) arg no-echo html start end)) - -(defun sqlplus-user-command (connect-string sql result-proc) - (let* ((context-options (list (cons :user-function result-proc) - (cons :columns-count 1))) - (prolog-commands (list (format "set wrap %s" sqlplus-default-wrap) - "set linesize 4000" - "set timing off" - "set pagesize 50000" - "btitle off" - (format "repfooter %s" (concat "left '" sqlplus-repfooter "'"))))) - (sqlplus-execute connect-string sql context-options prolog-commands 'no-echo 'dont-show-output-buffer))) - - -(defun sqlplus-hidden-select (connect-string sql result-proc) - (let* ((context-options (list (cons :result-table-function result-proc) - (cons :columns-count 1))) - (prolog-commands (list (format "set wrap %s" sqlplus-default-wrap) - "set linesize 4000" - "set pagesize 50000" - "btitle off" - (format "repfooter %s" (concat "left '" sqlplus-repfooter "'"))))) - (sqlplus-execute connect-string sql context-options prolog-commands 'no-echo 'dont-show-output-buffer))) - -;; "appi[nfo]" -> '("appinfo" "appi") -(defun sqlplus-full-forms (name) - (if (string-match "\\`\\([^[]*\\)?\\[\\([^]]+\\)\\]\\([^]]*\\)?\\'" name) - (list (replace-match "\\1\\2\\3" t nil name) - (replace-match "\\1\\3" t nil name)) - (list name))) - -(defun sqlplus-get-canonical-command-name (name) - (let ((association (assoc (downcase name) sqlplus-system-variables))) - (if association (cdr association) name))) - - -(defun sqlplus-execute (connect-string sql context-options prolog-commands &optional no-echo dont-show-output-buffer) - (sqlplus-verify-buffer connect-string) - (let* ((process-buffer-name (sqlplus-get-process-buffer-name connect-string)) - (process-buffer (get-buffer process-buffer-name)) - (output-buffer-name (sqlplus-get-output-buffer-name connect-string)) - (echo-prolog (concat "\n" sqlplus-output-separator " " (current-time-string) "\n\n")) - (process (get-buffer-process process-buffer-name)) - set-prolog-commands commands command-no - (history-buffer (sqlplus-get-history-buffer connect-string)) - (defines (sqlplus-define-user-variables sql))) - (setq prolog-commands (append (sqlplus-initial-strings) prolog-commands)) - (when process-buffer - (with-current-buffer process-buffer - (setq command-no sqlplus-command-seq) - (incf sqlplus-command-seq) - (setq context-options (append (list (cons :id command-no) (cons :sql sql)) (copy-list context-options))) - (setq sqlplus-command-contexts (reverse (cons context-options (reverse sqlplus-command-contexts)))))) - ;; move all "set" commands from prolog-commands to set-prolog-commands - (setq prolog-commands (delq nil (mapcar (lambda (command) (if (string-match "^\\s-*[sS][eE][tT]\\s-+" command) - (progn - (setq set-prolog-commands - (append set-prolog-commands - (list (substring command (length (match-string 0 command)))))) - nil) - command)) - prolog-commands))) - ;; remove duplicates commands from prolog-commands (last entries win) - (let (spc-alist) - (dolist (command prolog-commands) - (let* ((name (progn (string-match "^\\S-+" command) (downcase (match-string 0 command)))) - (association (assoc name spc-alist))) - (if (and association (not (equal name "define"))) - (setcdr association command) - (setq spc-alist (cons (cons name command) spc-alist))))) - (setq prolog-commands (mapcar (lambda (pair) (cdr pair)) (reverse spc-alist)))) - - (setq prolog-commands (append prolog-commands defines)) - (setq set-prolog-commands (append (list (format "sqlprompt '%s%S%s'" sqlplus-prompt-prefix command-no sqlplus-prompt-suffix)) set-prolog-commands)) - - ;; remove duplicates from set-prolog-commands (last entries win) - (let (spc-alist) - (dolist (set-command set-prolog-commands) - (let* ((name (progn (string-match "^\\S-+" set-command) (downcase (sqlplus-get-canonical-command-name (match-string 0 set-command))))) - (association (assoc name spc-alist))) - (if association - (setcdr association set-command) - (setq spc-alist (cons (cons name set-command) spc-alist))))) - (setq set-prolog-commands (mapcar (lambda (pair) (cdr pair)) (reverse spc-alist)))) - - (setq commands (concat (mapconcat 'identity (append - (list (concat "set " (mapconcat 'identity set-prolog-commands " "))) - prolog-commands - (list sql)) "\n") - "\n")) - (when history-buffer - (with-current-buffer history-buffer - (goto-char (point-max)) - (insert echo-prolog) - (insert (concat commands "\n")))) - (let ((saved-window (cons (selected-window) (window-buffer (selected-window)))) - (input-buffer (get-buffer (sqlplus-get-input-buffer-name connect-string)))) - (unless no-echo - (sqlplus-echo-in-buffer output-buffer-name echo-prolog) - (let ((old-suppress-show-output-buffer sqlplus-suppress-show-output-buffer)) - (unwind-protect - (save-selected-window - (setq sqlplus-suppress-show-output-buffer dont-show-output-buffer) - (when (and output-buffer-name - (get-buffer output-buffer-name)) - (with-current-buffer (get-buffer output-buffer-name) - (sqlplus-buffer-bottom connect-string) - (sqlplus-buffer-mark-current connect-string)))) - (setq sqlplus-suppress-show-output-buffer old-suppress-show-output-buffer))) - (sqlplus-echo-in-buffer output-buffer-name (concat sql "\n\n") nil t) - (save-selected-window - (unless dont-show-output-buffer - (when (and output-buffer-name - (get-buffer output-buffer-name)) - (with-current-buffer (get-buffer output-buffer-name) - (sqlplus-buffer-redisplay-current connect-string)))))) - (if (window-live-p (car saved-window)) - (select-window (car saved-window)) - (if (get-buffer-window (cdr saved-window)) - (select-window (get-buffer-window (cdr saved-window))) - (when (and input-buffer - (get-buffer-window input-buffer)) - (select-window (get-buffer-window input-buffer)))))) - (send-string process commands))) - -(defun sqlplus-fontify-string (connect-string string) - (let* ((input-buffer-name (sqlplus-get-input-buffer-name connect-string)) - (input-buffer (when input-buffer-name (get-buffer input-buffer-name))) - (result string)) - (when (and input-buffer (buffer-live-p input-buffer)) - (with-current-buffer input-buffer - (save-excursion - (goto-char (point-max)) - (let ((pos (point))) - (insert "\n\n") - (insert string) - (font-lock-fontify-block (+ (count "\n" string) 2)) - (setq result (buffer-substring (+ pos 2) (point-max))) - (delete-region pos (point-max)))))) - result)) - -(defvar plsql-mark-backward-list nil) - -(unless plsql-mode-map - (setq plsql-mode-map (copy-keymap sql-mode-map)) - (define-key plsql-mode-map "\M-." 'sqlplus-file-get-source) - (define-key plsql-mode-map [C-down-mouse-1] 'sqlplus-mouse-select-identifier) - (define-key plsql-mode-map [C-mouse-1] 'sqlplus-file-get-source-mouse) - (define-key plsql-mode-map "\C-c\C-g" 'plsql-begin) - (define-key plsql-mode-map "\C-c\C-q" 'plsql-loop) - (define-key plsql-mode-map "\C-c\C-z" 'plsql-if) - (define-key plsql-mode-map "\C-c\C-c" 'plsql-compile) - (define-key plsql-mode-map [tool-bar plsql-prev-mark] - (list 'menu-item "Previous mark" 'plsql-prev-mark - :image plsql-prev-mark-image - :enable 'plsql-mark-backward-list))) - -(defvar plsql-continue-anyway nil - "Local in input buffer (plsql-mode).") -(make-variable-buffer-local 'plsql-continue-anyway) - -(defun sqlplus-switch-to-buffer (buffer-or-path &optional line-no) - (if (fboundp 'ide-skel-select-buffer) - (funcall 'ide-skel-select-buffer buffer-or-path line-no) - (let ((buffer (or (and (bufferp buffer-or-path) buffer-or-path) - (find-file-noselect buffer-or-path)))) - (switch-to-buffer buffer) - (goto-line line-no)))) - -(defun plsql-prev-mark () - (interactive) - (let (finish) - (while (and plsql-mark-backward-list - (not finish)) - (let* ((marker (pop plsql-mark-backward-list)) - (buffer (marker-buffer marker)) - (point (marker-position marker))) - (set-marker marker nil) - (when (and buffer - (or (not (eq (current-buffer) buffer)) - (not (eql (point) point)))) - (sqlplus-switch-to-buffer buffer) - (goto-char point) - (setq finish t)))) - ;; (message "BACK: %S -- FORWARD: %S" plsql-mark-backward-list plsql-mark-forward-list) - (force-mode-line-update) - (sit-for 0))) - -(defun sqlplus-mouse-select-identifier (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (save-excursion - (let* ((point (posn-point (event-start event))) - (identifier (progn (goto-char point) (thing-at-point 'symbol))) - (ident-regexp (when identifier (regexp-quote identifier)))) - (push (point-marker) plsql-mark-backward-list) - (when ident-regexp - (save-excursion - (while (not (looking-at ident-regexp)) - (backward-char)) - (sqlplus-mouse-set-selection (current-buffer) (point) (+ (point) (length identifier)) 'highlight))))))) - -(defun sqlplus-file-get-source-mouse (event) - (interactive "@e") - (let (ident) - (with-selected-window (posn-window (event-start event)) - (save-excursion - (goto-char (posn-point (event-start event))) - (setq ident (thing-at-point 'symbol)))) - (sqlplus-file-get-source sqlplus-connect-string ident nil) - (sit-for 0))) - -(defun plsql-compile (&optional arg) - "Save buffer and send its content to SQL*Plus. -You must enter connect-string if buffer is disconnected; with -argument you can change connect-string even for connected -buffer." - (interactive "P") - (let (aborted - exists-show-error-command - (case-fold-search t)) - (save-window-excursion - (save-excursion - ;; ask for "/" and "show err" if absent - (let ((old-point (point)) - show-err-needed - exists-run-command best-point finish) - (goto-char (point-min)) - (setq show-err-needed (let ((case-fold-search t)) - (re-search-forward "create\\([ \t\n]+or[ \t\n]+replace\\)?[ \t\n]+\\(package\\|procedure\\|function\\|trigger\\|view\\|type\\)" nil t))) - (goto-char (point-max)) - (forward-comment (- (buffer-size))) - (re-search-backward "^\\s-*show\\s-+err" nil t) - (forward-comment (- (buffer-size))) - (condition-case nil (forward-char) (error nil)) - (setq best-point (point)) - (goto-char (point-min)) - (setq exists-run-command (re-search-forward "^\\s-*/[^*]" nil t)) - (goto-char (point-min)) - (setq exists-show-error-command (or (not show-err-needed) (re-search-forward "^\\s-*show\\s-+err" nil t))) - (while (and (not plsql-continue-anyway) (or (not exists-run-command) (not exists-show-error-command)) (not finish)) - (goto-char best-point) - (let ((c (read-char - (format "Cannot find %s. (I)nsert it at point, (A)bort, (C)ontinue anyway" - (concat (unless exists-run-command "\"/\"") - (unless (or exists-run-command exists-show-error-command) " and ") - (unless exists-show-error-command "\"show err\"")))))) - (cond ((memq c '(?i ?I)) - (unless exists-run-command (insert "/\n")) - (unless exists-show-error-command (insert "show err\n")) - (setq finish t)) - ((memq c '(?a ?A)) - (setq aborted t - finish t)) - ((memq c '(?c ?C)) - (setq plsql-continue-anyway t) - (setq finish t)))))))) - (unless aborted - (save-buffer) - (let* ((buffer (current-buffer)) - (input-buffer-name (buffer-name)) - (file-path (sqlplus-file-truename (buffer-file-name))) - (compilation-buffer (get-buffer sqlplus-plsql-compilation-results-buffer-name)) - (context-options (list (cons :last-compiled-file-path file-path) - (cons :current-command-input-buffer-name input-buffer-name) - (cons :compilation-expected exists-show-error-command))) - (prolog-commands (list (format "set wrap %s" sqlplus-default-wrap) - "set linesize 4000" - (format "set pagesize %S" sqlplus-pagesize) - (format "btitle %s" (concat "left '" sqlplus-page-separator "'")) - (format "repfooter %s" (concat "left '" sqlplus-repfooter "'"))))) - (when (or (not sqlplus-connect-string) - arg) - (setq sqlplus-connect-string (car (sqlplus-read-connect-string nil (caar (sqlplus-divide-connect-strings)))))) - (sqlplus sqlplus-connect-string nil (when plsql-auto-parse-errors-flag 'dont-show-output-buffer)) - (set-buffer buffer) - (force-mode-line-update) - (when font-lock-mode (font-lock-mode 1)) - (when compilation-buffer - (with-current-buffer compilation-buffer - (let ((inhibit-read-only t)) - (erase-buffer)))) - (setq prolog-commands (append prolog-commands (sqlplus-define-user-variables (buffer-string)))) - (sqlplus-execute sqlplus-connect-string (concat "@" file-path) context-options prolog-commands nil exists-show-error-command))))) - -(defun plsql-parse-errors (last-compiled-file-path) - (let ((file-name (file-name-nondirectory last-compiled-file-path)) - error-list) - (put-text-property 0 (length file-name) 'face 'font-lock-warning-face file-name) - (save-excursion - (when (re-search-forward "^LINE/COL\\>" nil t) - (beginning-of-line 3) - (while (re-search-forward "^\\([0-9]+\\)/\\([0-9]+\\)\\s-*\\(\\(.\\|\n\\)*?\\)[\r\t ]*\n\\([\r\t ]*\\(\n\\|\\'\\)\\|[0-9]+\\)" nil t) - (let ((line-no (match-string 1)) - (column-no (match-string 2)) - (errmsg (match-string 3)) - label) - (goto-char (match-beginning 5)) - (while (string-match "\\s-\\s-+" errmsg) - (setq errmsg (replace-match " " nil t errmsg))) - (put-text-property 0 (length line-no) 'face 'font-lock-variable-name-face line-no) - (put-text-property 0 (length column-no) 'face 'font-lock-variable-name-face column-no) - (setq label (concat file-name ":" line-no ":" column-no ": " errmsg)) - (put-text-property 0 (length label) 'mouse-face 'highlight label) - (push label error-list))))) - (save-excursion - (while (re-search-forward "\\s-\\([0-9]+\\):\n\\(ORA-[0-9]+[^\n]*\\)\n" nil t) - (let ((line-no (match-string 1)) - (errmsg (match-string 2)) - label) - (put-text-property 0 (length line-no) 'face 'font-lock-variable-name-face line-no) - (setq label (concat file-name ":" line-no ": " errmsg)) - (put-text-property 0 (length label) 'mouse-face 'highlight label) - (push label error-list)))) - (save-excursion - (while (re-search-forward "\\(\\(SP2\\|CPY\\)-[0-9]+:[^\n]*\\)\n" nil t) - (let ((errmsg (match-string 1)) - label) - (setq label (concat file-name ":" errmsg)) - (put-text-property 0 (length label) 'mouse-face 'highlight label) - (push label error-list)))) - error-list)) - -(defun plsql-display-errors (dir error-list) - (let ((buffer (get-buffer-create sqlplus-plsql-compilation-results-buffer-name))) - (save-selected-window - (save-excursion - (set-buffer buffer) - (let ((inhibit-read-only t)) - (erase-buffer) - (setq default-directory dir) - (insert (format "cd %s\n" default-directory)) - (insert (format "Compilation results\n")) - (compilation-minor-mode 1) - (dolist (msg (reverse error-list)) - (insert msg) - (insert "\n")) - (insert (format "\n(%s errors)\n" (length error-list)))) - (when (and error-list (fboundp 'compile-reinitialize-errors) (funcall (symbol-function 'compile-reinitialize-errors) t))) - (switch-to-buffer-other-window buffer) - (goto-line 1) - (goto-line 3))))) - - -(defun sqlplus-file-truename (file-name) - (if file-name - (file-truename file-name) - file-name)) - -(defun sqlplus--hidden-buffer-name-p (buffer-name) - (equal (elt buffer-name 0) 32)) - -(defun sqlplus-get-workbench-window () - "Return upper left window" - (if (fboundp 'ide-get-workbench-window) - (funcall (symbol-function 'ide-get-workbench-window)) - (let (best-window) - (dolist (win (copy-list (window-list nil 1))) - (when (not (sqlplus--hidden-buffer-name-p (buffer-name (window-buffer win)))) - (if (null best-window) - (setq best-window win) - (let* ((best-window-coords (window-edges best-window)) - (win-coords (window-edges win))) - (when (or (< (cadr win-coords) (cadr best-window-coords)) - (and (= (cadr win-coords) (cadr best-window-coords)) - (< (car win-coords) (car best-window-coords)))) - (setq best-window win)))))) - ;; (message "BEST-WINDOW: %S" best-window) - best-window))) - -(defun sqlplus-get-side-window () - "Return bottom helper window, or nil if not found" - (if (fboundp 'ide-get-side-window) - (funcall (symbol-function 'ide-get-side-window)) - (let* ((workbench-window (sqlplus-get-workbench-window)) - best-window) - (dolist (win (copy-list (window-list nil 1))) - (when (and (not (sqlplus--hidden-buffer-name-p (buffer-name (window-buffer win)))) - (not (eq win workbench-window))) - (if (null best-window) - (setq best-window win) - (when (> (cadr (window-edges win)) (cadr (window-edges best-window))) - (setq best-window win))))) - best-window))) - -(defvar sqlplus--idle-tasks nil) - -(defun sqlplus--enqueue-task (fun &rest params) - (setq sqlplus--idle-tasks (reverse (cons (cons fun params) (reverse sqlplus--idle-tasks))))) - -(defun sqlplus--execute-tasks () - (dolist (task sqlplus--idle-tasks) - (let ((fun (car task)) - (params (cdr task))) - (condition-case var - (apply fun params) - (error (message (error-message-string var)))))) - (setq sqlplus--idle-tasks nil)) - -(add-hook 'post-command-hook 'sqlplus--execute-tasks) - -(defvar sqlplus-mouse-selection nil) - -(defun sqlplus-mouse-set-selection (buffer begin end mouse-face) - (interactive "@e") - (let ((old-buffer-modified-p (buffer-modified-p))) - (when (buffer-live-p buffer) - (with-current-buffer buffer - (unwind-protect - (put-text-property begin end 'mouse-face mouse-face) - (set-buffer-modified-p old-buffer-modified-p) - (setq sqlplus-mouse-selection (when mouse-face (list buffer begin end)))))))) - -(defun sqlplus-clear-mouse-selection () - (when (and sqlplus-mouse-selection - (eq (event-basic-type last-input-event) 'mouse-1) - (not (memq 'down (event-modifiers last-input-event)))) - (sqlplus-mouse-set-selection (car sqlplus-mouse-selection) (cadr sqlplus-mouse-selection) (caddr sqlplus-mouse-selection) nil))) - -(add-hook 'plsql-mode-hook - (lambda () - (modify-syntax-entry ?. "." sql-mode-syntax-table) - (setq sqlplus-font-lock-keywords-1 (sqlplus-set-font-lock-emacs-structures-for-level 1 major-mode)) - (setq sqlplus-font-lock-keywords-2 (sqlplus-set-font-lock-emacs-structures-for-level 2 major-mode)) - (setq sqlplus-font-lock-keywords-3 (sqlplus-set-font-lock-emacs-structures-for-level 3 major-mode)) - (setq font-lock-defaults '((sqlplus-font-lock-keywords-1 sqlplus-font-lock-keywords-2 sqlplus-font-lock-keywords-3) - nil t ((?_ . "w") (?$ . "w") (?# . "w") (?& . "w")))) - (orcl-mode 1) - (use-local-map plsql-mode-map) ; std - (add-hook 'post-command-hook 'sqlplus-clear-mouse-selection nil t))) - -(setq recentf-exclude (cons (concat "^" (regexp-quote (file-name-as-directory temporary-file-directory))) - (when (boundp 'recentf-exclude) - recentf-exclude))) - -(when (fboundp 'ide-register-persistent-var) - (funcall (symbol-function 'ide-register-persistent-var) 'sqlplus-connect-strings-alist - ;; save proc - (lambda (alist) - (mapcar (lambda (pair) - (if sqlplus-save-passwords - pair - (cons (car pair) nil))) - alist)) - ;; load proc - (lambda (alist) - (setq sqlplus-connect-string-history (mapcar (lambda (pair) (car pair)) alist)) - alist))) - -(defun get-all-dirs (root-dir) - (let ((list-to-see (list root-dir)) - result-list) - (while list-to-see - (let* ((dir (pop list-to-see)) - (children (directory-files dir t))) - (push dir result-list) - (dolist (child children) - (when (and (not (string-match "^[.]+"(file-name-nondirectory child))) - (file-directory-p child)) - (push child list-to-see))))) - result-list)) - -(defun sqlplus-command-line () - (interactive) - (if (comint-check-proc "*SQL*") - (pop-to-buffer "*SQL*") - (let* ((pair (sqlplus-read-connect-string nil (when sqlplus-connect-string (car (refine-connect-string sqlplus-connect-string))))) - (qualified-cs (car pair)) - (refined-cs (cadr pair)) - (password (cdr (refine-connect-string qualified-cs)))) - (if (string-match "^\\([^@]*\\)@\\(.*\\)$" refined-cs) - (let ((old-sql-get-login-fun (symbol-function 'sql-get-login))) - (setq sql-user (match-string 1 refined-cs) - sql-password password - sql-database (match-string 2 refined-cs)) - (unwind-protect - (progn - (fset 'sql-get-login (lambda (&rest whatever) nil)) - (sql-oracle)) - (fset 'sql-get-login old-sql-get-login-fun))) - (error "Connect string must be in form login@sid"))))) - -(defun sqlplus-find-tnsnames () - (interactive) - (let* ((ora-home-dir (or (getenv "ORACLE_HOME") (error "Environment variable ORACLE_HOME not set"))) - found - (list-to-see (list ora-home-dir))) - (while (and (not found) list-to-see) - (let* ((dir (pop list-to-see)) - (children (condition-case nil (directory-files dir t) (error nil)))) - (dolist (child children) - (unless found - (if (string-match "admin.tnsnames\.ora$" child) - (progn - (setq found t) - (find-file child)) - (if (and (not (string-match "^[.]+" (file-name-nondirectory child))) - (file-directory-p child)) - (push child list-to-see))))))) - (unless found - (message "File tnsnames.ora not found")))) - -(defun sqlplus-remove-help-echo (list) - "Remove all HELP-ECHO properties from mode-line format value" - (when (listp list) - (if (eq (car list) :propertize) - (while list - (when (eq (cadr list) 'help-echo) - (setcdr list (cdddr list))) - (setq list (cdr list))) - (dolist (elem list) (sqlplus-remove-help-echo elem))))) - -(when (>= emacs-major-version 22) - (sqlplus-remove-help-echo mode-line-modes)) - -(defun sqlplus-get-project-root-dir (path) - (let ((path (file-truename (substitute-in-file-name path))) - dir) - (if (file-directory-p path) - (progn - (setq path (file-name-as-directory path)) - (setq dir path)) - (setq dir (file-name-as-directory (file-name-directory path)))) - (let ((last-project-dir dir) - (dir-list (split-string dir "/")) - is-project) - (while (directory-files dir t (concat "^" "\\(\\.svn\\|CVS\\)$") t) - (setq is-project t - last-project-dir (file-name-as-directory dir) - dir (file-name-as-directory (file-name-directory (directory-file-name dir))))) - (when is-project - (let ((list (nthcdr (1- (length (split-string last-project-dir "/"))) dir-list))) - (cond ((equal (car list) "trunk") - (setq last-project-dir (concat last-project-dir "trunk/"))) - ((member (car list) '("branches" "tags")) - (setq last-project-dir (concat last-project-dir (car list) "/" (when (cdr list) (concat (cadr list) "/"))))) - (t))) - (setq dir last-project-dir))) - dir)) - -(defvar sqlplus-search-buffer-name "*search*") - -(defvar sqlplus-object-types-regexps - '( - ("TABLE" . "\\bcreate\\s+table\\s+[^(]*?\\b#\\b") - ("VIEW" . "\\bview\\s+.*?\\b#\\b") - ("INDEX" . "\\b(constraint|index)\\s+.*?\\b#\\b") - ("TRIGGER" . "\\btrigger\\s+.*?\\b#\\b") - ("SEQUENCE" . "\\bsequence\\s+.*?\\b#\\b") - ("SYNONYM" . "\\bsynonym\\s+.*?\\b#\\b") - ("SCHEMA" . "\\bcreate\\b.*?\\buser\\b.*?\\b#\\b") - ("PROCEDURE" . "\\b(procedure|function)\\b[^(]*?\\b#\\b") - ("PACKAGE" . "\\bpackage\\s+.*?\\b#\\b"))) - -(defvar sqlplus-root-dir-history nil) - -(defvar sqlplus-compare-report-buffer-name "*Comparation Report*") - -(defun sqlplus-compare-schema-to-filesystem (&optional arg) - (interactive "P") - (let* ((connect-string sqlplus-connect-string) - (objects-alist (sqlplus-get-objects-alist sqlplus-connect-string)) - (report-buffer (get-buffer-create sqlplus-compare-report-buffer-name)) - (types-length (- (length objects-alist) 2)) - (root-dir (or (sqlplus-get-root-dir connect-string) - (sqlplus-set-project-for-connect-string connect-string) - (error "Root dir not set"))) - (counter 0)) - (unless objects-alist - (error "Not ready yet - try again later")) - (save-excursion - (switch-to-buffer-other-window report-buffer)) - (with-current-buffer report-buffer - (let ((inhibit-read-only t)) - (erase-buffer) - (insert (format "%s %s vs. %s\n\n" (current-time-string) (car (refine-connect-string connect-string)) root-dir)) - (sit-for 0))) - (dolist (pair objects-alist) - (let ((type (upcase (format "%s" (car pair)))) - (names (cdr pair))) - (unless (member type '("SCHEMA" "COLUMN")) - (incf counter) - (message (format "%s (%d/%d)..." type counter types-length)) - (dolist (name-pair names) - (let* ((name (car name-pair)) - (grep-result (sqlplus-file-get-source sqlplus-connect-string name type 'batch-mode))) - (with-current-buffer report-buffer - (let ((inhibit-read-only t)) - (goto-char (point-max)) - (cond ((eql (length grep-result) 0) - (insert (format "%s %s: not found\n" type name)) - (sit-for 0)) - ((and arg - (> (length grep-result) 1)) - (insert (format "%s %s:\n" type name)) - (dolist (list grep-result) - (insert (format " %s:%d %s\n" (car list) (cadr list) (caddr list)))) - (sit-for 0)) - (t))))))))) - (message "Done.") - (with-current-buffer report-buffer - (goto-char (point-min))))) - -(defun sqlplus-proj-find-files (dir file-predicate &optional dir-predicate) - (setq dir (file-name-as-directory (file-truename (substitute-in-file-name dir)))) - (let (result-list) - (mapcar (lambda (path) - (if (file-directory-p path) - (when (and (file-accessible-directory-p path) - (or (null dir-predicate) - (funcall dir-predicate path))) - (setq result-list (append result-list (sqlplus-proj-find-files path file-predicate dir-predicate)))) - (when (or (null file-predicate) - (funcall file-predicate path)) - (push path result-list)))) - (delete (concat (file-name-as-directory dir) ".") - (delete (concat (file-name-as-directory dir) "..") - (directory-files dir t nil t)))) - result-list)) - -(defvar sqlplus-proj-ignored-extensions '("semantic.cache")) - -(defun sqlplus-mode-file-regexp-list (mode-symbol-list) - (delq nil (mapcar (lambda (element) - (let ((fun-name (if (listp (cdr element)) (cadr element) (cdr element)))) - (when (memq fun-name mode-symbol-list) (cons (car element) fun-name)))) - auto-mode-alist))) - -(defun sqlplus-find-project-files (root-dir mode-symbol-list predicate) - (let ((obj-file-regexp-list (delq nil (mapcar (lambda (element) - (let ((len (length element))) - (unless (and (> len 0) - (equal (elt element (1- len)) ?/)) - (concat (regexp-quote element) "$")))) - (append sqlplus-proj-ignored-extensions completion-ignored-extensions)))) - (mode-file-regexp-list (sqlplus-mode-file-regexp-list mode-symbol-list))) ; (file-path-regexp . major-mode-function-symbol) - (when (and mode-symbol-list - (not mode-file-regexp-list)) - (error (format "No rules for %s major modes in auto-mode-alist." (mapconcat 'identity mode-symbol-list ", ")))) - (sqlplus-proj-find-files root-dir - (lambda (file-name) - (and (not (string-match "#" file-name)) - (not (string-match "semantic.cache" file-name)) - (or (and (not mode-symbol-list) - (not (some (lambda (regexp) - (string-match regexp file-name)) - obj-file-regexp-list))) - (and mode-symbol-list - (some (lambda (element) - (let ((freg (if (string-match "[$]" (car element)) - (car element) - (concat (car element) "$")))) - (when (string-match freg file-name) - (cdr element)))) - mode-file-regexp-list))) - (or (not predicate) - (funcall predicate file-name)))) - (lambda (dir-path) - (not (string-match "/\\(\\.svn\\|CVS\\)$" dir-path)))))) - - -(defun sqlplus-file-get-source (connect-string object-name object-type &optional batch-mode) - (interactive - (progn - (push (point-marker) plsql-mark-backward-list) - (list sqlplus-connect-string (thing-at-point 'symbol) nil))) - (unless object-name - (error "Nothing to search")) - (let* ((root-dir (or (and (not object-type) - (eq major-mode 'plsql-mode) - (buffer-file-name) - (sqlplus-get-project-root-dir (buffer-file-name))) - (sqlplus-get-root-dir connect-string) - (sqlplus-set-project-for-connect-string connect-string) - (error "Root dir not set"))) - (mode-symbol-list '(plsql-mode sql-mode)) - (files-to-grep (sqlplus-find-project-files root-dir mode-symbol-list nil)) - (temp-file-path (concat (file-name-as-directory temporary-file-directory) (make-temp-name "ide-"))) - (search-buffer (get-buffer sqlplus-search-buffer-name)) - (regexp (let ((index 0) - (len (length object-name)) - result) - (setq result - (if object-type - (let ((type (cond ((equal object-type "FUNCTION") "PROCEDURE") - ((equal object-type "PACKAGE BODY") "PACKAGE") - (t object-type)))) - (cdr (assoc type sqlplus-object-types-regexps))) - (mapconcat 'cdr sqlplus-object-types-regexps "|"))) - (unless result - (error "Not implemented")) - (while (and (< index (length result)) - (string-match "#" result index)) - (setq index (+ (match-beginning 0) len)) - (setq result (replace-match object-name t t result))) - (setq index 0) - (while (and (< index (length result)) - (string-match "[$]\\(\\\\b\\)?" result index)) - (setq index (+ (match-end 0) 1)) - (setq result (replace-match "\\$" t t result))) - result)) - grep-command - grep-result) - (when search-buffer - (with-current-buffer search-buffer - (let ((inhibit-read-only t)) - (erase-buffer)))) - ;; (message "Object type: %S, object name: %S, regexp: %S" object-type object-name regexp) - (with-temp-file temp-file-path - (dolist (path files-to-grep) - (insert (concat "'" path "'\n")))) - (let* ((grep-command (format "cat %s | xargs grep -nHiE -e '%s'" temp-file-path regexp)) - (raw-grep-result (split-string (shell-command-to-string grep-command) "\n" t)) - (grep-result (delq nil (mapcar (lambda (line) - (string-match "^\\(.*?\\):\\([0-9]+\\):\\(.*\\)$" line) - (let* ((path (match-string 1 line)) - (line-no (string-to-number (match-string 2 line))) - (text (match-string 3 line)) - (text2 text) - (syn-table (copy-syntax-table)) - (case-fold-search t)) - (modify-syntax-entry ?$ "w" syn-table) - (modify-syntax-entry ?# "w" syn-table) - (modify-syntax-entry ?_ "w" syn-table) - (with-syntax-table syn-table - (when (and (or (and (not object-type) - (> (length raw-grep-result) 1)) - (equal object-type "SYNONYM")) - (string-match "\\<\\(for\\|from\\|on\\|as\\)\\>" text2)) - (setq text2 (substring text2 0 (match-beginning 0)))) - ;; (message "GREP-RESULT: %s" text2) - (unless (or (not (string-match (concat "\\<" (regexp-quote object-name) "\\>") text2)) - (string-match (concat "\\(--\\|\\<pro\\>\\|\\<prompt\\>\\|\\<drop\\>\\|\\<grant\\>\\).*\\<" - (regexp-quote object-name) "\\>") text2) - (and (or (and (not object-type) - (> (length raw-grep-result) 1)) - (equal object-type "TRIGGER")) - (string-match "\\<\\(alter\\|disable\\|enable\\)\\>" text2)) - (and (or (and (not object-type) - (string-match "\\<package\\>" text2) - current-prefix-arg) - (equal object-type "PACKAGE")) - (string-match "\\<body\\>" text2)) - (and (or (and (not object-type) - (string-match "\\<package\\>" text2) - (not current-prefix-arg)) - (equal object-type "PACKAGE BODY")) - (not (string-match "\\<body\\>" text2))) - (and (not object-type) - (not current-prefix-arg) - (string-match "[.]pks$" path))) - (list path line-no text))))) - raw-grep-result)))) - (if batch-mode - grep-result - (cond ((not grep-result) - (error "Not found")) - ((eql (length grep-result) 1) - (sqlplus-switch-to-buffer (caar grep-result) (cadar grep-result)) - (when connect-string - (setq sqlplus-connect-string connect-string))) - (t - (let ((search-buffer (get-buffer-create sqlplus-search-buffer-name))) - (with-current-buffer search-buffer - (setq buffer-read-only t) - (let ((inhibit-read-only t)) - (setq default-directory root-dir) - (erase-buffer) - (insert "Root dir: ") - (sqlplus-proj-insert-with-face root-dir 'font-lock-keyword-face) - (insert "; Range: ") - (sqlplus-proj-insert-with-face (mapconcat (lambda (sym) (sqlplus-mode-name-stringify sym)) mode-symbol-list ", ") - 'font-lock-keyword-face) - (insert "; Object type: ") - (sqlplus-proj-insert-with-face (or object-type "unspecified") 'font-lock-keyword-face) - (insert "; Object name: ") - (sqlplus-proj-insert-with-face object-name 'font-lock-keyword-face) - (insert "\n\n") - (compilation-minor-mode 1) - (dolist (result grep-result) - (let ((relative-path (concat "./" (file-relative-name (car result) root-dir))) - (line-no (cadr result)) - (text (caddr result))) - (put-text-property 0 (length relative-path) 'mouse-face 'highlight relative-path) - (insert relative-path) - (insert (format ":%S:1 %s\n" line-no text)))) - (insert (format "\n%d matches found." (length grep-result))) - (goto-char (point-min)) - (when (and grep-result (fboundp 'compile-reinitialize-errors) (funcall (symbol-function 'compile-reinitialize-errors) t))) - (switch-to-buffer-other-window search-buffer) - (goto-line 1) - (goto-line 3)))))))))) - -(defun sqlplus-mode-name-stringify (mode-name) - (let ((name (format "%s" mode-name))) - (replace-regexp-in-string "-" " " - (capitalize - (if (string-match "^\\(.*\\)-mode" name) - (match-string 1 name) - name))))) - -(defun sqlplus-proj-insert-with-face (string face) - (let ((point (point))) - (insert string) - (let ((overlay (make-overlay point (point)))) - (overlay-put overlay 'face face)))) - -(defun sqlplus-set-project-for-connect-string (connect-string) - (if (featurep 'ide-skel) - ;; Prepare sqlplus-root-dir-history (file-name-history) for user convenience - ;; 0. previous project root - ;; 1. current editor file project root - ;; 2. previous choices - ;; 3. new project roots - (let* ((prev-proj-root-dir (sqlplus-get-root-dir connect-string)) - (last-sel-window (funcall 'ide-skel-get-last-selected-window)) - (editor-file-proj-root-dir (when last-sel-window - (let* ((buffer (window-buffer last-sel-window)) - (path (and buffer (buffer-file-name buffer))) - (project (and path (car (funcall 'ide-skel-proj-get-project-create path))))) - (when (funcall 'ide-skel-project-p project) - (funcall 'ide-skel-project-root-path project)))))) - (setq sqlplus-root-dir-history - (delete-dups - (delq nil - (mapcar (lambda (dir) - (when dir - (directory-file-name (file-truename (substitute-in-file-name dir))))) - (append - (list editor-file-proj-root-dir prev-proj-root-dir) - sqlplus-root-dir-history - (mapcar (lambda (project) (funcall 'ide-skel-project-root-path project)) - (symbol-value 'ide-skel-projects))))))) - (let* ((file-name-history (cdr sqlplus-root-dir-history)) - (use-file-dialog nil) - (dir (directory-file-name (file-truename (substitute-in-file-name - (read-directory-name (format "Root dir for %s: " (car (refine-connect-string connect-string))) - (car sqlplus-root-dir-history) - (car sqlplus-root-dir-history) - t - nil)))))) - (funcall 'ide-skel-proj-get-project-create dir) - (sqlplus-set-root-dir dir connect-string) - (message (format "Root dir for %s set to %s" (car (refine-connect-string connect-string)) dir)) - dir)) - (let* ((use-file-dialog nil) - (dir (directory-file-name (file-truename (substitute-in-file-name - (read-directory-name (format "Root dir for %s: " (car (refine-connect-string connect-string))) - nil nil t nil)))))) - (sqlplus-set-root-dir dir connect-string) - (message (format "Root dir for %s set to %s" (car (refine-connect-string connect-string)) dir)) - dir))) - -;;; Plugin for ide-skel.el - -(defstruct sqlplus-tab - id - name ; tab name - symbol ; view/sequence/schema/trigger/index/table/package/synonym/procedure - help-string - (display-start 1) ; display-start in side view window - (data nil) ; '(("name" . status)...), where status t means 'invalid' - draw-function ; parameters: sqlplus-tab - click-function ; parameters: event "@e" - (errors-count 0) - (refresh-in-progress t) - update-select) - -(defvar sqlplus-side-view-connect-string nil) -(make-variable-buffer-local 'sqlplus-side-view-connect-string) - -(defvar sqlplus-side-view-active-tab nil) -(make-variable-buffer-local 'sqlplus-side-view-active-tab) - -(defvar sqlplus-side-view-tabset nil) -(make-variable-buffer-local 'sqlplus-side-view-tabset) - -(defface sqlplus-side-view-face '((t :inherit variable-pitch :height 0.8)) - "Default face used in right view" - :group 'sqlplus) - -(defvar sqlplus-side-view-keymap nil) -(unless sqlplus-side-view-keymap - (setq sqlplus-side-view-keymap (make-sparse-keymap)) - (define-key sqlplus-side-view-keymap [mode-line down-mouse-1] 'ignore) - (define-key sqlplus-side-view-keymap [mode-line mouse-1] 'sqlplus-side-view-tab-click)) - -(defun sqlplus-side-view-tab-click (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((previous-sel-tab-info (nth sqlplus-side-view-active-tab sqlplus-side-view-tabset)) - (target (posn-string (event-start event))) - (tab-info (get-text-property (cdr target) 'tab-info (car target)))) - (setf (sqlplus-tab-display-start previous-sel-tab-info) (line-number-at-pos (window-start))) - (setq sqlplus-side-view-active-tab (sqlplus-tab-id tab-info)) - (sqlplus-side-view-redraw (current-buffer) t) - (sqlplus-side-view-buffer-mode-line)))) - -(defun sqlplus-side-view-buffer-mode-line () - (let* ((separator (propertize " " - 'face 'header-line - 'display '(space :width 0.2) - 'pointer 'arrow))) - (setq mode-line-format - (concat separator - (mapconcat (lambda (tab) - (let ((face (if (eq (sqlplus-tab-id tab) sqlplus-side-view-active-tab) - 'tabbar-selected - 'tabbar-unselected)) - (help-echo (concat (sqlplus-tab-help-string tab) - (if (> (sqlplus-tab-errors-count tab) 0) - (format "\n(%s error%s)" (sqlplus-tab-errors-count tab) - (if (> (sqlplus-tab-errors-count tab) 1) "s" "")) - "")))) - (propertize (format " %s " (sqlplus-tab-name tab)) - 'local-map sqlplus-side-view-keymap - 'tab-info tab - 'help-echo help-echo - 'mouse-face 'tabbar-highlight - 'face (if (> (sqlplus-tab-errors-count tab) 0) - (list '(foreground-color . "red") face) - face) - 'pointer 'hand))) - sqlplus-side-view-tabset - separator) - separator)))) - -(defun sqlplus-side-view-click-on-default-handler (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((posn-point (posn-point (event-start event))) - (object-name (get-text-property posn-point 'object-name)) - (object-type (get-text-property posn-point 'object-type)) - (type (car event))) - (when (eq type 'mouse-3) - (setq type (car (x-popup-menu t (append (list 'keymap object-name) - (list '(sqlplus-refresh-side-view-buffer "Refresh" t)) - (list '(mouse-1 "Get source from Oracle" t)) - (list '(M-mouse-1 "Search source in filesystem" t)) - (list (list 'C-M-mouse-1 (concat "Set root dir for " (car (refine-connect-string sqlplus-side-view-connect-string))) t)) - ))))) - (cond ((eq type 'mouse-1) - (sqlplus-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'C-M-mouse-1) - (sqlplus-set-project-for-connect-string sqlplus-side-view-connect-string)) - ((eq type nil)) - (t - (condition-case err - (funcall type) - (error nil))))))) - -(defun sqlplus-side-view-click-on-index-handler (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((posn-point (posn-point (event-start event))) - (object-name (get-text-property posn-point 'object-name)) - (object-type (get-text-property posn-point 'object-type)) - (type (car event))) - (when (eq type 'mouse-3) - (setq type (car (x-popup-menu t (append (list 'keymap object-name) - (list '(sqlplus-refresh-side-view-buffer "Refresh" t)) - (list '(mouse-1 "Get source from Oracle" t)) - (list '(M-mouse-1 "Search source in filesystem" t)) - (list (list 'C-M-mouse-1 (concat "Set root dir for " (car (refine-connect-string sqlplus-side-view-connect-string))) t)) - ))))) - (cond ((eq type 'mouse-1) - (sqlplus-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'C-M-mouse-1) - (sqlplus-set-project-for-connect-string sqlplus-side-view-connect-string)) - ((eq type nil)) - (t - (condition-case err - (funcall type) - (error nil))))))) - -(defun sqlplus-side-view-click-on-schema-handler (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((posn-point (posn-point (event-start event))) - (object-name (get-text-property posn-point 'object-name)) - (object-type (get-text-property posn-point 'object-type)) - (last-selected-win (funcall 'ide-skel-get-last-selected-window)) - (type (car event))) - (when (eq type 'mouse-3) - (setq type (car (x-popup-menu t (append (list 'keymap object-name) - (list '(sqlplus-refresh-side-view-buffer "Refresh" t)) - (list '(mouse-1 "Connect to schema" t)) - (list '(M-mouse-1 "Search source in filesystem" t)) - (list (list 'C-M-mouse-1 (concat "Set root dir for " (car (refine-connect-string sqlplus-side-view-connect-string))) t)) - ))))) - (cond ((eq type 'mouse-1) - (when (string-match "@.*$" sqlplus-side-view-connect-string) - (let* ((cs (downcase (concat object-name (match-string 0 sqlplus-side-view-connect-string)))) - (pair (sqlplus-read-connect-string cs cs))) - (select-window (or last-selected-win (funcall 'ide-skel-get-editor-window))) - (sqlplus (car pair) (concat (cadr pair) (concat "." sqlplus-session-file-extension)))))) - ((eq type 'M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'C-M-mouse-1) - (sqlplus-set-project-for-connect-string sqlplus-side-view-connect-string)) - ((eq type nil)) - (t - (condition-case err - (funcall type) - (error nil)))) - (select-window (funcall 'ide-skel-get-last-selected-window))))) - -(defun sqlplus-side-view-click-on-table-handler (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((posn-point (posn-point (event-start event))) - (object-name (get-text-property posn-point 'object-name)) - (object-type (get-text-property posn-point 'object-type)) - (type (car event))) - (when (eq type 'mouse-3) - (setq type (car (x-popup-menu t (append (list 'keymap object-name) - (list '(sqlplus-refresh-side-view-buffer "Refresh" t)) - (list '(mouse-1 "Show description" t)) - (list '(C-mouse-1 "Select *" t)) - (list '(S-mouse-1 "Get source from Oracle" t)) - (list '(M-mouse-1 "Search source in filesystem" t)) - (list (list 'C-M-mouse-1 (concat "Set root dir for " (car (refine-connect-string sqlplus-side-view-connect-string))) t)) - ))))) - (cond ((eq type 'mouse-1) - (sqlplus-execute sqlplus-side-view-connect-string - (sqlplus-fontify-string sqlplus-side-view-connect-string (format "desc %s;" object-name)) - nil nil)) - ((eq type 'C-mouse-1) - (sqlplus-execute sqlplus-side-view-connect-string - (sqlplus-fontify-string sqlplus-side-view-connect-string (format "select * from %s;" object-name)) - nil nil)) - ((eq type 'S-mouse-1) - (sqlplus-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'C-M-mouse-1) - (sqlplus-set-project-for-connect-string sqlplus-side-view-connect-string)) - ((eq type nil)) - (t - (condition-case err - (funcall type) - (error nil)))) - (select-window (funcall 'ide-skel-get-last-selected-window))))) - -(defun sqlplus-side-view-click-on-package-handler (event) - (interactive "@e") - (with-selected-window (posn-window (event-start event)) - (let* ((posn-point (posn-point (event-start event))) - (object-name (get-text-property posn-point 'object-name)) - (object-type (get-text-property posn-point 'object-type)) - (type (car event))) - (when (eq type 'mouse-3) - (setq type (car (x-popup-menu t (append (list 'keymap object-name) - (list '(sqlplus-refresh-side-view-buffer "Refresh" t)) - (list '(S-mouse-1 "Get package header from Oracle" t)) - (list '(mouse-1 "Get package body from Oracle" t)) - (list '(S-M-mouse-1 "Search header source in filesystem" t)) - (list '(M-mouse-1 "Search body source in filesystem" t)) - (list (list 'C-M-mouse-1 (concat "Set root dir for " (car (refine-connect-string sqlplus-side-view-connect-string))) t)) - ))))) - (cond ((eq type 'S-mouse-1) - (sqlplus-get-source sqlplus-side-view-connect-string object-name object-type)) - ((eq type 'mouse-1) - (sqlplus-get-source sqlplus-side-view-connect-string object-name "PACKAGE BODY")) - ((eq type 'M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name "PACKAGE BODY")) - ((eq type 'S-M-mouse-1) - (sqlplus-file-get-source sqlplus-side-view-connect-string object-name "PACKAGE")) - ((eq type 'C-M-mouse-1) - (sqlplus-set-project-for-connect-string sqlplus-side-view-connect-string)) - ((eq type nil)) - (t - (condition-case err - (funcall type) - (error nil))))))) - -(defun sqlplus-side-view-default-draw-panel (tab-info click-function) - (let ((pairs (sort (sqlplus-tab-data tab-info) - (lambda (pair1 pair2) (string< (car pair1) (car pair2))))) - (type-name (upcase (symbol-name (sqlplus-tab-symbol tab-info))))) - (dolist (pair pairs) - (let* ((label (format " % -100s" (car pair))) - (km (make-sparse-keymap))) - (define-key km [down-mouse-1] 'ignore) - (define-key km [mouse-1] click-function) - (define-key km [C-down-mouse-1] 'ignore) - (define-key km [C-mouse-1] click-function) - (define-key km [S-down-mouse-1] 'ignore) - (define-key km [S-mouse-1] click-function) - (define-key km [down-mouse-3] 'ignore) - (define-key km [mouse-3] click-function) - (setq label (propertize label - 'mouse-face 'ide-skel-highlight-face - 'face (if (cdr pair) - '(sqlplus-side-view-face (foreground-color . "red")) - 'sqlplus-side-view-face) - 'local-map km - 'pointer 'hand - 'object-name (car pair) - 'object-type type-name)) - (insert label) - (insert "\n"))))) - -(defun sqlplus-refresh-side-view-buffer () - (let* ((tab-info (nth sqlplus-side-view-active-tab sqlplus-side-view-tabset)) - (update-select (sqlplus-tab-update-select tab-info))) - (unless (sqlplus-tab-refresh-in-progress tab-info) - (sqlplus-hidden-select sqlplus-side-view-connect-string update-select 'sqlplus-my-update-handler)))) - -(defun sqlplus-get-default-update-select (symbol) - (concat "select object_name, object_type, decode( status, 'INVALID', 'I', ' ' ) from user_objects\n" - "where object_name not like 'BIN$%'\n" - (format "and object_type = '%s';" (upcase (symbol-name symbol))))) - -(defun sqlplus-create-side-view-buffer (connect-string) - (let* ((original-connect-string connect-string) - (connect-string (car (refine-connect-string connect-string))) - (buffer (funcall 'ide-skel-get-side-view-buffer-create - (concat " Ide Skel Right View SQL " connect-string) - 'right "SQL" (concat "SQL Panel for " connect-string) - (lambda (editor-buffer) - (let ((connect-string sqlplus-side-view-connect-string)) - (with-current-buffer editor-buffer - (and connect-string - (equal (car (refine-connect-string sqlplus-connect-string)) - (car (refine-connect-string connect-string))) - ))))))) - (with-current-buffer buffer - (set 'ide-skel-tabbar-menu-function - (lambda () - (let ((tab-info (nth sqlplus-side-view-active-tab sqlplus-side-view-tabset))) - (list - (unless (sqlplus-tab-refresh-in-progress tab-info) - '(sqlplus-refresh-side-view-buffer "Refresh" t)))))) - (setq sqlplus-side-view-connect-string original-connect-string - sqlplus-side-view-active-tab 0 - sqlplus-side-view-tabset - (list - (make-sqlplus-tab :id 0 :name "Tab" :symbol 'table :help-string "Tables" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'table) - :click-function 'sqlplus-side-view-click-on-table-handler) - (make-sqlplus-tab :id 1 :name "Vie" :symbol 'view :help-string "Views" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'view) - :click-function 'sqlplus-side-view-click-on-table-handler) - (make-sqlplus-tab :id 2 :name "Idx" :symbol 'index :help-string "Indexes" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'index) - :click-function 'sqlplus-side-view-click-on-index-handler) - (make-sqlplus-tab :id 3 :name "Tri" :symbol 'trigger :help-string "Triggers" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'trigger) - :click-function 'sqlplus-side-view-click-on-default-handler) - (make-sqlplus-tab :id 4 :name "Seq" :symbol 'sequence :help-string "Sequences" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'sequence) - :click-function 'sqlplus-side-view-click-on-default-handler) - (make-sqlplus-tab :id 5 :name "Syn" :symbol 'synonym :help-string "Synonyms" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'synonym) - :click-function 'sqlplus-side-view-click-on-default-handler) - (make-sqlplus-tab :id 6 :name "Pkg" :symbol 'package :help-string "PL/SQL Packages" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (sqlplus-get-default-update-select 'package) - :click-function 'sqlplus-side-view-click-on-package-handler) - (make-sqlplus-tab :id 7 :name "Prc" :symbol 'procedure :help-string "PL/SQL Functions & Procedures" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select (concat "select object_name, object_type, decode( status, 'INVALID', 'I', ' ' ) from user_objects\n" - "where object_name not like 'BIN$%'\n" - "and object_type in ('FUNCTION', 'PROCEDURE');") - :click-function 'sqlplus-side-view-click-on-default-handler) - (make-sqlplus-tab :id 8 :name "Sch" :symbol 'schema :help-string "Schemas" :draw-function 'sqlplus-side-view-default-draw-panel - :update-select "select username, 'SCHEMA', ' ' from all_users where username not like 'BIN$%';" - :click-function 'sqlplus-side-view-click-on-schema-handler) - )) - (sqlplus-side-view-buffer-mode-line)) - buffer)) - -(defun sqlplus-side-view-redraw (sql-view-buffer &optional window-start-from-tab-info) - (with-current-buffer sql-view-buffer - (let* ((point (point)) - (tab-info (nth sqlplus-side-view-active-tab sqlplus-side-view-tabset)) - (window-start (when (and (symbol-value 'ide-skel-current-right-view-window) - (eq (window-buffer (symbol-value 'ide-skel-current-right-view-window)) (current-buffer))) - (if window-start-from-tab-info - (sqlplus-tab-display-start tab-info) - (line-number-at-pos (window-start (symbol-value 'ide-skel-current-right-view-window))))))) - (let ((inhibit-read-only t)) - (setq buffer-read-only nil) - (erase-buffer) - (when (sqlplus-tab-draw-function tab-info) - (funcall (sqlplus-tab-draw-function tab-info) tab-info (sqlplus-tab-click-function tab-info)))) - (if window-start - (let ((pos (save-excursion - (goto-line window-start) - (beginning-of-line) - (point)))) - (set-window-start (symbol-value 'ide-skel-current-right-view-window) pos) - (setf (sqlplus-tab-display-start tab-info) window-start)) - (goto-char point) - (beginning-of-line))))) - -(defun sqlplus-side-view-update-data (connect-string alist) - (let* ((connect-string (car (refine-connect-string connect-string))) - (sql-view-buffer (sqlplus-get-side-view-buffer connect-string)) - was-proc) - (when sql-view-buffer - (with-current-buffer sql-view-buffer - (dolist (pair alist) - (let* ((symbol (if (eq (car pair) 'function) 'procedure (car pair))) - (data-list (cdr pair)) - (tab-info (some (lambda (tab) - (when (eq (sqlplus-tab-symbol tab) symbol) - tab)) - sqlplus-side-view-tabset))) - (when tab-info - (setf (sqlplus-tab-refresh-in-progress tab-info) nil) - (setf (sqlplus-tab-data tab-info) - (if (and (eq symbol 'procedure) - was-proc) - (append (sqlplus-tab-data tab-info) (copy-list data-list)) - data-list)) - (when (eq symbol 'procedure) - (setq was-proc t)) - (setf (sqlplus-tab-errors-count tab-info) - (count t (mapcar 'cdr data-list))) - (when (eql sqlplus-side-view-active-tab (sqlplus-tab-id tab-info)) - (sqlplus-side-view-redraw (current-buffer)))))) - (sqlplus-side-view-buffer-mode-line) - (force-mode-line-update))))) - -(defun sqlplus-side-view-window-function (side event &rest list) - (when (and (eq side 'right) - (symbol-value 'ide-skel-current-right-view-window) - (with-current-buffer (symbol-value 'ide-skel-current-editor-buffer) - sqlplus-connect-string)) - (cond ((memq event '(show editor-buffer-changed)) - (let ((sql-view-buffer (sqlplus-get-side-view-buffer (with-current-buffer (symbol-value 'ide-skel-current-editor-buffer) - sqlplus-connect-string)))) - (when sql-view-buffer - (with-current-buffer sql-view-buffer - (set 'ide-skel-tabbar-enabled t) - (funcall 'ide-skel-side-window-switch-to-buffer (symbol-value 'ide-skel-current-right-view-window) sql-view-buffer))))))) - nil) - -(add-hook 'ide-skel-side-view-window-functions 'sqlplus-side-view-window-function) - - -(provide 'sqlplus) - -;;; sqlplus.el ends here |