[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[ELPA-diffs] /srv/bzr/emacs/elpa r165: Add new package "ediprolog".
From: |
Stefan Monnier |
Subject: |
[ELPA-diffs] /srv/bzr/emacs/elpa r165: Add new package "ediprolog". |
Date: |
Thu, 22 Dec 2011 19:43:30 -0500 |
User-agent: |
Bazaar (2.3.1) |
------------------------------------------------------------
revno: 165
committer: Stefan Monnier <address@hidden>
branch nick: elpa
timestamp: Thu 2011-12-22 19:43:30 -0500
message:
Add new package "ediprolog".
added:
packages/ediprolog/
packages/ediprolog/ediprolog.el
=== added directory 'packages/ediprolog'
=== added file 'packages/ediprolog/ediprolog.el'
--- a/packages/ediprolog/ediprolog.el 1970-01-01 00:00:00 +0000
+++ b/packages/ediprolog/ediprolog.el 2011-12-23 00:43:30 +0000
@@ -0,0 +1,613 @@
+;;; ediprolog.el --- Emacs Does Interactive Prolog
+
+;; Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+
+;; Author: Markus Triska <address@hidden>
+;; Keywords: languages, processes
+;; Version: 1.0
+
+;; This file 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 3, or (at your option)
+;; any later version.
+
+;; This file 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. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; These definitions let you interact with SWI-Prolog in all buffers.
+;; You can consult Prolog programs and evaluate embedded queries.
+
+;; Installation
+;; ============
+;;
+;; Copy ediprolog.el to your load-path and add to your .emacs:
+;;
+;; (require 'ediprolog)
+;; (global-set-key [f10] 'ediprolog-dwim)
+;;
+;; Restart Emacs and customize ediprolog with
+;;
+;; M-x customize-group RET ediprolog RET
+;;
+
+;; Usage
+;; =====
+;;
+;; The central function is `ediprolog-dwim' (Do What I Mean), which is
+;; bound to F10 by the snippet above. Depending on the content at
+;; point, `ediprolog-dwim' does the "appropriate" thing: If point is
+;; on a query, F10 sends the query to a Prolog process, and you
+;; interact with the process in the current buffer as on a terminal.
+;; Queries start with "?-" or ":-", possibly preceded by "%" and
+;; whitespace. An example of a query is (without leading ";;"):
+;;
+;; %?- member(X, [a,b,c]).
+;;
+;; If you press F10 when point is on that query, you get:
+;;
+;; %?- member(X, [a,b,c]).
+;; %@ X = a ;
+;; %@ X = b ;
+;; %@ X = c ;
+;; %@ false.
+;;
+;; When waiting for output of the Prolog process, you can press C-g to
+;; unblock Emacs and continue with other work. To resume interaction
+;; with the Prolog process, use M-x ediprolog-toplevel RET.
+
+;; If you press F10 when point is NOT on a query, the buffer content
+;; is consulted in the Prolog process, and point is moved to the first
+;; error (if any).
+
+;; For convenience, the most recent interactions with the Prolog
+;; process are logged in the buffer "*ediprolog-history*".
+
+;; Use M-x ediprolog-localize RET to make any Prolog process started
+;; in the current buffer buffer-local. This way, you can run distinct
+;; processes simultaneously. Revert with M-x ediprolog-unlocalize RET.
+
+;; `ediprolog-dwim' with prefix arguments has special meanings:
+;;
+;; C-0 F10 kill Prolog process
+;; C-1 F10 always consult buffer (even when point is on a query)
+;; C-2 F10 always consult buffer, using a new process
+;; C-7 F10 equivalent to `ediprolog-toplevel'
+;; C-u F10 first consult buffer, then evaluate query (if any)
+;; C-u C-u F10 like C-u F10, with a new process
+
+;; Tested with SWI-Prolog 5.6.55 + Emacs 21.2, 22.3 and 23.0.92.2.
+
+;;; Code:
+
+(defconst ediprolog-version "0.9yb")
+
+(defgroup ediprolog nil
+ "Transparent interaction with SWI-Prolog."
+ :group 'languages
+ :group 'processes)
+
+(defcustom ediprolog-program
+ (or (executable-find "swipl") (executable-find "pl") "swipl")
+ "Program name of the Prolog executable."
+ :group 'ediprolog
+ :type 'string)
+
+(defcustom ediprolog-program-switches nil
+ "List of switches passed to the Prolog process. Example:
+'(\"-G128M\" \"-O\")"
+ :group 'ediprolog
+ :type '(repeat string))
+
+(defcustom ediprolog-prefix "%@ "
+ "String to prepend when inserting output from the Prolog
+process into the buffer."
+ :group 'ediprolog
+ :type 'string)
+
+(defcustom ediprolog-max-history 80000
+ "Maximal size of history buffers storing recent interactions, or
+nil to never truncate the history."
+ :group 'ediprolog
+ :type 'sexp)
+
+(defvar ediprolog-process nil "A Prolog process.")
+
+(defvar ediprolog-temp-buffer nil
+ "Buffer that temporarily saves process output ")
+
+(defvar ediprolog-seen-prompt nil
+ "Whether a prompt was (recently) emitted by the Prolog process.")
+
+(defvar ediprolog-read-term nil
+ "Whether the Prolog process waits for the user to enter a term.")
+
+(defvar ediprolog-indent-prefix ""
+ "Any whitespace occurring before the most recently executed query.")
+
+(defvar ediprolog-temp-file nil
+ "File name of a temporary file used for consulting the buffer.")
+
+(defvar ediprolog-prompt "?ediprolog- "
+ "Prompt used in the Prolog session. It must differ from the
+default Prolog prompt.")
+
+(defvar ediprolog-consult-buffer "*ediprolog-consult*"
+ "Buffer used to display consult output.")
+
+(defvar ediprolog-consult-window nil
+ "Window used to show consult output.")
+
+(defvar ediprolog-history-buffer nil
+ "Buffer that stores recent interactions.")
+
+(defvar ediprolog-interrupted nil
+ "True iff waiting for the previous query was interrupted with C-g.")
+
+(defmacro ediprolog-wait-for-prompt-after (&rest forms)
+ "Evaluate FORMS and wait for prompt."
+ `(progn
+ (setq ediprolog-seen-prompt nil)
+ (ediprolog-ensure-buffer "temp")
+ (with-current-buffer ediprolog-temp-buffer
+ (let (buffer-read-only)
+ (erase-buffer)))
+ ;; execute forms with default-directory etc. from invocation buffer
+ ,@forms
+ (unless (process-filter ediprolog-process)
+ (set-process-filter ediprolog-process
'ediprolog-wait-for-prompt-filter))
+ (while (not ediprolog-seen-prompt)
+ ;; Wait for output/sentinel and update consult window, if any.
+ ;; As `accept-process-output' does not run the sentinel in
+ ;; Emacs <= 23.1, we use `sit-for' to do both. However,
+ ;; `sit-for' returns immediately if keyboard input is
+ ;; available, so we must discard input.
+ (discard-input)
+ (sit-for 0.1))))
+
+(defmacro ediprolog-remember-interruption (form)
+ "Set `ediprolog-interrupted' if evaluation of FORM was interrupted."
+ `(condition-case nil
+ ,form
+ (quit (setq ediprolog-interrupted t))))
+
+;; Only the sentinel can reliably detect if no more output follows -
+;; even if process-status is 'exit, further output can still follow.
+(defun ediprolog-sentinel (proc str)
+ (when (buffer-live-p (process-buffer proc))
+ (with-current-buffer (process-buffer proc)
+ (let ((status (with-temp-buffer
+ (insert str)
+ (while (search-backward "\n" nil t)
+ (replace-match ""))
+ (buffer-string))))
+ (ediprolog-log
+ (format "%s: %s.\n"
+ (substring (current-time-string) 4 -5) status) "green" t))
+ (when (string-match "^\\(?:finished\n\\|exited abnormally\\|killed\n\\)"
+ str)
+ (setq ediprolog-seen-prompt t)))))
+
+(defun ediprolog-ensure-buffer (name)
+ (let ((str (format "*ediprolog-%s*" name))
+ (var (intern (format "ediprolog-%s-buffer" name))))
+ (unless (buffer-live-p (symbol-value var))
+ (set var (generate-new-buffer str))
+ (with-current-buffer (symbol-value var)
+ (buffer-disable-undo)
+ (setq buffer-read-only t)))))
+
+(defun ediprolog-log (str &optional col nl)
+ (ediprolog-ensure-buffer "history")
+ (with-current-buffer ediprolog-history-buffer
+ (let (buffer-read-only)
+ (goto-char (point-max))
+ (let ((s (format "%s%s" (if (and nl (not (bolp))) "\n" "") str)))
+ (insert (if col (propertize s 'face `(:background ,col)) s)))
+ (let ((size (- (point-max) (point-min))))
+ (when (and ediprolog-max-history
+ (> size ediprolog-max-history))
+ ;; delete older half of the (possibly narrowed) history
+ (delete-region (point-min) (+ (point-min) (/ size 2))))))))
+
+(defun ediprolog-run-prolog ()
+ "Start a Prolog process."
+ (let ((args (cons ediprolog-program ediprolog-program-switches)))
+ (ediprolog-log (format "%s: starting: %S\n"
+ (substring (current-time-string) 4 -5) args)
+ "green" t)
+ (condition-case nil
+ (ediprolog-wait-for-prompt-after
+ (setq ediprolog-process
+ (apply #'start-process "ediprolog" (current-buffer) args))
+ (set-process-sentinel ediprolog-process 'ediprolog-sentinel)
+ (ediprolog-send-string
+ (format "'$set_prompt'('%s').\n" ediprolog-prompt)))
+ ((error quit)
+ (ediprolog-log "No prompt found." "red" t)
+ (error "No prompt from: %s" ediprolog-program)))))
+
+(defun ediprolog-kill-prolog ()
+ "Kill the Prolog process and run the process sentinel."
+ (when (ediprolog-running)
+ (delete-process ediprolog-process)))
+
+(defun ediprolog-show-consult-output (str)
+ (with-current-buffer (get-buffer-create ediprolog-consult-buffer)
+ (setq buffer-read-only t)
+ (let (buffer-read-only)
+ (erase-buffer)
+ (insert str)
+ (goto-char (point-min))
+ ;; remove normal consult status lines, which start with "%"
+ (while (re-search-forward "^[\t ]*%.*\n" nil t)
+ (delete-region (match-beginning 0) (match-end 0))))
+ (setq str (buffer-string)))
+ ;; show consult output in a separate window unless it is a prefix of
+ ;; success (i.e., consulted without errors), or still an incomplete
+ ;; line that starts with a comment character
+ (unless (or (string-match "^[\t ]*\\(?:%.*\\)?\\'" str)
+ (let ((success "true."))
+ (and (<= (length str) (length success))
+ (string= str (substring success 0 (length str))))))
+ (setq ediprolog-consult-window (display-buffer ediprolog-consult-buffer))
+ (set-window-dedicated-p ediprolog-consult-window t)
+ (fit-window-to-buffer ediprolog-consult-window (/ (frame-height) 2))))
+
+(defun ediprolog-consult-filter (proc str)
+ "Filter used when consulting a file, showing consult output."
+ (with-current-buffer (ediprolog-temp-buffer proc)
+ (goto-char (point-max))
+ (let (buffer-read-only)
+ (insert str))
+ (with-current-buffer (process-buffer proc)
+ (ediprolog-log str))
+ (when (re-search-backward
+ (format "^%s" (regexp-quote ediprolog-prompt)) nil t)
+ (with-current-buffer (process-buffer proc)
+ (setq ediprolog-seen-prompt t)))
+ (skip-chars-backward "\n")
+ (ediprolog-show-consult-output (buffer-substring (point-min) (point)))))
+
+(defun ediprolog-wait-for-prompt-filter (proc str)
+ "Filter that only waits until prompt appears."
+ (with-current-buffer (ediprolog-temp-buffer proc)
+ (goto-char (point-max))
+ (let (buffer-read-only)
+ (insert str))
+ (with-current-buffer (process-buffer proc)
+ (ediprolog-log str))
+ (when (re-search-backward
+ (format "^%s" (regexp-quote ediprolog-prompt)) nil t)
+ (with-current-buffer (process-buffer proc)
+ (setq ediprolog-seen-prompt t)))))
+
+
+;;;###autoload
+(defun ediprolog-dwim (&optional arg)
+ "Load current buffer into Prolog or post query (Do What I Mean).
+If invoked on a line starting with `:-' or `?-', possibly
+preceded by `%' and whitespace, call `ediprolog-interact' with
+the query as argument. Otherwise, call `ediprolog-consult'.
+
+With prefix argument 0, kill the Prolog process. With prefix 1,
+equivalent to `ediprolog-consult'. With prefix 2, equivalent to
+`ediprolog-consult' with a new Prolog process. With prefix 7,
+equivalent to `ediprolog-toplevel'. With just C-u, first call
+`ediprolog-consult' and then, if point is on a query, call
+`ediprolog-interact' with it as argument. Analogously, C-u C-u
+for `ediprolog-consult' with a new process. With other prefix
+arguments, equivalent to `ediprolog-remove-interactions'."
+ (interactive "P")
+ (cond ((eq arg 0)
+ (unless (ediprolog-running)
+ (error "No Prolog process running"))
+ (ediprolog-kill-prolog)
+ (message "Prolog process killed."))
+ ((eq arg 1) (ediprolog-consult))
+ ((eq arg 2) (ediprolog-consult t))
+ ((eq arg 7)
+ (unless (ediprolog-more-solutions)
+ (error "No query in progress"))
+ (ediprolog-toplevel))
+ ((equal arg '(4)) (ediprolog-consult) (ediprolog-query))
+ ((equal arg '(16)) (ediprolog-consult t) (ediprolog-query))
+ ((null arg) (unless (ediprolog-query) (ediprolog-consult)))
+ (t (ediprolog-remove-interactions))))
+
+(defun ediprolog-process-ready ()
+ "Error if the previous query is still in progress."
+ (when (and ediprolog-interrupted
+ (ediprolog-running)
+ (ediprolog-more-solutions))
+ (error "Previous query still in progress, see `ediprolog-toplevel'"))
+ (setq ediprolog-interrupted nil))
+
+(defun ediprolog-query ()
+ "If point is on a query, send it to the process and start interaction."
+ (ediprolog-process-ready)
+ (when (and (not (and transient-mark-mode mark-active))
+ (save-excursion
+ (beginning-of-line)
+ (looking-at "\\([\t ]*\\)%*[\t ]*[:?]-")))
+ ;; whitespace preceding the query is the indentation level
+ (setq ediprolog-indent-prefix (match-string 1))
+ (let* ((from (goto-char (match-end 0)))
+ (to (if (re-search-forward "\\.[\t ]*\\(?:%.*\\)?$" nil t)
+ ;; omit trailing whitespace
+ (+ (point) (skip-chars-backward "\t "))
+ (error "Missing `.' at the end of this query")))
+ (query (buffer-substring-no-properties from to)))
+ (end-of-line)
+ (insert "\n" ediprolog-indent-prefix ediprolog-prefix)
+ (ediprolog-interact
+ (format "%s\n" (mapconcat #'identity
+ ;; `%' can precede each query line
+ (split-string query "\n[ \t%]*") " "))))
+ t))
+
+;;;###autoload
+(defun ediprolog-interact (query)
+ "Send QUERY to Prolog process and interact as on a terminal.
+
+You can use \\[keyboard-quit] to unblock Emacs in the case of
+longer-running queries. When the query completes and the toplevel
+asks for input, use \\[ediprolog-toplevel] to resume interaction
+with the Prolog process."
+ (unless (ediprolog-running)
+ (ediprolog-run-prolog))
+ (set-marker (process-mark ediprolog-process) (point))
+ (set-process-buffer ediprolog-process (current-buffer))
+ (set-process-filter ediprolog-process 'ediprolog-interact-filter)
+ (ediprolog-ensure-buffer "temp")
+ (with-current-buffer ediprolog-temp-buffer
+ (let (buffer-read-only)
+ (erase-buffer)))
+ (setq ediprolog-seen-prompt nil
+ ediprolog-read-term nil)
+ (ediprolog-send-string query)
+ (ediprolog-toplevel))
+
+(defun ediprolog-send-string (str)
+ "Send string to Prolog process and log it."
+ (ediprolog-log str "cyan")
+ (process-send-string ediprolog-process str))
+
+(defun ediprolog-toplevel ()
+ "Start or resume Prolog toplevel interaction in the buffer.
+
+You can use this function if you have previously quit (with
+\\[keyboard-quit]) waiting for a longer-running query and now
+want to resume interaction with the toplevel."
+ (interactive)
+ (when ediprolog-process
+ (select-window (display-buffer (process-buffer ediprolog-process))))
+ (ediprolog-remember-interruption
+ (while (ediprolog-more-solutions)
+ (let (str
+ char)
+ ;; poll for user input; meanwhile, process output can arrive
+ (while (and (ediprolog-more-solutions) (null str))
+ (goto-char (process-mark ediprolog-process))
+ (if ediprolog-read-term
+ (progn
+ (setq str (concat (read-string "Input: ") "\n"))
+ (ediprolog-insert-at-marker
+ str ediprolog-indent-prefix ediprolog-prefix)
+ (setq ediprolog-read-term nil))
+ (condition-case nil
+ (when (setq char (if (>= emacs-major-version 22)
+ (read-char nil nil 0.1)
+ (with-timeout (0.1 nil)
+ (read-char))))
+ ;; char-to-string might still yield an error (C-0 etc.)
+ (setq str (char-to-string char)))
+ (error
+ (message "Non-character key")
+ ;; non-character keys must not remain in the input
+ ;; buffer, lest `read-char' return immediately
+ (discard-input)))))
+ (when (ediprolog-more-solutions)
+ (if (eq char ?\C-c) ; char can be nil too
+ ;; sending C-c directly yields strange SWI buffering
+ (interrupt-process ediprolog-process)
+ (ediprolog-send-string str)))))))
+
+;;;###autoload
+(defun ediprolog-remove-interactions ()
+ "Remove all lines starting with `ediprolog-prefix' from buffer.
+
+In transient mark mode, the function operates on the region if it
+is active."
+ (interactive)
+ (save-excursion
+ (save-restriction
+ (when (and transient-mark-mode mark-active)
+ (narrow-to-region (region-beginning) (region-end)))
+ (goto-char (point-min))
+ (flush-lines (concat "^[\t ]*" (regexp-quote ediprolog-prefix)))))
+ (message "Interactions removed."))
+
+
+;;;###autoload
+(defun ediprolog-consult (&optional new-process)
+ "Buffer is loaded into a Prolog process. If NEW-PROCESS is
+non-nil, start a new process. Otherwise use the existing process,
+if any. In case of errors, point is moved to the position of the
+first error, and the mark is left at the previous position.
+
+In transient mark mode, the function operates on the region if it
+is active."
+ (interactive)
+ (when (string= (buffer-name) ediprolog-consult-buffer)
+ (error "Cannot consult the consult buffer"))
+ (when (window-live-p ediprolog-consult-window)
+ (condition-case nil
+ ;; deleting the window can still raise an error, if the window
+ ;; was the only window in the frame and the consult buffer was
+ ;; killed (and it thus displays a different buffer now)
+ (delete-window ediprolog-consult-window)
+ (error nil)))
+ (when (buffer-live-p ediprolog-consult-buffer)
+ (bury-buffer ediprolog-consult-buffer))
+ (when new-process
+ (ediprolog-kill-prolog))
+ (unless (ediprolog-running)
+ (ediprolog-run-prolog))
+ (ediprolog-process-ready)
+ (set-process-buffer ediprolog-process (current-buffer))
+ (unless ediprolog-temp-file
+ (setq ediprolog-temp-file (make-temp-file "ediprolog")))
+ (let ((start (if (and transient-mark-mode mark-active)
+ (region-beginning) (point-min)))
+ (end (if (and transient-mark-mode mark-active)
+ (region-end) (point-max))))
+ (write-region start end ediprolog-temp-file nil 'silent))
+ (set-process-filter ediprolog-process 'ediprolog-consult-filter)
+ (ediprolog-remember-interruption
+ (ediprolog-wait-for-prompt-after
+ (ediprolog-send-string (format "['%s'].\n" ediprolog-temp-file))))
+ (message "%s consulted." (if (and transient-mark-mode mark-active)
+ "Region" "Buffer"))
+ ;; go to line of the first error, if any
+ (let ((line (with-current-buffer ediprolog-temp-buffer
+ (when (save-excursion
+ (goto-char (point-min))
+ (re-search-forward "^ERROR.*?:\\([0-9]+\\)" nil t))
+ (string-to-number (match-string 1))))))
+ (when line
+ (if (and transient-mark-mode mark-active)
+ (when (fboundp 'line-number-at-pos)
+ (goto-line (+ (line-number-at-pos (region-beginning)) line -1)))
+ (goto-line line)))))
+
+(defun ediprolog-running ()
+ "True iff `ediprolog-process' is a running process."
+ (and (processp ediprolog-process)
+ (eq (process-status ediprolog-process) 'run)))
+
+(defun ediprolog-more-solutions ()
+ "True iff there could be more solutions from the process."
+ (not ediprolog-seen-prompt))
+
+(defun ediprolog-interact-filter (proc string)
+ "Insert output from the process and update the state."
+ (when (and (buffer-live-p (ediprolog-temp-buffer proc))
+ (buffer-live-p (process-buffer proc)))
+ (let (str)
+ (with-current-buffer (ediprolog-temp-buffer proc)
+ (goto-char (point-max))
+ (let (buffer-read-only)
+ (insert string))
+ (with-current-buffer (process-buffer proc)
+ (ediprolog-log string))
+ ;; read a term from the user?
+ (when (re-search-backward "^|: $" nil t)
+ (with-current-buffer (process-buffer proc)
+ (setq ediprolog-read-term t))
+ (setq str (buffer-string))
+ (let (buffer-read-only)
+ (erase-buffer)))
+ ;; check for prompt
+ (goto-char (point-max))
+ (when (re-search-backward
+ (format "^%s" (regexp-quote ediprolog-prompt)) nil t)
+ (with-current-buffer (process-buffer proc)
+ (setq ediprolog-seen-prompt t))
+ ;; ignore further output due to accidental user input (C-j,
+ ;; C-m, etc.) while the query was running
+ (set-process-filter proc 'ediprolog-ignore-filter)
+ (skip-chars-backward "\n")
+ (setq str (buffer-substring (point-min) (point))))
+ (unless str
+ (goto-char (point-max))
+ ;; delay final line if it can still be completed to prompt
+ (let ((l (buffer-substring (line-beginning-position) (point))))
+ (when (and (<= (length l) (length ediprolog-prompt))
+ (string= l (substring ediprolog-prompt 0 (length l))))
+ (goto-char (line-beginning-position))))
+ ;; delay emitting newlines until we are sure no prompt
+ ;; follows; one or two newlines can precede a prompt
+ (let ((d (abs (skip-chars-backward "\n"))))
+ (when (> d 2)
+ (forward-char (- d 2))))
+ (setq str (buffer-substring (point-min) (point)))
+ (let (buffer-read-only)
+ (delete-region (point-min) (point))))
+ (when str
+ (with-temp-buffer
+ ;; precede each line with ediprolog prefices
+ (insert str)
+ (goto-char (point-min))
+ (while (search-forward "\n" nil t)
+ (replace-match
+ (format "\n%s%s" (with-current-buffer (process-buffer proc)
+ ediprolog-indent-prefix) ediprolog-prefix)))
+ (setq str (buffer-string)))
+ (with-current-buffer (process-buffer proc)
+ (let ((near (<= (abs (- (point) (process-mark proc))) 1)))
+ (ediprolog-insert-at-marker str)
+ (when near
+ ;; catch up with output if point was reasonably close
+ (goto-char (process-mark proc))))))))))
+
+
+(defun ediprolog-insert-at-marker (&rest args)
+ "Insert strings ARGS at marker and update the marker."
+ (save-excursion
+ (goto-char (process-mark ediprolog-process))
+ (end-of-line)
+ (apply #'insert args)
+ (set-marker (process-mark ediprolog-process) (point))))
+
+(defun ediprolog-ignore-filter (proc str)
+ "Log and then ignore all process output."
+ (with-current-buffer (process-buffer proc)
+ (ediprolog-log str "gray")))
+
+(defun ediprolog-temp-buffer (proc)
+ (with-current-buffer (process-buffer proc)
+ ;; temp buffer can be buffer local
+ ediprolog-temp-buffer))
+
+(defun ediprolog-map-variables (func)
+ "Call FUNC with all ediprolog variables that can become buffer-local."
+ (mapc func '(ediprolog-process
+ ediprolog-program
+ ediprolog-program-switches
+ ediprolog-temp-buffer
+ ediprolog-history-buffer
+ ediprolog-seen-prompt
+ ediprolog-interrupted
+ ediprolog-read-term
+ ediprolog-indent-prefix
+ ediprolog-temp-file)))
+
+;;;###autoload
+(defun ediprolog-localize ()
+ "After `ediprolog-localize', any Prolog process started from
+this buffer becomes buffer-local."
+ (interactive)
+ (unless (local-variable-p 'ediprolog-process)
+ (ediprolog-map-variables #'make-local-variable)
+ (setq ediprolog-temp-file nil
+ ediprolog-process nil
+ ediprolog-history-buffer nil
+ ediprolog-temp-buffer nil)))
+
+(defun ediprolog-unlocalize ()
+ "Revert the effect of `ediprolog-localize'."
+ (interactive)
+ (when (local-variable-p 'ediprolog-process)
+ (ediprolog-kill-prolog)
+ (ediprolog-map-variables #'kill-local-variable)))
+
+(provide 'ediprolog)
+
+;;; ediprolog.el ends here
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [ELPA-diffs] /srv/bzr/emacs/elpa r165: Add new package "ediprolog".,
Stefan Monnier <=