home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!stanford.edu!ames!elroy.jpl.nasa.gov!lll-winken!llnl.gov
- From: markl@llnl.gov (Mark Levinson)
- Newsgroups: gnu.emacs.sources
- Subject: using sqlplus and emacs
- Message-ID: <141295@lll-winken.LLNL.GOV>
- Date: 12 Nov 92 17:11:24 GMT
- Sender: usenet@lll-winken.LLNL.GOV
- Reply-To: markl@llnl.gov
- Organization: Lawrence Livermore National Lab
- Lines: 1231
- Nntp-Posting-Host: aisws7.llnl.gov
-
-
- Here are two files: sql-mode.el and SQLMODE.DOC for using sqlplus with emacs:
-
-
- ---
-
- ;; sql-mode.el - Oracle SQL*Plus interface
- ;;
- ;; Author: Jim Lange, Oracle Corporation
- ;; Date: 27-MAR-90
- ;; Bugs to: jlange@us.oracle.com
- ;;
- ;; $Header: /home/jlange/emacs/RCS/sql-mode.el,v 1.2 90/04/10 07:11:42 jlange Exp Locker: jlange $
- ;;
- ;; Revision History:
- ;; 19-APR-90 (jlange) - Trap EXIT/QUIT and terminate session.
- ;; - Trap EDIT, but just print message.
- ;; - Allow multiple sqlplus sessions by renaming current
- ;; buffer to new name and executing sqlplus again.
- ;; - Set left-margin to 5 in sqlplus-mode so that
- ;; newline-and-indent (C-j) will indent.
- ;; - Added (accept-process-output process) in
- ;; sqlplus-kill-command to prevent occasional scrambled
- ;; lines when command is executed.
- ;; - Added sqlplus-reset-buffer.
- ;; 25-APR-90 (jlange) - Treat GET like LIST and RUN--ignore in
- ;; sqlplus-get-command.
- ;; - Add sqlplus-drop-old-lines.
- ;; 04-MAY-90 (jlange) - Add sqlplus-copy-word (C-c C-w).
- ;; - Enhance sqlplus-kill-command to delete command or
- ;; command output, depending on location of point.
- ;; 11-MAY-90 (jlange) - In sql-send-region, detect imbedded SQL statement
- ;; format (used in SQL*FORMS, SQL*REPORT, PRO*C, etc.)
- ;; and convert to standard SQL before executing (remove
- ;; INTO clause and convert :WORD to &WORD).
- ;; - Automatically load and save session history based
- ;; on the variable sqlplus-keep-history.
- ;; 05-JUN-90 (jlange) - Delete ~/sqlplus.buf when exiting.
- ;; - In sqlplus-send-region, when performing substitutions
- ;; in statements, add "/" at end if not present.
- ;; 12-JUN-90 (jlange) - In sqlplus-send-region, look for :text.text and convert
- ;; to &text_text (used in SQL*Forms for block.field).
- ;; 07-SEP-90 (jlange) - Removed process argument from accept-process-output in
- ;; sql-send-line to prevent apparent lockup after issuing
- ;; complex SQL statement.
- ;; - Trap EDIT command and open new emacs buffer containing
- ;; command text. (new revision 1.2)
- ;; 08-MAY-91 (jlange) - In sql-send-region, truncate &-variables to 30 characters
- ;; before executing.
- ;;---------------------------------------------------------------------------------
-
- ;; Copyright (C) 1990 Free Software Foundation, Inc., and Jim Lange.
- ;;
- ;; This file is part of GNU Emacs. It is derived from 18.55's shell.el.
- ;;
- ;; GNU Emacs is distributed in the hope that it will be useful,
- ;; but WITHOUT ANY WARRANTY. No author or distributor
- ;; accepts responsibility to anyone for the consequences of using it
- ;; or for whether it serves any particular purpose or works at all,
- ;; unless he says so in writing. Refer to the GNU Emacs General Public
- ;; License for full details.
- ;;
- ;; Everyone is granted permission to copy, modify and redistribute
- ;; GNU Emacs, but only under the conditions described in the
- ;; GNU Emacs General Public License. A copy of this license is
- ;; supposed to have been given to you along with GNU Emacs so you
- ;; can know your rights and responsibilities. It should be in a
- ;; file named COPYING. Among other things, the copyright notice
- ;; and this notice must be preserved on all copies.
-
- ;;----------------------------------------------------------------------
-
- ;; This file contains function definitions for two new Emacs major modes,
- ;; sql-mode and sqlplus-mode. Sql-mode is for editing SQL statements in
- ;; a standard text buffer. Sqlplus-mode is used in conjunction with the
- ;; sqlplus function which runs SQL*Plus as an inferior process (similar to
- ;; shell-mode).
- ;;
- ;; Sql-mode is provided primarily as a convenience so that SQL statements
- ;; may be sent to SQL*Plus running in another buffer. Eventually it may
- ;; also provide automatic formatting of SQL statements based on Oracle
- ;; indentation standards (if they exist).
- ;;
- ;; Both modes turn on abbrev-mode and share a mode-specific abbreviation table
- ;; with some predefined abbreviations. Users may add to these or load in their
- ;; own. Abbrev-mode may be turned off in a user defined hook routine.
- ;;
- ;; The following commands should be added to a global init file or to any
- ;; user's .emacs file to conveniently use the new sql modes.
- ;;
- ;; (autoload 'sqlplus "sql-mode"
- ;; "Run an interactive SQL*plus session in a separate buffer." t)
- ;;
- ;; (autoload 'sql-mode "sql-mode"
- ;; "Major mode for editing SQL*plus batch files." t)
- ;;
- ;; (setq auto-mode-alist (cons '("\\.sql$" . sql-mode) auto-mode-alist))
- ;;
- ;; Possible Enhancements:
- ;; - Detect actual prompt string and set sql-prompt variable appropriately.
- ;;
- ;; - Suggestions?
-
- (provide 'sql-mode)
-
- ;; define variables
- (defvar sqlplus-startup-message
- (concat
- "Emacs SQL*Plus Interpreter: by Jim Lange of Oracle Corporation\n"
- (substring "$Revision: 1.2 $" 1 -1)
- "\n\nCopyright (c) 1990 Free Software Foundation, Inc., and Jim Lange.\n"
- "------------------------------")
- "Message displayed when \\[sqlplus] is executed.")
-
- (defvar last-output-start nil
- "In a sqlplus-mode buffer, marker for beginning of last batch of output.")
- (defvar sql-prompt nil
- "In a sqlplus-mode buffer, string containing prompt text.")
- (defvar sql-continue-pattern nil
- "In a sqlplus-mode buffer, regular expression for continuation line prompt.")
- (defvar sqlplus-username-password nil
- "The username/password to use when starting SQL*Plus.")
- (defvar sqlplus-stack-pointer 0
- "Current command recalled from history of commands.")
- (defvar sqlplus-keep-history nil
- "If non-nil, save current session in file .sqlhist when exiting.")
- (defvar sqlplus-lines-to-keep 1000
- "Number of lines to keep in a SQL*Plus buffer when \\[sqlplus-drop-old-lines] is executed.")
- (defvar sqlplus-mode-map nil)
- (defvar sql-mode-map nil)
- (defvar sql-mode-syntax-table nil
- "Syntax table used while in SQL and SQL*Plus modes.")
- (defvar sql-mode-abbrev-table nil
- "Abbrev table used in SQL and SQL*Plus modes.")
-
- ;; initialize syntax table
- (if sql-mode-syntax-table
- ()
- (setq sql-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?/ ". 14" sql-mode-syntax-table) ; comment start
- (modify-syntax-entry ?* ". 23" sql-mode-syntax-table)
- (modify-syntax-entry ?+ "." sql-mode-syntax-table)
- (modify-syntax-entry ?- "." sql-mode-syntax-table)
- (modify-syntax-entry ?= "." sql-mode-syntax-table)
- (modify-syntax-entry ?% "w" sql-mode-syntax-table)
- (modify-syntax-entry ?< "." sql-mode-syntax-table)
- (modify-syntax-entry ?> "." sql-mode-syntax-table)
- (modify-syntax-entry ?& "w" sql-mode-syntax-table)
- (modify-syntax-entry ?| "." sql-mode-syntax-table)
- (modify-syntax-entry ?_ "w" sql-mode-syntax-table) ; make _ part of words
- (modify-syntax-entry ?\' "\"" sql-mode-syntax-table))
-
- ;; initialize abbreviations
- (if sql-mode-abbrev-table
- nil
- (define-abbrev-table 'sql-mode-abbrev-table ())
- (let ((abbrevs-changed nil))
- (define-abbrev sql-mode-abbrev-table "d" "describe" nil)
- (define-abbrev sql-mode-abbrev-table "s" "select" nil)
- (define-abbrev sql-mode-abbrev-table "f" "from" nil)
- (define-abbrev sql-mode-abbrev-table "w" "where" nil)
- (define-abbrev sql-mode-abbrev-table "o" "order by" nil)
- (define-abbrev sql-mode-abbrev-table "l" "like" nil)
- (define-abbrev sql-mode-abbrev-table "i" "in (" nil)
- (define-abbrev sql-mode-abbrev-table "g" "group by" nil)
- (define-abbrev sql-mode-abbrev-table "h" "having" nil)
- (define-abbrev sql-mode-abbrev-table "n" "not" nil)
- )
- )
-
- ;;-----------------------------
-
- (defun sql-mode ()
- "Major mode for editing SQL*Plus batch files.
- \\{sql-mode-map}
- sql-send-buffer and sql-send-region are commands that will send SQL*Plus
- commands defined in the current buffer to SQL*Plus to be executed. Output
- is displayed in the *sqlplus* buffer (which will open as separate window
- if it does not already exist). (use '\\[describe-mode]' while in *sqlplus*
- buffer for information on sqlplus-mode.)
-
- Entry to this mode calls the value of sqlplus-mode-hook with no args,
- if that value is non-nil. Abbrev-mode is also enabled with the following
- abbreviations available by default:
-
- s -> Select
- f -> From
- w -> Where
- o -> Order By
-
- Use \\[list-abbrevs] for a full list.
-
- If the SQL statements to be executed contain variables prefixed with colons
- or INTO clauses, the colons are converted into ampersands and the INTO clauses
- are removed before being sent to SQL*Plus. This provides compatibility with
- Pro*C, SQL*Report, and SQL*Forms (.inp files). For example,
-
- SELECT SYSDATE + :days_added INTO :variable FROM SYSTEM.DUAL
-
- is converted to
-
- SELECT SYSDATE + &days_added FROM SYSTEM.DUAL
-
- and the user is prompted to enter the value of days_added."
-
- (interactive)
- (setq major-mode 'sql-mode)
- (setq mode-name "SQL")
- (use-local-map sql-mode-map)
- (set-syntax-table sql-mode-syntax-table)
- (setq local-abbrev-table sql-mode-abbrev-table)
- (abbrev-mode 1)
- (setq abbrev-all-caps 1)
- (setq require-final-newline t)
- (run-hooks 'sql-mode-hook)
- )
-
- (if sql-mode-map
- nil
- (setq sql-mode-map (make-sparse-keymap))
- (define-key sql-mode-map "\C-c\C-x" 'sql-send-buffer)
- (define-key sql-mode-map "\C-c\C-r" 'sql-send-region)
- )
-
- (defun sqlplus-mode ()
- "Major mode for interacting with Oracle SQL*Plus.
- Return at end of buffer sends line as input.
- Return not at end copies SQL statement to end and executes it.
- \\{sqlplus-mode-map}
- This mode is normally invoked by 'M-x sqlplus' (not 'M-x sqlplus-mode').
- You will be prompted to enter a username/password combination
- to access the Oracle database. This can be prevented by setting the
- variable sqlplus-username-password in your .emacs file as follows:
-
- (setq sqlplus-username-password \"myname/mypassword\")
-
- There are two ways of editing and re-executing prior commands.
- '\\[sqlplus-back-command]' and '\\[sqlplus-forward-command]' will move to the location
- in the buffer of the previous or next SQL statement, respectively
- (based on the command prompt). The command can then be edited
- normally and re-executed by pressing Return. To insert a newline,
- you may press '\\[newline-and-indent]'. '\\[sqlplus-next-command]' and '\\[sqlplus-previous-command]'
- are similar except the next or previous SQL statement is inserted at
- the end of the buffer. Repeating these commands will clear the
- current statement and recall the next or previous statement from the
- stack. For additional information on command execution use
- '\\[describe-key] RTN'.
-
- '\\[show-sqlplus-output]' will move to the beginning of the last ouput
- generated by SQL*plus. This is useful for reviewing the results of
- the last statement. '\\[sqlplus-end-of-buffer]' moves to the end of the buffer,
- but unlike '\\[end-of-buffer]' (end-of-buffer), it does not set the mark.
-
- '\\[sqlplus-kill-command]' deletes either the current command being entered or
- the last output generated by SQL*Plus, depending on when it is used.
- If executed while the cursor is within a SQL statement, the statement and
- any text after it are deleted. If the cursor is within or at the end of
- output generated by SQL*Plus, the output is deleted and the cursor is
- positioned at the end of the SQL statement that generated the ouput.
- '\\[sqlplus-kill-command]' can be used like an undo command to alternately
- delete commands and output from the end of the buffer.
-
- The commands sql-send-region and sql-send-buffer can be executed from
- another buffer to execute the SQL statements defined by the current
- region or entire buffer, respectively. Output from these commands is
- displayed in the *sqlplus* buffer. The major mode called sql-mode has
- these functions bound to key sequences.
-
- Entry to this mode calls the value of sqlplus-mode-hook with no args,
- if that value is non-nil. Abbrev-mode is also enabled with the following
- abbreviations available by default:
-
- s -> Select
- f -> From
- w -> Where
- o -> Order By
-
- Use '\\[list-abbrevs]' for a full list.
-
- If the variable sqlplus-keep-history is non-nil, the current session is
- saved in the file ~/.sqlhist and recalled automatically the next time
- sqlplus is executed. The session will only be saved if the EXIT or QUIT
- command is used to terminate the SQL*Plus session. The maximum number of
- lines saved can be set with the variable sqlplus-lines-to-keep which defaults
- to 1000. The command '\\[sqlplus-drop-old-lines]' will truncate the buffer
- to this length at any time. sqlplus-keep-history and sqlplus-lines-to-keep
- should be set in your .emacs file.
-
- If the *sqlplus* buffer is killed with '\\[kill-buffer]', the SQL*Plus
- process will automatically be terminated, but the session will not be saved,
- even if sqlplus-keep-history is non-nil.
-
- '\\[sqlplus-reset-buffer]' will delete all ouput lines from the buffer, leaving
- only commands. This will significantly shrink the buffer, but retain a full
- history of commands for re-execution."
-
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'sqlplus-mode)
- (setq mode-name "SQL*Plus")
- (setq mode-line-process '(": %s"))
- (use-local-map sqlplus-mode-map)
- (set-syntax-table sql-mode-syntax-table)
- (setq local-abbrev-table sql-mode-abbrev-table)
- (make-local-variable 'last-output-start)
- (setq last-output-start (make-marker))
- (make-local-variable 'sql-prompt)
- (setq sql-prompt "^\\(SQL> \\)+") ;* allows "SQL> SQL> ..."
- (make-local-variable 'sql-continue-pattern)
- (setq sql-continue-pattern "^[ 0-9][ 0-9][0-9][* \t][ \t]\\| ")
- (setq indent-tabs-mode nil)
- (setq left-margin 5)
- (abbrev-mode 1)
- (setq abbrev-all-caps 1)
- (run-hooks 'sqlplus-mode-hook)
- )
-
- (if sqlplus-mode-map
- nil
- (setq sqlplus-mode-map (make-sparse-keymap))
- (define-key sqlplus-mode-map "\C-m" 'sqlplus-execute-command)
- (define-key sqlplus-mode-map "\t" 'indent-relative)
- (define-key sqlplus-mode-map "\C-c\C-c" 'interrupt-sqlplus-subjob)
- (define-key sqlplus-mode-map "\C-c\C-r" 'show-sqlplus-output)
- (define-key sqlplus-mode-map "\C-c\C-p" 'sqlplus-previous-command)
- (define-key sqlplus-mode-map "\C-c\C-n" 'sqlplus-next-command)
- (define-key sqlplus-mode-map "\C-c\C-e" 'sqlplus-end-of-buffer)
- (define-key sqlplus-mode-map "\C-c\C-b" 'sqlplus-back-command)
- (define-key sqlplus-mode-map "\C-c\C-f" 'sqlplus-forward-command)
- (define-key sqlplus-mode-map "\C-c\C-k" 'sqlplus-kill-command)
- (define-key sqlplus-mode-map "\C-c\C-x" 'sqlplus-reset-buffer)
- (define-key sqlplus-mode-map "\C-c\C-d" 'sqlplus-drop-old-lines)
- (define-key sqlplus-mode-map "\C-c\C-w" 'sqlplus-copy-word)
- (define-key sqlplus-mode-map "\C-c\C-s" 'sqlplus-save-session)
- )
-
- ;;-----------------------------
-
- (defun sqlplus ()
- "Start up an interactive SQL*Plus session in a new buffer.
- If an active SQL*Plus process already exists, will switch to that
- buffer."
- (interactive)
- (let ((process (sqlplus-start)))
- (switch-to-buffer "*sqlplus*")
- (if (and sqlplus-keep-history
- (file-readable-p (expand-file-name "~/.sqlhist")))
- (progn
- (sit-for 1)
- (while (accept-process-output) (sleep-for 1))
- (insert-file-contents (expand-file-name "~/.sqlhist") nil)
- (goto-char (point-max))
- (set-marker (process-mark process) (point))
- (message ".sqlhist loaded")
- )
- );endif
- )
- )
-
- (defun sqlplus-start ()
- "Start up an interactive SQL*Plus session in a new buffer."
- (let ((sqlplus-buffer (get-buffer-create "*sqlplus*")) process)
- (setq process ; set process
- (or ; to the first that is non-nil:
- (get-buffer-process sqlplus-buffer) ; current process
- (progn ; or new process
- (set-buffer sqlplus-buffer)
- (insert sqlplus-startup-message)
- (start-process "SQL*plus" sqlplus-buffer "sqlplus"
- (or sqlplus-username-password
- (setq sqlplus-username-password
- (read-string "Enter SQL*plus username/password: "))))
- ))
- )
- (set-buffer sqlplus-buffer)
- (goto-char (point-max))
- (set-marker (process-mark process) (point))
- (sqlplus-mode)
- process ; return process
- )
- )
-
- (defun sqlplus-execute-command ()
- "When executed at end of buffer, sends text entered since last
- output from SQL*Plus. When executed while positioned within another
- valid command in the buffer, copies command to end of buffer and
- re-executes it. If point is within a multi-line statement at the end
- of the buffer (such as after '\\[sqlplus-previous-command]'), the entire
- statement will be cleared and re-entered one line at a time.
-
- Multi-line statements are recognized by the continuation prompt displayed
- by SQL*Plus. This is controlled by the variable sqlplus-continue-pattern
- which defaults to recognize either a right-justified number padded to four
- characters followed by a space or asterisk, or simply five spaces. A line
- ending with \";\" or \" /\" is also considered the end of a statement.
- A new line inserted into a prior statement must be indented at least five
- spaces to be included when the statement is re-executed.
-
- The output from a List command is also recognized as a valid SQL*Plus
- statement; the 'List' command itself is stripped out (as are 'Get' and 'Run').
-
- When a complex SQL statement is executed, it may take a long time before
- the output is generated. Emacs may appear to be hung since no keystrokes
- are accepted until the first character of output arrives. In this situation
- '\\[keyboard-quit]' may be used to force emacs to stop waiting for output.
- You may then switch to another buffer to perform other work while you wait
- or press '\\[interrupt-sqlplus-subjob]' to cancel the current SQL command."
- (interactive)
- (let ((process (get-buffer-process (current-buffer))))
- (if (not process)
- (error "Current buffer has no process. Use 'M-x sqlplus' to start SQL*Plus process.")
- )
-
- (cond
- ; last line of buffer and only one input line
- ((and (save-excursion (end-of-line) (eobp))
- (<= (count-lines (process-mark process) (point)) 1))
- (end-of-line)
- (sqlplus-send-line process)
- )
-
- ; within last multi-line command of buffer
- ((not (save-excursion (re-search-forward sql-prompt (point-max) t)))
- (let ((command-lines (sqlplus-get-command)))
- (sqlplus-kill-command t) ; clear existing command lines
- (while command-lines ; send command lines
- (insert (car command-lines))
- (sqlplus-send-line process)
- (setq command-lines (cdr command-lines))
- )
- )
- )
- ; otherwise - prior command in buffer
- (t
- (or (save-excursion
- (beginning-of-line)
- (looking-at (concat sql-prompt "\\|" sql-continue-pattern)))
- (error "This is not a valid SQL*plus command."))
- (let ((command-lines (sqlplus-get-command)))
- (goto-char (point-max))
- (sqlplus-kill-command t) ; clear pending command (if any)
- (while command-lines
- (insert (car command-lines))
- (sqlplus-send-line process)
- (setq command-lines (cdr command-lines))
- )
- )
- )
- ) ;end cond
- ) ;end let
- (setq sqlplus-stack-pointer 0)
- ) ; end defun
-
- (defun sqlplus-send-line (process) ; called from sqlplus-execute-command
- (insert ?\n)
- (let ((command (buffer-substring (process-mark process) (point)))
- (temp-file (expand-file-name "~/sqlplus.buf")))
- (move-marker last-output-start (point))
- ; trap EDIT command - must be the only word on the line
- (if (string-match "^ *edit\\s-*\\(\\w*\\)[ ;]*$" command)
- (let (command-lines
- (edit-file-name (save-excursion (and
- (re-search-backward "edit\\s-+\\([^ \t\n;]+\\)"
- (process-mark process) t)
- (buffer-substring (match-beginning 1) (match-end 1))
- )))
-
- )
- (sit-for 0)
- (set-marker (process-mark process) (point))
- (process-send-string process "LIST\n")
- (accept-process-output process) ; wait for process to respond
- (sleep-for 1)
- (forward-line -1)
- (setq command-lines (sqlplus-get-command)) ; capture command
- (delete-region last-output-start (point)) ; delete listed lines
- (goto-char (point-max))
- (switch-to-buffer-other-window (get-buffer-create (or edit-file-name "*sqlplus-temp*")))
- (if edit-file-name
- (setq buffer-offer-save t)
- )
- (delete-region (point-min) (point-max)) ; clear buffer
- (while command-lines ;insert command lines
- (insert (car command-lines) "\n")
- (setq command-lines (cdr command-lines))
- )
- (insert "/\n")
- (goto-char (point-min))
- (sql-mode) ;turn on sql-mode
- )
- ; else
- ; execute command line
- (process-send-string process command)
- (goto-char (point-max))
- (set-marker (process-mark process) (point))
- (sit-for 0) ; force display update
- (accept-process-output) ; wait for process to respond
- )
- ; trap QUIT command
- (if (string-match "^ *\\(exit\\|quit\\)[ ;]*$" command)
- (progn
- (if sqlplus-keep-history
- (let ((lines-to-keep (or sqlplus-lines-to-keep 1000)))
- (and (> (count-lines (point-min) (point-max)) lines-to-keep)
- (y-or-n-p
- (format "Current session is longer than %d lines. Ok to truncate? " lines-to-keep))
- (sqlplus-drop-old-lines lines-to-keep)
- )
- (sqlplus-save-session "~/.sqlhist")
- )
- )
- (while (get-buffer-process (current-buffer))
- (sit-for 1)) ; wait for process to die
- (kill-buffer (current-buffer))
- (and (file-exists-p temp-file) ; if sqlplus.buf exists, delete it
- (delete-file temp-file))
- );end progn
- );end if
- );end let
- )
-
- (defun sqlplus-kill-command (command-only-flag)
- "Delete the current SQL command or output generated by last SQL command.
- When used at the end of the buffer, serves as an undo command.
-
- If point is within a valid SQL statement, delete region from SQL> prompt
- before point to end of buffer, otherwise delete all text between the end
- of the prior SQL statement and the end of the buffer."
- (interactive "P")
- (let ((process (get-buffer-process (current-buffer))))
- (if (or command-only-flag
- (save-excursion
- (beginning-of-line)
- (looking-at (concat sql-prompt ".+\\|" sql-continue-pattern))
- )
- )
- ;then - delete command and everything beyond
- (progn
- (delete-region (progn
- (re-search-backward sql-prompt (point-min) t)
- (point))
- (point-max))
- (process-send-string process "\n") ; generate new SQL> prompt
- (goto-char (point-max))
- (set-marker (process-mark process) (point))
- (sit-for 0) ; update display
- (accept-process-output process) ; wait for prompt
- )
- ;else - delete output from prior command, leaving cursor at end of command
- (beginning-of-line)
- (or (re-search-backward sql-prompt (point-min) t)
- (error "Nothing to kill"))
- (set-marker (process-mark process) (match-end 0))
- (sqlplus-get-command) ; convenient way to find end of command
- (forward-char -1) ; back up one character
- (delete-region (point) (point-max))
- );end if
- )
- )
-
- (defun sqlplus-get-command ()
- (interactive)
- (let ((line "") command-lines)
- (end-of-line)
- (or (re-search-backward sql-prompt (point-min) t)
- (error "Unable to execute this command"))
- (goto-char (match-end 0)) ; skip past prompt
- (setq command-lines ; initialize command-lines list
- (if (looking-at "l$\\|list$\\|r$\\|run$\\|get .*\\|edit") ;ignore LIST,RUN,GET,EDIT
- nil
- (list (setq line
- (buffer-substring (point) (progn (end-of-line) (point)))))
- )
- )
- (forward-line)
- (while (and ; while previous line
- (not (string-match "^\\(.*;$\\| */\\)$" line)) ; does not end in / or ;
- (looking-at sql-continue-pattern)) ; and this is a cont. line
- (goto-char (match-end 0)) ; skip over prompt
- (setq line (buffer-substring (point) (progn (end-of-line) (point))))
- (setq command-lines (append command-lines (list line)))
- (forward-line)
- )
- command-lines ; return command-lines as value of function
- ))
-
- (defun interrupt-sqlplus-subjob ()
- "Interrupt this shell's current subjob."
- (interactive)
- (interrupt-process nil t))
-
- (defun show-sqlplus-output ()
- "Display most recent batch of output at top of window.
- Also put cursor there."
- (interactive)
- (goto-char last-output-start)
- )
-
- (defun sql-send-buffer (prefix-arg)
- "Execute all SQL*Plus commands defined in current buffer.
- Output is displayed in the *sqlplus* buffer."
- (interactive "P")
- (sql-send-region (point-min) (point-max) prefix-arg)
- )
-
- (defun sql-send-region (start end prefix-arg)
- "Execute all SQL*Plus commands defined between point and mark.
- Output is displayed in the *sqlpus* buffer."
- (interactive "r\nP")
- (let (process this-buffer temp-file-name imbedded-variables (temp-buffer nil))
- (setq this-buffer (current-buffer))
- (or (setq process (get-buffer-process "*sqlplus*")) ; look for process
- (setq process (sqlplus-start)) ; or create process
- (error "Unable to create SQL*plus session."))
- ; (setq temp-file-name (format "/tmp/sqlbuf.%d" (process-id process)))
- (setq temp-file-name (expand-file-name "~/sqlplus.buf"))
- (set-buffer this-buffer)
- (if (and (null prefix-arg) ; if no prefix argument
- (save-excursion ; look for 'INTO :' or ':variable'
- (goto-char start)
- (re-search-forward "\\binto\\s-+:\\|\\s-:\\w+" end t)))
- (progn
- (setq temp-buffer (get-buffer-create "*sql-temp*"))
- (set-buffer temp-buffer)
- (set-syntax-table sql-mode-syntax-table) ; important for regular expressions
- (erase-buffer)
- (insert-buffer-substring this-buffer start end) ; insert region
- (skip-chars-backward "\n\t ") ; trim trailing whitespace
- (if (save-excursion
- (forward-char -1) ; back up one
- (not (looking-at ";\\|/")) ; last character is not ; or /
- )
- (insert "\n/\n") ; add "/" so statement is executed
- )
- (goto-char (point-min)) ; delete INTO clause
- (if (re-search-forward "\\binto\\s-+:" (point-max) t)
- (delete-region (match-beginning 0) ; delete between INTO & FROM
- (progn
- (re-search-forward "\\bfrom\\b" (point-max) t)
- (match-beginning 0)
- )
- )
- ) ;endif
- (goto-char (point-min)) ; convert all ":block.field" to "&block_field"
- (replace-regexp ":\\(\\w+\\)\\." "&\\1_" nil)
- (goto-char (point-min)) ; convert all remaining ":" to "&"
- (replace-string ":" "&" nil)
- (goto-char (point-min))
- (while (re-search-forward "&\\w+" (point-max) t)
- (let ( (wbeg (match-beginning 0)) (wend (match-end 0)) )
- (if (> (- wend wbeg) 30) ; if word > 30 characters
- (delete-region (+ wbeg 1) (- wend 30)) ; truncate to 30
- )
- )
- )
- (setq start (point-min)) ; reset start & end for write-region
- (setq end (point-max))
- ) ;end progn
- ) ;endif
- (setq imbedded-variables (save-excursion ; look for &, accept, acc
- (goto-char start)
- (re-search-forward "&\\|\\bacc\\(ept\\)?\\b" end t)))
- (write-region start end temp-file-name nil 0) ; write temp file
- (switch-to-buffer-other-window "*sqlplus*")
- (goto-char (point-max))
- (recenter 0)
- (insert (format "\nOutput from buffer '%s':\n"
- (buffer-name this-buffer)))
- (set-marker (process-mark process) (point))
- (sit-for 0) ; update display
- (process-send-string process (concat "@" temp-file-name "\n"))
- (if temp-buffer (kill-buffer temp-buffer))
- (if imbedded-variables ; stay in *sqlplus* buffer to
- (goto-char (point-max)) ; allow entry of variables
- (switch-to-buffer-other-window this-buffer)
- )
- )
- )
-
- (defun sqlplus-back-command (arg)
- "Move to the SQL*plus command before current position.
- With prefix argument, move to ARG'th previous command."
- (interactive "p")
- (if (save-excursion
- (beginning-of-line)
- (re-search-backward sql-prompt (point-min) t arg)
- )
- (goto-char (match-end 0))
- (error "No previous SQL*plus command.")
- )
- )
-
- (defun sqlplus-forward-command (arg)
- "Move to the SQL*plus command after current position.
- With prefix argument, move to ARG'th previous command."
- (interactive "p")
- (if (re-search-forward sql-prompt (point-max) t arg)
- nil
- (error "No next SQL*plus command.")
- )
- )
-
- (defun sqlplus-previous-command (arg)
- "Recall the previous SQL*plus command from the command stack.
- With prefix argument, recall the command ARG commands before the current
- stack pointer."
- (interactive "p")
- ; - clear current pending command
- (goto-char (process-mark (get-buffer-process (current-buffer))))
- (delete-region (point) (point-max))
-
- ; - increment stack pointer by arg
- (setq sqlplus-stack-pointer (+ sqlplus-stack-pointer arg))
- (if (< sqlplus-stack-pointer 0)
- (progn (setq sqlplus-stack-pointer 0)
- (error "At last command."))
- )
- ;if there is a prior command
- (if (re-search-backward (concat sql-prompt ".+") ; skip empty prompts
- (point-min) t sqlplus-stack-pointer)
- ;then
- (let ((command-lines (sqlplus-get-command)) col)
- (goto-char (point-max))
- (setq col (current-column))
- (while command-lines
- (indent-to col)
- (insert (car command-lines))
- (setq command-lines (cdr command-lines))
- (if command-lines (insert ?\n))
- )
- (message (if (> sqlplus-stack-pointer 0)
- (format "#%d" sqlplus-stack-pointer)
- ""))
- )
- ;else
- (setq sqlplus-stack-pointer (- sqlplus-stack-pointer arg)) ; reset
- (error "No previous SQL*plus command.")
- )
- )
-
- (defun sqlplus-next-command (arg)
- "Recall the next SQL*plus command from the command stack.
- With prefix argument, recall the command ARG commands after the current
- stack pointer."
- (interactive "p")
- (sqlplus-previous-command (- arg))
- )
-
- (defun sqlplus-end-of-buffer ()
- "Move cursor to end of buffer."
- (interactive)
- (goto-char (point-max))
- )
-
- (defun sqlplus-reset-buffer ()
- "Reset SQL*Plus buffer to contain only command history, not output.
- Commands of one or fewer characters (/, l, r, etc.) are not retained."
- (interactive)
- (and (y-or-n-p
- (format "Delete all output lines from buffer %s? " (buffer-name)))
- (let ((line "") (process (get-buffer-process (current-buffer))) start)
- (message "Deleting output lines...")
- (goto-char (point-min))
- (setq start (point))
- (while (re-search-forward (concat sql-prompt "..+") (point-max) t)
- (goto-char (match-end 1))
- (setq line (buffer-substring (point) (progn (end-of-line) (point))))
- (beginning-of-line)
- (delete-region start (point))
- (forward-line)
- (while (and ; skip past SQL statement
- (not (string-match "^\\(.*;$\\| */\\)$" line))
- (looking-at sql-continue-pattern)) ; and this is a cont. line
- (goto-char (match-end 0)) ; skip over prompt
- (setq line (buffer-substring (point) (progn (end-of-line) (point))))
- (forward-line)
- )
- (setq start (point))
- )
- (goto-char (point-max))
- (delete-region start (point))
- (process-send-string process "\n") ; generate new SQL> prompt
- (goto-char (point-max))
- (set-marker (process-mark process) (point))
- (sit-for 0) ; update display
- (accept-process-output) ; wait for prompt
- (message "Deleting output lines...Done.")
- )
- )
- )
-
- (defun sqlplus-drop-old-lines (lines-to-keep)
- "Delete old lines from current buffer.
- Number of lines to keep is determined by the variable sqlplus-lines-to-keep.
- With prefix argument, keep the last ARG lines."
- (interactive "P")
- (delete-region (save-excursion
- (goto-char (point-min))
- (point))
- (save-excursion
- (goto-char (point-max))
- (forward-line (- (or lines-to-keep
- sqlplus-lines-to-keep
- 1000)))
- (point)))
- )
-
- (defun sqlplus-save-session (filename)
- "Save current SQL*Plus session to FILENAME."
- (interactive "FFile to save session to: ")
- (save-excursion
- (if (or (null filename) (string= filename ""))
- (setq filename "~/.sqlhist"))
- (message (format "Saving %s..." filename))
- (write-region (progn
- (goto-char (point-min))
- (re-search-forward sql-prompt (point-max) t)
- (match-end 0))
- (progn
- (goto-char (point-max))
- (re-search-backward sql-prompt (point-min) t)
- (match-end 0))
- (expand-file-name filename) nil 0)
- (message (format "Saving %s...done" filename))
- )
- )
-
- (defun sqlplus-copy-word ()
- "Copy current word to the end of buffer, inserting SELECT keyword
- or commas if appropriate."
- (interactive)
- (let (word preceding-word)
- (save-excursion
- (setq word (buffer-substring ; extract word
- (progn (forward-char 1) (backward-word 1) (point))
- (progn (forward-word 1) (point))))
- (goto-char (point-max)) ; goto end of buffer
- (cond
- ; sitting at empty command line
- ((save-excursion (beginning-of-line)
- (looking-at (concat sql-prompt "$")))
- (insert "SELECT ")
- )
- ; on same line as SELECT or ORDER BY, but other words already inserted
- ((save-excursion (re-search-backward " select .+\\| order by .+"
- (save-excursion (beginning-of-line) (point)) t))
- (insert ", ")
- )
- ; Otherwise
- (t
- (if (eq (preceding-char) ? ) ; if preceding character = space
- nil
- (insert " ")
- )
- )
- );end case
- (insert word)
- (message (format "\"%s\" copied" word))
- )
- )
- )
-
- ;end if file -------- cut here ---------------------------------------
-
- ;This is a seperate file of documentation
-
- Although SQL*Plus is a powerful tool for producing ad hoc queries and
- interacting with an Oracle database, the user interface is less than
- state-of-the-art.
-
- I am now pleased to announce a new utility available to users of Emacs and
- SQL*Plus that allows SQL*Plus to run in an Emacs buffer. Even if you don't
- know Emacs, this utility makes SQL*Plus so much friendlier that you may want
- to learn the basics of Emacs just to take advantage of the improvements. For
- those of you who have been using the current version, this version includes
- many significant enhancements (see below).
-
- If anyone receives this message that does not yet have access to this utility
- but would like to use it, send me a mail message and I can send you the
- appropriate files with instructions.
-
- If you are not familiar with Emacs, some of the terms used below may be
- foreign to you (buffers, modes, key sequences, etc.). However, Emacs comes
- with an excellent tutorial that will teach you the basics (just press
- Control-H, then the letter "T", 'C-h t', after starting Emacs) as well as full
- on-line documentation (C-h i).
-
-
- Description
- ===========
-
- Here is a brief description of the enhancements that this utility adds to
- SQL*Plus (features added since version 1.1 are indicated with NEW!):
-
- * Fully compatible with SQL*Plus. If none of the new features
- are accessed, SQL*Plus looks and behaves exactly like it
- does normally. You can enter commands one line at a time and
- use all the awkward line editing commands you've become
- accustomed to.
-
- * Full history buffer. All text entered and received in the
- current session is stored so you can scroll forward and back
- to examine prior results.
-
- NEW! * Save history between sessions. You have the option of saving
- your sessions automatically so that the next time SQL*Plus
- is invoked, you are returned to where you left off--with all
- prior input and output intact!
-
- * Full command line editing. All of Emacs' editing commands
- may be used to correct errors in the current input line before
- pressing RETURN. When entering multi-line statements you may
- easily move up to prior lines to change them before executing
- the entire statement.
-
- * Recall, edit, and re-execute prior commands. Any prior command
- entered in the buffer may be modified and re-executed. Also,
- full cut and paste of commands or parts or commands is supported
- using standard Emacs features.
-
- * Entry shortcuts. Single letter abbreviations are provided for
- commonly used keywords. For example, typing S<space> inserts
- "SELECT ". Also, any other keyword, table, or column name
- used earlier may be abbreviated with the first few letters
- (see dynamic expansion below).
-
- NEW! * Powerful "word grab" feature. Position the cursor on a column
- or table name and with the press of a key, the text is appended
- to the end of the current SQL statement. Commas are even inserted
- automatically when appropriate!
-
- NEW! * Run multiple SQL*Plus sessions simultaneously. Using Emacs'
- multiple buffer/window features, two or more sessions may be
- active concurrently--each attached to a different database if
- desired.
-
- * Edit SQL*Plus batch files and execute them with a keystroke.
- You no longer need to use the EDIT or HOST commands to move
- in and out of a full screen editor while refining SQL scripts.
- Just edit in one Emacs window and with the press of a key, the
- commands will be executed with the output appearing in a second
- NEW! window. You can even execute SQL statements imbedded in a
- SQL*Report, SQL*Forms (.inp), or Pro*C (Fortran, COBOL, etc.) file!
-
- * On-line help. Help is available in any mode by pressing C-h m.
- (This is true of all Emacs modes, not just the new SQL modes.)
- You can also get help on any key sequence with C-h k <key sequence>.
-
- * Multi-tasking! Since you are in Emacs, you can perform
- other tasks while you wait for a complex SQL statement to finish
- executing. Switch to another document, open a new window,
- compose a letter, run an operating system shell, and if Emacs
- is run from the Unix c-shell, it can be "suspended" and you
- can return to it later.
-
- This utility is implemented as an Emacs "major mode" for editing text. There
- are actually two new major modes. The first is sqlplus-mode which runs a
- SQL*Plus session in a buffer called *sqlplus* and allows you to edit and
- re-execute prior commands, as well as providing a history of all interaction.
- This mode is similar to shell-mode (and is, in fact, based upon it), but with
- additional features specific to SQL*Plus.
-
- Another mode called sql-mode can be used to edit SQL*Plus batch programs which
- can then be executed with a keypress with the output appearing in another
- window.
-
- Like most other special Emacs modes, the commands unique to these new modes
- are accessed using a keystroke sequence of Control-C followed by another
- control character.
-
-
- SQL*Plus Mode
- =============
-
- To experiment with the interactive SQL*Plus mode, invoke Emacs with these
- options:
-
- emacs -l sql-mode -f sqlplus
-
- You will be prompted to enter a username/password combination to access an
- Oracle database. Interaction in the *sqlplus* buffer is exactly like normal
- SQL*Plus, including its limited editing capabilities, if all commands are
- entered at the end of the buffer. Prior commands may be recalled, edited, and
- re-executed in the following ways.
-
- 1) Manually cursor back up to the command to be edited, make changes,
- then press [Return] when the cursor is on any line of a multi-line
- statement. This is convenient after a command that produces a
- small amount of output or after a LIST command.
-
- 2) Use C-c C-b and C-c C-f (back/forward command) to move the cursor to
- the previous or next command in the buffer. Then edit and
- re-execute by pressing [Return]. C-c C-b is also useful after a
- command has produced several pages of output and you wish to begin
- reviewing it from the beginning. I have these commands bound to
- ESC up-arrow and ESC down-arrow in my .emacs file.
-
- 3) Use C-c C-p and C-c C-n (previous/next command) to recall the prior
- commands directly after the last prompt at the end of the buffer.
- When the desired command has been recalled, press [Return] to
- execute, or edit and then re-execute with [Return].
-
-
- Typing Shortcuts
- ----------------
-
- A powerful feature which is built into Emacs is the use of abbreviations. In
- sqlplus-mode, standard abbreviations are automatically available for common
- keywords such as DESCRIBE, SELECT, FROM, WHERE, ORDER BY, etc. by entering the
- first letter followed by space or tab. You may add to or modify this table
- and save it for later use (consult an Emacs manual or the on-line
- documentation for more information on using abreviations).
-
- Dynamic abbreviations are also very useful. Entering the first few characters
- of a table or column name (or any other word) included anywhere in the buffer
- and typing M-/ (note: M = ESC) will complete the name; successive M-/'s will
- cycle through all matches. I use this after "DESCRIBE table" so that all
- column names are conveniently available.
-
- Another way to quickly and easily build queries after using DESCRIBE is to
- position the cursor over (or after) the first column name you wish to SELECT
- and press C-c C-w (copy word). If the command line at the end of the buffer
- is blank, "SELECT" will be inserted, followed by the column name. Repeat this
- for each column to be selected and the names will be appended to the line with
- commas separating each entry. This technique may also be used to copy words
- from an earlier line of the same statement while entering expressions,
- comparisons, or ORDER BY clauses. Building SELECT statements has never been
- so easy!
-
-
- Saving Your Session
- -------------------
-
- Since all output is saved in the buffer, you can easily scroll back to review
- prior queries, without having to re-execute them. You may also save your
- session with C-c C-s (or M-x sqlplus-save-session) to any file and re-load it
- later with C-x i (insert-file). A better option is to have Emacs do this
- for you when you exit. By setting the the Emacs variable sqlplus-keep-history
- to a non-nil value in your .emacs file, your session will saved in the file
- .sqlhist in your home directory and automatically loaded the next time sqlplus
- is run (an example of how to set this variable is included later).
-
- Since your .sqlhist file is likely to grow very large after only a few
- sessions, I have provided some ways of preventing the history buffer from
- growing too large. When you exit SQL*Plus by typing EXIT or QUIT, the number
- of lines in the buffer is compared with the variable sqlplus-lines-to-keep,
- which defaults to 1000. If it is larger, you will be asked if you wish to
- tuncate the buffer to the indicated size before saving (the oldest lines will
- be deleted). You can also perform this truncation at any time during your
- session with the command C-c C-d (delete old lines). If you wish to exit
- without saving the session, use C-x k (kill-buffer).
-
- Another way to drastically shrink the buffer is with C-c C-x which deletes all
- output lines in the buffer, keeping only the commands that have been entered.
- This way you still have access to prior commands for re-execution.
-
- After entering a SQL command that generates an error, or produces a report
- that still is not quite correct, rather than recall the command to edit and
- re-execute it, use C-c C-k (kill) which deletes either the last output
- generated by SQL*Plus or the current command being entered, depending on where
- the cursor is when it is used. If executed while the cursor is within a SQL
- statement, the statement and any text after it are deleted. If the cursor is
- within or at the end of output generated by SQL*Plus, the output is deleted
- and the cursor is positioned at the end of the SQL statement that generated
- the output. Thus, it can be used like an undo command to alternately delete
- commands and output from the end of the buffer. This helps prevent the buffer
- from growing as a result of several "false starts" and makes finding prior
- valid commands easier (because you don't have to wade through several bad
- commands and their associated output).
-
-
-
- which will also kill the process (but will not save your session).
-
-
- Summary of Commands
- -------------------
-
- C-c C-p Recall previous command.
- C-c C-n Recall next command.
- C-c C-b Back one command.
- C-c C-f Forward one command.
- C-c C-e Move end of buffer (like M->, but does not set the mark.)
- C-c C-r Return to beginning of last output produced by SQL*Plus.
- C-c C-c Send ^C to interrupt current command execution.
- NEW! C-c C-k Kill current SQL statement or last output.
- NEW! C-c C-x Delete all output lines.
- NEW! C-c C-d Drop old lines (truncate to value of sqlplus-lines-to-keep).
- NEW! C-c C-w Copy word to end.
- NEW! C-c C-s Save session to file.
-
- You can generate a list like this while in sqlplus-mode by typing C-h m (Help
- with current Mode) or C-h b (Help keyBindings). You can also get help on any
- specific command with C-h k (Help Key) followed by the key sequence.
-
-
- SQL Edit Mode
- =============
-
- In a text buffer, the command 'M-x sql-mode' will enable SQL text editing
- mode. The keyword abbreviations described above are also available in this
- mode. Two special commands are provided to execute the SQL*Plus statements
- contained in a sql-mode buffer. C-c C-x will send the entire buffer to
- SQL*Plus. The output is displayed in the *sqlplus* buffer in a second window
- (if SQL*Plus is not currently running, a new buffer is created and the process
- started). C-c C-r will send the commands in the currently defined region
- (between point and mark). This feature may be useful to Pro*C programmers who
- need to test SQL statements imbedded in their code.
-
- If the SQL statements to be executed contain variables prefixed with colons
- or INTO clauses, the colons are converted into ampersands and the INTO clauses
- are removed before being sent to SQL*Plus. This provides compatibility with
- Pro*C, SQL*Report, and SQL*Forms (.inp files). For example,
-
- SELECT SYSDATE + :days_added INTO :variable FROM SYSTEM.DUAL
-
- is converted to
-
- SELECT SYSDATE + &days_added FROM SYSTEM.DUAL
-
- and the user is prompted to enter the value of days_added. This substitution
- process can be prevented by using a prefix argument with the
- sqlplus-send-region command. In practice, this is done by typing 'C-u C-c
- C-r'. Also, variables of the form :block_name.field_name are converted to
- &block_name_field_name for convenience when editing .inp files.
-
- In the future, this mode may automatically indent your SQL*Plus code based on
- Oracle standards (if they have been defined). Your suggestions are welcome.
-
-
- Accessing the New Modes
- =======================
-
- If Emacs is started normally, the new modes will not be available until the
- new library is loaded with the command:
-
- M-x load-library RET sql-mode RET (RET = the RETURN key)
-
- Or Emacs can be invoked with the option '-l sql-mode'.
-
- Once the library is loaded, the commands 'M-x sqlplus' and 'M-x sql-mode' can
- be used. This can be automated by including the following commands in your
- .emacs file:
-
- (autoload 'sql-mode "sql-mode" "SQL editing mode" t)
- (autoload 'sqlplus "sql-mode" "Run SQL*Plus interactively" t)
-
- This will load the sql-mode library the first time either of these commands is
- used.
-
- Sql-mode can be invoked automatically whenever a file ending in .sql is edited
- by including this command in .emacs:
-
- (setq auto-mode-alist (cons '("\\.sql$" . sql-mode) auto-mode-alist))
-
- Note: The above statements may eventually be added to the global
- initialization files used on each machine where Emacs is loaded
- (i.e. site-init.el).
-
-
- Customizing Your Environment
- ============================
-
- When sqlplus is initially executed, you will be prompted to enter a username
- and password to access an Oracle database. If you always use the same
- username/password combination, this can be suppressed by setting a special
- variable in your .emacs file as follows:
-
- (setq sqlplus-username-password "myname/mypassword")
-
- You may also wish to assign some of the special functions to more convenient
- keys on your keyboard. Each of these modes calls a "hook" routine (like all
- other Emacs modes). By assigning custom routines to these hooks, you can add
- additional functionality. Below are some statements that will assign common
- commands used in sqlplus and sql-mode to VT320 function keys.
-
- (global-unset-key "\e\e" ; allow ESC as a prefix to function keys
- (setq sql-mode-hook 'set-sql-keys)
- (setq sqlplus-mode-hook 'set-sqlplus-keys)
-
- (defun set-sql-keys ()
- "Customize sql-mode keys."
- (local-set-key "\eOM" 'sql-send-buffer) ; Enter
- (local-set-key "\e\eOM" 'sql-send-region)) ; ESC Enter
-
- (defun set-sqlplus-keys ()
- "Customize sqlplus-mode keys."
- (local-set-key "\e\eOA" 'sqlplus-back-command) ; ESC up-arrow
- (local-set-key "\e\eOB" 'sqlplus-forward-command) ; ESC down-arrow
- (local-set-key "\e\eOD" 'sqlplus-previous-command) ; ESC left-arrow
- (local-set-key "\e\eOC" 'sqlplus-next-command) ; ESC right-arrow
- (local-set-key "\e\r" 'sqlplus-end-of-buffer)) ; ESC Return
-
- These key bindings will only be active in the buffers running the new modes
- and thus will not affect other functions assigned to the same keys in other
- buffers.
-
- SQL*Plus reads and executes the contents of the file login.sql in your home
- directory when it starts up. If you have modified the default parameters you
- may need to make changes to this file for compatibility with sqlplus-mode.
-
- The current version requires that the SQL*Plus prompt be "SQL> " and that
- continuation prompts are numbered lines (the default), so do not change the
- settings of the SQL*Plus variables 'sqlprompt' or 'sqlnumber'. Page pause
- should be left OFF (set pause off) since you can page forward and back using
- Emacs commands (although setting pause ON will still work).
-
- Since Emacs automatically wraps long lines you can set the line length used by
- SQL*Plus to the maximum value (set linesize 500). Then if your terminal
- supports wide displays or variable size windows, long lines will always wrap
- to fit (however, this will also affect the centering of titles).
-
-
- Known Bugs
- ==========
-
- When entering a new command, if you move up to a prior line (of the same
- multi-line statement), make a change, then move back to the last line and
- finish entering it, SQL*Plus will not see the change--it will only process the
- last line entered. However, if you move up to any line except the last one
- before pressing [Return], all lines will be re-evaluated when the command is
- executed.
-
- If you discover additional bugs or think of some good enhancements, send them
- via email to jlange@us.oracle.com, or call me at (415) 506-4669.
-
- -Jim Lange
-
-
-
-
-